@wrongstack/plugins 0.313.0 → 0.316.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accessibility-auditor.js +3 -2
- package/dist/agent-handoff.js +13 -3
- package/dist/auto-doc.js +5 -2
- package/dist/auto-i18n-extractor.js +2 -1
- package/dist/branch-guard.js +1 -1
- package/dist/changelog-writer.js +16 -4
- package/dist/checkpoint.js +2 -1
- package/dist/commit-validator.js +2 -2
- package/dist/config-validator.js +26 -1
- package/dist/cost-tracker.js +2 -1
- package/dist/cron.js +1 -1
- package/dist/dependency-vulnerability-gate.js +12 -0
- package/dist/diff-summary.js +1 -1
- package/dist/doc-sync-guard.js +8 -1
- package/dist/duplicate-code-detector.js +4 -3
- package/dist/error-lens.js +3 -3
- package/dist/git-autocommit.js +5 -2
- package/dist/gitignore-guard.js +6 -2
- package/dist/import-organizer.js +10 -4
- package/dist/index.js +304 -186
- package/dist/interface-contract-guard.js +12 -3
- package/dist/knowledge-graph.js +5 -1
- package/dist/llm-cache.js +3 -2
- package/dist/loop-breaker.js +1 -1
- package/dist/migration-planner.js +0 -2
- package/dist/model-router.js +2 -0
- package/dist/notify-hub.js +5 -1
- package/dist/path-guard.js +2 -1
- package/dist/performance-regression-gate.js +2 -0
- package/dist/plugin-stack-observer.js +1 -0
- package/dist/pr-drafter.js +2 -2
- package/dist/process-guard.js +1 -2
- package/dist/prompt-firewall.js +3 -2
- package/dist/refactor-suggester.js +11 -0
- package/dist/security-hotspot-scanner.js +5 -5
- package/dist/semver-bump.js +3 -1
- package/dist/smart-rename.js +2 -2
- package/dist/spec-linker.js +1 -1
- package/dist/template-engine.js +4 -4
- package/dist/test-coverage-gate.js +5 -4
- package/dist/test-flake-detector.js +22 -8
- package/dist/test-generator.js +2 -2
- package/dist/todo-listener.js +3 -2
- package/dist/todo-tracker.js +2 -1
- package/package.json +5 -5
- package/dist/runtime/bounded-map.d.ts +0 -3
- package/dist/runtime/local-bin.d.ts +0 -3
- package/dist/runtime/safe-json.d.ts +0 -3
|
@@ -72,10 +72,19 @@ function extractInterfaceNames(content) {
|
|
|
72
72
|
}
|
|
73
73
|
return names;
|
|
74
74
|
}
|
|
75
|
-
var
|
|
75
|
+
var IMPLEMENTS_EXTENDS_RE = /(?:\bimplements\b|\bextends\b)\s+([^{;=]+)/g;
|
|
76
|
+
var SATISFIES_AS_RE = /(?:\bsatisfies\b|\bas\b)\s+([A-Za-z_$][A-Za-z0-9_$]*)/g;
|
|
77
|
+
var IDENTIFIER_RE = /[A-Za-z_$][A-Za-z0-9_$]*/g;
|
|
76
78
|
function collectImplementedNames(content, into) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
for (const m of content.matchAll(IMPLEMENTS_EXTENDS_RE)) {
|
|
80
|
+
const clause = m[1];
|
|
81
|
+
if (clause) {
|
|
82
|
+
for (const id of clause.matchAll(IDENTIFIER_RE)) {
|
|
83
|
+
if (id[0]) into.add(id[0]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (const m of content.matchAll(SATISFIES_AS_RE)) {
|
|
79
88
|
const name = m[1];
|
|
80
89
|
if (name) into.add(name);
|
|
81
90
|
}
|
package/dist/knowledge-graph.js
CHANGED
|
@@ -47,7 +47,11 @@ function loadFacts(filePath) {
|
|
|
47
47
|
const facts = Array.isArray(raw.facts) ? raw.facts.filter(
|
|
48
48
|
(f) => !!f && typeof f === "object" && typeof f.id === "string" && typeof f.subject === "string" && typeof f.relation === "string" && typeof f.object === "string"
|
|
49
49
|
) : [];
|
|
50
|
-
const
|
|
50
|
+
const maxExistingId = facts.reduce((max, f) => {
|
|
51
|
+
const n = parseInt(f.id.replace(/^\D+/, ""), 10);
|
|
52
|
+
return Number.isFinite(n) && n > max ? n : max;
|
|
53
|
+
}, 0);
|
|
54
|
+
const nextId = typeof raw.nextId === "number" && raw.nextId >= 1 ? raw.nextId : maxExistingId + 1;
|
|
51
55
|
return { facts, nextId };
|
|
52
56
|
} catch {
|
|
53
57
|
return { facts: [], nextId: 1 };
|
package/dist/llm-cache.js
CHANGED
|
@@ -30,7 +30,7 @@ function readConfig(raw) {
|
|
|
30
30
|
}
|
|
31
31
|
function isDeterministic(request) {
|
|
32
32
|
const t = request["temperature"];
|
|
33
|
-
return t === void 0 || t === 0;
|
|
33
|
+
return t === void 0 || t === null || t === 0;
|
|
34
34
|
}
|
|
35
35
|
var fingerprintCache = /* @__PURE__ */ new WeakMap();
|
|
36
36
|
function fingerprintRequest(request) {
|
|
@@ -172,7 +172,8 @@ var plugin = {
|
|
|
172
172
|
state.misses += 1;
|
|
173
173
|
api.metrics.counter("misses");
|
|
174
174
|
const response = await inner(_ctx, request);
|
|
175
|
-
|
|
175
|
+
const sr = response && typeof response === "object" ? response.stopReason : void 0;
|
|
176
|
+
if (response && typeof response === "object" && (sr === "end_turn" || sr === "stop" || sr === "tool_use")) {
|
|
176
177
|
lruSet(key, response, cfg.maxEntries);
|
|
177
178
|
}
|
|
178
179
|
return response;
|
package/dist/loop-breaker.js
CHANGED
|
@@ -112,7 +112,7 @@ function hashString(value) {
|
|
|
112
112
|
}
|
|
113
113
|
async function gitDiffFingerprint(cwd, targetPath, signal) {
|
|
114
114
|
const pathspec = isAbsolute(targetPath) ? relative(cwd, targetPath) : targetPath;
|
|
115
|
-
if (!pathspec || pathspec === ".." || pathspec.startsWith("../") || pathspec.startsWith("..\\")) {
|
|
115
|
+
if (!pathspec || isAbsolute(pathspec) || pathspec === ".." || pathspec.startsWith("../") || pathspec.startsWith("..\\")) {
|
|
116
116
|
return null;
|
|
117
117
|
}
|
|
118
118
|
try {
|
|
@@ -113,7 +113,6 @@ function extractBreakingChanges(sectionText) {
|
|
|
113
113
|
for (const rawLine of sectionText.split(/\r?\n/)) {
|
|
114
114
|
const line = rawLine.trim();
|
|
115
115
|
if (!line) {
|
|
116
|
-
inBreakingSection = false;
|
|
117
116
|
continue;
|
|
118
117
|
}
|
|
119
118
|
if (/^#{3,4}\s+(?:BREAKING\s+CHANGES?|Breaking\s+Changes?|Breaking)/i.test(line)) {
|
|
@@ -139,7 +138,6 @@ function extractRecommendedSteps(sectionText) {
|
|
|
139
138
|
for (const rawLine of sectionText.split(/\r?\n/)) {
|
|
140
139
|
const line = rawLine.trim();
|
|
141
140
|
if (!line) {
|
|
142
|
-
inMigrationSection = false;
|
|
143
141
|
continue;
|
|
144
142
|
}
|
|
145
143
|
if (/^#{3,4}\s+(?:Migration|Upgrade|How to|Steps|Recommended)/i.test(line)) {
|
package/dist/model-router.js
CHANGED
|
@@ -39,6 +39,8 @@ function requestCharSize(request) {
|
|
|
39
39
|
const o = v;
|
|
40
40
|
if (typeof o["text"] === "string") size += o["text"].length;
|
|
41
41
|
if (o["content"] !== void 0) walk(o["content"]);
|
|
42
|
+
if (o["input"] !== void 0) walk(o["input"]);
|
|
43
|
+
if (o["arguments"] !== void 0) walk(o["arguments"]);
|
|
42
44
|
}
|
|
43
45
|
};
|
|
44
46
|
walk(request["system"]);
|
package/dist/notify-hub.js
CHANGED
|
@@ -56,7 +56,7 @@ var WebhookNotificationChannel = class {
|
|
|
56
56
|
// -----------------------------------------------------------------------
|
|
57
57
|
async deliver(msg) {
|
|
58
58
|
const deliveredAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
59
|
-
const inCooldown = this.#resetMs
|
|
59
|
+
const inCooldown = this.#resetMs === 0 || Date.now() - this.#openedAt < this.#resetMs;
|
|
60
60
|
if (this.#circuit.open && this.#maxFailures > 0 && inCooldown) {
|
|
61
61
|
this.#totalSuppressed += 1;
|
|
62
62
|
return {
|
|
@@ -86,6 +86,10 @@ var WebhookNotificationChannel = class {
|
|
|
86
86
|
body,
|
|
87
87
|
signal: controller.signal
|
|
88
88
|
});
|
|
89
|
+
if (typeof res.arrayBuffer === "function") {
|
|
90
|
+
await res.arrayBuffer().catch(() => {
|
|
91
|
+
});
|
|
92
|
+
}
|
|
89
93
|
if (!res.ok) throw new Error(`webhook responded ${res.status}`);
|
|
90
94
|
} finally {
|
|
91
95
|
clearTimeout(timer);
|
package/dist/path-guard.js
CHANGED
|
@@ -89,6 +89,7 @@ function normalizePath(p) {
|
|
|
89
89
|
}
|
|
90
90
|
const joined = segments.join("/");
|
|
91
91
|
if (drive) return `${drive}/${joined}`.replace(/\/$/, "");
|
|
92
|
+
if (slashNormalized.startsWith("//")) return `//${joined}`.replace(/\/$/, "") || "//";
|
|
92
93
|
if (slashNormalized.startsWith("/")) return `/${joined}`.replace(/\/$/, "") || "/";
|
|
93
94
|
return joined;
|
|
94
95
|
}
|
|
@@ -1007,7 +1008,7 @@ function destructiveTargetsAtDepth(command, depth) {
|
|
|
1007
1008
|
targets.push(...roots.length > 0 ? roots : ["."]);
|
|
1008
1009
|
f = findDelete.exec(normalizedCommand);
|
|
1009
1010
|
}
|
|
1010
|
-
const shellWrapper = /\b(?:ba|z|k)?sh\s
|
|
1011
|
+
const shellWrapper = /\b(?:(?:ba|z|k)?sh|pwsh|powershell)\s+(?:-c|-Command)\s+(['"])(.*?)\1/gi;
|
|
1011
1012
|
let w = shellWrapper.exec(normalizedCommand);
|
|
1012
1013
|
while (w !== null) {
|
|
1013
1014
|
if (w[2] && !tokenIsQuoted(w, w[0].split(/\s/)[0] ?? "")) {
|
|
@@ -108,6 +108,8 @@ function pairCrossFile(baseline, current) {
|
|
|
108
108
|
const byKey = /* @__PURE__ */ new Map();
|
|
109
109
|
for (const bench of baseline) {
|
|
110
110
|
byKey.set(bench.key, bench);
|
|
111
|
+
const base = stripVariantSuffix(bench.name).base;
|
|
112
|
+
byKey.set(`${bench.group} > ${base}`, bench);
|
|
111
113
|
}
|
|
112
114
|
const pairs = [];
|
|
113
115
|
for (const bench of current) {
|
|
@@ -55,6 +55,7 @@ var PLUGIN = {
|
|
|
55
55
|
if (typeof p.plugin !== "string" || p.plugin.length === 0) return;
|
|
56
56
|
const wraps = Array.isArray(p.wraps) ? p.wraps.filter((w) => typeof w === "string") : [];
|
|
57
57
|
const kind = typeof p.kind === "string" ? p.kind : "unknown";
|
|
58
|
+
state.wraps = state.wraps.filter((w) => w.plugin !== p.plugin);
|
|
58
59
|
state.wraps.push({
|
|
59
60
|
plugin: p.plugin,
|
|
60
61
|
kind,
|
package/dist/pr-drafter.js
CHANGED
|
@@ -278,10 +278,10 @@ var plugin = {
|
|
|
278
278
|
category: "Workflow",
|
|
279
279
|
mutating: true,
|
|
280
280
|
capabilities: ["fs.write"],
|
|
281
|
-
async execute(input) {
|
|
281
|
+
async execute(input = {}) {
|
|
282
282
|
if (!cfg.enabled) return { ok: false, error: "pr-drafter is disabled" };
|
|
283
283
|
const draft = await buildDraft(cfg, api.llm);
|
|
284
|
-
if (input
|
|
284
|
+
if (input?.preview) {
|
|
285
285
|
return { ok: true, preview: true, title: draft.title, body: draft.body };
|
|
286
286
|
}
|
|
287
287
|
const resolved = resolveProjectPath(cfg.outputPath);
|
package/dist/process-guard.js
CHANGED
|
@@ -63,8 +63,7 @@ var plugin = {
|
|
|
63
63
|
const ti = input.toolInput ?? {};
|
|
64
64
|
const command = typeof ti["command"] === "string" ? ti["command"] : "";
|
|
65
65
|
if (!command) return;
|
|
66
|
-
const
|
|
67
|
-
const isKillRelated = cmdLower.includes("kill") || cmdLower.includes("taskkill") || cmdLower.includes("stop-process") || cmdLower.includes("tskill") || cmdLower.includes("pkill") || cmdLower.includes("killall") || cmdLower.includes("wmic");
|
|
66
|
+
const isKillRelated = /\b(?:kill|taskkill|stop-process|tskill|pkill|killall|wmic)\b/i.test(command);
|
|
68
67
|
if (!isKillRelated) return;
|
|
69
68
|
state.detections += 1;
|
|
70
69
|
state.lastDetection = {
|
package/dist/prompt-firewall.js
CHANGED
|
@@ -74,7 +74,7 @@ function growMatch(re, p, text, absStart, deadline) {
|
|
|
74
74
|
const ext = text.slice(absStart, extEnd);
|
|
75
75
|
re.lastIndex = 0;
|
|
76
76
|
const em = re.exec(ext);
|
|
77
|
-
if (
|
|
77
|
+
if (em?.index !== 0 || em[0].length === 0) return null;
|
|
78
78
|
const end = absStart + em[0].length;
|
|
79
79
|
if (end < extEnd || extEnd === text.length) {
|
|
80
80
|
return { start: absStart, end, matched: em[0] };
|
|
@@ -84,7 +84,8 @@ function growMatch(re, p, text, absStart, deadline) {
|
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
86
|
function* execWindowed(p, text, deadline) {
|
|
87
|
-
const
|
|
87
|
+
const flags = p.re.flags.includes("g") ? p.re.flags : `${p.re.flags}g`;
|
|
88
|
+
const re = new RegExp(p.re.source, flags);
|
|
88
89
|
let acceptLo = 0;
|
|
89
90
|
let highWater = 0;
|
|
90
91
|
for (let window = 0; acceptLo < text.length; window++) {
|
|
@@ -77,10 +77,21 @@ function detectSmells(filePath, content, rules) {
|
|
|
77
77
|
const suggestions = [];
|
|
78
78
|
const lines = content.split(/\r?\n/);
|
|
79
79
|
const stripped = content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, " ");
|
|
80
|
+
const CONTROL_KEYWORDS = /* @__PURE__ */ new Set([
|
|
81
|
+
"if",
|
|
82
|
+
"for",
|
|
83
|
+
"while",
|
|
84
|
+
"switch",
|
|
85
|
+
"catch",
|
|
86
|
+
"with",
|
|
87
|
+
"typeof",
|
|
88
|
+
"instanceof"
|
|
89
|
+
]);
|
|
80
90
|
const functionLikeRe = /(?:export\s+)?(?:async\s+)?(?:function\s+)?([A-Za-z_$][A-Za-z0-9_$]*)\s*\(([^)]*)\)\s*\{/g;
|
|
81
91
|
functionLikeRe.lastIndex = 0;
|
|
82
92
|
for (const match of stripped.matchAll(functionLikeRe)) {
|
|
83
93
|
const name = match[1];
|
|
94
|
+
if (CONTROL_KEYWORDS.has(name)) continue;
|
|
84
95
|
const paramsRaw = match[2];
|
|
85
96
|
const params = paramsRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
86
97
|
if (params.length > rules.maxParams) {
|
|
@@ -14,7 +14,7 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
14
14
|
|
|
15
15
|
// src/security-hotspot-scanner/index.ts
|
|
16
16
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
17
|
-
import { isAbsolute, relative, resolve } from "node:path";
|
|
17
|
+
import { extname, isAbsolute, relative, resolve } from "node:path";
|
|
18
18
|
|
|
19
19
|
// src/runtime/index.ts
|
|
20
20
|
var runtime_exports = {};
|
|
@@ -250,10 +250,10 @@ var plugin = {
|
|
|
250
250
|
if (!cfg.enabled) return;
|
|
251
251
|
if (input.toolResult?.isError) return;
|
|
252
252
|
const inp = input.toolInput ?? {};
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
256
|
-
const ext =
|
|
253
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"];
|
|
254
|
+
const sourcePath = typeof rawPath === "string" ? rawPath : void 0;
|
|
255
|
+
if (!sourcePath || !(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
256
|
+
const ext = extname(sourcePath).toLowerCase();
|
|
257
257
|
if (!scanOnChangeSet.has(ext)) {
|
|
258
258
|
state.skippedCount += 1;
|
|
259
259
|
return;
|
package/dist/semver-bump.js
CHANGED
|
@@ -217,6 +217,7 @@ var plugin = {
|
|
|
217
217
|
state.lastBump = null;
|
|
218
218
|
const tagPrefix = api.config.extensions?.["semver-bump"]?.["tagPrefix"] ?? "v";
|
|
219
219
|
const autoTag = api.config.extensions?.["semver-bump"]?.["autoTag"] ?? true;
|
|
220
|
+
const tagMessage = api.config.extensions?.["semver-bump"]?.["tagMessage"] ?? "Release {{version}}";
|
|
220
221
|
const VALID_PARTS = ["major", "minor", "patch", "auto"];
|
|
221
222
|
function readDefaultPart(cfg) {
|
|
222
223
|
const raw = cfg.extensions?.["semver-bump"]?.["defaultPart"];
|
|
@@ -325,7 +326,8 @@ var plugin = {
|
|
|
325
326
|
}
|
|
326
327
|
if (autoTag) {
|
|
327
328
|
try {
|
|
328
|
-
|
|
329
|
+
const msg = tagMessage.replace("{{version}}", newVersion);
|
|
330
|
+
await runGit(["tag", "-a", `${tagPrefix}${newVersion}`, "-m", msg], cwd);
|
|
329
331
|
} catch {
|
|
330
332
|
}
|
|
331
333
|
}
|
package/dist/smart-rename.js
CHANGED
|
@@ -171,8 +171,8 @@ var plugin = {
|
|
|
171
171
|
},
|
|
172
172
|
async health() {
|
|
173
173
|
return {
|
|
174
|
-
ok:
|
|
175
|
-
message:
|
|
174
|
+
ok: true,
|
|
175
|
+
message: `smart-rename: ${state.renameCount} rename(s), ${state.replacementCount} replacement(s)${state.errorCount ? ` (${state.errorCount} error(s))` : ""}`,
|
|
176
176
|
counters: {
|
|
177
177
|
renames: state.renameCount,
|
|
178
178
|
replacements: state.replacementCount,
|
package/dist/spec-linker.js
CHANGED
|
@@ -227,7 +227,7 @@ function isWrappedAsLinkOrCode(line, name) {
|
|
|
227
227
|
const target = name.toLowerCase();
|
|
228
228
|
if (lower.includes(`[${target}](`)) return true;
|
|
229
229
|
if (lower.includes(`\`${target}\``)) return true;
|
|
230
|
-
if (
|
|
230
|
+
if (new RegExp(`\\[[^\\]]*\`${escapeRegExp(target)}\`[^\\]]*\\]\\(`, "i").test(line)) return true;
|
|
231
231
|
return false;
|
|
232
232
|
}
|
|
233
233
|
function escapeRegExp(s) {
|
package/dist/template-engine.js
CHANGED
|
@@ -35,7 +35,7 @@ function templateChars(template) {
|
|
|
35
35
|
var contributorUnregister = null;
|
|
36
36
|
function expandTemplate(template, variables) {
|
|
37
37
|
let result = template;
|
|
38
|
-
result = result.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
38
|
+
result = result.replace(/\{\{([\w.-]+)\}\}/g, (match, key) => {
|
|
39
39
|
const value = variables[key];
|
|
40
40
|
if (value !== void 0) return value;
|
|
41
41
|
return match;
|
|
@@ -43,18 +43,18 @@ function expandTemplate(template, variables) {
|
|
|
43
43
|
return result;
|
|
44
44
|
}
|
|
45
45
|
function expandConditionals(template, variables) {
|
|
46
|
-
return template.replace(/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, key, content) => {
|
|
46
|
+
return template.replace(/\{\{#if\s+([\w.-]+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, key, content) => {
|
|
47
47
|
const val = variables[key];
|
|
48
48
|
return val !== void 0 && val !== "" && val !== "false" && val !== "0" ? content : "";
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
function expandLoops(template, variables) {
|
|
52
|
-
return template.replace(/\{\{#each\s+(\w+)\}\}([\s\S]*?)\{\{\/each\}\}/g, (_, key, content) => {
|
|
52
|
+
return template.replace(/\{\{#each\s+([\w.-]+)\}\}([\s\S]*?)\{\{\/each\}\}/g, (_, key, content) => {
|
|
53
53
|
const val = variables[key];
|
|
54
54
|
if (!val) return "";
|
|
55
55
|
if (typeof val === "string" && val.includes(",")) {
|
|
56
56
|
const items = val.split(",").map((s) => s.trim());
|
|
57
|
-
return items.map((item) => expandTemplate(content, { ...variables, [key]: item })).join("\n");
|
|
57
|
+
return items.map((item) => expandTemplate(content, { ...variables, [key]: item, item })).join("\n");
|
|
58
58
|
}
|
|
59
59
|
return expandTemplate(content, variables);
|
|
60
60
|
});
|
|
@@ -14,6 +14,7 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
14
14
|
|
|
15
15
|
// src/test-coverage-gate/index.ts
|
|
16
16
|
import { readFileSync } from "node:fs";
|
|
17
|
+
import { extname } from "node:path";
|
|
17
18
|
|
|
18
19
|
// src/runtime/index.ts
|
|
19
20
|
var runtime_exports = {};
|
|
@@ -137,10 +138,10 @@ var plugin = {
|
|
|
137
138
|
if (!cfg.enabled) return;
|
|
138
139
|
if (input.toolResult?.isError) return;
|
|
139
140
|
const inp = input.toolInput ?? {};
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
143
|
-
const ext =
|
|
141
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"];
|
|
142
|
+
const sourcePath = typeof rawPath === "string" ? rawPath : void 0;
|
|
143
|
+
if (!sourcePath || !(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
144
|
+
const ext = extname(sourcePath).toLowerCase();
|
|
144
145
|
if (!runOnChangeSet.has(ext)) {
|
|
145
146
|
state.skippedCount += 1;
|
|
146
147
|
return;
|
|
@@ -1,8 +1,29 @@
|
|
|
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
|
+
|
|
1
15
|
// src/test-flake-detector/index.ts
|
|
2
16
|
import { execFile } from "node:child_process";
|
|
3
17
|
import { readFileSync } from "node:fs";
|
|
4
18
|
import { createRequire } from "node:module";
|
|
5
19
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
20
|
+
|
|
21
|
+
// src/runtime/index.ts
|
|
22
|
+
var runtime_exports = {};
|
|
23
|
+
__reExport(runtime_exports, runtime_star);
|
|
24
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
25
|
+
|
|
26
|
+
// src/test-flake-detector/index.ts
|
|
6
27
|
var API_VERSION = "^0.1.10";
|
|
7
28
|
var state = {
|
|
8
29
|
invocationCount: 0,
|
|
@@ -71,13 +92,6 @@ var ALLOWED_RUNNER_FLAGS = /* @__PURE__ */ new Set([
|
|
|
71
92
|
"--reporter=verbose",
|
|
72
93
|
"--reporter=default"
|
|
73
94
|
]);
|
|
74
|
-
function withinProject(p) {
|
|
75
|
-
if (p.length === 0 || p.length > 4096 || p.startsWith("-")) return false;
|
|
76
|
-
const root = resolve(process.cwd());
|
|
77
|
-
const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
|
|
78
|
-
const rel = relative(root, resolved);
|
|
79
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
80
|
-
}
|
|
81
95
|
function isInside(parent, child) {
|
|
82
96
|
if (parent === child) return true;
|
|
83
97
|
const rel = relative(parent, child);
|
|
@@ -134,7 +148,7 @@ function resolveTestCommand(baseCommand, testPattern) {
|
|
|
134
148
|
}
|
|
135
149
|
const args = [resolvedEntry, ...runnerArgs];
|
|
136
150
|
if (testPattern) {
|
|
137
|
-
if (!withinProject(testPattern)) return null;
|
|
151
|
+
if (!(0, runtime_exports.withinProject)(testPattern)) return null;
|
|
138
152
|
args.push(testPattern);
|
|
139
153
|
}
|
|
140
154
|
return {
|
package/dist/test-generator.js
CHANGED
|
@@ -369,8 +369,8 @@ var plugin = {
|
|
|
369
369
|
},
|
|
370
370
|
async health() {
|
|
371
371
|
return {
|
|
372
|
-
ok:
|
|
373
|
-
message:
|
|
372
|
+
ok: true,
|
|
373
|
+
message: `test-generator: ${state.generateCount} generation(s), ${state.exportCount} export(s)${state.errorCount ? ` (${state.errorCount} error(s))` : ""}`,
|
|
374
374
|
counters: {
|
|
375
375
|
generated: state.generateCount,
|
|
376
376
|
exports: state.exportCount,
|
package/dist/todo-listener.js
CHANGED
|
@@ -47,8 +47,9 @@ function readConfig(raw) {
|
|
|
47
47
|
function hashTodos(todos) {
|
|
48
48
|
const sorted = todos.map((t) => `${t.id}|${t.status}|${t.content ?? ""}`).sort();
|
|
49
49
|
let h = 2166136261;
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const joined = sorted.join("\n");
|
|
51
|
+
for (let i = 0; i < joined.length; i++) {
|
|
52
|
+
h ^= joined.charCodeAt(i);
|
|
52
53
|
h = h * 16777619 >>> 0;
|
|
53
54
|
}
|
|
54
55
|
return h.toString(16);
|
package/dist/todo-tracker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/todo-tracker/index.ts
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import * as fsp from "node:fs/promises";
|
|
4
|
+
import { dirname } from "node:path";
|
|
4
5
|
import { atomicWrite, ensureDir } from "@wrongstack/core/utils";
|
|
5
6
|
import { nowIso } from "@wrongstack/primitives";
|
|
6
7
|
function deriveFilePath(api) {
|
|
@@ -32,7 +33,7 @@ async function loadFile(filePath) {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
async function saveFile(filePath, file) {
|
|
35
|
-
await ensureDir(filePath
|
|
36
|
+
await ensureDir(dirname(filePath));
|
|
36
37
|
await atomicWrite(filePath, JSON.stringify(file, null, 2), { mode: 384 });
|
|
37
38
|
}
|
|
38
39
|
var state = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/plugins",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.316.1",
|
|
4
4
|
"description": "Official WrongStack collection of focused plugins for code quality, security, observability, planning, and agent coordination",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ECOSTACK TECHNOLOGY OÜ",
|
|
@@ -303,10 +303,10 @@
|
|
|
303
303
|
"vitest": "^4.1.11"
|
|
304
304
|
},
|
|
305
305
|
"dependencies": {
|
|
306
|
-
"@wrongstack/
|
|
307
|
-
"@wrongstack/
|
|
308
|
-
"@wrongstack/tools": "0.
|
|
309
|
-
"@wrongstack/primitives": "0.
|
|
306
|
+
"@wrongstack/core": "0.316.1",
|
|
307
|
+
"@wrongstack/plugin-sdk": "0.316.1",
|
|
308
|
+
"@wrongstack/tools": "0.316.1",
|
|
309
|
+
"@wrongstack/primitives": "0.316.1"
|
|
310
310
|
},
|
|
311
311
|
"scripts": {
|
|
312
312
|
"build": "node ../../scripts/build-package.mjs",
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
/** Shim: implementation moved to @wrongstack/plugin-sdk/runtime. */
|
|
2
|
-
export { clearLocalBinCache, findOnPath, resolveExecInvocation, resolveFirstNodeBin, resolveNodeBin, resolveWin32Command, type ExecInvocation, type ResolvedNodeBin, } from '@wrongstack/plugin-sdk/runtime';
|
|
3
|
-
//# sourceMappingURL=local-bin.d.ts.map
|