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