@wrongstack/plugins 0.293.0 → 0.295.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -71
- package/dist/accessibility-auditor/index.d.ts +1 -1
- package/dist/accessibility-auditor/index.d.ts.map +1 -1
- package/dist/accessibility-auditor.js +50 -33
- package/dist/agent-handoff/index.d.ts +1 -1
- package/dist/agent-handoff/index.d.ts.map +1 -1
- package/dist/agent-handoff.js +30 -1
- package/dist/api-compatibility-gate/index.d.ts +1 -1
- package/dist/api-compatibility-gate/index.d.ts.map +1 -1
- package/dist/api-compatibility-gate.js +21 -16
- package/dist/audit/index.d.ts +386 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit.d.ts +1 -0
- package/dist/audit.js +454 -0
- package/dist/auto-doc/index.d.ts +1 -1
- package/dist/auto-doc/index.d.ts.map +1 -1
- package/dist/auto-doc.js +3 -1
- package/dist/auto-escalate/index.d.ts +1 -1
- package/dist/auto-escalate/index.d.ts.map +1 -1
- package/dist/auto-i18n-extractor/index.d.ts +1 -1
- package/dist/auto-i18n-extractor/index.d.ts.map +1 -1
- package/dist/auto-i18n-extractor.js +7 -1
- package/dist/branch-guard/index.d.ts +1 -1
- package/dist/branch-guard/index.d.ts.map +1 -1
- package/dist/branch-guard.js +111 -1
- package/dist/catalog.d.ts +5 -30
- package/dist/catalog.d.ts.map +1 -1
- package/dist/changelog-writer/index.d.ts +1 -1
- package/dist/changelog-writer/index.d.ts.map +1 -1
- package/dist/changelog-writer.js +137 -3
- package/dist/checkpoint/index.d.ts +3 -1
- package/dist/checkpoint/index.d.ts.map +1 -1
- package/dist/checkpoint.js +41 -16
- package/dist/code-metrics/index.d.ts +1 -1
- package/dist/code-metrics/index.d.ts.map +1 -1
- package/dist/code-metrics.js +34 -29
- package/dist/commit-validator/index.d.ts +1 -1
- package/dist/commit-validator/index.d.ts.map +1 -1
- package/dist/commit-validator.js +17 -7
- package/dist/config-validator/index.d.ts +1 -1
- package/dist/config-validator/index.d.ts.map +1 -1
- package/dist/context-pins/index.d.ts +1 -1
- package/dist/context-pins/index.d.ts.map +1 -1
- package/dist/context-pins.js +6 -5
- package/dist/cost-tracker/index.d.ts +1 -1
- package/dist/cost-tracker/index.d.ts.map +1 -1
- package/dist/cost-tracker.js +109 -2
- package/dist/cron/index.d.ts +1 -1
- package/dist/cron/index.d.ts.map +1 -1
- package/dist/cron.js +1 -0
- package/dist/dead-code-detector/index.d.ts +1 -1
- package/dist/dead-code-detector/index.d.ts.map +1 -1
- package/dist/dead-code-detector.js +31 -18
- package/dist/dep-guard/index.d.ts +1 -1
- package/dist/dep-guard/index.d.ts.map +1 -1
- package/dist/dependency-vulnerability-gate/index.d.ts +1 -1
- package/dist/dependency-vulnerability-gate/index.d.ts.map +1 -1
- package/dist/dependency-vulnerability-gate.js +67 -20
- package/dist/diff-summary/index.d.ts +1 -1
- package/dist/diff-summary/index.d.ts.map +1 -1
- package/dist/diff-summary.js +128 -30
- package/dist/doc-sync-guard/index.d.ts +1 -1
- package/dist/doc-sync-guard/index.d.ts.map +1 -1
- package/dist/doc-sync-guard.js +7 -1
- package/dist/duplicate-code-detector/index.d.ts +26 -1
- package/dist/duplicate-code-detector/index.d.ts.map +1 -1
- package/dist/duplicate-code-detector.js +280 -69
- package/dist/error-lens/index.d.ts +1 -1
- package/dist/error-lens/index.d.ts.map +1 -1
- package/dist/factories/index.d.ts +4 -0
- package/dist/factories/index.d.ts.map +1 -0
- package/dist/factories.d.ts +1 -0
- package/dist/factories.js +74 -0
- package/dist/feature-flag-tracker/index.d.ts +1 -1
- package/dist/feature-flag-tracker/index.d.ts.map +1 -1
- package/dist/feature-flag-tracker.js +59 -33
- package/dist/file-watcher/index.d.ts +1 -1
- package/dist/file-watcher/index.d.ts.map +1 -1
- package/dist/file-watcher.js +6 -7
- package/dist/format-on-save/index.d.ts +3 -1
- package/dist/format-on-save/index.d.ts.map +1 -1
- package/dist/format-on-save.js +289 -59
- package/dist/generated-plugin-exports.d.ts +65 -0
- package/dist/generated-plugin-exports.d.ts.map +1 -0
- package/dist/git-autocommit/index.d.ts +1 -1
- package/dist/git-autocommit/index.d.ts.map +1 -1
- package/dist/import-organizer/index.d.ts +1 -1
- package/dist/import-organizer/index.d.ts.map +1 -1
- package/dist/import-organizer.js +141 -20
- package/dist/index.d.ts +4 -183
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18298 -17279
- package/dist/injection-shield/index.d.ts +1 -1
- package/dist/injection-shield/index.d.ts.map +1 -1
- package/dist/interface-contract-guard/index.d.ts +1 -1
- package/dist/interface-contract-guard/index.d.ts.map +1 -1
- package/dist/interface-contract-guard.js +87 -53
- package/dist/knowledge-graph/index.d.ts +1 -1
- package/dist/knowledge-graph/index.d.ts.map +1 -1
- package/dist/knowledge-graph.js +7 -6
- package/dist/license-audit-gate/index.d.ts +1 -1
- package/dist/license-audit-gate/index.d.ts.map +1 -1
- package/dist/lint-gate/index.d.ts +1 -1
- package/dist/lint-gate/index.d.ts.map +1 -1
- package/dist/lint-gate.js +112 -1
- package/dist/llm-cache/index.d.ts +5 -1
- package/dist/llm-cache/index.d.ts.map +1 -1
- package/dist/llm-cache.js +16 -8
- package/dist/loop-breaker/index.d.ts +1 -1
- package/dist/loop-breaker/index.d.ts.map +1 -1
- package/dist/loop-breaker.js +25 -9
- package/dist/manifest/index.d.ts +16 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest.d.ts +1 -0
- package/dist/manifest.js +152 -0
- package/dist/migration-planner/index.d.ts +1 -1
- package/dist/migration-planner/index.d.ts.map +1 -1
- package/dist/migration-planner.js +5 -1
- package/dist/model-router/index.d.ts +1 -1
- package/dist/model-router/index.d.ts.map +1 -1
- package/dist/notify-hub/index.d.ts +1 -1
- package/dist/notify-hub/index.d.ts.map +1 -1
- package/dist/notify-hub/webhook-channel.d.ts +1 -1
- package/dist/notify-hub/webhook-channel.d.ts.map +1 -1
- package/dist/notify-hub.js +41 -4
- package/dist/path-guard/index.d.ts +1 -1
- package/dist/path-guard/index.d.ts.map +1 -1
- package/dist/performance-regression-gate/index.d.ts +1 -1
- package/dist/performance-regression-gate/index.d.ts.map +1 -1
- package/dist/plugin-stack-observer/index.d.ts +1 -1
- package/dist/plugin-stack-observer/index.d.ts.map +1 -1
- package/dist/pr-drafter/index.d.ts +1 -1
- package/dist/pr-drafter/index.d.ts.map +1 -1
- package/dist/pr-drafter.js +28 -29
- package/dist/process-guard/index.d.ts +1 -1
- package/dist/process-guard/index.d.ts.map +1 -1
- package/dist/prompt-firewall/index.d.ts +1 -1
- package/dist/prompt-firewall/index.d.ts.map +1 -1
- package/dist/prompt-firewall.js +140 -11
- package/dist/refactor-suggester/index.d.ts +1 -1
- package/dist/refactor-suggester/index.d.ts.map +1 -1
- package/dist/refactor-suggester.js +148 -33
- package/dist/release-notes-generator/index.d.ts +1 -1
- package/dist/release-notes-generator/index.d.ts.map +1 -1
- package/dist/release-notes-generator.js +29 -22
- package/dist/runtime/bounded-map.d.ts +86 -0
- package/dist/runtime/bounded-map.d.ts.map +1 -0
- package/dist/runtime/credential-patterns.d.ts +42 -0
- package/dist/runtime/credential-patterns.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +18 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/llm.d.ts +1 -1
- package/dist/runtime/llm.d.ts.map +1 -1
- package/dist/runtime/local-bin.d.ts +120 -0
- package/dist/runtime/local-bin.d.ts.map +1 -0
- package/dist/runtime/safe-json.d.ts +25 -0
- package/dist/runtime/safe-json.d.ts.map +1 -0
- package/dist/runtime.js +332 -22
- package/dist/schema-evolution-guard/index.d.ts +1 -1
- package/dist/schema-evolution-guard/index.d.ts.map +1 -1
- package/dist/schema-evolution-guard.js +7 -1
- package/dist/secret-scanner/index.d.ts +1 -1
- package/dist/secret-scanner/index.d.ts.map +1 -1
- package/dist/secret-scanner.js +181 -48
- package/dist/security-hotspot-scanner/index.d.ts +1 -1
- package/dist/security-hotspot-scanner/index.d.ts.map +1 -1
- package/dist/security-hotspot-scanner.js +158 -20
- package/dist/semantic-search-indexer/index.d.ts +1 -1
- package/dist/semantic-search-indexer/index.d.ts.map +1 -1
- package/dist/semantic-search-indexer.js +7 -1
- package/dist/semver-bump/index.d.ts +1 -1
- package/dist/semver-bump/index.d.ts.map +1 -1
- package/dist/semver-bump.js +97 -43
- package/dist/session-recap/index.d.ts +1 -1
- package/dist/session-recap/index.d.ts.map +1 -1
- package/dist/shell-check/index.d.ts +1 -1
- package/dist/shell-check/index.d.ts.map +1 -1
- package/dist/smart-rename/index.d.ts +1 -1
- package/dist/smart-rename/index.d.ts.map +1 -1
- package/dist/spec-linker/index.d.ts +1 -1
- package/dist/spec-linker/index.d.ts.map +1 -1
- package/dist/spec-linker.js +222 -20772
- package/dist/template-engine/index.d.ts +1 -1
- package/dist/template-engine/index.d.ts.map +1 -1
- package/dist/template-engine.js +34 -8
- package/dist/test-coverage-gate/index.d.ts +1 -1
- package/dist/test-coverage-gate/index.d.ts.map +1 -1
- package/dist/test-coverage-gate.js +34 -14
- package/dist/test-flake-detector/index.d.ts +1 -1
- package/dist/test-flake-detector/index.d.ts.map +1 -1
- package/dist/test-flake-detector.js +31 -20
- package/dist/test-generator/index.d.ts +1 -1
- package/dist/test-generator/index.d.ts.map +1 -1
- package/dist/test-runner-gate/index.d.ts +1 -1
- package/dist/test-runner-gate/index.d.ts.map +1 -1
- package/dist/test-runner-gate.js +132 -9
- package/dist/todo-listener/index.d.ts +1 -32
- package/dist/todo-listener/index.d.ts.map +1 -1
- package/dist/todo-listener.js +30 -1
- package/dist/todo-tracker/index.d.ts +1 -1
- package/dist/todo-tracker/index.d.ts.map +1 -1
- package/dist/todo-tracker.js +3 -4
- package/dist/token-budget/index.d.ts +1 -1
- package/dist/token-budget/index.d.ts.map +1 -1
- package/dist/token-throttle/index.d.ts +1 -1
- package/dist/token-throttle/index.d.ts.map +1 -1
- package/dist/token-throttle.js +17 -2
- package/dist/type-gate/index.d.ts +1 -1
- package/dist/type-gate/index.d.ts.map +1 -1
- package/dist/type-gate.js +106 -19
- package/package.json +80 -68
package/dist/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/runtime/index.ts
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
4
|
-
import { basename, extname, isAbsolute, relative, resolve } from "node:path";
|
|
4
|
+
import { basename, extname as extname2, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
|
|
5
5
|
|
|
6
6
|
// src/runtime/llm.ts
|
|
7
7
|
function stripOuterMarkdownFence(text) {
|
|
@@ -49,6 +49,249 @@ async function runOptionalPluginLlm(request) {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
// src/runtime/local-bin.ts
|
|
53
|
+
import { createRequire } from "node:module";
|
|
54
|
+
import { delimiter, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
55
|
+
import { accessSync, constants, readFileSync } from "node:fs";
|
|
56
|
+
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
57
|
+
function resolveExecInvocation(command, args = []) {
|
|
58
|
+
const resolved = resolveWin32Command(command);
|
|
59
|
+
const normalizedResolved = resolved.toLowerCase();
|
|
60
|
+
const needsShell = process.platform === "win32" && (normalizedResolved.endsWith(".cmd") || normalizedResolved.endsWith(".bat"));
|
|
61
|
+
if (needsShell) {
|
|
62
|
+
const shim = buildWin32CmdShimInvocation(resolved, args);
|
|
63
|
+
return { cmd: shim.command, args: shim.args, windowsVerbatimArguments: true };
|
|
64
|
+
}
|
|
65
|
+
return { cmd: resolved, args: [...args], windowsVerbatimArguments: false };
|
|
66
|
+
}
|
|
67
|
+
function findOnPath(cmd) {
|
|
68
|
+
if (!cmd) return null;
|
|
69
|
+
const exists = (p) => {
|
|
70
|
+
try {
|
|
71
|
+
accessSync(p, constants.X_OK);
|
|
72
|
+
return true;
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
78
|
+
return exists(cmd) ? resolve(cmd) : null;
|
|
79
|
+
}
|
|
80
|
+
const suffixes = process.platform === "win32" && extname(cmd) === "" ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
81
|
+
for (const dir of (process.env["PATH"] ?? "").split(delimiter)) {
|
|
82
|
+
if (!dir) continue;
|
|
83
|
+
const base = join(dir, cmd);
|
|
84
|
+
for (const suffix of suffixes) {
|
|
85
|
+
const candidate = `${base}${suffix}`;
|
|
86
|
+
if (exists(candidate)) return candidate;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
function isInside(parent, candidate) {
|
|
92
|
+
const rel = relative(parent, candidate);
|
|
93
|
+
return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel);
|
|
94
|
+
}
|
|
95
|
+
var binCache = /* @__PURE__ */ new Map();
|
|
96
|
+
var BIN_CACHE_MAX = 64;
|
|
97
|
+
var NEGATIVE_BIN_CACHE_TTL_MS = 5e3;
|
|
98
|
+
function cachePut(key, value) {
|
|
99
|
+
while (binCache.size >= BIN_CACHE_MAX) {
|
|
100
|
+
const oldest = binCache.keys().next().value;
|
|
101
|
+
if (oldest === void 0) break;
|
|
102
|
+
binCache.delete(oldest);
|
|
103
|
+
}
|
|
104
|
+
binCache.set(key, { value, cachedAt: Date.now() });
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
function clearLocalBinCache() {
|
|
108
|
+
binCache.clear();
|
|
109
|
+
}
|
|
110
|
+
function resolveNodeBin(packageName, binName, cwd, extraArgs = []) {
|
|
111
|
+
const key = `${packageName}|${binName}|${cwd}`;
|
|
112
|
+
const cached = binCache.get(key);
|
|
113
|
+
if (cached !== void 0) {
|
|
114
|
+
if (cached.value !== null || Date.now() - cached.cachedAt < NEGATIVE_BIN_CACHE_TTL_MS) {
|
|
115
|
+
return cached.value === null ? null : { ...cached.value, args: [cached.value.entry, ...extraArgs] };
|
|
116
|
+
}
|
|
117
|
+
binCache.delete(key);
|
|
118
|
+
}
|
|
119
|
+
let resolved = null;
|
|
120
|
+
try {
|
|
121
|
+
const requireFromProject = createRequire(resolve(cwd, "package.json"));
|
|
122
|
+
const packagePath = requireFromProject.resolve(`${packageName}/package.json`);
|
|
123
|
+
const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
|
|
124
|
+
const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[binName] ?? Object.values(packageJson.bin ?? {})[0];
|
|
125
|
+
if (relativeBin && !isAbsolute(relativeBin)) {
|
|
126
|
+
const packageDir = dirname(packagePath);
|
|
127
|
+
const entry = resolve(packageDir, relativeBin);
|
|
128
|
+
if (isInside(packageDir, entry)) {
|
|
129
|
+
resolved = { cmd: process.execPath, args: [entry], entry };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
resolved = null;
|
|
134
|
+
}
|
|
135
|
+
cachePut(key, resolved);
|
|
136
|
+
return resolved === null ? null : { ...resolved, args: [resolved.entry, ...extraArgs] };
|
|
137
|
+
}
|
|
138
|
+
function resolveFirstNodeBin(candidates, cwd) {
|
|
139
|
+
for (const c of candidates) {
|
|
140
|
+
const hit = resolveNodeBin(c.packageName, c.binName, cwd, c.args ?? []);
|
|
141
|
+
if (hit) return { ...hit, packageName: c.packageName, binName: c.binName };
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/runtime/bounded-map.ts
|
|
147
|
+
var BoundedMap = class {
|
|
148
|
+
map = /* @__PURE__ */ new Map();
|
|
149
|
+
max;
|
|
150
|
+
ttlMs;
|
|
151
|
+
now;
|
|
152
|
+
/** Entries dropped to stay under `max`. Surfaced by plugin health(). */
|
|
153
|
+
evictions = 0;
|
|
154
|
+
constructor(options) {
|
|
155
|
+
const normalizedMax = Math.floor(options.max);
|
|
156
|
+
this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
|
|
157
|
+
this.ttlMs = options.ttlMs;
|
|
158
|
+
this.now = options.now ?? Date.now;
|
|
159
|
+
}
|
|
160
|
+
expired(entry) {
|
|
161
|
+
return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
|
|
162
|
+
}
|
|
163
|
+
get(key) {
|
|
164
|
+
const entry = this.map.get(key);
|
|
165
|
+
if (entry === void 0) return void 0;
|
|
166
|
+
if (this.expired(entry)) {
|
|
167
|
+
this.map.delete(key);
|
|
168
|
+
return void 0;
|
|
169
|
+
}
|
|
170
|
+
this.map.delete(key);
|
|
171
|
+
this.map.set(key, entry);
|
|
172
|
+
return entry.value;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Read without promoting the key to most-recently-used. Use for
|
|
176
|
+
* diagnostics that must not perturb the eviction order.
|
|
177
|
+
*/
|
|
178
|
+
peek(key) {
|
|
179
|
+
const entry = this.map.get(key);
|
|
180
|
+
if (entry === void 0 || this.expired(entry)) return void 0;
|
|
181
|
+
return entry.value;
|
|
182
|
+
}
|
|
183
|
+
has(key) {
|
|
184
|
+
const entry = this.map.get(key);
|
|
185
|
+
if (entry === void 0) return false;
|
|
186
|
+
if (this.expired(entry)) {
|
|
187
|
+
this.map.delete(key);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
set(key, value) {
|
|
193
|
+
this.map.delete(key);
|
|
194
|
+
this.map.set(key, { value, storedAt: this.now() });
|
|
195
|
+
while (this.map.size > this.max) {
|
|
196
|
+
const coldest = this.map.keys().next().value;
|
|
197
|
+
if (coldest === void 0) break;
|
|
198
|
+
this.map.delete(coldest);
|
|
199
|
+
this.evictions += 1;
|
|
200
|
+
}
|
|
201
|
+
return this;
|
|
202
|
+
}
|
|
203
|
+
delete(key) {
|
|
204
|
+
return this.map.delete(key);
|
|
205
|
+
}
|
|
206
|
+
clear() {
|
|
207
|
+
this.map.clear();
|
|
208
|
+
this.evictions = 0;
|
|
209
|
+
}
|
|
210
|
+
get size() {
|
|
211
|
+
return this.map.size;
|
|
212
|
+
}
|
|
213
|
+
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
214
|
+
get evictionCount() {
|
|
215
|
+
return this.evictions;
|
|
216
|
+
}
|
|
217
|
+
/** Drop every expired entry. Cheap enough to call from a status tool. */
|
|
218
|
+
prune() {
|
|
219
|
+
if (this.ttlMs === void 0) return 0;
|
|
220
|
+
let removed = 0;
|
|
221
|
+
for (const [key, entry] of this.map) {
|
|
222
|
+
if (this.expired(entry)) {
|
|
223
|
+
this.map.delete(key);
|
|
224
|
+
removed += 1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return removed;
|
|
228
|
+
}
|
|
229
|
+
/** Live (non-expired) entries, coldest first. */
|
|
230
|
+
*entries() {
|
|
231
|
+
for (const [key, entry] of this.map) {
|
|
232
|
+
if (!this.expired(entry)) yield [key, entry.value];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
[Symbol.iterator]() {
|
|
236
|
+
return this.entries();
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
var BoundedSet = class {
|
|
240
|
+
inner;
|
|
241
|
+
constructor(options) {
|
|
242
|
+
this.inner = new BoundedMap(options);
|
|
243
|
+
}
|
|
244
|
+
has(value) {
|
|
245
|
+
return this.inner.has(value);
|
|
246
|
+
}
|
|
247
|
+
add(value) {
|
|
248
|
+
this.inner.set(value, true);
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
delete(value) {
|
|
252
|
+
return this.inner.delete(value);
|
|
253
|
+
}
|
|
254
|
+
clear() {
|
|
255
|
+
this.inner.clear();
|
|
256
|
+
}
|
|
257
|
+
get size() {
|
|
258
|
+
return this.inner.size;
|
|
259
|
+
}
|
|
260
|
+
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
261
|
+
get evictionCount() {
|
|
262
|
+
return this.inner.evictionCount;
|
|
263
|
+
}
|
|
264
|
+
*values() {
|
|
265
|
+
for (const [key] of this.inner) yield key;
|
|
266
|
+
}
|
|
267
|
+
[Symbol.iterator]() {
|
|
268
|
+
return this.values();
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// src/runtime/safe-json.ts
|
|
273
|
+
var UNSERIALIZABLE = "[unserializable]";
|
|
274
|
+
function safeJsonStringify(value, indent) {
|
|
275
|
+
try {
|
|
276
|
+
const stack = [];
|
|
277
|
+
const out = JSON.stringify(
|
|
278
|
+
value,
|
|
279
|
+
function replacer(_key, val) {
|
|
280
|
+
if (typeof val === "bigint") return `${val.toString()}n`;
|
|
281
|
+
if (val === null || typeof val !== "object") return val;
|
|
282
|
+
while (stack.length > 0 && stack[stack.length - 1] !== this) stack.pop();
|
|
283
|
+
if (stack.includes(val)) return "[circular]";
|
|
284
|
+
stack.push(val);
|
|
285
|
+
return val;
|
|
286
|
+
},
|
|
287
|
+
indent
|
|
288
|
+
);
|
|
289
|
+
return out ?? String(value);
|
|
290
|
+
} catch {
|
|
291
|
+
return UNSERIALIZABLE;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
52
295
|
// src/runtime/index.ts
|
|
53
296
|
var META_CHARS = /["'`;&|<>\r\n]/;
|
|
54
297
|
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
@@ -63,9 +306,9 @@ function safeSplit(command) {
|
|
|
63
306
|
function withinProjectPath(projectRoot, candidate) {
|
|
64
307
|
if (candidate.length === 0 || candidate.length > 4096) return false;
|
|
65
308
|
if (hasLeadingDash(candidate)) return false;
|
|
66
|
-
const resolved =
|
|
67
|
-
const rel =
|
|
68
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
309
|
+
const resolved = isAbsolute2(candidate) ? resolve2(candidate) : resolve2(projectRoot, candidate);
|
|
310
|
+
const rel = relative2(projectRoot, resolved);
|
|
311
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
|
|
69
312
|
}
|
|
70
313
|
function everyFlagAllowed(allowed, args) {
|
|
71
314
|
for (const arg of args) {
|
|
@@ -77,14 +320,14 @@ function everyFlagAllowed(allowed, args) {
|
|
|
77
320
|
}
|
|
78
321
|
function sanitizeRunnerPath(value, options = {}) {
|
|
79
322
|
if (!value || hasLeadingDash(value)) return null;
|
|
80
|
-
const projectRoot =
|
|
323
|
+
const projectRoot = resolve2(options.projectRoot ?? process.cwd());
|
|
81
324
|
if (!withinProjectPath(projectRoot, value)) return null;
|
|
82
|
-
return
|
|
325
|
+
return isAbsolute2(value) ? resolve2(value) : resolve2(projectRoot, value);
|
|
83
326
|
}
|
|
84
327
|
function resolveRunnerCommand(runtime, command, options = {}) {
|
|
85
328
|
const tokens = safeSplit(command);
|
|
86
329
|
if (!tokens || tokens.length === 0) return null;
|
|
87
|
-
const projectRoot =
|
|
330
|
+
const projectRoot = resolve2(options.projectRoot ?? process.cwd());
|
|
88
331
|
const launcher = runtime.packageManager;
|
|
89
332
|
const [head, second, ...rest] = tokens;
|
|
90
333
|
if (!head) return null;
|
|
@@ -115,7 +358,7 @@ function resolveRunnerCommand(runtime, command, options = {}) {
|
|
|
115
358
|
return { cmd: head, args: [second, exe, ...tail], display };
|
|
116
359
|
}
|
|
117
360
|
}
|
|
118
|
-
if (
|
|
361
|
+
if (isAbsolute2(head)) {
|
|
119
362
|
if (!withinProjectPath(projectRoot, head)) return null;
|
|
120
363
|
const base = basename(head);
|
|
121
364
|
if (base !== runtime.executable && base !== launcher) return null;
|
|
@@ -136,7 +379,7 @@ function runRunnerCommand(argv, options) {
|
|
|
136
379
|
});
|
|
137
380
|
}
|
|
138
381
|
return new Promise((resolvePromise) => {
|
|
139
|
-
const projectRoot =
|
|
382
|
+
const projectRoot = resolve2(options.projectRoot ?? process.cwd());
|
|
140
383
|
const trimmedCwd = options.cwd.trim();
|
|
141
384
|
if (!withinProjectPath(projectRoot, trimmedCwd)) {
|
|
142
385
|
resolvePromise({
|
|
@@ -154,21 +397,37 @@ function runRunnerCommand(argv, options) {
|
|
|
154
397
|
const stderrChunks = [];
|
|
155
398
|
let stdoutBytes = 0;
|
|
156
399
|
let stderrBytes = 0;
|
|
157
|
-
|
|
400
|
+
const onAbort = () => {
|
|
158
401
|
timedOut = true;
|
|
159
|
-
}
|
|
402
|
+
};
|
|
403
|
+
let invocation;
|
|
404
|
+
try {
|
|
405
|
+
invocation = resolveExecInvocation(argv[0], argv.slice(1));
|
|
406
|
+
} catch (err) {
|
|
407
|
+
resolvePromise({
|
|
408
|
+
code: null,
|
|
409
|
+
stdout: "",
|
|
410
|
+
stderr: `runtime helper: ${err instanceof Error ? err.message : String(err)}`,
|
|
411
|
+
timedOut: false,
|
|
412
|
+
spawnError: true
|
|
413
|
+
});
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
160
417
|
const child = execFile(
|
|
161
|
-
|
|
162
|
-
|
|
418
|
+
invocation.cmd,
|
|
419
|
+
invocation.args,
|
|
163
420
|
{
|
|
164
421
|
cwd: trimmedCwd,
|
|
165
422
|
timeout: options.timeoutMs,
|
|
166
423
|
signal: options.signal,
|
|
167
424
|
maxBuffer: MAX_BUFFER_BYTES,
|
|
168
425
|
windowsHide: true,
|
|
169
|
-
shell: false
|
|
426
|
+
shell: false,
|
|
427
|
+
...invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
|
|
170
428
|
},
|
|
171
429
|
(err) => {
|
|
430
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
172
431
|
if (timedOut) {
|
|
173
432
|
resolvePromise({
|
|
174
433
|
code: null,
|
|
@@ -240,14 +499,15 @@ async function probeRunner(runtime, probeArg = "--version", options) {
|
|
|
240
499
|
return result.code === 0;
|
|
241
500
|
}
|
|
242
501
|
function withinProject(p) {
|
|
243
|
-
|
|
502
|
+
const cwd = process.cwd();
|
|
503
|
+
return withinProjectPath(cwd, p) || relative2(cwd, p) === ".";
|
|
244
504
|
}
|
|
245
505
|
function locateRunnerEntry(runtime, projectRoot) {
|
|
246
|
-
const root =
|
|
506
|
+
const root = resolve2(projectRoot);
|
|
247
507
|
const candidates = [
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
508
|
+
resolve2(root, "node_modules", ".bin", runtime.executable),
|
|
509
|
+
resolve2(root, "node_modules", ".bin", `${runtime.executable}.cmd`),
|
|
510
|
+
resolve2(root, "node_modules", ".bin", `${runtime.executable}.ps1`)
|
|
251
511
|
];
|
|
252
512
|
for (const c of candidates) {
|
|
253
513
|
if (existsSync(c)) return c;
|
|
@@ -265,6 +525,7 @@ function collectSourceFiles(root, opts) {
|
|
|
265
525
|
}
|
|
266
526
|
if (!s.isDirectory()) return files;
|
|
267
527
|
const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
|
|
528
|
+
const excludeSet = new Set(exclude);
|
|
268
529
|
function walk(dir, depth) {
|
|
269
530
|
if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
|
|
270
531
|
let entries;
|
|
@@ -273,9 +534,10 @@ function collectSourceFiles(root, opts) {
|
|
|
273
534
|
} catch {
|
|
274
535
|
return;
|
|
275
536
|
}
|
|
537
|
+
entries.sort();
|
|
276
538
|
for (const entry of entries) {
|
|
277
|
-
if (
|
|
278
|
-
const full =
|
|
539
|
+
if (excludeSet.has(entry)) continue;
|
|
540
|
+
const full = resolve2(dir, entry);
|
|
279
541
|
let st;
|
|
280
542
|
try {
|
|
281
543
|
st = statSync(full);
|
|
@@ -292,18 +554,66 @@ function collectSourceFiles(root, opts) {
|
|
|
292
554
|
walk(root, 0);
|
|
293
555
|
return files;
|
|
294
556
|
}
|
|
557
|
+
async function collectSourceFilesAsync(root, opts) {
|
|
558
|
+
const { readdir, stat } = await import("node:fs/promises");
|
|
559
|
+
const files = [];
|
|
560
|
+
try {
|
|
561
|
+
const s = await stat(root);
|
|
562
|
+
if (s.isFile()) {
|
|
563
|
+
if (matchesExtension(root, opts.extensions)) files.push(root);
|
|
564
|
+
return files;
|
|
565
|
+
}
|
|
566
|
+
if (!s.isDirectory()) return files;
|
|
567
|
+
} catch {
|
|
568
|
+
return files;
|
|
569
|
+
}
|
|
570
|
+
const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
|
|
571
|
+
const excludeSet = new Set(exclude);
|
|
572
|
+
async function walk(dir, depth) {
|
|
573
|
+
if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
|
|
574
|
+
let entries;
|
|
575
|
+
try {
|
|
576
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
577
|
+
} catch {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
581
|
+
for (const entry of entries) {
|
|
582
|
+
if (excludeSet.has(entry.name)) continue;
|
|
583
|
+
const full = resolve2(dir, entry.name);
|
|
584
|
+
if (entry.isDirectory()) {
|
|
585
|
+
await walk(full, depth + 1);
|
|
586
|
+
} else if (entry.isFile() && matchesExtension(full, opts.extensions)) {
|
|
587
|
+
files.push(full);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
await walk(root, 0);
|
|
592
|
+
return files;
|
|
593
|
+
}
|
|
295
594
|
function matchesExtension(p, exts) {
|
|
296
|
-
return exts.includes(
|
|
595
|
+
return exts.includes(extname2(p).toLowerCase());
|
|
297
596
|
}
|
|
298
597
|
export {
|
|
598
|
+
BoundedMap,
|
|
599
|
+
BoundedSet,
|
|
600
|
+
UNSERIALIZABLE,
|
|
601
|
+
clearLocalBinCache,
|
|
299
602
|
collectSourceFiles,
|
|
603
|
+
collectSourceFilesAsync,
|
|
604
|
+
findOnPath,
|
|
300
605
|
locateRunnerEntry,
|
|
301
606
|
matchesExtension,
|
|
302
607
|
parseLlmJsonObject,
|
|
303
608
|
probeRunner,
|
|
609
|
+
resolveExecInvocation,
|
|
610
|
+
resolveFirstNodeBin,
|
|
611
|
+
resolveNodeBin,
|
|
304
612
|
resolveRunnerCommand,
|
|
613
|
+
resolveWin32Command,
|
|
305
614
|
runOptionalPluginLlm,
|
|
306
615
|
runRunnerCommand,
|
|
616
|
+
safeJsonStringify,
|
|
307
617
|
sanitizeRunnerPath,
|
|
308
618
|
stripOuterMarkdownFence,
|
|
309
619
|
withinProject
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema-evolution-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema-evolution-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA0MrD,QAAA,MAAM,MAAM,EAAE,MAgNb,CAAC;eAEa,MAAM"}
|
|
@@ -4,6 +4,11 @@ import { basename as basename2 } from "node:path";
|
|
|
4
4
|
|
|
5
5
|
// src/runtime/index.ts
|
|
6
6
|
import { basename, extname, isAbsolute, relative, resolve } from "node:path";
|
|
7
|
+
|
|
8
|
+
// src/runtime/local-bin.ts
|
|
9
|
+
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
10
|
+
|
|
11
|
+
// src/runtime/index.ts
|
|
7
12
|
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
8
13
|
function hasLeadingDash(arg) {
|
|
9
14
|
return arg.length > 0 && arg.startsWith("-");
|
|
@@ -16,7 +21,8 @@ function withinProjectPath(projectRoot, candidate) {
|
|
|
16
21
|
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
17
22
|
}
|
|
18
23
|
function withinProject(p) {
|
|
19
|
-
|
|
24
|
+
const cwd = process.cwd();
|
|
25
|
+
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
// src/schema-evolution-guard/index.ts
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* They share the same threat model but act at different points in the
|
|
27
27
|
* pipeline.
|
|
28
28
|
*/
|
|
29
|
-
import type { Plugin } from '@wrongstack/core';
|
|
29
|
+
import type { Plugin } from '@wrongstack/core/types';
|
|
30
30
|
declare const plugin: Plugin;
|
|
31
31
|
export default plugin;
|
|
32
32
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secret-scanner/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secret-scanner/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAwmBrD,QAAA,MAAM,MAAM,EAAE,MAgOb,CAAC;eAEa,MAAM"}
|