@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/branch-guard.js
CHANGED
|
@@ -1,5 +1,107 @@
|
|
|
1
1
|
// src/branch-guard/index.ts
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
|
+
|
|
4
|
+
// src/runtime/local-bin.ts
|
|
5
|
+
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
6
|
+
|
|
7
|
+
// src/runtime/bounded-map.ts
|
|
8
|
+
var BoundedMap = class {
|
|
9
|
+
map = /* @__PURE__ */ new Map();
|
|
10
|
+
max;
|
|
11
|
+
ttlMs;
|
|
12
|
+
now;
|
|
13
|
+
/** Entries dropped to stay under `max`. Surfaced by plugin health(). */
|
|
14
|
+
evictions = 0;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
const normalizedMax = Math.floor(options.max);
|
|
17
|
+
this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
|
|
18
|
+
this.ttlMs = options.ttlMs;
|
|
19
|
+
this.now = options.now ?? Date.now;
|
|
20
|
+
}
|
|
21
|
+
expired(entry) {
|
|
22
|
+
return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
|
|
23
|
+
}
|
|
24
|
+
get(key) {
|
|
25
|
+
const entry = this.map.get(key);
|
|
26
|
+
if (entry === void 0) return void 0;
|
|
27
|
+
if (this.expired(entry)) {
|
|
28
|
+
this.map.delete(key);
|
|
29
|
+
return void 0;
|
|
30
|
+
}
|
|
31
|
+
this.map.delete(key);
|
|
32
|
+
this.map.set(key, entry);
|
|
33
|
+
return entry.value;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Read without promoting the key to most-recently-used. Use for
|
|
37
|
+
* diagnostics that must not perturb the eviction order.
|
|
38
|
+
*/
|
|
39
|
+
peek(key) {
|
|
40
|
+
const entry = this.map.get(key);
|
|
41
|
+
if (entry === void 0 || this.expired(entry)) return void 0;
|
|
42
|
+
return entry.value;
|
|
43
|
+
}
|
|
44
|
+
has(key) {
|
|
45
|
+
const entry = this.map.get(key);
|
|
46
|
+
if (entry === void 0) return false;
|
|
47
|
+
if (this.expired(entry)) {
|
|
48
|
+
this.map.delete(key);
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
set(key, value) {
|
|
54
|
+
this.map.delete(key);
|
|
55
|
+
this.map.set(key, { value, storedAt: this.now() });
|
|
56
|
+
while (this.map.size > this.max) {
|
|
57
|
+
const coldest = this.map.keys().next().value;
|
|
58
|
+
if (coldest === void 0) break;
|
|
59
|
+
this.map.delete(coldest);
|
|
60
|
+
this.evictions += 1;
|
|
61
|
+
}
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
delete(key) {
|
|
65
|
+
return this.map.delete(key);
|
|
66
|
+
}
|
|
67
|
+
clear() {
|
|
68
|
+
this.map.clear();
|
|
69
|
+
this.evictions = 0;
|
|
70
|
+
}
|
|
71
|
+
get size() {
|
|
72
|
+
return this.map.size;
|
|
73
|
+
}
|
|
74
|
+
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
75
|
+
get evictionCount() {
|
|
76
|
+
return this.evictions;
|
|
77
|
+
}
|
|
78
|
+
/** Drop every expired entry. Cheap enough to call from a status tool. */
|
|
79
|
+
prune() {
|
|
80
|
+
if (this.ttlMs === void 0) return 0;
|
|
81
|
+
let removed = 0;
|
|
82
|
+
for (const [key, entry] of this.map) {
|
|
83
|
+
if (this.expired(entry)) {
|
|
84
|
+
this.map.delete(key);
|
|
85
|
+
removed += 1;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return removed;
|
|
89
|
+
}
|
|
90
|
+
/** Live (non-expired) entries, coldest first. */
|
|
91
|
+
*entries() {
|
|
92
|
+
for (const [key, entry] of this.map) {
|
|
93
|
+
if (!this.expired(entry)) yield [key, entry.value];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
[Symbol.iterator]() {
|
|
97
|
+
return this.entries();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/runtime/index.ts
|
|
102
|
+
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
103
|
+
|
|
104
|
+
// src/branch-guard/index.ts
|
|
3
105
|
var API_VERSION = "^0.1.10";
|
|
4
106
|
var state = {
|
|
5
107
|
invocationCount: 0,
|
|
@@ -51,6 +153,7 @@ function hasDisabledPluginEntry(raw) {
|
|
|
51
153
|
return name === "branch-guard" || name === "@wrongstack/plugins/branch-guard";
|
|
52
154
|
});
|
|
53
155
|
}
|
|
156
|
+
var branchCache = new BoundedMap({ max: 64, ttlMs: 3e4 });
|
|
54
157
|
function runGit(args, cwd, signal) {
|
|
55
158
|
return new Promise((resolve, reject) => {
|
|
56
159
|
execFile(
|
|
@@ -65,11 +168,17 @@ function runGit(args, cwd, signal) {
|
|
|
65
168
|
});
|
|
66
169
|
}
|
|
67
170
|
async function getCurrentBranch(cwd, signal) {
|
|
171
|
+
const cacheKey = `${cwd ?? "undefined"}`;
|
|
172
|
+
const cached = branchCache.get(cacheKey);
|
|
173
|
+
if (cached !== void 0) return cached;
|
|
68
174
|
try {
|
|
69
175
|
const branch = (await runGit(["branch", "--show-current"], cwd, signal)).trim();
|
|
70
|
-
|
|
176
|
+
const result = branch || null;
|
|
177
|
+
branchCache.set(cacheKey, result);
|
|
178
|
+
return result;
|
|
71
179
|
} catch (err) {
|
|
72
180
|
if (signal.aborted) throw err;
|
|
181
|
+
branchCache.set(cacheKey, null);
|
|
73
182
|
return null;
|
|
74
183
|
}
|
|
75
184
|
}
|
|
@@ -157,6 +266,7 @@ var plugin = {
|
|
|
157
266
|
state.hookUnregister = null;
|
|
158
267
|
state.configUnregister = null;
|
|
159
268
|
state.lastBlock = null;
|
|
269
|
+
branchCache.clear();
|
|
160
270
|
let cfg = readHostConfig(api.config);
|
|
161
271
|
state.configUnregister = api.onConfigChange((next) => {
|
|
162
272
|
cfg = readHostConfig(next);
|
package/dist/catalog.d.ts
CHANGED
|
@@ -1,39 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* plugin references in markdown files.
|
|
5
|
-
*
|
|
6
|
-
* The catalog is built at module load time by importing each plugin
|
|
7
|
-
* source and reading its `name` field. This means the catalog is
|
|
8
|
-
* always in sync with the actual plugins — adding a new plugin
|
|
9
|
-
* (exporting it from `./index.ts` AND adding a row to the table
|
|
10
|
-
* below) is enough for `spec-linker` to start detecting references
|
|
11
|
-
* to it.
|
|
12
|
-
*
|
|
13
|
-
* To add a new plugin: see the table in `catalog.ts`. The `name`
|
|
14
|
-
* must match the plugin's `name` field; the `path` is the
|
|
15
|
-
* relative source directory under `packages/plugins/src/`.
|
|
16
|
-
*
|
|
17
|
-
* @public
|
|
2
|
+
* Catalog projections used by spec-linker and public discovery APIs.
|
|
3
|
+
* Plugin identity and source paths are owned by the typed manifest.
|
|
18
4
|
*/
|
|
19
|
-
import type { Plugin } from '@wrongstack/core';
|
|
20
|
-
interface CatalogEntry {
|
|
21
|
-
/** The plugin's `name` field. */
|
|
5
|
+
import type { Plugin } from '@wrongstack/core/types';
|
|
6
|
+
export interface CatalogEntry {
|
|
22
7
|
name: string;
|
|
23
|
-
/** Relative path under `packages/plugins/src/`, e.g. `./src/auto-doc`. */
|
|
24
8
|
path: string;
|
|
25
9
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Read-only view of the catalog as a Map from plugin name to its
|
|
28
|
-
* source path. Frozen so consumers cannot mutate it.
|
|
29
|
-
*/
|
|
30
|
-
export declare const PLUGIN_CATALOG: ReadonlyMap<string, string>;
|
|
31
|
-
/**
|
|
32
|
-
* The list of catalog entries, ordered by the table above. Used by
|
|
33
|
-
* `spec-linker` to iterate names in a stable order for detection.
|
|
34
|
-
*/
|
|
35
10
|
export declare const PLUGIN_CATALOG_ENTRIES: readonly CatalogEntry[];
|
|
36
|
-
|
|
11
|
+
export declare const PLUGIN_CATALOG: ReadonlyMap<string, string>;
|
|
37
12
|
export declare const PLUGIN_NAMES: readonly string[];
|
|
38
13
|
export type { Plugin };
|
|
39
14
|
//# sourceMappingURL=catalog.d.ts.map
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGrD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,sBAAsB,EAAE,SAAS,YAAY,EAIzD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAEtD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAEzC,CAAC;AAEF,YAAY,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
*
|
|
44
44
|
* @public
|
|
45
45
|
*/
|
|
46
|
-
import type { Plugin } from '@wrongstack/core';
|
|
46
|
+
import type { Plugin } from '@wrongstack/core/types';
|
|
47
47
|
type Section = 'Added' | 'Changed' | 'Fixed' | 'Removed' | 'Security' | 'Documentation' | 'Maintenance';
|
|
48
48
|
export interface ChangelogEntry {
|
|
49
49
|
section: Section;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/changelog-writer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/changelog-writer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAOrD,KAAK,OAAO,GACR,OAAO,GACP,SAAS,GACT,OAAO,GACP,SAAS,GACT,UAAU,GACV,eAAe,GACf,aAAa,CAAC;AAElB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAwGD,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAQjF;AAED,+EAA+E;AAC/E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE;AAeD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CAiBvE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBjF;AAMD,QAAA,MAAM,MAAM,EAAE,MAqRb,CAAC;eAEa,MAAM"}
|
package/dist/changelog-writer.js
CHANGED
|
@@ -1,9 +1,143 @@
|
|
|
1
1
|
// src/changelog-writer/index.ts
|
|
2
2
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
// src/runtime/local-bin.ts
|
|
6
|
+
import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
|
|
7
|
+
|
|
8
|
+
// src/runtime/bounded-map.ts
|
|
9
|
+
var BoundedMap = class {
|
|
10
|
+
map = /* @__PURE__ */ new Map();
|
|
11
|
+
max;
|
|
12
|
+
ttlMs;
|
|
13
|
+
now;
|
|
14
|
+
/** Entries dropped to stay under `max`. Surfaced by plugin health(). */
|
|
15
|
+
evictions = 0;
|
|
16
|
+
constructor(options) {
|
|
17
|
+
const normalizedMax = Math.floor(options.max);
|
|
18
|
+
this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
|
|
19
|
+
this.ttlMs = options.ttlMs;
|
|
20
|
+
this.now = options.now ?? Date.now;
|
|
21
|
+
}
|
|
22
|
+
expired(entry) {
|
|
23
|
+
return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
|
|
24
|
+
}
|
|
25
|
+
get(key) {
|
|
26
|
+
const entry = this.map.get(key);
|
|
27
|
+
if (entry === void 0) return void 0;
|
|
28
|
+
if (this.expired(entry)) {
|
|
29
|
+
this.map.delete(key);
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
this.map.delete(key);
|
|
33
|
+
this.map.set(key, entry);
|
|
34
|
+
return entry.value;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Read without promoting the key to most-recently-used. Use for
|
|
38
|
+
* diagnostics that must not perturb the eviction order.
|
|
39
|
+
*/
|
|
40
|
+
peek(key) {
|
|
41
|
+
const entry = this.map.get(key);
|
|
42
|
+
if (entry === void 0 || this.expired(entry)) return void 0;
|
|
43
|
+
return entry.value;
|
|
44
|
+
}
|
|
45
|
+
has(key) {
|
|
46
|
+
const entry = this.map.get(key);
|
|
47
|
+
if (entry === void 0) return false;
|
|
48
|
+
if (this.expired(entry)) {
|
|
49
|
+
this.map.delete(key);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
set(key, value) {
|
|
55
|
+
this.map.delete(key);
|
|
56
|
+
this.map.set(key, { value, storedAt: this.now() });
|
|
57
|
+
while (this.map.size > this.max) {
|
|
58
|
+
const coldest = this.map.keys().next().value;
|
|
59
|
+
if (coldest === void 0) break;
|
|
60
|
+
this.map.delete(coldest);
|
|
61
|
+
this.evictions += 1;
|
|
62
|
+
}
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
delete(key) {
|
|
66
|
+
return this.map.delete(key);
|
|
67
|
+
}
|
|
68
|
+
clear() {
|
|
69
|
+
this.map.clear();
|
|
70
|
+
this.evictions = 0;
|
|
71
|
+
}
|
|
72
|
+
get size() {
|
|
73
|
+
return this.map.size;
|
|
74
|
+
}
|
|
75
|
+
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
76
|
+
get evictionCount() {
|
|
77
|
+
return this.evictions;
|
|
78
|
+
}
|
|
79
|
+
/** Drop every expired entry. Cheap enough to call from a status tool. */
|
|
80
|
+
prune() {
|
|
81
|
+
if (this.ttlMs === void 0) return 0;
|
|
82
|
+
let removed = 0;
|
|
83
|
+
for (const [key, entry] of this.map) {
|
|
84
|
+
if (this.expired(entry)) {
|
|
85
|
+
this.map.delete(key);
|
|
86
|
+
removed += 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return removed;
|
|
90
|
+
}
|
|
91
|
+
/** Live (non-expired) entries, coldest first. */
|
|
92
|
+
*entries() {
|
|
93
|
+
for (const [key, entry] of this.map) {
|
|
94
|
+
if (!this.expired(entry)) yield [key, entry.value];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
[Symbol.iterator]() {
|
|
98
|
+
return this.entries();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var BoundedSet = class {
|
|
102
|
+
inner;
|
|
103
|
+
constructor(options) {
|
|
104
|
+
this.inner = new BoundedMap(options);
|
|
105
|
+
}
|
|
106
|
+
has(value) {
|
|
107
|
+
return this.inner.has(value);
|
|
108
|
+
}
|
|
109
|
+
add(value) {
|
|
110
|
+
this.inner.set(value, true);
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
delete(value) {
|
|
114
|
+
return this.inner.delete(value);
|
|
115
|
+
}
|
|
116
|
+
clear() {
|
|
117
|
+
this.inner.clear();
|
|
118
|
+
}
|
|
119
|
+
get size() {
|
|
120
|
+
return this.inner.size;
|
|
121
|
+
}
|
|
122
|
+
/** How many entries have been dropped to respect `max`, since the last clear. */
|
|
123
|
+
get evictionCount() {
|
|
124
|
+
return this.inner.evictionCount;
|
|
125
|
+
}
|
|
126
|
+
*values() {
|
|
127
|
+
for (const [key] of this.inner) yield key;
|
|
128
|
+
}
|
|
129
|
+
[Symbol.iterator]() {
|
|
130
|
+
return this.values();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// src/runtime/index.ts
|
|
135
|
+
var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
136
|
+
|
|
137
|
+
// src/changelog-writer/index.ts
|
|
4
138
|
var state = {
|
|
5
139
|
entries: [],
|
|
6
|
-
filesTouched:
|
|
140
|
+
filesTouched: new BoundedSet({ max: 2e3 }),
|
|
7
141
|
commitsSeen: 0,
|
|
8
142
|
writes: 0,
|
|
9
143
|
polishes: 0,
|
|
@@ -164,7 +298,7 @@ var plugin = {
|
|
|
164
298
|
},
|
|
165
299
|
setup(api) {
|
|
166
300
|
state.entries = [];
|
|
167
|
-
state.filesTouched =
|
|
301
|
+
state.filesTouched = new BoundedSet({ max: 2e3 });
|
|
168
302
|
state.commitsSeen = 0;
|
|
169
303
|
state.writes = 0;
|
|
170
304
|
for (const off of state.eventUnsubscribers) {
|
|
@@ -356,7 +490,7 @@ var plugin = {
|
|
|
356
490
|
filesTouched: state.filesTouched.size
|
|
357
491
|
};
|
|
358
492
|
state.entries = [];
|
|
359
|
-
state.filesTouched =
|
|
493
|
+
state.filesTouched = new BoundedSet({ max: 2e3 });
|
|
360
494
|
state.commitsSeen = 0;
|
|
361
495
|
state.writes = 0;
|
|
362
496
|
api.log.info("changelog-writer: teardown complete", { final });
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
*
|
|
36
36
|
* @public
|
|
37
37
|
*/
|
|
38
|
-
import type { Plugin } from '@wrongstack/core';
|
|
38
|
+
import type { Plugin } from '@wrongstack/core/types';
|
|
39
39
|
export interface Snapshot {
|
|
40
40
|
id: string;
|
|
41
41
|
createdAt: string;
|
|
@@ -48,6 +48,8 @@ export interface Snapshot {
|
|
|
48
48
|
bytes: number;
|
|
49
49
|
}>;
|
|
50
50
|
}
|
|
51
|
+
/** Retained bytes across all snapshots — surfaced by status/health(). */
|
|
52
|
+
export declare function retainedSnapshotBytes(): number;
|
|
51
53
|
declare const plugin: Plugin;
|
|
52
54
|
export default plugin;
|
|
53
55
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checkpoint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checkpoint/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAMrD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,iDAAiD;QACjD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAsID,yEAAyE;AACzE,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAuBD,QAAA,MAAM,MAAM,EAAE,MAmVb,CAAC;eAEa,MAAM"}
|
package/dist/checkpoint.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// src/checkpoint/index.ts
|
|
2
|
-
import {
|
|
3
|
-
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
4
3
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
5
4
|
var state = {
|
|
6
5
|
snapshots: [],
|
|
@@ -8,13 +7,15 @@ var state = {
|
|
|
8
7
|
captures: 0,
|
|
9
8
|
restores: 0,
|
|
10
9
|
skippedLarge: 0,
|
|
10
|
+
evictedForBytes: 0,
|
|
11
11
|
hookUnregister: null
|
|
12
12
|
};
|
|
13
13
|
var DEFAULTS = {
|
|
14
14
|
enabled: true,
|
|
15
15
|
autoCapture: true,
|
|
16
16
|
maxSnapshots: 50,
|
|
17
|
-
maxFileBytes: 1048576
|
|
17
|
+
maxFileBytes: 1048576,
|
|
18
|
+
maxTotalBytes: 64 * 1048576
|
|
18
19
|
};
|
|
19
20
|
function readConfig(raw) {
|
|
20
21
|
if (!raw || typeof raw !== "object") return { ...DEFAULTS };
|
|
@@ -23,6 +24,7 @@ function readConfig(raw) {
|
|
|
23
24
|
enabled: r["enabled"] !== false,
|
|
24
25
|
autoCapture: r["autoCapture"] !== false,
|
|
25
26
|
maxSnapshots: typeof r["maxSnapshots"] === "number" && r["maxSnapshots"] >= 1 && r["maxSnapshots"] <= 500 ? r["maxSnapshots"] : DEFAULTS.maxSnapshots,
|
|
27
|
+
maxTotalBytes: typeof r["maxTotalBytes"] === "number" && r["maxTotalBytes"] >= 1024 ? r["maxTotalBytes"] : DEFAULTS.maxTotalBytes,
|
|
26
28
|
maxFileBytes: typeof r["maxFileBytes"] === "number" && r["maxFileBytes"] >= 1024 ? r["maxFileBytes"] : DEFAULTS.maxFileBytes
|
|
27
29
|
};
|
|
28
30
|
}
|
|
@@ -41,11 +43,11 @@ function hashContent(s) {
|
|
|
41
43
|
}
|
|
42
44
|
return h >>> 0;
|
|
43
45
|
}
|
|
44
|
-
function captureFile(path, maxBytes) {
|
|
46
|
+
async function captureFile(path, maxBytes) {
|
|
45
47
|
try {
|
|
46
|
-
const st =
|
|
48
|
+
const st = await stat(path);
|
|
47
49
|
if (st.size > maxBytes) return "too-large";
|
|
48
|
-
const content =
|
|
50
|
+
const content = await readFile(path, "utf-8");
|
|
49
51
|
return { path, content, bytes: st.size };
|
|
50
52
|
} catch {
|
|
51
53
|
return { path, content: null, bytes: 0 };
|
|
@@ -64,11 +66,22 @@ async function captureFileForHook(path, maxBytes, signal) {
|
|
|
64
66
|
return { path, content: null, bytes: 0 };
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
|
-
function
|
|
69
|
+
function retainedSnapshotBytes() {
|
|
70
|
+
let total = 0;
|
|
71
|
+
for (const snap of state.snapshots) {
|
|
72
|
+
for (const f of snap.files) total += f.content === null ? 0 : f.content.length;
|
|
73
|
+
}
|
|
74
|
+
return total;
|
|
75
|
+
}
|
|
76
|
+
function pushSnapshot(snapshot, maxSnapshots, maxTotalBytes) {
|
|
68
77
|
state.snapshots.push(snapshot);
|
|
69
78
|
if (state.snapshots.length > maxSnapshots) {
|
|
70
79
|
state.snapshots.splice(0, state.snapshots.length - maxSnapshots);
|
|
71
80
|
}
|
|
81
|
+
while (state.snapshots.length > 1 && retainedSnapshotBytes() > maxTotalBytes) {
|
|
82
|
+
state.snapshots.shift();
|
|
83
|
+
state.evictedForBytes += 1;
|
|
84
|
+
}
|
|
72
85
|
}
|
|
73
86
|
var plugin = {
|
|
74
87
|
name: "checkpoint",
|
|
@@ -107,6 +120,7 @@ var plugin = {
|
|
|
107
120
|
state.captures = 0;
|
|
108
121
|
state.restores = 0;
|
|
109
122
|
state.skippedLarge = 0;
|
|
123
|
+
state.evictedForBytes = 0;
|
|
110
124
|
if (state.hookUnregister) {
|
|
111
125
|
try {
|
|
112
126
|
state.hookUnregister();
|
|
@@ -134,7 +148,8 @@ var plugin = {
|
|
|
134
148
|
origin: `auto:${input.toolName ?? "unknown"}`,
|
|
135
149
|
files: [captured]
|
|
136
150
|
},
|
|
137
|
-
cfg.maxSnapshots
|
|
151
|
+
cfg.maxSnapshots,
|
|
152
|
+
cfg.maxTotalBytes
|
|
138
153
|
);
|
|
139
154
|
state.captures += 1;
|
|
140
155
|
api.metrics.counter("captures");
|
|
@@ -188,7 +203,7 @@ var plugin = {
|
|
|
188
203
|
rejectedOutsideProject.push(p);
|
|
189
204
|
continue;
|
|
190
205
|
}
|
|
191
|
-
const captured = captureFile(safePath, cfg.maxFileBytes);
|
|
206
|
+
const captured = await captureFile(safePath, cfg.maxFileBytes);
|
|
192
207
|
if (captured === "too-large") {
|
|
193
208
|
skipped += 1;
|
|
194
209
|
state.skippedLarge += 1;
|
|
@@ -212,7 +227,7 @@ var plugin = {
|
|
|
212
227
|
origin: input.label?.trim() ? `manual:${input.label.trim()}` : "manual",
|
|
213
228
|
files
|
|
214
229
|
};
|
|
215
|
-
pushSnapshot(snapshot, cfg.maxSnapshots);
|
|
230
|
+
pushSnapshot(snapshot, cfg.maxSnapshots, cfg.maxTotalBytes);
|
|
216
231
|
state.captures += 1;
|
|
217
232
|
api.metrics.counter("captures");
|
|
218
233
|
return {
|
|
@@ -255,7 +270,9 @@ var plugin = {
|
|
|
255
270
|
counters: {
|
|
256
271
|
captures: state.captures,
|
|
257
272
|
restores: state.restores,
|
|
258
|
-
skippedLarge: state.skippedLarge
|
|
273
|
+
skippedLarge: state.skippedLarge,
|
|
274
|
+
retainedBytes: retainedSnapshotBytes(),
|
|
275
|
+
evictedForBytes: state.evictedForBytes
|
|
259
276
|
}
|
|
260
277
|
};
|
|
261
278
|
}
|
|
@@ -298,8 +315,8 @@ var plugin = {
|
|
|
298
315
|
continue;
|
|
299
316
|
}
|
|
300
317
|
try {
|
|
301
|
-
|
|
302
|
-
|
|
318
|
+
await mkdir(dirname(f.path), { recursive: true });
|
|
319
|
+
await writeFile(f.path, f.content);
|
|
303
320
|
restored.push(f.path);
|
|
304
321
|
} catch (err) {
|
|
305
322
|
errors.push({ path: f.path, error: err instanceof Error ? err.message : String(err) });
|
|
@@ -337,13 +354,16 @@ var plugin = {
|
|
|
337
354
|
captures: state.captures,
|
|
338
355
|
restores: state.restores,
|
|
339
356
|
skippedLarge: state.skippedLarge,
|
|
340
|
-
snapshotsHeld: state.snapshots.length
|
|
357
|
+
snapshotsHeld: state.snapshots.length,
|
|
358
|
+
retainedBytes: retainedSnapshotBytes(),
|
|
359
|
+
evictedForBytes: state.evictedForBytes
|
|
341
360
|
};
|
|
342
361
|
state.snapshots = [];
|
|
343
362
|
state.nextId = 1;
|
|
344
363
|
state.captures = 0;
|
|
345
364
|
state.restores = 0;
|
|
346
365
|
state.skippedLarge = 0;
|
|
366
|
+
state.evictedForBytes = 0;
|
|
347
367
|
api.log.info("checkpoint: teardown complete", { final });
|
|
348
368
|
},
|
|
349
369
|
async health() {
|
|
@@ -354,12 +374,17 @@ var plugin = {
|
|
|
354
374
|
snapshotsHeld: state.snapshots.length,
|
|
355
375
|
captures: state.captures,
|
|
356
376
|
restores: state.restores,
|
|
357
|
-
skippedLarge: state.skippedLarge
|
|
377
|
+
skippedLarge: state.skippedLarge,
|
|
378
|
+
// Retained snapshot bytes: the count-based ring alone does not
|
|
379
|
+
// bound memory, so surface the number the byte budget acts on.
|
|
380
|
+
retainedBytes: retainedSnapshotBytes(),
|
|
381
|
+
evictedForBytes: state.evictedForBytes
|
|
358
382
|
}
|
|
359
383
|
};
|
|
360
384
|
}
|
|
361
385
|
};
|
|
362
386
|
var checkpoint_default = plugin;
|
|
363
387
|
export {
|
|
364
|
-
checkpoint_default as default
|
|
388
|
+
checkpoint_default as default,
|
|
389
|
+
retainedSnapshotBytes
|
|
365
390
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-metrics/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-metrics/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA6MrD,QAAA,MAAM,MAAM,EAAE,MAgMb,CAAC;eAEa,MAAM"}
|