@wrongstack/plugins 0.317.0 → 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 +17 -6
- 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 +1675 -745
- 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 +40 -14
- 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 +27 -6
- 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/notify-hub.js
CHANGED
|
@@ -215,13 +215,16 @@ function readConfig(raw) {
|
|
|
215
215
|
if (typeof v === "string") headers[k] = v;
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
|
+
const rawUrl = r["webhookUrl"] ?? r["webhook_url"] ?? r["url"];
|
|
219
|
+
const rawTimeout = r["timeoutMs"] ?? r["timeout_ms"] ?? r["timeout"];
|
|
220
|
+
const rawFailures = r["maxConsecutiveFailures"] ?? r["max_consecutive_failures"] ?? r["maxFailures"] ?? r["max_failures"];
|
|
218
221
|
return {
|
|
219
222
|
enabled: r["enabled"] !== false,
|
|
220
|
-
webhookUrl: normalizeWebhookUrl(
|
|
223
|
+
webhookUrl: normalizeWebhookUrl(rawUrl),
|
|
221
224
|
events: Array.isArray(r["events"]) ? r["events"].filter((e) => KNOWN_EVENTS.includes(e)) : [...DEFAULTS.events],
|
|
222
225
|
headers,
|
|
223
|
-
timeoutMs: typeof
|
|
224
|
-
maxConsecutiveFailures: typeof
|
|
226
|
+
timeoutMs: typeof rawTimeout === "number" && rawTimeout >= 500 && rawTimeout <= 6e4 ? rawTimeout : DEFAULTS.timeoutMs,
|
|
227
|
+
maxConsecutiveFailures: typeof rawFailures === "number" && rawFailures >= 1 ? rawFailures : DEFAULTS.maxConsecutiveFailures
|
|
225
228
|
};
|
|
226
229
|
}
|
|
227
230
|
async function deliver(event, payload) {
|
|
@@ -411,9 +414,15 @@ var plugin = {
|
|
|
411
414
|
error: 'no webhookUrl configured \u2014 set config.extensions["notify-hub"].webhookUrl to enable deliveries'
|
|
412
415
|
};
|
|
413
416
|
}
|
|
417
|
+
const inp = input ?? {};
|
|
418
|
+
const rawMsg = inp["message"] ?? inp["body"] ?? inp["text"] ?? inp["content"] ?? inp["msg"];
|
|
419
|
+
const message = typeof rawMsg === "string" && rawMsg.trim().length > 0 ? rawMsg.trim() : "";
|
|
420
|
+
if (!message) return { ok: false, error: "message is required" };
|
|
421
|
+
const rawTitle = inp["title"] ?? inp["subject"] ?? inp["header"];
|
|
422
|
+
const title = typeof rawTitle === "string" && rawTitle.trim() ? rawTitle.trim() : "WrongStack notification";
|
|
414
423
|
const result = await deliverViaChannel(ch, "manual", {
|
|
415
|
-
title: truncateText(
|
|
416
|
-
body: truncateText(
|
|
424
|
+
title: truncateText(title, 200),
|
|
425
|
+
body: truncateText(message, 2e3),
|
|
417
426
|
level: input.level === "warning" || input.level === "critical" ? input.level : "info",
|
|
418
427
|
source: "manual"
|
|
419
428
|
});
|
package/dist/path-guard.js
CHANGED
|
@@ -1354,11 +1354,15 @@ var DEFAULTS = {
|
|
|
1354
1354
|
function readConfig(raw) {
|
|
1355
1355
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS, protect: [...DEFAULT_PROTECT] };
|
|
1356
1356
|
const r = raw;
|
|
1357
|
+
const rawMode = typeof (r["mode"] ?? r["action"] ?? r["behavior"]) === "string" ? String(r["mode"] ?? r["action"] ?? r["behavior"]).trim().toLowerCase() : void 0;
|
|
1358
|
+
const mode = rawMode === "warn" ? "warn" : "block";
|
|
1359
|
+
const rawProtect = r["protect"] ?? r["protectedPaths"] ?? r["protected_paths"] ?? r["protected"];
|
|
1360
|
+
const rawAllow = r["allow"] ?? r["allowedPaths"] ?? r["allowed_paths"] ?? r["allowed"];
|
|
1357
1361
|
return {
|
|
1358
1362
|
enabled: r["enabled"] !== false,
|
|
1359
|
-
mode
|
|
1360
|
-
protect: Array.isArray(
|
|
1361
|
-
allow: Array.isArray(
|
|
1363
|
+
mode,
|
|
1364
|
+
protect: Array.isArray(rawProtect) ? rawProtect.filter((p) => typeof p === "string" && p.length > 0) : [...DEFAULT_PROTECT],
|
|
1365
|
+
allow: Array.isArray(rawAllow) ? rawAllow.filter((p) => typeof p === "string" && p.length > 0) : []
|
|
1362
1366
|
};
|
|
1363
1367
|
}
|
|
1364
1368
|
var plugin = {
|
|
@@ -200,8 +200,12 @@ var plugin = {
|
|
|
200
200
|
return { ok: false, error: "performance-regression-gate is disabled" };
|
|
201
201
|
}
|
|
202
202
|
state.invocationCount += 1;
|
|
203
|
-
const
|
|
204
|
-
const
|
|
203
|
+
const raw = input ?? {};
|
|
204
|
+
const rawThreshold = input.thresholdPercent ?? raw["threshold"] ?? raw["threshold_percent"] ?? raw["thresholdPercent"] ?? raw["percent"];
|
|
205
|
+
const threshold = typeof rawThreshold === "number" && rawThreshold >= 0 && rawThreshold <= 1e3 ? rawThreshold : cfg.thresholdPercent;
|
|
206
|
+
const rawResultsPath = input.resultsPath ?? raw["results_path"] ?? raw["file_path"] ?? raw["path"] ?? raw["filePath"] ?? raw["file"] ?? raw["TargetFile"] ?? raw["targetFile"] ?? "bench-results.json";
|
|
207
|
+
const resultsPathStr = typeof rawResultsPath === "string" && rawResultsPath.trim() ? rawResultsPath.trim() : "bench-results.json";
|
|
208
|
+
const resultsPath = resolveProjectPath(resultsPathStr) ?? "";
|
|
205
209
|
if (!resultsPath) {
|
|
206
210
|
state.errorCount += 1;
|
|
207
211
|
return { ok: false, error: "invalid results path (must be inside project)" };
|
|
@@ -215,7 +219,7 @@ var plugin = {
|
|
|
215
219
|
thresholdPercent: threshold,
|
|
216
220
|
comparisons: 0,
|
|
217
221
|
regressions: [],
|
|
218
|
-
message: `No benchmark results found at ${
|
|
222
|
+
message: `No benchmark results found at ${resultsPathStr}.`
|
|
219
223
|
};
|
|
220
224
|
}
|
|
221
225
|
const current = flattenResults(results);
|
|
@@ -230,9 +234,11 @@ var plugin = {
|
|
|
230
234
|
message: "No benchmarks with valid mean/period values were found."
|
|
231
235
|
};
|
|
232
236
|
}
|
|
237
|
+
const rawBaselinePath = input.baselinePath ?? raw["baseline_path"] ?? raw["baseline"] ?? raw["basePath"] ?? raw["base_path"];
|
|
238
|
+
const baselinePathStr = typeof rawBaselinePath === "string" && rawBaselinePath.trim() ? rawBaselinePath.trim() : void 0;
|
|
233
239
|
let pairs;
|
|
234
|
-
if (
|
|
235
|
-
const baselineResolved = resolveProjectPath(
|
|
240
|
+
if (baselinePathStr) {
|
|
241
|
+
const baselineResolved = resolveProjectPath(baselinePathStr) ?? "";
|
|
236
242
|
if (!baselineResolved) {
|
|
237
243
|
state.errorCount += 1;
|
|
238
244
|
return { ok: false, error: "invalid baseline path (must be inside project)" };
|
|
@@ -242,7 +248,7 @@ var plugin = {
|
|
|
242
248
|
state.errorCount += 1;
|
|
243
249
|
return {
|
|
244
250
|
ok: false,
|
|
245
|
-
error: `Could not read baseline results at ${
|
|
251
|
+
error: `Could not read baseline results at ${baselinePathStr}.`
|
|
246
252
|
};
|
|
247
253
|
}
|
|
248
254
|
const baseline = flattenResults(baselineResults);
|
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
15
|
+
// src/runtime/index.ts
|
|
16
|
+
var runtime_exports = {};
|
|
17
|
+
__reExport(runtime_exports, runtime_star);
|
|
18
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
19
|
+
|
|
1
20
|
// src/plugin-stack-observer/index.ts
|
|
2
21
|
var state = {
|
|
3
22
|
wraps: [],
|
|
4
23
|
contributions: 0,
|
|
5
|
-
patternUnregister: null
|
|
24
|
+
patternUnregister: null,
|
|
25
|
+
contributorUnregister: null
|
|
6
26
|
};
|
|
7
27
|
function clearObserverState() {
|
|
8
28
|
if (state.patternUnregister) {
|
|
@@ -12,6 +32,7 @@ function clearObserverState() {
|
|
|
12
32
|
}
|
|
13
33
|
state.patternUnregister = null;
|
|
14
34
|
}
|
|
35
|
+
state.contributorUnregister = (0, runtime_exports.releaseHandle)(state.contributorUnregister);
|
|
15
36
|
state.wraps = [];
|
|
16
37
|
state.contributions = 0;
|
|
17
38
|
}
|
|
@@ -65,8 +86,9 @@ var PLUGIN = {
|
|
|
65
86
|
api.metrics.counter("wrap_loaded");
|
|
66
87
|
}
|
|
67
88
|
);
|
|
89
|
+
state.contributorUnregister = (0, runtime_exports.releaseHandle)(state.contributorUnregister);
|
|
68
90
|
if (cfg.injectIntoSystemPrompt) {
|
|
69
|
-
api.registerSystemPromptContributor(async () => {
|
|
91
|
+
state.contributorUnregister = api.registerSystemPromptContributor(async () => {
|
|
70
92
|
if (state.wraps.length === 0) return [];
|
|
71
93
|
state.contributions += 1;
|
|
72
94
|
api.metrics.counter("system_prompt_contribution");
|
|
@@ -131,7 +153,7 @@ function readConfig(raw) {
|
|
|
131
153
|
const r = raw;
|
|
132
154
|
return {
|
|
133
155
|
enabled: r["enabled"] !== false,
|
|
134
|
-
injectIntoSystemPrompt: r["injectIntoSystemPrompt"] === true
|
|
156
|
+
injectIntoSystemPrompt: r["injectIntoSystemPrompt"] === true || r["inject_into_system_prompt"] === true
|
|
135
157
|
};
|
|
136
158
|
}
|
|
137
159
|
var plugin_stack_observer_default = PLUGIN;
|
package/dist/pr-drafter.js
CHANGED
|
@@ -236,8 +236,10 @@ var plugin = {
|
|
|
236
236
|
const msg = p.result.commitMessage ?? p.input?.message ?? "commit";
|
|
237
237
|
state.commits.push(msg);
|
|
238
238
|
}
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
const rawInput = p?.input ?? {};
|
|
240
|
+
const filePath = typeof rawInput["path"] === "string" && rawInput["path"] || typeof rawInput["filePath"] === "string" && rawInput["filePath"] || typeof rawInput["file_path"] === "string" && rawInput["file_path"] || typeof rawInput["TargetFile"] === "string" && rawInput["TargetFile"] || typeof rawInput["targetFile"] === "string" && rawInput["targetFile"] || typeof rawInput["file"] === "string" && rawInput["file"];
|
|
241
|
+
if ((toolName === "write" || toolName === "edit" || toolName === "write_to_file" || toolName === "replace_file_content") && filePath) {
|
|
242
|
+
state.files.add(filePath);
|
|
241
243
|
}
|
|
242
244
|
});
|
|
243
245
|
state.eventUnsubscribers.push(offTool);
|
|
@@ -246,8 +248,11 @@ var plugin = {
|
|
|
246
248
|
const offUsage = api.onEvent("provider.response", (payload) => {
|
|
247
249
|
const p = payload;
|
|
248
250
|
if (p?.model) state.models.add(p.model);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
+
const rawUsage = p?.usage;
|
|
252
|
+
const inputTokens = (typeof rawUsage?.["input"] === "number" ? rawUsage["input"] : void 0) ?? (typeof rawUsage?.["prompt_tokens"] === "number" ? rawUsage["prompt_tokens"] : void 0) ?? (typeof rawUsage?.["input_tokens"] === "number" ? rawUsage["input_tokens"] : void 0) ?? (typeof rawUsage?.["promptTokens"] === "number" ? rawUsage["promptTokens"] : 0);
|
|
253
|
+
const outputTokens = (typeof rawUsage?.["output"] === "number" ? rawUsage["output"] : void 0) ?? (typeof rawUsage?.["completion_tokens"] === "number" ? rawUsage["completion_tokens"] : void 0) ?? (typeof rawUsage?.["output_tokens"] === "number" ? rawUsage["output_tokens"] : void 0) ?? (typeof rawUsage?.["completionTokens"] === "number" ? rawUsage["completionTokens"] : 0);
|
|
254
|
+
state.totalInputTokens += inputTokens;
|
|
255
|
+
state.totalOutputTokens += outputTokens;
|
|
251
256
|
});
|
|
252
257
|
state.eventUnsubscribers.push(offUsage);
|
|
253
258
|
}
|
|
@@ -280,11 +285,15 @@ var plugin = {
|
|
|
280
285
|
capabilities: ["fs.write"],
|
|
281
286
|
async execute(input = {}) {
|
|
282
287
|
if (!cfg.enabled) return { ok: false, error: "pr-drafter is disabled" };
|
|
288
|
+
const raw = input ?? {};
|
|
289
|
+
const preview = Boolean(input?.preview ?? raw["dryRun"] ?? raw["dry_run"] ?? raw["dry"] ?? raw["previewOnly"]);
|
|
290
|
+
const rawOutputPath = raw["outputPath"] ?? raw["output_path"] ?? raw["path"] ?? raw["filePath"] ?? raw["file"] ?? raw["TargetFile"] ?? raw["targetFile"] ?? cfg.outputPath;
|
|
291
|
+
const outputPathStr = typeof rawOutputPath === "string" && rawOutputPath.trim().length > 0 ? rawOutputPath.trim() : cfg.outputPath;
|
|
283
292
|
const draft = await buildDraft(cfg, api.llm);
|
|
284
|
-
if (
|
|
293
|
+
if (preview) {
|
|
285
294
|
return { ok: true, preview: true, title: draft.title, body: draft.body };
|
|
286
295
|
}
|
|
287
|
-
const resolved = resolveProjectPath(
|
|
296
|
+
const resolved = resolveProjectPath(outputPathStr);
|
|
288
297
|
if (!resolved) return { ok: false, error: "outputPath resolves outside project" };
|
|
289
298
|
try {
|
|
290
299
|
await mkdir(dirname(resolved), { recursive: true });
|
|
@@ -292,7 +301,7 @@ var plugin = {
|
|
|
292
301
|
state.draftsWritten += 1;
|
|
293
302
|
return {
|
|
294
303
|
ok: true,
|
|
295
|
-
path:
|
|
304
|
+
path: outputPathStr,
|
|
296
305
|
resolvedPath: resolved,
|
|
297
306
|
title: draft.title
|
|
298
307
|
};
|
package/dist/process-guard.js
CHANGED
|
@@ -61,7 +61,8 @@ var plugin = {
|
|
|
61
61
|
const toolName = input.toolName ?? "";
|
|
62
62
|
if (toolName !== "bash" && toolName !== "exec") return;
|
|
63
63
|
const ti = input.toolInput ?? {};
|
|
64
|
-
const
|
|
64
|
+
const rawCmd = ti["command"] ?? ti["CommandLine"] ?? ti["cmd"] ?? ti["script"] ?? ti["input"];
|
|
65
|
+
const command = typeof rawCmd === "string" ? rawCmd : "";
|
|
65
66
|
if (!command) return;
|
|
66
67
|
const isKillRelated = /\b(?:kill|taskkill|stop-process|tskill|pkill|killall|wmic)\b/i.test(command);
|
|
67
68
|
if (!isKillRelated) return;
|
package/dist/prompt-firewall.js
CHANGED
|
@@ -256,17 +256,21 @@ function readConfig(raw) {
|
|
|
256
256
|
};
|
|
257
257
|
if (!raw || typeof raw !== "object") return base;
|
|
258
258
|
const r = raw;
|
|
259
|
-
const
|
|
259
|
+
const rawAllow = r["allow"] ?? r["allowlist"] ?? r["allowed"];
|
|
260
|
+
const allow = Array.isArray(rawAllow) ? rawAllow.filter((s) => typeof s === "string" && s.length > 0).flatMap((s) => {
|
|
260
261
|
try {
|
|
261
262
|
return [new RegExp(s)];
|
|
262
263
|
} catch {
|
|
263
264
|
return [];
|
|
264
265
|
}
|
|
265
266
|
}) : [];
|
|
267
|
+
const rawMode = typeof (r["mode"] ?? r["action"] ?? r["behavior"]) === "string" ? String(r["mode"] ?? r["action"] ?? r["behavior"]).trim().toLowerCase() : void 0;
|
|
268
|
+
const mode = rawMode === "warn" ? "warn" : rawMode === "block" ? "block" : "redact";
|
|
269
|
+
const rawScan = r["scanResponse"] ?? r["scan_response"];
|
|
266
270
|
return {
|
|
267
271
|
enabled: r["enabled"] === true,
|
|
268
|
-
mode
|
|
269
|
-
scanResponse:
|
|
272
|
+
mode,
|
|
273
|
+
scanResponse: rawScan !== false,
|
|
270
274
|
allow
|
|
271
275
|
};
|
|
272
276
|
}
|
|
@@ -412,11 +416,9 @@ var plugin = {
|
|
|
412
416
|
function redactResponse(response, allow, skip) {
|
|
413
417
|
if (!response || typeof response !== "object") return response;
|
|
414
418
|
const counter = { n: 0 };
|
|
415
|
-
const content = response.content;
|
|
416
|
-
if (content === void 0) return response;
|
|
417
419
|
const budget = { remaining: RESPONSE_SCAN_BUDGET, truncated: false };
|
|
418
420
|
const deadline = createScanDeadline();
|
|
419
|
-
const redacted = redactDeep(
|
|
421
|
+
const redacted = redactDeep(response, allow, counter, skip, budget, deadline);
|
|
420
422
|
if (deadline.tripped.size > 0) surfaceScanTrips(api, deadline.tripped);
|
|
421
423
|
if (budget.truncated) {
|
|
422
424
|
state.responseTruncated = true;
|
|
@@ -434,7 +436,7 @@ var plugin = {
|
|
|
434
436
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
435
437
|
};
|
|
436
438
|
}
|
|
437
|
-
return
|
|
439
|
+
return redacted;
|
|
438
440
|
}
|
|
439
441
|
api.tools.register({
|
|
440
442
|
name: "prompt_firewall_status",
|
|
@@ -42,19 +42,24 @@ var DEFAULTS = {
|
|
|
42
42
|
function readRules(raw) {
|
|
43
43
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS.rules };
|
|
44
44
|
const r = raw;
|
|
45
|
+
const rawLong = r["longFunctionLines"] ?? r["long_function_lines"] ?? r["maxLines"] ?? r["max_lines"];
|
|
46
|
+
const rawParams = r["maxParams"] ?? r["max_params"];
|
|
47
|
+
const rawNesting = r["maxNesting"] ?? r["max_nesting"] ?? r["nesting"];
|
|
45
48
|
return {
|
|
46
|
-
longFunctionLines: typeof
|
|
47
|
-
maxParams: typeof
|
|
48
|
-
maxNesting: typeof
|
|
49
|
+
longFunctionLines: typeof rawLong === "number" && rawLong >= 1 ? rawLong : DEFAULTS.rules.longFunctionLines,
|
|
50
|
+
maxParams: typeof rawParams === "number" && rawParams >= 1 ? rawParams : DEFAULTS.rules.maxParams,
|
|
51
|
+
maxNesting: typeof rawNesting === "number" && rawNesting >= 1 ? rawNesting : DEFAULTS.rules.maxNesting
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
54
|
function readConfig(raw) {
|
|
52
55
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
53
56
|
const r = raw;
|
|
57
|
+
const rawExts = r["extensions"] ?? r["file_extensions"] ?? r["fileExtensions"];
|
|
58
|
+
const rawMax = r["maxSuggestions"] ?? r["max_suggestions"] ?? r["limit"];
|
|
54
59
|
return {
|
|
55
60
|
enabled: r["enabled"] === true,
|
|
56
|
-
extensions: Array.isArray(
|
|
57
|
-
maxSuggestions: typeof
|
|
61
|
+
extensions: Array.isArray(rawExts) ? rawExts.filter((x) => typeof x === "string") : DEFAULTS.extensions,
|
|
62
|
+
maxSuggestions: typeof rawMax === "number" && rawMax >= 1 && rawMax <= 500 ? rawMax : DEFAULTS.maxSuggestions,
|
|
58
63
|
rules: readRules(r["rules"])
|
|
59
64
|
};
|
|
60
65
|
}
|
|
@@ -67,6 +72,28 @@ function toPosix(p) {
|
|
|
67
72
|
function relativePath(p) {
|
|
68
73
|
return toPosix(relative(process.cwd(), p));
|
|
69
74
|
}
|
|
75
|
+
function splitTopLevelParams(paramsRaw) {
|
|
76
|
+
const result = [];
|
|
77
|
+
let current = "";
|
|
78
|
+
let depth = 0;
|
|
79
|
+
for (let i = 0; i < paramsRaw.length; i++) {
|
|
80
|
+
const ch = paramsRaw[i];
|
|
81
|
+
if (ch === "(" || ch === "{" || ch === "[" || ch === "<") {
|
|
82
|
+
depth++;
|
|
83
|
+
current += ch;
|
|
84
|
+
} else if (ch === ")" || ch === "}" || ch === "]" || ch === ">") {
|
|
85
|
+
if (depth > 0) depth--;
|
|
86
|
+
current += ch;
|
|
87
|
+
} else if (ch === "," && depth === 0) {
|
|
88
|
+
if (current.trim().length > 0) result.push(current.trim());
|
|
89
|
+
current = "";
|
|
90
|
+
} else {
|
|
91
|
+
current += ch;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (current.trim().length > 0) result.push(current.trim());
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
70
97
|
function leadingIndentLevel(line) {
|
|
71
98
|
const leading = line.match(/^(\s*)/)?.[1] ?? "";
|
|
72
99
|
const tabs = leading.split(" ").length - 1;
|
|
@@ -93,7 +120,7 @@ function detectSmells(filePath, content, rules) {
|
|
|
93
120
|
const name = match[1];
|
|
94
121
|
if (CONTROL_KEYWORDS.has(name)) continue;
|
|
95
122
|
const paramsRaw = match[2];
|
|
96
|
-
const params = paramsRaw
|
|
123
|
+
const params = splitTopLevelParams(paramsRaw);
|
|
97
124
|
if (params.length > rules.maxParams) {
|
|
98
125
|
suggestions.push({
|
|
99
126
|
file: relativePath(filePath),
|
|
@@ -241,7 +268,8 @@ var plugin = {
|
|
|
241
268
|
if (!cfg.enabled) return;
|
|
242
269
|
if (input.toolResult?.isError) return;
|
|
243
270
|
const inp = input.toolInput ?? {};
|
|
244
|
-
const
|
|
271
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
272
|
+
const sourcePath = typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
245
273
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
246
274
|
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
247
275
|
const exts = normalizeExtensions(cfg.extensions);
|
|
@@ -282,7 +310,8 @@ var plugin = {
|
|
|
282
310
|
mutating: false,
|
|
283
311
|
async execute(input) {
|
|
284
312
|
if (!cfg.enabled) return { ok: false, error: "refactor-suggester is disabled" };
|
|
285
|
-
const
|
|
313
|
+
const raw = input ?? {};
|
|
314
|
+
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["TargetFile"] === "string" ? raw["TargetFile"] : void 0) ?? (typeof raw["filePath"] === "string" ? raw["filePath"] : void 0) ?? (typeof raw["targetFile"] === "string" ? raw["targetFile"] : void 0) ?? ".";
|
|
286
315
|
if (!(0, runtime_exports.withinProject)(rawPath)) {
|
|
287
316
|
return { ok: false, error: "path is outside the project root" };
|
|
288
317
|
}
|
|
@@ -22,6 +22,15 @@
|
|
|
22
22
|
* @public
|
|
23
23
|
*/
|
|
24
24
|
import type { Plugin } from '@wrongstack/core/types';
|
|
25
|
+
interface ReleaseNotesGeneratorConfig {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
includeScope: boolean;
|
|
28
|
+
defaultFrom: string;
|
|
29
|
+
useLlm: boolean;
|
|
30
|
+
audience: ReleaseAudience;
|
|
31
|
+
}
|
|
32
|
+
type ReleaseAudience = 'users' | 'developers' | 'operators';
|
|
33
|
+
export declare function readConfig(raw: unknown): ReleaseNotesGeneratorConfig;
|
|
25
34
|
declare const plugin: Plugin;
|
|
26
35
|
export default plugin;
|
|
27
36
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -26,26 +26,44 @@ var DEFAULTS = {
|
|
|
26
26
|
audience: "users"
|
|
27
27
|
};
|
|
28
28
|
function readAudience(raw) {
|
|
29
|
-
|
|
29
|
+
const norm = typeof raw === "string" ? raw.trim().toLowerCase() : "";
|
|
30
|
+
return norm === "developers" || norm === "operators" || norm === "users" ? norm : DEFAULTS.audience;
|
|
30
31
|
}
|
|
31
32
|
function readConfig(raw) {
|
|
32
33
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
33
34
|
const r = raw;
|
|
35
|
+
const rawScope = r["includeScope"] ?? r["include_scope"];
|
|
36
|
+
const rawFrom = r["defaultFrom"] ?? r["default_from"] ?? r["from"];
|
|
37
|
+
const rawLlm = r["useLlm"] ?? r["use_llm"];
|
|
34
38
|
return {
|
|
35
39
|
enabled: r["enabled"] !== false,
|
|
36
|
-
includeScope:
|
|
37
|
-
defaultFrom: typeof
|
|
38
|
-
useLlm:
|
|
40
|
+
includeScope: rawScope !== false,
|
|
41
|
+
defaultFrom: typeof rawFrom === "string" ? rawFrom : DEFAULTS.defaultFrom,
|
|
42
|
+
useLlm: rawLlm === true,
|
|
39
43
|
audience: readAudience(r["audience"])
|
|
40
44
|
};
|
|
41
45
|
}
|
|
42
|
-
var CONVENTIONAL_TYPES = [
|
|
46
|
+
var CONVENTIONAL_TYPES = [
|
|
47
|
+
"feat",
|
|
48
|
+
"fix",
|
|
49
|
+
"docs",
|
|
50
|
+
"refactor",
|
|
51
|
+
"perf",
|
|
52
|
+
"test",
|
|
53
|
+
"chore",
|
|
54
|
+
"revert",
|
|
55
|
+
"build",
|
|
56
|
+
"ci",
|
|
57
|
+
"style",
|
|
58
|
+
"i18n",
|
|
59
|
+
"a11y"
|
|
60
|
+
];
|
|
43
61
|
function parseConventionalCommit(subject) {
|
|
44
|
-
const match = subject.match(/^([a-
|
|
62
|
+
const match = subject.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(?:\(([^)]+)\))?!?:\s*(.+)$/);
|
|
45
63
|
if (!match) {
|
|
46
64
|
return { type: "uncategorized", scope: null, description: subject };
|
|
47
65
|
}
|
|
48
|
-
const rawType = match[1];
|
|
66
|
+
const rawType = match[1].toLowerCase();
|
|
49
67
|
const scope = match[2] ?? null;
|
|
50
68
|
const description = match[3];
|
|
51
69
|
const type = CONVENTIONAL_TYPES.includes(rawType) ? rawType : "uncategorized";
|
|
@@ -128,7 +146,21 @@ function generateNotes(commits, includeScope) {
|
|
|
128
146
|
const lines = [];
|
|
129
147
|
lines.push(`## Release Notes (${commits.length} commit${commits.length === 1 ? "" : "s"})`);
|
|
130
148
|
lines.push("");
|
|
131
|
-
const order = [
|
|
149
|
+
const order = [
|
|
150
|
+
"feat",
|
|
151
|
+
"fix",
|
|
152
|
+
"perf",
|
|
153
|
+
"refactor",
|
|
154
|
+
"docs",
|
|
155
|
+
"test",
|
|
156
|
+
"chore",
|
|
157
|
+
"revert",
|
|
158
|
+
"build",
|
|
159
|
+
"ci",
|
|
160
|
+
"style",
|
|
161
|
+
"i18n",
|
|
162
|
+
"a11y"
|
|
163
|
+
];
|
|
132
164
|
for (const type of order) {
|
|
133
165
|
const list = groups[type];
|
|
134
166
|
if (!list || list.length === 0) continue;
|
|
@@ -254,8 +286,13 @@ var plugin = {
|
|
|
254
286
|
async execute(input, _ctx, execOpts) {
|
|
255
287
|
if (!cfg.enabled) return { ok: false, error: "release-notes-generator is disabled" };
|
|
256
288
|
execOpts?.signal?.throwIfAborted();
|
|
257
|
-
const
|
|
258
|
-
const
|
|
289
|
+
const raw = input ?? {};
|
|
290
|
+
const rawTo = input.to ?? raw["to_ref"] ?? raw["toRef"] ?? raw["until"] ?? raw["end"];
|
|
291
|
+
const rawFrom = input.from ?? raw["from_ref"] ?? raw["fromRef"] ?? raw["since"] ?? raw["start"];
|
|
292
|
+
const rawUseLlm = input.use_llm ?? raw["useLlm"] ?? raw["use_ai"] ?? raw["useAi"];
|
|
293
|
+
const toRef = typeof rawTo === "string" && rawTo.trim() ? rawTo.trim() : "HEAD";
|
|
294
|
+
const fromInput = typeof rawFrom === "string" && rawFrom.trim() ? rawFrom.trim() : void 0;
|
|
295
|
+
const fromRef = await resolveFromRef(cfg.defaultFrom, fromInput, execOpts?.signal);
|
|
259
296
|
state.generateCount += 1;
|
|
260
297
|
let commits;
|
|
261
298
|
try {
|
|
@@ -267,7 +304,7 @@ var plugin = {
|
|
|
267
304
|
state.commitCount += commits.length;
|
|
268
305
|
execOpts?.signal?.throwIfAborted();
|
|
269
306
|
const deterministicNotes = generateNotes(commits, cfg.includeScope);
|
|
270
|
-
const requested = (
|
|
307
|
+
const requested = ((typeof rawUseLlm === "boolean" ? rawUseLlm : void 0) ?? cfg.useLlm) && commits.length > 0;
|
|
271
308
|
const audience = readAudience(input.audience ?? cfg.audience);
|
|
272
309
|
const llm = await runOptionalPluginLlm({
|
|
273
310
|
requested,
|
|
@@ -342,5 +379,6 @@ var plugin = {
|
|
|
342
379
|
};
|
|
343
380
|
var release_notes_generator_default = plugin;
|
|
344
381
|
export {
|
|
345
|
-
release_notes_generator_default as default
|
|
382
|
+
release_notes_generator_default as default,
|
|
383
|
+
readConfig
|
|
346
384
|
};
|
|
@@ -49,11 +49,14 @@ var DEFAULTS = {
|
|
|
49
49
|
function readConfig(raw) {
|
|
50
50
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
51
51
|
const r = raw;
|
|
52
|
+
const rawSev = typeof (r["failSeverity"] ?? r["fail_severity"] ?? r["severity"] ?? r["mode"]) === "string" ? String(r["failSeverity"] ?? r["fail_severity"] ?? r["severity"] ?? r["mode"]).trim().toLowerCase() : void 0;
|
|
53
|
+
const rawMax = r["maxFindings"] ?? r["max_findings"] ?? r["limit"];
|
|
54
|
+
const rawPatterns = r["filePatterns"] ?? r["file_patterns"] ?? r["patterns"];
|
|
52
55
|
return {
|
|
53
56
|
enabled: r["enabled"] !== false,
|
|
54
|
-
failSeverity:
|
|
55
|
-
maxFindings: typeof
|
|
56
|
-
filePatterns: Array.isArray(
|
|
57
|
+
failSeverity: rawSev === "block" ? "block" : DEFAULTS.failSeverity,
|
|
58
|
+
maxFindings: typeof rawMax === "number" && Number.isFinite(rawMax) && rawMax >= 1 && rawMax <= 50 ? Math.floor(rawMax) : DEFAULTS.maxFindings,
|
|
59
|
+
filePatterns: Array.isArray(rawPatterns) ? rawPatterns.filter((x) => typeof x === "string") : DEFAULTS.filePatterns
|
|
57
60
|
};
|
|
58
61
|
}
|
|
59
62
|
function patternToRegExp(pattern) {
|
|
@@ -95,7 +98,12 @@ function findIssues(content, kind, maxFindings) {
|
|
|
95
98
|
}
|
|
96
99
|
case "prisma": {
|
|
97
100
|
const match = line.match(/^\s+([A-Za-z_]\w*)\s+([A-Za-z_]\w+)(\?)?(\s+@.*)?$/);
|
|
98
|
-
|
|
101
|
+
const attrs = match?.[4] ?? "";
|
|
102
|
+
const isExempt = attrs.split(/\s+/).some((t) => {
|
|
103
|
+
const name = t.replace(/\(.*$/, "");
|
|
104
|
+
return name === "@default" || name === "@id" || name === "@updatedAt" || name === "@relation" || name === "@ignore";
|
|
105
|
+
});
|
|
106
|
+
if (match && !match[3] && !isExempt) {
|
|
99
107
|
findings.push(
|
|
100
108
|
`required field without default at line ${lineNumber}: ${match[1]} (${match[2]})`
|
|
101
109
|
);
|
|
@@ -205,7 +213,8 @@ var plugin = {
|
|
|
205
213
|
if (!cfg.enabled) return;
|
|
206
214
|
if (input.toolResult?.isError) return;
|
|
207
215
|
const toolInput = input.toolInput ?? {};
|
|
208
|
-
const
|
|
216
|
+
const rawPath = toolInput["path"] ?? toolInput["filePath"] ?? toolInput["file_path"] ?? toolInput["TargetFile"] ?? toolInput["targetFile"] ?? toolInput["file"];
|
|
217
|
+
const filePath = typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
209
218
|
if (!filePath) return;
|
|
210
219
|
state.invocationCount += 1;
|
|
211
220
|
const fileName = basename(filePath);
|
|
@@ -221,6 +230,22 @@ var plugin = {
|
|
|
221
230
|
let content;
|
|
222
231
|
if (typeof toolInput["content"] === "string") {
|
|
223
232
|
content = toolInput["content"];
|
|
233
|
+
} else if (typeof toolInput["CodeContent"] === "string") {
|
|
234
|
+
content = toolInput["CodeContent"];
|
|
235
|
+
} else if (typeof toolInput["code"] === "string") {
|
|
236
|
+
content = toolInput["code"];
|
|
237
|
+
} else if (typeof toolInput["text"] === "string") {
|
|
238
|
+
content = toolInput["text"];
|
|
239
|
+
} else if (typeof toolInput["contents"] === "string") {
|
|
240
|
+
content = toolInput["contents"];
|
|
241
|
+
} else if (typeof toolInput["body"] === "string") {
|
|
242
|
+
content = toolInput["body"];
|
|
243
|
+
} else if (typeof toolInput["new_string"] === "string") {
|
|
244
|
+
content = toolInput["new_string"];
|
|
245
|
+
} else if (typeof toolInput["ReplacementContent"] === "string") {
|
|
246
|
+
content = toolInput["ReplacementContent"];
|
|
247
|
+
} else if (typeof toolInput["newContent"] === "string") {
|
|
248
|
+
content = toolInput["newContent"];
|
|
224
249
|
} else if ((0, runtime_exports.withinProject)(filePath)) {
|
|
225
250
|
try {
|
|
226
251
|
content = readFileSync(filePath, "utf-8");
|
|
@@ -250,7 +275,9 @@ ${body}${suffix}`;
|
|
|
250
275
|
state.warningCount += 1;
|
|
251
276
|
return { additionalContext: message };
|
|
252
277
|
};
|
|
253
|
-
state.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, {
|
|
278
|
+
state.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, {
|
|
279
|
+
background: true
|
|
280
|
+
});
|
|
254
281
|
api.tools.register({
|
|
255
282
|
name: "schema_evolution_status",
|
|
256
283
|
description: "Reports schema-evolution-guard state: config, file patterns, and per-session counters.",
|
package/dist/secret-scanner.js
CHANGED
|
@@ -198,14 +198,16 @@ var DEFAULTS = {
|
|
|
198
198
|
function readConfig(raw) {
|
|
199
199
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
200
200
|
const r = raw;
|
|
201
|
-
const
|
|
201
|
+
const rawMode = typeof (r["mode"] ?? r["action"] ?? r["behavior"]) === "string" ? String(r["mode"] ?? r["action"] ?? r["behavior"]).trim().toLowerCase() : void 0;
|
|
202
|
+
const mode = rawMode === "redact" || rawMode === "allow" || rawMode === "warn" ? rawMode === "warn" ? "allow" : rawMode : "block";
|
|
202
203
|
const customPatterns = [];
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
const rawCustom = r["customPatterns"] ?? r["custom_patterns"] ?? r["patterns"];
|
|
205
|
+
if (Array.isArray(rawCustom)) {
|
|
206
|
+
for (const entry of rawCustom) {
|
|
205
207
|
if (!entry || typeof entry !== "object") continue;
|
|
206
208
|
const e = entry;
|
|
207
|
-
const type = e["type"];
|
|
208
|
-
const regex = e["regex"];
|
|
209
|
+
const type = e["type"] ?? e["name"] ?? e["kind"];
|
|
210
|
+
const regex = e["regex"] ?? e["pattern"];
|
|
209
211
|
if (typeof type !== "string" || typeof regex !== "string") continue;
|
|
210
212
|
try {
|
|
211
213
|
new RegExp(regex, "g");
|
|
@@ -221,7 +223,7 @@ function readConfig(raw) {
|
|
|
221
223
|
}
|
|
222
224
|
return {
|
|
223
225
|
matcher: typeof r["matcher"] === "string" ? r["matcher"] : DEFAULTS.matcher,
|
|
224
|
-
postToolUseMatcher: typeof r["postToolUseMatcher"] === "string" ? r["postToolUseMatcher"] : DEFAULTS.postToolUseMatcher,
|
|
226
|
+
postToolUseMatcher: typeof (r["postToolUseMatcher"] ?? r["post_tool_use_matcher"] ?? r["outputMatcher"]) === "string" ? r["postToolUseMatcher"] ?? r["post_tool_use_matcher"] ?? r["outputMatcher"] : DEFAULTS.postToolUseMatcher,
|
|
225
227
|
mode,
|
|
226
228
|
enabled: r["enabled"] !== false,
|
|
227
229
|
customPatterns
|
|
@@ -445,7 +447,8 @@ var plugin = {
|
|
|
445
447
|
mutating: false,
|
|
446
448
|
async execute(input) {
|
|
447
449
|
activateRuntime(runtime);
|
|
448
|
-
const
|
|
450
|
+
const rawText = input["text"] ?? input["content"] ?? input["string"] ?? input["input"] ?? input["code"] ?? input["value"] ?? "";
|
|
451
|
+
const text = typeof rawText === "string" ? rawText : "";
|
|
449
452
|
const matched = findMatches(text);
|
|
450
453
|
return {
|
|
451
454
|
ok: true,
|