@shakecodeslikecray/whiterose 0.2.6 → 1.0.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/dist/index.d.ts CHANGED
@@ -2,7 +2,9 @@ import { z } from 'zod';
2
2
 
3
3
  declare const BugSeverity: z.ZodEnum<["critical", "high", "medium", "low"]>;
4
4
  type BugSeverity = z.infer<typeof BugSeverity>;
5
- declare const BugCategory: z.ZodEnum<["logic-error", "security", "async-race-condition", "edge-case", "null-reference", "type-coercion", "resource-leak", "intent-violation"]>;
5
+ declare const FindingKind: z.ZodEnum<["bug", "smell"]>;
6
+ type FindingKind = z.infer<typeof FindingKind>;
7
+ declare const BugCategory: z.ZodEnum<["injection", "auth-bypass", "secrets-exposure", "null-reference", "boundary-error", "resource-leak", "async-issue", "logic-error", "data-validation", "type-coercion", "concurrency", "intent-violation"]>;
6
8
  type BugCategory = z.infer<typeof BugCategory>;
7
9
  declare const ConfidenceLevel: z.ZodEnum<["high", "medium", "low"]>;
8
10
  type ConfidenceLevel = z.infer<typeof ConfidenceLevel>;
@@ -49,6 +51,8 @@ declare const CodePathStep: z.ZodObject<{
49
51
  explanation: string;
50
52
  }>;
51
53
  type CodePathStep = z.infer<typeof CodePathStep>;
