@wrongstack/plugins 1.0.7 → 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.
Files changed (72) hide show
  1. package/dist/accessibility-auditor/index.d.ts +1 -1
  2. package/dist/accessibility-auditor.js +15 -3
  3. package/dist/agent-handoff.js +6 -6
  4. package/dist/auto-doc/index.d.ts +1 -1
  5. package/dist/auto-doc.js +31 -20
  6. package/dist/auto-i18n-extractor/index.d.ts +1 -1
  7. package/dist/auto-i18n-extractor.js +12 -8
  8. package/dist/branch-guard.js +3 -3
  9. package/dist/changelog-writer/index.d.ts +1 -1
  10. package/dist/changelog-writer.js +19 -10
  11. package/dist/checkpoint/index.d.ts +1 -1
  12. package/dist/checkpoint.js +38 -24
  13. package/dist/code-metrics/index.d.ts +1 -1
  14. package/dist/code-metrics.js +12 -4
  15. package/dist/commit-validator.js +5 -5
  16. package/dist/context-pins/index.d.ts +1 -1
  17. package/dist/context-pins.js +12 -9
  18. package/dist/cost-tracker.js +21 -9
  19. package/dist/cron/index.d.ts +1 -1
  20. package/dist/cron.js +18 -5
  21. package/dist/dead-code-detector/index.d.ts +1 -1
  22. package/dist/dead-code-detector.js +14 -12
  23. package/dist/duplicate-code-detector/index.d.ts +1 -1
  24. package/dist/duplicate-code-detector.js +11 -3
  25. package/dist/feature-flag-tracker/index.d.ts +1 -1
  26. package/dist/feature-flag-tracker.js +12 -4
  27. package/dist/file-watcher/index.d.ts +1 -1
  28. package/dist/file-watcher.js +37 -38
  29. package/dist/git-autocommit/index.d.ts +1 -1
  30. package/dist/git-autocommit.js +44 -39
  31. package/dist/gitignore-guard/index.d.ts +1 -1
  32. package/dist/gitignore-guard.js +12 -6
  33. package/dist/index.js +1534 -1080
  34. package/dist/interface-contract-guard/index.d.ts +1 -1
  35. package/dist/interface-contract-guard.js +12 -4
  36. package/dist/knowledge-graph/index.d.ts +1 -1
  37. package/dist/knowledge-graph.js +11 -9
  38. package/dist/migration-planner/index.d.ts +1 -1
  39. package/dist/migration-planner.js +6 -2
  40. package/dist/notify-hub/index.d.ts +1 -1
  41. package/dist/notify-hub.js +12 -11
  42. package/dist/performance-regression-gate/index.d.ts +1 -1
  43. package/dist/performance-regression-gate.js +33 -13
  44. package/dist/pr-drafter/index.d.ts +10 -1
  45. package/dist/pr-drafter.js +57 -26
  46. package/dist/refactor-suggester/index.d.ts +1 -1
  47. package/dist/refactor-suggester.js +17 -4
  48. package/dist/release-notes-generator.js +2 -2
  49. package/dist/secret-scanner/index.d.ts +1 -1
  50. package/dist/secret-scanner.js +11 -3
  51. package/dist/security-hotspot-scanner/index.d.ts +1 -1
  52. package/dist/security-hotspot-scanner.js +6 -2
  53. package/dist/semantic-search-indexer/index.d.ts +1 -1
  54. package/dist/semantic-search-indexer.js +19 -3
  55. package/dist/semver-bump/index.d.ts +1 -1
  56. package/dist/semver-bump.js +57 -37
  57. package/dist/session-recap.js +4 -2
  58. package/dist/shell-check/index.d.ts +1 -1
  59. package/dist/shell-check.js +30 -39
  60. package/dist/smart-rename/index.d.ts +1 -1
  61. package/dist/smart-rename.js +23 -10
  62. package/dist/template-engine/index.d.ts +1 -1
  63. package/dist/template-engine.js +51 -38
  64. package/dist/test-flake-detector/index.d.ts +1 -1
  65. package/dist/test-flake-detector.js +11 -5
  66. package/dist/test-generator/index.d.ts +1 -1
  67. package/dist/test-generator.js +12 -8
  68. package/dist/todo-tracker/index.d.ts +68 -1
  69. package/dist/todo-tracker.js +579 -395
  70. package/dist/token-budget.js +7 -4
  71. package/dist/token-throttle.js +6 -3
  72. package/package.json +7 -7
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * @public
21
21
  */
22
- import type { Plugin } from '@wrongstack/core/types';
22
+ import { type Plugin } from '@wrongstack/core/types';
23
23
  declare const plugin: Plugin;
24
24
  export default plugin;
25
25
  //# sourceMappingURL=index.d.ts.map
@@ -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
- return { ok: false, error: "test-flake-detector is disabled" };
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
- return {
289
- ok: false,
290
- error: "Unsupported test command or unsafe testPattern. Use vitest, jest, or mocha through a supported package runner, and keep patterns inside the project."
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);
@@ -22,7 +22,7 @@
22
22
  *
23
23
  * @public
24
24
  */
25
- import type { Plugin } from '@wrongstack/core/types';
25
+ import { type Plugin } from '@wrongstack/core/types';
26
26
  interface TestGeneratorConfig {
27
27
  enabled: boolean;
28
28
  framework: TestFramework;
@@ -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) return { ok: false, error: "test-generator is disabled" };
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
- return { ok: false, error: "path is required" };
314
+ throw new ToolValidationError({ message: "path is required", field: "path" });
314
315
  }
315
316
  if (!withinProject(rawPath)) {
316
- return { ok: false, error: "path is outside the project root" };
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
- return {
320
- ok: false,
321
- error: `test generation only reads source files (${SOURCE_EXTENSIONS.join(", ")}); refusing "${rawPath}"`
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
- return { ok: false, error: String(err) };
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
- import type { Plugin } from '@wrongstack/core/types';
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