slopbrick 0.41.0 → 0.43.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 +45 -55
- package/bin/slopbrick.js +23 -2
- package/dist/engine/worker.cjs +198 -40
- package/dist/engine/worker.js +198 -40
- package/dist/index.cjs +1792 -715
- package/dist/index.d.cts +141 -15
- package/dist/index.d.ts +141 -15
- package/dist/index.js +1740 -664
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -776,6 +776,101 @@ interface Rule<Context = unknown> {
|
|
|
776
776
|
create(context: RuleContext): Context;
|
|
777
777
|
analyze(context: Context, facts: ScanFacts): Issue[];
|
|
778
778
|
}
|
|
779
|
+
/**
|
|
780
|
+
* v0.42.0 (Sprint 3, task 3b.1): composite rule type. A composite
|
|
781
|
+
* fires when *at least `minMatch`* of its member `ruleIds` fire on the
|
|
782
|
+
* same file. Members are referenced by their existing `Rule.id`.
|
|
783
|
+
*
|
|
784
|
+
* Structurally parallel to `Rule<Context>` so the `RuleRegistry`
|
|
785
|
+
* treats it uniformly: same `create` + `analyze` lifecycle, same
|
|
786
|
+
* `defaultOff` opt-in semantics, same `severity` for reporter
|
|
787
|
+
* weighting. The engine wires composites after per-file `RuleRegistry`
|
|
788
|
+
* (see `engine/worker.ts` + task 3b.5).
|
|
789
|
+
*
|
|
790
|
+
* Design choice: `CompositeRule<Context>` is its own interface rather
|
|
791
|
+
* than a `Rule<Context>` variant because (a) it carries member-rule
|
|
792
|
+
* metadata (`ruleIds`, `minMatch`) that vanilla rules do not, and
|
|
793
|
+
* (b) the union of the two types would force every consumer to
|
|
794
|
+
* narrow, defeating the structural-parallelism goal.
|
|
795
|
+
*/
|
|
796
|
+
interface CompositeRule<Context = unknown> {
|
|
797
|
+
id: string;
|
|
798
|
+
category: Category;
|
|
799
|
+
severity: Severity;
|
|
800
|
+
aiSpecific: boolean;
|
|
801
|
+
/** Short description shown by `slopbrick rules`. */
|
|
802
|
+
description?: string;
|
|
803
|
+
/** v0.42.0: composite rules are opt-in by default. */
|
|
804
|
+
defaultOff?: boolean;
|
|
805
|
+
/** Member rule IDs (sorted, unique). The composite fires when
|
|
806
|
+
* at least `minMatch` of these fire on the same file. */
|
|
807
|
+
ruleIds: string[];
|
|
808
|
+
/** Minimum number of `ruleIds` that must fire together. */
|
|
809
|
+
minMatch: number;
|
|
810
|
+
create(context: RuleContext): Context;
|
|
811
|
+
analyze(context: Context, facts: ScanFacts): Issue[];
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* v0.42.0 (Sprint 3, task 3b.3): clusterer-emitted composite rule
|
|
815
|
+
* entry. The shape that `engine/cluster.ts` produces and that the
|
|
816
|
+
* `RuleRegistry` loader materializes into `CompositeRule<Context>`
|
|
817
|
+
* instances. Lives next to `CompositeRule<Context>` so the public
|
|
818
|
+
* type surface for empirical composites is in one place.
|
|
819
|
+
*
|
|
820
|
+
* Fields mirror the spec in `docs/superpowers/sprint-0.41-0.42.md`
|
|
821
|
+
* §3b STEP 5: id, ruleIds, minMatch, severity, defaultOff,
|
|
822
|
+
* description, calibration, provenance.
|
|
823
|
+
*/
|
|
824
|
+
interface CompositeRuleEntry {
|
|
825
|
+
id: string;
|
|
826
|
+
ruleIds: string[];
|
|
827
|
+
minMatch: number;
|
|
828
|
+
severity: Severity;
|
|
829
|
+
defaultOff: true;
|
|
830
|
+
description: string;
|
|
831
|
+
calibration: {
|
|
832
|
+
recall: number;
|
|
833
|
+
/** False-positive rate, FP / neg_count. */
|
|
834
|
+
FP: number;
|
|
835
|
+
precision: number;
|
|
836
|
+
F1: number;
|
|
837
|
+
nFiles: number;
|
|
838
|
+
};
|
|
839
|
+
provenance: {
|
|
840
|
+
seed: 'auto-cluster' | 'hand-curated-by-brief';
|
|
841
|
+
discoveredAt: string;
|
|
842
|
+
nFiles: number;
|
|
843
|
+
members: number;
|
|
844
|
+
/** Strongest NPMI edge among cluster members (0 if singleton). */
|
|
845
|
+
npmi: number;
|
|
846
|
+
/** Strongest-edge Fisher's p (1 if singleton). */
|
|
847
|
+
fisherP: number;
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* v0.42.0 (Sprint 3, task 3b.2): input to the empirical composite
|
|
852
|
+
* clusterer. `fireMatrix` is the per-file fired-rule-set map; the
|
|
853
|
+
* other fields are optional inputs to STEP 4 calibration.
|
|
854
|
+
*/
|
|
855
|
+
interface ClusterInput {
|
|
856
|
+
/** Per-file fired-rule-set map (file id → set of rule IDs that fired). */
|
|
857
|
+
fireMatrix: ReadonlyMap<string, ReadonlySet<string>>;
|
|
858
|
+
/** Positive (gold-standard) file IDs for recall/precision. */
|
|
859
|
+
positiveFiles?: ReadonlySet<string>;
|
|
860
|
+
/** Severity of each member rule; used to pick `severity = worst`. */
|
|
861
|
+
memberSeverities?: ReadonlyMap<string, Severity>;
|
|
862
|
+
/** Algorithm parameter overrides (all optional). */
|
|
863
|
+
params?: ClusterParamOverrides;
|
|
864
|
+
/** ISO timestamp embedded in `provenance.discoveredAt` for tests. */
|
|
865
|
+
now?: string;
|
|
866
|
+
}
|
|
867
|
+
type ClusterParams = {
|
|
868
|
+
minSupport: number;
|
|
869
|
+
minNPMI: number;
|
|
870
|
+
fisherAlpha: number;
|
|
871
|
+
minClusterSize: number;
|
|
872
|
+
};
|
|
873
|
+
type ClusterParamOverrides = Partial<ClusterParams>;
|
|
779
874
|
interface ResolvedConfig {
|
|
780
875
|
framework?: string;
|
|
781
876
|
hasTailwind?: boolean;
|
|
@@ -1060,9 +1155,8 @@ type AiDebt = 'low' | 'medium' | 'high' | 'critical';
|
|
|
1060
1155
|
declare const AI_SECURITY_NUMERIC: Record<'low' | 'medium' | 'high' | 'critical', number>;
|
|
1061
1156
|
/** Inputs to the pure `buildRepositoryHealth` function. Every input is optional. */
|
|
1062
1157
|
interface RepositoryHealthInputs {
|
|
1063
|
-
/** v0.
|
|
1064
|
-
*
|
|
1065
|
-
* going forward. */
|
|
1158
|
+
/** v0.21.0: 0-100, lower = better (raw amount of slop).
|
|
1159
|
+
* Replaces the v0.15-v0.20.1 inverted cleanliness reading. */
|
|
1066
1160
|
aiSlopScore?: number;
|
|
1067
1161
|
/** v0.15.0 U.4+: 0-100, higher = better. */
|
|
1068
1162
|
engineeringHygiene?: number;
|
|
@@ -1306,15 +1400,15 @@ interface ProjectReport {
|
|
|
1306
1400
|
generatedAt: string;
|
|
1307
1401
|
configPath?: string;
|
|
1308
1402
|
/**
|
|
1309
|
-
* v0.
|
|
1310
|
-
*
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1403
|
+
* v0.21.0: 0-100, **lower = better** (raw amount of slop).
|
|
1404
|
+
* The CI gate is `aiSlopScore <= meanSlop` (where meanSlop defaults
|
|
1405
|
+
* to 30). Higher values mean more AI-detection rules fired on this
|
|
1406
|
+
* codebase. The previous v0.15-v0.20.1 reading inverted this to
|
|
1407
|
+
* "cleanliness" (higher = better), which made the JSON output and
|
|
1408
|
+
* the CLI gate disagree. This field has been lower-is-better
|
|
1409
|
+
* since v0.21.0; the JSDoc that said "0-100, higher is better"
|
|
1410
|
+
* was a stale v0.15-era comment that survived past the inversion.
|
|
1411
|
+
* Fixed in v0.42.0.
|
|
1318
1412
|
*/
|
|
1319
1413
|
aiSlopScore: number;
|
|
1320
1414
|
engineeringHygiene: number;
|
|
@@ -1483,6 +1577,18 @@ interface ProjectReport {
|
|
|
1483
1577
|
p90Slop: number;
|
|
1484
1578
|
individualSlopThreshold: number;
|
|
1485
1579
|
};
|
|
1580
|
+
/**
|
|
1581
|
+
* v0.42.0 (user-review fix): names of thresholds that tripped in this
|
|
1582
|
+
* scan. Optional for backward compat with v0.41 and earlier reports.
|
|
1583
|
+
* Empty/undefined means all gates passed.
|
|
1584
|
+
*
|
|
1585
|
+
* Possible values: 'meanSlop', 'p90Slop', 'individualSlopThreshold',
|
|
1586
|
+
* 'category:<name>' (per-category thresholds).
|
|
1587
|
+
*
|
|
1588
|
+
* CI consumers can grep this field directly instead of parsing the
|
|
1589
|
+
* stderr message. See threshold.ts#failedThresholds for source.
|
|
1590
|
+
*/
|
|
1591
|
+
failedThresholds?: string[];
|
|
1486
1592
|
/** Research/flywheel snapshot — present when the flywheel directory has artifacts. */
|
|
1487
1593
|
research?: ResearchMetrics;
|
|
1488
1594
|
topOffenders?: TopOffender[];
|
|
@@ -1559,9 +1665,12 @@ interface ProjectReport {
|
|
|
1559
1665
|
/** v0.14.5i — Number of distinct rules marked defaultOff. The ratio
|
|
1560
1666
|
* suppressedCount / defaultOffRuleCount is the calibration coverage. */
|
|
1561
1667
|
defaultOffRuleCount?: number;
|
|
1562
|
-
/** v0.14.5j — The previous run's
|
|
1668
|
+
/** v0.14.5j — The previous run's value, if any. Used by
|
|
1563
1669
|
* formatPretty to render a "±N from last run" delta so the user
|
|
1564
|
-
* can see the trajectory without grep'ing the run log.
|
|
1670
|
+
* can see the trajectory without grep'ing the run log. The
|
|
1671
|
+
* name is kept as `previousSlopIndex` for backward compat with
|
|
1672
|
+
* telemetry consumers, but the value is the previous
|
|
1673
|
+
* aiSlopScore (since v0.21: lower = cleaner). */
|
|
1565
1674
|
previousSlopIndex?: number;
|
|
1566
1675
|
/** v0.14.5j — ISO timestamp of the previous run, paired with
|
|
1567
1676
|
* previousSlopIndex so the delta line can say "vs 2026-06-27". */
|
|
@@ -1612,6 +1721,13 @@ interface ScanProjectOptions {
|
|
|
1612
1721
|
noIncrease?: boolean;
|
|
1613
1722
|
cache?: boolean;
|
|
1614
1723
|
telemetry?: boolean;
|
|
1724
|
+
/** v0.42.0 (§3a.4): opt-in flag for the AGENTS.md auto-refresh hook.
|
|
1725
|
+
* When true, `slopbrick scan` writes the freshly-built snippet body
|
|
1726
|
+
* inside the `<!-- slopbrick:begin:v3 --> ... -->` block in
|
|
1727
|
+
* AGENTS.md / CLAUDE.md, replacing only that block (user-edited
|
|
1728
|
+
* content outside the markers is preserved). Default false so
|
|
1729
|
+
* first-time users aren't surprised. */
|
|
1730
|
+
autoRefreshSnippets?: boolean;
|
|
1615
1731
|
}
|
|
1616
1732
|
|
|
1617
1733
|
declare function scanProject(options: ScanProjectOptions): Promise<ProjectReport>;
|
|
@@ -1627,6 +1743,16 @@ declare function runCli({ start }: {
|
|
|
1627
1743
|
|
|
1628
1744
|
declare function thresholdExceeded(report: ProjectReport, config: ResolvedConfig): boolean;
|
|
1629
1745
|
declare function failedThresholdCount(report: ProjectReport, config: ResolvedConfig): number;
|
|
1746
|
+
/**
|
|
1747
|
+
* v0.42.0 (user-review fix): failedThresholdCount() returned just the
|
|
1748
|
+
* count. The CLI then printed "{n} threshold(s) failed. See details
|
|
1749
|
+
* above." — but in --brief the user sees only the headline CI gate
|
|
1750
|
+
* ("AI Slop Score <= 15 -> fail"), not the per-threshold list.
|
|
1751
|
+
*
|
|
1752
|
+
* This function returns the actual list of failed threshold names so
|
|
1753
|
+
* the caller can name them in the final error message.
|
|
1754
|
+
*/
|
|
1755
|
+
declare function failedThresholds(report: ProjectReport, config: ResolvedConfig): string[];
|
|
1630
1756
|
declare function baselineStatusMessage(baseline: BaselineMeta): string;
|
|
1631
1757
|
interface StagedGatingResult {
|
|
1632
1758
|
failed: boolean;
|
|
@@ -1674,4 +1800,4 @@ declare function formatBadge(report: ProjectReport): string;
|
|
|
1674
1800
|
/** Render an array of values as a Unicode sparkline (▁▂▃▄▅▆▇█). */
|
|
1675
1801
|
declare function formatSparkline(values: number[]): string;
|
|
1676
1802
|
|
|
1677
|
-
export { AI_SECURITY_NUMERIC, type AiDebt, type AiMaintenanceCost, type AiMaintenanceCostResult, type AstroComponentFact, type AutoRelaxedRule, type AutoTunedRule, type BaselineCache, type BaselineMeta, type CachedFile, type Category, type ClassNameFact, type CommentFact, type ComponentFacts, type ComponentScore, type ComponentSizeFact, type ConsoleCallFact, type Constitution, DEFAULT_CONFIG, type DangerouslySetInnerHtmlFact, type DbDriftLevel, type DbFinding, type DialogCallFact, type DisabledLintRuleFact, type DocDriftLevel, type DocFinding, type DomQueryFact, type ElementFact, type EvalCallFact, type ExplicitAnyFact, type FetchCallFact, type FileScanResult, type FixSuggestion, type FlywheelOutput, type FlywheelState, type Framework$1 as Framework, type HealthFile, type HookCallFact, type HookDependencyArrayFact, type HookFact, type ImportFact, type InlineEventHandlerFact, type Issue, type JsxAttributeStringLiteralFact, type JsxTextLiteralFact, type KeyPropFact, type LogicalExpressionFact, type MagicNumberSpacingConfig, type MaintenanceAxes, type MaintenanceAxisHealth, type NonNullAssertionFact, type OptimisticUpdateFact, type ProjectReport, type PropMutationFact, type PropPassThroughFact, REPOSITORY_HEALTH_WEIGHTS, type ReportReadResult, type RepositoryHealth, type RepositoryHealthInputs, type ResearchMetrics, type ResolvedConfig, type Rule, type RuleContext, type RuleSeverity, type RuleSuggestion, type ScanCache, type ScanFacts, type ScanProjectOptions, type ScanSelfScanConfig, type Severity, type SlopAuditRun, type StateBinding, type StateBindingFact, type StringLiteralFact, type StylePropFact, type TamaguiStylePropFact, type TopOffender, type UseEffectBodyFact, VERSION, baselineStatusMessage, colorForSlop, failedThresholdCount, filterByDisabledDirectives, filterIssues, formatBadge, formatReportFromFile, formatSparkline, loadConfig, readReportFile, runCli, runInitWizard, scanProject, serializeConfig, stagedGating, thresholdExceeded };
|
|
1803
|
+
export { AI_SECURITY_NUMERIC, type AiDebt, type AiMaintenanceCost, type AiMaintenanceCostResult, type AstroComponentFact, type AutoRelaxedRule, type AutoTunedRule, type BaselineCache, type BaselineMeta, type CachedFile, type Category, type ClassNameFact, type ClusterInput, type ClusterParamOverrides, type ClusterParams, type CommentFact, type ComponentFacts, type ComponentScore, type ComponentSizeFact, type CompositeRule, type CompositeRuleEntry, type ConsoleCallFact, type Constitution, DEFAULT_CONFIG, type DangerouslySetInnerHtmlFact, type DbDriftLevel, type DbFinding, type DialogCallFact, type DisabledLintRuleFact, type DocDriftLevel, type DocFinding, type DomQueryFact, type ElementFact, type EvalCallFact, type ExplicitAnyFact, type FetchCallFact, type FileScanResult, type FixSuggestion, type FlywheelOutput, type FlywheelState, type Framework$1 as Framework, type HealthFile, type HookCallFact, type HookDependencyArrayFact, type HookFact, type ImportFact, type InlineEventHandlerFact, type Issue, type JsxAttributeStringLiteralFact, type JsxTextLiteralFact, type KeyPropFact, type LogicalExpressionFact, type MagicNumberSpacingConfig, type MaintenanceAxes, type MaintenanceAxisHealth, type NonNullAssertionFact, type OptimisticUpdateFact, type ProjectReport, type PropMutationFact, type PropPassThroughFact, REPOSITORY_HEALTH_WEIGHTS, type ReportReadResult, type RepositoryHealth, type RepositoryHealthInputs, type ResearchMetrics, type ResolvedConfig, type Rule, type RuleContext, type RuleSeverity, type RuleSuggestion, type ScanCache, type ScanFacts, type ScanProjectOptions, type ScanSelfScanConfig, type Severity, type SlopAuditRun, type StateBinding, type StateBindingFact, type StringLiteralFact, type StylePropFact, type TamaguiStylePropFact, type TopOffender, type UseEffectBodyFact, VERSION, baselineStatusMessage, colorForSlop, failedThresholdCount, failedThresholds, filterByDisabledDirectives, filterIssues, formatBadge, formatReportFromFile, formatSparkline, loadConfig, readReportFile, runCli, runInitWizard, scanProject, serializeConfig, stagedGating, thresholdExceeded };
|
package/dist/index.d.ts
CHANGED
|
@@ -776,6 +776,101 @@ interface Rule<Context = unknown> {
|
|
|
776
776
|
create(context: RuleContext): Context;
|
|
777
777
|
analyze(context: Context, facts: ScanFacts): Issue[];
|
|
778
778
|
}
|
|
779
|
+
/**
|
|
780
|
+
* v0.42.0 (Sprint 3, task 3b.1): composite rule type. A composite
|
|
781
|
+
* fires when *at least `minMatch`* of its member `ruleIds` fire on the
|
|
782
|
+
* same file. Members are referenced by their existing `Rule.id`.
|
|
783
|
+
*
|
|
784
|
+
* Structurally parallel to `Rule<Context>` so the `RuleRegistry`
|
|
785
|
+
* treats it uniformly: same `create` + `analyze` lifecycle, same
|
|
786
|
+
* `defaultOff` opt-in semantics, same `severity` for reporter
|
|
787
|
+
* weighting. The engine wires composites after per-file `RuleRegistry`
|
|
788
|
+
* (see `engine/worker.ts` + task 3b.5).
|
|
789
|
+
*
|
|
790
|
+
* Design choice: `CompositeRule<Context>` is its own interface rather
|
|
791
|
+
* than a `Rule<Context>` variant because (a) it carries member-rule
|
|
792
|
+
* metadata (`ruleIds`, `minMatch`) that vanilla rules do not, and
|
|
793
|
+
* (b) the union of the two types would force every consumer to
|
|
794
|
+
* narrow, defeating the structural-parallelism goal.
|
|
795
|
+
*/
|
|
796
|
+
interface CompositeRule<Context = unknown> {
|
|
797
|
+
id: string;
|
|
798
|
+
category: Category;
|
|
799
|
+
severity: Severity;
|
|
800
|
+
aiSpecific: boolean;
|
|
801
|
+
/** Short description shown by `slopbrick rules`. */
|
|
802
|
+
description?: string;
|
|
803
|
+
/** v0.42.0: composite rules are opt-in by default. */
|
|
804
|
+
defaultOff?: boolean;
|
|
805
|
+
/** Member rule IDs (sorted, unique). The composite fires when
|
|
806
|
+
* at least `minMatch` of these fire on the same file. */
|
|
807
|
+
ruleIds: string[];
|
|
808
|
+
/** Minimum number of `ruleIds` that must fire together. */
|
|
809
|
+
minMatch: number;
|
|
810
|
+
create(context: RuleContext): Context;
|
|
811
|
+
analyze(context: Context, facts: ScanFacts): Issue[];
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* v0.42.0 (Sprint 3, task 3b.3): clusterer-emitted composite rule
|
|
815
|
+
* entry. The shape that `engine/cluster.ts` produces and that the
|
|
816
|
+
* `RuleRegistry` loader materializes into `CompositeRule<Context>`
|
|
817
|
+
* instances. Lives next to `CompositeRule<Context>` so the public
|
|
818
|
+
* type surface for empirical composites is in one place.
|
|
819
|
+
*
|
|
820
|
+
* Fields mirror the spec in `docs/superpowers/sprint-0.41-0.42.md`
|
|
821
|
+
* §3b STEP 5: id, ruleIds, minMatch, severity, defaultOff,
|
|
822
|
+
* description, calibration, provenance.
|
|
823
|
+
*/
|
|
824
|
+
interface CompositeRuleEntry {
|
|
825
|
+
id: string;
|
|
826
|
+
ruleIds: string[];
|
|
827
|
+
minMatch: number;
|
|
828
|
+
severity: Severity;
|
|
829
|
+
defaultOff: true;
|
|
830
|
+
description: string;
|
|
831
|
+
calibration: {
|
|
832
|
+
recall: number;
|
|
833
|
+
/** False-positive rate, FP / neg_count. */
|
|
834
|
+
FP: number;
|
|
835
|
+
precision: number;
|
|
836
|
+
F1: number;
|
|
837
|
+
nFiles: number;
|
|
838
|
+
};
|
|
839
|
+
provenance: {
|
|
840
|
+
seed: 'auto-cluster' | 'hand-curated-by-brief';
|
|
841
|
+
discoveredAt: string;
|
|
842
|
+
nFiles: number;
|
|
843
|
+
members: number;
|
|
844
|
+
/** Strongest NPMI edge among cluster members (0 if singleton). */
|
|
845
|
+
npmi: number;
|
|
846
|
+
/** Strongest-edge Fisher's p (1 if singleton). */
|
|
847
|
+
fisherP: number;
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* v0.42.0 (Sprint 3, task 3b.2): input to the empirical composite
|
|
852
|
+
* clusterer. `fireMatrix` is the per-file fired-rule-set map; the
|
|
853
|
+
* other fields are optional inputs to STEP 4 calibration.
|
|
854
|
+
*/
|
|
855
|
+
interface ClusterInput {
|
|
856
|
+
/** Per-file fired-rule-set map (file id → set of rule IDs that fired). */
|
|
857
|
+
fireMatrix: ReadonlyMap<string, ReadonlySet<string>>;
|
|
858
|
+
/** Positive (gold-standard) file IDs for recall/precision. */
|
|
859
|
+
positiveFiles?: ReadonlySet<string>;
|
|
860
|
+
/** Severity of each member rule; used to pick `severity = worst`. */
|
|
861
|
+
memberSeverities?: ReadonlyMap<string, Severity>;
|
|
862
|
+
/** Algorithm parameter overrides (all optional). */
|
|
863
|
+
params?: ClusterParamOverrides;
|
|
864
|
+
/** ISO timestamp embedded in `provenance.discoveredAt` for tests. */
|
|
865
|
+
now?: string;
|
|
866
|
+
}
|
|
867
|
+
type ClusterParams = {
|
|
868
|
+
minSupport: number;
|
|
869
|
+
minNPMI: number;
|
|
870
|
+
fisherAlpha: number;
|
|
871
|
+
minClusterSize: number;
|
|
872
|
+
};
|
|
873
|
+
type ClusterParamOverrides = Partial<ClusterParams>;
|
|
779
874
|
interface ResolvedConfig {
|
|
780
875
|
framework?: string;
|
|
781
876
|
hasTailwind?: boolean;
|
|
@@ -1060,9 +1155,8 @@ type AiDebt = 'low' | 'medium' | 'high' | 'critical';
|
|
|
1060
1155
|
declare const AI_SECURITY_NUMERIC: Record<'low' | 'medium' | 'high' | 'critical', number>;
|
|
1061
1156
|
/** Inputs to the pure `buildRepositoryHealth` function. Every input is optional. */
|
|
1062
1157
|
interface RepositoryHealthInputs {
|
|
1063
|
-
/** v0.
|
|
1064
|
-
*
|
|
1065
|
-
* going forward. */
|
|
1158
|
+
/** v0.21.0: 0-100, lower = better (raw amount of slop).
|
|
1159
|
+
* Replaces the v0.15-v0.20.1 inverted cleanliness reading. */
|
|
1066
1160
|
aiSlopScore?: number;
|
|
1067
1161
|
/** v0.15.0 U.4+: 0-100, higher = better. */
|
|
1068
1162
|
engineeringHygiene?: number;
|
|
@@ -1306,15 +1400,15 @@ interface ProjectReport {
|
|
|
1306
1400
|
generatedAt: string;
|
|
1307
1401
|
configPath?: string;
|
|
1308
1402
|
/**
|
|
1309
|
-
* v0.
|
|
1310
|
-
*
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1403
|
+
* v0.21.0: 0-100, **lower = better** (raw amount of slop).
|
|
1404
|
+
* The CI gate is `aiSlopScore <= meanSlop` (where meanSlop defaults
|
|
1405
|
+
* to 30). Higher values mean more AI-detection rules fired on this
|
|
1406
|
+
* codebase. The previous v0.15-v0.20.1 reading inverted this to
|
|
1407
|
+
* "cleanliness" (higher = better), which made the JSON output and
|
|
1408
|
+
* the CLI gate disagree. This field has been lower-is-better
|
|
1409
|
+
* since v0.21.0; the JSDoc that said "0-100, higher is better"
|
|
1410
|
+
* was a stale v0.15-era comment that survived past the inversion.
|
|
1411
|
+
* Fixed in v0.42.0.
|
|
1318
1412
|
*/
|
|
1319
1413
|
aiSlopScore: number;
|
|
1320
1414
|
engineeringHygiene: number;
|
|
@@ -1483,6 +1577,18 @@ interface ProjectReport {
|
|
|
1483
1577
|
p90Slop: number;
|
|
1484
1578
|
individualSlopThreshold: number;
|
|
1485
1579
|
};
|
|
1580
|
+
/**
|
|
1581
|
+
* v0.42.0 (user-review fix): names of thresholds that tripped in this
|
|
1582
|
+
* scan. Optional for backward compat with v0.41 and earlier reports.
|
|
1583
|
+
* Empty/undefined means all gates passed.
|
|
1584
|
+
*
|
|
1585
|
+
* Possible values: 'meanSlop', 'p90Slop', 'individualSlopThreshold',
|
|
1586
|
+
* 'category:<name>' (per-category thresholds).
|
|
1587
|
+
*
|
|
1588
|
+
* CI consumers can grep this field directly instead of parsing the
|
|
1589
|
+
* stderr message. See threshold.ts#failedThresholds for source.
|
|
1590
|
+
*/
|
|
1591
|
+
failedThresholds?: string[];
|
|
1486
1592
|
/** Research/flywheel snapshot — present when the flywheel directory has artifacts. */
|
|
1487
1593
|
research?: ResearchMetrics;
|
|
1488
1594
|
topOffenders?: TopOffender[];
|
|
@@ -1559,9 +1665,12 @@ interface ProjectReport {
|
|
|
1559
1665
|
/** v0.14.5i — Number of distinct rules marked defaultOff. The ratio
|
|
1560
1666
|
* suppressedCount / defaultOffRuleCount is the calibration coverage. */
|
|
1561
1667
|
defaultOffRuleCount?: number;
|
|
1562
|
-
/** v0.14.5j — The previous run's
|
|
1668
|
+
/** v0.14.5j — The previous run's value, if any. Used by
|
|
1563
1669
|
* formatPretty to render a "±N from last run" delta so the user
|
|
1564
|
-
* can see the trajectory without grep'ing the run log.
|
|
1670
|
+
* can see the trajectory without grep'ing the run log. The
|
|
1671
|
+
* name is kept as `previousSlopIndex` for backward compat with
|
|
1672
|
+
* telemetry consumers, but the value is the previous
|
|
1673
|
+
* aiSlopScore (since v0.21: lower = cleaner). */
|
|
1565
1674
|
previousSlopIndex?: number;
|
|
1566
1675
|
/** v0.14.5j — ISO timestamp of the previous run, paired with
|
|
1567
1676
|
* previousSlopIndex so the delta line can say "vs 2026-06-27". */
|
|
@@ -1612,6 +1721,13 @@ interface ScanProjectOptions {
|
|
|
1612
1721
|
noIncrease?: boolean;
|
|
1613
1722
|
cache?: boolean;
|
|
1614
1723
|
telemetry?: boolean;
|
|
1724
|
+
/** v0.42.0 (§3a.4): opt-in flag for the AGENTS.md auto-refresh hook.
|
|
1725
|
+
* When true, `slopbrick scan` writes the freshly-built snippet body
|
|
1726
|
+
* inside the `<!-- slopbrick:begin:v3 --> ... -->` block in
|
|
1727
|
+
* AGENTS.md / CLAUDE.md, replacing only that block (user-edited
|
|
1728
|
+
* content outside the markers is preserved). Default false so
|
|
1729
|
+
* first-time users aren't surprised. */
|
|
1730
|
+
autoRefreshSnippets?: boolean;
|
|
1615
1731
|
}
|
|
1616
1732
|
|
|
1617
1733
|
declare function scanProject(options: ScanProjectOptions): Promise<ProjectReport>;
|
|
@@ -1627,6 +1743,16 @@ declare function runCli({ start }: {
|
|
|
1627
1743
|
|
|
1628
1744
|
declare function thresholdExceeded(report: ProjectReport, config: ResolvedConfig): boolean;
|
|
1629
1745
|
declare function failedThresholdCount(report: ProjectReport, config: ResolvedConfig): number;
|
|
1746
|
+
/**
|
|
1747
|
+
* v0.42.0 (user-review fix): failedThresholdCount() returned just the
|
|
1748
|
+
* count. The CLI then printed "{n} threshold(s) failed. See details
|
|
1749
|
+
* above." — but in --brief the user sees only the headline CI gate
|
|
1750
|
+
* ("AI Slop Score <= 15 -> fail"), not the per-threshold list.
|
|
1751
|
+
*
|
|
1752
|
+
* This function returns the actual list of failed threshold names so
|
|
1753
|
+
* the caller can name them in the final error message.
|
|
1754
|
+
*/
|
|
1755
|
+
declare function failedThresholds(report: ProjectReport, config: ResolvedConfig): string[];
|
|
1630
1756
|
declare function baselineStatusMessage(baseline: BaselineMeta): string;
|
|
1631
1757
|
interface StagedGatingResult {
|
|
1632
1758
|
failed: boolean;
|
|
@@ -1674,4 +1800,4 @@ declare function formatBadge(report: ProjectReport): string;
|
|
|
1674
1800
|
/** Render an array of values as a Unicode sparkline (▁▂▃▄▅▆▇█). */
|
|
1675
1801
|
declare function formatSparkline(values: number[]): string;
|
|
1676
1802
|
|
|
1677
|
-
export { AI_SECURITY_NUMERIC, type AiDebt, type AiMaintenanceCost, type AiMaintenanceCostResult, type AstroComponentFact, type AutoRelaxedRule, type AutoTunedRule, type BaselineCache, type BaselineMeta, type CachedFile, type Category, type ClassNameFact, type CommentFact, type ComponentFacts, type ComponentScore, type ComponentSizeFact, type ConsoleCallFact, type Constitution, DEFAULT_CONFIG, type DangerouslySetInnerHtmlFact, type DbDriftLevel, type DbFinding, type DialogCallFact, type DisabledLintRuleFact, type DocDriftLevel, type DocFinding, type DomQueryFact, type ElementFact, type EvalCallFact, type ExplicitAnyFact, type FetchCallFact, type FileScanResult, type FixSuggestion, type FlywheelOutput, type FlywheelState, type Framework$1 as Framework, type HealthFile, type HookCallFact, type HookDependencyArrayFact, type HookFact, type ImportFact, type InlineEventHandlerFact, type Issue, type JsxAttributeStringLiteralFact, type JsxTextLiteralFact, type KeyPropFact, type LogicalExpressionFact, type MagicNumberSpacingConfig, type MaintenanceAxes, type MaintenanceAxisHealth, type NonNullAssertionFact, type OptimisticUpdateFact, type ProjectReport, type PropMutationFact, type PropPassThroughFact, REPOSITORY_HEALTH_WEIGHTS, type ReportReadResult, type RepositoryHealth, type RepositoryHealthInputs, type ResearchMetrics, type ResolvedConfig, type Rule, type RuleContext, type RuleSeverity, type RuleSuggestion, type ScanCache, type ScanFacts, type ScanProjectOptions, type ScanSelfScanConfig, type Severity, type SlopAuditRun, type StateBinding, type StateBindingFact, type StringLiteralFact, type StylePropFact, type TamaguiStylePropFact, type TopOffender, type UseEffectBodyFact, VERSION, baselineStatusMessage, colorForSlop, failedThresholdCount, filterByDisabledDirectives, filterIssues, formatBadge, formatReportFromFile, formatSparkline, loadConfig, readReportFile, runCli, runInitWizard, scanProject, serializeConfig, stagedGating, thresholdExceeded };
|
|
1803
|
+
export { AI_SECURITY_NUMERIC, type AiDebt, type AiMaintenanceCost, type AiMaintenanceCostResult, type AstroComponentFact, type AutoRelaxedRule, type AutoTunedRule, type BaselineCache, type BaselineMeta, type CachedFile, type Category, type ClassNameFact, type ClusterInput, type ClusterParamOverrides, type ClusterParams, type CommentFact, type ComponentFacts, type ComponentScore, type ComponentSizeFact, type CompositeRule, type CompositeRuleEntry, type ConsoleCallFact, type Constitution, DEFAULT_CONFIG, type DangerouslySetInnerHtmlFact, type DbDriftLevel, type DbFinding, type DialogCallFact, type DisabledLintRuleFact, type DocDriftLevel, type DocFinding, type DomQueryFact, type ElementFact, type EvalCallFact, type ExplicitAnyFact, type FetchCallFact, type FileScanResult, type FixSuggestion, type FlywheelOutput, type FlywheelState, type Framework$1 as Framework, type HealthFile, type HookCallFact, type HookDependencyArrayFact, type HookFact, type ImportFact, type InlineEventHandlerFact, type Issue, type JsxAttributeStringLiteralFact, type JsxTextLiteralFact, type KeyPropFact, type LogicalExpressionFact, type MagicNumberSpacingConfig, type MaintenanceAxes, type MaintenanceAxisHealth, type NonNullAssertionFact, type OptimisticUpdateFact, type ProjectReport, type PropMutationFact, type PropPassThroughFact, REPOSITORY_HEALTH_WEIGHTS, type ReportReadResult, type RepositoryHealth, type RepositoryHealthInputs, type ResearchMetrics, type ResolvedConfig, type Rule, type RuleContext, type RuleSeverity, type RuleSuggestion, type ScanCache, type ScanFacts, type ScanProjectOptions, type ScanSelfScanConfig, type Severity, type SlopAuditRun, type StateBinding, type StateBindingFact, type StringLiteralFact, type StylePropFact, type TamaguiStylePropFact, type TopOffender, type UseEffectBodyFact, VERSION, baselineStatusMessage, colorForSlop, failedThresholdCount, failedThresholds, filterByDisabledDirectives, filterIssues, formatBadge, formatReportFromFile, formatSparkline, loadConfig, readReportFile, runCli, runInitWizard, scanProject, serializeConfig, stagedGating, thresholdExceeded };
|