@wrongstack/plugins 0.281.3 → 0.282.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 +29 -3
- package/dist/accessibility-auditor.d.ts +40 -0
- package/dist/accessibility-auditor.js +411 -0
- package/dist/agent-handoff.d.ts +37 -0
- package/dist/agent-handoff.js +298 -0
- package/dist/api-compatibility-gate.d.ts +38 -0
- package/dist/api-compatibility-gate.js +357 -0
- package/dist/auto-i18n-extractor.d.ts +36 -0
- package/dist/auto-i18n-extractor.js +335 -0
- package/dist/checkpoint.js +18 -0
- package/dist/code-metrics.d.ts +31 -0
- package/dist/code-metrics.js +338 -0
- package/dist/commit-validator.js +67 -12
- package/dist/cost-tracker.js +58 -16
- package/dist/dead-code-detector.d.ts +34 -0
- package/dist/dead-code-detector.js +354 -0
- package/dist/dep-guard.js +47 -6
- package/dist/dependency-vulnerability-gate.d.ts +35 -0
- package/dist/dependency-vulnerability-gate.js +308 -0
- package/dist/diff-summary.js +97 -10
- package/dist/doc-sync-guard.d.ts +33 -0
- package/dist/doc-sync-guard.js +223 -0
- package/dist/duplicate-code-detector.d.ts +33 -0
- package/dist/duplicate-code-detector.js +384 -0
- package/dist/feature-flag-tracker.d.ts +38 -0
- package/dist/feature-flag-tracker.js +316 -0
- package/dist/file-watcher.js +85 -36
- package/dist/format-on-save.js +76 -10
- package/dist/import-organizer.js +73 -14
- package/dist/index.d.ts +27 -0
- package/dist/index.js +14067 -5054
- package/dist/interface-contract-guard.d.ts +37 -0
- package/dist/interface-contract-guard.js +302 -0
- package/dist/knowledge-graph.d.ts +45 -0
- package/dist/knowledge-graph.js +325 -0
- package/dist/license-audit-gate.d.ts +34 -0
- package/dist/license-audit-gate.js +260 -0
- package/dist/llm-cache.js +5 -0
- package/dist/loop-breaker.d.ts +0 -38
- package/dist/loop-breaker.js +209 -8
- package/dist/migration-planner.d.ts +30 -0
- package/dist/migration-planner.js +349 -0
- package/dist/model-router.js +5 -0
- package/dist/performance-regression-gate.d.ts +33 -0
- package/dist/performance-regression-gate.js +315 -0
- package/dist/plugin-stack-observer.d.ts +35 -0
- package/dist/plugin-stack-observer.js +125 -0
- package/dist/pr-drafter.d.ts +35 -0
- package/dist/pr-drafter.js +334 -0
- package/dist/prompt-firewall.js +5 -0
- package/dist/refactor-suggester.d.ts +38 -0
- package/dist/refactor-suggester.js +382 -0
- package/dist/release-notes-generator.d.ts +27 -0
- package/dist/release-notes-generator.js +209 -0
- package/dist/schema-evolution-guard.d.ts +42 -0
- package/dist/schema-evolution-guard.js +319 -0
- package/dist/security-hotspot-scanner.d.ts +30 -0
- package/dist/security-hotspot-scanner.js +402 -0
- package/dist/semantic-search-indexer.d.ts +38 -0
- package/dist/semantic-search-indexer.js +436 -0
- package/dist/shell-check.js +38 -3
- package/dist/smart-rename.d.ts +26 -0
- package/dist/smart-rename.js +170 -0
- package/dist/spec-linker.js +273 -133
- package/dist/test-coverage-gate.d.ts +37 -0
- package/dist/test-coverage-gate.js +263 -0
- package/dist/test-flake-detector.d.ts +27 -0
- package/dist/test-flake-detector.js +274 -0
- package/dist/test-generator.d.ts +32 -0
- package/dist/test-generator.js +243 -0
- package/dist/test-runner-gate.js +154 -22
- package/dist/todo-listener.d.ts +2 -2
- package/dist/todo-listener.js +5 -5
- package/dist/token-throttle.js +5 -0
- package/dist/type-gate.d.ts +37 -0
- package/dist/type-gate.js +311 -0
- package/package.json +112 -4
- package/LICENSE +0 -21
package/dist/import-organizer.js
CHANGED
|
@@ -1,7 +1,48 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { existsSync, statSync } from 'fs';
|
|
3
|
+
import { isAbsolute, resolve, relative, basename } from 'path';
|
|
3
4
|
|
|
4
5
|
// src/import-organizer/index.ts
|
|
6
|
+
function withinProject(p) {
|
|
7
|
+
if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
|
|
8
|
+
const root = process.cwd();
|
|
9
|
+
const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
|
|
10
|
+
const rel = relative(root, resolved);
|
|
11
|
+
if (rel === "" || rel === ".") return true;
|
|
12
|
+
if (rel.startsWith("..")) return false;
|
|
13
|
+
if (isAbsolute(rel)) return false;
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
var ALLOWED_FIRST_TOKENS = /* @__PURE__ */ new Set([
|
|
17
|
+
"npx",
|
|
18
|
+
"pnpm",
|
|
19
|
+
"npm",
|
|
20
|
+
"yarn",
|
|
21
|
+
"biome",
|
|
22
|
+
"@biomejs/biome",
|
|
23
|
+
"eslint",
|
|
24
|
+
"node"
|
|
25
|
+
// Recognise a fully-qualified project-local path like
|
|
26
|
+
// "./node_modules/.bin/biome"; basename check kicks in below.
|
|
27
|
+
]);
|
|
28
|
+
function resolveAllowedCommand(command) {
|
|
29
|
+
const tokens = command.split(/\s+/).filter(Boolean);
|
|
30
|
+
if (tokens.length === 0) return null;
|
|
31
|
+
const head = tokens[0];
|
|
32
|
+
if (ALLOWED_FIRST_TOKENS.has(head)) {
|
|
33
|
+
return { cmd: head, args: tokens.slice(1) };
|
|
34
|
+
}
|
|
35
|
+
if (isAbsolute(head)) {
|
|
36
|
+
if (!withinProject(head)) return null;
|
|
37
|
+
const base = basename(head);
|
|
38
|
+
if (ALLOWED_FIRST_TOKENS.has(base)) return { cmd: head, args: tokens.slice(1) };
|
|
39
|
+
}
|
|
40
|
+
if (!isAbsolute(head) && withinProject(head)) {
|
|
41
|
+
const base = basename(head);
|
|
42
|
+
if (ALLOWED_FIRST_TOKENS.has(base)) return { cmd: head, args: tokens.slice(1) };
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
5
46
|
var API_VERSION = "^0.1.10";
|
|
6
47
|
var state = {
|
|
7
48
|
invocationCount: 0,
|
|
@@ -17,7 +58,8 @@ var DEFAULTS = {
|
|
|
17
58
|
enabled: true,
|
|
18
59
|
command: "npx @biomejs/biome check --write --unsafe",
|
|
19
60
|
fallbackCommand: "npx eslint --fix",
|
|
20
|
-
timeoutMs: 1e4
|
|
61
|
+
timeoutMs: 1e4,
|
|
62
|
+
notifyFormatOnSave: true
|
|
21
63
|
};
|
|
22
64
|
function readConfig(raw) {
|
|
23
65
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
@@ -26,11 +68,12 @@ function readConfig(raw) {
|
|
|
26
68
|
enabled: r["enabled"] !== false,
|
|
27
69
|
command: typeof r["command"] === "string" && r["command"].length > 0 ? r["command"] : DEFAULTS.command,
|
|
28
70
|
fallbackCommand: typeof r["fallbackCommand"] === "string" && r["fallbackCommand"].length > 0 ? r["fallbackCommand"] : DEFAULTS.fallbackCommand,
|
|
29
|
-
timeoutMs: typeof r["timeoutMs"] === "number" && r["timeoutMs"] > 0 ? r["timeoutMs"] : DEFAULTS.timeoutMs
|
|
71
|
+
timeoutMs: typeof r["timeoutMs"] === "number" && r["timeoutMs"] > 0 ? r["timeoutMs"] : DEFAULTS.timeoutMs,
|
|
72
|
+
notifyFormatOnSave: r["notifyFormatOnSave"] !== false
|
|
30
73
|
};
|
|
31
74
|
}
|
|
32
75
|
function runCommand(command, args, timeoutMs, cwd) {
|
|
33
|
-
return new Promise((
|
|
76
|
+
return new Promise((resolve2) => {
|
|
34
77
|
let timedOut = false;
|
|
35
78
|
const stdoutChunks = [];
|
|
36
79
|
const stderrChunks = [];
|
|
@@ -42,17 +85,17 @@ function runCommand(command, args, timeoutMs, cwd) {
|
|
|
42
85
|
signal: AbortSignal.timeout(timeoutMs)
|
|
43
86
|
});
|
|
44
87
|
} catch {
|
|
45
|
-
|
|
88
|
+
resolve2({ code: 127, stdout: "", stderr: "", timedOut: false });
|
|
46
89
|
return;
|
|
47
90
|
}
|
|
48
91
|
child.stdout?.on("data", (c) => stdoutChunks.push(c));
|
|
49
92
|
child.stderr?.on("data", (c) => stderrChunks.push(c));
|
|
50
93
|
child.on("error", () => {
|
|
51
|
-
|
|
94
|
+
resolve2({ code: 127, stdout: "", stderr: "", timedOut: false });
|
|
52
95
|
});
|
|
53
96
|
child.on("close", (code) => {
|
|
54
97
|
if (timedOut) return;
|
|
55
|
-
|
|
98
|
+
resolve2({
|
|
56
99
|
code,
|
|
57
100
|
stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
|
|
58
101
|
stderr: Buffer.concat(stderrChunks).toString("utf-8"),
|
|
@@ -61,11 +104,12 @@ function runCommand(command, args, timeoutMs, cwd) {
|
|
|
61
104
|
});
|
|
62
105
|
child.on("abort", () => {
|
|
63
106
|
timedOut = true;
|
|
64
|
-
|
|
107
|
+
resolve2({ code: null, stdout: "", stderr: "", timedOut: true });
|
|
65
108
|
});
|
|
66
109
|
});
|
|
67
110
|
}
|
|
68
111
|
async function organizeImports(filePath, cfg, cwd) {
|
|
112
|
+
if (!withinProject(filePath)) return null;
|
|
69
113
|
if (!existsSync(filePath)) return null;
|
|
70
114
|
let bytesBefore;
|
|
71
115
|
try {
|
|
@@ -73,15 +117,15 @@ async function organizeImports(filePath, cfg, cwd) {
|
|
|
73
117
|
} catch {
|
|
74
118
|
return null;
|
|
75
119
|
}
|
|
76
|
-
const primary = cfg.command
|
|
77
|
-
if (primary
|
|
78
|
-
const [primaryCmd, ...primaryArgs] = primary;
|
|
120
|
+
const primary = resolveAllowedCommand(cfg.command);
|
|
121
|
+
if (!primary) return null;
|
|
122
|
+
const [primaryCmd, ...primaryArgs] = [primary.cmd, ...primary.args];
|
|
79
123
|
let result = await runCommand(primaryCmd, [...primaryArgs, filePath], cfg.timeoutMs, cwd);
|
|
80
124
|
let usedCommand = cfg.command;
|
|
81
125
|
if (result.code === 127 && cfg.fallbackCommand) {
|
|
82
|
-
const fallback = cfg.fallbackCommand
|
|
83
|
-
if (fallback
|
|
84
|
-
const [fbCmd, ...fbArgs] = fallback;
|
|
126
|
+
const fallback = resolveAllowedCommand(cfg.fallbackCommand);
|
|
127
|
+
if (fallback) {
|
|
128
|
+
const [fbCmd, ...fbArgs] = [fallback.cmd, ...fallback.args];
|
|
85
129
|
result = await runCommand(fbCmd, [...fbArgs, filePath], cfg.timeoutMs, cwd);
|
|
86
130
|
usedCommand = cfg.fallbackCommand;
|
|
87
131
|
}
|
|
@@ -132,6 +176,11 @@ var plugin = {
|
|
|
132
176
|
minimum: 1e3,
|
|
133
177
|
default: 1e4,
|
|
134
178
|
description: "Per-invocation linter timeout in milliseconds."
|
|
179
|
+
},
|
|
180
|
+
notifyFormatOnSave: {
|
|
181
|
+
type: "boolean",
|
|
182
|
+
default: true,
|
|
183
|
+
description: "Emit `import-organizer:done` after each successful run so `format-on-save` can skip its redundant `biome format --write` pass on the same file. Set false to keep both running unconditionally."
|
|
135
184
|
}
|
|
136
185
|
}
|
|
137
186
|
},
|
|
@@ -160,13 +209,23 @@ var plugin = {
|
|
|
160
209
|
if (!state.linterAvailable) {
|
|
161
210
|
state.linterAvailable = false;
|
|
162
211
|
state.probeComplete = true;
|
|
163
|
-
api.log.warn(
|
|
212
|
+
api.log.warn(
|
|
213
|
+
"import-organizer: no linter available \u2014 hook will be a no-op for the rest of the session"
|
|
214
|
+
);
|
|
164
215
|
}
|
|
165
216
|
state.errorCount += 1;
|
|
166
217
|
return;
|
|
167
218
|
}
|
|
168
219
|
state.linterAvailable = true;
|
|
169
220
|
state.probeComplete = true;
|
|
221
|
+
if (cfg.notifyFormatOnSave) {
|
|
222
|
+
api.emitCustom("import-organizer:done", {
|
|
223
|
+
path: filePath,
|
|
224
|
+
changed: result.changed,
|
|
225
|
+
command: result.command,
|
|
226
|
+
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
227
|
+
});
|
|
228
|
+
}
|
|
170
229
|
state.lastResult = {
|
|
171
230
|
path: filePath,
|
|
172
231
|
tool: toolName,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { default as agentHandoffPlugin } from './agent-handoff.js';
|
|
1
2
|
export { default as autoDocPlugin } from './auto-doc.js';
|
|
2
3
|
export { default as autoEscalatePlugin } from './auto-escalate.js';
|
|
3
4
|
export { default as branchGuardPlugin } from './branch-guard.js';
|
|
@@ -16,12 +17,15 @@ export { default as formatOnSavePlugin } from './format-on-save.js';
|
|
|
16
17
|
export { default as gitAutocommitPlugin } from './git-autocommit.js';
|
|
17
18
|
export { default as importOrganizerPlugin } from './import-organizer.js';
|
|
18
19
|
export { default as injectionShieldPlugin } from './injection-shield.js';
|
|
20
|
+
export { default as knowledgeGraphPlugin } from './knowledge-graph.js';
|
|
19
21
|
export { default as lintGatePlugin } from './lint-gate.js';
|
|
20
22
|
export { default as llmCachePlugin } from './llm-cache.js';
|
|
21
23
|
export { default as loopBreakerPlugin } from './loop-breaker.js';
|
|
22
24
|
export { default as modelRouterPlugin } from './model-router.js';
|
|
23
25
|
export { default as notifyHubPlugin } from './notify-hub.js';
|
|
24
26
|
export { default as pathGuardPlugin } from './path-guard.js';
|
|
27
|
+
export { default as pluginStackObserverPlugin } from './plugin-stack-observer.js';
|
|
28
|
+
export { default as prDrafterPlugin } from './pr-drafter.js';
|
|
25
29
|
export { default as promptFirewallPlugin } from './prompt-firewall.js';
|
|
26
30
|
export { default as secretScannerPlugin } from './secret-scanner.js';
|
|
27
31
|
export { default as semverBumpPlugin } from './semver-bump.js';
|
|
@@ -29,7 +33,30 @@ export { default as sessionRecapPlugin } from './session-recap.js';
|
|
|
29
33
|
export { default as shellCheckPlugin } from './shell-check.js';
|
|
30
34
|
export { default as specLinkerPlugin } from './spec-linker.js';
|
|
31
35
|
export { default as templateEnginePlugin } from './template-engine.js';
|
|
36
|
+
export { default as testCoverageGatePlugin } from './test-coverage-gate.js';
|
|
32
37
|
export { default as testRunnerGatePlugin } from './test-runner-gate.js';
|
|
38
|
+
export { default as typeGatePlugin } from './type-gate.js';
|
|
39
|
+
export { default as accessibilityAuditorPlugin } from './accessibility-auditor.js';
|
|
40
|
+
export { default as apiCompatibilityGatePlugin } from './api-compatibility-gate.js';
|
|
41
|
+
export { default as autoI18nExtractorPlugin } from './auto-i18n-extractor.js';
|
|
42
|
+
export { default as codeMetricsPlugin } from './code-metrics.js';
|
|
43
|
+
export { default as deadCodeDetectorPlugin } from './dead-code-detector.js';
|
|
44
|
+
export { default as dependencyVulnerabilityGatePlugin } from './dependency-vulnerability-gate.js';
|
|
45
|
+
export { default as docSyncGuardPlugin } from './doc-sync-guard.js';
|
|
46
|
+
export { default as duplicateCodeDetectorPlugin } from './duplicate-code-detector.js';
|
|
47
|
+
export { default as featureFlagTrackerPlugin } from './feature-flag-tracker.js';
|
|
48
|
+
export { default as interfaceContractGuardPlugin } from './interface-contract-guard.js';
|
|
49
|
+
export { default as licenseAuditGatePlugin } from './license-audit-gate.js';
|
|
50
|
+
export { default as migrationPlannerPlugin } from './migration-planner.js';
|
|
51
|
+
export { default as performanceRegressionGatePlugin } from './performance-regression-gate.js';
|
|
52
|
+
export { default as refactorSuggesterPlugin } from './refactor-suggester.js';
|
|
53
|
+
export { default as releaseNotesGeneratorPlugin } from './release-notes-generator.js';
|
|
54
|
+
export { default as schemaEvolutionGuardPlugin } from './schema-evolution-guard.js';
|
|
55
|
+
export { default as securityHotspotScannerPlugin } from './security-hotspot-scanner.js';
|
|
56
|
+
export { default as semanticSearchIndexerPlugin } from './semantic-search-indexer.js';
|
|
57
|
+
export { default as smartRenamePlugin } from './smart-rename.js';
|
|
58
|
+
export { default as testFlakeDetectorPlugin } from './test-flake-detector.js';
|
|
59
|
+
export { default as testGeneratorPlugin } from './test-generator.js';
|
|
33
60
|
export { default as todoListenerPlugin } from './todo-listener.js';
|
|
34
61
|
export { default as todoTrackerPlugin } from './todo-tracker.js';
|
|
35
62
|
export { default as tokenBudgetPlugin } from './token-budget.js';
|