@wrongstack/plugins 0.303.0 → 0.305.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.
@@ -1,11 +1,9 @@
1
1
  // src/path-guard/index.ts
2
- var state = {
3
- invocations: 0,
4
- blocks: 0,
5
- warns: 0,
6
- lastBlock: null,
7
- hookUnregister: null
8
- };
2
+ function createState() {
3
+ return { invocations: 0, blocks: 0, warns: 0, lastBlock: null, hookUnregister: null };
4
+ }
5
+ var states = /* @__PURE__ */ new WeakMap();
6
+ var latestState = createState();
9
7
  var DEFAULT_PROTECT = [
10
8
  "pnpm-lock.yaml",
11
9
  "package-lock.json",
@@ -1273,17 +1271,16 @@ var plugin = {
1273
1271
  }
1274
1272
  },
1275
1273
  setup(api) {
1276
- state.invocations = 0;
1277
- state.blocks = 0;
1278
- state.warns = 0;
1279
- state.lastBlock = null;
1280
- if (state.hookUnregister) {
1274
+ const previous = states.get(api);
1275
+ if (previous?.hookUnregister) {
1281
1276
  try {
1282
- state.hookUnregister();
1277
+ previous.hookUnregister();
1283
1278
  } catch {
1284
1279
  }
1285
- state.hookUnregister = null;
1286
1280
  }
1281
+ const state = createState();
1282
+ states.set(api, state);
1283
+ latestState = state;
1287
1284
  const cfg = readConfig(api.config.extensions?.["path-guard"]);
1288
1285
  const protectRes = cfg.protect.map(compilePathGlob);
1289
1286
  const allowRes = cfg.allow.map(compilePathGlob);
@@ -1397,6 +1394,8 @@ var plugin = {
1397
1394
  });
1398
1395
  },
