@wrongstack/plugins 0.308.6 → 0.309.0
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 +26 -82
- package/dist/agent-handoff.js +16 -26
- package/dist/auto-i18n-extractor.js +19 -23
- package/dist/branch-guard.js +19 -111
- package/dist/changelog-writer.js +20 -133
- package/dist/code-metrics.js +26 -71
- package/dist/commit-validator.js +16 -14
- package/dist/config-validator.js +18 -22
- package/dist/cost-tracker.js +15 -96
- package/dist/dead-code-detector.js +27 -31
- package/dist/dependency-vulnerability-gate.js +18 -15
- package/dist/diff-summary.js +19 -128
- package/dist/doc-sync-guard.js +24 -39
- package/dist/duplicate-code-detector.js +30 -169
- package/dist/feature-flag-tracker.js +26 -71
- package/dist/file-watcher.js +19 -23
- package/dist/format-on-save.js +25 -214
- package/dist/import-organizer.js +31 -106
- package/dist/index.js +452 -1236
- package/dist/interface-contract-guard.js +26 -71
- package/dist/lint-gate.js +19 -111
- package/dist/migration-planner.js +28 -120
- package/dist/notify-hub.js +18 -28
- package/dist/path-guard.js +27 -102
- package/dist/pr-drafter.js +18 -16
- package/dist/prompt-firewall.js +8 -205
- package/dist/refactor-suggester.js +27 -166
- package/dist/release-notes-generator.js +6 -35
- package/dist/runtime/bounded-map.d.ts +2 -85
- package/dist/runtime/credential-patterns.d.ts +2 -41
- package/dist/runtime/h1-state.d.ts +2 -61
- package/dist/runtime/handles.d.ts +2 -45
- package/dist/runtime/index.d.ts +8 -180
- package/dist/runtime/llm.d.ts +2 -43
- package/dist/runtime/local-bin.d.ts +2 -119
- package/dist/runtime/redos-guard.d.ts +2 -68
- package/dist/runtime/safe-json.d.ts +2 -24
- package/dist/runtime/sandbox.d.ts +2 -58
- package/dist/runtime.js +1 -868
- package/dist/schema-evolution-guard.js +20 -24
- package/dist/secret-scanner.js +22 -146
- package/dist/security-hotspot-scanner.js +24 -154
- package/dist/session-recap.js +16 -14
- package/dist/spec-linker.js +19 -17
- package/dist/template-engine.js +22 -37
- package/dist/test-coverage-gate.js +19 -34
- package/dist/test-generator.js +6 -35
- package/dist/test-runner-gate.js +34 -143
- package/dist/todo-listener.js +17 -38
- package/dist/type-gate.js +23 -311
- package/package.json +4 -3
|
@@ -1,70 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/interface-contract-guard/index.ts
|
|
2
16
|
import { readFile } from "node:fs/promises";
|
|
3
|
-
import { isAbsolute
|
|
4
|
-
|
|
5
|
-
// src/runtime/index.ts
|
|
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";
|
|
17
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
10
18
|
|
|
11
19
|
// src/runtime/index.ts
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
function withinProjectPath(projectRoot, candidate) {
|
|
17
|
-
if (candidate.length === 0 || candidate.length > 4096) return false;
|
|
18
|
-
if (hasLeadingDash(candidate)) return false;
|
|
19
|
-
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
|
|
20
|
-
const rel = relative(projectRoot, resolved);
|
|
21
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
22
|
-
}
|
|
23
|
-
function withinProject(p) {
|
|
24
|
-
const cwd = process.cwd();
|
|
25
|
-
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
26
|
-
}
|
|
27
|
-
var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
|
|
28
|
-
async function collectSourceFilesAsync(root, opts) {
|
|
29
|
-
const { readdir, stat } = await import("node:fs/promises");
|
|
30
|
-
const files = [];
|
|
31
|
-
try {
|
|
32
|
-
const s = await stat(root);
|
|
33
|
-
if (s.isFile()) {
|
|
34
|
-
if (matchesExtension(root, opts.extensions)) files.push(root);
|
|
35
|
-
return files;
|
|
36
|
-
}
|
|
37
|
-
if (!s.isDirectory()) return files;
|
|
38
|
-
} catch {
|
|
39
|
-
return files;
|
|
40
|
-
}
|
|
41
|
-
const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
|
|
42
|
-
const excludeSet = new Set(exclude);
|
|
43
|
-
async function walk(dir, depth) {
|
|
44
|
-
if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
|
|
45
|
-
let entries;
|
|
46
|
-
try {
|
|
47
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
48
|
-
} catch {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
52
|
-
for (const entry of entries) {
|
|
53
|
-
if (excludeSet.has(entry.name)) continue;
|
|
54
|
-
const full = resolve(dir, entry.name);
|
|
55
|
-
if (entry.isDirectory()) {
|
|
56
|
-
await walk(full, depth + 1);
|
|
57
|
-
} else if (entry.isFile() && matchesExtension(full, opts.extensions)) {
|
|
58
|
-
files.push(full);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
await walk(root, 0);
|
|
63
|
-
return files;
|
|
64
|
-
}
|
|
65
|
-
function matchesExtension(p, exts) {
|
|
66
|
-
return exts.includes(extname(p).toLowerCase());
|
|
67
|
-
}
|
|
20
|
+
var runtime_exports = {};
|
|
21
|
+
__reExport(runtime_exports, runtime_star);
|
|
22
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
68
23
|
|
|
69
24
|
// src/interface-contract-guard/index.ts
|
|
70
25
|
var API_VERSION = "^0.1.10";
|
|
@@ -99,7 +54,7 @@ function toPosix(p) {
|
|
|
99
54
|
return p.replace(/\\/g, "/");
|
|
100
55
|
}
|
|
101
56
|
function relativePath(p) {
|
|
102
|
-
return toPosix(
|
|
57
|
+
return toPosix(relative(process.cwd(), p));
|
|
103
58
|
}
|
|
104
59
|
var INTERFACE_RE = /(?:export\s+)?interface\s+([A-Za-z_$][A-Za-z0-9_$]*)/g;
|
|
105
60
|
function extractInterfaceNames(content) {
|
|
@@ -127,9 +82,9 @@ function collectImplementedNames(content, into) {
|
|
|
127
82
|
}
|
|
128
83
|
async function scanPath(rawPath, cfg) {
|
|
129
84
|
const root = process.cwd();
|
|
130
|
-
const resolved =
|
|
85
|
+
const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
|
|
131
86
|
const exts = normalizeExtensions(cfg.extensions);
|
|
132
|
-
const allFiles = await collectSourceFilesAsync(resolved, { extensions: exts });
|
|
87
|
+
const allFiles = await (0, runtime_exports.collectSourceFilesAsync)(resolved, { extensions: exts });
|
|
133
88
|
const files = allFiles.slice(0, cfg.maxFiles);
|
|
134
89
|
const implemented = /* @__PURE__ */ new Set();
|
|
135
90
|
const declarations = [];
|
|
@@ -213,11 +168,11 @@ var plugin = {
|
|
|
213
168
|
const inp = input.toolInput ?? {};
|
|
214
169
|
const sourcePath = inp["path"];
|
|
215
170
|
if (!sourcePath || typeof sourcePath !== "string") return;
|
|
216
|
-
if (!withinProject(sourcePath)) return;
|
|
171
|
+
if (!(0, runtime_exports.withinProject)(sourcePath)) return;
|
|
217
172
|
const exts = normalizeExtensions(cfg.extensions);
|
|
218
|
-
if (!matchesExtension(sourcePath, exts)) return;
|
|
173
|
+
if (!(0, runtime_exports.matchesExtension)(sourcePath, exts)) return;
|
|
219
174
|
state.hookInvocationCount += 1;
|
|
220
|
-
const resolved =
|
|
175
|
+
const resolved = resolve(process.cwd(), sourcePath);
|
|
221
176
|
let content;
|
|
222
177
|
try {
|
|
223
178
|
content = await readFile(resolved, "utf-8");
|
|
@@ -251,7 +206,7 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
|
|
|
251
206
|
async execute(input) {
|
|
252
207
|
if (!cfg.enabled) return { ok: false, error: "interface-contract-guard is disabled" };
|
|
253
208
|
const rawPath = typeof input.path === "string" ? input.path : ".";
|
|
254
|
-
if (!withinProject(rawPath)) {
|
|
209
|
+
if (!(0, runtime_exports.withinProject)(rawPath)) {
|
|
255
210
|
return { ok: false, error: "path is outside the project root" };
|
|
256
211
|
}
|
|
257
212
|
state.scanCount += 1;
|
|
@@ -265,7 +220,7 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
|
|
|
265
220
|
state.findingCount += result.findings.length;
|
|
266
221
|
return {
|
|
267
222
|
ok: true,
|
|
268
|
-
path: relativePath(
|
|
223
|
+
path: relativePath(resolve(process.cwd(), rawPath)),
|
|
269
224
|
scannedFiles: result.scannedFiles,
|
|
270
225
|
findings: result.findings,
|
|
271
226
|
// Say so when the corpus was cut short. A partial scan that
|
package/dist/lint-gate.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/lint-gate/index.ts
|
|
2
16
|
import { execFile } from "node:child_process";
|
|
3
17
|
import { readFileSync } from "node:fs";
|
|
@@ -6,116 +20,10 @@ import { createRequire } from "node:module";
|
|
|
6
20
|
import { tmpdir } from "node:os";
|
|
7
21
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
8
22
|
|
|
9
|
-
// src/runtime/local-bin.ts
|
|
10
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
11
|
-
|
|
12
|
-
// src/runtime/bounded-map.ts
|
|
13
|
-
var BoundedMap = class {
|
|
14
|
-
map = /* @__PURE__ */ new Map();
|
|
15
|
-
max;
|
|
16
|
-
ttlMs;
|
|
17
|
-
now;
|
|
18
|
-
/** Entries dropped to stay under `max`. Surfaced by plugin health(). */
|
|
19
|
-
evictions = 0;
|
|
20
|
-
constructor(options) {
|
|
21
|
-
const normalizedMax = Math.floor(options.max);
|
|
22
|
-
this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
|
|
23
|
-
this.ttlMs = options.ttlMs;
|
|
24
|
-
this.now = options.now ?? Date.now;
|
|
25
|
-
}
|
|
26
|
-
expired(entry) {
|
|
27
|
-
return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
|
|
28
|
-
}
|
|
29
|
-
get(key) {
|
|
30
|
-
const entry = this.map.get(key);
|
|
31
|
-
if (entry === void 0) return void 0;
|
|
32
|
-
if (this.expired(entry)) {
|
|
33
|
-
this.map.delete(key);
|
|
34
|
-
return void 0;
|
|
35
|
-
}
|
|
36
|
-
this.map.delete(key);
|
|
37
|
-
this.map.set(key, entry);
|
|
38
|
-
return entry.value;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Read without promoting the key to most-recently-used. Use for
|
|
42
|
-
* diagnostics that must not perturb the eviction order.
|
|
43
|
-
*/
|
|
44
|
-
peek(key) {
|
|
45
|
-
const entry = this.map.get(key);
|
|
46
|
-
if (entry === void 0 || this.expired(entry)) return void 0;
|
|
47
|
-
return entry.value;
|
|
48
|
-
}
|
|
49
|
-
has(key) {
|
|
50
|
-
const entry = this.map.get(key);
|
|
51
|
-
if (entry === void 0) return false;
|
|
52
|
-
if (this.expired(entry)) {
|
|
53
|
-
this.map.delete(key);
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
set(key, value) {
|
|
59
|
-
this.map.delete(key);
|
|
60
|
-
this.map.set(key, { value, storedAt: this.now() });
|
|
61
|
-
while (this.map.size > this.max) {
|
|
62
|
-
const coldest = this.map.keys().next().value;
|
|
63
|
-
if (coldest === void 0) break;
|
|
64
|
-
this.map.delete(coldest);
|
|
65
|
-
this.evictions += 1;
|
|
66
|
-
}
|
|
67
|
-
return this;
|
|
68
|
-
}
|
|
69
|
-
delete(key) {
|
|
70
|
-
return this.map.delete(key);
|
|
71
|
-
}
|
|
72
|
-
clear() {
|
|
73
|
-
this.map.clear();
|
|
74
|
-
this.evictions = 0;
|
|
75
|
-
}
|
|
76
|
-
get size() {
|
|
77
|
-
return this.map.size;
|
|
78
|
-
}
|
|
79
|
-
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
80
|
-
get evictionCount() {
|
|
81
|
-
return this.evictions;
|
|
82
|
-
}
|
|
83
|
-
/** Drop every expired entry. Cheap enough to call from a status tool. */
|
|
84
|
-
prune() {
|
|
85
|
-
if (this.ttlMs === void 0) return 0;
|
|
86
|
-
let removed = 0;
|
|
87
|
-
for (const [key, entry] of this.map) {
|
|
88
|
-
if (this.expired(entry)) {
|
|
89
|
-
this.map.delete(key);
|
|
90
|
-
removed += 1;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return removed;
|
|
94
|
-
}
|
|
95
|
-
/** Live (non-expired) entries, coldest first. */
|
|
96
|
-
*entries() {
|
|
97
|
-
for (const [key, entry] of this.map) {
|
|
98
|
-
if (!this.expired(entry)) yield [key, entry.value];
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
[Symbol.iterator]() {
|
|
102
|
-
return this.entries();
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// src/runtime/handles.ts
|
|
107
|
-
function releaseHandle(off) {
|
|
108
|
-
if (off) {
|
|
109
|
-
try {
|
|
110
|
-
off();
|
|
111
|
-
} catch {
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
23
|
// src/runtime/index.ts
|
|
118
|
-
var
|
|
24
|
+
var runtime_exports = {};
|
|
25
|
+
__reExport(runtime_exports, runtime_star);
|
|
26
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
119
27
|
|
|
120
28
|
// src/lint-gate/index.ts
|
|
121
29
|
var API_VERSION = "^0.1.10";
|
|
@@ -155,7 +63,7 @@ var LINTER_PACKAGES = {
|
|
|
155
63
|
biome: "@biomejs/biome",
|
|
156
64
|
eslint: "eslint"
|
|
157
65
|
};
|
|
158
|
-
var linterCache = new BoundedMap({ max: 32, ttlMs: 3e5 });
|
|
66
|
+
var linterCache = new runtime_exports.BoundedMap({ max: 32, ttlMs: 3e5 });
|
|
159
67
|
function isInside(parent, candidate) {
|
|
160
68
|
const rel = relative(parent, candidate);
|
|
161
69
|
return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel);
|
|
@@ -344,7 +252,7 @@ var plugin = {
|
|
|
344
252
|
state.hitCount = 0;
|
|
345
253
|
state.fixCount = 0;
|
|
346
254
|
state.linterErrorCount = 0;
|
|
347
|
-
state.hookUnregister = releaseHandle(state.hookUnregister);
|
|
255
|
+
state.hookUnregister = (0, runtime_exports.releaseHandle)(state.hookUnregister);
|
|
348
256
|
state.lastResult = null;
|
|
349
257
|
linterCache.clear();
|
|
350
258
|
const cfg = readConfig(api.config.extensions?.["lint-gate"]);
|
|
@@ -1,124 +1,32 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/migration-planner/index.ts
|
|
2
16
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
17
|
|
|
4
18
|
// src/runtime/index.ts
|
|
5
|
-
|
|
19
|
+
var runtime_exports = {};
|
|
20
|
+
__reExport(runtime_exports, runtime_star);
|
|
21
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
6
22
|
|
|
7
23
|
// src/runtime/llm.ts
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const candidate = stripOuterMarkdownFence(text);
|
|
15
|
-
try {
|
|
16
|
-
const parsed = JSON.parse(candidate);
|
|
17
|
-
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
18
|
-
} catch {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
async function runOptionalPluginLlm(request) {
|
|
23
|
-
if (!request.requested) {
|
|
24
|
-
return { used: false, value: null, fallbackReason: "not-requested" };
|
|
25
|
-
}
|
|
26
|
-
if (!request.api.llm) {
|
|
27
|
-
return { used: false, value: null, fallbackReason: "unavailable" };
|
|
28
|
-
}
|
|
29
|
-
if (request.options?.signal?.aborted) {
|
|
30
|
-
return { used: false, value: null, fallbackReason: "cancelled" };
|
|
31
|
-
}
|
|
32
|
-
try {
|
|
33
|
-
const response = await request.api.llm.complete(request.prompt, request.options);
|
|
34
|
-
const parsed = request.parse(response.text);
|
|
35
|
-
if (parsed === null) {
|
|
36
|
-
request.api.log.warn(`${request.label}: ignored invalid LLM response`);
|
|
37
|
-
return { used: false, value: null, fallbackReason: "invalid-response" };
|
|
38
|
-
}
|
|
39
|
-
return { used: true, value: parsed, fallbackReason: null };
|
|
40
|
-
} catch (error) {
|
|
41
|
-
const cancelled = request.options?.signal?.aborted === true;
|
|
42
|
-
request.api.log.warn(`${request.label}: LLM enrichment failed; using deterministic fallback`, {
|
|
43
|
-
error: error instanceof Error ? error.message : String(error)
|
|
44
|
-
});
|
|
45
|
-
return {
|
|
46
|
-
used: false,
|
|
47
|
-
value: null,
|
|
48
|
-
fallbackReason: cancelled ? "cancelled" : "provider-error"
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
async function runOptionalPluginCouncil(request) {
|
|
53
|
-
if (!request.requested) {
|
|
54
|
-
return { used: false, value: null, fallbackReason: "not-requested" };
|
|
55
|
-
}
|
|
56
|
-
if (request.options?.signal?.aborted) {
|
|
57
|
-
return { used: false, value: null, fallbackReason: "cancelled" };
|
|
58
|
-
}
|
|
59
|
-
const council = request.api.llm?.council;
|
|
60
|
-
if (council) {
|
|
61
|
-
try {
|
|
62
|
-
const result = await council(request.prompt, {
|
|
63
|
-
...request.context ? { context: request.context } : {},
|
|
64
|
-
...request.profile ? { profile: request.profile } : {},
|
|
65
|
-
...request.councilOptions ? { options: request.councilOptions } : {},
|
|
66
|
-
...request.options?.signal ? { signal: request.options.signal } : {}
|
|
67
|
-
});
|
|
68
|
-
if (result.status === "cancelled") {
|
|
69
|
-
return { used: false, value: null, fallbackReason: "cancelled" };
|
|
70
|
-
}
|
|
71
|
-
const parsed = result.status === "decided" ? request.parse(result.answer ?? "") : null;
|
|
72
|
-
if (parsed !== null) return { used: true, value: parsed, fallbackReason: null };
|
|
73
|
-
request.api.log.warn(
|
|
74
|
-
`${request.label}: Council did not return a valid answer; trying One Shot`,
|
|
75
|
-
{
|
|
76
|
-
status: result.status,
|
|
77
|
-
resolution: result.resolution
|
|
78
|
-
}
|
|
79
|
-
);
|
|
80
|
-
} catch (error) {
|
|
81
|
-
if (request.options?.signal?.aborted) {
|
|
82
|
-
return { used: false, value: null, fallbackReason: "cancelled" };
|
|
83
|
-
}
|
|
84
|
-
request.api.log.warn(`${request.label}: Council failed; trying One Shot`, {
|
|
85
|
-
error: error instanceof Error ? error.message : String(error)
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return runOptionalPluginLlm(request);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// src/runtime/local-bin.ts
|
|
93
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
94
|
-
|
|
95
|
-
// src/runtime/handles.ts
|
|
96
|
-
function releaseHandle(off) {
|
|
97
|
-
if (off) {
|
|
98
|
-
try {
|
|
99
|
-
off();
|
|
100
|
-
} catch {
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// src/runtime/index.ts
|
|
107
|
-
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
108
|
-
function hasLeadingDash(arg) {
|
|
109
|
-
return arg.length > 0 && arg.startsWith("-");
|
|
110
|
-
}
|
|
111
|
-
function withinProjectPath(projectRoot, candidate) {
|
|
112
|
-
if (candidate.length === 0 || candidate.length > 4096) return false;
|
|
113
|
-
if (hasLeadingDash(candidate)) return false;
|
|
114
|
-
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
|
|
115
|
-
const rel = relative(projectRoot, resolved);
|
|
116
|
-
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
117
|
-
}
|
|
118
|
-
function withinProject(p) {
|
|
119
|
-
const cwd = process.cwd();
|
|
120
|
-
return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
|
|
121
|
-
}
|
|
24
|
+
import {
|
|
25
|
+
parseLlmJsonObject,
|
|
26
|
+
runOptionalPluginCouncil,
|
|
27
|
+
runOptionalPluginLlm,
|
|
28
|
+
stripOuterMarkdownFence
|
|
29
|
+
} from "@wrongstack/plugin-sdk/runtime";
|
|
122
30
|
|
|
123
31
|
// src/migration-planner/index.ts
|
|
124
32
|
var API_VERSION = "^0.1.10";
|
|
@@ -157,7 +65,7 @@ function readChangelog(packageName, cfg) {
|
|
|
157
65
|
candidates.push(`node_modules/${packageName}/CHANGELOG.md`);
|
|
158
66
|
candidates.push(`node_modules/${packageName}/changelog.md`);
|
|
159
67
|
for (const candidate of candidates) {
|
|
160
|
-
if (!withinProject(candidate)) continue;
|
|
68
|
+
if (!(0, runtime_exports.withinProject)(candidate)) continue;
|
|
161
69
|
if (existsSync(candidate)) {
|
|
162
70
|
try {
|
|
163
71
|
const content = readFileSync(candidate, "utf-8");
|
|
@@ -368,7 +276,7 @@ var plugin = {
|
|
|
368
276
|
state.llmAnalysisCount = 0;
|
|
369
277
|
state.llmFallbackCount = 0;
|
|
370
278
|
state.lastPlan = null;
|
|
371
|
-
state.hookUnregister = releaseHandle(state.hookUnregister);
|
|
279
|
+
state.hookUnregister = (0, runtime_exports.releaseHandle)(state.hookUnregister);
|
|
372
280
|
const cfg = readConfig(api.config.extensions?.["migration-planner"]);
|
|
373
281
|
const hook = (input) => {
|
|
374
282
|
if (!cfg.enabled) return;
|
|
@@ -376,14 +284,14 @@ var plugin = {
|
|
|
376
284
|
const inp = input.toolInput ?? {};
|
|
377
285
|
const path = inp["path"];
|
|
378
286
|
if (!path) return;
|
|
379
|
-
const
|
|
287
|
+
const basename = path.split(/[/\\]/).pop() ?? "";
|
|
380
288
|
if (!/^(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?)$/i.test(
|
|
381
|
-
|
|
289
|
+
basename
|
|
382
290
|
)) {
|
|
383
291
|
return;
|
|
384
292
|
}
|
|
385
293
|
return {
|
|
386
|
-
additionalContext: `Manifest file ${
|
|
294
|
+
additionalContext: `Manifest file ${basename} changed. Consider running migration_plan if a dependency version was updated.`
|
|
387
295
|
};
|
|
388
296
|
};
|
|
389
297
|
state.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, {
|
package/dist/notify-hub.js
CHANGED
|
@@ -1,34 +1,24 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
|
|
1
15
|
// src/notify-hub/index.ts
|
|
2
16
|
import { lookup } from "node:dns/promises";
|
|
3
17
|
|
|
4
|
-
// src/runtime/local-bin.ts
|
|
5
|
-
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
6
|
-
|
|
7
|
-
// src/runtime/safe-json.ts
|
|
8
|
-
var UNSERIALIZABLE = "[unserializable]";
|
|
9
|
-
function safeJsonStringify(value, indent) {
|
|
10
|
-
try {
|
|
11
|
-
const stack = [];
|
|
12
|
-
const out = JSON.stringify(
|
|
13
|
-
value,
|
|
14
|
-
function replacer(_key, val) {
|
|
15
|
-
if (typeof val === "bigint") return `${val.toString()}n`;
|
|
16
|
-
if (val === null || typeof val !== "object") return val;
|
|
17
|
-
while (stack.length > 0 && stack[stack.length - 1] !== this) stack.pop();
|
|
18
|
-
if (stack.includes(val)) return "[circular]";
|
|
19
|
-
stack.push(val);
|
|
20
|
-
return val;
|
|
21
|
-
},
|
|
22
|
-
indent
|
|
23
|
-
);
|
|
24
|
-
return out ?? String(value);
|
|
25
|
-
} catch {
|
|
26
|
-
return UNSERIALIZABLE;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
18
|
// src/runtime/index.ts
|
|
31
|
-
var
|
|
19
|
+
var runtime_exports = {};
|
|
20
|
+
__reExport(runtime_exports, runtime_star);
|
|
21
|
+
import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
|
|
32
22
|
|
|
33
23
|
// src/notify-hub/webhook-channel.ts
|
|
34
24
|
function freshCircuit() {
|
|
@@ -231,7 +221,7 @@ async function deliver(event, payload) {
|
|
|
231
221
|
}
|
|
232
222
|
const result = await deliverViaChannel(ch, event, {
|
|
233
223
|
title: typeof payload.title === "string" ? payload.title : event,
|
|
234
|
-
body: typeof payload.message === "string" ? payload.message : typeof payload.error === "string" ? payload.error : safeJsonStringify(payload),
|
|
224
|
+
body: typeof payload.message === "string" ? payload.message : typeof payload.error === "string" ? payload.error : (0, runtime_exports.safeJsonStringify)(payload),
|
|
235
225
|
level: event === "tool.error" || event === "budget.threshold" ? "warning" : "info",
|
|
236
226
|
source: event,
|
|
237
227
|
metadata: payload
|