@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
|
@@ -59,22 +59,23 @@ var DEFAULTS = {
|
|
|
59
59
|
excludeDirs: ["node_modules", "dist", ".git", "coverage"],
|
|
60
60
|
maxFindings: 5
|
|
61
61
|
};
|
|
62
|
-
var extensionsSet = new Set(DEFAULTS.extensions);
|
|
63
62
|
function readConfig(raw) {
|
|
64
63
|
if (!raw || typeof raw !== "object") {
|
|
65
|
-
extensionsSet = new Set(DEFAULTS.extensions);
|
|
66
64
|
return { ...DEFAULTS };
|
|
67
65
|
}
|
|
68
66
|
const r = raw;
|
|
69
|
-
const
|
|
70
|
-
|
|
67
|
+
const rawExts = r["extensions"] ?? r["file_extensions"] ?? r["fileExtensions"];
|
|
68
|
+
const extensions = Array.isArray(rawExts) ? rawExts.filter((x) => typeof x === "string") : DEFAULTS.extensions;
|
|
69
|
+
const rawMin = r["minLines"] ?? r["min_lines"] ?? r["min"];
|
|
70
|
+
const rawExclude = r["excludeDirs"] ?? r["exclude_dirs"] ?? r["exclude"];
|
|
71
|
+
const rawMax = r["maxFindings"] ?? r["max_findings"] ?? r["limit"];
|
|
71
72
|
return {
|
|
72
73
|
enabled: r["enabled"] === true,
|
|
73
|
-
minLines: typeof
|
|
74
|
+
minLines: typeof rawMin === "number" && rawMin >= 2 && rawMin <= 100 ? rawMin : DEFAULTS.minLines,
|
|
74
75
|
threshold: typeof r["threshold"] === "number" && r["threshold"] > 0 && r["threshold"] <= 1 ? r["threshold"] : DEFAULTS.threshold,
|
|
75
76
|
extensions,
|
|
76
|
-
excludeDirs: Array.isArray(
|
|
77
|
-
maxFindings: typeof
|
|
77
|
+
excludeDirs: Array.isArray(rawExclude) ? rawExclude.filter((x) => typeof x === "string") : DEFAULTS.excludeDirs,
|
|
78
|
+
maxFindings: typeof rawMax === "number" && rawMax >= 1 && rawMax <= 500 ? rawMax : DEFAULTS.maxFindings
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
function isWithinRoot(projectRoot, candidate) {
|
|
@@ -135,19 +136,31 @@ function evictHookIndex() {
|
|
|
135
136
|
}
|
|
136
137
|
function extractWindows(filePath, content, minLines) {
|
|
137
138
|
const rawLines = content.split(/\r?\n/);
|
|
139
|
+
const covered = [];
|
|
138
140
|
const windows = [];
|
|
139
141
|
for (let i = 0; i <= rawLines.length - minLines; i++) {
|
|
142
|
+
const startLine = i + 1;
|
|
143
|
+
const endLine = i + minLines;
|
|
144
|
+
let overlaps = false;
|
|
145
|
+
for (const [s, e] of covered) {
|
|
146
|
+
if (startLine <= e && s <= endLine) {
|
|
147
|
+
overlaps = true;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (overlaps) continue;
|
|
140
152
|
const slice = rawLines.slice(i, i + minLines);
|
|
141
153
|
const fingerprint = buildFingerprint(slice);
|
|
142
154
|
if (fingerprint.length === 0) continue;
|
|
143
155
|
const snippet = slice.join("\n");
|
|
144
156
|
windows.push({
|
|
145
157
|
file: filePath,
|
|
146
|
-
startLine
|
|
147
|
-
endLine
|
|
158
|
+
startLine,
|
|
159
|
+
endLine,
|
|
148
160
|
snippet,
|
|
149
161
|
fingerprint
|
|
150
162
|
});
|
|
163
|
+
covered.push([startLine, endLine]);
|
|
151
164
|
}
|
|
152
165
|
return windows;
|
|
153
166
|
}
|
|
@@ -162,8 +175,17 @@ function findDuplicates(files, minLines, maxFindings) {
|
|
|
162
175
|
}
|
|
163
176
|
}
|
|
164
177
|
const findings = [];
|
|
178
|
+
const coveredSpans = /* @__PURE__ */ new Set();
|
|
165
179
|
for (const [fingerprint, windows] of byFingerprint.entries()) {
|
|
166
180
|
if (windows.length < 2) continue;
|
|
181
|
+
const isOverlapping = windows.every((w) => {
|
|
182
|
+
const spanKey = `${w.file}:${Math.floor(w.startLine / minLines)}`;
|
|
183
|
+
return coveredSpans.has(spanKey);
|
|
184
|
+
});
|
|
185
|
+
if (isOverlapping && findings.length > 0) continue;
|
|
186
|
+
for (const w of windows) {
|
|
187
|
+
coveredSpans.add(`${w.file}:${Math.floor(w.startLine / minLines)}`);
|
|
188
|
+
}
|
|
167
189
|
const locations = windows.map((w) => ({
|
|
168
190
|
file: relativePath(w.file),
|
|
169
191
|
startLine: w.startLine,
|
|
@@ -171,9 +193,51 @@ function findDuplicates(files, minLines, maxFindings) {
|
|
|
171
193
|
snippet: w.snippet
|
|
172
194
|
}));
|
|
173
195
|
findings.push({ fingerprint, lineCount: fingerprint.split("\n").length, locations });
|
|
174
|
-
if (findings.length >= maxFindings) break;
|
|
175
196
|
}
|
|
176
|
-
|
|
197
|
+
function locationsOverlap(a, b) {
|
|
198
|
+
for (const la of a.locations) {
|
|
199
|
+
for (const lb of b.locations) {
|
|
200
|
+
if (la.file !== lb.file) continue;
|
|
201
|
+
if (la.startLine <= lb.endLine && lb.startLine <= la.endLine) return true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
let merged = true;
|
|
207
|
+
while (merged) {
|
|
208
|
+
merged = false;
|
|
209
|
+
for (let i = 0; i < findings.length; i++) {
|
|
210
|
+
for (let j = i + 1; j < findings.length; j++) {
|
|
211
|
+
if (!locationsOverlap(findings[i], findings[j])) continue;
|
|
212
|
+
const a = findings[i];
|
|
213
|
+
const b = findings[j];
|
|
214
|
+
const keep = b.fingerprint.split("\n").length > a.fingerprint.split("\n").length ? b : a;
|
|
215
|
+
const drop = keep === a ? b : a;
|
|
216
|
+
const seen = /* @__PURE__ */ new Set();
|
|
217
|
+
const mergedLocations = [];
|
|
218
|
+
for (const loc of [...keep.locations, ...drop.locations]) {
|
|
219
|
+
const k = `${loc.file}#${loc.startLine}#${loc.endLine}`;
|
|
220
|
+
if (seen.has(k)) continue;
|
|
221
|
+
seen.add(k);
|
|
222
|
+
mergedLocations.push(loc);
|
|
223
|
+
}
|
|
224
|
+
mergedLocations.sort(
|
|
225
|
+
(x, y) => x.file === y.file ? x.startLine - y.startLine : x.file.localeCompare(y.file)
|
|
226
|
+
);
|
|
227
|
+
findings[i] = {
|
|
228
|
+
fingerprint: keep.fingerprint,
|
|
229
|
+
lineCount: keep.fingerprint.split("\n").length,
|
|
230
|
+
locations: mergedLocations
|
|
231
|
+
};
|
|
232
|
+
findings.splice(j, 1);
|
|
233
|
+
merged = true;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (merged) break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const capped = findings.slice(0, maxFindings);
|
|
240
|
+
return capped;
|
|
177
241
|
}
|
|
178
242
|
async function scanPath(rawPath, cfg) {
|
|
179
243
|
const root = process.cwd();
|
|
@@ -189,7 +253,10 @@ async function scanPath(rawPath, cfg) {
|
|
|
189
253
|
} catch {
|
|
190
254
|
}
|
|
191
255
|
}
|
|
192
|
-
return {
|
|
256
|
+
return {
|
|
257
|
+
findings: findDuplicates(files, cfg.minLines, cfg.maxFindings),
|
|
258
|
+
scannedFiles: files.size
|
|
259
|
+
};
|
|
193
260
|
}
|
|
194
261
|
var plugin = {
|
|
195
262
|
name: "duplicate-code-detector",
|
|
@@ -256,6 +323,7 @@ var plugin = {
|
|
|
256
323
|
state.hookUnregister = null;
|
|
257
324
|
}
|
|
258
325
|
const cfg = readConfig(api.config.extensions?.["duplicate-code-detector"]);
|
|
326
|
+
const extensionsSet = new Set(cfg.extensions);
|
|
259
327
|
async function readCachedFingerprints(filePath, minLines) {
|
|
260
328
|
let st;
|
|
261
329
|
try {
|
|
@@ -303,7 +371,8 @@ var plugin = {
|
|
|
303
371
|
if (!cfg.enabled) return;
|
|
304
372
|
if (input.toolResult?.isError) return;
|
|
305
373
|
const inp = input.toolInput ?? {};
|
|
306
|
-
const
|
|
374
|
+
const rawSource = inp["path"] ?? inp["TargetFile"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["targetFile"] ?? inp["file"];
|
|
375
|
+
const sourcePath = typeof rawSource === "string" ? rawSource : void 0;
|
|
307
376
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
308
377
|
const projectRoot = resolve(process.cwd());
|
|
309
378
|
const resolvedFile = isAbsolute(sourcePath) ? resolve(sourcePath) : resolve(projectRoot, sourcePath);
|
|
@@ -357,7 +426,9 @@ var plugin = {
|
|
|
357
426
|
contextAs: "separate"
|
|
358
427
|
};
|
|
359
428
|
};
|
|
360
|
-
state.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, {
|
|
429
|
+
state.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, {
|
|
430
|
+
background: true
|
|
431
|
+
});
|
|
361
432
|
api.tools.register({
|
|
362
433
|
name: "detect_duplicate_code",
|
|
363
434
|
description: "Scan source files for duplicated code blocks. Uses normalized-line fingerprinting to find identical multi-line blocks across files.",
|
|
@@ -372,7 +443,8 @@ var plugin = {
|
|
|
372
443
|
mutating: false,
|
|
373
444
|
async execute(input) {
|
|
374
445
|
if (!cfg.enabled) return { ok: false, error: "duplicate-code-detector is disabled" };
|
|
375
|
-
const
|
|
446
|
+
const raw = input;
|
|
447
|
+
const rawPath = (typeof raw["path"] === "string" ? raw["path"] : 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["file_path"] === "string" ? raw["file_path"] : void 0) ?? (typeof raw["TargetFile"] === "string" ? raw["TargetFile"] : void 0) ?? (typeof raw["targetFile"] === "string" ? raw["targetFile"] : void 0) ?? (typeof raw["file"] === "string" ? raw["file"] : void 0) ?? ".";
|
|
376
448
|
if (!(0, runtime_exports.withinProject)(rawPath)) {
|
|
377
449
|
return { ok: false, error: "scan path is outside the project root" };
|
|
378
450
|
}
|
package/dist/error-lens.js
CHANGED
|
@@ -41,12 +41,12 @@ var ERROR_LINE_PATTERNS = [
|
|
|
41
41
|
/^[ \t]*((?:FAIL|✗|×)[ \t]+[^\n]{5,})/m
|
|
42
42
|
];
|
|
43
43
|
var FRAME_PATTERNS = [
|
|
44
|
-
// Node/V8: "at fn (path/file.ts:12:5)" or "at path/file.ts:12:5"
|
|
45
|
-
/\bat\s+(?:[^(\n]+\()?((?:[A-Za-z]:[\\/])?[^()\n:]+:\d+)(?::\d+)?\)?/g,
|
|
44
|
+
// Node/V8: "at fn (path/file.ts:12:5)" or "at file:///path/file.ts:12:5"
|
|
45
|
+
/\bat\s+(?:[^(\n]+\()?((?:file:\/\/\/?)?(?:[A-Za-z]:[\\/])?[^()\n:]+:\d+)(?::\d+)?\)?/g,
|
|
46
46
|
// Python: File "path/file.py", line 12
|
|
47
47
|
/File "([^"]+)", line (\d+)/g,
|
|
48
48
|
// tsc/vitest/eslint bare: "src/foo.ts:12:5" (require a path-ish prefix)
|
|
49
|
-
/(?:^|[ \t(])((?:[A-Za-z]:[\\/])?[A-Za-z0-9_./\\-]+\.[a-z]{1,4}:\d+)(?::\d+)?/gm,
|
|
49
|
+
/(?:^|[ \t(])((?:file:\/\/\/?)?(?:[A-Za-z]:[\\/])?[A-Za-z0-9_./\\-]+\.[a-z]{1,4}:\d+)(?::\d+)?/gm,
|
|
50
50
|
// Rust: "--> src/main.rs:4:5"
|
|
51
51
|
/-->\s+((?:[A-Za-z]:[\\/])?[^\s:]+:\d+)/g
|
|
52
52
|
];
|
|
@@ -66,7 +66,7 @@ function extractFrames(output, maxFrames) {
|
|
|
66
66
|
let m = re.exec(output);
|
|
67
67
|
while (m !== null) {
|
|
68
68
|
const frame = m[2] !== void 0 ? `${m[1]}:${m[2]}` : m[1] ?? "";
|
|
69
|
-
const cleaned = frame.replace(/\\/g, "/").trim();
|
|
69
|
+
const cleaned = frame.replace(/^file:\/\/\/?/i, "").replace(/\\/g, "/").trim();
|
|
70
70
|
if (cleaned && !seen.has(cleaned)) {
|
|
71
71
|
seen.add(cleaned);
|
|
72
72
|
const isVendor = cleaned.includes("node_modules/") || cleaned.startsWith("node:") || cleaned.includes("internal/");
|
|
@@ -161,10 +161,11 @@ var plugin = {
|
|
|
161
161
|
} else {
|
|
162
162
|
isNewFailure = true;
|
|
163
163
|
const ti = input.toolInput ?? {};
|
|
164
|
+
const rawCmd = ti["command"] ?? ti["CommandLine"] ?? ti["cmd"] ?? ti["script"];
|
|
164
165
|
state.history.push({
|
|
165
166
|
when: (/* @__PURE__ */ new Date()).toISOString(),
|
|
166
167
|
tool: input.toolName ?? "unknown",
|
|
167
|
-
command: typeof
|
|
168
|
+
command: typeof rawCmd === "string" ? rawCmd.slice(0, 200) : null,
|
|
168
169
|
errorLine,
|
|
169
170
|
frames,
|
|
170
171
|
repeats: 1
|
|
@@ -32,10 +32,10 @@ var state = {
|
|
|
32
32
|
hookUnregister: null
|
|
33
33
|
};
|
|
34
34
|
var DEFAULT_PATTERNS = [
|
|
35
|
-
String.raw`isFeatureEnabled\(['"]([^'"]+)['"]\)`,
|
|
36
|
-
String.raw`featureFlags
|
|
37
|
-
String.raw`useFeatureFlag\(['"]([^'"]+)['"]\)`,
|
|
38
|
-
String.raw`flags
|
|
35
|
+
String.raw`isFeatureEnabled\(['"\`]([^'"\`]+)['"\`]\)`,
|
|
36
|
+
String.raw`featureFlags?(?:\.|\?\.)([A-Za-z_$][A-Za-z0-9_$]*)`,
|
|
37
|
+
String.raw`useFeatureFlag\(['"\`]([^'"\`]+)['"\`]\)`,
|
|
38
|
+
String.raw`flags(?:\.|\?\.)([A-Za-z_$][A-Za-z0-9_$]*)`
|
|
39
39
|
];
|
|
40
40
|
var DEFAULTS = {
|
|
41
41
|
enabled: false,
|
|
@@ -46,11 +46,14 @@ var DEFAULTS = {
|
|
|
46
46
|
function readConfig(raw) {
|
|
47
47
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
48
48
|
const r = raw;
|
|
49
|
+
const rawExts = r["extensions"] ?? r["file_extensions"] ?? r["fileExtensions"];
|
|
50
|
+
const rawPatterns = r["patterns"] ?? r["custom_patterns"] ?? r["customPatterns"];
|
|
51
|
+
const rawMax = r["maxFindings"] ?? r["max_findings"] ?? r["limit"];
|
|
49
52
|
return {
|
|
50
53
|
enabled: r["enabled"] !== false,
|
|
51
|
-
extensions: Array.isArray(
|
|
52
|
-
patterns: Array.isArray(
|
|
53
|
-
maxFindings: typeof
|
|
54
|
+
extensions: Array.isArray(rawExts) ? rawExts.filter((x) => typeof x === "string") : DEFAULTS.extensions,
|
|
55
|
+
patterns: Array.isArray(rawPatterns) ? rawPatterns.filter((x) => typeof x === "string") : DEFAULTS.patterns,
|
|
56
|
+
maxFindings: typeof rawMax === "number" && rawMax >= 1 && rawMax <= 500 ? rawMax : DEFAULTS.maxFindings
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
59
|
function normalizeExtensions(exts) {
|
|
@@ -72,6 +75,34 @@ function compilePatterns(patterns) {
|
|
|
72
75
|
}
|
|
73
76
|
return out;
|
|
74
77
|
}
|
|
78
|
+
var RESERVED_FLAG_NAMES = /* @__PURE__ */ new Set([
|
|
79
|
+
"includes",
|
|
80
|
+
"length",
|
|
81
|
+
"has",
|
|
82
|
+
"get",
|
|
83
|
+
"set",
|
|
84
|
+
"size",
|
|
85
|
+
"slice",
|
|
86
|
+
"split",
|
|
87
|
+
"filter",
|
|
88
|
+
"map",
|
|
89
|
+
"forEach",
|
|
90
|
+
"join",
|
|
91
|
+
"push",
|
|
92
|
+
"pop",
|
|
93
|
+
"indexOf",
|
|
94
|
+
"values",
|
|
95
|
+
"keys",
|
|
96
|
+
"entries",
|
|
97
|
+
"toString",
|
|
98
|
+
"trim",
|
|
99
|
+
"toLowerCase",
|
|
100
|
+
"toUpperCase",
|
|
101
|
+
"match",
|
|
102
|
+
"replace",
|
|
103
|
+
"name",
|
|
104
|
+
"type"
|
|
105
|
+
]);
|
|
75
106
|
function scanFile(filePath, content, patterns, maxFindings) {
|
|
76
107
|
const usages = [];
|
|
77
108
|
const lines = content.split(/\r?\n/);
|
|
@@ -79,6 +110,7 @@ function scanFile(filePath, content, patterns, maxFindings) {
|
|
|
79
110
|
re.lastIndex = 0;
|
|
80
111
|
for (const m of content.matchAll(re)) {
|
|
81
112
|
const flag = m[1] ?? m[0];
|
|
113
|
+
if (RESERVED_FLAG_NAMES.has(flag)) continue;
|
|
82
114
|
const lineNo = content.slice(0, m.index).split(/\r?\n/).length;
|
|
83
115
|
const context = (lines[lineNo - 1] ?? "").trim();
|
|
84
116
|
usages.push({
|
|
@@ -172,7 +204,8 @@ var plugin = {
|
|
|
172
204
|
if (!cfg.enabled) return;
|
|
173
205
|
if (input.toolResult?.isError) return;
|
|
174
206
|
const inp = input.toolInput ?? {};
|
|
175
|
-
const
|
|
207
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
208
|
+
const sourcePath = typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
176
209
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
177
210
|
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
178
211
|
const exts = normalizeExtensions(cfg.extensions);
|
|
@@ -212,7 +245,8 @@ Make sure flag behavior is intentional and consider updating flag inventory/docs
|
|
|
212
245
|
mutating: false,
|
|
213
246
|
async execute(input) {
|
|
214
247
|
if (!cfg.enabled) return { ok: false, error: "feature-flag-tracker is disabled" };
|
|
215
|
-
const
|
|
248
|
+
const raw = input ?? {};
|
|
249
|
+
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["SearchDirectory"] === "string" ? raw["SearchDirectory"] : void 0) ?? (typeof raw["dir"] === "string" ? raw["dir"] : void 0) ?? (typeof raw["TargetFile"] === "string" ? raw["TargetFile"] : void 0) ?? (typeof raw["targetFile"] === "string" ? raw["targetFile"] : void 0) ?? (typeof raw["filePath"] === "string" ? raw["filePath"] : void 0) ?? (typeof raw["file_path"] === "string" ? raw["file_path"] : void 0) ?? (typeof raw["file"] === "string" ? raw["file"] : void 0) ?? ".";
|
|
216
250
|
if (!(0, runtime_exports.withinProject)(rawPath)) {
|
|
217
251
|
return { ok: false, error: "path is outside the project root" };
|
|
218
252
|
}
|
package/dist/file-watcher.js
CHANGED
|
@@ -205,8 +205,22 @@ var plugin = {
|
|
|
205
205
|
category: "Filesystem",
|
|
206
206
|
mutating: false,
|
|
207
207
|
async execute(input) {
|
|
208
|
-
const
|
|
209
|
-
|
|
208
|
+
const explicitPaths = input["paths"];
|
|
209
|
+
let rawPaths;
|
|
210
|
+
if (explicitPaths !== void 0) {
|
|
211
|
+
if (!Array.isArray(explicitPaths)) {
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
error: "paths must be an array of file/directory paths",
|
|
215
|
+
watch_id: null
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
rawPaths = explicitPaths;
|
|
219
|
+
} else {
|
|
220
|
+
const fallback = input["path"] ?? input["file"] ?? input["directory"] ?? input["TargetFile"] ?? input["filePath"];
|
|
221
|
+
rawPaths = Array.isArray(fallback) ? fallback : typeof fallback === "string" && fallback.trim().length > 0 ? [fallback.trim()] : void 0;
|
|
222
|
+
}
|
|
223
|
+
if (!rawPaths || !Array.isArray(rawPaths)) {
|
|
210
224
|
return {
|
|
211
225
|
ok: false,
|
|
212
226
|
error: "paths must be an array of file/directory paths",
|
|
@@ -294,9 +308,11 @@ var plugin = {
|
|
|
294
308
|
required: ["watch_id"]
|
|
295
309
|
},
|
|
296
310
|
permission: "auto",
|
|
311
|
+
category: "Filesystem",
|
|
297
312
|
mutating: false,
|
|
298
313
|
async execute(input) {
|
|
299
|
-
const
|
|
314
|
+
const rawId = input["watch_id"] ?? input["watchId"] ?? input["id"];
|
|
315
|
+
const watch_id = typeof rawId === "string" ? rawId.trim() : "";
|
|
300
316
|
const handle = watches.get(watch_id);
|
|
301
317
|
if (!handle) {
|
|
302
318
|
return { ok: false, error: `No active watch with ID: ${watch_id}` };
|
|
@@ -307,6 +323,13 @@ var plugin = {
|
|
|
307
323
|
} catch {
|
|
308
324
|
}
|
|
309
325
|
}
|
|
326
|
+
const prefix = `${watch_id}:`;
|
|
327
|
+
for (const [key, timer] of debounceTimers.entries()) {
|
|
328
|
+
if (key.startsWith(prefix)) {
|
|
329
|
+
clearTimeout(timer);
|
|
330
|
+
debounceTimers.delete(key);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
310
333
|
watches.delete(watch_id);
|
|
311
334
|
api.metrics.gauge("active_watches", watches.size);
|
|
312
335
|
return {
|
package/dist/format-on-save.js
CHANGED
|
@@ -51,11 +51,14 @@ var DEFAULTS = {
|
|
|
51
51
|
function readConfig(raw) {
|
|
52
52
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
53
53
|
const r = raw;
|
|
54
|
+
const rawTimeout = r["timeoutMs"] ?? r["timeout_ms"] ?? r["timeout"];
|
|
55
|
+
const rawCovered = r["skipWhenCoveredBy"] ?? r["skip_when_covered_by"] ?? r["skipCovered"] ?? r["skip_covered"];
|
|
56
|
+
const rawTtl = r["skipTtlMs"] ?? r["skip_ttl_ms"] ?? r["ttlMs"] ?? r["ttl_ms"] ?? r["ttl"];
|
|
54
57
|
return {
|
|
55
58
|
enabled: r["enabled"] !== false,
|
|
56
|
-
timeoutMs: typeof
|
|
57
|
-
skipWhenCoveredBy:
|
|
58
|
-
skipTtlMs: typeof
|
|
59
|
+
timeoutMs: typeof rawTimeout === "number" && rawTimeout > 0 ? rawTimeout : DEFAULTS.timeoutMs,
|
|
60
|
+
skipWhenCoveredBy: rawCovered !== false,
|
|
61
|
+
skipTtlMs: typeof rawTtl === "number" && rawTtl >= 0 ? rawTtl : DEFAULTS.skipTtlMs
|
|
59
62
|
};
|
|
60
63
|
}
|
|
61
64
|
var recentlyCovered = new runtime_exports.BoundedMap({ max: 256 });
|
|
@@ -253,8 +256,9 @@ var plugin = {
|
|
|
253
256
|
if (input.toolResult?.isError) return;
|
|
254
257
|
const toolName = input.toolName ?? "";
|
|
255
258
|
const inp = input.toolInput ?? {};
|
|
256
|
-
const
|
|
257
|
-
|
|
259
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
260
|
+
const filePath = typeof rawPath === "string" && rawPath.trim() ? rawPath.trim() : void 0;
|
|
261
|
+
if (!filePath) return;
|
|
258
262
|
if (cfg.skipWhenCoveredBy && cfg.skipTtlMs > 0) {
|
|
259
263
|
evictExpired(cfg.skipTtlMs);
|
|
260
264
|
if (recentlyCovered.has(filePath)) {
|
package/dist/git-autocommit.js
CHANGED
|
@@ -357,22 +357,28 @@ var plugin = {
|
|
|
357
357
|
try {
|
|
358
358
|
let type = input["type"];
|
|
359
359
|
let scope = input["scope"];
|
|
360
|
-
let summary = input["message"] ?? "";
|
|
360
|
+
let summary = input["message"] ?? input["summary"] ?? input["msg"] ?? input["description"] ?? "";
|
|
361
361
|
let body = input["body"];
|
|
362
|
-
const dryRun = input["dry_run"] ?? false;
|
|
363
|
-
const explicitAsk = input["generate"] === true;
|
|
362
|
+
const dryRun = input["dry_run"] ?? input["dryRun"] ?? false;
|
|
363
|
+
const explicitAsk = (input["generate"] ?? input["autoGenerate"] ?? input["auto_generate"]) === true;
|
|
364
364
|
const autoAsk = opts.useLlm && !input["type"] && !input["message"];
|
|
365
365
|
const wantGenerate = (explicitAsk || autoAsk) && Boolean(api.llm);
|
|
366
366
|
let files;
|
|
367
|
-
const rawFiles = input["files"];
|
|
367
|
+
const rawFiles = input["files"] ?? input["fileList"] ?? input["file_list"];
|
|
368
368
|
if (rawFiles !== void 0) {
|
|
369
369
|
if (!Array.isArray(rawFiles)) {
|
|
370
370
|
return { ok: false, error: "files must be an array of file paths" };
|
|
371
371
|
}
|
|
372
372
|
files = rawFiles;
|
|
373
|
+
} else if (typeof (input["file"] ?? input["file_path"]) === "string" && String(input["file"] ?? input["file_path"]).trim().length > 0) {
|
|
374
|
+
files = [String(input["file"] ?? input["file_path"]).trim()];
|
|
375
|
+
} else if (typeof input["filePath"] === "string" && input["filePath"].trim().length > 0) {
|
|
376
|
+
files = [input["filePath"].trim()];
|
|
377
|
+
} else if (typeof (input["TargetFile"] ?? input["targetFile"]) === "string" && String(input["TargetFile"] ?? input["targetFile"]).trim().length > 0) {
|
|
378
|
+
files = [String(input["TargetFile"] ?? input["targetFile"]).trim()];
|
|
373
379
|
}
|
|
374
380
|
let pathspecs;
|
|
375
|
-
const rawPaths = input["paths"];
|
|
381
|
+
const rawPaths = input["paths"] ?? input["pathList"] ?? input["path_list"];
|
|
376
382
|
if (rawPaths !== void 0) {
|
|
377
383
|
if (!Array.isArray(rawPaths)) {
|
|
378
384
|
return { ok: false, error: "paths must be an array of pathspec patterns" };
|
|
@@ -381,12 +387,14 @@ var plugin = {
|
|
|
381
387
|
if (pathspecs.length === 0) {
|
|
382
388
|
return { ok: false, error: "paths must contain at least one non-empty pattern" };
|
|
383
389
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
+
} else if (typeof input["path"] === "string" && input["path"].trim().length > 0) {
|
|
391
|
+
pathspecs = [input["path"].trim()];
|
|
392
|
+
}
|
|
393
|
+
if (rawPaths !== void 0 && files && files.length > 0) {
|
|
394
|
+
return {
|
|
395
|
+
ok: false,
|
|
396
|
+
error: "Pass either files (exact paths) or paths (pathspec globs), not both \u2014 the other would be silently ignored."
|
|
397
|
+
};
|
|
390
398
|
}
|
|
391
399
|
let commitScope;
|
|
392
400
|
let staged = [];
|
|
@@ -562,7 +570,7 @@ ${stagedDiff}
|
|
|
562
570
|
lastCommit.hash = String(hash);
|
|
563
571
|
lastCommit.at = (/* @__PURE__ */ new Date()).toISOString();
|
|
564
572
|
try {
|
|
565
|
-
await api.session
|
|
573
|
+
await api.session?.append?.({
|
|
566
574
|
type: "git-autocommit:commit",
|
|
567
575
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
568
576
|
hash: String(hash),
|
package/dist/gitignore-guard.js
CHANGED
|
@@ -257,9 +257,10 @@ var plugin = {
|
|
|
257
257
|
if (!cfg.enabled) return;
|
|
258
258
|
if (input.toolResult?.isError) return;
|
|
259
259
|
const toolName = input.toolName ?? "";
|
|
260
|
-
const
|
|
261
|
-
const
|
|
262
|
-
|
|
260
|
+
const toolInput = input.toolInput ?? {};
|
|
261
|
+
const raw = toolInput["path"] ?? toolInput["filePath"] ?? toolInput["file_path"] ?? toolInput["TargetFile"] ?? toolInput["targetFile"] ?? toolInput["file"];
|
|
262
|
+
const rawPath = typeof raw === "string" ? raw : "";
|
|
263
|
+
if (rawPath.trim().length === 0) return;
|
|
263
264
|
if (basename(rawPath) === ".gitignore") return;
|
|
264
265
|
const resolved = projectRelativePath(rawPath, input.cwd);
|
|
265
266
|
if (!resolved) return;
|
|
@@ -365,7 +366,9 @@ var plugin = {
|
|
|
365
366
|
category: "Code Quality",
|
|
366
367
|
mutating: true,
|
|
367
368
|
async execute(input) {
|
|
368
|
-
const
|
|
369
|
+
const rawInp = input ?? {};
|
|
370
|
+
const raw = rawInp["path"] ?? rawInp["filePath"] ?? rawInp["file_path"] ?? rawInp["TargetFile"] ?? rawInp["targetFile"] ?? rawInp["file"];
|
|
371
|
+
const rawPath = typeof raw === "string" ? raw.trim() : "";
|
|
369
372
|
if (rawPath.length === 0) return { ok: false, reason: "path is required" };
|
|
370
373
|
const resolved = projectRelativePath(rawPath, process.cwd());
|
|
371
374
|
if (!resolved) {
|
package/dist/import-organizer.js
CHANGED
|
@@ -116,12 +116,15 @@ var DEFAULTS = {
|
|
|
116
116
|
function readConfig(raw) {
|
|
117
117
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
118
118
|
const r = raw;
|
|
119
|
+
const rawFallback = r["fallbackCommand"] ?? r["fallback_command"] ?? r["fallback"];
|
|
120
|
+
const rawTimeout = r["timeoutMs"] ?? r["timeout_ms"] ?? r["timeout"];
|
|
121
|
+
const rawNotify = r["notifyFormatOnSave"] ?? r["notify_format_on_save"] ?? r["notify"];
|
|
119
122
|
return {
|
|
120
123
|
enabled: r["enabled"] !== false,
|
|
121
124
|
command: typeof r["command"] === "string" && r["command"].length > 0 ? r["command"] : DEFAULTS.command,
|
|
122
|
-
fallbackCommand: typeof
|
|
123
|
-
timeoutMs: typeof
|
|
124
|
-
notifyFormatOnSave:
|
|
125
|
+
fallbackCommand: typeof rawFallback === "string" && rawFallback.length > 0 ? rawFallback : DEFAULTS.fallbackCommand,
|
|
126
|
+
timeoutMs: typeof rawTimeout === "number" && rawTimeout > 0 ? rawTimeout : DEFAULTS.timeoutMs,
|
|
127
|
+
notifyFormatOnSave: rawNotify !== false
|
|
125
128
|
};
|
|
126
129
|
}
|
|
127
130
|
var MAX_CAPTURE_BYTES = 4 * 1024 * 1024;
|
|
@@ -287,8 +290,9 @@ var plugin = {
|
|
|
287
290
|
if (input.toolResult?.isError) return;
|
|
288
291
|
const toolName = input.toolName ?? "";
|
|
289
292
|
const inp = input.toolInput ?? {};
|
|
290
|
-
const
|
|
291
|
-
|
|
293
|
+
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
294
|
+
const filePath = typeof rawPath === "string" ? rawPath : void 0;
|
|
295
|
+
if (!filePath) return;
|
|
292
296
|
const ext = filePath.includes(".") ? filePath.slice(filePath.lastIndexOf(".")) : "";
|
|
293
297
|
if (![".ts", ".tsx", ".js", ".jsx", ".mjs", ".mts", ".cjs", ".cts"].includes(ext)) return;
|
|
294
298
|
state.invocationCount += 1;
|