1399
1396
  teardown(api) {
1397
+ const state = states.get(api);
1398
+ if (!state) return;
1400
1399
  if (state.hookUnregister) {
1401
1400
  try {
1402
1401
  state.hookUnregister();
@@ -1409,9 +1408,11 @@ var plugin = {
1409
1408
  state.blocks = 0;
1410
1409
  state.warns = 0;
1411
1410
  state.lastBlock = null;
1411
+ states.delete(api);
1412
1412
  api.log.info("path-guard: teardown complete", { final });
1413
1413
  },
1414
1414
  async health() {
1415
+ const state = latestState;
1415
1416
  return {
1416
1417
  ok: true,
1417
1418
  message: state.lastBlock === null ? `path-guard: ${state.invocations} invocation(s), ${state.blocks} block(s), ${state.warns} warn(s)` : `path-guard: last block on "${state.lastBlock.path}" (${state.lastBlock.tool}) at ${state.lastBlock.when}`,
@@ -1,20 +1,3 @@
1
- // src/runtime/local-bin.ts
2
- import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
3
-
4
- // src/runtime/handles.ts
5
- function releaseHandle(off) {
6
- if (off) {
7
- try {
8
- off();
9
- } catch {
10
- }
11
- }
12
- return null;
13
- }
14
-
15
- // src/runtime/index.ts
16
- var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
17
-
18
1
  // src/runtime/credential-patterns.ts
19
2
  var CREDENTIAL_PATTERNS = [
20
3
  // LLM provider keys
@@ -125,10 +108,26 @@ function cloneCredentialPatterns() {
125
108
  }));
126
109
  }
127
110
 
111
+ // src/runtime/local-bin.ts
112
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
113
+
114
+ // src/runtime/handles.ts
115
+ function releaseHandle(off) {
116
+ if (off) {
117
+ try {
118
+ off();
119
+ } catch {
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+
125
+ // src/runtime/index.ts
126
+ var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
127
+
128
128
  // src/secret-scanner/index.ts
129
129
  var BASE_PATTERNS = cloneCredentialPatterns();
130
130
  var PATTERNS = [...BASE_PATTERNS];
131
- var patternCacheKey = "";
132
131
  var GROUP_INDEX_OF_PATTERN = [];
133
132
  var COMBINED_REGEX = buildCombinedRegex(PATTERNS);
134
133
  var SCAN_WINDOW_LENGTH = 1e5;
@@ -151,11 +150,6 @@ function patternTypeForGroups(groups) {
151
150
  return void 0;
152
151
  }
153
152
  function buildCombinedRegex(patterns) {
154
- const newCacheKey = JSON.stringify(patterns.map((p) => [p.type, p.regex.source]));
155
- if (newCacheKey === patternCacheKey && COMBINED_REGEX) {
156
- return COMBINED_REGEX;
157
- }
158
- patternCacheKey = newCacheKey;
159
153
  const offsets = [];
160
154
  let cursor = 0;
161
155
  for (const p of patterns) {
@@ -165,21 +159,30 @@ function buildCombinedRegex(patterns) {
165
159
  GROUP_INDEX_OF_PATTERN = offsets;
166
160
  return new RegExp(patterns.map((p) => `(${p.regex.source})`).join("|"), "g");
167
161
  }
168
- var state = {
169
- blockCount: 0,
170
- redactCount: 0,
171
- allowCount: 0,
172
- /** PostToolUse: secrets detected in tool output. */
173
- leakCount: 0,
174
- /** Most recent PreToolUse block — surfaced by `secret_scanner_status`. */
175
- lastBlock: null,
176
- /** Most recent PostToolUse leak — surfaced by `secret_scanner_status`. */
177
- lastLeak: null,
178
- /** PreToolUse hook handle so teardown can unregister. */
179
- hookUnregister: null,
180
- /** PostToolUse hook handle so teardown can unregister. */
181
- postHookUnregister: null
182
- };
162
+ function createState() {
163
+ return {
164
+ blockCount: 0,
165
+ redactCount: 0,
166
+ allowCount: 0,
167
+ /** PostToolUse: secrets detected in tool output. */
168
+ leakCount: 0,
169
+ /** Most recent PreToolUse block — surfaced by `secret_scanner_status`. */
170
+ lastBlock: null,
171
+ /** Most recent PostToolUse leak — surfaced by `secret_scanner_status`. */
172
+ lastLeak: null,
173
+ /** PreToolUse hook handle so teardown can unregister. */
174
+ hookUnregister: null,
175
+ /** PostToolUse hook handle so teardown can unregister. */
176
+ postHookUnregister: null
177
+ };
178
+ }
179
+ var runtimes = /* @__PURE__ */ new WeakMap();
180
+ var latestRuntime;
181
+ function activateRuntime(runtime) {
182
+ PATTERNS = runtime.patterns;
183
+ COMBINED_REGEX = runtime.combinedRegex;
184
+ GROUP_INDEX_OF_PATTERN = runtime.groupIndexes;
185
+ }
183
186
  function scanWindow(window, found, startTime) {
184
187
  COMBINED_REGEX.lastIndex = 0;
185
188
  let m;
@@ -325,8 +328,10 @@ function readConfig(raw) {
325
328
  customPatterns
326
329
  };
327
330
  }
328
- function buildHook(cfg, log) {
331
+ function buildHook(cfg, log, runtime) {
329
332
  return (input) => {
333
+ activateRuntime(runtime);
334
+ const { state } = runtime;
330
335
  if (!cfg.enabled) return;
331
336
  const toolName = input.toolName ?? "unknown";
332
337
  const matched = scanInput(input.toolInput);
@@ -368,8 +373,10 @@ function buildHook(cfg, log) {
368
373
  return void 0;
369
374
  };
370
375
  }
371
- function buildPostHook(cfg, log) {
376
+ function buildPostHook(cfg, log, runtime) {
372
377
  return (input) => {
378
+ activateRuntime(runtime);
379
+ const { state } = runtime;
373
380
  if (!cfg.enabled) return;
374
381
  const result = input.toolResult;
375
382
  if (!result || typeof result.content !== "string") return;
@@ -446,14 +453,11 @@ var plugin = {
446
453
  }
447
454
  },
448
455
  setup(api) {
449
- state.blockCount = 0;
450
- state.redactCount = 0;
451
- state.allowCount = 0;
452
- state.leakCount = 0;
453
- state.lastBlock = null;
454
- state.lastLeak = null;
455
- state.hookUnregister = releaseHandle(state.hookUnregister);
456
- state.postHookUnregister = releaseHandle(state.postHookUnregister);
456
+ const previous = runtimes.get(api);
457
+ if (previous) {
458
+ previous.state.hookUnregister = releaseHandle(previous.state.hookUnregister);
459
+ previous.state.postHookUnregister = releaseHandle(previous.state.postHookUnregister);
460
+ }
457
461
  const cfg = readConfig(api.config.extensions?.["secret-scanner"]);
458
462
  PATTERNS = [...BASE_PATTERNS];
459
463
  for (const cp of cfg.customPatterns) {
@@ -463,11 +467,20 @@ var plugin = {
463
467
  }
464
468
  }
465
469
  COMBINED_REGEX = buildCombinedRegex(PATTERNS);
470
+ const runtime = {
471
+ state: createState(),
472
+ patterns: PATTERNS,
473
+ combinedRegex: COMBINED_REGEX,
474
+ groupIndexes: [...GROUP_INDEX_OF_PATTERN]
475
+ };
476
+ runtimes.set(api, runtime);
477
+ latestRuntime = runtime;
478
+ const { state } = runtime;
466
479
  const log = {
467
480
  warn: (msg, ...rest) => api.log.warn(msg, ...rest),
468
481
  info: (msg, ...rest) => api.log.info(msg, ...rest)
469
482
  };
470
- const hook = buildHook(cfg, log);
483
+ const hook = buildHook(cfg, log, runtime);
471
484
  state.hookUnregister = api.registerHook("PreToolUse", cfg.matcher, hook, {
472
485
  name: "secret-scanner",
473
486
  // Redaction rewrites arguments; block/allow modes must inspect the final
@@ -477,7 +490,7 @@ var plugin = {
477
490
  failurePolicy: "closed",
478
491
  policy: true
479
492
  });
480
- const postHook = buildPostHook(cfg, log);
493
+ const postHook = buildPostHook(cfg, log, runtime);
481
494
  state.postHookUnregister = api.registerHook("PostToolUse", cfg.postToolUseMatcher, postHook);
482
495
  api.tools.register({
483
496
  name: "secret_scanner_status",
@@ -486,6 +499,7 @@ var plugin = {
486
499
  permission: "auto",
487
500
  mutating: false,
488
501
  async execute() {
502
+ activateRuntime(runtime);
489
503
  return {
490
504
  ok: true,
491
505
  enabled: cfg.enabled,
@@ -518,6 +532,7 @@ var plugin = {
518
532
  permission: "auto",
519
533
  mutating: false,
520
534
  async execute(input) {
535
+ activateRuntime(runtime);
521
536
  const text = typeof input["text"] === "string" ? input["text"] : "";
522
537
  const matched = findMatches(text);
523
538
  return {
@@ -535,6 +550,9 @@ var plugin = {
535
550
  });
536
551
  },
537
552
  teardown(api) {
553
+ const runtime = runtimes.get(api);
554
+ if (!runtime) return;
555
+ const { state } = runtime;
538
556
  if (state.hookUnregister) {
539
557
  try {
540
558
  state.hookUnregister();
@@ -561,11 +579,11 @@ var plugin = {
561
579
  state.leakCount = 0;
562
580
  state.lastBlock = null;
563
581
  state.lastLeak = null;
564
- PATTERNS = [...BASE_PATTERNS];
565
- COMBINED_REGEX = buildCombinedRegex(PATTERNS);
582
+ runtimes.delete(api);
566
583
  api.log.info("secret-scanner: teardown complete", { counters: finalCounters });
567
584
  },
568
585
  async health() {
586
+ const state = latestRuntime?.state ?? createState();
569
587
  return {
570
588
  ok: true,
571
589
  message: state.lastLeak !== null ? `secret-scanner: last leak at ${state.lastLeak.when} on ${state.lastLeak.toolName} (${state.lastLeak.matchedTypes.join(", ")})` : state.lastBlock !== null ? `secret-scanner: last block at ${state.lastBlock.when} on ${state.lastBlock.toolName} (${state.lastBlock.matchedTypes.join(", ")})` : `secret-scanner: ${state.blockCount + state.redactCount + state.allowCount + state.leakCount} invocations, no blocks or leaks`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/plugins",
3
- "version": "0.303.0",
3
+ "version": "0.305.1",
4
4
  "description": "Official WrongStack collection of focused plugins for code quality, security, observability, planning, and agent coordination",
5
5
  "license": "MIT",
6
6
  "author": "ECOSTACK TECHNOLOGY OÜ",
@@ -299,8 +299,8 @@
299
299
  "vitest": "^4.1.10"
300
300
  },
301
301
  "dependencies": {
302
- "@wrongstack/core": "0.303.0",
303
- "@wrongstack/tools": "0.303.0"
302
+ "@wrongstack/tools": "0.305.1",
303
+ "@wrongstack/core": "0.305.1"
304
304
  },
305
305
  "scripts": {
306
306
  "build": "node ../../scripts/build-package.mjs",