@lbroth/rothunter 1.0.0-rc.1
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/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/adapters/llm.d.ts +68 -0
- package/dist/adapters/llm.d.ts.map +1 -0
- package/dist/adapters/llm.js +189 -0
- package/dist/adapters/llm.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +81 -0
- package/dist/config.js.map +1 -0
- package/dist/detector-registry.d.ts +32 -0
- package/dist/detector-registry.d.ts.map +1 -0
- package/dist/detector-registry.js +74 -0
- package/dist/detector-registry.js.map +1 -0
- package/dist/detectors/api-race.d.ts +6 -0
- package/dist/detectors/api-race.d.ts.map +1 -0
- package/dist/detectors/api-race.js +222 -0
- package/dist/detectors/api-race.js.map +1 -0
- package/dist/detectors/bad-config.d.ts +6 -0
- package/dist/detectors/bad-config.d.ts.map +1 -0
- package/dist/detectors/bad-config.js +529 -0
- package/dist/detectors/bad-config.js.map +1 -0
- package/dist/detectors/console-log-prod.d.ts +6 -0
- package/dist/detectors/console-log-prod.d.ts.map +1 -0
- package/dist/detectors/console-log-prod.js +72 -0
- package/dist/detectors/console-log-prod.js.map +1 -0
- package/dist/detectors/dead-api.d.ts +10 -0
- package/dist/detectors/dead-api.d.ts.map +1 -0
- package/dist/detectors/dead-api.js +115 -0
- package/dist/detectors/dead-api.js.map +1 -0
- package/dist/detectors/dead-export.d.ts +12 -0
- package/dist/detectors/dead-export.d.ts.map +1 -0
- package/dist/detectors/dead-export.js +140 -0
- package/dist/detectors/dead-export.js.map +1 -0
- package/dist/detectors/dead-handler.d.ts +12 -0
- package/dist/detectors/dead-handler.d.ts.map +1 -0
- package/dist/detectors/dead-handler.js +40 -0
- package/dist/detectors/dead-handler.js.map +1 -0
- package/dist/detectors/dead-module.d.ts +14 -0
- package/dist/detectors/dead-module.d.ts.map +1 -0
- package/dist/detectors/dead-module.js +50 -0
- package/dist/detectors/dead-module.js.map +1 -0
- package/dist/detectors/deep-nesting.d.ts +12 -0
- package/dist/detectors/deep-nesting.d.ts.map +1 -0
- package/dist/detectors/deep-nesting.js +133 -0
- package/dist/detectors/deep-nesting.js.map +1 -0
- package/dist/detectors/duplicate-function.d.ts +9 -0
- package/dist/detectors/duplicate-function.d.ts.map +1 -0
- package/dist/detectors/duplicate-function.js +199 -0
- package/dist/detectors/duplicate-function.js.map +1 -0
- package/dist/detectors/duplicate-type.d.ts +9 -0
- package/dist/detectors/duplicate-type.d.ts.map +1 -0
- package/dist/detectors/duplicate-type.js +166 -0
- package/dist/detectors/duplicate-type.js.map +1 -0
- package/dist/detectors/hot-hub-file.d.ts +11 -0
- package/dist/detectors/hot-hub-file.d.ts.map +1 -0
- package/dist/detectors/hot-hub-file.js +42 -0
- package/dist/detectors/hot-hub-file.js.map +1 -0
- package/dist/detectors/long-file.d.ts +12 -0
- package/dist/detectors/long-file.d.ts.map +1 -0
- package/dist/detectors/long-file.js +82 -0
- package/dist/detectors/long-file.js.map +1 -0
- package/dist/detectors/long-function.d.ts +12 -0
- package/dist/detectors/long-function.d.ts.map +1 -0
- package/dist/detectors/long-function.js +45 -0
- package/dist/detectors/long-function.js.map +1 -0
- package/dist/detectors/magic-numbers.d.ts +10 -0
- package/dist/detectors/magic-numbers.d.ts.map +1 -0
- package/dist/detectors/magic-numbers.js +332 -0
- package/dist/detectors/magic-numbers.js.map +1 -0
- package/dist/detectors/mutable-globals.d.ts +6 -0
- package/dist/detectors/mutable-globals.d.ts.map +1 -0
- package/dist/detectors/mutable-globals.js +95 -0
- package/dist/detectors/mutable-globals.js.map +1 -0
- package/dist/detectors/mutation.d.ts +11 -0
- package/dist/detectors/mutation.d.ts.map +1 -0
- package/dist/detectors/mutation.js +397 -0
- package/dist/detectors/mutation.js.map +1 -0
- package/dist/detectors/public-any.d.ts +6 -0
- package/dist/detectors/public-any.d.ts.map +1 -0
- package/dist/detectors/public-any.js +52 -0
- package/dist/detectors/public-any.js.map +1 -0
- package/dist/detectors/race-condition.d.ts +6 -0
- package/dist/detectors/race-condition.d.ts.map +1 -0
- package/dist/detectors/race-condition.js +608 -0
- package/dist/detectors/race-condition.js.map +1 -0
- package/dist/detectors/shared-db-write.d.ts +6 -0
- package/dist/detectors/shared-db-write.d.ts.map +1 -0
- package/dist/detectors/shared-db-write.js +656 -0
- package/dist/detectors/shared-db-write.js.map +1 -0
- package/dist/detectors/silent-catch.d.ts +6 -0
- package/dist/detectors/silent-catch.d.ts.map +1 -0
- package/dist/detectors/silent-catch.js +167 -0
- package/dist/detectors/silent-catch.js.map +1 -0
- package/dist/detectors/similar-functions.d.ts +15 -0
- package/dist/detectors/similar-functions.d.ts.map +1 -0
- package/dist/detectors/similar-functions.js +334 -0
- package/dist/detectors/similar-functions.js.map +1 -0
- package/dist/detectors/skip-tests.d.ts +6 -0
- package/dist/detectors/skip-tests.d.ts.map +1 -0
- package/dist/detectors/skip-tests.js +69 -0
- package/dist/detectors/skip-tests.js.map +1 -0
- package/dist/detectors/todo-comments.d.ts +29 -0
- package/dist/detectors/todo-comments.d.ts.map +1 -0
- package/dist/detectors/todo-comments.js +154 -0
- package/dist/detectors/todo-comments.js.map +1 -0
- package/dist/detectors/unused-deps.d.ts +8 -0
- package/dist/detectors/unused-deps.d.ts.map +1 -0
- package/dist/detectors/unused-deps.js +115 -0
- package/dist/detectors/unused-deps.js.map +1 -0
- package/dist/extraction/api-race-confirmer.d.ts +31 -0
- package/dist/extraction/api-race-confirmer.d.ts.map +1 -0
- package/dist/extraction/api-race-confirmer.js +110 -0
- package/dist/extraction/api-race-confirmer.js.map +1 -0
- package/dist/extraction/llm-confirmer.d.ts +25 -0
- package/dist/extraction/llm-confirmer.d.ts.map +1 -0
- package/dist/extraction/llm-confirmer.js +118 -0
- package/dist/extraction/llm-confirmer.js.map +1 -0
- package/dist/extraction/mutation-confirmer.d.ts +30 -0
- package/dist/extraction/mutation-confirmer.d.ts.map +1 -0
- package/dist/extraction/mutation-confirmer.js +73 -0
- package/dist/extraction/mutation-confirmer.js.map +1 -0
- package/dist/extraction/prompt-chunking.d.ts +37 -0
- package/dist/extraction/prompt-chunking.d.ts.map +1 -0
- package/dist/extraction/prompt-chunking.js +61 -0
- package/dist/extraction/prompt-chunking.js.map +1 -0
- package/dist/extraction/race-confirmer.d.ts +28 -0
- package/dist/extraction/race-confirmer.d.ts.map +1 -0
- package/dist/extraction/race-confirmer.js +68 -0
- package/dist/extraction/race-confirmer.js.map +1 -0
- package/dist/extraction/shared-db-write-confirmer.d.ts +31 -0
- package/dist/extraction/shared-db-write-confirmer.d.ts.map +1 -0
- package/dist/extraction/shared-db-write-confirmer.js +141 -0
- package/dist/extraction/shared-db-write-confirmer.js.map +1 -0
- package/dist/extraction/triage-confirmer.d.ts +59 -0
- package/dist/extraction/triage-confirmer.d.ts.map +1 -0
- package/dist/extraction/triage-confirmer.js +104 -0
- package/dist/extraction/triage-confirmer.js.map +1 -0
- package/dist/graph/cfg.d.ts +45 -0
- package/dist/graph/cfg.d.ts.map +1 -0
- package/dist/graph/cfg.js +198 -0
- package/dist/graph/cfg.js.map +1 -0
- package/dist/graph/decorator-entries.d.ts +2 -0
- package/dist/graph/decorator-entries.d.ts.map +1 -0
- package/dist/graph/decorator-entries.js +89 -0
- package/dist/graph/decorator-entries.js.map +1 -0
- package/dist/graph/entry-points.d.ts +12 -0
- package/dist/graph/entry-points.d.ts.map +1 -0
- package/dist/graph/entry-points.js +282 -0
- package/dist/graph/entry-points.js.map +1 -0
- package/dist/graph/handler-conventions.d.ts +2 -0
- package/dist/graph/handler-conventions.d.ts.map +1 -0
- package/dist/graph/handler-conventions.js +26 -0
- package/dist/graph/handler-conventions.js.map +1 -0
- package/dist/graph/iac-entries.d.ts +2 -0
- package/dist/graph/iac-entries.d.ts.map +1 -0
- package/dist/graph/iac-entries.js +123 -0
- package/dist/graph/iac-entries.js.map +1 -0
- package/dist/graph/import-graph.d.ts +48 -0
- package/dist/graph/import-graph.d.ts.map +1 -0
- package/dist/graph/import-graph.js +86 -0
- package/dist/graph/import-graph.js.map +1 -0
- package/dist/graph/monorepo-detect.d.ts +3 -0
- package/dist/graph/monorepo-detect.d.ts.map +1 -0
- package/dist/graph/monorepo-detect.js +166 -0
- package/dist/graph/monorepo-detect.js.map +1 -0
- package/dist/graph/tsconfig-paths.d.ts +23 -0
- package/dist/graph/tsconfig-paths.d.ts.map +1 -0
- package/dist/graph/tsconfig-paths.js +217 -0
- package/dist/graph/tsconfig-paths.js.map +1 -0
- package/dist/multi-workspace-scanner.d.ts +13 -0
- package/dist/multi-workspace-scanner.d.ts.map +1 -0
- package/dist/multi-workspace-scanner.js +130 -0
- package/dist/multi-workspace-scanner.js.map +1 -0
- package/dist/normalizers/type-normalizer.d.ts +16 -0
- package/dist/normalizers/type-normalizer.d.ts.map +1 -0
- package/dist/normalizers/type-normalizer.js +189 -0
- package/dist/normalizers/type-normalizer.js.map +1 -0
- package/dist/parsers/typescript-parser.d.ts +57 -0
- package/dist/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/parsers/typescript-parser.js +502 -0
- package/dist/parsers/typescript-parser.js.map +1 -0
- package/dist/reporter/json-reporter.d.ts +12 -0
- package/dist/reporter/json-reporter.d.ts.map +1 -0
- package/dist/reporter/json-reporter.js +28 -0
- package/dist/reporter/json-reporter.js.map +1 -0
- package/dist/reporter/markdown-reporter.d.ts +11 -0
- package/dist/reporter/markdown-reporter.d.ts.map +1 -0
- package/dist/reporter/markdown-reporter.js +77 -0
- package/dist/reporter/markdown-reporter.js.map +1 -0
- package/dist/rothunter.d.ts +125 -0
- package/dist/rothunter.d.ts.map +1 -0
- package/dist/rothunter.js +1038 -0
- package/dist/rothunter.js.map +1 -0
- package/dist/server/false-positives.d.ts +34 -0
- package/dist/server/false-positives.d.ts.map +1 -0
- package/dist/server/false-positives.js +85 -0
- package/dist/server/false-positives.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1529 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/marked-to-fix.d.ts +16 -0
- package/dist/server/marked-to-fix.d.ts.map +1 -0
- package/dist/server/marked-to-fix.js +36 -0
- package/dist/server/marked-to-fix.js.map +1 -0
- package/dist/server/scan-store.d.ts +147 -0
- package/dist/server/scan-store.d.ts.map +1 -0
- package/dist/server/scan-store.js +291 -0
- package/dist/server/scan-store.js.map +1 -0
- package/dist/server/settings-store.d.ts +28 -0
- package/dist/server/settings-store.d.ts.map +1 -0
- package/dist/server/settings-store.js +46 -0
- package/dist/server/settings-store.js.map +1 -0
- package/dist/server/workspace-store.d.ts +39 -0
- package/dist/server/workspace-store.d.ts.map +1 -0
- package/dist/server/workspace-store.js +108 -0
- package/dist/server/workspace-store.js.map +1 -0
- package/dist/types/detector-input.d.ts +37 -0
- package/dist/types/detector-input.d.ts.map +1 -0
- package/dist/types/detector-input.js +2 -0
- package/dist/types/detector-input.js.map +1 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/clustering.d.ts +14 -0
- package/dist/utils/clustering.d.ts.map +1 -0
- package/dist/utils/clustering.js +56 -0
- package/dist/utils/clustering.js.map +1 -0
- package/dist/utils/gitignore.d.ts +32 -0
- package/dist/utils/gitignore.d.ts.map +1 -0
- package/dist/utils/gitignore.js +122 -0
- package/dist/utils/gitignore.js.map +1 -0
- package/dist/utils/hash.d.ts +11 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +14 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/ignore-annotation.d.ts +28 -0
- package/dist/utils/ignore-annotation.d.ts.map +1 -0
- package/dist/utils/ignore-annotation.js +46 -0
- package/dist/utils/ignore-annotation.js.map +1 -0
- package/dist/utils/llm-json.d.ts +2 -0
- package/dist/utils/llm-json.d.ts.map +1 -0
- package/dist/utils/llm-json.js +53 -0
- package/dist/utils/llm-json.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +4 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/project-conventions.d.ts +2 -0
- package/dist/utils/project-conventions.d.ts.map +1 -0
- package/dist/utils/project-conventions.js +108 -0
- package/dist/utils/project-conventions.js.map +1 -0
- package/dist/utils/regex.d.ts +9 -0
- package/dist/utils/regex.d.ts.map +1 -0
- package/dist/utils/regex.js +11 -0
- package/dist/utils/regex.js.map +1 -0
- package/dist/utils/snippet.d.ts +20 -0
- package/dist/utils/snippet.d.ts.map +1 -0
- package/dist/utils/snippet.js +28 -0
- package/dist/utils/snippet.js.map +1 -0
- package/dist/utils/source-reader.d.ts +19 -0
- package/dist/utils/source-reader.d.ts.map +1 -0
- package/dist/utils/source-reader.js +32 -0
- package/dist/utils/source-reader.js.map +1 -0
- package/logo.png +0 -0
- package/package.json +92 -0
- package/scripts/start-llm.mjs +161 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-store.js","sourceRoot":"","sources":["../../src/server/scan-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-server app settings — survive restarts via ~/.rothunter/settings.json.
|
|
3
|
+
* The Settings page in the dashboard edits this; scan start picks defaults
|
|
4
|
+
* from here when the request body omits them.
|
|
5
|
+
*/
|
|
6
|
+
export interface AppSettings {
|
|
7
|
+
detectors: Record<string, boolean>;
|
|
8
|
+
minConfidence: number;
|
|
9
|
+
/**
|
|
10
|
+
* Number of LLM verdict requests in flight at once. 1 = sequential
|
|
11
|
+
* (original behaviour). 4-8 is a good default on llama.cpp run with
|
|
12
|
+
* `--parallel N -cb` (continuous batching), or on vLLM where dynamic
|
|
13
|
+
* batching is on by default.
|
|
14
|
+
*/
|
|
15
|
+
llmConcurrency: number;
|
|
16
|
+
/**
|
|
17
|
+
* Confidence floor at which a negative LLM verdict routes a finding
|
|
18
|
+
* to the auto-FP bucket. `0.6` keeps almost every LLM "intentional"
|
|
19
|
+
* call out of the open list; `0.85` is strict (only very-confident
|
|
20
|
+
* verdicts auto-FP); `1` effectively disables auto-FP routing. The
|
|
21
|
+
* Findings UI shows the LLM reason on every routed entry so the
|
|
22
|
+
* operator can un-mark with one click if a verdict was wrong.
|
|
23
|
+
*/
|
|
24
|
+
llmAutoFpThreshold: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function readSettings(): AppSettings;
|
|
27
|
+
export declare function writeSettings(s: AppSettings): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=settings-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-store.d.ts","sourceRoot":"","sources":["../../src/server/settings-store.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAeD,wBAAgB,YAAY,IAAI,WAAW,CAsB1C;AAED,wBAAsB,aAAa,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
5
|
+
import { CONFIG_DIR } from './workspace-store.js';
|
|
6
|
+
import { DETECTOR_IDS } from '../detector-registry.js';
|
|
7
|
+
const SETTINGS_FILE = path.join(CONFIG_DIR, 'settings.json');
|
|
8
|
+
function defaultSettings() {
|
|
9
|
+
const detectors = {};
|
|
10
|
+
for (const id of DETECTOR_IDS)
|
|
11
|
+
detectors[id] = true;
|
|
12
|
+
// Auto-tune LLM concurrency: default to half the CPU cores, clamped
|
|
13
|
+
// to [1, 8]. Most laptops land at 4 — a sane balance between local
|
|
14
|
+
// llama.cpp throughput and OS responsiveness during a scan.
|
|
15
|
+
const cores = Math.max(1, os.cpus().length);
|
|
16
|
+
const auto = Math.max(1, Math.min(8, Math.floor(cores / 2)));
|
|
17
|
+
return { detectors, minConfidence: 0.6, llmConcurrency: auto, llmAutoFpThreshold: 0.6 };
|
|
18
|
+
}
|
|
19
|
+
export function readSettings() {
|
|
20
|
+
try {
|
|
21
|
+
if (!existsSync(SETTINGS_FILE))
|
|
22
|
+
return defaultSettings();
|
|
23
|
+
const raw = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
24
|
+
const base = defaultSettings();
|
|
25
|
+
return {
|
|
26
|
+
detectors: { ...base.detectors, ...(raw.detectors ?? {}) },
|
|
27
|
+
minConfidence: typeof raw.minConfidence === 'number' ? raw.minConfidence : base.minConfidence,
|
|
28
|
+
llmConcurrency: typeof raw.llmConcurrency === 'number' && raw.llmConcurrency >= 1
|
|
29
|
+
? Math.min(16, Math.floor(raw.llmConcurrency))
|
|
30
|
+
: base.llmConcurrency,
|
|
31
|
+
llmAutoFpThreshold: typeof raw.llmAutoFpThreshold === 'number' &&
|
|
32
|
+
raw.llmAutoFpThreshold >= 0 &&
|
|
33
|
+
raw.llmAutoFpThreshold <= 1
|
|
34
|
+
? raw.llmAutoFpThreshold
|
|
35
|
+
: base.llmAutoFpThreshold,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return defaultSettings();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function writeSettings(s) {
|
|
43
|
+
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
44
|
+
await fs.writeFile(SETTINGS_FILE, JSON.stringify(s, null, 2), 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=settings-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-store.js","sourceRoot":"","sources":["../../src/server/settings-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AA4BvD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AAE7D,SAAS,eAAe;IACtB,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,EAAE,IAAI,YAAY;QAAE,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IACpD,oEAAoE;IACpE,mEAAmE;IACnE,4DAA4D;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,OAAO,eAAe,EAAE,CAAC;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAyB,CAAC;QACrF,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;QAC/B,OAAO;YACL,SAAS,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa;YAC7F,cAAc,EACZ,OAAO,GAAG,CAAC,cAAc,KAAK,QAAQ,IAAI,GAAG,CAAC,cAAc,IAAI,CAAC;gBAC/D,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC9C,CAAC,CAAC,IAAI,CAAC,cAAc;YACzB,kBAAkB,EAChB,OAAO,GAAG,CAAC,kBAAkB,KAAK,QAAQ;gBAC1C,GAAG,CAAC,kBAAkB,IAAI,CAAC;gBAC3B,GAAG,CAAC,kBAAkB,IAAI,CAAC;gBACzB,CAAC,CAAC,GAAG,CAAC,kBAAkB;gBACxB,CAAC,CAAC,IAAI,CAAC,kBAAkB;SAC9B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,CAAc;IAChD,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace selection + filesystem allow-roots. Two responsibilities:
|
|
3
|
+
* 1. Persist the operator's active workspace (and recent picks) under
|
|
4
|
+
* ~/.rothunter/workspace.json so server restarts remember the choice.
|
|
5
|
+
* 2. Guard every fs-reaching endpoint against paths outside the
|
|
6
|
+
* configured allow-roots — defaults to $HOME (+ /workspace inside the
|
|
7
|
+
* Docker image) unless ROTHUNTER_FS_ROOTS overrides.
|
|
8
|
+
*
|
|
9
|
+
* Module-level mutables (WORKSPACE_ROOT, RECENT_WORKSPACES) are exposed
|
|
10
|
+
* through getters/setters so the rest of the server can hold a reference
|
|
11
|
+
* to "current workspace" without each caller re-reading the persisted
|
|
12
|
+
* config every time.
|
|
13
|
+
*/
|
|
14
|
+
export declare const CONFIG_DIR: string;
|
|
15
|
+
export declare const CONFIG_FILE: string;
|
|
16
|
+
export declare const FS_CASE_INSENSITIVE: boolean;
|
|
17
|
+
export declare const FS_ALLOW_ROOTS: string[];
|
|
18
|
+
export declare function isUnderAllowRoot(abs: string): boolean;
|
|
19
|
+
interface PersistedWorkspaceConfig {
|
|
20
|
+
current: string;
|
|
21
|
+
recent: string[];
|
|
22
|
+
}
|
|
23
|
+
export declare function readPersistedWorkspace(): PersistedWorkspaceConfig | null;
|
|
24
|
+
/**
|
|
25
|
+
* Boot-time workspace initialisation. Must be called once before any
|
|
26
|
+
* getWorkspaceRoot() reader. Throws when no candidate falls inside the
|
|
27
|
+
* allow-roots — the server is unusable in that state, so we let the
|
|
28
|
+
* caller decide whether to exit or fall back.
|
|
29
|
+
*/
|
|
30
|
+
export declare function initWorkspaceStore(initial: string): {
|
|
31
|
+
workspaceRoot: string;
|
|
32
|
+
recent: string[];
|
|
33
|
+
};
|
|
34
|
+
export declare function getWorkspaceRoot(): string;
|
|
35
|
+
export declare function getRecentWorkspaces(): ReadonlyArray<string>;
|
|
36
|
+
export declare function setWorkspaceRoot(next: string): void;
|
|
37
|
+
export declare function persistCurrentWorkspace(): Promise<void>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=workspace-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-store.d.ts","sourceRoot":"","sources":["../../src/server/workspace-store.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,UAAU,QAAwC,CAAC;AAChE,eAAO,MAAM,WAAW,QAA0C,CAAC;AAInE,eAAO,MAAM,mBAAmB,SAAgE,CAAC;AAkBjG,eAAO,MAAM,cAAc,UAAqB,CAAC;AAEjD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAerD;AAED,UAAU,wBAAwB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,sBAAsB,IAAI,wBAAwB,GAAG,IAAI,CAOxE;AAUD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAM/F;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CAAC,MAAM,CAAC,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAInD;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM7D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
import { existsSync, realpathSync, readFileSync } from 'node:fs';
|
|
5
|
+
/**
|
|
6
|
+
* Workspace selection + filesystem allow-roots. Two responsibilities:
|
|
7
|
+
* 1. Persist the operator's active workspace (and recent picks) under
|
|
8
|
+
* ~/.rothunter/workspace.json so server restarts remember the choice.
|
|
9
|
+
* 2. Guard every fs-reaching endpoint against paths outside the
|
|
10
|
+
* configured allow-roots — defaults to $HOME (+ /workspace inside the
|
|
11
|
+
* Docker image) unless ROTHUNTER_FS_ROOTS overrides.
|
|
12
|
+
*
|
|
13
|
+
* Module-level mutables (WORKSPACE_ROOT, RECENT_WORKSPACES) are exposed
|
|
14
|
+
* through getters/setters so the rest of the server can hold a reference
|
|
15
|
+
* to "current workspace" without each caller re-reading the persisted
|
|
16
|
+
* config every time.
|
|
17
|
+
*/
|
|
18
|
+
export const CONFIG_DIR = path.join(os.homedir(), '.rothunter');
|
|
19
|
+
export const CONFIG_FILE = path.join(CONFIG_DIR, 'workspace.json');
|
|
20
|
+
// macOS HFS+/APFS and Windows NTFS are case-insensitive by default.
|
|
21
|
+
// Fold case on the prefix comparison so `/Users/Foo` matches `/users/foo`.
|
|
22
|
+
export const FS_CASE_INSENSITIVE = process.platform === 'darwin' || process.platform === 'win32';
|
|
23
|
+
function loadFsAllowRoots() {
|
|
24
|
+
const raw = process.env.ROTHUNTER_FS_ROOTS;
|
|
25
|
+
const explicit = !!raw;
|
|
26
|
+
const roots = raw ? raw.split(':').filter(Boolean) : [os.homedir()];
|
|
27
|
+
if (!explicit && existsSync('/workspace'))
|
|
28
|
+
roots.push('/workspace');
|
|
29
|
+
const resolved = roots.map((r) => {
|
|
30
|
+
const abs = path.resolve(r);
|
|
31
|
+
try {
|
|
32
|
+
return realpathSync(abs);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return abs; // path may not exist yet (e.g. fresh container)
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return [...new Set(resolved)];
|
|
39
|
+
}
|
|
40
|
+
export const FS_ALLOW_ROOTS = loadFsAllowRoots();
|
|
41
|
+
export function isUnderAllowRoot(abs) {
|
|
42
|
+
let resolved = path.resolve(abs);
|
|
43
|
+
try {
|
|
44
|
+
resolved = realpathSync(resolved);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Path may not exist yet (POST /api/workspace before mkdir, etc.).
|
|
48
|
+
// Fall back to the un-resolved form — the caller's existsSync gate
|
|
49
|
+
// catches "missing path" cases separately.
|
|
50
|
+
}
|
|
51
|
+
const needle = FS_CASE_INSENSITIVE ? resolved.toLowerCase() : resolved;
|
|
52
|
+
return FS_ALLOW_ROOTS.some((root) => {
|
|
53
|
+
const r = FS_CASE_INSENSITIVE ? root.toLowerCase() : root;
|
|
54
|
+
if (needle === r)
|
|
55
|
+
return true;
|
|
56
|
+
return needle.startsWith(r + path.sep);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export function readPersistedWorkspace() {
|
|
60
|
+
try {
|
|
61
|
+
if (!existsSync(CONFIG_FILE))
|
|
62
|
+
return null;
|
|
63
|
+
return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function writePersistedWorkspace(cfg) {
|
|
70
|
+
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
71
|
+
await fs.writeFile(CONFIG_FILE, JSON.stringify(cfg, null, 2), 'utf-8');
|
|
72
|
+
}
|
|
73
|
+
let WORKSPACE_ROOT;
|
|
74
|
+
let RECENT_WORKSPACES;
|
|
75
|
+
/**
|
|
76
|
+
* Boot-time workspace initialisation. Must be called once before any
|
|
77
|
+
* getWorkspaceRoot() reader. Throws when no candidate falls inside the
|
|
78
|
+
* allow-roots — the server is unusable in that state, so we let the
|
|
79
|
+
* caller decide whether to exit or fall back.
|
|
80
|
+
*/
|
|
81
|
+
export function initWorkspaceStore(initial) {
|
|
82
|
+
const persisted = readPersistedWorkspace();
|
|
83
|
+
WORKSPACE_ROOT = initial;
|
|
84
|
+
RECENT_WORKSPACES = (persisted?.recent ?? [initial]).filter((p) => isUnderAllowRoot(p));
|
|
85
|
+
if (RECENT_WORKSPACES.length === 0)
|
|
86
|
+
RECENT_WORKSPACES = [initial];
|
|
87
|
+
return { workspaceRoot: WORKSPACE_ROOT, recent: RECENT_WORKSPACES };
|
|
88
|
+
}
|
|
89
|
+
export function getWorkspaceRoot() {
|
|
90
|
+
return WORKSPACE_ROOT;
|
|
91
|
+
}
|
|
92
|
+
export function getRecentWorkspaces() {
|
|
93
|
+
return RECENT_WORKSPACES;
|
|
94
|
+
}
|
|
95
|
+
export function setWorkspaceRoot(next) {
|
|
96
|
+
WORKSPACE_ROOT = next;
|
|
97
|
+
// Move to head of recent list (MRU).
|
|
98
|
+
RECENT_WORKSPACES = [next, ...RECENT_WORKSPACES.filter((p) => p !== next)].slice(0, 10);
|
|
99
|
+
}
|
|
100
|
+
export async function persistCurrentWorkspace() {
|
|
101
|
+
try {
|
|
102
|
+
await writePersistedWorkspace({ current: WORKSPACE_ROOT, recent: RECENT_WORKSPACES });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Persist failures should not crash the server; the next switch will retry.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=workspace-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-store.js","sourceRoot":"","sources":["../../src/server/workspace-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Project } from 'ts-morph';
|
|
2
|
+
import type { SymbolRecord } from '../types.js';
|
|
3
|
+
import type { ImportRecord } from '../graph/import-graph.js';
|
|
4
|
+
/**
|
|
5
|
+
* Shared input shape for file-walking detectors. Eleven detectors used
|
|
6
|
+
* to declare their own near-identical `{ workspaceRoot, files, project? }`
|
|
7
|
+
* interface — the duplicate-type detector flagged them as a cluster.
|
|
8
|
+
* One canonical type here, each detector either uses this directly or
|
|
9
|
+
* extends it with detector-specific fields.
|
|
10
|
+
*/
|
|
11
|
+
export interface FileWalkingDetectorInput {
|
|
12
|
+
workspaceRoot: string;
|
|
13
|
+
files: ReadonlyArray<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Optional pre-built ts-morph Project — the orchestrator builds one
|
|
16
|
+
* shared Project per scan and passes it down so detectors don't have
|
|
17
|
+
* to re-parse the same source tree N times. When absent, detectors
|
|
18
|
+
* fall back to readFileSync via `utils/source-reader.ts`.
|
|
19
|
+
*/
|
|
20
|
+
project?: Project;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Detectors whose input is the parsed symbol set (no per-file walking).
|
|
24
|
+
* Used by long-function / deep-nesting / public-any / hot-hub-file.
|
|
25
|
+
*/
|
|
26
|
+
export interface SymbolDetectorInput {
|
|
27
|
+
symbols: ReadonlyArray<SymbolRecord>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Detectors that consume the import graph directly (dead-export,
|
|
31
|
+
* dead-api, dead-handler, unused-deps). Shape kept here so changes to
|
|
32
|
+
* the import record propagate via a single canonical reference.
|
|
33
|
+
*/
|
|
34
|
+
export interface ImportGraphDetectorInput {
|
|
35
|
+
imports: ReadonlyArray<ImportRecord>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=detector-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector-input.d.ts","sourceRoot":"","sources":["../../src/types/detector-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector-input.js","sourceRoot":"","sources":["../../src/types/detector-input.ts"],"names":[],"mappings":""}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export type SymbolKind = 'interface' | 'type-alias' | 'class' | 'enum' | 'function';
|
|
2
|
+
export interface FieldStructure {
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
optional: boolean;
|
|
6
|
+
readonly: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface TypeStructure {
|
|
9
|
+
kind: 'object' | 'union' | 'intersection' | 'literal' | 'unknown';
|
|
10
|
+
fields?: FieldStructure[];
|
|
11
|
+
members?: TypeStructure[];
|
|
12
|
+
raw?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface FunctionStructure {
|
|
15
|
+
kind: 'function';
|
|
16
|
+
/** Parameters in declaration order. Reuses FieldStructure (name, type, optional). */
|
|
17
|
+
params: FieldStructure[];
|
|
18
|
+
/** TypeScript-rendered return type. */
|
|
19
|
+
returnType: string;
|
|
20
|
+
/** Whether the function is `async`. */
|
|
21
|
+
async: boolean;
|
|
22
|
+
/** Whether the function is a `*` generator. */
|
|
23
|
+
generator: boolean;
|
|
24
|
+
/** Raw body source including the braces, exactly as the user wrote it. */
|
|
25
|
+
body: string;
|
|
26
|
+
/**
|
|
27
|
+
* Body after whitespace/comment collapse, used as the body-similarity hash
|
|
28
|
+
* input. Local identifier renaming happens at the normalizer level so the
|
|
29
|
+
* raw text here is still recognizable in evidence snippets.
|
|
30
|
+
*/
|
|
31
|
+
bodyNormalized: string;
|
|
32
|
+
/**
|
|
33
|
+
* Token shingles (4-grams of identifier-anonymised tokens) used for the
|
|
34
|
+
* near-duplicate Layer-4 pairwise Jaccard pass.
|
|
35
|
+
*/
|
|
36
|
+
bodyShingles: ReadonlySet<string>;
|
|
37
|
+
}
|
|
38
|
+
export type AnyStructure = TypeStructure | FunctionStructure;
|
|
39
|
+
export interface SourceRange {
|
|
40
|
+
startLine: number;
|
|
41
|
+
endLine: number;
|
|
42
|
+
}
|
|
43
|
+
export interface SymbolRecord {
|
|
44
|
+
id: string;
|
|
45
|
+
kind: SymbolKind;
|
|
46
|
+
name: string;
|
|
47
|
+
file: string;
|
|
48
|
+
/** Logical workspace name when running in multi-workspace mode. Undefined for single-workspace scans. */
|
|
49
|
+
workspace?: string;
|
|
50
|
+
range: SourceRange;
|
|
51
|
+
source: string;
|
|
52
|
+
exported: boolean;
|
|
53
|
+
/** True iff the symbol is the file's default export (`export default X`). */
|
|
54
|
+
isDefault?: boolean;
|
|
55
|
+
structure?: AnyStructure;
|
|
56
|
+
hashStrict?: string;
|
|
57
|
+
hashStructural?: string;
|
|
58
|
+
hashNormalizedNames?: string;
|
|
59
|
+
canonicalSignature?: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
domain?: string;
|
|
62
|
+
embeddingSignature?: number[];
|
|
63
|
+
embeddingSemantic?: number[];
|
|
64
|
+
}
|
|
65
|
+
export interface Evidence {
|
|
66
|
+
file: string;
|
|
67
|
+
range: SourceRange;
|
|
68
|
+
snippet: string;
|
|
69
|
+
note?: string;
|
|
70
|
+
}
|
|
71
|
+
export type Severity = 'low' | 'medium' | 'high';
|
|
72
|
+
export interface Finding {
|
|
73
|
+
detectorId: string;
|
|
74
|
+
severity: Severity;
|
|
75
|
+
confidence: number;
|
|
76
|
+
layer: 1 | 2 | 3;
|
|
77
|
+
title: string;
|
|
78
|
+
description: string;
|
|
79
|
+
evidence: Evidence[];
|
|
80
|
+
suggestion?: string;
|
|
81
|
+
fingerprint: string;
|
|
82
|
+
/**
|
|
83
|
+
* Unix-ms timestamp when this finding was confirmed resolved by a
|
|
84
|
+
* single-finding re-run (POST /api/findings/:fp/rerun). The persisted
|
|
85
|
+
* scan record keeps the entry around — flipped to `resolved` instead
|
|
86
|
+
* of deleted — so History / Findings views can surface the fix as a
|
|
87
|
+
* "completed" item rather than silently dropping it.
|
|
88
|
+
*/
|
|
89
|
+
resolvedAt?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Auto-flagged by an LLM verdict as a false positive during this scan.
|
|
92
|
+
* Populated when the relevant confirmer (mutation, triage, …) returns
|
|
93
|
+
* `intentional` / `not real` with high confidence. Surface-level effect
|
|
94
|
+
* matches the manual FP store: the finding moves to the FP bucket
|
|
95
|
+
* instead of cluttering the open list. Differs from the persisted FP
|
|
96
|
+
* store in that it is scan-scoped and recomputed every run — if the
|
|
97
|
+
* code changes and the LLM no longer thinks it is intentional, the
|
|
98
|
+
* finding comes back automatically.
|
|
99
|
+
*/
|
|
100
|
+
llmFalsePositive?: {
|
|
101
|
+
confidence: number;
|
|
102
|
+
reason: string;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export interface Detector {
|
|
106
|
+
id: string;
|
|
107
|
+
name: string;
|
|
108
|
+
run(symbols: SymbolRecord[]): Promise<Finding[]>;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SymbolRecord } from '../types.js';
|
|
2
|
+
/** Bucket a list of symbols by a hash extractor (skipping symbols whose hash is empty). */
|
|
3
|
+
export declare function bucketBy(symbols: SymbolRecord[], hashFn: (s: SymbolRecord) => string | undefined): Map<string, SymbolRecord[]>;
|
|
4
|
+
/** First non-empty hash from a cluster, picked by the layer that matched. */
|
|
5
|
+
export declare function representativeHash<MatchedBy extends string>(group: SymbolRecord[], matchedBy: MatchedBy, pickers: Record<MatchedBy, (s: SymbolRecord) => string | undefined>): string;
|
|
6
|
+
/** Flat-array union-find with path compression + rank balancing. */
|
|
7
|
+
export declare class UnionFind {
|
|
8
|
+
private readonly parent;
|
|
9
|
+
private readonly rank;
|
|
10
|
+
constructor(n: number);
|
|
11
|
+
find(x: number): number;
|
|
12
|
+
union(a: number, b: number): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=clustering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clustering.d.ts","sourceRoot":"","sources":["../../src/utils/clustering.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,2FAA2F;AAC3F,wBAAgB,QAAQ,CACtB,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,GAC9C,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAU7B;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,MAAM,EACzD,KAAK,EAAE,YAAY,EAAE,EACrB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC,GAClE,MAAM,CAOR;AAED,oEAAoE;AACpE,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;gBAEpB,CAAC,EAAE,MAAM;IAKrB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAQvB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;CAalC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Bucket a list of symbols by a hash extractor (skipping symbols whose hash is empty). */
|
|
2
|
+
export function bucketBy(symbols, hashFn) {
|
|
3
|
+
const out = new Map();
|
|
4
|
+
for (const s of symbols) {
|
|
5
|
+
const h = hashFn(s);
|
|
6
|
+
if (!h)
|
|
7
|
+
continue;
|
|
8
|
+
const list = out.get(h) ?? [];
|
|
9
|
+
list.push(s);
|
|
10
|
+
out.set(h, list);
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
/** First non-empty hash from a cluster, picked by the layer that matched. */
|
|
15
|
+
export function representativeHash(group, matchedBy, pickers) {
|
|
16
|
+
const pick = pickers[matchedBy];
|
|
17
|
+
for (const s of group) {
|
|
18
|
+
const h = pick(s);
|
|
19
|
+
if (h)
|
|
20
|
+
return h;
|
|
21
|
+
}
|
|
22
|
+
return 'unknown';
|
|
23
|
+
}
|
|
24
|
+
/** Flat-array union-find with path compression + rank balancing. */
|
|
25
|
+
export class UnionFind {
|
|
26
|
+
parent;
|
|
27
|
+
rank;
|
|
28
|
+
constructor(n) {
|
|
29
|
+
this.parent = Array.from({ length: n }, (_, i) => i);
|
|
30
|
+
this.rank = new Array(n).fill(0);
|
|
31
|
+
}
|
|
32
|
+
find(x) {
|
|
33
|
+
while (this.parent[x] !== x) {
|
|
34
|
+
this.parent[x] = this.parent[this.parent[x]];
|
|
35
|
+
x = this.parent[x];
|
|
36
|
+
}
|
|
37
|
+
return x;
|
|
38
|
+
}
|
|
39
|
+
union(a, b) {
|
|
40
|
+
const ra = this.find(a);
|
|
41
|
+
const rb = this.find(b);
|
|
42
|
+
if (ra === rb)
|
|
43
|
+
return;
|
|
44
|
+
if (this.rank[ra] < this.rank[rb]) {
|
|
45
|
+
this.parent[ra] = rb;
|
|
46
|
+
}
|
|
47
|
+
else if (this.rank[ra] > this.rank[rb]) {
|
|
48
|
+
this.parent[rb] = ra;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.parent[rb] = ra;
|
|
52
|
+
this.rank[ra]++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=clustering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clustering.js","sourceRoot":"","sources":["../../src/utils/clustering.ts"],"names":[],"mappings":"AAEA,2FAA2F;AAC3F,MAAM,UAAU,QAAQ,CACtB,OAAuB,EACvB,MAA+C;IAE/C,MAAM,GAAG,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACb,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAChC,KAAqB,EACrB,SAAoB,EACpB,OAAmE;IAEnE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,oEAAoE;AACpE,MAAM,OAAO,SAAS;IACH,MAAM,CAAW;IACjB,IAAI,CAAW;IAEhC,YAAY,CAAS;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,CAAS;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAE,CAAC;YAC/C,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,CAAS,EAAE,CAAS;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO;QACtB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Ignore } from 'ignore';
|
|
2
|
+
/**
|
|
3
|
+
* Load every `.gitignore` reachable from `workspaceRoot` AND the
|
|
4
|
+
* workspace-root `.rothunterignore` (gitignore-syntax extension, only
|
|
5
|
+
* for rothunter). Returns a unified matcher.
|
|
6
|
+
*
|
|
7
|
+
* The matcher answers "is this workspace-relative path ignored?" — used
|
|
8
|
+
* by the parser + by any detector that walks the filesystem on its own.
|
|
9
|
+
*
|
|
10
|
+
* Rules:
|
|
11
|
+
* - Top-level `.gitignore` always loads (when present).
|
|
12
|
+
* - Nested `.gitignore`s load too, prefixed with their relative dir so
|
|
13
|
+
* a pattern like `dist/` inside `packages/foo/.gitignore` matches
|
|
14
|
+
* `packages/foo/dist/...` and not the root `dist/`.
|
|
15
|
+
* - `.rothunterignore` at the workspace root loads with the same
|
|
16
|
+
* syntax — use this for files that ARE in git but should be hidden
|
|
17
|
+
* from rothunter (fixtures, vendored SDKs, generated test data).
|
|
18
|
+
* - `node_modules/` and `.git/` are always ignored regardless of
|
|
19
|
+
* what the operator's files say — the cost of scanning them is
|
|
20
|
+
* prohibitive on every repo and never produces useful findings.
|
|
21
|
+
*
|
|
22
|
+
* Always returns a non-null matcher; the always-on rules (`node_modules`
|
|
23
|
+
* + `.git`) ensure callers get sensible defaults even when no ignore
|
|
24
|
+
* file exists.
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadGitignore(workspaceRoot: string): Ignore;
|
|
27
|
+
/**
|
|
28
|
+
* Filter a workspace-relative path list through the gitignore matcher,
|
|
29
|
+
* preserving order.
|
|
30
|
+
*/
|
|
31
|
+
export declare function filterGitignored(matcher: Ignore, files: ReadonlyArray<string>): string[];
|
|
32
|
+
//# sourceMappingURL=gitignore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore.d.ts","sourceRoot":"","sources":["../../src/utils/gitignore.ts"],"names":[],"mappings":"AAEA,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAmF3D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAExF"}
|