@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
|
@@ -58,6 +58,7 @@ import type { Plugin } from '@wrongstack/core/types';
|
|
|
58
58
|
*/
|
|
59
59
|
export declare function stripInvisible(text: string): string;
|
|
60
60
|
export declare function scanForInjection(text: string): string[];
|
|
61
|
+
export declare function extractToolContent(toolResult: unknown): string;
|
|
61
62
|
declare const plugin: Plugin;
|
|
62
63
|
export default plugin;
|
|
63
64
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/injection-shield.js
CHANGED
|
@@ -15,11 +15,14 @@ var DEFAULTS = {
|
|
|
15
15
|
function readConfig(raw) {
|
|
16
16
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
17
17
|
const r = raw;
|
|
18
|
+
const rawTools = r["tools"] ?? r["matcher"] ?? r["toolMatcher"] ?? r["tool_matcher"];
|
|
19
|
+
const rawMin = r["minMatches"] ?? r["min_matches"] ?? r["min"];
|
|
20
|
+
const rawMax = r["maxScanChars"] ?? r["max_scan_chars"] ?? r["maxChars"] ?? r["max_chars"];
|
|
18
21
|
return {
|
|
19
22
|
enabled: r["enabled"] !== false,
|
|
20
|
-
tools: typeof
|
|
21
|
-
minMatches: typeof
|
|
22
|
-
maxScanChars: typeof
|
|
23
|
+
tools: typeof rawTools === "string" && rawTools.length > 0 ? rawTools : DEFAULTS.tools,
|
|
24
|
+
minMatches: typeof rawMin === "number" && rawMin >= 1 && rawMin <= 10 ? rawMin : DEFAULTS.minMatches,
|
|
25
|
+
maxScanChars: typeof rawMax === "number" && rawMax >= 1024 ? rawMax : DEFAULTS.maxScanChars
|
|
23
26
|
};
|
|
24
27
|
}
|
|
25
28
|
var PATTERNS = [
|
|
@@ -78,6 +81,27 @@ function scanForInjection(text) {
|
|
|
78
81
|
}
|
|
79
82
|
return [...hits];
|
|
80
83
|
}
|
|
84
|
+
function extractToolContent(toolResult) {
|
|
85
|
+
if (!toolResult) return "";
|
|
86
|
+
if (typeof toolResult === "string") return toolResult;
|
|
87
|
+
if (typeof toolResult === "object") {
|
|
88
|
+
const tr = toolResult;
|
|
89
|
+
if (typeof tr["content"] === "string") return tr["content"];
|
|
90
|
+
if (Array.isArray(tr["content"])) {
|
|
91
|
+
return tr["content"].map(
|
|
92
|
+
(item) => typeof item === "string" ? item : typeof item === "object" && item && typeof item["text"] === "string" ? item["text"] : ""
|
|
93
|
+
).filter(Boolean).join("\n");
|
|
94
|
+
}
|
|
95
|
+
if (typeof tr["output"] === "string") return tr["output"];
|
|
96
|
+
if (typeof tr["stdout"] === "string") return tr["stdout"];
|
|
97
|
+
if (typeof tr["text"] === "string") return tr["text"];
|
|
98
|
+
if (typeof tr["result"] === "string") return tr["result"];
|
|
99
|
+
if (typeof tr["body"] === "string") return tr["body"];
|
|
100
|
+
if (typeof tr["contents"] === "string") return tr["contents"];
|
|
101
|
+
if (typeof tr["data"] === "string") return tr["data"];
|
|
102
|
+
}
|
|
103
|
+
return "";
|
|
104
|
+
}
|
|
81
105
|
var plugin = {
|
|
82
106
|
name: "injection-shield",
|
|
83
107
|
version: "0.1.0",
|
|
@@ -125,8 +149,8 @@ var plugin = {
|
|
|
125
149
|
const hook = (input) => {
|
|
126
150
|
if (!cfg.enabled) return;
|
|
127
151
|
state.invocations += 1;
|
|
128
|
-
const content = input.toolResult
|
|
129
|
-
if (
|
|
152
|
+
const content = extractToolContent(input.toolResult);
|
|
153
|
+
if (content.length === 0) return;
|
|
130
154
|
state.scans += 1;
|
|
131
155
|
const hits = scanForInjection(content.slice(0, cfg.maxScanChars));
|
|
132
156
|
if (hits.length < cfg.minMatches) return;
|
|
@@ -211,6 +235,7 @@ var plugin = {
|
|
|
211
235
|
var injection_shield_default = plugin;
|
|
212
236
|
export {
|
|
213
237
|
injection_shield_default as default,
|
|
238
|
+
extractToolContent,
|
|
214
239
|
scanForInjection,
|
|
215
240
|
stripInvisible
|
|
216
241
|
};
|
|
@@ -175,7 +175,8 @@ var plugin = {
|
|
|
175
175
|
if (!cfg.enabled) return;
|
|
176
176
|
if (input.toolResult?.isError) return;
|
|
177
177
|
const inp = input.toolInput ?? {};
|
|
178
|
-
const
|
|
178
|
+
const rawPath = inp["path"] ?? inp["TargetFile"] ?? inp["filePath"] ?? inp["targetFile"] ?? inp["file_path"] ?? inp["file"];
|
|
179
|
+
const sourcePath = typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
179
180
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
180
181
|
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
181
182
|
const exts = normalizeExtensions(cfg.extensions);
|
|
@@ -214,7 +215,8 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
|
|
|
214
215
|
mutating: false,
|
|
215
216
|
async execute(input) {
|
|
216
217
|
if (!cfg.enabled) return { ok: false, error: "interface-contract-guard is disabled" };
|
|
217
|
-
const
|
|
218
|
+
const raw = input ?? {};
|
|
219
|
+
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) ?? (typeof raw["file"] === "string" ? raw["file"] : void 0) ?? ".";
|
|
218
220
|
if (!(0, runtime_exports.withinProject)(rawPath)) {
|
|
219
221
|
return { ok: false, error: "path is outside the project root" };
|
|
220
222
|
}
|
package/dist/knowledge-graph.js
CHANGED
|
@@ -25,19 +25,24 @@ function resolveProjectPath(rawPath, cwd = process.cwd()) {
|
|
|
25
25
|
const root = resolve(cwd);
|
|
26
26
|
const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
|
|
27
27
|
const rel = relative(root, resolved);
|
|
28
|
-
if (rel === "" ||
|
|
29
|
-
return
|
|
28
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) return null;
|
|
29
|
+
return resolved;
|
|
30
30
|
}
|
|
31
31
|
function readConfig(raw) {
|
|
32
32
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
33
33
|
const r = raw;
|
|
34
|
+
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;
|
|
35
|
+
const rawMaxFacts = r["maxFacts"] ?? r["max_facts"] ?? r["limit"];
|
|
36
|
+
const rawMaxFactChars = r["maxFactChars"] ?? r["max_fact_chars"] ?? r["maxChars"] ?? r["max_chars"];
|
|
37
|
+
const rawContribute = r["contributeToSystemPrompt"] ?? r["contribute_to_system_prompt"] ?? r["contribute"];
|
|
38
|
+
const rawContributeMax = r["contributeMaxChars"] ?? r["contribute_max_chars"];
|
|
34
39
|
return {
|
|
35
40
|
enabled: r["enabled"] !== false,
|
|
36
|
-
filePath: typeof
|
|
37
|
-
maxFacts: typeof
|
|
38
|
-
maxFactChars: typeof
|
|
39
|
-
contributeToSystemPrompt:
|
|
40
|
-
contributeMaxChars: typeof
|
|
41
|
+
filePath: typeof rawPath === "string" ? rawPath : DEFAULTS.filePath,
|
|
42
|
+
maxFacts: typeof rawMaxFacts === "number" && rawMaxFacts >= 1 && rawMaxFacts <= 2e3 ? rawMaxFacts : DEFAULTS.maxFacts,
|
|
43
|
+
maxFactChars: typeof rawMaxFactChars === "number" && rawMaxFactChars >= 20 ? rawMaxFactChars : DEFAULTS.maxFactChars,
|
|
44
|
+
contributeToSystemPrompt: rawContribute !== false,
|
|
45
|
+
contributeMaxChars: typeof rawContributeMax === "number" && rawContributeMax >= 100 ? rawContributeMax : DEFAULTS.contributeMaxChars
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
48
|
function loadFacts(filePath) {
|
|
@@ -174,19 +179,28 @@ var plugin = {
|
|
|
174
179
|
};
|
|
175
180
|
}
|
|
176
181
|
const trim = (s) => String(s ?? "").trim().slice(0, cfg.maxFactChars);
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
182
|
+
const raw = input;
|
|
183
|
+
const subject = trim(
|
|
184
|
+
input.subject ?? raw["entity"] ?? raw["topic"] ?? raw["sub"] ?? raw["name"] ?? raw["sourceEntity"]
|
|
185
|
+
);
|
|
186
|
+
const relation = trim(
|
|
187
|
+
input.relation ?? raw["predicate"] ?? raw["rel"] ?? raw["verb"] ?? raw["relationship"] ?? raw["action"]
|
|
188
|
+
);
|
|
189
|
+
const object = trim(
|
|
190
|
+
input.object ?? raw["target"] ?? raw["val"] ?? raw["value"] ?? raw["obj"] ?? raw["targetEntity"]
|
|
191
|
+
);
|
|
180
192
|
if (!subject || !relation || !object) {
|
|
181
193
|
return { ok: false, error: "subject, relation, and object are required" };
|
|
182
194
|
}
|
|
195
|
+
const rawConf = typeof input.confidence === "string" ? input.confidence.trim().toLowerCase() : "";
|
|
196
|
+
const confidence = rawConf === "low" || rawConf === "high" || rawConf === "medium" ? rawConf : "medium";
|
|
183
197
|
const fact = {
|
|
184
198
|
id: `kg-${state.nextId++}`,
|
|
185
199
|
subject,
|
|
186
200
|
relation,
|
|
187
201
|
object,
|
|
188
202
|
source: input.source ? String(input.source).slice(0, cfg.maxFactChars) : null,
|
|
189
|
-
confidence
|
|
203
|
+
confidence,
|
|
190
204
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
191
205
|
};
|
|
192
206
|
state.facts.push(fact);
|
|
@@ -215,19 +229,29 @@ var plugin = {
|
|
|
215
229
|
async execute(input) {
|
|
216
230
|
if (!cfg.enabled) return { ok: false, error: "knowledge-graph is disabled" };
|
|
217
231
|
state.queries += 1;
|
|
232
|
+
const raw = input;
|
|
233
|
+
const rawQ = (typeof raw["query"] === "string" ? raw["query"] : void 0) ?? (typeof raw["q"] === "string" ? raw["q"] : void 0);
|
|
234
|
+
const q = rawQ?.toLowerCase();
|
|
235
|
+
const rawFilterConf = typeof input.confidence === "string" ? input.confidence.trim().toLowerCase() : void 0;
|
|
236
|
+
const filterConf = rawFilterConf === "low" || rawFilterConf === "medium" || rawFilterConf === "high" ? rawFilterConf : void 0;
|
|
218
237
|
const limit = typeof input.limit === "number" && input.limit >= 1 ? Math.floor(input.limit) : 20;
|
|
219
238
|
const matches = state.facts.filter((f) => {
|
|
239
|
+
if (q) {
|
|
240
|
+
const hasMatch = f.subject.toLowerCase().includes(q) || f.relation.toLowerCase().includes(q) || f.object.toLowerCase().includes(q);
|
|
241
|
+
if (!hasMatch) return false;
|
|
242
|
+
}
|
|
220
243
|
if (input.subject && !f.subject.toLowerCase().includes(input.subject.toLowerCase())) return false;
|
|
221
244
|
if (input.relation && !f.relation.toLowerCase().includes(input.relation.toLowerCase())) return false;
|
|
222
245
|
if (input.object && !f.object.toLowerCase().includes(input.object.toLowerCase())) return false;
|
|
223
|
-
if (
|
|
246
|
+
if (filterConf && f.confidence.toLowerCase() !== filterConf) return false;
|
|
224
247
|
return true;
|
|
225
248
|
});
|
|
249
|
+
const returnedFacts = matches.slice(-limit);
|
|
226
250
|
return {
|
|
227
251
|
ok: true,
|
|
228
252
|
totalFacts: state.facts.length,
|
|
229
|
-
returned:
|
|
230
|
-
facts:
|
|
253
|
+
returned: returnedFacts.length,
|
|
254
|
+
facts: returnedFacts
|
|
231
255
|
};
|
|
232
256
|
}
|
|
233
257
|
});
|
|
@@ -247,9 +271,12 @@ var plugin = {
|
|
|
247
271
|
async execute(input) {
|
|
248
272
|
if (!cfg.enabled) return { ok: false, error: "knowledge-graph is disabled" };
|
|
249
273
|
const before = state.facts.length;
|
|
250
|
-
|
|
274
|
+
const raw = input ?? {};
|
|
275
|
+
const rawId = String(input.id ?? raw["factId"] ?? raw["fact_id"] ?? "").trim();
|
|
276
|
+
const normalized = rawId.toLowerCase().startsWith("kg-") ? rawId.toLowerCase() : `kg-${rawId.toLowerCase()}`;
|
|
277
|
+
state.facts = state.facts.filter((f) => f.id.toLowerCase() !== normalized && f.id !== rawId);
|
|
251
278
|
const removed = before - state.facts.length;
|
|
252
|
-
if (removed === 0) return { ok: false, error: `no fact matches "${input.id}"` };
|
|
279
|
+
if (removed === 0) return { ok: false, error: `no fact matches "${input.id ?? rawId}"` };
|
|
253
280
|
state.removals += removed;
|
|
254
281
|
api.metrics.counter("removals", removed);
|
|
255
282
|
const persisted = await persistFacts(resolved);
|
|
@@ -36,14 +36,14 @@ function readConfig(raw) {
|
|
|
36
36
|
confirmTyposquatsWithLlm: r["confirmTyposquatsWithLlm"] === true
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
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;
|
|
39
|
+
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;
|
|
40
40
|
function parseInstallCommands(command) {
|
|
41
41
|
const out = [];
|
|
42
42
|
INSTALL_RE.lastIndex = 0;
|
|
43
43
|
let m = INSTALL_RE.exec(command);
|
|
44
44
|
while (m !== null) {
|
|
45
|
-
const manager = (m[1] ?? m[3] ?? m[5] ?? "").toLowerCase();
|
|
46
|
-
const argString = m[2] ?? m[4] ?? m[6] ?? "";
|
|
45
|
+
const manager = (m[1] ?? m[3] ?? m[5] ?? m[7] ?? "").toLowerCase();
|
|
46
|
+
const argString = m[2] ?? m[4] ?? m[6] ?? m[8] ?? "";
|
|
47
47
|
const packages = [];
|
|
48
48
|
for (const token of argString.split(/\s+/)) {
|
|
49
49
|
if (!token || token.startsWith("-")) continue;
|
|
@@ -205,7 +205,8 @@ var plugin = {
|
|
|
205
205
|
if (!cfg.enabled) return;
|
|
206
206
|
state.invocations += 1;
|
|
207
207
|
const ti = input.toolInput ?? {};
|
|
208
|
-
const
|
|
208
|
+
const rawCmd = ti["command"] ?? ti["CommandLine"] ?? ti["cmd"] ?? ti["script"] ?? ti["input"];
|
|
209
|
+
const command = typeof rawCmd === "string" ? rawCmd : "";
|
|
209
210
|
if (!command) return;
|
|
210
211
|
const installs = parseInstallCommands(command);
|
|
211
212
|
const packages = installs.flatMap((i) => i.packages);
|
|
@@ -400,11 +401,13 @@ function normalizeStrings(v) {
|
|
|
400
401
|
function readConfig2(raw) {
|
|
401
402
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS2 };
|
|
402
403
|
const r = raw;
|
|
403
|
-
const
|
|
404
|
+
const rawLicenses = r["allowedLicenses"] ?? r["allowed_licenses"] ?? r["licenses"];
|
|
405
|
+
const allowed = normalizeStrings(rawLicenses);
|
|
406
|
+
const rawBlock = r["block"] ?? r["fail_on_violation"] ?? r["failOnViolation"];
|
|
404
407
|
return {
|
|
405
408
|
enabled: r["enabled"] !== false,
|
|
406
409
|
allowedLicenses: allowed.length > 0 ? allowed : [...DEFAULTS2.allowedLicenses],
|
|
407
|
-
block:
|
|
410
|
+
block: rawBlock !== false
|
|
408
411
|
};
|
|
409
412
|
}
|
|
410
413
|
function extractLicenseStrings(pkg) {
|
|
@@ -430,6 +433,56 @@ function parsePackageNames(command) {
|
|
|
430
433
|
...new Set(parseInstallCommands(command).flatMap((entry) => entry.packages.map((pkg) => pkg.name)))
|
|
431
434
|
];
|
|
432
435
|
}
|
|
436
|
+
function splitTopLevel(expr, separator) {
|
|
437
|
+
const parts = [];
|
|
438
|
+
let depth = 0;
|
|
439
|
+
let start = 0;
|
|
440
|
+
for (let i = 0; i < expr.length; i++) {
|
|
441
|
+
const ch = expr[i];
|
|
442
|
+
if (ch === "(") depth++;
|
|
443
|
+
else if (ch === ")") depth = Math.max(0, depth - 1);
|
|
444
|
+
else if (depth === 0) {
|
|
445
|
+
const match = separator.exec(expr.slice(i));
|
|
446
|
+
if (match && match.index === 0) {
|
|
447
|
+
parts.push(expr.slice(start, i).trim());
|
|
448
|
+
i += match[0].length - 1;
|
|
449
|
+
start = i + 1;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
parts.push(expr.slice(start).trim());
|
|
454
|
+
return parts;
|
|
455
|
+
}
|
|
456
|
+
function isLicenseAllowed(licenseStr, normalizedAllowed) {
|
|
457
|
+
let expr = licenseStr.trim();
|
|
458
|
+
if (!expr) return false;
|
|
459
|
+
if (normalizedAllowed.has(expr.toLowerCase())) return true;
|
|
460
|
+
while (expr.startsWith("(")) {
|
|
461
|
+
let depth = 0;
|
|
462
|
+
let close = -1;
|
|
463
|
+
for (let i = 0; i < expr.length; i++) {
|
|
464
|
+
if (expr[i] === "(") depth++;
|
|
465
|
+
else if (expr[i] === ")") {
|
|
466
|
+
depth--;
|
|
467
|
+
if (depth === 0) {
|
|
468
|
+
close = i;
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (close !== expr.length - 1) break;
|
|
474
|
+
expr = expr.slice(1, -1).trim();
|
|
475
|
+
}
|
|
476
|
+
const orParts = splitTopLevel(expr, /\s+OR\s+/i);
|
|
477
|
+
if (orParts.length > 1) {
|
|
478
|
+
return orParts.some((p) => isLicenseAllowed(p, normalizedAllowed));
|
|
479
|
+
}
|
|
480
|
+
const andParts = splitTopLevel(expr, /\s+AND\s+/i);
|
|
481
|
+
if (andParts.length > 1) {
|
|
482
|
+
return andParts.every((p) => isLicenseAllowed(p, normalizedAllowed));
|
|
483
|
+
}
|
|
484
|
+
return normalizedAllowed.has(expr.toLowerCase());
|
|
485
|
+
}
|
|
433
486
|
function auditPackages(names, allowedLicenses) {
|
|
434
487
|
const results = [];
|
|
435
488
|
const errors = [];
|
|
@@ -443,7 +496,7 @@ function auditPackages(names, allowedLicenses) {
|
|
|
443
496
|
} catch {
|
|
444
497
|
errors.push(name);
|
|
445
498
|
}
|
|
446
|
-
const allowed = licenses.length > 0 && licenses.every((l) =>
|
|
499
|
+
const allowed = licenses.length > 0 && licenses.every((l) => isLicenseAllowed(l, normalizedAllowed));
|
|
447
500
|
results.push({ name, licenses, allowed });
|
|
448
501
|
}
|
|
449
502
|
const ok = errors.length === 0 && results.every((r) => r.allowed);
|
|
@@ -498,7 +551,7 @@ var plugin2 = {
|
|
|
498
551
|
if (!cfg.enabled) return;
|
|
499
552
|
if (input.toolResult?.isError) return;
|
|
500
553
|
const ti = input.toolInput ?? {};
|
|
501
|
-
const command = typeof ti["command"] === "string" ? ti["command"] : "";
|
|
554
|
+
const command = (typeof ti["command"] === "string" ? ti["command"] : void 0) ?? (typeof ti["CommandLine"] === "string" ? ti["CommandLine"] : void 0) ?? (typeof ti["cmd"] === "string" ? ti["cmd"] : void 0) ?? (typeof ti["script"] === "string" ? ti["script"] : void 0) ?? "";
|
|
502
555
|
if (!command) return;
|
|
503
556
|
state2.invocations += 1;
|
|
504
557
|
const names = parsePackageNames(command);
|
package/dist/lint-gate.js
CHANGED
|
@@ -51,12 +51,20 @@ var DEFAULTS = {
|
|
|
51
51
|
function readConfig(raw) {
|
|
52
52
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
53
53
|
const r = raw;
|
|
54
|
+
const rawLinter = typeof r["linter"] === "string" ? r["linter"].trim().toLowerCase() : void 0;
|
|
55
|
+
const linter = rawLinter === "biome" || rawLinter === "eslint" ? rawLinter : "auto";
|
|
56
|
+
const rawMode = typeof (r["mode"] ?? r["action"] ?? r["behavior"]) === "string" ? String(r["mode"] ?? r["action"] ?? r["behavior"]).trim().toLowerCase() : void 0;
|
|
57
|
+
const mode = rawMode === "block" ? "block" : rawMode === "fix" ? "fix" : "warn";
|
|
58
|
+
const rawSeverity = typeof r["severity"] === "string" ? r["severity"].trim().toLowerCase() : void 0;
|
|
59
|
+
const severity = rawSeverity === "warning" ? "warning" : "error";
|
|
60
|
+
const rawTimeout = r["timeoutMs"] ?? r["timeout_ms"] ?? r["timeout"];
|
|
61
|
+
const rawRules = r["fixRules"] ?? r["fix_rules"] ?? r["rules"];
|
|
54
62
|
return {
|
|
55
|
-
linter
|
|
56
|
-
mode
|
|
57
|
-
severity
|
|
58
|
-
timeoutMs: typeof
|
|
59
|
-
fixRules: Array.isArray(
|
|
63
|
+
linter,
|
|
64
|
+
mode,
|
|
65
|
+
severity,
|
|
66
|
+
timeoutMs: typeof rawTimeout === "number" && rawTimeout > 0 ? rawTimeout : DEFAULTS.timeoutMs,
|
|
67
|
+
fixRules: Array.isArray(rawRules) ? rawRules.filter((x) => typeof x === "string") : []
|
|
60
68
|
};
|
|
61
69
|
}
|
|
62
70
|
var LINTER_PACKAGES = {
|
package/dist/llm-cache.js
CHANGED
|
@@ -20,12 +20,16 @@ var DEFAULTS = {
|
|
|
20
20
|
function readConfig(raw) {
|
|
21
21
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
22
22
|
const r = raw;
|
|
23
|
+
const rawMax = r["maxEntries"] ?? r["max_entries"] ?? r["limit"];
|
|
24
|
+
const rawTtl = r["ttlMs"] ?? r["ttl_ms"] ?? r["ttl"];
|
|
25
|
+
const rawDet = r["onlyDeterministic"] ?? r["only_deterministic"];
|
|
26
|
+
const rawZero = r["zeroUsageOnHit"] ?? r["zero_usage_on_hit"] ?? r["zeroUsage"] ?? r["zero_usage"];
|
|
23
27
|
return {
|
|
24
28
|
enabled: r["enabled"] === true,
|
|
25
|
-
maxEntries: typeof
|
|
26
|
-
ttlMs: typeof
|
|
27
|
-
onlyDeterministic:
|
|
28
|
-
zeroUsageOnHit:
|
|
29
|
+
maxEntries: typeof rawMax === "number" && rawMax >= 1 ? Math.floor(rawMax) : DEFAULTS.maxEntries,
|
|
30
|
+
ttlMs: typeof rawTtl === "number" && rawTtl >= 0 ? rawTtl : DEFAULTS.ttlMs,
|
|
31
|
+
onlyDeterministic: rawDet !== false,
|
|
32
|
+
zeroUsageOnHit: rawZero === true
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
35
|
function isDeterministic(request) {
|
|
@@ -36,6 +40,7 @@ var fingerprintCache = /* @__PURE__ */ new WeakMap();
|
|
|
36
40
|
function fingerprintRequest(request) {
|
|
37
41
|
const cached = fingerprintCache.get(request);
|
|
38
42
|
if (cached) return cached;
|
|
43
|
+
const rawTools = request["tools"] ?? request["tool_definitions"] ?? request["toolDefinitions"] ?? request["functions"];
|
|
39
44
|
const subset = {
|
|
40
45
|
maxTokens: request["maxTokens"] ?? null,
|
|
41
46
|
messages: request["messages"] ?? null,
|
|
@@ -45,7 +50,7 @@ function fingerprintRequest(request) {
|
|
|
45
50
|
stopSequences: request["stopSequences"] ?? null,
|
|
46
51
|
system: request["system"] ?? null,
|
|
47
52
|
temperature: request["temperature"] ?? null,
|
|
48
|
-
tools: Array.isArray(
|
|
53
|
+
tools: Array.isArray(rawTools) ? rawTools.map((t) => t?.name ?? t) : null,
|
|
49
54
|
topK: request["topK"] ?? null,
|
|
50
55
|
topP: request["topP"] ?? null
|
|
51
56
|
};
|
|
@@ -173,7 +178,16 @@ var plugin = {
|
|
|
173
178
|
api.metrics.counter("misses");
|
|
174
179
|
const response = await inner(_ctx, request);
|
|
175
180
|
const sr = response && typeof response === "object" ? response.stopReason : void 0;
|
|
176
|
-
|
|
181
|
+
const normSr = typeof sr === "string" ? sr.toLowerCase() : "";
|
|
182
|
+
const validStopReasons = /* @__PURE__ */ new Set([
|
|
183
|
+
"end_turn",
|
|
184
|
+
"stop",
|
|
185
|
+
"tool_use",
|
|
186
|
+
"tool_calls",
|
|
187
|
+
"function_call",
|
|
188
|
+
"stop_sequence"
|
|
189
|
+
]);
|
|
190
|
+
if (response && typeof response === "object" && validStopReasons.has(normSr)) {
|
|
177
191
|
lruSet(key, response, cfg.maxEntries);
|
|
178
192
|
}
|
|
179
193
|
return response;
|
package/dist/loop-breaker.js
CHANGED
|
@@ -42,17 +42,24 @@ function readConfig(raw) {
|
|
|
42
42
|
return { ...DEFAULTS };
|
|
43
43
|
}
|
|
44
44
|
const r = raw;
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
45
|
+
const rawWarn = r["warnAfter"] ?? r["warn_after"] ?? r["warnThreshold"] ?? r["warn_threshold"];
|
|
46
|
+
const warnAfter = typeof rawWarn === "number" && rawWarn >= 2 ? rawWarn : DEFAULTS.warnAfter;
|
|
47
|
+
const rawBlock = r["blockAfter"] ?? r["block_after"] ?? r["blockThreshold"] ?? r["block_threshold"];
|
|
48
|
+
const blockAfter = typeof rawBlock === "number" && rawBlock > warnAfter ? rawBlock : Math.max(DEFAULTS.blockAfter, warnAfter + 1);
|
|
49
|
+
const rawIgnore = r["ignoreTools"] ?? r["ignore_tools"] ?? r["ignore"] ?? r["ignoredTools"];
|
|
50
|
+
const ignoreTools = Array.isArray(rawIgnore) ? rawIgnore.filter((t) => typeof t === "string") : [];
|
|
48
51
|
ignoreToolsSet = new Set(ignoreTools);
|
|
52
|
+
const rawMode = typeof (r["mode"] ?? r["action"] ?? r["behavior"]) === "string" ? String(r["mode"] ?? r["action"] ?? r["behavior"]).trim().toLowerCase() : void 0;
|
|
53
|
+
const mode = rawMode === "warn" ? "warn" : "block";
|
|
54
|
+
const rawOsc = r["oscillationWindow"] ?? r["oscillation_window"] ?? r["window"];
|
|
55
|
+
const rawMaxSteps = r["maxSteps"] ?? r["max_steps"] ?? r["stepLimit"] ?? r["step_limit"];
|
|
49
56
|
return {
|
|
50
57
|
enabled: r["enabled"] !== false,
|
|
51
|
-
mode
|
|
58
|
+
mode,
|
|
52
59
|
warnAfter,
|
|
53
60
|
blockAfter,
|
|
54
|
-
oscillationWindow: typeof
|
|
55
|
-
maxSteps: typeof
|
|
61
|
+
oscillationWindow: typeof rawOsc === "number" && rawOsc >= 4 ? rawOsc : DEFAULTS.oscillationWindow,
|
|
62
|
+
maxSteps: typeof rawMaxSteps === "number" && rawMaxSteps >= 0 ? Math.floor(rawMaxSteps) : DEFAULTS.maxSteps,
|
|
56
63
|
noDiffWarnAfter: typeof r["noDiffWarnAfter"] === "number" && r["noDiffWarnAfter"] >= 1 ? Math.floor(r["noDiffWarnAfter"]) : DEFAULTS.noDiffWarnAfter,
|
|
57
64
|
noDiffBlockAfter: typeof r["noDiffBlockAfter"] === "number" && r["noDiffBlockAfter"] >= 0 ? Math.floor(r["noDiffBlockAfter"]) : DEFAULTS.noDiffBlockAfter,
|
|
58
65
|
repeatedErrorWarnAfter: typeof r["repeatedErrorWarnAfter"] === "number" && r["repeatedErrorWarnAfter"] >= 1 ? Math.floor(r["repeatedErrorWarnAfter"]) : DEFAULTS.repeatedErrorWarnAfter,
|
|
@@ -101,7 +108,7 @@ function isOscillating(recent, windowSize) {
|
|
|
101
108
|
}
|
|
102
109
|
return window[0] !== window[1];
|
|
103
110
|
}
|
|
104
|
-
var MUTATING_TOOLS = /* @__PURE__ */ new Set(["edit", "write"]);
|
|
111
|
+
var MUTATING_TOOLS = /* @__PURE__ */ new Set(["edit", "write", "write_to_file", "replace_file_content"]);
|
|
105
112
|
function hashString(value) {
|
|
106
113
|
let h = 5381;
|
|
107
114
|
const cap = Math.min(value.length, 1e6);
|
|
@@ -339,7 +346,8 @@ var plugin = {
|
|
|
339
346
|
state.repeatedErrorStreak = 0;
|
|
340
347
|
if (!MUTATING_TOOLS.has(toolName)) return;
|
|
341
348
|
const toolInput = input.toolInput ?? {};
|
|
342
|
-
const
|
|
349
|
+
const rawTarget = toolInput["path"] ?? toolInput["TargetFile"] ?? toolInput["filePath"] ?? toolInput["targetFile"] ?? toolInput["file_path"] ?? toolInput["destination"] ?? toolInput["file"];
|
|
350
|
+
const targetPath = typeof rawTarget === "string" ? rawTarget : void 0;
|
|
343
351
|
if (typeof targetPath !== "string" || targetPath.length === 0) return;
|
|
344
352
|
const diffFingerprint = await gitDiffFingerprint(
|
|
345
353
|
input.cwd ?? process.cwd(),
|
|
@@ -49,12 +49,16 @@ var DEFAULTS = {
|
|
|
49
49
|
function readConfig(raw) {
|
|
50
50
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
51
51
|
const r = raw;
|
|
52
|
+
const rawPaths = r["changelogPaths"] ?? r["changelog_paths"] ?? r["paths"];
|
|
53
|
+
const rawMax = r["maxChars"] ?? r["max_chars"] ?? r["limit"];
|
|
54
|
+
const rawUseLlm = r["useLlm"] ?? r["use_llm"];
|
|
55
|
+
const rawMaxLlm = r["maxLlmChars"] ?? r["max_llm_chars"];
|
|
52
56
|
return {
|
|
53
57
|
enabled: r["enabled"] !== false,
|
|
54
|
-
changelogPaths: Array.isArray(
|
|
55
|
-
maxChars: typeof
|
|
56
|
-
useLlm:
|
|
57
|
-
maxLlmChars: typeof
|
|
58
|
+
changelogPaths: Array.isArray(rawPaths) ? rawPaths.filter((x) => typeof x === "string") : DEFAULTS.changelogPaths,
|
|
59
|
+
maxChars: typeof rawMax === "number" && rawMax >= 1e3 && rawMax <= 1e6 ? rawMax : DEFAULTS.maxChars,
|
|
60
|
+
useLlm: rawUseLlm === true,
|
|
61
|
+
maxLlmChars: typeof rawMaxLlm === "number" && rawMaxLlm >= 1e3 && rawMaxLlm <= 1e5 ? rawMaxLlm : DEFAULTS.maxLlmChars
|
|
58
62
|
};
|
|
59
63
|
}
|
|
60
64
|
function normalizeVersion(v) {
|
|
@@ -280,7 +284,8 @@ var plugin = {
|
|
|
280
284
|
if (!cfg.enabled) return;
|
|
281
285
|
if (input.toolResult?.isError) return;
|
|
282
286
|
const inp = input.toolInput ?? {};
|
|
283
|
-
const
|
|
287
|
+
const rawPath = inp["path"] ?? inp["TargetFile"] ?? inp["filePath"] ?? inp["targetFile"] ?? inp["file_path"] ?? inp["file"];
|
|
288
|
+
const path = typeof rawPath === "string" ? rawPath : void 0;
|
|
284
289
|
if (!path) return;
|
|
285
290
|
const basename = path.split(/[/\\]/).pop() ?? "";
|
|
286
291
|
if (!/^(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?)$/i.test(
|
|
@@ -305,14 +310,31 @@ var plugin = {
|
|
|
305
310
|
type: "string",
|
|
306
311
|
description: "Name of the npm package or framework."
|
|
307
312
|
},
|
|
313
|
+
package: { type: "string", description: "Alias for packageName." },
|
|
314
|
+
pkg: { type: "string", description: "Alias for packageName." },
|
|
315
|
+
name: { type: "string", description: "Alias for packageName." },
|
|
316
|
+
package_name: { type: "string", description: "Alias for packageName." },
|
|
317
|
+
dependency: { type: "string", description: "Alias for packageName." },
|
|
318
|
+
dep: { type: "string", description: "Alias for packageName." },
|
|
319
|
+
module: { type: "string", description: "Alias for packageName." },
|
|
308
320
|
fromVersion: {
|
|
309
321
|
type: "string",
|
|
310
322
|
description: 'Current version, e.g. "1.2.3".'
|
|
311
323
|
},
|
|
324
|
+
from: { type: "string", description: "Alias for fromVersion." },
|
|
325
|
+
from_version: { type: "string", description: "Alias for fromVersion." },
|
|
326
|
+
currentVersion: { type: "string", description: "Alias for fromVersion." },
|
|
327
|
+
since: { type: "string", description: "Alias for fromVersion." },
|
|
328
|
+
start: { type: "string", description: "Alias for fromVersion." },
|
|
312
329
|
toVersion: {
|
|
313
330
|
type: "string",
|
|
314
331
|
description: 'Target version, e.g. "2.0.0".'
|
|
315
332
|
},
|
|
333
|
+
to: { type: "string", description: "Alias for toVersion." },
|
|
334
|
+
to_version: { type: "string", description: "Alias for toVersion." },
|
|
335
|
+
targetVersion: { type: "string", description: "Alias for toVersion." },
|
|
336
|
+
until: { type: "string", description: "Alias for toVersion." },
|
|
337
|
+
end: { type: "string", description: "Alias for toVersion." },
|
|
316
338
|
scope: {
|
|
317
339
|
type: "string",
|
|
318
340
|
description: "Optional scope describing which parts of the project use the package."
|
|
@@ -320,9 +342,51 @@ var plugin = {
|
|
|
320
342
|
use_llm: {
|
|
321
343
|
type: "boolean",
|
|
322
344
|
description: "Add evidence-bounded Council risk analysis with One Shot fallback. Overrides useLlm for this call."
|
|
323
|
-
}
|
|
345
|
+
},
|
|
346
|
+
useLlm: { type: "boolean", description: "Alias for use_llm." },
|
|
347
|
+
use_ai: { type: "boolean", description: "Alias for use_llm." },
|
|
348
|
+
useAi: { type: "boolean", description: "Alias for use_llm." }
|
|
324
349
|
},
|
|
325
|
-
required
|
|
350
|
+
// One name from each required field group must be sufficient for
|
|
351
|
+
// raw-schema validation. Note: the tool-wire flattener strips
|
|
352
|
+
// top-level combinators (docs/tool-author-guide.md), so wire-level
|
|
353
|
+
// guidance loses these required markers by design — the executor
|
|
354
|
+
// remains the authoritative validator and reports missing canonical
|
|
355
|
+
// fields with a clear error.
|
|
356
|
+
allOf: [
|
|
357
|
+
{
|
|
358
|
+
anyOf: [
|
|
359
|
+
{ required: ["packageName"] },
|
|
360
|
+
{ required: ["package"] },
|
|
361
|
+
{ required: ["pkg"] },
|
|
362
|
+
{ required: ["name"] },
|
|
363
|
+
{ required: ["package_name"] },
|
|
364
|
+
{ required: ["dependency"] },
|
|
365
|
+
{ required: ["dep"] },
|
|
366
|
+
{ required: ["module"] }
|
|
367
|
+
]
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
anyOf: [
|
|
371
|
+
{ required: ["fromVersion"] },
|
|
372
|
+
{ required: ["from"] },
|
|
373
|
+
{ required: ["from_version"] },
|
|
374
|
+
{ required: ["currentVersion"] },
|
|
375
|
+
{ required: ["since"] },
|
|
376
|
+
{ required: ["start"] }
|
|
377
|
+
]
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
anyOf: [
|
|
381
|
+
{ required: ["toVersion"] },
|
|
382
|
+
{ required: ["to"] },
|
|
383
|
+
{ required: ["to_version"] },
|
|
384
|
+
{ required: ["targetVersion"] },
|
|
385
|
+
{ required: ["until"] },
|
|
386
|
+
{ required: ["end"] }
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
]
|
|
326
390
|
},
|
|
327
391
|
permission: "auto",
|
|
328
392
|
category: "Planning",
|
|
@@ -330,9 +394,14 @@ var plugin = {
|
|
|
330
394
|
async execute(input, _ctx, execOpts) {
|
|
331
395
|
if (!cfg.enabled) return { ok: false, error: "migration-planner is disabled" };
|
|
332
396
|
execOpts?.signal?.throwIfAborted();
|
|
333
|
-
const
|
|
334
|
-
const
|
|
335
|
-
const
|
|
397
|
+
const raw = input ?? {};
|
|
398
|
+
const rawPackage = input.packageName || raw["package"] || raw["pkg"] || raw["name"] || raw["package_name"] || raw["packageName"] || raw["dependency"] || raw["dep"] || raw["module"];
|
|
399
|
+
const rawFrom = input.fromVersion || raw["from"] || raw["from_version"] || raw["fromVersion"] || raw["currentVersion"] || raw["since"] || raw["start"];
|
|
400
|
+
const rawTo = input.toVersion || raw["to"] || raw["to_version"] || raw["toVersion"] || raw["targetVersion"] || raw["until"] || raw["end"];
|
|
401
|
+
const rawUseLlm = input.use_llm ?? raw["useLlm"] ?? raw["use_ai"] ?? raw["useAi"];
|
|
402
|
+
const packageName = String(rawPackage ?? "").trim();
|
|
403
|
+
const fromVersion = String(rawFrom ?? "").trim();
|
|
404
|
+
const toVersion = String(rawTo ?? "").trim();
|
|
336
405
|
if (!packageName || !fromVersion || !toVersion) {
|
|
337
406
|
return { ok: false, error: "packageName, fromVersion, and toVersion are required" };
|
|
338
407
|
}
|
|
@@ -357,7 +426,7 @@ var plugin = {
|
|
|
357
426
|
evidence = `No local changelog was found for ${packageName}.`;
|
|
358
427
|
}
|
|
359
428
|
execOpts?.signal?.throwIfAborted();
|
|
360
|
-
const requested =
|
|
429
|
+
const requested = typeof rawUseLlm === "boolean" ? rawUseLlm : cfg.useLlm;
|
|
361
430
|
const llm = await runOptionalPluginCouncil({
|
|
362
431
|
requested,
|
|
363
432
|
api,
|