@wrongstack/plugins 0.292.1 → 0.295.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 +7 -71
- package/dist/accessibility-auditor/index.d.ts +1 -1
- package/dist/accessibility-auditor/index.d.ts.map +1 -1
- package/dist/accessibility-auditor.js +31 -31
- package/dist/agent-handoff/index.d.ts +1 -1
- package/dist/agent-handoff/index.d.ts.map +1 -1
- package/dist/api-compatibility-gate/index.d.ts +1 -1
- package/dist/api-compatibility-gate/index.d.ts.map +1 -1
- package/dist/api-compatibility-gate.js +21 -16
- package/dist/audit/index.d.ts +386 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit.d.ts +1 -0
- package/dist/audit.js +454 -0
- package/dist/auto-doc/index.d.ts +1 -1
- package/dist/auto-doc/index.d.ts.map +1 -1
- package/dist/auto-escalate/index.d.ts +1 -1
- package/dist/auto-escalate/index.d.ts.map +1 -1
- package/dist/auto-i18n-extractor/index.d.ts +1 -1
- package/dist/auto-i18n-extractor/index.d.ts.map +1 -1
- package/dist/auto-i18n-extractor.js +2 -1
- package/dist/branch-guard/index.d.ts +1 -1
- package/dist/branch-guard/index.d.ts.map +1 -1
- package/dist/branch-guard.js +9 -1
- package/dist/catalog.d.ts +5 -30
- package/dist/catalog.d.ts.map +1 -1
- package/dist/changelog-writer/index.d.ts +1 -1
- package/dist/changelog-writer/index.d.ts.map +1 -1
- package/dist/checkpoint/index.d.ts +1 -1
- package/dist/checkpoint/index.d.ts.map +1 -1
- package/dist/checkpoint.js +7 -8
- package/dist/code-metrics/index.d.ts +1 -1
- package/dist/code-metrics/index.d.ts.map +1 -1
- package/dist/code-metrics.js +29 -29
- package/dist/commit-validator/index.d.ts +1 -1
- package/dist/commit-validator/index.d.ts.map +1 -1
- package/dist/config-validator/index.d.ts +1 -1
- package/dist/config-validator/index.d.ts.map +1 -1
- package/dist/context-pins/index.d.ts +1 -1
- package/dist/context-pins/index.d.ts.map +1 -1
- package/dist/cost-tracker/index.d.ts +1 -1
- package/dist/cost-tracker/index.d.ts.map +1 -1
- package/dist/cost-tracker.js +9 -2
- package/dist/cron/index.d.ts +1 -1
- package/dist/cron/index.d.ts.map +1 -1
- package/dist/dead-code-detector/index.d.ts +1 -1
- package/dist/dead-code-detector/index.d.ts.map +1 -1
- package/dist/dead-code-detector.js +26 -18
- package/dist/dep-guard/index.d.ts +1 -1
- package/dist/dep-guard/index.d.ts.map +1 -1
- package/dist/dependency-vulnerability-gate/index.d.ts +1 -1
- package/dist/dependency-vulnerability-gate/index.d.ts.map +1 -1
- package/dist/dependency-vulnerability-gate.js +34 -22
- package/dist/diff-summary/index.d.ts +1 -1
- package/dist/diff-summary/index.d.ts.map +1 -1
- package/dist/diff-summary.js +28 -29
- package/dist/doc-sync-guard/index.d.ts +1 -1
- package/dist/doc-sync-guard/index.d.ts.map +1 -1
- package/dist/doc-sync-guard.js +2 -1
- package/dist/duplicate-code-detector/index.d.ts +26 -1
- package/dist/duplicate-code-detector/index.d.ts.map +1 -1
- package/dist/duplicate-code-detector.js +178 -67
- package/dist/error-lens/index.d.ts +1 -1
- package/dist/error-lens/index.d.ts.map +1 -1
- package/dist/factories/index.d.ts +4 -0
- package/dist/factories/index.d.ts.map +1 -0
- package/dist/factories.d.ts +1 -0
- package/dist/factories.js +74 -0
- package/dist/feature-flag-tracker/index.d.ts +1 -1
- package/dist/feature-flag-tracker/index.d.ts.map +1 -1
- package/dist/feature-flag-tracker.js +29 -29
- package/dist/file-watcher/index.d.ts +1 -1
- package/dist/file-watcher/index.d.ts.map +1 -1
- package/dist/format-on-save/index.d.ts +1 -1
- package/dist/format-on-save/index.d.ts.map +1 -1
- package/dist/format-on-save.js +2 -1
- package/dist/generated-plugin-exports.d.ts +65 -0
- package/dist/generated-plugin-exports.d.ts.map +1 -0
- package/dist/git-autocommit/index.d.ts +1 -1
- package/dist/git-autocommit/index.d.ts.map +1 -1
- package/dist/import-organizer/index.d.ts +1 -1
- package/dist/import-organizer/index.d.ts.map +1 -1
- package/dist/import-organizer.js +2 -1
- package/dist/index.d.ts +4 -183
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17675 -17377
- package/dist/injection-shield/index.d.ts +1 -1
- package/dist/injection-shield/index.d.ts.map +1 -1
- package/dist/interface-contract-guard/index.d.ts +1 -1
- package/dist/interface-contract-guard/index.d.ts.map +1 -1
- package/dist/interface-contract-guard.js +29 -29
- package/dist/knowledge-graph/index.d.ts +1 -1
- package/dist/knowledge-graph/index.d.ts.map +1 -1
- package/dist/license-audit-gate/index.d.ts +1 -1
- package/dist/license-audit-gate/index.d.ts.map +1 -1
- package/dist/lint-gate/index.d.ts +1 -1
- package/dist/lint-gate/index.d.ts.map +1 -1
- package/dist/lint-gate.js +10 -1
- package/dist/llm-cache/index.d.ts +5 -1
- package/dist/llm-cache/index.d.ts.map +1 -1
- package/dist/llm-cache.js +16 -8
- package/dist/loop-breaker/index.d.ts +1 -1
- package/dist/loop-breaker/index.d.ts.map +1 -1
- package/dist/loop-breaker.js +10 -4
- package/dist/manifest/index.d.ts +16 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest.d.ts +1 -0
- package/dist/manifest.js +152 -0
- package/dist/migration-planner/index.d.ts +1 -1
- package/dist/migration-planner/index.d.ts.map +1 -1
- package/dist/migration-planner.js +2 -1
- package/dist/model-router/index.d.ts +1 -1
- package/dist/model-router/index.d.ts.map +1 -1
- package/dist/notify-hub/index.d.ts +1 -1
- package/dist/notify-hub/index.d.ts.map +1 -1
- package/dist/notify-hub/webhook-channel.d.ts +1 -1
- package/dist/notify-hub/webhook-channel.d.ts.map +1 -1
- package/dist/path-guard/index.d.ts +1 -1
- package/dist/path-guard/index.d.ts.map +1 -1
- package/dist/performance-regression-gate/index.d.ts +1 -1
- package/dist/performance-regression-gate/index.d.ts.map +1 -1
- package/dist/plugin-stack-observer/index.d.ts +1 -1
- package/dist/plugin-stack-observer/index.d.ts.map +1 -1
- package/dist/pr-drafter/index.d.ts +1 -1
- package/dist/pr-drafter/index.d.ts.map +1 -1
- package/dist/pr-drafter.js +28 -29
- package/dist/process-guard/index.d.ts +1 -1
- package/dist/process-guard/index.d.ts.map +1 -1
- package/dist/prompt-firewall/index.d.ts +1 -1
- package/dist/prompt-firewall/index.d.ts.map +1 -1
- package/dist/refactor-suggester/index.d.ts +1 -1
- package/dist/refactor-suggester/index.d.ts.map +1 -1
- package/dist/refactor-suggester.js +29 -29
- package/dist/release-notes-generator/index.d.ts +1 -1
- package/dist/release-notes-generator/index.d.ts.map +1 -1
- package/dist/release-notes-generator.js +29 -22
- package/dist/runtime/index.d.ts +15 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/llm.d.ts +1 -1
- package/dist/runtime/llm.d.ts.map +1 -1
- package/dist/runtime.js +43 -2
- package/dist/schema-evolution-guard/index.d.ts +1 -1
- package/dist/schema-evolution-guard/index.d.ts.map +1 -1
- package/dist/schema-evolution-guard.js +2 -1
- package/dist/secret-scanner/index.d.ts +1 -1
- package/dist/secret-scanner/index.d.ts.map +1 -1
- package/dist/secret-scanner.js +7 -1
- package/dist/security-hotspot-scanner/index.d.ts +1 -1
- package/dist/security-hotspot-scanner/index.d.ts.map +1 -1
- package/dist/security-hotspot-scanner.js +26 -19
- package/dist/semantic-search-indexer/index.d.ts +1 -1
- package/dist/semantic-search-indexer/index.d.ts.map +1 -1
- package/dist/semver-bump/index.d.ts +1 -1
- package/dist/semver-bump/index.d.ts.map +1 -1
- package/dist/semver-bump.js +78 -43
- package/dist/session-recap/index.d.ts +1 -1
- package/dist/session-recap/index.d.ts.map +1 -1
- package/dist/shell-check/index.d.ts +1 -1
- package/dist/shell-check/index.d.ts.map +1 -1
- package/dist/smart-rename/index.d.ts +1 -1
- package/dist/smart-rename/index.d.ts.map +1 -1
- package/dist/spec-linker/index.d.ts +1 -1
- package/dist/spec-linker/index.d.ts.map +1 -1
- package/dist/spec-linker.js +222 -20772
- package/dist/template-engine/index.d.ts +1 -1
- package/dist/template-engine/index.d.ts.map +1 -1
- package/dist/template-engine.js +4 -6
- package/dist/test-coverage-gate/index.d.ts +1 -1
- package/dist/test-coverage-gate/index.d.ts.map +1 -1
- package/dist/test-coverage-gate.js +29 -14
- package/dist/test-flake-detector/index.d.ts +1 -1
- package/dist/test-flake-detector/index.d.ts.map +1 -1
- package/dist/test-flake-detector.js +31 -20
- package/dist/test-generator/index.d.ts +1 -1
- package/dist/test-generator/index.d.ts.map +1 -1
- package/dist/test-runner-gate/index.d.ts +1 -1
- package/dist/test-runner-gate/index.d.ts.map +1 -1
- package/dist/test-runner-gate.js +2 -1
- package/dist/todo-listener/index.d.ts +1 -32
- package/dist/todo-listener/index.d.ts.map +1 -1
- package/dist/todo-tracker/index.d.ts +1 -1
- package/dist/todo-tracker/index.d.ts.map +1 -1
- package/dist/token-budget/index.d.ts +1 -1
- package/dist/token-budget/index.d.ts.map +1 -1
- package/dist/token-throttle/index.d.ts +1 -1
- package/dist/token-throttle/index.d.ts.map +1 -1
- package/dist/type-gate/index.d.ts +1 -1
- package/dist/type-gate/index.d.ts.map +1 -1
- package/dist/type-gate.js +11 -4
- package/package.json +80 -68
package/dist/diff-summary.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/diff-summary/index.ts
|
|
2
|
-
import {
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
3
|
|
|
4
4
|
// src/runtime/index.ts
|
|
5
5
|
import { basename, extname, isAbsolute, relative, resolve } from "node:path";
|
|
@@ -15,7 +15,8 @@ function withinProjectPath(projectRoot, candidate) {
|
|
|
15
15
|
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
16
16
|
}
|
|
17
17
|
function withinProject(p) {
|
|
18
|
-
|
|
18
|
+
const cwd = process.cwd();
|
|
19
|
+
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
// src/diff-summary/index.ts
|
|
@@ -64,36 +65,34 @@ function contentHash(s) {
|
|
|
64
65
|
return h >>> 0;
|
|
65
66
|
}
|
|
66
67
|
var pathMemo = /* @__PURE__ */ new Map();
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
68
|
+
function runGit(args, cwd) {
|
|
69
|
+
return new Promise((resolveCommand) => {
|
|
70
|
+
execFile(
|
|
71
|
+
"git",
|
|
72
|
+
args,
|
|
73
|
+
{
|
|
74
|
+
encoding: "utf8",
|
|
75
|
+
timeout: 3e3,
|
|
76
|
+
cwd,
|
|
77
|
+
windowsHide: true,
|
|
78
|
+
maxBuffer: 5 * 1024 * 1024
|
|
79
|
+
},
|
|
80
|
+
(error, stdout) => resolveCommand({ ok: !error, stdout })
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function getGitDiff(filePath, contextLines, cwd) {
|
|
85
|
+
const tracked = await runGit(["ls-files", "--error-unmatch", "--", filePath], cwd);
|
|
86
|
+
const isTracked = tracked.ok;
|
|
81
87
|
try {
|
|
82
88
|
let rawDiff;
|
|
83
89
|
const contextFlag = `-U${contextLines}`;
|
|
84
90
|
if (isTracked) {
|
|
85
|
-
|
|
91
|
+
const result = await runGit(["diff", contextFlag, "--", filePath], cwd);
|
|
92
|
+
if (!result.ok) return null;
|
|
93
|
+
rawDiff = result.stdout;
|
|
86
94
|
} else {
|
|
87
|
-
|
|
88
|
-
rawDiff = execFileSync(
|
|
89
|
-
"git",
|
|
90
|
-
["diff", "--no-index", contextFlag, "/dev/null", filePath],
|
|
91
|
-
opts
|
|
92
|
-
);
|
|
93
|
-
} catch (err) {
|
|
94
|
-
const e = err;
|
|
95
|
-
rawDiff = e.stdout ?? "";
|
|
96
|
-
}
|
|
95
|
+
rawDiff = (await runGit(["diff", "--no-index", contextFlag, "/dev/null", filePath], cwd)).stdout;
|
|
97
96
|
}
|
|
98
97
|
if (!rawDiff.trim()) {
|
|
99
98
|
return { diff: "", added: 0, removed: 0, isNewFile: !isTracked };
|
|
@@ -185,7 +184,7 @@ var plugin = {
|
|
|
185
184
|
pathMemo.clear();
|
|
186
185
|
const cfg = readConfig(api.config.extensions?.["diff-summary"]);
|
|
187
186
|
const cwd = typeof process.cwd === "function" ? process.cwd() : void 0;
|
|
188
|
-
const hook = (input) => {
|
|
187
|
+
const hook = async (input) => {
|
|
189
188
|
if (cfg.mode === "off") return;
|
|
190
189
|
if (input.toolResult?.isError) return;
|
|
191
190
|
const toolName = input.toolName ?? "";
|
|
@@ -212,7 +211,7 @@ var plugin = {
|
|
|
212
211
|
return;
|
|
213
212
|
}
|
|
214
213
|
}
|
|
215
|
-
const result = getGitDiff(filePath, cfg.includeContext, cwd);
|
|
214
|
+
const result = await getGitDiff(filePath, cfg.includeContext, cwd);
|
|
216
215
|
if (!result) {
|
|
217
216
|
state.fallbackCount += 1;
|
|
218
217
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/doc-sync-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/doc-sync-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA0IrD,QAAA,MAAM,MAAM,EAAE,MAuJb,CAAC;eAEa,MAAM"}
|
package/dist/doc-sync-guard.js
CHANGED
|
@@ -15,7 +15,8 @@ function withinProjectPath(projectRoot, candidate) {
|
|
|
15
15
|
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
16
16
|
}
|
|
17
17
|
function withinProject(p) {
|
|
18
|
-
|
|
18
|
+
const cwd = process.cwd();
|
|
19
|
+
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
// src/doc-sync-guard/index.ts
|
|
@@ -25,7 +25,32 @@
|
|
|
25
25
|
*
|
|
26
26
|
* @public
|
|
27
27
|
*/
|
|
28
|
-
import type { Plugin } from '@wrongstack/core';
|
|
28
|
+
import type { Plugin } from '@wrongstack/core/types';
|
|
29
|
+
/**
|
|
30
|
+
* Tunable budgets that bound the hook fingerprint index. Keeping the defaults
|
|
31
|
+
* together makes the file, fingerprint, and byte limits explicit.
|
|
32
|
+
*/
|
|
33
|
+
export declare const hookIndexBudgets: {
|
|
34
|
+
/** Max number of files retained in the hook fingerprint index (LRU-evicted). */
|
|
35
|
+
maxFiles: number;
|
|
36
|
+
/** Max total fingerprints across the whole index (running-sum enforced, LRU-evicted). */
|
|
37
|
+
maxFingerprints: number;
|
|
38
|
+
/**
|
|
39
|
+
* Max candidate windows hashed and cached per file by the advisory hook. The
|
|
40
|
+
* on-demand detect_duplicate_code tool intentionally scans every window.
|
|
41
|
+
*/
|
|
42
|
+
maxFingerprintsPerFile: number;
|
|
43
|
+
/** Files larger than this are skipped entirely by the hook (never read/extracted/cached). */
|
|
44
|
+
maxFileBytes: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Compact 53-bit hash of a fingerprint string. The hook index can retain up to
|
|
48
|
+
* 300k fingerprints, where a 32-bit hash has a material birthday-collision risk
|
|
49
|
+
* and can emit a false duplicate warning. The result remains a JS-safe integer,
|
|
50
|
+
* so the index keeps the compact `Set<number>` representation instead of storing
|
|
51
|
+
* raw fingerprint text.
|
|
52
|
+
*/
|
|
53
|
+
export declare function hashFingerprint(fp: string): number;
|
|
29
54
|
declare const plugin: Plugin;
|
|
30
55
|
export default plugin;
|
|
31
56
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/duplicate-code-detector/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/duplicate-code-detector/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA8ErD;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B,gFAAgF;IAChF,QAAQ;IACR,yFAAyF;IACzF,eAAe;IACf;;;OAGG;IACH,sBAAsB;IACtB,6FAA6F;IAC7F,YAAY;CACb,CAAC;AAyGF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAelD;AA4HD,QAAA,MAAM,MAAM,EAAE,MA4Wb,CAAC;eAEa,MAAM"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// src/duplicate-code-detector/index.ts
|
|
2
|
-
import {
|
|
3
|
-
import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
|
|
2
|
+
import { readFile, realpath, stat } from "node:fs/promises";
|
|
3
|
+
import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep } from "node:path";
|
|
4
4
|
|
|
5
5
|
// src/runtime/index.ts
|
|
6
|
-
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
7
6
|
import { basename, extname, isAbsolute, relative, resolve } from "node:path";
|
|
8
7
|
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
9
8
|
function hasLeadingDash(arg) {
|
|
@@ -17,44 +16,45 @@ function withinProjectPath(projectRoot, candidate) {
|
|
|
17
16
|
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
18
17
|
}
|
|
19
18
|
function withinProject(p) {
|
|
20
|
-
|
|
19
|
+
const cwd = process.cwd();
|
|
20
|
+
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
21
21
|
}
|
|
22
22
|
var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
|
|
23
|
-
function
|
|
23
|
+
async function collectSourceFilesAsync(root, opts) {
|
|
24
|
+
const { readdir, stat: stat2 } = await import("node:fs/promises");
|
|
24
25
|
const files = [];
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
try {
|
|
27
|
+
const s = await stat2(root);
|
|
28
|
+
if (s.isFile()) {
|
|
29
|
+
if (matchesExtension(root, opts.extensions)) files.push(root);
|
|
30
|
+
return files;
|
|
31
|
+
}
|
|
32
|
+
if (!s.isDirectory()) return files;
|
|
33
|
+
} catch {
|
|
29
34
|
return files;
|
|
30
35
|
}
|
|
31
|
-
if (!s.isDirectory()) return files;
|
|
32
36
|
const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
|
|
33
|
-
|
|
37
|
+
const excludeSet = new Set(exclude);
|
|
38
|
+
async function walk(dir, depth) {
|
|
34
39
|
if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
|
|
35
40
|
let entries;
|
|
36
41
|
try {
|
|
37
|
-
entries =
|
|
42
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
38
43
|
} catch {
|
|
39
44
|
return;
|
|
40
45
|
}
|
|
46
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
41
47
|
for (const entry of entries) {
|
|
42
|
-
if (
|
|
43
|
-
const full = resolve(dir, entry);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} catch {
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (st.isDirectory()) {
|
|
51
|
-
walk(full, depth + 1);
|
|
52
|
-
} else if (st.isFile() && matchesExtension(full, opts.extensions)) {
|
|
48
|
+
if (excludeSet.has(entry.name)) continue;
|
|
49
|
+
const full = resolve(dir, entry.name);
|
|
50
|
+
if (entry.isDirectory()) {
|
|
51
|
+
await walk(full, depth + 1);
|
|
52
|
+
} else if (entry.isFile() && matchesExtension(full, opts.extensions)) {
|
|
53
53
|
files.push(full);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
walk(root, 0);
|
|
57
|
+
await walk(root, 0);
|
|
58
58
|
return files;
|
|
59
59
|
}
|
|
60
60
|
function matchesExtension(p, exts) {
|
|
@@ -71,7 +71,24 @@ var state = {
|
|
|
71
71
|
errorCount: 0,
|
|
72
72
|
hookUnregister: null,
|
|
73
73
|
lastHookWarning: /* @__PURE__ */ new Map(),
|
|
74
|
-
fileIndex: /* @__PURE__ */ new Map()
|
|
74
|
+
fileIndex: /* @__PURE__ */ new Map(),
|
|
75
|
+
inFlightFingerprintReads: /* @__PURE__ */ new Map(),
|
|
76
|
+
indexFingerprintCount: 0,
|
|
77
|
+
hookIndexEvictions: 0,
|
|
78
|
+
oversizedFileSkips: 0
|
|
79
|
+
};
|
|
80
|
+
var hookIndexBudgets = {
|
|
81
|
+
/** Max number of files retained in the hook fingerprint index (LRU-evicted). */
|
|
82
|
+
maxFiles: 5e3,
|
|
83
|
+
/** Max total fingerprints across the whole index (running-sum enforced, LRU-evicted). */
|
|
84
|
+
maxFingerprints: 3e5,
|
|
85
|
+
/**
|
|
86
|
+
* Max candidate windows hashed and cached per file by the advisory hook. The
|
|
87
|
+
* on-demand detect_duplicate_code tool intentionally scans every window.
|
|
88
|
+
*/
|
|
89
|
+
maxFingerprintsPerFile: 25e3,
|
|
90
|
+
/** Files larger than this are skipped entirely by the hook (never read/extracted/cached). */
|
|
91
|
+
maxFileBytes: 2 * 1024 * 1024
|
|
75
92
|
};
|
|
76
93
|
var DEFAULTS = {
|
|
77
94
|
enabled: false,
|
|
@@ -81,18 +98,28 @@ var DEFAULTS = {
|
|
|
81
98
|
excludeDirs: ["node_modules", "dist", ".git", "coverage"],
|
|
82
99
|
maxFindings: 5
|
|
83
100
|
};
|
|
101
|
+
var extensionsSet = new Set(DEFAULTS.extensions);
|
|
84
102
|
function readConfig(raw) {
|
|
85
|
-
if (!raw || typeof raw !== "object")
|
|
103
|
+
if (!raw || typeof raw !== "object") {
|
|
104
|
+
extensionsSet = new Set(DEFAULTS.extensions);
|
|
105
|
+
return { ...DEFAULTS };
|
|
106
|
+
}
|
|
86
107
|
const r = raw;
|
|
108
|
+
const extensions = Array.isArray(r["extensions"]) ? r["extensions"].filter((x) => typeof x === "string") : DEFAULTS.extensions;
|
|
109
|
+
extensionsSet = new Set(extensions);
|
|
87
110
|
return {
|
|
88
111
|
enabled: r["enabled"] === true,
|
|
89
112
|
minLines: typeof r["minLines"] === "number" && r["minLines"] >= 2 && r["minLines"] <= 100 ? r["minLines"] : DEFAULTS.minLines,
|
|
90
113
|
threshold: typeof r["threshold"] === "number" && r["threshold"] > 0 && r["threshold"] <= 1 ? r["threshold"] : DEFAULTS.threshold,
|
|
91
|
-
extensions
|
|
114
|
+
extensions,
|
|
92
115
|
excludeDirs: Array.isArray(r["excludeDirs"]) ? r["excludeDirs"].filter((x) => typeof x === "string") : DEFAULTS.excludeDirs,
|
|
93
116
|
maxFindings: typeof r["maxFindings"] === "number" && r["maxFindings"] >= 1 && r["maxFindings"] <= 500 ? r["maxFindings"] : DEFAULTS.maxFindings
|
|
94
117
|
};
|
|
95
118
|
}
|
|
119
|
+
function isWithinRoot(projectRoot, candidate) {
|
|
120
|
+
const rel = relative2(projectRoot, candidate);
|
|
121
|
+
return rel === "" || rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute2(rel);
|
|
122
|
+
}
|
|
96
123
|
function toPosix(p) {
|
|
97
124
|
return p.replace(/\\/g, "/");
|
|
98
125
|
}
|
|
@@ -111,6 +138,40 @@ function normalizeLine(line) {
|
|
|
111
138
|
function buildFingerprint(lines) {
|
|
112
139
|
return lines.map(normalizeLine).filter((l) => l.length > 0).join("\n");
|
|
113
140
|
}
|
|
141
|
+
function hashFingerprint(fp) {
|
|
142
|
+
let low = 3735928559;
|
|
143
|
+
let high = 1103547991;
|
|
144
|
+
for (let index = 0; index < fp.length; index += 1) {
|
|
145
|
+
const code = fp.charCodeAt(index);
|
|
146
|
+
low = Math.imul(low ^ code, 2654435761);
|
|
147
|
+
high = Math.imul(high ^ code, 1597334677);
|
|
148
|
+
}
|
|
149
|
+
low = Math.imul(low ^ low >>> 16, 2246822507) ^ Math.imul(high ^ high >>> 13, 3266489909);
|
|
150
|
+
high = Math.imul(high ^ high >>> 16, 2246822507) ^ Math.imul(low ^ low >>> 13, 3266489909);
|
|
151
|
+
return 4294967296 * (high & 2097151) + (low >>> 0);
|
|
152
|
+
}
|
|
153
|
+
function extractFingerprintHashes(content, minLines, maxWindows) {
|
|
154
|
+
const rawLines = content.split(/\r?\n/);
|
|
155
|
+
const normalizedLines = rawLines.map(normalizeLine);
|
|
156
|
+
const fingerprints = /* @__PURE__ */ new Set();
|
|
157
|
+
const windowCount = Math.min(Math.max(rawLines.length - minLines + 1, 0), maxWindows);
|
|
158
|
+
for (let index = 0; index < windowCount; index += 1) {
|
|
159
|
+
const fingerprint = normalizedLines.slice(index, index + minLines).filter((line) => line.length > 0).join("\n");
|
|
160
|
+
if (fingerprint.length > 0) fingerprints.add(hashFingerprint(fingerprint));
|
|
161
|
+
}
|
|
162
|
+
return fingerprints;
|
|
163
|
+
}
|
|
164
|
+
function evictHookIndex() {
|
|
165
|
+
while (state.fileIndex.size > hookIndexBudgets.maxFiles || state.indexFingerprintCount > hookIndexBudgets.maxFingerprints) {
|
|
166
|
+
const oldest = state.fileIndex.keys().next();
|
|
167
|
+
if (oldest.done) break;
|
|
168
|
+
const key = oldest.value;
|
|
169
|
+
const entry = state.fileIndex.get(key);
|
|
170
|
+
if (entry) state.indexFingerprintCount -= entry.fingerprints.size;
|
|
171
|
+
state.fileIndex.delete(key);
|
|
172
|
+
state.hookIndexEvictions += 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
114
175
|
function extractWindows(filePath, content, minLines) {
|
|
115
176
|
const rawLines = content.split(/\r?\n/);
|
|
116
177
|
const windows = [];
|
|
@@ -153,14 +214,17 @@ function findDuplicates(files, minLines, maxFindings) {
|
|
|
153
214
|
}
|
|
154
215
|
return findings;
|
|
155
216
|
}
|
|
156
|
-
function scanPath(rawPath, cfg) {
|
|
217
|
+
async function scanPath(rawPath, cfg) {
|
|
157
218
|
const root = process.cwd();
|
|
158
219
|
const resolved = isAbsolute2(rawPath) ? resolve2(rawPath) : resolve2(root, rawPath);
|
|
159
|
-
const filePaths =
|
|
220
|
+
const filePaths = await collectSourceFilesAsync(resolved, {
|
|
221
|
+
extensions: cfg.extensions,
|
|
222
|
+
excludeDirs: cfg.excludeDirs
|
|
223
|
+
});
|
|
160
224
|
const files = /* @__PURE__ */ new Map();
|
|
161
225
|
for (const p of filePaths) {
|
|
162
226
|
try {
|
|
163
|
-
files.set(p,
|
|
227
|
+
files.set(p, await readFile(p, "utf-8"));
|
|
164
228
|
} catch {
|
|
165
229
|
}
|
|
166
230
|
}
|
|
@@ -220,6 +284,9 @@ var plugin = {
|
|
|
220
284
|
state.errorCount = 0;
|
|
221
285
|
state.lastHookWarning.clear();
|
|
222
286
|
state.fileIndex.clear();
|
|
287
|
+
state.indexFingerprintCount = 0;
|
|
288
|
+
state.hookIndexEvictions = 0;
|
|
289
|
+
state.oversizedFileSkips = 0;
|
|
223
290
|
if (state.hookUnregister) {
|
|
224
291
|
try {
|
|
225
292
|
state.hookUnregister();
|
|
@@ -228,77 +295,103 @@ var plugin = {
|
|
|
228
295
|
state.hookUnregister = null;
|
|
229
296
|
}
|
|
230
297
|
const cfg = readConfig(api.config.extensions?.["duplicate-code-detector"]);
|
|
231
|
-
function
|
|
298
|
+
async function readCachedFingerprints(filePath, minLines) {
|
|
232
299
|
let st;
|
|
233
300
|
try {
|
|
234
|
-
st =
|
|
301
|
+
st = await stat(filePath);
|
|
235
302
|
} catch {
|
|
236
303
|
return null;
|
|
237
304
|
}
|
|
238
305
|
const cached = state.fileIndex.get(filePath);
|
|
239
306
|
if (cached && cached.mtimeMs === st.mtimeMs && cached.size === st.size) {
|
|
240
|
-
|
|
307
|
+
state.fileIndex.delete(filePath);
|
|
308
|
+
state.fileIndex.set(filePath, cached);
|
|
309
|
+
return cached.fingerprints;
|
|
310
|
+
}
|
|
311
|
+
if (st.size > hookIndexBudgets.maxFileBytes) {
|
|
312
|
+
if (cached) {
|
|
313
|
+
state.indexFingerprintCount -= cached.fingerprints.size;
|
|
314
|
+
state.fileIndex.delete(filePath);
|
|
315
|
+
}
|
|
316
|
+
state.oversizedFileSkips += 1;
|
|
317
|
+
api.log.trace("duplicate-code-detector: skipped oversized file in hook index", {
|
|
318
|
+
file: relativePath(filePath),
|
|
319
|
+
sizeBytes: st.size,
|
|
320
|
+
maxFileBytes: hookIndexBudgets.maxFileBytes
|
|
321
|
+
});
|
|
322
|
+
return /* @__PURE__ */ new Set();
|
|
241
323
|
}
|
|
242
324
|
let content;
|
|
243
325
|
try {
|
|
244
|
-
content =
|
|
326
|
+
content = await readFile(filePath, "utf-8");
|
|
245
327
|
} catch {
|
|
246
328
|
return null;
|
|
247
329
|
}
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
330
|
+
const fingerprints = extractFingerprintHashes(
|
|
331
|
+
content,
|
|
332
|
+
minLines,
|
|
333
|
+
hookIndexBudgets.maxFingerprintsPerFile
|
|
334
|
+
);
|
|
335
|
+
if (cached) state.indexFingerprintCount -= cached.fingerprints.size;
|
|
336
|
+
state.fileIndex.set(filePath, { mtimeMs: st.mtimeMs, size: st.size, fingerprints });
|
|
337
|
+
state.indexFingerprintCount += fingerprints.size;
|
|
338
|
+
evictHookIndex();
|
|
339
|
+
return fingerprints;
|
|
251
340
|
}
|
|
252
|
-
const hook = (input) => {
|
|
341
|
+
const hook = async (input) => {
|
|
253
342
|
if (!cfg.enabled) return;
|
|
254
343
|
if (input.toolResult?.isError) return;
|
|
255
344
|
const inp = input.toolInput ?? {};
|
|
256
345
|
const sourcePath = inp["path"];
|
|
257
346
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
258
|
-
|
|
347
|
+
const projectRoot = resolve2(process.cwd());
|
|
348
|
+
const resolvedFile = isAbsolute2(sourcePath) ? resolve2(sourcePath) : resolve2(projectRoot, sourcePath);
|
|
349
|
+
if (!isWithinRoot(projectRoot, resolvedFile)) return;
|
|
350
|
+
let changedFile;
|
|
351
|
+
try {
|
|
352
|
+
changedFile = await realpath(resolvedFile);
|
|
353
|
+
} catch {
|
|
354
|
+
state.errorCount += 1;
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (!isWithinRoot(projectRoot, changedFile)) return;
|
|
259
358
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
260
|
-
if (!
|
|
359
|
+
if (!extensionsSet.has(ext)) return;
|
|
261
360
|
state.hookInvocationCount += 1;
|
|
262
361
|
const now = Date.now();
|
|
263
|
-
const lastWarning = state.lastHookWarning.get(
|
|
362
|
+
const lastWarning = state.lastHookWarning.get(changedFile);
|
|
264
363
|
if (lastWarning !== void 0 && now - lastWarning < 6e4) return;
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
if (changedWindows === null) {
|
|
364
|
+
const changedFps = await readCachedFingerprints(changedFile, cfg.minLines);
|
|
365
|
+
if (changedFps === null) {
|
|
268
366
|
state.errorCount += 1;
|
|
269
367
|
return;
|
|
270
368
|
}
|
|
271
|
-
if (
|
|
272
|
-
const projectRoot = resolve2(process.cwd());
|
|
369
|
+
if (changedFps.size === 0) return;
|
|
273
370
|
let otherFilePaths;
|
|
274
371
|
try {
|
|
275
|
-
otherFilePaths =
|
|
372
|
+
otherFilePaths = await collectSourceFilesAsync(projectRoot, {
|
|
276
373
|
extensions: cfg.extensions,
|
|
277
374
|
excludeDirs: cfg.excludeDirs
|
|
278
|
-
})
|
|
375
|
+
});
|
|
279
376
|
} catch {
|
|
280
377
|
state.errorCount += 1;
|
|
281
378
|
return;
|
|
282
379
|
}
|
|
283
|
-
const
|
|
380
|
+
const matched = /* @__PURE__ */ new Set();
|
|
284
381
|
for (const p of otherFilePaths) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
for (const ew of existingWindows) {
|
|
291
|
-
if (cw.fingerprint === ew.fingerprint) {
|
|
292
|
-
hits.push(ew);
|
|
293
|
-
break;
|
|
294
|
-
}
|
|
382
|
+
if (resolve2(p) === resolve2(changedFile)) continue;
|
|
383
|
+
const otherFps = await readCachedFingerprints(p, cfg.minLines);
|
|
384
|
+
if (otherFps === null || otherFps.size === 0) continue;
|
|
385
|
+
for (const fp of changedFps) {
|
|
386
|
+
if (!matched.has(fp) && otherFps.has(fp)) matched.add(fp);
|
|
295
387
|
}
|
|
388
|
+
if (matched.size === changedFps.size) break;
|
|
296
389
|
}
|
|
297
|
-
if (
|
|
298
|
-
state.warningCount +=
|
|
299
|
-
state.lastHookWarning.set(
|
|
390
|
+
if (matched.size === 0) return;
|
|
391
|
+
state.warningCount += matched.size;
|
|
392
|
+
state.lastHookWarning.set(changedFile, now);
|
|
300
393
|
return {
|
|
301
|
-
additionalContext: `\u26A0\uFE0F duplicate-code-detector: ${sourcePath} contains ${
|
|
394
|
+
additionalContext: `\u26A0\uFE0F duplicate-code-detector: ${sourcePath} contains ${matched.size} block(s) already present elsewhere. Run detect_duplicate_code for details.`,
|
|
302
395
|
contextAs: "separate"
|
|
303
396
|
};
|
|
304
397
|
};
|
|
@@ -324,7 +417,7 @@ var plugin = {
|
|
|
324
417
|
state.scanCount += 1;
|
|
325
418
|
let result;
|
|
326
419
|
try {
|
|
327
|
-
result = scanPath(rawPath, cfg);
|
|
420
|
+
result = await scanPath(rawPath, cfg);
|
|
328
421
|
} catch (err) {
|
|
329
422
|
state.errorCount += 1;
|
|
330
423
|
return { ok: false, error: String(err) };
|
|
@@ -360,7 +453,15 @@ var plugin = {
|
|
|
360
453
|
findings: state.findingCount,
|
|
361
454
|
hookInvocations: state.hookInvocationCount,
|
|
362
455
|
warnings: state.warningCount,
|
|
363
|
-
errors: state.errorCount
|
|
456
|
+
errors: state.errorCount,
|
|
457
|
+
// Hook fingerprint-index footprint (bounded; see hookIndexBudgets).
|
|
458
|
+
indexedFiles: state.fileIndex.size,
|
|
459
|
+
indexedFingerprints: state.indexFingerprintCount,
|
|
460
|
+
hookIndexEvictions: state.hookIndexEvictions,
|
|
461
|
+
oversizedFileSkips: state.oversizedFileSkips,
|
|
462
|
+
// Rough retained-bytes estimate: ~8B per numeric fingerprint + ~120B
|
|
463
|
+
// per file entry (key string + Set/entry overhead). Compact by design.
|
|
464
|
+
approxIndexBytes: state.indexFingerprintCount * 8 + state.fileIndex.size * 120
|
|
364
465
|
}
|
|
365
466
|
};
|
|
366
467
|
}
|
|
@@ -392,6 +493,10 @@ var plugin = {
|
|
|
392
493
|
state.warningCount = 0;
|
|
393
494
|
state.errorCount = 0;
|
|
394
495
|
state.lastHookWarning.clear();
|
|
496
|
+
state.fileIndex.clear();
|
|
497
|
+
state.indexFingerprintCount = 0;
|
|
498
|
+
state.hookIndexEvictions = 0;
|
|
499
|
+
state.oversizedFileSkips = 0;
|
|
395
500
|
api.log.info("duplicate-code-detector: teardown complete", { final });
|
|
396
501
|
},
|
|
397
502
|
async health() {
|
|
@@ -403,12 +508,18 @@ var plugin = {
|
|
|
403
508
|
findings: state.findingCount,
|
|
404
509
|
hookInvocations: state.hookInvocationCount,
|
|
405
510
|
warnings: state.warningCount,
|
|
406
|
-
errors: state.errorCount
|
|
511
|
+
errors: state.errorCount,
|
|
512
|
+
indexedFiles: state.fileIndex.size,
|
|
513
|
+
indexedFingerprints: state.indexFingerprintCount,
|
|
514
|
+
hookIndexEvictions: state.hookIndexEvictions,
|
|
515
|
+
oversizedFileSkips: state.oversizedFileSkips
|
|
407
516
|
}
|
|
408
517
|
};
|
|
409
518
|
}
|
|
410
519
|
};
|
|
411
520
|
var duplicate_code_detector_default = plugin;
|
|
412
521
|
export {
|
|
413
|
-
duplicate_code_detector_default as default
|
|
522
|
+
duplicate_code_detector_default as default,
|
|
523
|
+
hashFingerprint,
|
|
524
|
+
hookIndexBudgets
|
|
414
525
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/error-lens/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/error-lens/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAMrD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AA6FD,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBzE;AAUD,QAAA,MAAM,MAAM,EAAE,MAoOb,CAAC;eAEa,MAAM"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Plugin } from '@wrongstack/core/types';
|
|
2
|
+
export declare const OFFICIAL_PLUGIN_SPECIFIERS: readonly ['@wrongstack/plugins/agent-handoff', '@wrongstack/plugins/cost-tracker', '@wrongstack/plugins/file-watcher', '@wrongstack/plugins/git-autocommit', '@wrongstack/plugins/auto-doc', '@wrongstack/plugins/shell-check', '@wrongstack/plugins/cron', '@wrongstack/plugins/template-engine', '@wrongstack/plugins/semver-bump', '@wrongstack/plugins/secret-scanner', '@wrongstack/plugins/todo-tracker', '@wrongstack/plugins/token-budget', '@wrongstack/plugins/lint-gate', '@wrongstack/plugins/branch-guard', '@wrongstack/plugins/diff-summary', '@wrongstack/plugins/commit-validator', '@wrongstack/plugins/format-on-save', '@wrongstack/plugins/test-runner-gate', '@wrongstack/plugins/import-organizer', '@wrongstack/plugins/knowledge-graph', '@wrongstack/plugins/todo-listener', '@wrongstack/plugins/session-recap', '@wrongstack/plugins/spec-linker', '@wrongstack/plugins/loop-breaker', '@wrongstack/plugins/path-guard', '@wrongstack/plugins/process-guard', '@wrongstack/plugins/context-pins', '@wrongstack/plugins/checkpoint', '@wrongstack/plugins/error-lens', '@wrongstack/plugins/dep-guard', '@wrongstack/plugins/config-validator', '@wrongstack/plugins/notify-hub', '@wrongstack/plugins/changelog-writer', '@wrongstack/plugins/injection-shield', '@wrongstack/plugins/llm-cache', '@wrongstack/plugins/model-router', '@wrongstack/plugins/pr-drafter', '@wrongstack/plugins/prompt-firewall', '@wrongstack/plugins/auto-escalate', '@wrongstack/plugins/test-coverage-gate', '@wrongstack/plugins/type-gate', '@wrongstack/plugins/token-throttle', '@wrongstack/plugins/plugin-stack-observer', '@wrongstack/plugins/dead-code-detector', '@wrongstack/plugins/dependency-vulnerability-gate', '@wrongstack/plugins/migration-planner', '@wrongstack/plugins/semantic-search-indexer', '@wrongstack/plugins/auto-i18n-extractor', '@wrongstack/plugins/doc-sync-guard', '@wrongstack/plugins/api-compatibility-gate', '@wrongstack/plugins/performance-regression-gate', '@wrongstack/plugins/test-flake-detector', '@wrongstack/plugins/schema-evolution-guard', '@wrongstack/plugins/license-audit-gate', '@wrongstack/plugins/accessibility-auditor', '@wrongstack/plugins/security-hotspot-scanner', '@wrongstack/plugins/duplicate-code-detector', '@wrongstack/plugins/code-metrics', '@wrongstack/plugins/refactor-suggester', '@wrongstack/plugins/test-generator', '@wrongstack/plugins/release-notes-generator', '@wrongstack/plugins/smart-rename', '@wrongstack/plugins/feature-flag-tracker', '@wrongstack/plugins/interface-contract-guard'];
|
|
3
|
+
export declare const OFFICIAL_PLUGIN_FACTORIES: readonly (() => Promise<Plugin>)[];
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/factories/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD,eAAO,MAAM,0BAA0B,YACrC,mCAAmC,EACnC,kCAAkC,EAClC,kCAAkC,EAClC,oCAAoC,EACpC,8BAA8B,EAC9B,iCAAiC,EACjC,0BAA0B,EAC1B,qCAAqC,EACrC,iCAAiC,EACjC,oCAAoC,EACpC,kCAAkC,EAClC,kCAAkC,EAClC,+BAA+B,EAC/B,kCAAkC,EAClC,kCAAkC,EAClC,sCAAsC,EACtC,oCAAoC,EACpC,sCAAsC,EACtC,sCAAsC,EACtC,qCAAqC,EACrC,mCAAmC,EACnC,mCAAmC,EACnC,iCAAiC,EACjC,kCAAkC,EAClC,gCAAgC,EAChC,mCAAmC,EACnC,kCAAkC,EAClC,gCAAgC,EAChC,gCAAgC,EAChC,+BAA+B,EAC/B,sCAAsC,EACtC,gCAAgC,EAChC,sCAAsC,EACtC,sCAAsC,EACtC,+BAA+B,EAC/B,kCAAkC,EAClC,gCAAgC,EAChC,qCAAqC,EACrC,mCAAmC,EACnC,wCAAwC,EACxC,+BAA+B,EAC/B,oCAAoC,EACpC,2CAA2C,EAC3C,wCAAwC,EACxC,mDAAmD,EACnD,uCAAuC,EACvC,6CAA6C,EAC7C,yCAAyC,EACzC,oCAAoC,EACpC,4CAA4C,EAC5C,iDAAiD,EACjD,yCAAyC,EACzC,4CAA4C,EAC5C,wCAAwC,EACxC,2CAA2C,EAC3C,8CAA8C,EAC9C,6CAA6C,EAC7C,kCAAkC,EAClC,wCAAwC,EACxC,oCAAoC,EACpC,6CAA6C,EAC7C,kCAAkC,EAClC,0CAA0C,EAC1C,8CAA8C,CACtC,CAAC;AAEX,eAAO,MAAM,yBAAyB,EAAE,SAAS,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,EAGrE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './factories/index.js';
|