@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/README.md +432 -404
- package/dist/cli/index.js +5617 -2747
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +302 -85
- package/dist/index.js +3565 -1448
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
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
|
|
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<["
|
|
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: "
|
|
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: "
|
|
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<["
|
|
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: ("
|
|
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?: ("
|
|
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<["
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
|
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
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
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
|
-
*
|
|
963
|
-
|
|
964
|
-
|
|
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
|
-
|
|
977
|
-
|
|
978
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 };
|