fallow 3.2.0 → 3.4.2
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 +11 -1
- package/capabilities.json +944 -3
- package/issue-registry.json +357 -0
- package/package.json +10 -10
- package/schema.json +132 -1
- package/scripts/platform-package.js +1 -1
- package/scripts/platform-package.test.js +3 -3
- package/scripts/run-binary.js +15 -1
- package/scripts/run-binary.test.js +17 -0
- package/skills/fallow/SKILL.md +23 -51
- package/skills/fallow/references/cli-reference.md +24 -11
- package/skills/fallow/references/mcp.md +64 -0
- package/types/output-contract.d.ts +458 -6
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator
|
|
27
|
+
* Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator. Current kind values: `audit`, `explain`, `inspect_target`, `trace`, `review-envelope`, `review-reconcile`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `list-workspaces`, `health`, `dupes`, `dead-code-grouped`, `impact`, `impact-cross-repo`, `security`, `security-survivors`, `security-blind-spots`, `dead-code`, `combined`, `feature-flags`, `audit-brief`, `decision-surface`, `review-walkthrough-guide`, `review-walkthrough-validation`, `suppression-inventory`. Consumers should branch on `kind` instead of probing for unique field presence. `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
28
|
*/
|
|
29
29
|
export type FallowJsonOutput = (FallowOutput | CodeClimateOutput)
|
|
30
30
|
/**
|
|
@@ -50,6 +50,8 @@ kind: "audit"
|
|
|
50
50
|
kind: "explain"
|
|
51
51
|
}) | (InspectOutput & {
|
|
52
52
|
kind: "inspect_target"
|
|
53
|
+
}) | (SymbolChainTrace & {
|
|
54
|
+
kind: "trace"
|
|
53
55
|
}) | (ReviewEnvelopeOutput & {
|
|
54
56
|
kind: "review-envelope"
|
|
55
57
|
}) | (ReviewReconcileOutput & {
|
|
@@ -82,12 +84,18 @@ kind: "security-blind-spots"
|
|
|
82
84
|
kind: "dead-code"
|
|
83
85
|
}) | (CombinedOutput & {
|
|
84
86
|
kind: "combined"
|
|
87
|
+
}) | (FeatureFlagsOutput & {
|
|
88
|
+
kind: "feature-flags"
|
|
85
89
|
}) | (ReviewBriefOutput & {
|
|
86
90
|
kind: "audit-brief"
|
|
91
|
+
}) | (DecisionSurfaceOutput & {
|
|
92
|
+
kind: "decision-surface"
|
|
87
93
|
}) | (WalkthroughGuide & {
|
|
88
94
|
kind: "review-walkthrough-guide"
|
|
89
95
|
}) | (WalkthroughValidation & {
|
|
90
96
|
kind: "review-walkthrough-validation"
|
|
97
|
+
}) | (SuppressionInventoryOutput & {
|
|
98
|
+
kind: "suppression-inventory"
|
|
91
99
|
}))
|
|
92
100
|
/**
|
|
93
101
|
* Schema version for this output format (independent of tool version). Bump
|
|
@@ -369,6 +377,12 @@ kind: "skipped-large-file"
|
|
|
369
377
|
*/
|
|
370
378
|
size_bytes: number
|
|
371
379
|
kind: "skipped-minified-file"
|
|
380
|
+
} | {
|
|
381
|
+
/**
|
|
382
|
+
* Filesystem or UTF-8 decoding error from `read_to_string`.
|
|
383
|
+
*/
|
|
384
|
+
error: string
|
|
385
|
+
kind: "source-read-failure"
|
|
372
386
|
})
|
|
373
387
|
/**
|
|
374
388
|
* Discriminant for [`CloneGroupAction::kind`]. Mirrors the action types
|
|
@@ -639,6 +653,10 @@ type: "symbol"
|
|
|
639
653
|
export type InspectIdentity = (InspectFileIdentity | InspectSymbolIdentity)
|
|
640
654
|
export type InspectSectionStatus = ("ok" | "error")
|
|
641
655
|
export type InspectEvidenceScope = ("symbol" | "file" | "project_filtered_to_file")
|
|
656
|
+
/**
|
|
657
|
+
* Best-effort classification of why a callee did not resolve to an edge.
|
|
658
|
+
*/
|
|
659
|
+
export type UnresolvedReason = ("local-or-global" | "member-or-dynamic")
|
|
642
660
|
/**
|
|
643
661
|
* Singleton GitHub review-event marker.
|
|
644
662
|
*/
|
|
@@ -800,6 +818,18 @@ export type SecurityVerifierVerdictStatus = ("survivor" | "dismissed" | "needs-h
|
|
|
800
818
|
* The `fallow security blind-spots --format json` schema version.
|
|
801
819
|
*/
|
|
802
820
|
export type SecurityBlindSpotsSchemaVersion = "1"
|
|
821
|
+
/**
|
|
822
|
+
* Feature flag kind values emitted in JSON.
|
|
823
|
+
*/
|
|
824
|
+
export type FeatureFlagKind = ("environment_variable" | "sdk_call" | "config_object")
|
|
825
|
+
/**
|
|
826
|
+
* Feature flag confidence values emitted in JSON.
|
|
827
|
+
*/
|
|
828
|
+
export type FeatureFlagConfidence = ("high" | "medium" | "low")
|
|
829
|
+
/**
|
|
830
|
+
* Feature flag action discriminants.
|
|
831
|
+
*/
|
|
832
|
+
export type FeatureFlagActionType = ("investigate-flag" | "suppress-line")
|
|
803
833
|
/**
|
|
804
834
|
* Independently-versioned wire-version newtype for the brief envelope.
|
|
805
835
|
* Serializes as the integer `REVIEW_BRIEF_SCHEMA_VERSION`.
|
|
@@ -840,6 +870,28 @@ export type WeakeningKind = ("test-weakened" | "threshold-lowered" | "suppressio
|
|
|
840
870
|
* enum is the structural guarantee that confirmed-noise categories never ship.
|
|
841
871
|
*/
|
|
842
872
|
export type DecisionCategory = ("coupling-boundary" | "public-api-contract" | "dependency")
|
|
873
|
+
/**
|
|
874
|
+
* Independently-versioned wire-version newtype. Serializes as the integer
|
|
875
|
+
* [`DECISION_SURFACE_SCHEMA_VERSION`].
|
|
876
|
+
*/
|
|
877
|
+
export type DecisionSurfaceSchemaVersion = number
|
|
878
|
+
/**
|
|
879
|
+
* The discriminated action kinds a decision can carry.
|
|
880
|
+
*/
|
|
881
|
+
export type DecisionActionType = ("ask-expert" | "suppress")
|
|
882
|
+
/**
|
|
883
|
+
* The `fallow suppressions --format json` schema version. Independently
|
|
884
|
+
* versioned from the main contract, mirroring `SecuritySchemaVersion`.
|
|
885
|
+
*/
|
|
886
|
+
export type SuppressionInventorySchemaVersion = "1"
|
|
887
|
+
/**
|
|
888
|
+
* Suppression marker scope.
|
|
889
|
+
*/
|
|
890
|
+
export type SuppressionInventoryLevel = ("file" | "line")
|
|
891
|
+
/**
|
|
892
|
+
* How a suppression in the inventory was authored.
|
|
893
|
+
*/
|
|
894
|
+
export type SuppressionInventoryOrigin = "comment"
|
|
843
895
|
/**
|
|
844
896
|
* Discriminator value for [`CodeClimateIssue::kind`].
|
|
845
897
|
*/
|
|
@@ -3721,8 +3773,9 @@ stats: DuplicationStats
|
|
|
3721
3773
|
/**
|
|
3722
3774
|
* Wire-shape envelope for a [`CloneGroup`] finding. Flattens the bare
|
|
3723
3775
|
* group via `#[serde(flatten)]` and carries a typed `actions` array plus
|
|
3724
|
-
* the optional audit-mode `introduced` flag.
|
|
3725
|
-
* post-pass injection in
|
|
3776
|
+
* the optional audit-mode `introduced` flag. The typed envelope replaced
|
|
3777
|
+
* the legacy JSON post-pass injection; a guard test in
|
|
3778
|
+
* `crates/cli/src/report/json.rs` rejects any reintroduced post-pass.
|
|
3726
3779
|
*/
|
|
3727
3780
|
export interface CloneGroupFinding {
|
|
3728
3781
|
/**
|
|
@@ -3796,9 +3849,9 @@ fragment: string
|
|
|
3796
3849
|
}
|
|
3797
3850
|
/**
|
|
3798
3851
|
* Per-action wire shape attached to each `CloneGroupFinding` and
|
|
3799
|
-
* `AttributedCloneGroupFinding
|
|
3800
|
-
*
|
|
3801
|
-
*
|
|
3852
|
+
* `AttributedCloneGroupFinding` (see `crates/api/src/dupes_output.rs`):
|
|
3853
|
+
* `extract-shared` plus `suppress-line`. The typed wrappers replaced the
|
|
3854
|
+
* legacy JSON post-pass injection that used to live in the CLI report layer.
|
|
3802
3855
|
*/
|
|
3803
3856
|
export interface CloneGroupAction {
|
|
3804
3857
|
type: CloneGroupActionType
|
|
@@ -6013,6 +6066,13 @@ unused_theme_tokens?: UnusedThemeToken[]
|
|
|
6013
6066
|
* candidates because they need whole-project token context.
|
|
6014
6067
|
*/
|
|
6015
6068
|
near_duplicate_theme_tokens?: NearDuplicateThemeToken[]
|
|
6069
|
+
/**
|
|
6070
|
+
* CSS-in-JS design tokens whose comparable values are close to another
|
|
6071
|
+
* token from the same project. Covers StyleX, vanilla-extract, PandaCSS,
|
|
6072
|
+
* styled-components, and Emotion token definitions. These are opt-in
|
|
6073
|
+
* `--css-deep` candidates because they need whole-project token context.
|
|
6074
|
+
*/
|
|
6075
|
+
near_duplicate_css_in_js_tokens?: NearDuplicateThemeToken[]
|
|
6016
6076
|
/**
|
|
6017
6077
|
* A location-aware reverse index of Tailwind v4 `@theme` token consumers:
|
|
6018
6078
|
* per token, where it is consumed (`var()` reads, `@apply` bodies, generated
|
|
@@ -6389,6 +6449,12 @@ unused_theme_tokens: number
|
|
|
6389
6449
|
* `near_duplicate_theme_tokens`.
|
|
6390
6450
|
*/
|
|
6391
6451
|
near_duplicate_theme_tokens: number
|
|
6452
|
+
/**
|
|
6453
|
+
* CSS-in-JS design tokens whose comparable values are close to another
|
|
6454
|
+
* token from the same project. Located in
|
|
6455
|
+
* `near_duplicate_css_in_js_tokens`.
|
|
6456
|
+
*/
|
|
6457
|
+
near_duplicate_css_in_js_tokens: number
|
|
6392
6458
|
/**
|
|
6393
6459
|
* Number of distinct `font-size` units (`px` / `rem` / `em` / `%`) authored
|
|
6394
6460
|
* across the codebase. Mixing units is a type-scale consistency smell,
|
|
@@ -7154,6 +7220,93 @@ scope: InspectEvidenceScope
|
|
|
7154
7220
|
message?: (string | null)
|
|
7155
7221
|
data?: unknown
|
|
7156
7222
|
}
|
|
7223
|
+
/**
|
|
7224
|
+
* The result of a symbol-level call-chain trace. Its own surface (`kind:
|
|
7225
|
+
* "trace"`), NOT folded into the ranked brief.
|
|
7226
|
+
*/
|
|
7227
|
+
export interface SymbolChainTrace {
|
|
7228
|
+
/**
|
|
7229
|
+
* The file containing the traced symbol (project-root-relative).
|
|
7230
|
+
*/
|
|
7231
|
+
file: string
|
|
7232
|
+
/**
|
|
7233
|
+
* The traced symbol name.
|
|
7234
|
+
*/
|
|
7235
|
+
symbol: string
|
|
7236
|
+
/**
|
|
7237
|
+
* Whether the symbol's defining export was found in the graph. When
|
|
7238
|
+
* `false`, the chains are empty and `reason` explains why.
|
|
7239
|
+
*/
|
|
7240
|
+
symbol_found: boolean
|
|
7241
|
+
/**
|
|
7242
|
+
* The chain depth applied to both directions.
|
|
7243
|
+
*/
|
|
7244
|
+
depth: number
|
|
7245
|
+
/**
|
|
7246
|
+
* Whether this trace is best-effort (always `true`: symbol-level chains are
|
|
7247
|
+
* labeled best-effort, syntactic per ADR-001).
|
|
7248
|
+
*/
|
|
7249
|
+
best_effort: boolean
|
|
7250
|
+
/**
|
|
7251
|
+
* Caller chain hops (UP). Present only when `--callers` was requested.
|
|
7252
|
+
*/
|
|
7253
|
+
callers?: (ChainHop[] | null)
|
|
7254
|
+
/**
|
|
7255
|
+
* Callee chain hops (DOWN) resolved to an import-symbol edge. Present only
|
|
7256
|
+
* when `--callees` was requested.
|
|
7257
|
+
*/
|
|
7258
|
+
callees?: (ChainHop[] | null)
|
|
7259
|
+
/**
|
|
7260
|
+
* Callees referenced at a call site in the symbol's module that the
|
|
7261
|
+
* syntactic walk could NOT resolve to an import-symbol edge (locals,
|
|
7262
|
+
* globals, dynamic dispatch, re-bound callees). Reported, never dropped.
|
|
7263
|
+
* Present only when `--callees` was requested.
|
|
7264
|
+
*/
|
|
7265
|
+
unresolved_callees?: (UnresolvedCallee[] | null)
|
|
7266
|
+
/**
|
|
7267
|
+
* A human-readable summary of the trace outcome.
|
|
7268
|
+
*/
|
|
7269
|
+
reason: string
|
|
7270
|
+
}
|
|
7271
|
+
/**
|
|
7272
|
+
* One hop in a caller / callee chain.
|
|
7273
|
+
*/
|
|
7274
|
+
export interface ChainHop {
|
|
7275
|
+
/**
|
|
7276
|
+
* The file at this hop (project-root-relative). For a caller hop this is
|
|
7277
|
+
* the importing module; for a callee hop the imported module.
|
|
7278
|
+
*/
|
|
7279
|
+
file: string
|
|
7280
|
+
/**
|
|
7281
|
+
* The symbol name as imported across the edge (`default`, `*` for namespace,
|
|
7282
|
+
* the imported name otherwise).
|
|
7283
|
+
*/
|
|
7284
|
+
imported_as: string
|
|
7285
|
+
/**
|
|
7286
|
+
* The local binding name in the file at this hop.
|
|
7287
|
+
*/
|
|
7288
|
+
local_name: string
|
|
7289
|
+
/**
|
|
7290
|
+
* Whether the import edge is type-only (`import type { ... }`).
|
|
7291
|
+
*/
|
|
7292
|
+
type_only: boolean
|
|
7293
|
+
/**
|
|
7294
|
+
* The hop's depth (1 = direct caller/callee of the symbol).
|
|
7295
|
+
*/
|
|
7296
|
+
depth: number
|
|
7297
|
+
}
|
|
7298
|
+
/**
|
|
7299
|
+
* A callee referenced at a call site that did not resolve to an import-symbol
|
|
7300
|
+
* edge. Surfaced so a missing callee is never silently dropped.
|
|
7301
|
+
*/
|
|
7302
|
+
export interface UnresolvedCallee {
|
|
7303
|
+
/**
|
|
7304
|
+
* The callee path as written at the call site (e.g. `helper`,
|
|
7305
|
+
* `obj.method`).
|
|
7306
|
+
*/
|
|
7307
|
+
callee: string
|
|
7308
|
+
reason: UnresolvedReason
|
|
7309
|
+
}
|
|
7157
7310
|
/**
|
|
7158
7311
|
* Envelope emitted by `fallow --format review-github` / `review-gitlab`.
|
|
7159
7312
|
*/
|
|
@@ -7807,6 +7960,11 @@ grouped_by: GroupByMode
|
|
|
7807
7960
|
total_issues: number
|
|
7808
7961
|
groups: CheckGroupedEntry[]
|
|
7809
7962
|
_meta?: (Meta | null)
|
|
7963
|
+
/**
|
|
7964
|
+
* Diagnostics collected for the full analysis before issue grouping.
|
|
7965
|
+
* See [`CheckOutput::workspace_diagnostics`] for the contract.
|
|
7966
|
+
*/
|
|
7967
|
+
workspace_diagnostics?: WorkspaceDiagnostic[]
|
|
7810
7968
|
/**
|
|
7811
7969
|
* Read-only follow-up commands computed from the full (ungrouped) findings.
|
|
7812
7970
|
* See [`CheckOutput::next_steps`] for the contract.
|
|
@@ -9146,6 +9304,79 @@ dupes?: (Meta | null)
|
|
|
9146
9304
|
health?: (Meta | null)
|
|
9147
9305
|
telemetry?: (TelemetryMeta | null)
|
|
9148
9306
|
}
|
|
9307
|
+
/**
|
|
9308
|
+
* Envelope emitted by `fallow flags --format json`.
|
|
9309
|
+
*/
|
|
9310
|
+
export interface FeatureFlagsOutput {
|
|
9311
|
+
schema_version: SchemaVersion
|
|
9312
|
+
version: ToolVersion
|
|
9313
|
+
elapsed_ms: ElapsedMs
|
|
9314
|
+
feature_flags: FeatureFlagFinding[]
|
|
9315
|
+
total_flags: number
|
|
9316
|
+
_meta?: (FeatureFlagsMeta | null)
|
|
9317
|
+
}
|
|
9318
|
+
/**
|
|
9319
|
+
* One feature flag finding in JSON output.
|
|
9320
|
+
*/
|
|
9321
|
+
export interface FeatureFlagFinding {
|
|
9322
|
+
path: string
|
|
9323
|
+
flag_name: string
|
|
9324
|
+
kind: FeatureFlagKind
|
|
9325
|
+
confidence: FeatureFlagConfidence
|
|
9326
|
+
line: number
|
|
9327
|
+
col: number
|
|
9328
|
+
actions: FeatureFlagAction[]
|
|
9329
|
+
sdk_name?: (string | null)
|
|
9330
|
+
dead_code_overlap?: (FeatureFlagDeadCodeOverlap | null)
|
|
9331
|
+
}
|
|
9332
|
+
/**
|
|
9333
|
+
* Per-finding action emitted for feature flag findings.
|
|
9334
|
+
*/
|
|
9335
|
+
export interface FeatureFlagAction {
|
|
9336
|
+
type: FeatureFlagActionType
|
|
9337
|
+
auto_fixable: boolean
|
|
9338
|
+
description: string
|
|
9339
|
+
comment?: (string | null)
|
|
9340
|
+
}
|
|
9341
|
+
/**
|
|
9342
|
+
* Dead-code overlap block attached when a flag guards unused exports.
|
|
9343
|
+
*/
|
|
9344
|
+
export interface FeatureFlagDeadCodeOverlap {
|
|
9345
|
+
guarded_lines: number
|
|
9346
|
+
dead_export_count: number
|
|
9347
|
+
dead_exports: string[]
|
|
9348
|
+
}
|
|
9349
|
+
/**
|
|
9350
|
+
* `_meta.feature_flags` details emitted with `--explain`.
|
|
9351
|
+
*/
|
|
9352
|
+
export interface FeatureFlagsMeta {
|
|
9353
|
+
feature_flags: FeatureFlagsMetaDetails
|
|
9354
|
+
}
|
|
9355
|
+
/**
|
|
9356
|
+
* Feature flag explanatory metadata.
|
|
9357
|
+
*/
|
|
9358
|
+
export interface FeatureFlagsMetaDetails {
|
|
9359
|
+
description: string
|
|
9360
|
+
kinds: FeatureFlagsKindMeta
|
|
9361
|
+
confidence: FeatureFlagsConfidenceMeta
|
|
9362
|
+
docs: string
|
|
9363
|
+
}
|
|
9364
|
+
/**
|
|
9365
|
+
* Feature flag kind explanations.
|
|
9366
|
+
*/
|
|
9367
|
+
export interface FeatureFlagsKindMeta {
|
|
9368
|
+
environment_variable: string
|
|
9369
|
+
sdk_call: string
|
|
9370
|
+
config_object: string
|
|
9371
|
+
}
|
|
9372
|
+
/**
|
|
9373
|
+
* Feature flag confidence explanations.
|
|
9374
|
+
*/
|
|
9375
|
+
export interface FeatureFlagsConfidenceMeta {
|
|
9376
|
+
high: string
|
|
9377
|
+
medium: string
|
|
9378
|
+
low: string
|
|
9379
|
+
}
|
|
9149
9380
|
/**
|
|
9150
9381
|
* The full `fallow audit --brief --format json` envelope. Carries the
|
|
9151
9382
|
* informational verdict, the triage and graph-facts orientation stages, plus
|
|
@@ -9567,6 +9798,127 @@ collapsed: number
|
|
|
9567
9798
|
*/
|
|
9568
9799
|
reason: string
|
|
9569
9800
|
}
|
|
9801
|
+
/**
|
|
9802
|
+
* The separable `decision-surface` envelope: the single call that puts taste-
|
|
9803
|
+
* decisions in front of a human, callable WITHOUT the full pipeline (the
|
|
9804
|
+
* `decision_surface` MCP tool's output). Carries `kind`/`schema_version` plus
|
|
9805
|
+
* structured `actions[]` per decision.
|
|
9806
|
+
*/
|
|
9807
|
+
export interface DecisionSurfaceOutput {
|
|
9808
|
+
schema_version: DecisionSurfaceSchemaVersion
|
|
9809
|
+
/**
|
|
9810
|
+
* Fallow CLI version that produced this output.
|
|
9811
|
+
*/
|
|
9812
|
+
version: string
|
|
9813
|
+
/**
|
|
9814
|
+
* Command discriminator singleton: always `"decision-surface"`.
|
|
9815
|
+
*/
|
|
9816
|
+
command: string
|
|
9817
|
+
/**
|
|
9818
|
+
* The ranked, capped decisions, each with structured actions.
|
|
9819
|
+
*/
|
|
9820
|
+
decisions: DecisionWithActions[]
|
|
9821
|
+
/**
|
|
9822
|
+
* Present when more than the cap were extracted.
|
|
9823
|
+
*/
|
|
9824
|
+
truncated?: (TruncationNote | null)
|
|
9825
|
+
/**
|
|
9826
|
+
* Count of fallow-emitted signal_ids (the anti-hallucination allowlist size).
|
|
9827
|
+
*/
|
|
9828
|
+
signal_count: number
|
|
9829
|
+
}
|
|
9830
|
+
/**
|
|
9831
|
+
* One decision plus its structured `actions[]`.
|
|
9832
|
+
*/
|
|
9833
|
+
export interface DecisionWithActions {
|
|
9834
|
+
/**
|
|
9835
|
+
* Deterministic anchor to the fallow-emitted candidate this decision frames.
|
|
9836
|
+
* `accept_signal_id` rejects any id not in the emitted set.
|
|
9837
|
+
*/
|
|
9838
|
+
signal_id: string
|
|
9839
|
+
category: DecisionCategory
|
|
9840
|
+
/**
|
|
9841
|
+
* The decision framed as a judgment question for the human.
|
|
9842
|
+
*/
|
|
9843
|
+
question: string
|
|
9844
|
+
/**
|
|
9845
|
+
* Root-relative file the decision is anchored at.
|
|
9846
|
+
*/
|
|
9847
|
+
anchor_file: string
|
|
9848
|
+
/**
|
|
9849
|
+
* 1-based anchor line, when the underlying signal carries one (0 = file head).
|
|
9850
|
+
*/
|
|
9851
|
+
anchor_line: number
|
|
9852
|
+
/**
|
|
9853
|
+
* The raw fallow-emitted candidate key the `signal_id` hashes.
|
|
9854
|
+
*/
|
|
9855
|
+
signal_key: string
|
|
9856
|
+
/**
|
|
9857
|
+
* The `signal_id` this decision WOULD have had before any rename in this
|
|
9858
|
+
* change (the anchor file's pre-rename path). Present only when the anchor was
|
|
9859
|
+
* renamed. A review-memory layer carries a dismissal across a `git mv`: if
|
|
9860
|
+
* `previous_signal_id` was dismissed in an earlier PR, treat this decision as
|
|
9861
|
+
* dismissed too. Keeps `signal_id` itself exact + deterministic.
|
|
9862
|
+
*/
|
|
9863
|
+
previous_signal_id?: (string | null)
|
|
9864
|
+
/**
|
|
9865
|
+
* Blast radius: count of modules affected beyond the diff by this decision.
|
|
9866
|
+
*/
|
|
9867
|
+
blast: number
|
|
9868
|
+
/**
|
|
9869
|
+
* `blast * reversibility_weight`: the rank key (sorted descending).
|
|
9870
|
+
*/
|
|
9871
|
+
consequence: number
|
|
9872
|
+
/**
|
|
9873
|
+
* The routed expert(s) to ask, from ownership routing. Empty when no
|
|
9874
|
+
* ownership signal is available for the anchor file.
|
|
9875
|
+
*/
|
|
9876
|
+
expert: string[]
|
|
9877
|
+
/**
|
|
9878
|
+
* Whether the anchor file's only qualified owner is one person.
|
|
9879
|
+
*/
|
|
9880
|
+
bus_factor_one?: boolean
|
|
9881
|
+
/**
|
|
9882
|
+
* Honest per-decision count: in-repo modules OUTSIDE the diff that already
|
|
9883
|
+
* depend on this decision's anchor. This is the DISPLAY number (taste
|
|
9884
|
+
* ownership: the human reads reversibility from the count itself), distinct
|
|
9885
|
+
* from `blast` (the project-wide proxy used only for ranking). Never a door
|
|
9886
|
+
* label. Internal-only by construction, so it cannot see a published library's
|
|
9887
|
+
* external consumers; the public-API trade-off clause names that risk in prose.
|
|
9888
|
+
*/
|
|
9889
|
+
internal_consumer_count: number
|
|
9890
|
+
/**
|
|
9891
|
+
* The named structural sacrifice this change makes, stated as a fact, never a
|
|
9892
|
+
* recommendation (e.g. "Couples `app` to `infra`; 4 in-repo modules already
|
|
9893
|
+
* depend on this anchor."). A sibling fact to `question`; it never tells the
|
|
9894
|
+
* human what to choose.
|
|
9895
|
+
*/
|
|
9896
|
+
tradeoff: string
|
|
9897
|
+
/**
|
|
9898
|
+
* Structured actions: route to the expert, or suppress.
|
|
9899
|
+
*/
|
|
9900
|
+
actions: DecisionAction[]
|
|
9901
|
+
}
|
|
9902
|
+
/**
|
|
9903
|
+
* A structured action attached to a surfaced decision (the agent-actionable
|
|
9904
|
+
* surface). Mirrors the typed-action shape the rest of fallow emits.
|
|
9905
|
+
*/
|
|
9906
|
+
export interface DecisionAction {
|
|
9907
|
+
type: DecisionActionType
|
|
9908
|
+
/**
|
|
9909
|
+
* Human-readable description of the action.
|
|
9910
|
+
*/
|
|
9911
|
+
description: string
|
|
9912
|
+
/**
|
|
9913
|
+
* Runnable command or paste-ready suppression comment.
|
|
9914
|
+
*/
|
|
9915
|
+
command?: (string | null)
|
|
9916
|
+
/**
|
|
9917
|
+
* Whether fallow can carry the action out automatically. Always `false`:
|
|
9918
|
+
* a decision is a human judgment, never auto-applied.
|
|
9919
|
+
*/
|
|
9920
|
+
auto_fixable: boolean
|
|
9921
|
+
}
|
|
9570
9922
|
/**
|
|
9571
9923
|
* The `fallow review --walkthrough-guide` envelope: the current digest + schema
|
|
9572
9924
|
* the agent fetches. The tool owns this; the skill stays thin (it fetches this
|
|
@@ -9809,6 +10161,106 @@ change_anchor: string
|
|
|
9809
10161
|
*/
|
|
9810
10162
|
reason: string
|
|
9811
10163
|
}
|
|
10164
|
+
/**
|
|
10165
|
+
* The `fallow suppressions --format json` envelope. `FallowOutput`
|
|
10166
|
+
* discriminates it by the `kind: "suppression-inventory"` tag.
|
|
10167
|
+
*
|
|
10168
|
+
* A read-only projection over the suppression markers present in analyzed
|
|
10169
|
+
* files this run: nothing here is a finding, and the command that emits it
|
|
10170
|
+
* always exits 0.
|
|
10171
|
+
*/
|
|
10172
|
+
export interface SuppressionInventoryOutput {
|
|
10173
|
+
schema_version: SuppressionInventorySchemaVersion
|
|
10174
|
+
summary: SuppressionInventorySummary
|
|
10175
|
+
/**
|
|
10176
|
+
* Per-file suppression listings, sorted by path then line.
|
|
10177
|
+
*/
|
|
10178
|
+
files: SuppressionInventoryFile[]
|
|
10179
|
+
}
|
|
10180
|
+
/**
|
|
10181
|
+
* Project-level totals for the suppression inventory.
|
|
10182
|
+
*/
|
|
10183
|
+
export interface SuppressionInventorySummary {
|
|
10184
|
+
/**
|
|
10185
|
+
* Total suppression markers in scope.
|
|
10186
|
+
*/
|
|
10187
|
+
total: number
|
|
10188
|
+
/**
|
|
10189
|
+
* Number of files carrying at least one marker.
|
|
10190
|
+
*/
|
|
10191
|
+
files: number
|
|
10192
|
+
/**
|
|
10193
|
+
* Markers without a human-authored `--` reason.
|
|
10194
|
+
*/
|
|
10195
|
+
without_reason: number
|
|
10196
|
+
/**
|
|
10197
|
+
* Markers that also appear as stale-suppression findings this run. This
|
|
10198
|
+
* is a JOIN against the existing stale-suppression detector's output
|
|
10199
|
+
* (matched by file and kind), not a new detection.
|
|
10200
|
+
*/
|
|
10201
|
+
stale: number
|
|
10202
|
+
/**
|
|
10203
|
+
* Marker counts per suppressed kind, sorted by count (descending) then
|
|
10204
|
+
* kind. `kind` is `null` for blanket markers, mirroring the per-entry
|
|
10205
|
+
* contract.
|
|
10206
|
+
*/
|
|
10207
|
+
by_kind: SuppressionKindCount[]
|
|
10208
|
+
}
|
|
10209
|
+
/**
|
|
10210
|
+
* One `by_kind` row in the suppression inventory summary.
|
|
10211
|
+
*/
|
|
10212
|
+
export interface SuppressionKindCount {
|
|
10213
|
+
/**
|
|
10214
|
+
* The suppressed issue kind in kebab-case, or `null` for blanket markers
|
|
10215
|
+
* (rendered as "blanket" in human output; machine consumers branch on
|
|
10216
|
+
* `null`).
|
|
10217
|
+
*/
|
|
10218
|
+
kind?: (string | null)
|
|
10219
|
+
/**
|
|
10220
|
+
* Number of markers targeting this kind.
|
|
10221
|
+
*/
|
|
10222
|
+
count: number
|
|
10223
|
+
}
|
|
10224
|
+
/**
|
|
10225
|
+
* One file's suppression listing.
|
|
10226
|
+
*/
|
|
10227
|
+
export interface SuppressionInventoryFile {
|
|
10228
|
+
/**
|
|
10229
|
+
* Project-root-relative path, forward-slash separated.
|
|
10230
|
+
*/
|
|
10231
|
+
path: string
|
|
10232
|
+
/**
|
|
10233
|
+
* Markers in this file, sorted by line.
|
|
10234
|
+
*/
|
|
10235
|
+
suppressions: SuppressionInventoryEntry[]
|
|
10236
|
+
}
|
|
10237
|
+
/**
|
|
10238
|
+
* One suppression marker in the inventory.
|
|
10239
|
+
*/
|
|
10240
|
+
export interface SuppressionInventoryEntry {
|
|
10241
|
+
/**
|
|
10242
|
+
* 1-based line of the suppression comment itself; 0 only if unknown.
|
|
10243
|
+
*/
|
|
10244
|
+
line: number
|
|
10245
|
+
/**
|
|
10246
|
+
* The suppressed issue kind in kebab-case (e.g. `"unused-export"`), or
|
|
10247
|
+
* `null` for a blanket marker that suppresses every kind on its target.
|
|
10248
|
+
* Human output renders the blanket case as the literal word "blanket";
|
|
10249
|
+
* the JSON contract deliberately keeps `null` so machine consumers
|
|
10250
|
+
* branch on `null` instead of a magic string.
|
|
10251
|
+
*/
|
|
10252
|
+
kind?: (string | null)
|
|
10253
|
+
level: SuppressionInventoryLevel
|
|
10254
|
+
origin: SuppressionInventoryOrigin
|
|
10255
|
+
/**
|
|
10256
|
+
* Human-authored reason after `--`; `null` when absent.
|
|
10257
|
+
*/
|
|
10258
|
+
reason?: (string | null)
|
|
10259
|
+
/**
|
|
10260
|
+
* Whether a human-authored reason is present.
|
|
10261
|
+
*/
|
|
10262
|
+
reason_present: boolean
|
|
10263
|
+
}
|
|
9812
10264
|
/**
|
|
9813
10265
|
* Single CodeClimate-compatible issue inside [`CodeClimateOutput`].
|
|
9814
10266
|
*/
|