@wrongstack/plugins 1.0.8 → 1.0.10
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/index.d.ts +1 -1
- package/dist/accessibility-auditor.js +15 -3
- package/dist/agent-handoff.js +6 -6
- package/dist/auto-doc/index.d.ts +1 -1
- package/dist/auto-doc.js +31 -20
- package/dist/auto-i18n-extractor/index.d.ts +1 -1
- package/dist/auto-i18n-extractor.js +12 -8
- package/dist/branch-guard.js +3 -3
- package/dist/changelog-writer/index.d.ts +1 -1
- package/dist/changelog-writer.js +19 -10
- package/dist/checkpoint/index.d.ts +1 -1
- package/dist/checkpoint.js +38 -24
- package/dist/code-metrics/index.d.ts +1 -1
- package/dist/code-metrics.js +12 -4
- package/dist/commit-validator.js +5 -5
- package/dist/context-pins/index.d.ts +1 -1
- package/dist/context-pins.js +12 -9
- package/dist/cost-tracker.js +21 -9
- package/dist/cron/index.d.ts +1 -1
- package/dist/cron.js +18 -5
- package/dist/dead-code-detector/index.d.ts +1 -1
- package/dist/dead-code-detector.js +14 -12
- package/dist/duplicate-code-detector/index.d.ts +1 -1
- package/dist/duplicate-code-detector.js +11 -3
- package/dist/feature-flag-tracker/index.d.ts +1 -1
- package/dist/feature-flag-tracker.js +12 -4
- package/dist/file-watcher/index.d.ts +1 -1
- package/dist/file-watcher.js +37 -38
- package/dist/git-autocommit/index.d.ts +1 -1
- package/dist/git-autocommit.js +44 -39
- package/dist/gitignore-guard/index.d.ts +1 -1
- package/dist/gitignore-guard.js +12 -6
- package/dist/index.js +1534 -1080
- package/dist/interface-contract-guard/index.d.ts +1 -1
- package/dist/interface-contract-guard.js +12 -4
- package/dist/knowledge-graph/index.d.ts +1 -1
- package/dist/knowledge-graph.js +11 -9
- package/dist/migration-planner/index.d.ts +1 -1
- package/dist/migration-planner.js +6 -2
- package/dist/notify-hub/index.d.ts +1 -1
- package/dist/notify-hub.js +12 -11
- package/dist/performance-regression-gate/index.d.ts +1 -1
- package/dist/performance-regression-gate.js +33 -13
- package/dist/pr-drafter/index.d.ts +10 -1
- package/dist/pr-drafter.js +57 -26
- package/dist/refactor-suggester/index.d.ts +1 -1
- package/dist/refactor-suggester.js +17 -4
- package/dist/release-notes-generator.js +2 -2
- package/dist/secret-scanner/index.d.ts +1 -1
- package/dist/secret-scanner.js +11 -3
- package/dist/security-hotspot-scanner/index.d.ts +1 -1
- package/dist/security-hotspot-scanner.js +6 -2
- package/dist/semantic-search-indexer/index.d.ts +1 -1
- package/dist/semantic-search-indexer.js +19 -3
- package/dist/semver-bump/index.d.ts +1 -1
- package/dist/semver-bump.js +57 -37
- package/dist/session-recap.js +4 -2
- package/dist/shell-check/index.d.ts +1 -1
- package/dist/shell-check.js +30 -39
- package/dist/smart-rename/index.d.ts +1 -1
- package/dist/smart-rename.js +23 -10
- package/dist/template-engine/index.d.ts +1 -1
- package/dist/template-engine.js +51 -38
- package/dist/test-flake-detector/index.d.ts +1 -1
- package/dist/test-flake-detector.js +11 -5
- package/dist/test-generator/index.d.ts +1 -1
- package/dist/test-generator.js +12 -8
- package/dist/todo-tracker/index.d.ts +68 -1
- package/dist/todo-tracker.js +579 -395
- package/dist/token-budget.js +7 -4
- package/dist/token-throttle.js +6 -3
- package/package.json +7 -7
|
@@ -17,6 +17,7 @@ import { execFile } from "node:child_process";
|
|
|
17
17
|
import { readFileSync } from "node:fs";
|
|
18
18
|
import { createRequire } from "node:module";
|
|
19
19
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
20
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
20
21
|
|
|
21
22
|
// src/runtime/index.ts
|
|
22
23
|
var runtime_exports = {};
|
|
@@ -274,7 +275,7 @@ var plugin = {
|
|
|
274
275
|
mutating: false,
|
|
275
276
|
async execute(input) {
|
|
276
277
|
if (!cfg.enabled) {
|
|
277
|
-
|
|
278
|
+
throw new Error("test-flake-detector is disabled");
|
|
278
279
|
}
|
|
279
280
|
const raw = input;
|
|
280
281
|
const rawPattern = input.testPattern ?? raw["pattern"] ?? raw["path"] ?? raw["file"] ?? raw["filePath"] ?? raw["TargetFile"] ?? raw["targetFile"];
|
|
@@ -285,10 +286,10 @@ var plugin = {
|
|
|
285
286
|
const requestedRuns = typeof rawRuns === "number" && rawRuns >= 1 ? Math.min(Math.floor(rawRuns), cfg.maxRuns) : 5;
|
|
286
287
|
const command = resolveTestCommand(commandString, testPattern);
|
|
287
288
|
if (!command) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
};
|
|
289
|
+
throw new ToolValidationError({
|
|
290
|
+
message: "Unsupported test command or unsafe testPattern. Use vitest, jest, or mocha through a supported package runner, and keep patterns inside the project.",
|
|
291
|
+
field: "command"
|
|
292
|
+
});
|
|
292
293
|
}
|
|
293
294
|
state.invocationCount += 1;
|
|
294
295
|
const start = Date.now();
|
|
@@ -316,6 +317,11 @@ var plugin = {
|
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
const all = Array.from(records.values());
|
|
320
|
+
if (all.length === 0 && runErrors.length === requestedRuns) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
`test command produced no test results in ${requestedRuns} run(s): ${runErrors.slice(0, 3).join("; ")}`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
319
325
|
const flakyTests = all.filter((r) => r.passCount > 0 && r.failCount > 0);
|
|
320
326
|
const alwaysFailing = all.filter((r) => r.passCount === 0 && r.failCount > 0);
|
|
321
327
|
const alwaysPassing = all.filter((r) => r.passCount > 0 && r.failCount === 0);
|
package/dist/test-generator.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/test-generator/index.ts
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
4
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
4
5
|
|
|
5
6
|
// src/runtime/llm.ts
|
|
6
7
|
import {
|
|
@@ -299,7 +300,7 @@ var plugin = {
|
|
|
299
300
|
category: "Development",
|
|
300
301
|
mutating: false,
|
|
301
302
|
async execute(input, _ctx, execOpts) {
|
|
302
|
-
if (!cfg.enabled)
|
|
303
|
+
if (!cfg.enabled) throw new Error("test-generator is disabled");
|
|
303
304
|
execOpts?.signal?.throwIfAborted();
|
|
304
305
|
const inp = input ?? {};
|
|
305
306
|
const rawFramework = inp["framework"];
|
|
@@ -310,16 +311,19 @@ var plugin = {
|
|
|
310
311
|
};
|
|
311
312
|
const rawPath = inp["path"] ?? inp["filePath"] ?? inp["file_path"] ?? inp["TargetFile"] ?? inp["targetFile"] ?? inp["file"];
|
|
312
313
|
if (!rawPath || typeof rawPath !== "string") {
|
|
313
|
-
|
|
314
|
+
throw new ToolValidationError({ message: "path is required", field: "path" });
|
|
314
315
|
}
|
|
315
316
|
if (!withinProject(rawPath)) {
|
|
316
|
-
|
|
317
|
+
throw new ToolValidationError({
|
|
318
|
+
message: "path is outside the project root",
|
|
319
|
+
field: "path"
|
|
320
|
+
});
|
|
317
321
|
}
|
|
318
322
|
if (!SOURCE_EXTENSIONS.some((ext) => rawPath.toLowerCase().endsWith(ext))) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
};
|
|
323
|
+
throw new ToolValidationError({
|
|
324
|
+
message: `test generation only reads source files (${SOURCE_EXTENSIONS.join(", ")}); refusing "${rawPath}"`,
|
|
325
|
+
field: "path"
|
|
326
|
+
});
|
|
323
327
|
}
|
|
324
328
|
const resolved = resolve(process.cwd(), rawPath);
|
|
325
329
|
state.generateCount += 1;
|
|
@@ -328,7 +332,7 @@ var plugin = {
|
|
|
328
332
|
result = generateForFile(resolved, effectiveCfg);
|
|
329
333
|
} catch (err) {
|
|
330
334
|
state.errorCount += 1;
|
|
331
|
-
|
|
335
|
+
throw new Error(`Could not read ${rawPath}: ${String(err)}`, { cause: err });
|
|
332
336
|
}
|
|
333
337
|
state.exportCount += result.exports.length;
|
|
334
338
|
const raw = input ?? {};
|
|
@@ -26,8 +26,75 @@
|
|
|
26
26
|
* into the session's ctx.todos via the
|
|
27
27
|
* built-in `todo` tool
|
|
28
28
|
* - todo_tracker_status : Counters + last update timestamp
|
|
29
|
+
*
|
|
30
|
+
* Durability contract (the file is the source of truth, memory is a cache):
|
|
31
|
+
* - A file that cannot be parsed or validated is QUARANTINED (renamed to
|
|
32
|
+
* `<file>.corrupt-<timestamp>`), never silently overwritten. If the
|
|
33
|
+
* rename fails the store goes read-only.
|
|
34
|
+
* - A file written by a newer format version is never written to.
|
|
35
|
+
* - Every mutation runs under the shared file lock, re-reads the file,
|
|
36
|
+
* applies the change to a clone, writes atomically, and only then
|
|
37
|
+
* updates memory. Two sessions on one project therefore merge instead of
|
|
38
|
+
* erasing each other, and a failed write leaves memory and disk unchanged.
|
|
39
|
+
* - Read tools re-read the file so another process's changes are visible.
|
|
40
|
+
*/
|
|
41
|
+
import { type Plugin } from '@wrongstack/core/types';
|
|
42
|
+
type Status = 'pending' | 'in_progress' | 'completed' | 'dropped';
|
|
43
|
+
type Priority = 'low' | 'normal' | 'high';
|
|
44
|
+
interface TrackedItem {
|
|
45
|
+
id: string;
|
|
46
|
+
content: string;
|
|
47
|
+
status: Status;
|
|
48
|
+
priority: Priority;
|
|
49
|
+
tags: string[];
|
|
50
|
+
createdAt: string;
|
|
51
|
+
updatedAt: string;
|
|
52
|
+
completedAt: string | null;
|
|
53
|
+
/** Session that first created the item (if known). */
|
|
54
|
+
sourceSessionId: string | null;
|
|
55
|
+
/** Optional free-form note attached to the item. */
|
|
56
|
+
notes: string | null;
|
|
57
|
+
}
|
|
58
|
+
interface TodoTrackerFile {
|
|
59
|
+
version: 1;
|
|
60
|
+
projectSlug: string;
|
|
61
|
+
updatedAt: string;
|
|
62
|
+
items: TrackedItem[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Filesystem/persistence seam. Production uses the real primitives; tests
|
|
66
|
+
* inject faults here instead of module-mocking `@wrongstack/core/utils`
|
|
67
|
+
* (which is flaky under parallel vitest — see context-pins-extra.test.ts).
|
|
29
68
|
*/
|
|
30
|
-
|
|
69
|
+
export interface TodoTrackerDeps {
|
|
70
|
+
readFile(path: string): Promise<string>;
|
|
71
|
+
rename(from: string, to: string): Promise<void>;
|
|
72
|
+
atomicWrite(path: string, content: string, opts?: {
|
|
73
|
+
mode?: number;
|
|
74
|
+
}): Promise<void>;
|
|
75
|
+
withFileLock<T>(path: string, fn: () => Promise<T>): Promise<T>;
|
|
76
|
+
ensureDir(dir: string): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
/** Basename without its extension; dotfiles like `.todos` keep their name. */
|
|
79
|
+
export declare function deriveProjectSlug(filePath: string): string;
|
|
80
|
+
type LoadResult = {
|
|
81
|
+
kind: 'missing';
|
|
82
|
+
} | {
|
|
83
|
+
kind: 'ok';
|
|
84
|
+
file: TodoTrackerFile;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'corrupt';
|
|
87
|
+
reason: string;
|
|
88
|
+
} | {
|
|
89
|
+
kind: 'unsupportedVersion';
|
|
90
|
+
version: unknown;
|
|
91
|
+
} | {
|
|
92
|
+
kind: 'invalidItems';
|
|
93
|
+
reason: string;
|
|
94
|
+
};
|
|
95
|
+
/** Pure classification of raw file bytes. Exported for tests. */
|
|
96
|
+
export declare function parseTrackerFile(rawText: string): LoadResult;
|
|
97
|
+
export declare function createTodoTrackerPlugin(overrides?: Partial<TodoTrackerDeps>): Plugin;
|
|
31
98
|
declare const plugin: Plugin;
|
|
32
99
|
export default plugin;
|
|
33
100
|
//# sourceMappingURL=index.d.ts.map
|