54
+ declare const BugStatus: z.ZodEnum<["open", "fixed", "false-positive", "wont-fix"]>;
55
+ type BugStatus = z.infer<typeof BugStatus>;
52
56
  declare const Bug: z.ZodObject<{
53
57
  id: z.ZodString;
54
58
  title: z.ZodString;
@@ -56,8 +60,9 @@ declare const Bug: z.ZodObject<{
56
60
  file: z.ZodString;
57
61
  line: z.ZodNumber;
58
62
  endLine: z.ZodOptional<z.ZodNumber>;
63
+ kind: z.ZodDefault<z.ZodEnum<["bug", "smell"]>>;
59
64
  severity: z.ZodEnum<["critical", "high", "medium", "low"]>;
60
- category: z.ZodEnum<["logic-error", "security", "async-race-condition", "edge-case", "null-reference", "type-coercion", "resource-leak", "intent-violation"]>;
65
+ category: z.ZodEnum<["injection", "auth-bypass", "secrets-exposure", "null-reference", "boundary-error", "resource-leak", "async-issue", "logic-error", "data-validation", "type-coercion", "concurrency", "intent-violation"]>;
61
66
  confidence: z.ZodObject<{
62
67
  overall: z.ZodEnum<["high", "medium", "low"]>;
63
68
  codePathValidity: z.ZodNumber;
@@ -104,14 +109,20 @@ declare const Bug: z.ZodObject<{
104
109
  relatedContract: z.ZodOptional<z.ZodString>;
105
110
  staticAnalysisSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
106
111
  createdAt: z.ZodString;
112
+ status: z.ZodDefault<z.ZodEnum<["open", "fixed", "false-positive", "wont-fix"]>>;
113
+ fixedAt: z.ZodOptional<z.ZodString>;
114
+ fixCommit: z.ZodOptional<z.ZodString>;
115
+ passName: z.ZodOptional<z.ZodString>;
107
116
  }, "strip", z.ZodTypeAny, {
117
+ status: "open" | "fixed" | "false-positive" | "wont-fix";
108
118
  file: string;
109
119
  line: number;
110
120
  id: string;
111
121
  title: string;
112
122
  description: string;
123
+ kind: "bug" | "smell";
113
124
  severity: "critical" | "high" | "medium" | "low";
114
- category: "logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation";
125
+ category: "injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation";
115
126
  confidence: {
116
127
  overall: "high" | "medium" | "low";
117
128
  codePathValidity: number;
@@ -133,6 +144,9 @@ declare const Bug: z.ZodObject<{
133
144
  suggestedFix?: string | undefined;
134
145
  relatedContract?: string | undefined;
135
146
  staticAnalysisSignals?: string[] | undefined;
147
+ fixedAt?: string | undefined;
148
+ fixCommit?: string | undefined;
149
+ passName?: string | undefined;
136
150
  }, {
137
151
  file: string;
138
152
  line: number;
@@ -140,7 +154,7 @@ declare const Bug: z.ZodObject<{
140
154
  title: string;
141
155
  description: string;
142
156
  severity: "critical" | "high" | "medium" | "low";
143
- category: "logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation";
157
+ category: "injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation";
144
158
  confidence: {
145
159
  overall: "high" | "medium" | "low";
146
160
  codePathValidity: number;
@@ -158,10 +172,15 @@ declare const Bug: z.ZodObject<{
158
172
  }[];
159
173
  evidence: string[];
160
174
  createdAt: string;
175
+ status?: "open" | "fixed" | "false-positive" | "wont-fix" | undefined;
161
176
  endLine?: number | undefined;
177
+ kind?: "bug" | "smell" | undefined;
162
178
  suggestedFix?: string | undefined;
163
179
  relatedContract?: string | undefined;
164
180
  staticAnalysisSignals?: string[] | undefined;
181
+ fixedAt?: string | undefined;
182
+ fixCommit?: string | undefined;
183
+ passName?: string | undefined;
165
184
  }>;
166
185
  type Bug = z.infer<typeof Bug>;
167
186
  declare const ProviderType: z.ZodEnum<["claude-code", "aider", "codex", "opencode", "ollama", "gemini"]>;
@@ -231,7 +250,7 @@ declare const WhiteroseConfig: z.ZodObject<{
231
250
  include: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
232
251
  exclude: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
233
252
  priorities: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<["critical", "high", "medium", "low", "ignore"]>>>;
234
- categories: z.ZodDefault<z.ZodArray<z.ZodEnum<["logic-error", "security", "async-race-condition", "edge-case", "null-reference", "type-coercion", "resource-leak", "intent-violation"]>, "many">>;
253
+ categories: z.ZodDefault<z.ZodArray<z.ZodEnum<["injection", "auth-bypass", "secrets-exposure", "null-reference", "boundary-error", "resource-leak", "async-issue", "logic-error", "data-validation", "type-coercion", "concurrency", "intent-violation"]>, "many">>;
235
254
  minConfidence: z.ZodDefault<z.ZodEnum<["high", "medium", "low"]>>;
236
255
  monorepo: z.ZodOptional<z.ZodObject<{
237
256
  detection: z.ZodEnum<["auto", "explicit"]>;
@@ -303,7 +322,7 @@ declare const WhiteroseConfig: z.ZodObject<{
303
322
  version: string;
304
323
  provider: "claude-code" | "aider" | "codex" | "opencode" | "ollama" | "gemini";
305
324
  priorities: Record<string, "critical" | "high" | "medium" | "low" | "ignore">;
306
- categories: ("logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation")[];
325
+ categories: ("injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation")[];
307
326
  minConfidence: "high" | "medium" | "low";
308
327
  staticAnalysis: {
309
328
  typescript: boolean;
@@ -333,7 +352,7 @@ declare const WhiteroseConfig: z.ZodObject<{
333
352
  provider?: "claude-code" | "aider" | "codex" | "opencode" | "ollama" | "gemini" | undefined;
334
353
  providerFallback?: ("claude-code" | "aider" | "codex" | "opencode" | "ollama" | "gemini")[] | undefined;
335
354
  priorities?: Record<string, "critical" | "high" | "medium" | "low" | "ignore"> | undefined;
336
- categories?: ("logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation")[] | undefined;
355
+ categories?: ("injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation")[] | undefined;
337
356
  minConfidence?: "high" | "medium" | "low" | undefined;
338
357
  monorepo?: {
339
358
  detection: "auto" | "explicit";
@@ -679,12 +698,6 @@ declare const CacheState: z.ZodObject<{
679
698
  lastIncrementalScan?: string | undefined;
680
699
  }>;
681
700
  type CacheState = z.infer<typeof CacheState>;
682
- interface AnalysisContext {
683
- files: string[];
684
- understanding: CodebaseUnderstanding;
685
- config: WhiteroseConfig;
686
- staticAnalysisResults: StaticAnalysisResult[];
687
- }
688
701
  interface StaticAnalysisResult {
689
702
  tool: 'typescript' | 'eslint';
690
703
  file: string;
@@ -693,14 +706,6 @@ interface StaticAnalysisResult {
693
706
  severity: 'error' | 'warning' | 'info';
694
707
  code?: string;
695
708
  }
696
- interface LLMProvider {
697
- name: ProviderType;
698
- detect(): Promise<boolean>;
699
- isAvailable(): Promise<boolean>;
700
- analyze(context: AnalysisContext): Promise<Bug[]>;
701
- adversarialValidate(bug: Bug, context: AnalysisContext): Promise<AdversarialResult>;
702
- generateUnderstanding(files: string[], existingDocsSummary?: string): Promise<CodebaseUnderstanding>;
703
- }
704
709
  interface AdversarialResult {
705
710
  survived: boolean;
706
711
  counterArguments: string[];
@@ -720,8 +725,9 @@ declare const ScanResult: z.ZodObject<{
720
725
  file: z.ZodString;
721
726
  line: z.ZodNumber;
722
727
  endLine: z.ZodOptional<z.ZodNumber>;
728
+ kind: z.ZodDefault<z.ZodEnum<["bug", "smell"]>>;
723
729
  severity: z.ZodEnum<["critical", "high", "medium", "low"]>;
724
- category: z.ZodEnum<["logic-error", "security", "async-race-condition", "edge-case", "null-reference", "type-coercion", "resource-leak", "intent-violation"]>;
730
+ category: z.ZodEnum<["injection", "auth-bypass", "secrets-exposure", "null-reference", "boundary-error", "resource-leak", "async-issue", "logic-error", "data-validation", "type-coercion", "concurrency", "intent-violation"]>;
725
731
  confidence: z.ZodObject<{
726
732
  overall: z.ZodEnum<["high", "medium", "low"]>;
727
733
  codePathValidity: z.ZodNumber;
@@ -768,14 +774,20 @@ declare const ScanResult: z.ZodObject<{
768
774
  relatedContract: z.ZodOptional<z.ZodString>;
769
775
  staticAnalysisSignals: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
770
776
  createdAt: z.ZodString;
777
+ status: z.ZodDefault<z.ZodEnum<["open", "fixed", "false-positive", "wont-fix"]>>;
778
+ fixedAt: z.ZodOptional<z.ZodString>;
779
+ fixCommit: z.ZodOptional<z.ZodString>;
780
+ passName: z.ZodOptional<z.ZodString>;
771
781
  }, "strip", z.ZodTypeAny, {
782
+ status: "open" | "fixed" | "false-positive" | "wont-fix";
772
783
  file: string;
773
784
  line: number;
774
785
  id: string;
775
786
  title: string;
776
787
  description: string;
788
+ kind: "bug" | "smell";
777
789
  severity: "critical" | "high" | "medium" | "low";
778
- category: "logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation";
790
+ category: "injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation";
779
791
  confidence: {
780
792
  overall: "high" | "medium" | "low";
781
793
  codePathValidity: number;
@@ -797,6 +809,9 @@ declare const ScanResult: z.ZodObject<{
797
809
  suggestedFix?: string | undefined;
798
810
  relatedContract?: string | undefined;
799
811
  staticAnalysisSignals?: string[] | undefined;
812
+ fixedAt?: string | undefined;
813
+ fixCommit?: string | undefined;
814
+ passName?: string | undefined;
800
815
  }, {
801
816
  file: string;
802
817
  line: number;
@@ -804,7 +819,7 @@ declare const ScanResult: z.ZodObject<{
804
819
  title: string;
805
820
  description: string;
806
821
  severity: "critical" | "high" | "medium" | "low";
807
- category: "logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation";
822
+ category: "injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation";
808
823
  confidence: {
809
824
  overall: "high" | "medium" | "low";
810
825
  codePathValidity: number;
@@ -822,10 +837,15 @@ declare const ScanResult: z.ZodObject<{
822
837
  }[];
823
838
  evidence: string[];
824
839
  createdAt: string;
840
+ status?: "open" | "fixed" | "false-positive" | "wont-fix" | undefined;
825
841
  endLine?: number | undefined;
842
+ kind?: "bug" | "smell" | undefined;
826
843
  suggestedFix?: string | undefined;
827
844
  relatedContract?: string | undefined;
828
845
  staticAnalysisSignals?: string[] | undefined;
846
+ fixedAt?: string | undefined;
847
+ fixCommit?: string | undefined;
848
+ passName?: string | undefined;
829
849
  }>, "many">;
830
850
  summary: z.ZodObject<{
831
851
  critical: z.ZodNumber;
@@ -833,18 +853,24 @@ declare const ScanResult: z.ZodObject<{
833
853
  medium: z.ZodNumber;
834
854
  low: z.ZodNumber;
835
855
  total: z.ZodNumber;
856
+ bugs: z.ZodNumber;
857
+ smells: z.ZodNumber;
836
858
  }, "strip", z.ZodTypeAny, {
837
859
  critical: number;
838
860
  high: number;
839
861
  medium: number;
840
862
  low: number;
863
+ bugs: number;
841
864
  total: number;
865
+ smells: number;
842
866
  }, {
843
867
  critical: number;
844
868
  high: number;
845
869
  medium: number;
846
870
  low: number;
871
+ bugs: number;
847
872
  total: number;
873
+ smells: number;
848
874
  }>;
849
875
  }, "strip", z.ZodTypeAny, {
850
876
  id: string;
@@ -853,20 +879,24 @@ declare const ScanResult: z.ZodObject<{
853
879
  high: number;
854
880
  medium: number;
855
881
  low: number;
882
+ bugs: number;
856
883
  total: number;
884
+ smells: number;
857
885
  };
858
886
  duration: number;
859
887
  timestamp: string;
860
888
  scanType: "full" | "incremental";
861
889
  filesScanned: number;
862
890
  bugs: {
891
+ status: "open" | "fixed" | "false-positive" | "wont-fix";
863
892
  file: string;
864
893
  line: number;
865
894
  id: string;
866
895
  title: string;
867
896
  description: string;
897
+ kind: "bug" | "smell";
868
898
  severity: "critical" | "high" | "medium" | "low";
869
- category: "logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation";
899
+ category: "injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation";
870
900
  confidence: {
871
901
  overall: "high" | "medium" | "low";
872
902
  codePathValidity: number;
@@ -888,6 +918,9 @@ declare const ScanResult: z.ZodObject<{
888
918
  suggestedFix?: string | undefined;
889
919
  relatedContract?: string | undefined;
890
920
  staticAnalysisSignals?: string[] | undefined;
921
+ fixedAt?: string | undefined;
922
+ fixCommit?: string | undefined;
923
+ passName?: string | undefined;
891
924
  }[];
892
925
  filesChanged?: number | undefined;
893
926
  }, {
@@ -897,7 +930,9 @@ declare const ScanResult: z.ZodObject<{
897
930
  high: number;
898
931
  medium: number;
899
932
  low: number;
933
+ bugs: number;
900
934
  total: number;
935
+ smells: number;
901
936
  };
902
937
  duration: number;
903
938
  timestamp: string;
@@ -910,7 +945,7 @@ declare const ScanResult: z.ZodObject<{
910
945
  title: string;
911
946
  description: string;
912
947
  severity: "critical" | "high" | "medium" | "low";
913
- category: "logic-error" | "security" | "async-race-condition" | "edge-case" | "null-reference" | "type-coercion" | "resource-leak" | "intent-violation";
948
+ category: "injection" | "auth-bypass" | "secrets-exposure" | "null-reference" | "boundary-error" | "resource-leak" | "async-issue" | "logic-error" | "data-validation" | "type-coercion" | "concurrency" | "intent-violation";
914
949
  confidence: {
915
950
  overall: "high" | "medium" | "low";
916
951
  codePathValidity: number;
@@ -928,10 +963,15 @@ declare const ScanResult: z.ZodObject<{
928
963
  }[];
929
964
  evidence: string[];
930
965
  createdAt: string;
966
+ status?: "open" | "fixed" | "false-positive" | "wont-fix" | undefined;
931
967
  endLine?: number | undefined;
968
+ kind?: "bug" | "smell" | undefined;
932
969
  suggestedFix?: string | undefined;
933
970
  relatedContract?: string | undefined;
934
971
  staticAnalysisSignals?: string[] | undefined;
972
+ fixedAt?: string | undefined;
973
+ fixCommit?: string | undefined;
974
+ passName?: string | undefined;
935
975
  }[];
936
976
  filesChanged?: number | undefined;
937
977
  }>;
@@ -942,83 +982,148 @@ declare function loadUnderstanding(cwd: string): Promise<CodebaseUnderstanding |
942
982
  declare function saveConfig(cwd: string, config: WhiteroseConfig): Promise<void>;
943
983
 
944
984
  declare function scanCodebase(cwd: string, config?: WhiteroseConfig): Promise<string[]>;
945
- declare function getChangedFiles(cwd: string, config: WhiteroseConfig): Promise<{
985
+ declare function getChangedFiles(cwd: string, config: WhiteroseConfig, options?: {
986
+ writeCache?: boolean;
987
+ }): Promise<{
946
988
  files: string[];
947
989
  hashes: FileHash[];
990
+ state: CacheState;
948
991
  }>;
949
992
  declare function getDependentFiles(changedFiles: string[], cwd: string, allFiles?: string[]): Promise<string[]>;
950
993
 
951
- type ProgressCallback = (message: string) => void;
952
- type BugFoundCallback = (bug: Bug) => void;
953
- declare class ClaudeCodeProvider implements LLMProvider {
954
- name: ProviderType;
955
- private progressCallback?;
956
- private bugFoundCallback?;
957
- private currentProcess?;
958
- private unsafeMode;
959
- detect(): Promise<boolean>;
994
+ /**
995
+ * Core Scanner - LSP-Compliant Architecture
996
+ *
997
+ * Scanning logic lives HERE, not in providers.
998
+ * Providers are just "dumb prompt executors".
999
+ *
1000
+ * This ensures all providers get the same 19-pass scanning,
1001
+ * batching, deduplication, and merging logic.
1002
+ */
1003
+
1004
+ interface PromptOptions {
1005
+ cwd: string;
1006
+ timeout?: number;
1007
+ }
1008
+ interface PromptResult {
1009
+ output: string;
1010
+ error?: string;
1011
+ }
1012
+ /**
1013
+ * Minimal interface that ALL providers must implement.
1014
+ * No scanning logic - just execute prompts and return results.
1015
+ */
1016
+ interface PromptExecutor {
1017
+ name: string;
960
1018
  isAvailable(): Promise<boolean>;
1019
+ runPrompt(prompt: string, options: PromptOptions): Promise<PromptResult>;
1020
+ }
1021
+ interface ScannerConfig {
1022
+ batchSize: number;
1023
+ batchDelayMs: number;
1024
+ passTimeoutMs: number;
1025
+ }
1026
+ interface StaticFinding {
1027
+ tool: string;
1028
+ file: string;
1029
+ line: number;
1030
+ message: string;
1031
+ severity: string;
1032
+ }
1033
+ interface ScanContext {
1034
+ files: string[];
1035
+ understanding: CodebaseUnderstanding;
1036
+ staticResults: StaticFinding[];
1037
+ config?: WhiteroseConfig;
1038
+ }
1039
+ interface ScanProgress {
1040
+ onPhaseStart?: (phase: string, passCount: number) => void;
1041
+ onPassStart?: (passName: string) => void;
1042
+ onPassComplete?: (passName: string, bugCount: number) => void;
1043
+ onPassError?: (passName: string, error: string) => void;
1044
+ onBugFound?: (bug: Bug) => void;
1045
+ onProgress?: (message: string) => void;
1046
+ }
1047
+ declare class CoreScanner {
1048
+ private executor;
1049
+ private config;
1050
+ private progress;
1051
+ constructor(executor: PromptExecutor, config?: Partial<ScannerConfig>, progress?: ScanProgress);
1052
+ /**
1053
+ * Run a thorough 19-pass scan with findings flowing through pipeline:
1054
+ *
1055
+ * Static Analysis → Unit Passes → Integration Passes → E2E Passes
1056
+ * ↓ ↓ ↓
1057
+ * unitFindings → integrationFindings → e2eFindings
1058
+ * └──────────────┴─────────────────┘
1059
+ * ↓
1060
+ * Combined + Deduped
1061
+ */
1062
+ scan(context: ScanContext): Promise<Bug[]>;
961
1063
  /**
962
- * Enable unsafe mode (--dangerously-skip-permissions).
963
- * WARNING: This bypasses Claude's permission prompts and should only be used
964
- * when you trust the codebase being analyzed.
1064
+ * Run a batch of passes in parallel (within a phase)
1065
+ */
1066
+ private runPassBatch;
1067
+ /**
1068
+ * Run a quick single-pass scan
1069
+ */
1070
+ quickScan(context: ScanContext): Promise<Bug[]>;
1071
+ /**
1072
+ * Generate codebase understanding (for init/refresh commands)
1073
+ * Uses the LLM to analyze project structure and extract features
965
1074
  */
966
- setUnsafeMode(enabled: boolean): void;
967
- isUnsafeMode(): boolean;
968
- setProgressCallback(callback: ProgressCallback): void;
969
- setBugFoundCallback(callback: BugFoundCallback): void;
970
- private reportProgress;
971
- private reportBug;
972
- cancel(): void;
973
- analyze(context: AnalysisContext): Promise<Bug[]>;
974
- adversarialValidate(bug: Bug, _context: AnalysisContext): Promise<AdversarialResult>;
975
1075
  generateUnderstanding(files: string[], existingDocsSummary?: string): Promise<CodebaseUnderstanding>;
976
- private buildAgenticAnalysisPrompt;
977
- private buildAgenticUnderstandingPrompt;
978
- private buildAdversarialPrompt;
979
- private runAgenticClaude;
980
- private processAgentOutput;
981
- private streamBuffer;
982
- private fullResponseBuffer;
983
- private processTextContent;
984
- private tryExtractUnderstandingJson;
985
- private tryExtractBugsJson;
986
- private runSimpleClaude;
987
- private parseBugData;
988
- private parseAdversarialResponse;
989
- private parseUnderstandingResponse;
990
- private extractJson;
991
- private findBalancedJson;
992
- }
993
-
994
- declare class AiderProvider implements LLMProvider {
995
- name: ProviderType;
996
- detect(): Promise<boolean>;
997
- isAvailable(): Promise<boolean>;
998
- analyze(context: AnalysisContext): Promise<Bug[]>;
999
- adversarialValidate(bug: Bug, _context: AnalysisContext): Promise<AdversarialResult>;
1000
- generateUnderstanding(files: string[], _existingDocsSummary?: string): Promise<CodebaseUnderstanding>;
1001
- private readFilesWithLimit;
1002
- private prioritizeFiles;
1003
- private buildAnalysisPrompt;
1004
- private buildAdversarialPrompt;
1005
- private buildUnderstandingPrompt;
1006
- private runAider;
1007
- private parseAnalysisResponse;
1008
- private parseAdversarialResponse;
1076
+ /**
1077
+ * Parse understanding response from LLM
1078
+ */
1009
1079
  private parseUnderstandingResponse;
1010
- private extractJson;
1080
+ private parseFeaturePriority;
1081
+ /**
1082
+ * Build unit pass jobs - these only see static analysis results
1083
+ */
1084
+ private buildUnitPassJobs;
1085
+ /**
1086
+ * Build integration pass jobs - these see static + unit findings
1087
+ */
1088
+ private buildIntegrationPassJobs;
1089
+ /**
1090
+ * Build E2E pass jobs - these see static + unit + integration findings
1091
+ */
1092
+ private buildE2EPassJobs;
1093
+ private buildQuickScanPrompt;
1094
+ private parseResponse;
1095
+ private parseBugData;
1096
+ private deduplicateBugs;
1097
+ private mergeSimilarBugs;
1098
+ private report;
1099
+ private delay;
1011
1100
  private parseSeverity;
1012
1101
  private parseCategory;
1013
1102
  private parseConfidence;
1103
+ private confidenceToNum;
1104
+ private severityToNum;
1014
1105
  }
1015
1106
 
1016
- declare function getProvider(name: ProviderType): Promise<LLMProvider>;
1107
+ /**
1108
+ * Provider Executors - Simple prompt execution implementations
1109
+ *
1110
+ * All executors implement the PromptExecutor interface.
1111
+ * No scanning logic - just run prompts and return results.
1112
+ */
1113
+
1114
+ /**
1115
+ * Get a prompt executor by provider name
1116
+ */
1117
+ declare function getExecutor(name: ProviderType): PromptExecutor;
1118
+ /**
1119
+ * Get all available executors
1120
+ */
1121
+ declare function getAvailableExecutors(): Promise<PromptExecutor[]>;
1017
1122
 
1018
1123
  declare function detectProvider(): Promise<ProviderType[]>;
1019
1124
  declare function isProviderAvailable(name: ProviderType): Promise<boolean>;
1020
1125
 
1021
- declare function runStaticAnalysis(cwd: string, files: string[], config: WhiteroseConfig): Promise<StaticAnalysisResult[]>;
1126
+ declare function runStaticAnalysis(cwd: string, files: string[], config?: WhiteroseConfig): Promise<StaticAnalysisResult[]>;
1022
1127
 
1023
1128
  interface SarifResult {
1024
1129
  $schema: string;
@@ -1050,6 +1155,7 @@ interface SarifRule {
1050
1155
  };
1051
1156
  properties: {
1052
1157
  category: string;
1158
+ kind?: string;
1053
1159
  };
1054
1160
  }
1055
1161
  interface SarifResultItem {
@@ -1061,6 +1167,7 @@ interface SarifResultItem {
1061
1167
  };
1062
1168
  locations: SarifLocation[];
1063
1169
  codeFlows?: SarifCodeFlow[];
1170
+ properties?: Record<string, any>;
1064
1171
  }
1065
1172
  interface SarifLocation {
1066
1173
  physicalLocation: {
@@ -1112,7 +1219,21 @@ interface FixResult {
1112
1219
  diff?: string;
1113
1220
  error?: string;
1114
1221
  branchName?: string;
1222
+ commitHash?: string;
1223
+ falsePositive?: boolean;
1224
+ falsePositiveReason?: string;
1115
1225
  }
1226
+ /**
1227
+ * Apply a fix to a bug using an agentic approach.
1228
+ *
1229
+ * Instead of generating a fix and applying it ourselves, we give the bug
1230
+ * details to the LLM provider and let it explore the code and fix it directly.
1231
+ * This produces much better fixes because the LLM can:
1232
+ * - Read related files for context
1233
+ * - Understand the codebase architecture
1234
+ * - Make multi-file changes if needed
1235
+ * - Verify the fix makes sense
1236
+ */
1116
1237
  declare function applyFix(bug: Bug, config: WhiteroseConfig, options: FixOptions): Promise<FixResult>;
1117
1238
  declare function batchFix(bugs: Bug[], config: WhiteroseConfig, options: FixOptions): Promise<Map<string, FixResult>>;
1118
1239
 
@@ -1191,4 +1312,100 @@ declare function groupFilesByPackage(files: string[], packages: Package[]): Map<
1191
1312
  */
1192
1313
  declare function getCrossPackageDependencies(packages: Package[]): Promise<Map<string, string[]>>;
1193
1314
 
1194
- export { type AdversarialResult, AiderProvider, type AnalysisContext, BehavioralContract, Bug, BugCategory, BugSeverity, CacheState, ClaudeCodeProvider, CodePathStep, CodebaseUnderstanding, ConfidenceLevel, ConfidenceScore, FeatureIntent, FileHash, type GitStatus, type LLMProvider, MonorepoConfig, type MonorepoInfo, type Package, PackageConfig, PriorityLevel, ProviderType, ScanResult, type StaticAnalysisResult, WhiteroseConfig, applyFix, batchFix, buildDependencyGraph, commitFix, createFixBranch, dependsOn, detectMonorepo, detectProvider, findCircularDependencies, generateIntentDocument, getChangedFiles, getCrossPackageDependencies, getCurrentBranch, getDependentFiles, getDiff, getFileAtHead, getGitStatus, getImportsOf, getPackageFiles, getPackageForFile, getProvider, getStagedDiff, groupFilesByPackage, hasUncommittedChanges, isGitRepo, isProviderAvailable, loadConfig, loadUnderstanding, mergeIntentWithUnderstanding, outputMarkdown, outputSarif, parseIntentDocument, popStash, resetFile, runStaticAnalysis, saveConfig, scanCodebase, stashChanges };
1315
+ /**
1316
+ * Cross-File Analyzer
1317
+ *
1318
+ * Detects bugs that span multiple files/commands:
1319
+ * - Incomplete features (scan writes to A,B,C but clear only clears A)
1320
+ * - State mismatches (command X expects state that command Y doesn't set)
1321
+ * - Orphaned operations (writes without corresponding cleanup)
1322
+ *
1323
+ * This catches bugs that single-file analysis misses.
1324
+ */
1325
+
1326
+ /**
1327
+ * Run cross-file analysis and return bugs
1328
+ */
1329
+ declare function analyzeCrossFile(cwd: string): Promise<Bug[]>;
1330
+ /**
1331
+ * Get summary of command effects for debugging
1332
+ */
1333
+ declare function getCommandEffectsSummary(cwd: string): Promise<string>;
1334
+
1335
+ /**
1336
+ * Contract Analyzer
1337
+ *
1338
+ * Detects bugs related to:
1339
+ * - Missing error recovery (write without rollback on failure)
1340
+ * - Missing validation (parse without verify)
1341
+ * - Missing post-conditions (fix without verify it works)
1342
+ * - Transaction atomicity violations (multi-step operations that can fail partially)
1343
+ *
1344
+ * This extends the cross-file analyzer to catch behavioral bugs.
1345
+ */
1346
+
1347
+ /**
1348
+ * Run contract analysis and return bugs
1349
+ */
1350
+ declare function analyzeContracts(cwd: string): Promise<Bug[]>;
1351
+ /**
1352
+ * Get summary of contract violations for debugging
1353
+ */
1354
+ declare function getContractSummary(cwd: string): Promise<string>;
1355
+
1356
+ /**
1357
+ * Code Smells Analyzer
1358
+ *
1359
+ * Detects patterns that indicate poor code quality and are PROBABLE CAUSES for future bugs.
1360
+ * These are NOT bugs themselves, but maintainability issues that increase bug risk.
1361
+ *
1362
+ * Categories based on Martin Fowler's Refactoring catalog + TypeScript-specific patterns:
1363
+ *
1364
+ * 1. BLOATERS - Code that grows too large
1365
+ * - Long Method, Large Class, Long Parameter List, Data Clumps
1366
+ *
1367
+ * 2. OBJECT-ORIENTATION ABUSERS
1368
+ * - Switch Statements, Temporary Field, Refused Bequest
1369
+ *
1370
+ * 3. CHANGE PREVENTERS - Make changes ripple through codebase
1371
+ * - Divergent Change, Shotgun Surgery, Parallel Inheritance
1372
+ *
1373
+ * 4. DISPENSABLES - Unnecessary elements
1374
+ * - Dead Code, Duplicate Code, Speculative Generality, Comments as Deodorant
1375
+ *
1376
+ * 5. COUPLERS - Excessive interdependence
1377
+ * - Feature Envy, Message Chains, Middle Man
1378
+ *
1379
+ * 6. TYPESCRIPT-SPECIFIC
1380
+ * - Excessive 'any', 'as' assertions, Missing error handling
1381
+ *
1382
+ * 7. MAGIC VALUES
1383
+ * - Hardcoded constants, Magic numbers/strings
1384
+ *
1385
+ * Sources:
1386
+ * - https://refactoring.guru/refactoring/smells
1387
+ * - https://ducin.dev/typescript-anti-patterns
1388
+ * - https://www.mdpi.com/2078-2489/9/11/273
1389
+ */
1390
+ interface CodeSmell {
1391
+ type: SmellCategory;
1392
+ name: string;
1393
+ title: string;
1394
+ description: string;
1395
+ file: string;
1396
+ line: number;
1397
+ evidence: string[];
1398
+ impact: 'high' | 'medium' | 'low';
1399
+ refactoring: string;
1400
+ }
1401
+ type SmellCategory = 'bloater' | 'oo-abuser' | 'change-preventer' | 'dispensable' | 'coupler' | 'typescript-smell' | 'magic-value';
1402
+ /**
1403
+ * Run code smells analysis and return findings
1404
+ */
1405
+ declare function analyzeSmells(cwd: string): Promise<CodeSmell[]>;
1406
+ /**
1407
+ * Get summary of code smells for reporting
1408
+ */
1409
+ declare function getSmellsSummary(cwd: string): Promise<string>;
1410
+
1411
+ export { type AdversarialResult, BehavioralContract, Bug, BugCategory, BugSeverity, BugStatus, CacheState, CodePathStep, CodebaseUnderstanding, ConfidenceLevel, ConfidenceScore, CoreScanner, FeatureIntent, FileHash, FindingKind, type GitStatus, MonorepoConfig, type MonorepoInfo, type Package, PackageConfig, PriorityLevel, type PromptExecutor, type PromptOptions, type PromptResult, ProviderType, ScanResult, type StaticAnalysisResult, WhiteroseConfig, analyzeContracts, analyzeCrossFile, analyzeSmells, applyFix, batchFix, buildDependencyGraph, commitFix, createFixBranch, dependsOn, detectMonorepo, detectProvider, findCircularDependencies, generateIntentDocument, getAvailableExecutors, getChangedFiles, getCommandEffectsSummary, getContractSummary, getCrossPackageDependencies, getCurrentBranch, getDependentFiles, getDiff, getExecutor, getFileAtHead, getGitStatus, getImportsOf, getPackageFiles, getPackageForFile, getSmellsSummary, getStagedDiff, groupFilesByPackage, hasUncommittedChanges, isGitRepo, isProviderAvailable, loadConfig, loadUnderstanding, mergeIntentWithUnderstanding, outputMarkdown, outputSarif, parseIntentDocument, popStash, resetFile, runStaticAnalysis, saveConfig, scanCodebase, stashChanges };