@wrongstack/plugins 0.316.2 → 0.317.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accessibility-auditor.js +12 -10
- package/dist/agent-handoff.js +30 -10
- package/dist/auto-doc.js +22 -9
- package/dist/auto-escalate.js +17 -7
- package/dist/auto-i18n-extractor.js +19 -9
- package/dist/branch-guard.js +12 -9
- package/dist/changelog-writer/index.d.ts +3 -3
- package/dist/changelog-writer.js +59 -14
- package/dist/checkpoint.js +18 -7
- package/dist/code-metrics.js +17 -9
- package/dist/commit-validator.js +18 -11
- package/dist/config-validator.js +5 -3
- package/dist/context-pins.js +21 -9
- package/dist/cost-tracker.js +24 -16
- package/dist/cron.js +17 -13
- package/dist/dead-code-detector.js +5 -4
- package/dist/dep-guard.js +5 -4
- package/dist/dependency-vulnerability-gate.js +64 -24
- package/dist/diff-summary.js +6 -2
- package/dist/doc-sync-guard.js +12 -2
- package/dist/duplicate-code-detector.js +87 -15
- package/dist/error-lens.js +6 -5
- package/dist/feature-flag-tracker.js +43 -9
- package/dist/file-watcher.js +26 -3
- package/dist/format-on-save.js +9 -5
- package/dist/git-autocommit.js +20 -12
- package/dist/gitignore-guard.js +7 -4
- package/dist/import-organizer.js +9 -5
- package/dist/index.js +1684 -751
- package/dist/injection-shield/index.d.ts +1 -0
- package/dist/injection-shield.js +30 -5
- package/dist/interface-contract-guard.js +4 -2
- package/dist/knowledge-graph.js +43 -16
- package/dist/license-audit-gate.js +61 -8
- package/dist/lint-gate.js +13 -5
- package/dist/llm-cache.js +20 -6
- package/dist/loop-breaker.js +16 -8
- package/dist/migration-planner.js +80 -11
- package/dist/model-router.js +16 -9
- package/dist/notify-hub.js +14 -5
- package/dist/path-guard.js +7 -3
- package/dist/performance-regression-gate.js +12 -6
- package/dist/plugin-stack-observer.js +25 -3
- package/dist/pr-drafter.js +16 -7
- package/dist/process-guard.js +2 -1
- package/dist/prompt-firewall.js +9 -7
- package/dist/refactor-suggester.js +37 -8
- package/dist/release-notes-generator/index.d.ts +9 -0
- package/dist/release-notes-generator.js +50 -12
- package/dist/schema-evolution-guard.js +33 -6
- package/dist/secret-scanner.js +10 -7
- package/dist/security-hotspot-scanner.js +13 -8
- package/dist/semantic-search-indexer/index.d.ts +11 -0
- package/dist/semantic-search-indexer.js +67 -19
- package/dist/semver-bump/index.d.ts +3 -3
- package/dist/semver-bump.js +30 -15
- package/dist/session-recap/index.d.ts +16 -0
- package/dist/session-recap.js +18 -9
- package/dist/shell-check.js +29 -7
- package/dist/smart-rename.js +18 -9
- package/dist/spec-linker.js +70 -19
- package/dist/template-engine.js +24 -14
- package/dist/test-coverage-gate.js +1 -1
- package/dist/test-flake-detector.js +28 -5
- package/dist/test-generator/index.d.ts +10 -0
- package/dist/test-generator.js +35 -13
- package/dist/todo-listener.js +2 -2
- package/dist/todo-tracker.js +19 -11
- package/dist/token-budget.js +14 -9
- package/dist/token-throttle.js +8 -3
- package/dist/type-gate.js +9 -5
- package/package.json +5 -5
package/dist/commit-validator.js
CHANGED
|
@@ -42,14 +42,19 @@ var DEFAULTS = {
|
|
|
42
42
|
function readConfig(raw) {
|
|
43
43
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
44
44
|
const r = raw;
|
|
45
|
+
const rawMode = typeof (r["mode"] ?? r["action"] ?? r["behavior"]) === "string" ? String(r["mode"] ?? r["action"] ?? r["behavior"]).trim().toLowerCase() : void 0;
|
|
46
|
+
const mode = rawMode === "warn" ? "warn" : "block";
|
|
47
|
+
const rawTypes = r["allowedTypes"] ?? r["allowed_types"] ?? r["types"];
|
|
48
|
+
const rawMaxSubj = r["maxSubjectLength"] ?? r["max_subject_length"] ?? r["maxLength"] ?? r["max_length"];
|
|
49
|
+
const rawMinBody = r["minBodyLength"] ?? r["min_body_length"] ?? r["minLength"] ?? r["min_length"];
|
|
45
50
|
return {
|
|
46
|
-
mode
|
|
47
|
-
requireScope: r["requireScope"] === true,
|
|
48
|
-
allowedTypes: Array.isArray(
|
|
49
|
-
maxSubjectLength: typeof
|
|
50
|
-
bodyRequired: r["bodyRequired"] === true,
|
|
51
|
-
minBodyLength: typeof
|
|
52
|
-
suggestFix: r["suggestFix"] === true
|
|
51
|
+
mode,
|
|
52
|
+
requireScope: (r["requireScope"] ?? r["require_scope"]) === true,
|
|
53
|
+
allowedTypes: Array.isArray(rawTypes) ? rawTypes.filter((x) => typeof x === "string") : [],
|
|
54
|
+
maxSubjectLength: typeof rawMaxSubj === "number" && rawMaxSubj > 0 ? rawMaxSubj : DEFAULTS.maxSubjectLength,
|
|
55
|
+
bodyRequired: (r["bodyRequired"] ?? r["body_required"] ?? r["requireBody"] ?? r["require_body"]) === true,
|
|
56
|
+
minBodyLength: typeof rawMinBody === "number" && rawMinBody > 0 ? rawMinBody : DEFAULTS.minBodyLength,
|
|
57
|
+
suggestFix: (r["suggestFix"] ?? r["suggest_fix"]) === true
|
|
53
58
|
};
|
|
54
59
|
}
|
|
55
60
|
var STANDARD_TYPES = [
|
|
@@ -63,7 +68,9 @@ var STANDARD_TYPES = [
|
|
|
63
68
|
"build",
|
|
64
69
|
"ci",
|
|
65
70
|
"chore",
|
|
66
|
-
"revert"
|
|
71
|
+
"revert",
|
|
72
|
+
"i18n",
|
|
73
|
+
"a11y"
|
|
67
74
|
];
|
|
68
75
|
function parseCommitMessage(message, cfg) {
|
|
69
76
|
const errors = [];
|
|
@@ -78,7 +85,7 @@ function parseCommitMessage(message, cfg) {
|
|
|
78
85
|
errors: ["empty commit message"]
|
|
79
86
|
};
|
|
80
87
|
}
|
|
81
|
-
const match = firstLine.match(/^([a-zA-Z]
|
|
88
|
+
const match = firstLine.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(?:\(([^)]+)\))?(!)?:\s*(.+)$/);
|
|
82
89
|
if (!match) {
|
|
83
90
|
errors.push(
|
|
84
91
|
`Message does not match conventional-commit format: "<type>[(scope)][!]: <description>". Got: "${firstLine.slice(0, 60)}"`
|
|
@@ -219,7 +226,7 @@ var plugin = {
|
|
|
219
226
|
const inp = input.toolInput ?? {};
|
|
220
227
|
let message = null;
|
|
221
228
|
if (toolName === "git_autocommit") {
|
|
222
|
-
message = inp["message"] ?? null;
|
|
229
|
+
message = inp["message"] ?? inp["msg"] ?? inp["commitMessage"] ?? inp["commit_message"] ?? inp["description"] ?? inp["summary"] ?? inp["text"] ?? null;
|
|
223
230
|
if (!message) {
|
|
224
231
|
const type = inp["type"];
|
|
225
232
|
if (type && cfg.allowedTypes.length > 0 && !cfg.allowedTypes.includes(type)) {
|
|
@@ -249,7 +256,7 @@ var plugin = {
|
|
|
249
256
|
return;
|
|
250
257
|
}
|
|
251
258
|
} else if (toolName === "bash") {
|
|
252
|
-
const command = inp["command"];
|
|
259
|
+
const command = inp["command"] ?? inp["CommandLine"] ?? inp["cmd"] ?? inp["script"] ?? inp["input"];
|
|
253
260
|
if (typeof command !== "string") return;
|
|
254
261
|
if (!/\bgit\s+commit\b/.test(command)) return;
|
|
255
262
|
message = extractMessageFromBash(command);
|
package/dist/config-validator.js
CHANGED
|
@@ -37,10 +37,12 @@ var DEFAULTS = {
|
|
|
37
37
|
function readConfig(raw) {
|
|
38
38
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS, extensions: [...DEFAULT_EXTENSIONS] };
|
|
39
39
|
const r = raw;
|
|
40
|
+
const rawExts = r["extensions"] ?? r["file_extensions"] ?? r["fileExtensions"];
|
|
41
|
+
const rawMax = r["maxFileBytes"] ?? r["max_file_bytes"] ?? r["maxBytes"] ?? r["max_bytes"];
|
|
40
42
|
return {
|
|
41
43
|
enabled: r["enabled"] !== false,
|
|
42
|
-
extensions: Array.isArray(
|
|
43
|
-
maxFileBytes: typeof
|
|
44
|
+
extensions: Array.isArray(rawExts) ? rawExts.filter((e) => typeof e === "string" && e.trim().length > 0).map((e) => e.trim().startsWith(".") ? e.trim().toLowerCase() : `.${e.trim().toLowerCase()}`) : [...DEFAULT_EXTENSIONS],
|
|
45
|
+
maxFileBytes: typeof rawMax === "number" && rawMax >= 1024 ? rawMax : DEFAULTS.maxFileBytes
|
|
44
46
|
};
|
|
45
47
|
}
|
|
46
48
|
function stripJsonc(text) {
|
|
@@ -304,7 +306,7 @@ var plugin = {
|
|
|
304
306
|
if (input.toolResult?.isError) return;
|
|
305
307
|
state.invocations += 1;
|
|
306
308
|
const ti = input.toolInput ?? {};
|
|
307
|
-
const raw = ti["path"] ?? ti["file_path"] ?? ti["filePath"];
|
|
309
|
+
const raw = ti["path"] ?? ti["file_path"] ?? ti["filePath"] ?? ti["TargetFile"] ?? ti["targetFile"] ?? ti["file"];
|
|
308
310
|
if (typeof raw !== "string" || raw.length === 0) return;
|
|
309
311
|
if (!(0, runtime_exports.withinProject)(raw)) return;
|
|
310
312
|
const lower = raw.toLowerCase();
|
package/dist/context-pins.js
CHANGED
|
@@ -27,12 +27,14 @@ function resolveProjectPath(rawPath, cwd = process.cwd()) {
|
|
|
27
27
|
function readConfig(raw) {
|
|
28
28
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
29
29
|
const r = raw;
|
|
30
|
-
const rawPath = typeof r["filePath"] === "string" ? r["filePath"] : DEFAULTS.filePath;
|
|
30
|
+
const rawPath = typeof r["filePath"] === "string" ? r["filePath"] : typeof r["file_path"] === "string" ? r["file_path"] : typeof r["path"] === "string" ? r["path"] : typeof r["file"] === "string" ? r["file"] : DEFAULTS.filePath;
|
|
31
|
+
const rawMaxPins = r["maxPins"] ?? r["max_pins"] ?? r["limit"];
|
|
32
|
+
const rawMaxChars = r["maxPinChars"] ?? r["max_pin_chars"] ?? r["maxChars"] ?? r["max_chars"];
|
|
31
33
|
return {
|
|
32
34
|
enabled: r["enabled"] !== false,
|
|
33
35
|
filePath: rawPath ? resolveProjectPath(rawPath) ?? "" : "",
|
|
34
|
-
maxPins: typeof
|
|
35
|
-
maxPinChars: typeof
|
|
36
|
+
maxPins: typeof rawMaxPins === "number" && rawMaxPins >= 1 && rawMaxPins <= 100 ? rawMaxPins : DEFAULTS.maxPins,
|
|
37
|
+
maxPinChars: typeof rawMaxChars === "number" && rawMaxChars >= 20 ? rawMaxChars : DEFAULTS.maxPinChars
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
function loadPins(filePath) {
|
|
@@ -42,7 +44,11 @@ function loadPins(filePath) {
|
|
|
42
44
|
const pins = Array.isArray(raw.pins) ? raw.pins.filter(
|
|
43
45
|
(p) => !!p && typeof p === "object" && typeof p.id === "string" && typeof p.text === "string"
|
|
44
46
|
) : [];
|
|
45
|
-
const
|
|
47
|
+
const maxExistingId = pins.reduce((max, p) => {
|
|
48
|
+
const num = parseInt(p.id.replace(/\D/g, ""), 10);
|
|
49
|
+
return Number.isFinite(num) && num > max ? num : max;
|
|
50
|
+
}, 0);
|
|
51
|
+
const nextId = typeof raw.nextId === "number" && raw.nextId > maxExistingId ? raw.nextId : maxExistingId + 1;
|
|
46
52
|
return { pins, nextId };
|
|
47
53
|
} catch {
|
|
48
54
|
return { pins: [], nextId: 1 };
|
|
@@ -133,7 +139,9 @@ var plugin = {
|
|
|
133
139
|
mutating: true,
|
|
134
140
|
async execute(input) {
|
|
135
141
|
if (!cfg.enabled) return { ok: false, error: "context-pins is disabled" };
|
|
136
|
-
const
|
|
142
|
+
const raw = input ?? {};
|
|
143
|
+
const rawText = input.text ?? raw["pin"] ?? raw["content"] ?? raw["message"] ?? raw["note"] ?? raw["fact"] ?? raw["data"];
|
|
144
|
+
const text = String(rawText ?? "").trim();
|
|
137
145
|
if (!text) return { ok: false, error: "pin text must not be empty" };
|
|
138
146
|
if (state.pins.length >= cfg.maxPins) {
|
|
139
147
|
return {
|
|
@@ -160,16 +168,20 @@ var plugin = {
|
|
|
160
168
|
inputSchema: {
|
|
161
169
|
type: "object",
|
|
162
170
|
properties: {
|
|
163
|
-
id: { type: "string", description: "Pin id (pin-N) or label to remove." }
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
id: { type: "string", description: "Pin id (pin-N) or label to remove." },
|
|
172
|
+
label: { type: "string", description: "Alternative label to remove." }
|
|
173
|
+
}
|
|
166
174
|
},
|
|
167
175
|
permission: "auto",
|
|
168
176
|
category: "Memory",
|
|
169
177
|
mutating: true,
|
|
170
178
|
async execute(input) {
|
|
171
179
|
if (!cfg.enabled) return { ok: false, error: "context-pins is disabled" };
|
|
172
|
-
const
|
|
180
|
+
const raw = input ?? {};
|
|
181
|
+
const key = String(
|
|
182
|
+
input.id ?? input.label ?? raw["pinId"] ?? raw["pin_id"] ?? raw["name"] ?? raw["key"] ?? ""
|
|
183
|
+
).trim();
|
|
184
|
+
if (!key) return { ok: false, error: "id or label is required" };
|
|
173
185
|
const before = state.pins.length;
|
|
174
186
|
state.pins = state.pins.filter((p) => p.id !== key && p.label !== key);
|
|
175
187
|
const removed = before - state.pins.length;
|
package/dist/cost-tracker.js
CHANGED
|
@@ -40,11 +40,13 @@ var digestCounters = {
|
|
|
40
40
|
mailboxDigestErrors: 0
|
|
41
41
|
};
|
|
42
42
|
function readCostTrackerConfig(raw) {
|
|
43
|
-
const digestEveryN = raw?.["mailboxDigestEveryN"];
|
|
44
|
-
const digestTo = raw?.["mailboxDigestTo"];
|
|
43
|
+
const digestEveryN = raw?.["mailboxDigestEveryN"] ?? raw?.["mailbox_digest_every_n"] ?? raw?.["digestEveryN"];
|
|
44
|
+
const digestTo = raw?.["mailboxDigestTo"] ?? raw?.["mailbox_digest_to"] ?? raw?.["digestTo"];
|
|
45
|
+
const rawBudget = raw?.["budgetLimit"] ?? raw?.["budget_limit"] ?? raw?.["budget"] ?? raw?.["limit"];
|
|
46
|
+
const rawThreshold = raw?.["warningThreshold"] ?? raw?.["warning_threshold"] ?? raw?.["warnThreshold"] ?? raw?.["warn_threshold"] ?? raw?.["threshold"];
|
|
45
47
|
return {
|
|
46
|
-
budgetLimit: typeof
|
|
47
|
-
warningThreshold: typeof
|
|
48
|
+
budgetLimit: typeof rawBudget === "number" ? rawBudget : 0,
|
|
49
|
+
warningThreshold: typeof rawThreshold === "number" ? rawThreshold : 80,
|
|
48
50
|
mailboxDigestEveryN: typeof digestEveryN === "number" && digestEveryN >= 0 ? Math.floor(digestEveryN) : 0,
|
|
49
51
|
mailboxDigestTo: typeof digestTo === "string" && digestTo.length > 0 ? digestTo : "cost-tracker"
|
|
50
52
|
};
|
|
@@ -127,7 +129,7 @@ var plugin = {
|
|
|
127
129
|
digestCounters.mailboxDigestErrors = 0;
|
|
128
130
|
const rawConfig = api.config.extensions?.["cost-tracker"];
|
|
129
131
|
const cfg = readCostTrackerConfig(rawConfig);
|
|
130
|
-
const userOverrides = rawConfig?.["pricingOverrides"];
|
|
132
|
+
const userOverrides = rawConfig?.["pricingOverrides"] ?? rawConfig?.["pricing_overrides"] ?? rawConfig?.["pricing"];
|
|
131
133
|
if (userOverrides && typeof userOverrides === "object") {
|
|
132
134
|
for (const [model, value] of Object.entries(userOverrides)) {
|
|
133
135
|
if (!value || typeof value !== "object") continue;
|
|
@@ -183,10 +185,13 @@ var plugin = {
|
|
|
183
185
|
api.onEvent("provider.response", async (payload) => {
|
|
184
186
|
const usage = payload.usage;
|
|
185
187
|
const model = payload.ctx?.model ?? "unknown";
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
+
const u = usage ?? {};
|
|
189
|
+
const cachedTokens = Number(u["cacheRead"] ?? u["cache_read_input_tokens"] ?? u["cached_prompt_tokens"] ?? 0) || 0;
|
|
190
|
+
const rawInput = Number(u["input"] ?? u["prompt_tokens"] ?? u["inputTokens"] ?? u["promptTokens"] ?? 0) || 0;
|
|
191
|
+
const rawCacheWrite = Number(u["cacheWrite"] ?? u["cache_creation_input_tokens"] ?? 0) || 0;
|
|
192
|
+
const freshTokens = rawInput + rawCacheWrite;
|
|
188
193
|
const promptTokens = freshTokens + cachedTokens;
|
|
189
|
-
const completionTokens =
|
|
194
|
+
const completionTokens = Number(u["output"] ?? u["completion_tokens"] ?? u["outputTokens"] ?? u["completionTokens"] ?? 0) || 0;
|
|
190
195
|
const totalTokens = promptTokens + completionTokens;
|
|
191
196
|
const costUsd = estimateCost(model, freshTokens, completionTokens, cachedTokens);
|
|
192
197
|
const record = {
|
|
@@ -351,14 +356,17 @@ by model: ${top || "(none)"}`
|
|
|
351
356
|
});
|
|
352
357
|
api.onEvent("session.ended", async () => {
|
|
353
358
|
if (sessionCost.requests.length > 0) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
359
|
+
try {
|
|
360
|
+
await api.session?.append?.({
|
|
361
|
+
type: "cost-tracker:session_summary",
|
|
362
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
363
|
+
totalTokens: sessionCost.totalTokens,
|
|
364
|
+
totalCostUsd: sessionCost.totalCostUsd,
|
|
365
|
+
totalRequests: sessionCost.requests.length,
|
|
366
|
+
byModel: sessionCost.byModel
|
|
367
|
+
});
|
|
368
|
+
} catch {
|
|
369
|
+
}
|
|
362
370
|
}
|
|
363
371
|
});
|
|
364
372
|
api.log.info("cost-tracker plugin loaded", { version: "0.1.0" });
|
package/dist/cron.js
CHANGED
|
@@ -107,13 +107,16 @@ var plugin = {
|
|
|
107
107
|
activeJobs++;
|
|
108
108
|
promises.push(
|
|
109
109
|
(async () => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
try {
|
|
111
|
+
await api.session?.append?.({
|
|
112
|
+
type: "cron:scheduled_trigger",
|
|
113
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
114
|
+
jobName: name,
|
|
115
|
+
action: job.action,
|
|
116
|
+
runCount: job.runCount + 1
|
|
117
|
+
});
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
117
120
|
api.emitCustom("cron:job_due", {
|
|
118
121
|
name,
|
|
119
122
|
action: job.action,
|
|
@@ -152,14 +155,15 @@ var plugin = {
|
|
|
152
155
|
mutating: false,
|
|
153
156
|
capabilities: [COORDINATION_CRON_CAPABILITY],
|
|
154
157
|
async execute(input) {
|
|
155
|
-
const name = input["name"];
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
+
const name = input["name"] ?? input["jobName"] ?? input["job_name"] ?? input["job"] ?? input["id"];
|
|
159
|
+
const rawInterval = input["intervalMs"] ?? input["interval_ms"] ?? input["interval"] ?? input["every"] ?? input["period"];
|
|
160
|
+
const intervalMs = Math.max(1e3, Number(rawInterval));
|
|
161
|
+
const action = input["action"] ?? input["task"] ?? input["command"] ?? input["run"];
|
|
158
162
|
const enabled = input["enabled"] ?? true;
|
|
159
163
|
if (!name || typeof name !== "string" || name.trim() === "") {
|
|
160
164
|
return { ok: false, error: "name is required and must be a non-empty string" };
|
|
161
165
|
}
|
|
162
|
-
if (Number.isNaN(intervalMs)) {
|
|
166
|
+
if (Number.isNaN(intervalMs) || rawInterval === void 0 || rawInterval === null) {
|
|
163
167
|
return { ok: false, error: "intervalMs must be a number >= 1000" };
|
|
164
168
|
}
|
|
165
169
|
if (state.jobs.has(name)) {
|
|
@@ -230,8 +234,8 @@ var plugin = {
|
|
|
230
234
|
mutating: false,
|
|
231
235
|
capabilities: [COORDINATION_CRON_CAPABILITY],
|
|
232
236
|
async execute(input) {
|
|
233
|
-
const name = input["name"];
|
|
234
|
-
if (!state.jobs.has(name)) {
|
|
237
|
+
const name = input["name"] ?? input["jobName"] ?? input["job_name"] ?? input["job"] ?? input["id"];
|
|
238
|
+
if (!name || typeof name !== "string" || !state.jobs.has(name)) {
|
|
235
239
|
return { ok: false, error: `No cron job named '${name}'` };
|
|
236
240
|
}
|
|
237
241
|
cancelJob(name);
|
|
@@ -238,16 +238,16 @@ var plugin = {
|
|
|
238
238
|
if (!cfg.enabled) return;
|
|
239
239
|
if (input.toolResult?.isError) return;
|
|
240
240
|
const inp = input.toolInput ?? {};
|
|
241
|
-
const
|
|
241
|
+
const rawSource = inp["path"] ?? inp["TargetFile"] ?? inp["filePath"] ?? inp["targetFile"] ?? inp["file_path"] ?? inp["file"];
|
|
242
|
+
const sourcePath = typeof rawSource === "string" ? rawSource : void 0;
|
|
242
243
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
243
244
|
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
244
245
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
245
246
|
if (!cfg.extensions.includes(ext)) return;
|
|
246
247
|
state.hookInvocationCount += 1;
|
|
247
|
-
const scanRoot = await resolveScanRoot(sourcePath);
|
|
248
248
|
let result;
|
|
249
249
|
try {
|
|
250
|
-
result = await scan(
|
|
250
|
+
result = await scan(process.cwd(), cfg.defaultDepth, cfg);
|
|
251
251
|
} catch {
|
|
252
252
|
state.errorCount += 1;
|
|
253
253
|
return;
|
|
@@ -295,7 +295,8 @@ Consider removing the export if it is not part of the public API.`;
|
|
|
295
295
|
mutating: false,
|
|
296
296
|
async execute(input) {
|
|
297
297
|
if (!cfg.enabled) return { ok: false, error: "dead-code-detector is disabled" };
|
|
298
|
-
const
|
|
298
|
+
const raw = input ?? {};
|
|
299
|
+
const rawPath = (typeof input.path === "string" && input.path.trim().length > 0 ? input.path.trim() : void 0) ?? (typeof raw["directory"] === "string" ? raw["directory"] : void 0) ?? (typeof raw["dir"] === "string" ? raw["dir"] : void 0) ?? (typeof raw["SearchDirectory"] === "string" ? raw["SearchDirectory"] : void 0) ?? (typeof raw["filePath"] === "string" ? raw["filePath"] : void 0) ?? (typeof raw["TargetFile"] === "string" ? raw["TargetFile"] : void 0) ?? (typeof raw["targetFile"] === "string" ? raw["targetFile"] : void 0) ?? (typeof raw["file_path"] === "string" ? raw["file_path"] : void 0) ?? (typeof raw["file"] === "string" ? raw["file"] : void 0) ?? ".";
|
|
299
300
|
const rawDepth = typeof input.depth === "number" ? input.depth : cfg.defaultDepth;
|
|
300
301
|
const depth = Math.max(0, Math.min(Math.floor(rawDepth), cfg.maxDepth));
|
|
301
302
|
if (!(0, runtime_exports.withinProject)(rawPath)) {
|
package/dist/dep-guard.js
CHANGED
|
@@ -32,14 +32,14 @@ function readConfig(raw) {
|
|
|
32
32
|
confirmTyposquatsWithLlm: r["confirmTyposquatsWithLlm"] === true
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
var INSTALL_RE = /(?:^|[;&|]\s*)(npm|pnpm|yarn|bun)\s+(?:install|i|add)\s+([^;&|]+)|(?:^|[;&|]\s*)(pip3?|uv)\s+(?:pip\s+)?install\s+([^;&|]+)|(?:^|[;&|]\s*)(cargo)\s+add\s+([^;&|]+)/gi;
|
|
35
|
+
var INSTALL_RE = /(?:^|[;&|]\s*)(npm|pnpm|yarn|bun)\s+(?:install|i|add)\s+([^;&|]+)|(?:^|[;&|]\s*)(pip3?|uv)\s+(?:pip\s+)?install\s+([^;&|]+)|(?:^|[;&|]\s*)(uv)\s+add\s+([^;&|]+)|(?:^|[;&|]\s*)(cargo)\s+add\s+([^;&|]+)/gi;
|
|
36
36
|
function parseInstallCommands(command) {
|
|
37
37
|
const out = [];
|
|
38
38
|
INSTALL_RE.lastIndex = 0;
|
|
39
39
|
let m = INSTALL_RE.exec(command);
|
|
40
40
|
while (m !== null) {
|
|
41
|
-
const manager = (m[1] ?? m[3] ?? m[5] ?? "").toLowerCase();
|
|
42
|
-
const argString = m[2] ?? m[4] ?? m[6] ?? "";
|
|
41
|
+
const manager = (m[1] ?? m[3] ?? m[5] ?? m[7] ?? "").toLowerCase();
|
|
42
|
+
const argString = m[2] ?? m[4] ?? m[6] ?? m[8] ?? "";
|
|
43
43
|
const packages = [];
|
|
44
44
|
for (const token of argString.split(/\s+/)) {
|
|
45
45
|
if (!token || token.startsWith("-")) continue;
|
|
@@ -201,7 +201,8 @@ var plugin = {
|
|
|
201
201
|
if (!cfg.enabled) return;
|
|
202
202
|
state.invocations += 1;
|
|
203
203
|
const ti = input.toolInput ?? {};
|
|
204
|
-
const
|
|
204
|
+
const rawCmd = ti["command"] ?? ti["CommandLine"] ?? ti["cmd"] ?? ti["script"] ?? ti["input"];
|
|
205
|
+
const command = typeof rawCmd === "string" ? rawCmd : "";
|
|
205
206
|
if (!command) return;
|
|
206
207
|
const installs = parseInstallCommands(command);
|
|
207
208
|
const packages = installs.flatMap((i) => i.packages);
|
|
@@ -55,14 +55,14 @@ function readConfig(raw) {
|
|
|
55
55
|
confirmTyposquatsWithLlm: r["confirmTyposquatsWithLlm"] === true
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
var INSTALL_RE = /(?:^|[;&|]\s*)(npm|pnpm|yarn|bun)\s+(?:install|i|add)\s+([^;&|]+)|(?:^|[;&|]\s*)(pip3?|uv)\s+(?:pip\s+)?install\s+([^;&|]+)|(?:^|[;&|]\s*)(cargo)\s+add\s+([^;&|]+)/gi;
|
|
58
|
+
var INSTALL_RE = /(?:^|[;&|]\s*)(npm|pnpm|yarn|bun)\s+(?:install|i|add)\s+([^;&|]+)|(?:^|[;&|]\s*)(pip3?|uv)\s+(?:pip\s+)?install\s+([^;&|]+)|(?:^|[;&|]\s*)(uv)\s+add\s+([^;&|]+)|(?:^|[;&|]\s*)(cargo)\s+add\s+([^;&|]+)/gi;
|
|
59
59
|
function parseInstallCommands(command) {
|
|
60
60
|
const out = [];
|
|
61
61
|
INSTALL_RE.lastIndex = 0;
|
|
62
62
|
let m = INSTALL_RE.exec(command);
|
|
63
63
|
while (m !== null) {
|
|
64
|
-
const manager = (m[1] ?? m[3] ?? m[5] ?? "").toLowerCase();
|
|
65
|
-
const argString = m[2] ?? m[4] ?? m[6] ?? "";
|
|
64
|
+
const manager = (m[1] ?? m[3] ?? m[5] ?? m[7] ?? "").toLowerCase();
|
|
65
|
+
const argString = m[2] ?? m[4] ?? m[6] ?? m[8] ?? "";
|
|
66
66
|
const packages = [];
|
|
67
67
|
for (const token of argString.split(/\s+/)) {
|
|
68
68
|
if (!token || token.startsWith("-")) continue;
|
|
@@ -224,7 +224,8 @@ var plugin = {
|
|
|
224
224
|
if (!cfg.enabled) return;
|
|
225
225
|
state.invocations += 1;
|
|
226
226
|
const ti = input.toolInput ?? {};
|
|
227
|
-
const
|
|
227
|
+
const rawCmd = ti["command"] ?? ti["CommandLine"] ?? ti["cmd"] ?? ti["script"] ?? ti["input"];
|
|
228
|
+
const command = typeof rawCmd === "string" ? rawCmd : "";
|
|
228
229
|
if (!command) return;
|
|
229
230
|
const installs = parseInstallCommands(command);
|
|
230
231
|
const packages = installs.flatMap((i) => i.packages);
|
|
@@ -443,16 +444,51 @@ function collectSeverities(out, severity) {
|
|
|
443
444
|
}
|
|
444
445
|
}
|
|
445
446
|
function parseAuditJson(jsonString) {
|
|
446
|
-
let parsed;
|
|
447
|
-
try {
|
|
448
|
-
parsed = JSON.parse(jsonString);
|
|
449
|
-
} catch {
|
|
450
|
-
return null;
|
|
451
|
-
}
|
|
452
447
|
const out = { maxSeverity: null, counts: {}, total: 0 };
|
|
453
448
|
let recognizedShape = false;
|
|
454
|
-
|
|
455
|
-
|
|
449
|
+
const processObject = (parsed) => {
|
|
450
|
+
if (!parsed || typeof parsed !== "object") return;
|
|
451
|
+
if (Array.isArray(parsed)) {
|
|
452
|
+
recognizedShape = true;
|
|
453
|
+
for (const entry of parsed) {
|
|
454
|
+
if (entry && typeof entry === "object") {
|
|
455
|
+
const severity = entry["severity"];
|
|
456
|
+
if (typeof severity === "string") {
|
|
457
|
+
collectSeverities(out, severity);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const p = parsed;
|
|
464
|
+
if (p["type"] === "auditAdvisory" && p["data"] && typeof p["data"] === "object") {
|
|
465
|
+
recognizedShape = true;
|
|
466
|
+
const adv = p["data"]["advisory"];
|
|
467
|
+
if (adv && typeof adv === "object") {
|
|
468
|
+
const severity = adv["severity"];
|
|
469
|
+
if (typeof severity === "string") collectSeverities(out, severity);
|
|
470
|
+
}
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
if (p["type"] === "auditSummary" && p["data"] && typeof p["data"] === "object") {
|
|
474
|
+
recognizedShape = true;
|
|
475
|
+
const vulns = p["data"]["vulnerabilities"];
|
|
476
|
+
if (vulns && typeof vulns === "object") {
|
|
477
|
+
for (const [key, value] of Object.entries(vulns)) {
|
|
478
|
+
const count = typeof value === "number" ? value : 0;
|
|
479
|
+
if (count > 0 && SEVERITY_RANK[key] != null) {
|
|
480
|
+
out.counts[key] = (out.counts[key] ?? 0) + count;
|
|
481
|
+
out.total += count;
|
|
482
|
+
const currentMax = out.maxSeverity;
|
|
483
|
+
if (currentMax === null || SEVERITY_RANK[key] > (SEVERITY_RANK[currentMax] ?? 0)) {
|
|
484
|
+
out.maxSeverity = key;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const vulnerabilities = p["vulnerabilities"];
|
|
456
492
|
if (vulnerabilities && typeof vulnerabilities === "object" && !Array.isArray(vulnerabilities)) {
|
|
457
493
|
recognizedShape = true;
|
|
458
494
|
for (const entry of Object.values(vulnerabilities)) {
|
|
@@ -464,7 +500,7 @@ function parseAuditJson(jsonString) {
|
|
|
464
500
|
}
|
|
465
501
|
}
|
|
466
502
|
}
|
|
467
|
-
const advisories =
|
|
503
|
+
const advisories = p["advisories"];
|
|
468
504
|
if (advisories && typeof advisories === "object" && !Array.isArray(advisories)) {
|
|
469
505
|
recognizedShape = true;
|
|
470
506
|
for (const entry of Object.values(advisories)) {
|
|
@@ -477,7 +513,7 @@ function parseAuditJson(jsonString) {
|
|
|
477
513
|
}
|
|
478
514
|
}
|
|
479
515
|
if (out.total === 0) {
|
|
480
|
-
const metadata =
|
|
516
|
+
const metadata = p["metadata"];
|
|
481
517
|
const metaVulns = metadata && typeof metadata === "object" ? metadata["vulnerabilities"] : void 0;
|
|
482
518
|
if (metaVulns && typeof metaVulns === "object" && !Array.isArray(metaVulns)) {
|
|
483
519
|
recognizedShape = true;
|
|
@@ -494,15 +530,18 @@ function parseAuditJson(jsonString) {
|
|
|
494
530
|
}
|
|
495
531
|
}
|
|
496
532
|
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
533
|
+
};
|
|
534
|
+
try {
|
|
535
|
+
const single = JSON.parse(jsonString);
|
|
536
|
+
processObject(single);
|
|
537
|
+
} catch {
|
|
538
|
+
for (const line of jsonString.split(/\r?\n/)) {
|
|
539
|
+
const trimmed = line.trim();
|
|
540
|
+
if (!trimmed) continue;
|
|
541
|
+
try {
|
|
542
|
+
const lineObj = JSON.parse(trimmed);
|
|
543
|
+
processObject(lineObj);
|
|
544
|
+
} catch {
|
|
506
545
|
}
|
|
507
546
|
}
|
|
508
547
|
}
|
|
@@ -520,7 +559,8 @@ function isInstallCommand(input) {
|
|
|
520
559
|
if (input.toolName === "install") return true;
|
|
521
560
|
if (input.toolName !== "bash" && input.toolName !== "exec") return false;
|
|
522
561
|
const ti = input.toolInput ?? {};
|
|
523
|
-
const
|
|
562
|
+
const rawCmd = ti["command"] ?? ti["CommandLine"] ?? ti["cmd"] ?? ti["script"];
|
|
563
|
+
const command = typeof rawCmd === "string" ? rawCmd : "";
|
|
524
564
|
return parseInstallCommands(command).length > 0;
|
|
525
565
|
}
|
|
526
566
|
var LOCKFILE_MANAGERS = [
|
package/dist/diff-summary.js
CHANGED
|
@@ -190,14 +190,18 @@ var plugin = {
|
|
|
190
190
|
if (input.toolResult?.isError) return;
|
|
191
191
|
const toolName = input.toolName ?? "";
|
|
192
192
|
const inp = input.toolInput ?? {};
|
|
193
|
-
const
|
|
193
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
194
|
+
const filePath = typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
194
195
|
if (!filePath || typeof filePath !== "string") return;
|
|
195
196
|
state.invocationCount += 1;
|
|
196
197
|
if (!(0, runtime_exports.withinProject)(filePath)) {
|
|
197
198
|
state.fallbackCount += 1;
|
|
198
199
|
return;
|
|
199
200
|
}
|
|
200
|
-
const
|
|
201
|
+
const oldStr = String(inp["old_string"] ?? inp["TargetContent"] ?? inp["oldContent"] ?? "");
|
|
202
|
+
const newStr = String(inp["new_string"] ?? inp["ReplacementContent"] ?? inp["newContent"] ?? "");
|
|
203
|
+
const contentStr = String(inp["content"] ?? inp["CodeContent"] ?? inp["code"] ?? inp["text"] ?? inp["contents"] ?? inp["body"] ?? "");
|
|
204
|
+
const toolInputForHash = oldStr || newStr ? `${oldStr}:::${newStr}` : contentStr;
|
|
201
205
|
const now = Date.now();
|
|
202
206
|
const memo = pathMemo.get(filePath);
|
|
203
207
|
if (memo) {
|
package/dist/doc-sync-guard.js
CHANGED
|
@@ -72,13 +72,23 @@ function isDocFile(p, docNames) {
|
|
|
72
72
|
}
|
|
73
73
|
function extractPath(toolInput) {
|
|
74
74
|
const inp = toolInput ?? {};
|
|
75
|
-
const
|
|
76
|
-
return typeof
|
|
75
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
76
|
+
return typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
77
77
|
}
|
|
78
78
|
function extractDocContent(toolInput) {
|
|
79
79
|
const inp = toolInput ?? {};
|
|
80
80
|
if (typeof inp["content"] === "string") return inp["content"];
|
|
81
|
+
if (typeof inp["CodeContent"] === "string") return inp["CodeContent"];
|
|
82
|
+
if (typeof inp["text"] === "string") return inp["text"];
|
|
83
|
+
if (typeof inp["contents"] === "string") return inp["contents"];
|
|
84
|
+
if (typeof inp["body"] === "string") return inp["body"];
|
|
85
|
+
if (typeof inp["description"] === "string") return inp["description"];
|
|
86
|
+
if (typeof inp["summary"] === "string") return inp["summary"];
|
|
87
|
+
if (typeof inp["message"] === "string") return inp["message"];
|
|
88
|
+
if (typeof inp["code"] === "string") return inp["code"];
|
|
81
89
|
if (typeof inp["new_string"] === "string") return inp["new_string"];
|
|
90
|
+
if (typeof inp["ReplacementContent"] === "string") return inp["ReplacementContent"];
|
|
91
|
+
if (typeof inp["newContent"] === "string") return inp["newContent"];
|
|
82
92
|
return void 0;
|
|
83
93
|
}
|
|
84
94
|
function referenceTokens(p) {
|