@wrongstack/plugins 0.302.2 → 0.305.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/index.js +1220 -1201
- package/dist/path-guard.js +15 -14
- package/dist/secret-scanner.js +70 -52
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -13131,13 +13131,11 @@ var plugin37 = {
|
|
|
13131
13131
|
var notify_hub_default = plugin37;
|
|
13132
13132
|
|
|
13133
13133
|
// src/path-guard/index.ts
|
|
13134
|
-
|
|
13135
|
-
invocations: 0,
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
hookUnregister: null
|
|
13140
|
-
};
|
|
13134
|
+
function createState() {
|
|
13135
|
+
return { invocations: 0, blocks: 0, warns: 0, lastBlock: null, hookUnregister: null };
|
|
13136
|
+
}
|
|
13137
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
13138
|
+
var latestState = createState();
|
|
13141
13139
|
var DEFAULT_PROTECT = [
|
|
13142
13140
|
"pnpm-lock.yaml",
|
|
13143
13141
|
"package-lock.json",
|
|
@@ -14405,17 +14403,16 @@ var plugin38 = {
|
|
|
14405
14403
|
}
|
|
14406
14404
|
},
|
|
14407
14405
|
setup(api) {
|
|
14408
|
-
|
|
14409
|
-
|
|
14410
|
-
state35.warns = 0;
|
|
14411
|
-
state35.lastBlock = null;
|
|
14412
|
-
if (state35.hookUnregister) {
|
|
14406
|
+
const previous = states.get(api);
|
|
14407
|
+
if (previous?.hookUnregister) {
|
|
14413
14408
|
try {
|
|
14414
|
-
|
|
14409
|
+
previous.hookUnregister();
|
|
14415
14410
|
} catch {
|
|
14416
14411
|
}
|
|
14417
|
-
state35.hookUnregister = null;
|
|
14418
14412
|
}
|
|
14413
|
+
const state59 = createState();
|
|
14414
|
+
states.set(api, state59);
|
|
14415
|
+
latestState = state59;
|
|
14419
14416
|
const cfg = readConfig33(api.config.extensions?.["path-guard"]);
|
|
14420
14417
|
const protectRes = cfg.protect.map(compilePathGlob);
|
|
14421
14418
|
const allowRes = cfg.allow.map(compilePathGlob);
|
|
@@ -14423,15 +14420,15 @@ var plugin38 = {
|
|
|
14423
14420
|
const subject = isScope ? `write scope "${path}" may include a protected path \u2014 narrow it or add an \`allow\` glob` : `"${path}" is a protected path`;
|
|
14424
14421
|
const matchContext = isScope ? 'its unresolved scope overlaps config.extensions["path-guard"].protect' : 'matched by config.extensions["path-guard"].protect';
|
|
14425
14422
|
if (cfg.mode === "block") {
|
|
14426
|
-
|
|
14427
|
-
|
|
14423
|
+
state59.blocks += 1;
|
|
14424
|
+
state59.lastBlock = { path, tool, when: (/* @__PURE__ */ new Date()).toISOString() };
|
|
14428
14425
|
api.metrics.counter("blocks");
|
|
14429
14426
|
return {
|
|
14430
14427
|
decision: "block",
|
|
14431
14428
|
reason: `path-guard: ${subject} (${matchContext}) \u2014 ${operation} refused. If this change is intentional, ask the user to do it, add an \`allow\` glob, or set mode: "warn".`
|
|
14432
14429
|
};
|
|
14433
14430
|
}
|
|
14434
|
-
|
|
14431
|
+
state59.warns += 1;
|
|
14435
14432
|
api.metrics.counter("warns");
|
|
14436
14433
|
return {
|
|
14437
14434
|
decision: "allow",
|
|
@@ -14440,7 +14437,7 @@ var plugin38 = {
|
|
|
14440
14437
|
};
|
|
14441
14438
|
const hook = (input) => {
|
|
14442
14439
|
if (!cfg.enabled) return;
|
|
14443
|
-
|
|
14440
|
+
state59.invocations += 1;
|
|
14444
14441
|
const toolName = input.toolName ?? "";
|
|
14445
14442
|
const ti = input.toolInput ?? {};
|
|
14446
14443
|
const command = typeof ti["command"] === "string" ? ti["command"] : "";
|
|
@@ -14492,7 +14489,7 @@ var plugin38 = {
|
|
|
14492
14489
|
}
|
|
14493
14490
|
return;
|
|
14494
14491
|
};
|
|
14495
|
-
|
|
14492
|
+
state59.hookUnregister = api.registerHook("PreToolUse", "*", hook, {
|
|
14496
14493
|
name: "path-guard",
|
|
14497
14494
|
stage: "validate",
|
|
14498
14495
|
failurePolicy: "closed",
|
|
@@ -14513,11 +14510,11 @@ var plugin38 = {
|
|
|
14513
14510
|
protect: cfg.protect,
|
|
14514
14511
|
allow: cfg.allow,
|
|
14515
14512
|
counters: {
|
|
14516
|
-
invocations:
|
|
14517
|
-
blocks:
|
|
14518
|
-
warns:
|
|
14513
|
+
invocations: state59.invocations,
|
|
14514
|
+
blocks: state59.blocks,
|
|
14515
|
+
warns: state59.warns
|
|
14519
14516
|
},
|
|
14520
|
-
lastBlock:
|
|
14517
|
+
lastBlock: state59.lastBlock
|
|
14521
14518
|
};
|
|
14522
14519
|
}
|
|
14523
14520
|
});
|
|
@@ -14529,28 +14526,32 @@ var plugin38 = {
|
|
|
14529
14526
|
});
|
|
14530
14527
|
},
|
|
14531
14528
|
teardown(api) {
|
|
14532
|
-
|
|
14529
|
+
const state59 = states.get(api);
|
|
14530
|
+
if (!state59) return;
|
|
14531
|
+
if (state59.hookUnregister) {
|
|
14533
14532
|
try {
|
|
14534
|
-
|
|
14533
|
+
state59.hookUnregister();
|
|
14535
14534
|
} catch {
|
|
14536
14535
|
}
|
|
14537
|
-
|
|
14536
|
+
state59.hookUnregister = null;
|
|
14538
14537
|
}
|
|
14539
|
-
const final = { invocations:
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14538
|
+
const final = { invocations: state59.invocations, blocks: state59.blocks, warns: state59.warns };
|
|
14539
|
+
state59.invocations = 0;
|
|
14540
|
+
state59.blocks = 0;
|
|
14541
|
+
state59.warns = 0;
|
|
14542
|
+
state59.lastBlock = null;
|
|
14543
|
+
states.delete(api);
|
|
14544
14544
|
api.log.info("path-guard: teardown complete", { final });
|
|
14545
14545
|
},
|
|
14546
14546
|
async health() {
|
|
14547
|
+
const state59 = latestState;
|
|
14547
14548
|
return {
|
|
14548
14549
|
ok: true,
|
|
14549
|
-
message:
|
|
14550
|
+
message: state59.lastBlock === null ? `path-guard: ${state59.invocations} invocation(s), ${state59.blocks} block(s), ${state59.warns} warn(s)` : `path-guard: last block on "${state59.lastBlock.path}" (${state59.lastBlock.tool}) at ${state59.lastBlock.when}`,
|
|
14550
14551
|
counters: {
|
|
14551
|
-
invocations:
|
|
14552
|
-
blocks:
|
|
14553
|
-
warns:
|
|
14552
|
+
invocations: state59.invocations,
|
|
14553
|
+
blocks: state59.blocks,
|
|
14554
|
+
warns: state59.warns
|
|
14554
14555
|
}
|
|
14555
14556
|
};
|
|
14556
14557
|
}
|
|
@@ -14561,7 +14562,7 @@ var path_guard_default = plugin38;
|
|
|
14561
14562
|
import { existsSync as existsSync5, readFileSync as readFileSync11 } from "node:fs";
|
|
14562
14563
|
import { isAbsolute as isAbsolute18, relative as relative18, resolve as resolve18 } from "node:path";
|
|
14563
14564
|
var API_VERSION25 = "^0.1.10";
|
|
14564
|
-
var
|
|
14565
|
+
var state35 = {
|
|
14565
14566
|
invocationCount: 0,
|
|
14566
14567
|
comparisonCount: 0,
|
|
14567
14568
|
regressionCount: 0,
|
|
@@ -14721,12 +14722,12 @@ var plugin39 = {
|
|
|
14721
14722
|
}
|
|
14722
14723
|
},
|
|
14723
14724
|
setup(api) {
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14725
|
+
state35.invocationCount = 0;
|
|
14726
|
+
state35.comparisonCount = 0;
|
|
14727
|
+
state35.regressionCount = 0;
|
|
14728
|
+
state35.missingResultsCount = 0;
|
|
14729
|
+
state35.errorCount = 0;
|
|
14730
|
+
state35.lastResult = null;
|
|
14730
14731
|
const cfg = readConfig34(api.config.extensions?.["performance-regression-gate"]);
|
|
14731
14732
|
api.tools.register({
|
|
14732
14733
|
name: "perf_regression_status",
|
|
@@ -14756,16 +14757,16 @@ var plugin39 = {
|
|
|
14756
14757
|
if (!cfg.enabled) {
|
|
14757
14758
|
return { ok: false, error: "performance-regression-gate is disabled" };
|
|
14758
14759
|
}
|
|
14759
|
-
|
|
14760
|
+
state35.invocationCount += 1;
|
|
14760
14761
|
const threshold = typeof input.thresholdPercent === "number" && input.thresholdPercent >= 0 && input.thresholdPercent <= 1e3 ? input.thresholdPercent : cfg.thresholdPercent;
|
|
14761
14762
|
const resultsPath = resolveProjectPath6(input.resultsPath || "bench-results.json") ?? "";
|
|
14762
14763
|
if (!resultsPath) {
|
|
14763
|
-
|
|
14764
|
+
state35.errorCount += 1;
|
|
14764
14765
|
return { ok: false, error: "invalid results path (must be inside project)" };
|
|
14765
14766
|
}
|
|
14766
14767
|
const results = loadResults(resultsPath);
|
|
14767
14768
|
if (!results) {
|
|
14768
|
-
|
|
14769
|
+
state35.missingResultsCount += 1;
|
|
14769
14770
|
return {
|
|
14770
14771
|
ok: true,
|
|
14771
14772
|
hasResults: false,
|
|
@@ -14777,7 +14778,7 @@ var plugin39 = {
|
|
|
14777
14778
|
}
|
|
14778
14779
|
const current = flattenResults(results);
|
|
14779
14780
|
if (current.length === 0) {
|
|
14780
|
-
|
|
14781
|
+
state35.missingResultsCount += 1;
|
|
14781
14782
|
return {
|
|
14782
14783
|
ok: true,
|
|
14783
14784
|
hasResults: false,
|
|
@@ -14791,12 +14792,12 @@ var plugin39 = {
|
|
|
14791
14792
|
if (input.baselinePath) {
|
|
14792
14793
|
const baselineResolved = resolveProjectPath6(input.baselinePath) ?? "";
|
|
14793
14794
|
if (!baselineResolved) {
|
|
14794
|
-
|
|
14795
|
+
state35.errorCount += 1;
|
|
14795
14796
|
return { ok: false, error: "invalid baseline path (must be inside project)" };
|
|
14796
14797
|
}
|
|
14797
14798
|
const baselineResults = loadResults(baselineResolved);
|
|
14798
14799
|
if (!baselineResults) {
|
|
14799
|
-
|
|
14800
|
+
state35.errorCount += 1;
|
|
14800
14801
|
return {
|
|
14801
14802
|
ok: false,
|
|
14802
14803
|
error: `Could not read baseline results at ${input.baselinePath}.`
|
|
@@ -14808,9 +14809,9 @@ var plugin39 = {
|
|
|
14808
14809
|
pairs = pairInternal(current);
|
|
14809
14810
|
}
|
|
14810
14811
|
const regressions = comparePairs(pairs, threshold);
|
|
14811
|
-
|
|
14812
|
-
|
|
14813
|
-
|
|
14812
|
+
state35.comparisonCount += pairs.length;
|
|
14813
|
+
state35.regressionCount += regressions.length;
|
|
14814
|
+
state35.lastResult = {
|
|
14814
14815
|
comparisons: pairs.length,
|
|
14815
14816
|
regressions: regressions.length,
|
|
14816
14817
|
thresholdPercent: threshold,
|
|
@@ -14839,53 +14840,53 @@ var plugin39 = {
|
|
|
14839
14840
|
},
|
|
14840
14841
|
teardown(api) {
|
|
14841
14842
|
const final = {
|
|
14842
|
-
invocations:
|
|
14843
|
-
comparisons:
|
|
14844
|
-
regressions:
|
|
14845
|
-
missingResults:
|
|
14846
|
-
errors:
|
|
14843
|
+
invocations: state35.invocationCount,
|
|
14844
|
+
comparisons: state35.comparisonCount,
|
|
14845
|
+
regressions: state35.regressionCount,
|
|
14846
|
+
missingResults: state35.missingResultsCount,
|
|
14847
|
+
errors: state35.errorCount
|
|
14847
14848
|
};
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14849
|
+
state35.invocationCount = 0;
|
|
14850
|
+
state35.comparisonCount = 0;
|
|
14851
|
+
state35.regressionCount = 0;
|
|
14852
|
+
state35.missingResultsCount = 0;
|
|
14853
|
+
state35.errorCount = 0;
|
|
14854
|
+
state35.lastResult = null;
|
|
14854
14855
|
api.log.info("performance-regression-gate: teardown complete", { final });
|
|
14855
14856
|
},
|
|
14856
14857
|
async health() {
|
|
14857
14858
|
return {
|
|
14858
|
-
ok:
|
|
14859
|
-
message:
|
|
14859
|
+
ok: state35.errorCount === 0,
|
|
14860
|
+
message: state35.lastResult ? `performance-regression-gate: ${state35.lastResult.regressions} regression(s) across ${state35.lastResult.comparisons} comparison(s) (threshold ${state35.lastResult.thresholdPercent}%)` : `performance-regression-gate: ${state35.invocationCount} invocation(s), ${state35.comparisonCount} comparison(s)`,
|
|
14860
14861
|
counters: {
|
|
14861
|
-
invocations:
|
|
14862
|
-
comparisons:
|
|
14863
|
-
regressions:
|
|
14864
|
-
missingResults:
|
|
14865
|
-
errors:
|
|
14862
|
+
invocations: state35.invocationCount,
|
|
14863
|
+
comparisons: state35.comparisonCount,
|
|
14864
|
+
regressions: state35.regressionCount,
|
|
14865
|
+
missingResults: state35.missingResultsCount,
|
|
14866
|
+
errors: state35.errorCount
|
|
14866
14867
|
},
|
|
14867
|
-
lastResult:
|
|
14868
|
+
lastResult: state35.lastResult
|
|
14868
14869
|
};
|
|
14869
14870
|
}
|
|
14870
14871
|
};
|
|
14871
14872
|
var performance_regression_gate_default = plugin39;
|
|
14872
14873
|
|
|
14873
14874
|
// src/plugin-stack-observer/index.ts
|
|
14874
|
-
var
|
|
14875
|
+
var state36 = {
|
|
14875
14876
|
wraps: [],
|
|
14876
14877
|
contributions: 0,
|
|
14877
14878
|
patternUnregister: null
|
|
14878
14879
|
};
|
|
14879
14880
|
function clearObserverState() {
|
|
14880
|
-
if (
|
|
14881
|
+
if (state36.patternUnregister) {
|
|
14881
14882
|
try {
|
|
14882
|
-
|
|
14883
|
+
state36.patternUnregister();
|
|
14883
14884
|
} catch {
|
|
14884
14885
|
}
|
|
14885
|
-
|
|
14886
|
+
state36.patternUnregister = null;
|
|
14886
14887
|
}
|
|
14887
|
-
|
|
14888
|
-
|
|
14888
|
+
state36.wraps = [];
|
|
14889
|
+
state36.contributions = 0;
|
|
14889
14890
|
}
|
|
14890
14891
|
var PLUGIN = {
|
|
14891
14892
|
name: "plugin-stack-observer",
|
|
@@ -14920,14 +14921,14 @@ var PLUGIN = {
|
|
|
14920
14921
|
api.log.info("plugin-stack-observer loaded (disabled)");
|
|
14921
14922
|
return;
|
|
14922
14923
|
}
|
|
14923
|
-
|
|
14924
|
+
state36.patternUnregister = api.onPattern(
|
|
14924
14925
|
"provider.wrap:loaded",
|
|
14925
14926
|
(_eventName, payload) => {
|
|
14926
14927
|
const p = payload ?? {};
|
|
14927
14928
|
if (typeof p.plugin !== "string" || p.plugin.length === 0) return;
|
|
14928
14929
|
const wraps = Array.isArray(p.wraps) ? p.wraps.filter((w) => typeof w === "string") : [];
|
|
14929
14930
|
const kind = typeof p.kind === "string" ? p.kind : "unknown";
|
|
14930
|
-
|
|
14931
|
+
state36.wraps.push({
|
|
14931
14932
|
plugin: p.plugin,
|
|
14932
14933
|
kind,
|
|
14933
14934
|
wraps,
|
|
@@ -14938,10 +14939,10 @@ var PLUGIN = {
|
|
|
14938
14939
|
);
|
|
14939
14940
|
if (cfg.injectIntoSystemPrompt) {
|
|
14940
14941
|
api.registerSystemPromptContributor(async () => {
|
|
14941
|
-
if (
|
|
14942
|
-
|
|
14942
|
+
if (state36.wraps.length === 0) return [];
|
|
14943
|
+
state36.contributions += 1;
|
|
14943
14944
|
api.metrics.counter("system_prompt_contribution");
|
|
14944
|
-
const lines =
|
|
14945
|
+
const lines = state36.wraps.map(
|
|
14945
14946
|
(w, i) => `${i + 1}. ${w.plugin} [${w.kind}] wraps: ${w.wraps.join(", ")}`
|
|
14946
14947
|
);
|
|
14947
14948
|
return [
|
|
@@ -14967,9 +14968,9 @@ Any failure or latency above is attributable to one of the above.`
|
|
|
14967
14968
|
ok: true,
|
|
14968
14969
|
enabled: cfg.enabled,
|
|
14969
14970
|
injectIntoSystemPrompt: cfg.injectIntoSystemPrompt,
|
|
14970
|
-
wrapCount:
|
|
14971
|
-
wraps:
|
|
14972
|
-
contributions:
|
|
14971
|
+
wrapCount: state36.wraps.length,
|
|
14972
|
+
wraps: state36.wraps,
|
|
14973
|
+
contributions: state36.contributions
|
|
14973
14974
|
};
|
|
14974
14975
|
}
|
|
14975
14976
|
});
|
|
@@ -14980,20 +14981,20 @@ Any failure or latency above is attributable to one of the above.`
|
|
|
14980
14981
|
},
|
|
14981
14982
|
teardown(api) {
|
|
14982
14983
|
const final = {
|
|
14983
|
-
wrapCount:
|
|
14984
|
-
contributions:
|
|
14984
|
+
wrapCount: state36.wraps.length,
|
|
14985
|
+
contributions: state36.contributions
|
|
14985
14986
|
};
|
|
14986
14987
|
clearObserverState();
|
|
14987
14988
|
api.log.info("plugin-stack-observer: teardown complete", { final });
|
|
14988
14989
|
},
|
|
14989
14990
|
async health() {
|
|
14990
|
-
const stack =
|
|
14991
|
+
const stack = state36.wraps.length === 0 ? "no wraps active" : state36.wraps.map((w) => w.plugin).join(" \u2192 ");
|
|
14991
14992
|
return {
|
|
14992
14993
|
ok: true,
|
|
14993
|
-
message: `plugin-stack-observer: ${
|
|
14994
|
-
wrapCount:
|
|
14995
|
-
contributions:
|
|
14996
|
-
wraps:
|
|
14994
|
+
message: `plugin-stack-observer: ${state36.wraps.length} wrap(s) loaded [${stack}]`,
|
|
14995
|
+
wrapCount: state36.wraps.length,
|
|
14996
|
+
contributions: state36.contributions,
|
|
14997
|
+
wraps: state36.wraps
|
|
14997
14998
|
};
|
|
14998
14999
|
}
|
|
14999
15000
|
};
|
|
@@ -15012,7 +15013,7 @@ import { execFile as execFile10 } from "node:child_process";
|
|
|
15012
15013
|
import { mkdir as mkdir2, writeFile as writeFile3 } from "node:fs/promises";
|
|
15013
15014
|
import { dirname as dirname7, isAbsolute as isAbsolute19, relative as relative19, resolve as resolve19 } from "node:path";
|
|
15014
15015
|
var API_VERSION26 = "^0.1.10";
|
|
15015
|
-
var
|
|
15016
|
+
var state37 = {
|
|
15016
15017
|
commits: [],
|
|
15017
15018
|
files: /* @__PURE__ */ new Set(),
|
|
15018
15019
|
models: /* @__PURE__ */ new Set(),
|
|
@@ -15089,10 +15090,10 @@ async function buildDraft(cfg, llm) {
|
|
|
15089
15090
|
lines.push("");
|
|
15090
15091
|
if (cfg.aiSummary && llm) {
|
|
15091
15092
|
try {
|
|
15092
|
-
const context = `Files changed: ${[...
|
|
15093
|
-
Commits: ${
|
|
15094
|
-
Tool calls: ${
|
|
15095
|
-
Tokens: ${
|
|
15093
|
+
const context = `Files changed: ${[...state37.files].join(", ") || "none"}
|
|
15094
|
+
Commits: ${state37.commits.join("; ") || "none"}
|
|
15095
|
+
Tool calls: ${state37.toolCalls}
|
|
15096
|
+
Tokens: ${state37.totalInputTokens} in / ${state37.totalOutputTokens} out`;
|
|
15096
15097
|
const result = await llm.complete(
|
|
15097
15098
|
"Write a concise PR title and one-paragraph summary for the changes below. Format exactly as:\nTITLE: <title>\nSUMMARY: <summary>\n\n" + context,
|
|
15098
15099
|
{
|
|
@@ -15109,14 +15110,14 @@ Tokens: ${state38.totalInputTokens} in / ${state38.totalOutputTokens} out`;
|
|
|
15109
15110
|
} catch {
|
|
15110
15111
|
}
|
|
15111
15112
|
}
|
|
15112
|
-
if (cfg.includeCommits &&
|
|
15113
|
+
if (cfg.includeCommits && state37.commits.length > 0) {
|
|
15113
15114
|
lines.push("## Commits");
|
|
15114
|
-
for (const c of
|
|
15115
|
+
for (const c of state37.commits) lines.push(`- ${c}`);
|
|
15115
15116
|
lines.push("");
|
|
15116
15117
|
}
|
|
15117
|
-
if (cfg.includeFiles &&
|
|
15118
|
+
if (cfg.includeFiles && state37.files.size > 0) {
|
|
15118
15119
|
lines.push("## Files changed");
|
|
15119
|
-
for (const f of [...
|
|
15120
|
+
for (const f of [...state37.files].sort()) lines.push(`- \`${f}\``);
|
|
15120
15121
|
lines.push("");
|
|
15121
15122
|
}
|
|
15122
15123
|
if (diffStat) {
|
|
@@ -15127,26 +15128,26 @@ Tokens: ${state38.totalInputTokens} in / ${state38.totalOutputTokens} out`;
|
|
|
15127
15128
|
lines.push("");
|
|
15128
15129
|
}
|
|
15129
15130
|
lines.push("## Session metrics");
|
|
15130
|
-
lines.push(`- Tool calls: ${
|
|
15131
|
-
lines.push(`- Models used: ${[...
|
|
15132
|
-
lines.push(`- Tokens: ${
|
|
15131
|
+
lines.push(`- Tool calls: ${state37.toolCalls}`);
|
|
15132
|
+
lines.push(`- Models used: ${[...state37.models].join(", ") || "unknown"}`);
|
|
15133
|
+
lines.push(`- Tokens: ${state37.totalInputTokens} in / ${state37.totalOutputTokens} out`);
|
|
15133
15134
|
lines.push("");
|
|
15134
|
-
const title =
|
|
15135
|
+
const title = state37.commits[0] ?? `Changes on ${branch ?? "current branch"}`;
|
|
15135
15136
|
return { title, body: lines.join("\n") };
|
|
15136
15137
|
}
|
|
15137
15138
|
async function writeDraft(cfg, llm) {
|
|
15138
15139
|
const resolved = resolveProjectPath7(cfg.outputPath);
|
|
15139
15140
|
if (!resolved) {
|
|
15140
|
-
|
|
15141
|
+
state37.draftErrors += 1;
|
|
15141
15142
|
return;
|
|
15142
15143
|
}
|
|
15143
15144
|
const draft = await buildDraft(cfg, llm);
|
|
15144
15145
|
try {
|
|
15145
15146
|
await mkdir2(dirname7(resolved), { recursive: true });
|
|
15146
15147
|
await writeFile3(resolved, draft.body);
|
|
15147
|
-
|
|
15148
|
+
state37.draftsWritten += 1;
|
|
15148
15149
|
} catch {
|
|
15149
|
-
|
|
15150
|
+
state37.draftErrors += 1;
|
|
15150
15151
|
}
|
|
15151
15152
|
}
|
|
15152
15153
|
var plugin40 = {
|
|
@@ -15197,54 +15198,54 @@ var plugin40 = {
|
|
|
15197
15198
|
}
|
|
15198
15199
|
},
|
|
15199
15200
|
setup(api) {
|
|
15200
|
-
|
|
15201
|
-
|
|
15202
|
-
|
|
15203
|
-
|
|
15204
|
-
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
|
|
15208
|
-
|
|
15209
|
-
|
|
15210
|
-
for (const off of
|
|
15201
|
+
state37.commits = [];
|
|
15202
|
+
state37.files = /* @__PURE__ */ new Set();
|
|
15203
|
+
state37.models = /* @__PURE__ */ new Set();
|
|
15204
|
+
state37.totalInputTokens = 0;
|
|
15205
|
+
state37.totalOutputTokens = 0;
|
|
15206
|
+
state37.toolCalls = 0;
|
|
15207
|
+
state37.draftsWritten = 0;
|
|
15208
|
+
state37.draftErrors = 0;
|
|
15209
|
+
state37.stopInvocations = 0;
|
|
15210
|
+
state37.stopHookUnregister = releaseHandle(state37.stopHookUnregister);
|
|
15211
|
+
for (const off of state37.eventUnsubscribers) {
|
|
15211
15212
|
try {
|
|
15212
15213
|
off();
|
|
15213
15214
|
} catch {
|
|
15214
15215
|
}
|
|
15215
15216
|
}
|
|
15216
|
-
|
|
15217
|
+
state37.eventUnsubscribers = [];
|
|
15217
15218
|
const cfg = readConfig36(api.config.extensions?.["pr-drafter"]);
|
|
15218
15219
|
if (api.onPattern) {
|
|
15219
15220
|
const offTool = api.onPattern("tool.completed", (_event, payload) => {
|
|
15220
15221
|
const p = payload;
|
|
15221
15222
|
const toolName = p?.tool;
|
|
15222
|
-
|
|
15223
|
+
state37.toolCalls += 1;
|
|
15223
15224
|
if (toolName === "git_autocommit" && p?.result?.committed) {
|
|
15224
15225
|
const msg = p.result.commitMessage ?? p.input?.message ?? "commit";
|
|
15225
|
-
|
|
15226
|
+
state37.commits.push(msg);
|
|
15226
15227
|
}
|
|
15227
15228
|
if ((toolName === "write" || toolName === "edit") && p?.input?.path) {
|
|
15228
|
-
|
|
15229
|
+
state37.files.add(p.input.path);
|
|
15229
15230
|
}
|
|
15230
15231
|
});
|
|
15231
|
-
|
|
15232
|
+
state37.eventUnsubscribers.push(offTool);
|
|
15232
15233
|
}
|
|
15233
15234
|
if (api.onEvent) {
|
|
15234
15235
|
const offUsage = api.onEvent("provider.response", (payload) => {
|
|
15235
15236
|
const p = payload;
|
|
15236
|
-
if (p?.model)
|
|
15237
|
-
|
|
15238
|
-
|
|
15237
|
+
if (p?.model) state37.models.add(p.model);
|
|
15238
|
+
state37.totalInputTokens += p?.usage?.input ?? 0;
|
|
15239
|
+
state37.totalOutputTokens += p?.usage?.output ?? 0;
|
|
15239
15240
|
});
|
|
15240
|
-
|
|
15241
|
+
state37.eventUnsubscribers.push(offUsage);
|
|
15241
15242
|
}
|
|
15242
15243
|
const stopHook = async () => {
|
|
15243
15244
|
if (!cfg.enabled || !cfg.writeOnStop) return;
|
|
15244
|
-
|
|
15245
|
+
state37.stopInvocations += 1;
|
|
15245
15246
|
await writeDraft(cfg, api.llm);
|
|
15246
15247
|
};
|
|
15247
|
-
|
|
15248
|
+
state37.stopHookUnregister = api.registerHook("Stop", void 0, stopHook);
|
|
15248
15249
|
api.tools.register({
|
|
15249
15250
|
name: "pr_draft",
|
|
15250
15251
|
description: "Generate or refresh the pull-request draft for the current session. Writes the markdown file and returns its path + title.",
|
|
@@ -15277,7 +15278,7 @@ var plugin40 = {
|
|
|
15277
15278
|
try {
|
|
15278
15279
|
await mkdir2(dirname7(resolved), { recursive: true });
|
|
15279
15280
|
await writeFile3(resolved, draft.body);
|
|
15280
|
-
|
|
15281
|
+
state37.draftsWritten += 1;
|
|
15281
15282
|
return {
|
|
15282
15283
|
ok: true,
|
|
15283
15284
|
path: cfg.outputPath,
|
|
@@ -15285,7 +15286,7 @@ var plugin40 = {
|
|
|
15285
15286
|
title: draft.title
|
|
15286
15287
|
};
|
|
15287
15288
|
} catch (err) {
|
|
15288
|
-
|
|
15289
|
+
state37.draftErrors += 1;
|
|
15289
15290
|
return {
|
|
15290
15291
|
ok: false,
|
|
15291
15292
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -15300,48 +15301,48 @@ var plugin40 = {
|
|
|
15300
15301
|
});
|
|
15301
15302
|
},
|
|
15302
15303
|
teardown(api) {
|
|
15303
|
-
if (
|
|
15304
|
+
if (state37.stopHookUnregister) {
|
|
15304
15305
|
try {
|
|
15305
|
-
|
|
15306
|
+
state37.stopHookUnregister();
|
|
15306
15307
|
} catch {
|
|
15307
15308
|
}
|
|
15308
|
-
|
|
15309
|
+
state37.stopHookUnregister = null;
|
|
15309
15310
|
}
|
|
15310
|
-
for (const off of
|
|
15311
|
+
for (const off of state37.eventUnsubscribers) {
|
|
15311
15312
|
try {
|
|
15312
15313
|
off();
|
|
15313
15314
|
} catch {
|
|
15314
15315
|
}
|
|
15315
15316
|
}
|
|
15316
|
-
|
|
15317
|
+
state37.eventUnsubscribers = [];
|
|
15317
15318
|
const final = {
|
|
15318
|
-
commits:
|
|
15319
|
-
files:
|
|
15320
|
-
toolCalls:
|
|
15321
|
-
draftsWritten:
|
|
15322
|
-
draftErrors:
|
|
15319
|
+
commits: state37.commits.length,
|
|
15320
|
+
files: state37.files.size,
|
|
15321
|
+
toolCalls: state37.toolCalls,
|
|
15322
|
+
draftsWritten: state37.draftsWritten,
|
|
15323
|
+
draftErrors: state37.draftErrors
|
|
15323
15324
|
};
|
|
15324
|
-
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15325
|
+
state37.commits = [];
|
|
15326
|
+
state37.files = /* @__PURE__ */ new Set();
|
|
15327
|
+
state37.models = /* @__PURE__ */ new Set();
|
|
15328
|
+
state37.totalInputTokens = 0;
|
|
15329
|
+
state37.totalOutputTokens = 0;
|
|
15330
|
+
state37.toolCalls = 0;
|
|
15331
|
+
state37.draftsWritten = 0;
|
|
15332
|
+
state37.draftErrors = 0;
|
|
15333
|
+
state37.stopInvocations = 0;
|
|
15333
15334
|
api.log.info("pr-drafter: teardown complete", { final });
|
|
15334
15335
|
},
|
|
15335
15336
|
async health() {
|
|
15336
15337
|
return {
|
|
15337
|
-
ok:
|
|
15338
|
-
message: `pr-drafter: ${
|
|
15338
|
+
ok: state37.draftErrors === 0,
|
|
15339
|
+
message: `pr-drafter: ${state37.commits.length} commit(s), ${state37.files.size} file(s), ${state37.draftsWritten} draft(s) written, ${state37.draftErrors} error(s)`,
|
|
15339
15340
|
counters: {
|
|
15340
|
-
commits:
|
|
15341
|
-
files:
|
|
15342
|
-
toolCalls:
|
|
15343
|
-
draftsWritten:
|
|
15344
|
-
draftErrors:
|
|
15341
|
+
commits: state37.commits.length,
|
|
15342
|
+
files: state37.files.size,
|
|
15343
|
+
toolCalls: state37.toolCalls,
|
|
15344
|
+
draftsWritten: state37.draftsWritten,
|
|
15345
|
+
draftErrors: state37.draftErrors
|
|
15345
15346
|
}
|
|
15346
15347
|
};
|
|
15347
15348
|
}
|
|
@@ -15350,7 +15351,7 @@ var pr_drafter_default = plugin40;
|
|
|
15350
15351
|
|
|
15351
15352
|
// src/process-guard/index.ts
|
|
15352
15353
|
import * as os from "node:os";
|
|
15353
|
-
var
|
|
15354
|
+
var state38 = {
|
|
15354
15355
|
invocations: 0,
|
|
15355
15356
|
detections: 0,
|
|
15356
15357
|
warns: 0,
|
|
@@ -15389,16 +15390,16 @@ var plugin41 = {
|
|
|
15389
15390
|
}
|
|
15390
15391
|
},
|
|
15391
15392
|
setup(api) {
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
if (
|
|
15393
|
+
state38.invocations = 0;
|
|
15394
|
+
state38.detections = 0;
|
|
15395
|
+
state38.warns = 0;
|
|
15396
|
+
state38.lastDetection = null;
|
|
15397
|
+
if (state38.hookUnregister) {
|
|
15397
15398
|
try {
|
|
15398
|
-
|
|
15399
|
+
state38.hookUnregister();
|
|
15399
15400
|
} catch {
|
|
15400
15401
|
}
|
|
15401
|
-
|
|
15402
|
+
state38.hookUnregister = null;
|
|
15402
15403
|
}
|
|
15403
15404
|
const cfg = readConfig37(api.config.extensions?.["process-guard"]);
|
|
15404
15405
|
if (cfg.mode === "off") {
|
|
@@ -15407,7 +15408,7 @@ var plugin41 = {
|
|
|
15407
15408
|
}
|
|
15408
15409
|
const hook = (input) => {
|
|
15409
15410
|
if (!cfg.enabled || cfg.mode === "off") return;
|
|
15410
|
-
|
|
15411
|
+
state38.invocations += 1;
|
|
15411
15412
|
const toolName = input.toolName ?? "";
|
|
15412
15413
|
if (toolName !== "bash" && toolName !== "exec") return;
|
|
15413
15414
|
const ti = input.toolInput ?? {};
|
|
@@ -15416,8 +15417,8 @@ var plugin41 = {
|
|
|
15416
15417
|
const cmdLower = command.toLowerCase();
|
|
15417
15418
|
const isKillRelated = cmdLower.includes("kill") || cmdLower.includes("taskkill") || cmdLower.includes("stop-process") || cmdLower.includes("tskill") || cmdLower.includes("pkill") || cmdLower.includes("killall") || cmdLower.includes("wmic");
|
|
15418
15419
|
if (!isKillRelated) return;
|
|
15419
|
-
|
|
15420
|
-
|
|
15420
|
+
state38.detections += 1;
|
|
15421
|
+
state38.lastDetection = {
|
|
15421
15422
|
target: command.slice(0, 100),
|
|
15422
15423
|
tool: toolName,
|
|
15423
15424
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -15431,7 +15432,7 @@ var plugin41 = {
|
|
|
15431
15432
|
}
|
|
15432
15433
|
);
|
|
15433
15434
|
};
|
|
15434
|
-
|
|
15435
|
+
state38.hookUnregister = api.registerHook("PreToolUse", "bash|exec", hook, {
|
|
15435
15436
|
name: "process-guard",
|
|
15436
15437
|
stage: "validate",
|
|
15437
15438
|
failurePolicy: "closed",
|
|
@@ -15453,11 +15454,11 @@ var plugin41 = {
|
|
|
15453
15454
|
selfPid: process.pid,
|
|
15454
15455
|
parentPid: process.ppid,
|
|
15455
15456
|
counters: {
|
|
15456
|
-
invocations:
|
|
15457
|
-
detections:
|
|
15458
|
-
warns:
|
|
15457
|
+
invocations: state38.invocations,
|
|
15458
|
+
detections: state38.detections,
|
|
15459
|
+
warns: state38.warns
|
|
15459
15460
|
},
|
|
15460
|
-
lastDetection:
|
|
15461
|
+
lastDetection: state38.lastDetection
|
|
15461
15462
|
};
|
|
15462
15463
|
}
|
|
15463
15464
|
});
|
|
@@ -15470,27 +15471,27 @@ var plugin41 = {
|
|
|
15470
15471
|
});
|
|
15471
15472
|
},
|
|
15472
15473
|
teardown(api) {
|
|
15473
|
-
if (
|
|
15474
|
+
if (state38.hookUnregister) {
|
|
15474
15475
|
try {
|
|
15475
|
-
|
|
15476
|
+
state38.hookUnregister();
|
|
15476
15477
|
} catch {
|
|
15477
15478
|
}
|
|
15478
|
-
|
|
15479
|
+
state38.hookUnregister = null;
|
|
15479
15480
|
}
|
|
15480
15481
|
const final = {
|
|
15481
|
-
invocations:
|
|
15482
|
-
detections:
|
|
15483
|
-
warns:
|
|
15482
|
+
invocations: state38.invocations,
|
|
15483
|
+
detections: state38.detections,
|
|
15484
|
+
warns: state38.warns
|
|
15484
15485
|
};
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15486
|
+
state38.invocations = 0;
|
|
15487
|
+
state38.detections = 0;
|
|
15488
|
+
state38.warns = 0;
|
|
15488
15489
|
api.log.info("[process-guard] teardown complete", { final });
|
|
15489
15490
|
},
|
|
15490
15491
|
async health() {
|
|
15491
15492
|
return {
|
|
15492
15493
|
ok: true,
|
|
15493
|
-
message:
|
|
15494
|
+
message: state38.lastDetection === null ? `process-guard: ${state38.invocations} invocation(s), ${state38.detections} detection(s), ${state38.warns} warn(s)` : `process-guard: last detection on "${state38.lastDetection.tool}" at ${state38.lastDetection.when}`
|
|
15494
15495
|
};
|
|
15495
15496
|
}
|
|
15496
15497
|
};
|
|
@@ -15723,7 +15724,7 @@ function readConfig38(raw) {
|
|
|
15723
15724
|
allow
|
|
15724
15725
|
};
|
|
15725
15726
|
}
|
|
15726
|
-
var
|
|
15727
|
+
var state39 = {
|
|
15727
15728
|
invocations: 0,
|
|
15728
15729
|
requestsWithSecrets: 0,
|
|
15729
15730
|
requestRedactions: 0,
|
|
@@ -15768,19 +15769,19 @@ var plugin42 = {
|
|
|
15768
15769
|
}
|
|
15769
15770
|
},
|
|
15770
15771
|
setup(api) {
|
|
15771
|
-
|
|
15772
|
-
|
|
15773
|
-
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
|
|
15777
|
-
|
|
15778
|
-
if (
|
|
15772
|
+
state39.invocations = 0;
|
|
15773
|
+
state39.requestsWithSecrets = 0;
|
|
15774
|
+
state39.requestRedactions = 0;
|
|
15775
|
+
state39.responseRedactions = 0;
|
|
15776
|
+
state39.blocked = 0;
|
|
15777
|
+
state39.byKind.clear();
|
|
15778
|
+
state39.lastDetection = null;
|
|
15779
|
+
if (state39.extensionUnregister) {
|
|
15779
15780
|
try {
|
|
15780
|
-
|
|
15781
|
+
state39.extensionUnregister();
|
|
15781
15782
|
} catch {
|
|
15782
15783
|
}
|
|
15783
|
-
|
|
15784
|
+
state39.extensionUnregister = null;
|
|
15784
15785
|
}
|
|
15785
15786
|
const cfg = readConfig38(api.config.extensions?.["prompt-firewall"]);
|
|
15786
15787
|
if (cfg.enabled) {
|
|
@@ -15789,25 +15790,25 @@ var plugin42 = {
|
|
|
15789
15790
|
kind: "security",
|
|
15790
15791
|
wraps: ["request", "response"]
|
|
15791
15792
|
});
|
|
15792
|
-
|
|
15793
|
+
state39.extensionUnregister = api.extensions.register({
|
|
15793
15794
|
name: "prompt-firewall",
|
|
15794
15795
|
owner: "prompt-firewall",
|
|
15795
15796
|
async wrapProviderRunner(_ctx, request, inner) {
|
|
15796
15797
|
const req = request ?? {};
|
|
15797
|
-
|
|
15798
|
+
state39.invocations += 1;
|
|
15798
15799
|
const detections = detectSecrets(collectText(req), cfg.allow);
|
|
15799
15800
|
if (detections.length > 0) {
|
|
15800
|
-
|
|
15801
|
+
state39.requestsWithSecrets += 1;
|
|
15801
15802
|
for (const d of detections) {
|
|
15802
|
-
|
|
15803
|
+
state39.byKind.set(d.kind, (state39.byKind.get(d.kind) ?? 0) + d.count);
|
|
15803
15804
|
}
|
|
15804
15805
|
const kinds = detections.map((d) => d.kind);
|
|
15805
|
-
|
|
15806
|
+
state39.lastDetection = { where: "request", kinds, when: (/* @__PURE__ */ new Date()).toISOString() };
|
|
15806
15807
|
api.metrics.counter("request_leaks", 1);
|
|
15807
15808
|
api.log.warn("prompt-firewall: secrets detected in outgoing request", { kinds });
|
|
15808
15809
|
api.emitCustom("prompt-firewall:leak", { where: "request", kinds });
|
|
15809
15810
|
if (cfg.mode === "block") {
|
|
15810
|
-
|
|
15811
|
+
state39.blocked += 1;
|
|
15811
15812
|
throw new Error(
|
|
15812
15813
|
`prompt-firewall blocked a provider call: outgoing context contains credential-shaped data (${kinds.join(", ")}). Remove the secret from context, add an \`allow\` pattern, or switch mode to "warn".`
|
|
15813
15814
|
);
|
|
@@ -15815,7 +15816,7 @@ var plugin42 = {
|
|
|
15815
15816
|
if (cfg.mode === "redact") {
|
|
15816
15817
|
const counter = { n: 0 };
|
|
15817
15818
|
const redactedReq = redactDeep(req, cfg.allow, counter);
|
|
15818
|
-
|
|
15819
|
+
state39.requestRedactions += counter.n;
|
|
15819
15820
|
api.metrics.counter("request_redactions", counter.n);
|
|
15820
15821
|
const response2 = await inner(_ctx, redactedReq);
|
|
15821
15822
|
return cfg.scanResponse ? redactResponse(response2, cfg.allow) : response2;
|
|
@@ -15836,9 +15837,9 @@ var plugin42 = {
|
|
|
15836
15837
|
if (content === void 0) return response;
|
|
15837
15838
|
const redacted = redactDeep(content, allow, counter);
|
|
15838
15839
|
if (counter.n > 0) {
|
|
15839
|
-
|
|
15840
|
+
state39.responseRedactions += counter.n;
|
|
15840
15841
|
api.metrics.counter("response_redactions", counter.n);
|
|
15841
|
-
|
|
15842
|
+
state39.lastDetection = {
|
|
15842
15843
|
where: "response",
|
|
15843
15844
|
kinds: ["echoed-secret"],
|
|
15844
15845
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -15861,14 +15862,14 @@ var plugin42 = {
|
|
|
15861
15862
|
scanResponse: cfg.scanResponse,
|
|
15862
15863
|
patterns: PATTERNS2.map((p) => p.kind),
|
|
15863
15864
|
counters: {
|
|
15864
|
-
invocations:
|
|
15865
|
-
requestsWithSecrets:
|
|
15866
|
-
requestRedactions:
|
|
15867
|
-
responseRedactions:
|
|
15868
|
-
blocked:
|
|
15865
|
+
invocations: state39.invocations,
|
|
15866
|
+
requestsWithSecrets: state39.requestsWithSecrets,
|
|
15867
|
+
requestRedactions: state39.requestRedactions,
|
|
15868
|
+
responseRedactions: state39.responseRedactions,
|
|
15869
|
+
blocked: state39.blocked
|
|
15869
15870
|
},
|
|
15870
|
-
byKind: Object.fromEntries(
|
|
15871
|
-
lastDetection:
|
|
15871
|
+
byKind: Object.fromEntries(state39.byKind),
|
|
15872
|
+
lastDetection: state39.lastDetection
|
|
15872
15873
|
};
|
|
15873
15874
|
}
|
|
15874
15875
|
});
|
|
@@ -15880,39 +15881,39 @@ var plugin42 = {
|
|
|
15880
15881
|
});
|
|
15881
15882
|
},
|
|
15882
15883
|
teardown(api) {
|
|
15883
|
-
if (
|
|
15884
|
+
if (state39.extensionUnregister) {
|
|
15884
15885
|
try {
|
|
15885
|
-
|
|
15886
|
+
state39.extensionUnregister();
|
|
15886
15887
|
} catch {
|
|
15887
15888
|
}
|
|
15888
|
-
|
|
15889
|
+
state39.extensionUnregister = null;
|
|
15889
15890
|
}
|
|
15890
15891
|
const final = {
|
|
15891
|
-
invocations:
|
|
15892
|
-
requestsWithSecrets:
|
|
15893
|
-
requestRedactions:
|
|
15894
|
-
responseRedactions:
|
|
15895
|
-
blocked:
|
|
15892
|
+
invocations: state39.invocations,
|
|
15893
|
+
requestsWithSecrets: state39.requestsWithSecrets,
|
|
15894
|
+
requestRedactions: state39.requestRedactions,
|
|
15895
|
+
responseRedactions: state39.responseRedactions,
|
|
15896
|
+
blocked: state39.blocked
|
|
15896
15897
|
};
|
|
15897
|
-
|
|
15898
|
-
|
|
15899
|
-
|
|
15900
|
-
|
|
15901
|
-
|
|
15902
|
-
|
|
15903
|
-
|
|
15898
|
+
state39.invocations = 0;
|
|
15899
|
+
state39.requestsWithSecrets = 0;
|
|
15900
|
+
state39.requestRedactions = 0;
|
|
15901
|
+
state39.responseRedactions = 0;
|
|
15902
|
+
state39.blocked = 0;
|
|
15903
|
+
state39.byKind.clear();
|
|
15904
|
+
state39.lastDetection = null;
|
|
15904
15905
|
api.log.info("prompt-firewall: teardown complete", { final });
|
|
15905
15906
|
},
|
|
15906
15907
|
async health() {
|
|
15907
15908
|
return {
|
|
15908
15909
|
ok: true,
|
|
15909
|
-
message: `prompt-firewall: ${
|
|
15910
|
+
message: `prompt-firewall: ${state39.requestsWithSecrets} request(s) with secrets, ${state39.requestRedactions} request redaction(s), ${state39.blocked} blocked`,
|
|
15910
15911
|
counters: {
|
|
15911
|
-
invocations:
|
|
15912
|
-
requestsWithSecrets:
|
|
15913
|
-
requestRedactions:
|
|
15914
|
-
responseRedactions:
|
|
15915
|
-
blocked:
|
|
15912
|
+
invocations: state39.invocations,
|
|
15913
|
+
requestsWithSecrets: state39.requestsWithSecrets,
|
|
15914
|
+
requestRedactions: state39.requestRedactions,
|
|
15915
|
+
responseRedactions: state39.responseRedactions,
|
|
15916
|
+
blocked: state39.blocked
|
|
15916
15917
|
}
|
|
15917
15918
|
};
|
|
15918
15919
|
}
|
|
@@ -15924,7 +15925,7 @@ import { readFile as readFile11 } from "node:fs/promises";
|
|
|
15924
15925
|
import { isAbsolute as isAbsolute20, relative as relative20, resolve as resolve20 } from "node:path";
|
|
15925
15926
|
var API_VERSION27 = "^0.1.10";
|
|
15926
15927
|
var HOOK_WARNING_COOLDOWN_MS2 = 6e4;
|
|
15927
|
-
var
|
|
15928
|
+
var state40 = {
|
|
15928
15929
|
scanCount: 0,
|
|
15929
15930
|
suggestionCount: 0,
|
|
15930
15931
|
hookInvocationCount: 0,
|
|
@@ -16112,18 +16113,18 @@ var plugin43 = {
|
|
|
16112
16113
|
}
|
|
16113
16114
|
},
|
|
16114
16115
|
setup(api) {
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
if (
|
|
16116
|
+
state40.scanCount = 0;
|
|
16117
|
+
state40.suggestionCount = 0;
|
|
16118
|
+
state40.hookInvocationCount = 0;
|
|
16119
|
+
state40.warningCount = 0;
|
|
16120
|
+
state40.errorCount = 0;
|
|
16121
|
+
state40.lastHookWarning.clear();
|
|
16122
|
+
if (state40.hookUnregister) {
|
|
16122
16123
|
try {
|
|
16123
|
-
|
|
16124
|
+
state40.hookUnregister();
|
|
16124
16125
|
} catch {
|
|
16125
16126
|
}
|
|
16126
|
-
|
|
16127
|
+
state40.hookUnregister = null;
|
|
16127
16128
|
}
|
|
16128
16129
|
const cfg = readConfig39(api.config.extensions?.["refactor-suggester"]);
|
|
16129
16130
|
const hook = async (input) => {
|
|
@@ -16135,28 +16136,28 @@ var plugin43 = {
|
|
|
16135
16136
|
if (!withinProject(sourcePath)) return;
|
|
16136
16137
|
const exts = normalizeExtensions5(cfg.extensions);
|
|
16137
16138
|
if (!matchesExtension(sourcePath, exts)) return;
|
|
16138
|
-
|
|
16139
|
+
state40.hookInvocationCount += 1;
|
|
16139
16140
|
const now = Date.now();
|
|
16140
|
-
const lastWarning =
|
|
16141
|
+
const lastWarning = state40.lastHookWarning.get(sourcePath);
|
|
16141
16142
|
if (lastWarning !== void 0 && now - lastWarning < HOOK_WARNING_COOLDOWN_MS2) return;
|
|
16142
16143
|
const resolved = resolve20(process.cwd(), sourcePath);
|
|
16143
16144
|
let content;
|
|
16144
16145
|
try {
|
|
16145
16146
|
content = await readFile11(resolved, "utf-8");
|
|
16146
16147
|
} catch {
|
|
16147
|
-
|
|
16148
|
+
state40.errorCount += 1;
|
|
16148
16149
|
return;
|
|
16149
16150
|
}
|
|
16150
16151
|
const suggestions = detectSmells(resolved, content, cfg.rules);
|
|
16151
16152
|
if (suggestions.length === 0) return;
|
|
16152
|
-
|
|
16153
|
-
|
|
16153
|
+
state40.warningCount += suggestions.length;
|
|
16154
|
+
state40.lastHookWarning.set(sourcePath, now);
|
|
16154
16155
|
return {
|
|
16155
16156
|
additionalContext: `\u{1F527} refactor-suggester: ${suggestions.length} suggestion(s) for ${sourcePath}. Run suggest_refactors for the full list.`,
|
|
16156
16157
|
contextAs: "separate"
|
|
16157
16158
|
};
|
|
16158
16159
|
};
|
|
16159
|
-
|
|
16160
|
+
state40.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, { background: true });
|
|
16160
16161
|
api.tools.register({
|
|
16161
16162
|
name: "suggest_refactors",
|
|
16162
16163
|
description: "Scan source files for refactoring smells: long functions, deep nesting, many parameters, magic numbers, and console logging.",
|
|
@@ -16175,15 +16176,15 @@ var plugin43 = {
|
|
|
16175
16176
|
if (!withinProject(rawPath)) {
|
|
16176
16177
|
return { ok: false, error: "path is outside the project root" };
|
|
16177
16178
|
}
|
|
16178
|
-
|
|
16179
|
+
state40.scanCount += 1;
|
|
16179
16180
|
let result;
|
|
16180
16181
|
try {
|
|
16181
16182
|
result = await scanPath4(rawPath, cfg);
|
|
16182
16183
|
} catch (err) {
|
|
16183
|
-
|
|
16184
|
+
state40.errorCount += 1;
|
|
16184
16185
|
return { ok: false, error: String(err) };
|
|
16185
16186
|
}
|
|
16186
|
-
|
|
16187
|
+
state40.suggestionCount += result.suggestions.length;
|
|
16187
16188
|
return {
|
|
16188
16189
|
ok: true,
|
|
16189
16190
|
path: relativePath6(resolve20(process.cwd(), rawPath)),
|
|
@@ -16212,11 +16213,11 @@ var plugin43 = {
|
|
|
16212
16213
|
maxSuggestions: cfg.maxSuggestions,
|
|
16213
16214
|
rules: cfg.rules,
|
|
16214
16215
|
counters: {
|
|
16215
|
-
scans:
|
|
16216
|
-
suggestions:
|
|
16217
|
-
hookInvocations:
|
|
16218
|
-
warnings:
|
|
16219
|
-
errors:
|
|
16216
|
+
scans: state40.scanCount,
|
|
16217
|
+
suggestions: state40.suggestionCount,
|
|
16218
|
+
hookInvocations: state40.hookInvocationCount,
|
|
16219
|
+
warnings: state40.warningCount,
|
|
16220
|
+
errors: state40.errorCount
|
|
16220
16221
|
}
|
|
16221
16222
|
};
|
|
16222
16223
|
}
|
|
@@ -16228,38 +16229,38 @@ var plugin43 = {
|
|
|
16228
16229
|
});
|
|
16229
16230
|
},
|
|
16230
16231
|
teardown(api) {
|
|
16231
|
-
if (
|
|
16232
|
+
if (state40.hookUnregister) {
|
|
16232
16233
|
try {
|
|
16233
|
-
|
|
16234
|
+
state40.hookUnregister();
|
|
16234
16235
|
} catch {
|
|
16235
16236
|
}
|
|
16236
|
-
|
|
16237
|
+
state40.hookUnregister = null;
|
|
16237
16238
|
}
|
|
16238
16239
|
const final = {
|
|
16239
|
-
scans:
|
|
16240
|
-
suggestions:
|
|
16241
|
-
hookInvocations:
|
|
16242
|
-
warnings:
|
|
16243
|
-
errors:
|
|
16240
|
+
scans: state40.scanCount,
|
|
16241
|
+
suggestions: state40.suggestionCount,
|
|
16242
|
+
hookInvocations: state40.hookInvocationCount,
|
|
16243
|
+
warnings: state40.warningCount,
|
|
16244
|
+
errors: state40.errorCount
|
|
16244
16245
|
};
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16249
|
-
|
|
16250
|
-
|
|
16246
|
+
state40.scanCount = 0;
|
|
16247
|
+
state40.suggestionCount = 0;
|
|
16248
|
+
state40.hookInvocationCount = 0;
|
|
16249
|
+
state40.warningCount = 0;
|
|
16250
|
+
state40.errorCount = 0;
|
|
16251
|
+
state40.lastHookWarning.clear();
|
|
16251
16252
|
api.log.info("refactor-suggester: teardown complete", { final });
|
|
16252
16253
|
},
|
|
16253
16254
|
async health() {
|
|
16254
16255
|
return {
|
|
16255
|
-
ok:
|
|
16256
|
-
message:
|
|
16256
|
+
ok: state40.errorCount === 0,
|
|
16257
|
+
message: state40.errorCount ? `refactor-suggester: ${state40.errorCount} error(s)` : `refactor-suggester: ${state40.scanCount} scan(s), ${state40.suggestionCount} suggestion(s)`,
|
|
16257
16258
|
counters: {
|
|
16258
|
-
scans:
|
|
16259
|
-
suggestions:
|
|
16260
|
-
hookInvocations:
|
|
16261
|
-
warnings:
|
|
16262
|
-
errors:
|
|
16259
|
+
scans: state40.scanCount,
|
|
16260
|
+
suggestions: state40.suggestionCount,
|
|
16261
|
+
hookInvocations: state40.hookInvocationCount,
|
|
16262
|
+
warnings: state40.warningCount,
|
|
16263
|
+
errors: state40.errorCount
|
|
16263
16264
|
}
|
|
16264
16265
|
};
|
|
16265
16266
|
}
|
|
@@ -16269,7 +16270,7 @@ var refactor_suggester_default = plugin43;
|
|
|
16269
16270
|
// src/release-notes-generator/index.ts
|
|
16270
16271
|
import { execFile as execFile11 } from "node:child_process";
|
|
16271
16272
|
var API_VERSION28 = "^0.1.10";
|
|
16272
|
-
var
|
|
16273
|
+
var state41 = {
|
|
16273
16274
|
generateCount: 0,
|
|
16274
16275
|
commitCount: 0,
|
|
16275
16276
|
errorCount: 0,
|
|
@@ -16474,11 +16475,11 @@ var plugin44 = {
|
|
|
16474
16475
|
}
|
|
16475
16476
|
},
|
|
16476
16477
|
setup(api) {
|
|
16477
|
-
|
|
16478
|
-
|
|
16479
|
-
|
|
16480
|
-
|
|
16481
|
-
|
|
16478
|
+
state41.generateCount = 0;
|
|
16479
|
+
state41.commitCount = 0;
|
|
16480
|
+
state41.errorCount = 0;
|
|
16481
|
+
state41.llmPolishCount = 0;
|
|
16482
|
+
state41.llmFallbackCount = 0;
|
|
16482
16483
|
const cfg = readConfig40(api.config.extensions?.["release-notes-generator"]);
|
|
16483
16484
|
api.tools.register({
|
|
16484
16485
|
name: "generate_release_notes",
|
|
@@ -16514,15 +16515,15 @@ var plugin44 = {
|
|
|
16514
16515
|
execOpts?.signal?.throwIfAborted();
|
|
16515
16516
|
const toRef = typeof input.to === "string" ? input.to : "HEAD";
|
|
16516
16517
|
const fromRef = await resolveFromRef(cfg.defaultFrom, input.from, execOpts?.signal);
|
|
16517
|
-
|
|
16518
|
+
state41.generateCount += 1;
|
|
16518
16519
|
let commits;
|
|
16519
16520
|
try {
|
|
16520
16521
|
commits = await getCommits(fromRef, toRef, execOpts?.signal);
|
|
16521
16522
|
} catch (err) {
|
|
16522
|
-
|
|
16523
|
+
state41.errorCount += 1;
|
|
16523
16524
|
return { ok: false, error: String(err) };
|
|
16524
16525
|
}
|
|
16525
|
-
|
|
16526
|
+
state41.commitCount += commits.length;
|
|
16526
16527
|
execOpts?.signal?.throwIfAborted();
|
|
16527
16528
|
const deterministicNotes = generateNotes(commits, cfg.includeScope);
|
|
16528
16529
|
const requested = (input.use_llm ?? cfg.useLlm) && commits.length > 0;
|
|
@@ -16541,8 +16542,8 @@ var plugin44 = {
|
|
|
16541
16542
|
},
|
|
16542
16543
|
parse: (text) => parsePolishedNotes(text, commits)
|
|
16543
16544
|
});
|
|
16544
|
-
if (llm.used)
|
|
16545
|
-
else if (requested)
|
|
16545
|
+
if (llm.used) state41.llmPolishCount += 1;
|
|
16546
|
+
else if (requested) state41.llmFallbackCount += 1;
|
|
16546
16547
|
api.metrics.counter("generations", 1);
|
|
16547
16548
|
api.metrics.counter("commits_processed", commits.length);
|
|
16548
16549
|
if (llm.used) api.metrics.counter("llm_polishes", 1, { audience });
|
|
@@ -16571,29 +16572,29 @@ var plugin44 = {
|
|
|
16571
16572
|
},
|
|
16572
16573
|
teardown(api) {
|
|
16573
16574
|
const final = {
|
|
16574
|
-
generated:
|
|
16575
|
-
commits:
|
|
16576
|
-
errors:
|
|
16577
|
-
llmPolishes:
|
|
16578
|
-
llmFallbacks:
|
|
16575
|
+
generated: state41.generateCount,
|
|
16576
|
+
commits: state41.commitCount,
|
|
16577
|
+
errors: state41.errorCount,
|
|
16578
|
+
llmPolishes: state41.llmPolishCount,
|
|
16579
|
+
llmFallbacks: state41.llmFallbackCount
|
|
16579
16580
|
};
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16584
|
-
|
|
16581
|
+
state41.generateCount = 0;
|
|
16582
|
+
state41.commitCount = 0;
|
|
16583
|
+
state41.errorCount = 0;
|
|
16584
|
+
state41.llmPolishCount = 0;
|
|
16585
|
+
state41.llmFallbackCount = 0;
|
|
16585
16586
|
api.log.info("release-notes-generator: teardown complete", { final });
|
|
16586
16587
|
},
|
|
16587
16588
|
async health() {
|
|
16588
16589
|
return {
|
|
16589
|
-
ok:
|
|
16590
|
-
message:
|
|
16590
|
+
ok: state41.errorCount === 0,
|
|
16591
|
+
message: state41.errorCount ? `release-notes-generator: ${state41.errorCount} error(s)` : `release-notes-generator: ${state41.generateCount} generation(s), ${state41.commitCount} commit(s)`,
|
|
16591
16592
|
counters: {
|
|
16592
|
-
generated:
|
|
16593
|
-
commits:
|
|
16594
|
-
errors:
|
|
16595
|
-
llmPolishes:
|
|
16596
|
-
llmFallbacks:
|
|
16593
|
+
generated: state41.generateCount,
|
|
16594
|
+
commits: state41.commitCount,
|
|
16595
|
+
errors: state41.errorCount,
|
|
16596
|
+
llmPolishes: state41.llmPolishCount,
|
|
16597
|
+
llmFallbacks: state41.llmFallbackCount
|
|
16597
16598
|
}
|
|
16598
16599
|
};
|
|
16599
16600
|
}
|
|
@@ -16604,7 +16605,7 @@ var release_notes_generator_default = plugin44;
|
|
|
16604
16605
|
import { readFileSync as readFileSync12 } from "node:fs";
|
|
16605
16606
|
import { basename as basename5 } from "node:path";
|
|
16606
16607
|
var API_VERSION29 = "^0.1.10";
|
|
16607
|
-
var
|
|
16608
|
+
var state42 = {
|
|
16608
16609
|
invocationCount: 0,
|
|
16609
16610
|
scannedCount: 0,
|
|
16610
16611
|
skippedCount: 0,
|
|
@@ -16767,19 +16768,19 @@ var plugin45 = {
|
|
|
16767
16768
|
}
|
|
16768
16769
|
},
|
|
16769
16770
|
setup(api) {
|
|
16770
|
-
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
|
|
16775
|
-
|
|
16776
|
-
|
|
16777
|
-
if (
|
|
16771
|
+
state42.invocationCount = 0;
|
|
16772
|
+
state42.scannedCount = 0;
|
|
16773
|
+
state42.skippedCount = 0;
|
|
16774
|
+
state42.hitCount = 0;
|
|
16775
|
+
state42.warningCount = 0;
|
|
16776
|
+
state42.blockedCount = 0;
|
|
16777
|
+
state42.lastFinding = null;
|
|
16778
|
+
if (state42.hookUnregister) {
|
|
16778
16779
|
try {
|
|
16779
|
-
|
|
16780
|
+
state42.hookUnregister();
|
|
16780
16781
|
} catch {
|
|
16781
16782
|
}
|
|
16782
|
-
|
|
16783
|
+
state42.hookUnregister = null;
|
|
16783
16784
|
}
|
|
16784
16785
|
const cfg = readConfig41(api.config.extensions?.["schema-evolution-guard"]);
|
|
16785
16786
|
const hook = (input) => {
|
|
@@ -16788,15 +16789,15 @@ var plugin45 = {
|
|
|
16788
16789
|
const toolInput = input.toolInput ?? {};
|
|
16789
16790
|
const filePath = typeof toolInput["path"] === "string" ? toolInput["path"] : void 0;
|
|
16790
16791
|
if (!filePath) return;
|
|
16791
|
-
|
|
16792
|
+
state42.invocationCount += 1;
|
|
16792
16793
|
const fileName = basename5(filePath);
|
|
16793
16794
|
if (!matchesAnyPattern2(fileName, cfg.filePatterns)) {
|
|
16794
|
-
|
|
16795
|
+
state42.skippedCount += 1;
|
|
16795
16796
|
return;
|
|
16796
16797
|
}
|
|
16797
16798
|
const kind = fileKind(fileName);
|
|
16798
16799
|
if (!kind) {
|
|
16799
|
-
|
|
16800
|
+
state42.skippedCount += 1;
|
|
16800
16801
|
return;
|
|
16801
16802
|
}
|
|
16802
16803
|
let content;
|
|
@@ -16810,14 +16811,14 @@ var plugin45 = {
|
|
|
16810
16811
|
}
|
|
16811
16812
|
}
|
|
16812
16813
|
if (content === void 0) {
|
|
16813
|
-
|
|
16814
|
+
state42.skippedCount += 1;
|
|
16814
16815
|
return;
|
|
16815
16816
|
}
|
|
16816
|
-
|
|
16817
|
+
state42.scannedCount += 1;
|
|
16817
16818
|
const findings = findIssues(content, kind, cfg.maxFindings);
|
|
16818
16819
|
if (findings.length === 0) return;
|
|
16819
|
-
|
|
16820
|
-
|
|
16820
|
+
state42.hitCount += 1;
|
|
16821
|
+
state42.lastFinding = findings[0] ?? null;
|
|
16821
16822
|
const header = `
|
|
16822
16823
|
\u26A0\uFE0F schema-evolution-guard: destructive schema pattern(s) detected in ${filePath}`;
|
|
16823
16824
|
const body = findings.map((f) => ` - ${f}`).join("\n");
|
|
@@ -16825,13 +16826,13 @@ var plugin45 = {
|
|
|
16825
16826
|
const message = `${header}
|
|
16826
16827
|
${body}${suffix}`;
|
|
16827
16828
|
if (cfg.failSeverity === "block") {
|
|
16828
|
-
|
|
16829
|
+
state42.blockedCount += 1;
|
|
16829
16830
|
return { decision: "block", reason: message };
|
|
16830
16831
|
}
|
|
16831
|
-
|
|
16832
|
+
state42.warningCount += 1;
|
|
16832
16833
|
return { additionalContext: message };
|
|
16833
16834
|
};
|
|
16834
|
-
|
|
16835
|
+
state42.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, { background: true });
|
|
16835
16836
|
api.tools.register({
|
|
16836
16837
|
name: "schema_evolution_status",
|
|
16837
16838
|
description: "Reports schema-evolution-guard state: config, file patterns, and per-session counters.",
|
|
@@ -16847,14 +16848,14 @@ ${body}${suffix}`;
|
|
|
16847
16848
|
maxFindings: cfg.maxFindings,
|
|
16848
16849
|
filePatterns: cfg.filePatterns,
|
|
16849
16850
|
counters: {
|
|
16850
|
-
invocations:
|
|
16851
|
-
scanned:
|
|
16852
|
-
skipped:
|
|
16853
|
-
hits:
|
|
16854
|
-
warnings:
|
|
16855
|
-
blocked:
|
|
16851
|
+
invocations: state42.invocationCount,
|
|
16852
|
+
scanned: state42.scannedCount,
|
|
16853
|
+
skipped: state42.skippedCount,
|
|
16854
|
+
hits: state42.hitCount,
|
|
16855
|
+
warnings: state42.warningCount,
|
|
16856
|
+
blocked: state42.blockedCount
|
|
16856
16857
|
},
|
|
16857
|
-
lastFinding:
|
|
16858
|
+
lastFinding: state42.lastFinding
|
|
16858
16859
|
};
|
|
16859
16860
|
}
|
|
16860
16861
|
});
|
|
@@ -16865,43 +16866,43 @@ ${body}${suffix}`;
|
|
|
16865
16866
|
});
|
|
16866
16867
|
},
|
|
16867
16868
|
teardown(api) {
|
|
16868
|
-
if (
|
|
16869
|
+
if (state42.hookUnregister) {
|
|
16869
16870
|
try {
|
|
16870
|
-
|
|
16871
|
+
state42.hookUnregister();
|
|
16871
16872
|
} catch {
|
|
16872
16873
|
}
|
|
16873
|
-
|
|
16874
|
+
state42.hookUnregister = null;
|
|
16874
16875
|
}
|
|
16875
16876
|
const final = {
|
|
16876
|
-
invocations:
|
|
16877
|
-
scanned:
|
|
16878
|
-
skipped:
|
|
16879
|
-
hits:
|
|
16880
|
-
warnings:
|
|
16881
|
-
blocked:
|
|
16877
|
+
invocations: state42.invocationCount,
|
|
16878
|
+
scanned: state42.scannedCount,
|
|
16879
|
+
skipped: state42.skippedCount,
|
|
16880
|
+
hits: state42.hitCount,
|
|
16881
|
+
warnings: state42.warningCount,
|
|
16882
|
+
blocked: state42.blockedCount
|
|
16882
16883
|
};
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
16889
|
-
|
|
16884
|
+
state42.invocationCount = 0;
|
|
16885
|
+
state42.scannedCount = 0;
|
|
16886
|
+
state42.skippedCount = 0;
|
|
16887
|
+
state42.hitCount = 0;
|
|
16888
|
+
state42.warningCount = 0;
|
|
16889
|
+
state42.blockedCount = 0;
|
|
16890
|
+
state42.lastFinding = null;
|
|
16890
16891
|
api.log.info("schema-evolution-guard: teardown complete", { final });
|
|
16891
16892
|
},
|
|
16892
16893
|
async health() {
|
|
16893
16894
|
return {
|
|
16894
16895
|
ok: true,
|
|
16895
|
-
message: `schema-evolution-guard: ${
|
|
16896
|
+
message: `schema-evolution-guard: ${state42.scannedCount} scan(s), ${state42.hitCount} hit(s), ${state42.blockedCount} blocked`,
|
|
16896
16897
|
counters: {
|
|
16897
|
-
invocations:
|
|
16898
|
-
scanned:
|
|
16899
|
-
skipped:
|
|
16900
|
-
hits:
|
|
16901
|
-
warnings:
|
|
16902
|
-
blocked:
|
|
16903
|
-
},
|
|
16904
|
-
lastFinding:
|
|
16898
|
+
invocations: state42.invocationCount,
|
|
16899
|
+
scanned: state42.scannedCount,
|
|
16900
|
+
skipped: state42.skippedCount,
|
|
16901
|
+
hits: state42.hitCount,
|
|
16902
|
+
warnings: state42.warningCount,
|
|
16903
|
+
blocked: state42.blockedCount
|
|
16904
|
+
},
|
|
16905
|
+
lastFinding: state42.lastFinding
|
|
16905
16906
|
};
|
|
16906
16907
|
}
|
|
16907
16908
|
};
|
|
@@ -16910,7 +16911,6 @@ var schema_evolution_guard_default = plugin45;
|
|
|
16910
16911
|
// src/secret-scanner/index.ts
|
|
16911
16912
|
var BASE_PATTERNS = cloneCredentialPatterns();
|
|
16912
16913
|
var PATTERNS3 = [...BASE_PATTERNS];
|
|
16913
|
-
var patternCacheKey = "";
|
|
16914
16914
|
var GROUP_INDEX_OF_PATTERN = [];
|
|
16915
16915
|
var COMBINED_REGEX = buildCombinedRegex(PATTERNS3);
|
|
16916
16916
|
var SCAN_WINDOW_LENGTH = 1e5;
|
|
@@ -16933,11 +16933,6 @@ function patternTypeForGroups(groups) {
|
|
|
16933
16933
|
return void 0;
|
|
16934
16934
|
}
|
|
16935
16935
|
function buildCombinedRegex(patterns) {
|
|
16936
|
-
const newCacheKey = JSON.stringify(patterns.map((p) => [p.type, p.regex.source]));
|
|
16937
|
-
if (newCacheKey === patternCacheKey && COMBINED_REGEX) {
|
|
16938
|
-
return COMBINED_REGEX;
|
|
16939
|
-
}
|
|
16940
|
-
patternCacheKey = newCacheKey;
|
|
16941
16936
|
const offsets = [];
|
|
16942
16937
|
let cursor = 0;
|
|
16943
16938
|
for (const p of patterns) {
|
|
@@ -16947,21 +16942,30 @@ function buildCombinedRegex(patterns) {
|
|
|
16947
16942
|
GROUP_INDEX_OF_PATTERN = offsets;
|
|
16948
16943
|
return new RegExp(patterns.map((p) => `(${p.regex.source})`).join("|"), "g");
|
|
16949
16944
|
}
|
|
16950
|
-
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
|
|
16954
|
-
|
|
16955
|
-
|
|
16956
|
-
|
|
16957
|
-
|
|
16958
|
-
|
|
16959
|
-
|
|
16960
|
-
|
|
16961
|
-
|
|
16962
|
-
|
|
16963
|
-
|
|
16964
|
-
|
|
16945
|
+
function createState2() {
|
|
16946
|
+
return {
|
|
16947
|
+
blockCount: 0,
|
|
16948
|
+
redactCount: 0,
|
|
16949
|
+
allowCount: 0,
|
|
16950
|
+
/** PostToolUse: secrets detected in tool output. */
|
|
16951
|
+
leakCount: 0,
|
|
16952
|
+
/** Most recent PreToolUse block — surfaced by `secret_scanner_status`. */
|
|
16953
|
+
lastBlock: null,
|
|
16954
|
+
/** Most recent PostToolUse leak — surfaced by `secret_scanner_status`. */
|
|
16955
|
+
lastLeak: null,
|
|
16956
|
+
/** PreToolUse hook handle so teardown can unregister. */
|
|
16957
|
+
hookUnregister: null,
|
|
16958
|
+
/** PostToolUse hook handle so teardown can unregister. */
|
|
16959
|
+
postHookUnregister: null
|
|
16960
|
+
};
|
|
16961
|
+
}
|
|
16962
|
+
var runtimes = /* @__PURE__ */ new WeakMap();
|
|
16963
|
+
var latestRuntime;
|
|
16964
|
+
function activateRuntime(runtime) {
|
|
16965
|
+
PATTERNS3 = runtime.patterns;
|
|
16966
|
+
COMBINED_REGEX = runtime.combinedRegex;
|
|
16967
|
+
GROUP_INDEX_OF_PATTERN = runtime.groupIndexes;
|
|
16968
|
+
}
|
|
16965
16969
|
function scanWindow(window, found, startTime) {
|
|
16966
16970
|
COMBINED_REGEX.lastIndex = 0;
|
|
16967
16971
|
let m;
|
|
@@ -17107,8 +17111,10 @@ function readConfig42(raw) {
|
|
|
17107
17111
|
customPatterns
|
|
17108
17112
|
};
|
|
17109
17113
|
}
|
|
17110
|
-
function buildHook(cfg, log) {
|
|
17114
|
+
function buildHook(cfg, log, runtime) {
|
|
17111
17115
|
return (input) => {
|
|
17116
|
+
activateRuntime(runtime);
|
|
17117
|
+
const { state: state59 } = runtime;
|
|
17112
17118
|
if (!cfg.enabled) return;
|
|
17113
17119
|
const toolName = input.toolName ?? "unknown";
|
|
17114
17120
|
const matched = scanInput(input.toolInput);
|
|
@@ -17116,8 +17122,8 @@ function buildHook(cfg, log) {
|
|
|
17116
17122
|
const summary = matched.join(", ");
|
|
17117
17123
|
const when = (/* @__PURE__ */ new Date()).toISOString();
|
|
17118
17124
|
if (cfg.mode === "block") {
|
|
17119
|
-
|
|
17120
|
-
|
|
17125
|
+
state59.blockCount += 1;
|
|
17126
|
+
state59.lastBlock = { toolName, matchedTypes: matched, when };
|
|
17121
17127
|
log.warn(`[secret-scanner] blocked ${toolName} \u2014 matched: ${summary}`);
|
|
17122
17128
|
return {
|
|
17123
17129
|
decision: "block",
|
|
@@ -17127,7 +17133,7 @@ function buildHook(cfg, log) {
|
|
|
17127
17133
|
if (cfg.mode === "redact") {
|
|
17128
17134
|
const redacted = redactInput(input.toolInput);
|
|
17129
17135
|
if (redacted.ok && redacted.value !== null && typeof redacted.value === "object" && !Array.isArray(redacted.value)) {
|
|
17130
|
-
|
|
17136
|
+
state59.redactCount += 1;
|
|
17131
17137
|
log.info(`[secret-scanner] redacted ${toolName} \u2014 matched: ${summary}`);
|
|
17132
17138
|
return {
|
|
17133
17139
|
decision: "allow",
|
|
@@ -17135,23 +17141,25 @@ function buildHook(cfg, log) {
|
|
|
17135
17141
|
additionalContext: `secret-scanner: redacted ${matched.length} credential pattern(s) from the ${toolName} arguments before execution.`
|
|
17136
17142
|
};
|
|
17137
17143
|
}
|
|
17138
|
-
|
|
17139
|
-
|
|
17144
|
+
state59.blockCount += 1;
|
|
17145
|
+
state59.lastBlock = { toolName, matchedTypes: matched, when };
|
|
17140
17146
|
const detail = !redacted.ok ? redacted.reason === "oversized_input" ? "an input field exceeds the safe scan limit" : "the input exceeds the safe nesting depth" : "the input has a non-object shape";
|
|
17141
17147
|
return {
|
|
17142
17148
|
decision: "block",
|
|
17143
17149
|
reason: `secret-scanner: cannot safely redact '${toolName}' because ${detail}; refusing to run.`
|
|
17144
17150
|
};
|
|
17145
17151
|
}
|
|
17146
|
-
|
|
17152
|
+
state59.allowCount += 1;
|
|
17147
17153
|
log.warn(
|
|
17148
17154
|
`[secret-scanner] allow-mode: ${toolName} matched ${summary} but mode='allow' lets it through.`
|
|
17149
17155
|
);
|
|
17150
17156
|
return void 0;
|
|
17151
17157
|
};
|
|
17152
17158
|
}
|
|
17153
|
-
function buildPostHook(cfg, log) {
|
|
17159
|
+
function buildPostHook(cfg, log, runtime) {
|
|
17154
17160
|
return (input) => {
|
|
17161
|
+
activateRuntime(runtime);
|
|
17162
|
+
const { state: state59 } = runtime;
|
|
17155
17163
|
if (!cfg.enabled) return;
|
|
17156
17164
|
const result = input.toolResult;
|
|
17157
17165
|
if (!result || typeof result.content !== "string") return;
|
|
@@ -17171,8 +17179,8 @@ function buildPostHook(cfg, log) {
|
|
|
17171
17179
|
}
|
|
17172
17180
|
const summary = credentialMatches.join(", ");
|
|
17173
17181
|
const when = (/* @__PURE__ */ new Date()).toISOString();
|
|
17174
|
-
|
|
17175
|
-
|
|
17182
|
+
state59.leakCount += 1;
|
|
17183
|
+
state59.lastLeak = { toolName, matchedTypes: credentialMatches, when };
|
|
17176
17184
|
log.warn(`[secret-scanner] POST-TOOL LEAK: ${toolName} output matched ${summary}`);
|
|
17177
17185
|
return {
|
|
17178
17186
|
additionalContext: `
|
|
@@ -17228,14 +17236,11 @@ var plugin46 = {
|
|
|
17228
17236
|
}
|
|
17229
17237
|
},
|
|
17230
17238
|
setup(api) {
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
state44.lastLeak = null;
|
|
17237
|
-
state44.hookUnregister = releaseHandle(state44.hookUnregister);
|
|
17238
|
-
state44.postHookUnregister = releaseHandle(state44.postHookUnregister);
|
|
17239
|
+
const previous = runtimes.get(api);
|
|
17240
|
+
if (previous) {
|
|
17241
|
+
previous.state.hookUnregister = releaseHandle(previous.state.hookUnregister);
|
|
17242
|
+
previous.state.postHookUnregister = releaseHandle(previous.state.postHookUnregister);
|
|
17243
|
+
}
|
|
17239
17244
|
const cfg = readConfig42(api.config.extensions?.["secret-scanner"]);
|
|
17240
17245
|
PATTERNS3 = [...BASE_PATTERNS];
|
|
17241
17246
|
for (const cp of cfg.customPatterns) {
|
|
@@ -17245,12 +17250,21 @@ var plugin46 = {
|
|
|
17245
17250
|
}
|
|
17246
17251
|
}
|
|
17247
17252
|
COMBINED_REGEX = buildCombinedRegex(PATTERNS3);
|
|
17253
|
+
const runtime = {
|
|
17254
|
+
state: createState2(),
|
|
17255
|
+
patterns: PATTERNS3,
|
|
17256
|
+
combinedRegex: COMBINED_REGEX,
|
|
17257
|
+
groupIndexes: [...GROUP_INDEX_OF_PATTERN]
|
|
17258
|
+
};
|
|
17259
|
+
runtimes.set(api, runtime);
|
|
17260
|
+
latestRuntime = runtime;
|
|
17261
|
+
const { state: state59 } = runtime;
|
|
17248
17262
|
const log = {
|
|
17249
17263
|
warn: (msg, ...rest) => api.log.warn(msg, ...rest),
|
|
17250
17264
|
info: (msg, ...rest) => api.log.info(msg, ...rest)
|
|
17251
17265
|
};
|
|
17252
|
-
const hook = buildHook(cfg, log);
|
|
17253
|
-
|
|
17266
|
+
const hook = buildHook(cfg, log, runtime);
|
|
17267
|
+
state59.hookUnregister = api.registerHook("PreToolUse", cfg.matcher, hook, {
|
|
17254
17268
|
name: "secret-scanner",
|
|
17255
17269
|
// Redaction rewrites arguments; block/allow modes must inspect the final
|
|
17256
17270
|
// result after every mutator has run so a later rewrite cannot smuggle a
|
|
@@ -17259,8 +17273,8 @@ var plugin46 = {
|
|
|
17259
17273
|
failurePolicy: "closed",
|
|
17260
17274
|
policy: true
|
|
17261
17275
|
});
|
|
17262
|
-
const postHook = buildPostHook(cfg, log);
|
|
17263
|
-
|
|
17276
|
+
const postHook = buildPostHook(cfg, log, runtime);
|
|
17277
|
+
state59.postHookUnregister = api.registerHook("PostToolUse", cfg.postToolUseMatcher, postHook);
|
|
17264
17278
|
api.tools.register({
|
|
17265
17279
|
name: "secret_scanner_status",
|
|
17266
17280
|
description: "Reports the current secret-scanner state: pattern count, last block (if any), and per-mode invocation counters.",
|
|
@@ -17268,6 +17282,7 @@ var plugin46 = {
|
|
|
17268
17282
|
permission: "auto",
|
|
17269
17283
|
mutating: false,
|
|
17270
17284
|
async execute() {
|
|
17285
|
+
activateRuntime(runtime);
|
|
17271
17286
|
return {
|
|
17272
17287
|
ok: true,
|
|
17273
17288
|
enabled: cfg.enabled,
|
|
@@ -17277,13 +17292,13 @@ var plugin46 = {
|
|
|
17277
17292
|
patternCount: PATTERNS3.length,
|
|
17278
17293
|
patternTypes: PATTERNS3.map((p) => p.type),
|
|
17279
17294
|
counters: {
|
|
17280
|
-
block:
|
|
17281
|
-
redact:
|
|
17282
|
-
allow:
|
|
17283
|
-
leak:
|
|
17295
|
+
block: state59.blockCount,
|
|
17296
|
+
redact: state59.redactCount,
|
|
17297
|
+
allow: state59.allowCount,
|
|
17298
|
+
leak: state59.leakCount
|
|
17284
17299
|
},
|
|
17285
|
-
lastBlock:
|
|
17286
|
-
lastLeak:
|
|
17300
|
+
lastBlock: state59.lastBlock,
|
|
17301
|
+
lastLeak: state59.lastLeak
|
|
17287
17302
|
};
|
|
17288
17303
|
}
|
|
17289
17304
|
});
|
|
@@ -17300,6 +17315,7 @@ var plugin46 = {
|
|
|
17300
17315
|
permission: "auto",
|
|
17301
17316
|
mutating: false,
|
|
17302
17317
|
async execute(input) {
|
|
17318
|
+
activateRuntime(runtime);
|
|
17303
17319
|
const text = typeof input["text"] === "string" ? input["text"] : "";
|
|
17304
17320
|
const matched = findMatches(text);
|
|
17305
17321
|
return {
|
|
@@ -17317,48 +17333,51 @@ var plugin46 = {
|
|
|
17317
17333
|
});
|
|
17318
17334
|
},
|
|
17319
17335
|
teardown(api) {
|
|
17320
|
-
|
|
17336
|
+
const runtime = runtimes.get(api);
|
|
17337
|
+
if (!runtime) return;
|
|
17338
|
+
const { state: state59 } = runtime;
|
|
17339
|
+
if (state59.hookUnregister) {
|
|
17321
17340
|
try {
|
|
17322
|
-
|
|
17341
|
+
state59.hookUnregister();
|
|
17323
17342
|
} catch {
|
|
17324
17343
|
}
|
|
17325
|
-
|
|
17344
|
+
state59.hookUnregister = null;
|
|
17326
17345
|
}
|
|
17327
|
-
if (
|
|
17346
|
+
if (state59.postHookUnregister) {
|
|
17328
17347
|
try {
|
|
17329
|
-
|
|
17348
|
+
state59.postHookUnregister();
|
|
17330
17349
|
} catch {
|
|
17331
17350
|
}
|
|
17332
|
-
|
|
17351
|
+
state59.postHookUnregister = null;
|
|
17333
17352
|
}
|
|
17334
17353
|
const finalCounters = {
|
|
17335
|
-
block:
|
|
17336
|
-
redact:
|
|
17337
|
-
allow:
|
|
17338
|
-
leak:
|
|
17354
|
+
block: state59.blockCount,
|
|
17355
|
+
redact: state59.redactCount,
|
|
17356
|
+
allow: state59.allowCount,
|
|
17357
|
+
leak: state59.leakCount
|
|
17339
17358
|
};
|
|
17340
|
-
|
|
17341
|
-
|
|
17342
|
-
|
|
17343
|
-
|
|
17344
|
-
|
|
17345
|
-
|
|
17346
|
-
|
|
17347
|
-
COMBINED_REGEX = buildCombinedRegex(PATTERNS3);
|
|
17359
|
+
state59.blockCount = 0;
|
|
17360
|
+
state59.redactCount = 0;
|
|
17361
|
+
state59.allowCount = 0;
|
|
17362
|
+
state59.leakCount = 0;
|
|
17363
|
+
state59.lastBlock = null;
|
|
17364
|
+
state59.lastLeak = null;
|
|
17365
|
+
runtimes.delete(api);
|
|
17348
17366
|
api.log.info("secret-scanner: teardown complete", { counters: finalCounters });
|
|
17349
17367
|
},
|
|
17350
17368
|
async health() {
|
|
17369
|
+
const state59 = latestRuntime?.state ?? createState2();
|
|
17351
17370
|
return {
|
|
17352
17371
|
ok: true,
|
|
17353
|
-
message:
|
|
17372
|
+
message: state59.lastLeak !== null ? `secret-scanner: last leak at ${state59.lastLeak.when} on ${state59.lastLeak.toolName} (${state59.lastLeak.matchedTypes.join(", ")})` : state59.lastBlock !== null ? `secret-scanner: last block at ${state59.lastBlock.when} on ${state59.lastBlock.toolName} (${state59.lastBlock.matchedTypes.join(", ")})` : `secret-scanner: ${state59.blockCount + state59.redactCount + state59.allowCount + state59.leakCount} invocations, no blocks or leaks`,
|
|
17354
17373
|
counters: {
|
|
17355
|
-
block:
|
|
17356
|
-
redact:
|
|
17357
|
-
allow:
|
|
17358
|
-
leak:
|
|
17374
|
+
block: state59.blockCount,
|
|
17375
|
+
redact: state59.redactCount,
|
|
17376
|
+
allow: state59.allowCount,
|
|
17377
|
+
leak: state59.leakCount
|
|
17359
17378
|
},
|
|
17360
|
-
lastBlock:
|
|
17361
|
-
lastLeak:
|
|
17379
|
+
lastBlock: state59.lastBlock,
|
|
17380
|
+
lastLeak: state59.lastLeak
|
|
17362
17381
|
};
|
|
17363
17382
|
}
|
|
17364
17383
|
};
|
|
@@ -17368,7 +17387,7 @@ var secret_scanner_default = plugin46;
|
|
|
17368
17387
|
import { readdir as readdir2, readFile as readFile12, stat as stat5 } from "node:fs/promises";
|
|
17369
17388
|
import { isAbsolute as isAbsolute21, relative as relative21, resolve as resolve21 } from "node:path";
|
|
17370
17389
|
var API_VERSION30 = "^0.1.10";
|
|
17371
|
-
var
|
|
17390
|
+
var state43 = {
|
|
17372
17391
|
scanCount: 0,
|
|
17373
17392
|
fileScanCount: 0,
|
|
17374
17393
|
findingCount: 0,
|
|
@@ -17575,20 +17594,20 @@ var plugin47 = {
|
|
|
17575
17594
|
}
|
|
17576
17595
|
},
|
|
17577
17596
|
setup(api) {
|
|
17578
|
-
|
|
17579
|
-
|
|
17580
|
-
|
|
17581
|
-
|
|
17582
|
-
|
|
17583
|
-
|
|
17584
|
-
|
|
17585
|
-
|
|
17586
|
-
if (
|
|
17597
|
+
state43.scanCount = 0;
|
|
17598
|
+
state43.fileScanCount = 0;
|
|
17599
|
+
state43.findingCount = 0;
|
|
17600
|
+
state43.hookInvocationCount = 0;
|
|
17601
|
+
state43.skippedCount = 0;
|
|
17602
|
+
state43.blockedCount = 0;
|
|
17603
|
+
state43.lastResult = null;
|
|
17604
|
+
state43.knownHotspots.clear();
|
|
17605
|
+
if (state43.hookUnregister) {
|
|
17587
17606
|
try {
|
|
17588
|
-
|
|
17607
|
+
state43.hookUnregister();
|
|
17589
17608
|
} catch {
|
|
17590
17609
|
}
|
|
17591
|
-
|
|
17610
|
+
state43.hookUnregister = null;
|
|
17592
17611
|
}
|
|
17593
17612
|
const cfg = readConfig43(api.config.extensions?.["security-hotspot-scanner"]);
|
|
17594
17613
|
const hook = async (input) => {
|
|
@@ -17600,25 +17619,25 @@ var plugin47 = {
|
|
|
17600
17619
|
if (!withinProject(sourcePath)) return;
|
|
17601
17620
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
17602
17621
|
if (!scanOnChangeSet.has(ext)) {
|
|
17603
|
-
|
|
17622
|
+
state43.skippedCount += 1;
|
|
17604
17623
|
return;
|
|
17605
17624
|
}
|
|
17606
|
-
|
|
17625
|
+
state43.hookInvocationCount += 1;
|
|
17607
17626
|
const result = await scanPath5(sourcePath, cfg);
|
|
17608
|
-
|
|
17609
|
-
|
|
17627
|
+
state43.scanCount += 1;
|
|
17628
|
+
state43.fileScanCount += result.filesScanned;
|
|
17610
17629
|
if (!result.scanned) {
|
|
17611
17630
|
return;
|
|
17612
17631
|
}
|
|
17613
17632
|
const newFindings = result.findings.filter((f) => {
|
|
17614
17633
|
const key = `${result.path}:${f.type}:${f.line}`;
|
|
17615
|
-
if (
|
|
17616
|
-
|
|
17634
|
+
if (state43.knownHotspots.has(key)) return false;
|
|
17635
|
+
state43.knownHotspots.add(key);
|
|
17617
17636
|
return true;
|
|
17618
17637
|
});
|
|
17619
17638
|
if (newFindings.length === 0) return;
|
|
17620
|
-
|
|
17621
|
-
|
|
17639
|
+
state43.findingCount += newFindings.length;
|
|
17640
|
+
state43.lastResult = {
|
|
17622
17641
|
path: result.path,
|
|
17623
17642
|
findings: newFindings.length,
|
|
17624
17643
|
durationMs: result.durationMs,
|
|
@@ -17633,7 +17652,7 @@ ${lines.join("\n")}` + (result.findings.length >= cfg.maxFindings ? `
|
|
|
17633
17652
|
\u2026 and possibly more (showing first ${cfg.maxFindings})` : "") + `
|
|
17634
17653
|
Review or remove the risky pattern(s).`;
|
|
17635
17654
|
if (cfg.severity === "block") {
|
|
17636
|
-
|
|
17655
|
+
state43.blockedCount += 1;
|
|
17637
17656
|
return {
|
|
17638
17657
|
decision: "block",
|
|
17639
17658
|
reason: message
|
|
@@ -17641,7 +17660,7 @@ Review or remove the risky pattern(s).`;
|
|
|
17641
17660
|
}
|
|
17642
17661
|
return { additionalContext: message };
|
|
17643
17662
|
};
|
|
17644
|
-
|
|
17663
|
+
state43.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, { background: true });
|
|
17645
17664
|
api.tools.register({
|
|
17646
17665
|
name: "security_hotspot_scan",
|
|
17647
17666
|
description: "Scan a file or directory for security anti-patterns (eval, Function constructor, innerHTML, SQL concatenation, http URLs, credential logging, variable exec commands).",
|
|
@@ -17661,13 +17680,13 @@ Review or remove the risky pattern(s).`;
|
|
|
17661
17680
|
async execute(input) {
|
|
17662
17681
|
if (!cfg.enabled) return { ok: false, error: "security-hotspot-scanner is disabled" };
|
|
17663
17682
|
const result = await scanPath5(input.path, cfg);
|
|
17664
|
-
|
|
17665
|
-
|
|
17666
|
-
|
|
17683
|
+
state43.scanCount += 1;
|
|
17684
|
+
state43.fileScanCount += result.filesScanned;
|
|
17685
|
+
state43.findingCount += result.findings.length;
|
|
17667
17686
|
if (!result.scanned) {
|
|
17668
17687
|
return { ok: false, error: result.error, path: input.path };
|
|
17669
17688
|
}
|
|
17670
|
-
|
|
17689
|
+
state43.lastResult = {
|
|
17671
17690
|
path: result.path,
|
|
17672
17691
|
findings: result.findings.length,
|
|
17673
17692
|
durationMs: result.durationMs,
|
|
@@ -17699,14 +17718,14 @@ Review or remove the risky pattern(s).`;
|
|
|
17699
17718
|
scanOnChange: cfg.scanOnChange,
|
|
17700
17719
|
patternTypes: PATTERNS4.map((p) => p.type),
|
|
17701
17720
|
counters: {
|
|
17702
|
-
scans:
|
|
17703
|
-
filesScanned:
|
|
17704
|
-
findings:
|
|
17705
|
-
hookInvocations:
|
|
17706
|
-
skipped:
|
|
17707
|
-
blocked:
|
|
17721
|
+
scans: state43.scanCount,
|
|
17722
|
+
filesScanned: state43.fileScanCount,
|
|
17723
|
+
findings: state43.findingCount,
|
|
17724
|
+
hookInvocations: state43.hookInvocationCount,
|
|
17725
|
+
skipped: state43.skippedCount,
|
|
17726
|
+
blocked: state43.blockedCount
|
|
17708
17727
|
},
|
|
17709
|
-
lastResult:
|
|
17728
|
+
lastResult: state43.lastResult
|
|
17710
17729
|
};
|
|
17711
17730
|
}
|
|
17712
17731
|
});
|
|
@@ -17717,44 +17736,44 @@ Review or remove the risky pattern(s).`;
|
|
|
17717
17736
|
});
|
|
17718
17737
|
},
|
|
17719
17738
|
teardown(api) {
|
|
17720
|
-
if (
|
|
17739
|
+
if (state43.hookUnregister) {
|
|
17721
17740
|
try {
|
|
17722
|
-
|
|
17741
|
+
state43.hookUnregister();
|
|
17723
17742
|
} catch {
|
|
17724
17743
|
}
|
|
17725
|
-
|
|
17744
|
+
state43.hookUnregister = null;
|
|
17726
17745
|
}
|
|
17727
17746
|
const final = {
|
|
17728
|
-
scans:
|
|
17729
|
-
filesScanned:
|
|
17730
|
-
findings:
|
|
17731
|
-
hookInvocations:
|
|
17732
|
-
skipped:
|
|
17733
|
-
blocked:
|
|
17747
|
+
scans: state43.scanCount,
|
|
17748
|
+
filesScanned: state43.fileScanCount,
|
|
17749
|
+
findings: state43.findingCount,
|
|
17750
|
+
hookInvocations: state43.hookInvocationCount,
|
|
17751
|
+
skipped: state43.skippedCount,
|
|
17752
|
+
blocked: state43.blockedCount
|
|
17734
17753
|
};
|
|
17735
|
-
|
|
17736
|
-
|
|
17737
|
-
|
|
17738
|
-
|
|
17739
|
-
|
|
17740
|
-
|
|
17741
|
-
|
|
17742
|
-
|
|
17754
|
+
state43.scanCount = 0;
|
|
17755
|
+
state43.fileScanCount = 0;
|
|
17756
|
+
state43.findingCount = 0;
|
|
17757
|
+
state43.hookInvocationCount = 0;
|
|
17758
|
+
state43.skippedCount = 0;
|
|
17759
|
+
state43.blockedCount = 0;
|
|
17760
|
+
state43.lastResult = null;
|
|
17761
|
+
state43.knownHotspots.clear();
|
|
17743
17762
|
api.log.info("security-hotspot-scanner: teardown complete", { final });
|
|
17744
17763
|
},
|
|
17745
17764
|
async health() {
|
|
17746
17765
|
return {
|
|
17747
17766
|
ok: true,
|
|
17748
|
-
message:
|
|
17767
|
+
message: state43.lastResult ? `security-hotspot-scanner: ${state43.scanCount} scan(s), last scan found ${state43.lastResult.findings} hotspot(s)` : `security-hotspot-scanner: ${state43.scanCount} scan(s), ${state43.findingCount} finding(s)`,
|
|
17749
17768
|
counters: {
|
|
17750
|
-
scans:
|
|
17751
|
-
filesScanned:
|
|
17752
|
-
findings:
|
|
17753
|
-
hookInvocations:
|
|
17754
|
-
skipped:
|
|
17755
|
-
blocked:
|
|
17756
|
-
},
|
|
17757
|
-
lastResult:
|
|
17769
|
+
scans: state43.scanCount,
|
|
17770
|
+
filesScanned: state43.fileScanCount,
|
|
17771
|
+
findings: state43.findingCount,
|
|
17772
|
+
hookInvocations: state43.hookInvocationCount,
|
|
17773
|
+
skipped: state43.skippedCount,
|
|
17774
|
+
blocked: state43.blockedCount
|
|
17775
|
+
},
|
|
17776
|
+
lastResult: state43.lastResult
|
|
17758
17777
|
};
|
|
17759
17778
|
}
|
|
17760
17779
|
};
|
|
@@ -17766,7 +17785,7 @@ import { isAbsolute as isAbsolute22, relative as relative22, resolve as resolve2
|
|
|
17766
17785
|
import { DEFAULT_WALK_IGNORE_DIRS } from "@wrongstack/core/utils";
|
|
17767
17786
|
var API_VERSION31 = "^0.1.10";
|
|
17768
17787
|
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
17769
|
-
var
|
|
17788
|
+
var state44 = {
|
|
17770
17789
|
index: null,
|
|
17771
17790
|
cachedPath: null,
|
|
17772
17791
|
fileCount: 0,
|
|
@@ -17887,17 +17906,17 @@ function yieldEventLoop() {
|
|
|
17887
17906
|
return new Promise((resolve28) => setImmediate(resolve28));
|
|
17888
17907
|
}
|
|
17889
17908
|
function addFileToIndex(relPath, content, size, cfg) {
|
|
17890
|
-
if (!
|
|
17891
|
-
|
|
17909
|
+
if (!state44.index || content.includes("\0")) return;
|
|
17910
|
+
state44.bytesIndexed += content.length;
|
|
17892
17911
|
const lines = content.split(/\r?\n/);
|
|
17893
|
-
|
|
17912
|
+
state44.index.files.set(relPath, { lines, size });
|
|
17894
17913
|
for (let i = 0; i < lines.length; i += 1) {
|
|
17895
17914
|
const terms = tokenize(lines[i], cfg.minTokenLength);
|
|
17896
17915
|
for (const term of terms) {
|
|
17897
|
-
let postings =
|
|
17916
|
+
let postings = state44.index.terms.get(term);
|
|
17898
17917
|
if (!postings) {
|
|
17899
17918
|
postings = /* @__PURE__ */ new Map();
|
|
17900
|
-
|
|
17919
|
+
state44.index.terms.set(term, postings);
|
|
17901
17920
|
}
|
|
17902
17921
|
let posting = postings.get(relPath);
|
|
17903
17922
|
if (!posting) {
|
|
@@ -17934,8 +17953,8 @@ async function walkDirectory(absPath, cfg, excludes, fileBatch) {
|
|
|
17934
17953
|
}
|
|
17935
17954
|
const root = normalizeSlashes2(process.cwd());
|
|
17936
17955
|
for (const ent of entries) {
|
|
17937
|
-
if (
|
|
17938
|
-
|
|
17956
|
+
if (state44.fileCount >= cfg.maxFiles) {
|
|
17957
|
+
state44.truncated = true;
|
|
17939
17958
|
return;
|
|
17940
17959
|
}
|
|
17941
17960
|
const absChild = normalizeSlashes2(resolve22(absPath, ent.name));
|
|
@@ -17944,9 +17963,9 @@ async function walkDirectory(absPath, cfg, excludes, fileBatch) {
|
|
|
17944
17963
|
if (excludes.some((re) => re.test(relChild))) continue;
|
|
17945
17964
|
if (ent.isDirectory()) {
|
|
17946
17965
|
await walkDirectory(absChild, cfg, excludes, fileBatch);
|
|
17947
|
-
if (
|
|
17966
|
+
if (state44.truncated) return;
|
|
17948
17967
|
} else if (ent.isFile()) {
|
|
17949
|
-
|
|
17968
|
+
state44.fileCount += 1;
|
|
17950
17969
|
if (!shouldIndexFile(relChild, cfg)) continue;
|
|
17951
17970
|
let stats;
|
|
17952
17971
|
try {
|
|
@@ -17958,50 +17977,50 @@ async function walkDirectory(absPath, cfg, excludes, fileBatch) {
|
|
|
17958
17977
|
if (fileBatch.length >= INDEX_BATCH_SIZE) {
|
|
17959
17978
|
await flushFileBatch(fileBatch, cfg);
|
|
17960
17979
|
}
|
|
17961
|
-
if (
|
|
17980
|
+
if (state44.fileCount % YIELD_EVERY_FILES === 0) {
|
|
17962
17981
|
await yieldEventLoop();
|
|
17963
17982
|
}
|
|
17964
17983
|
}
|
|
17965
17984
|
}
|
|
17966
17985
|
}
|
|
17967
17986
|
async function buildIndex(rootPath, cfg) {
|
|
17968
|
-
|
|
17969
|
-
|
|
17970
|
-
|
|
17971
|
-
|
|
17972
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
17987
|
+
state44.index = { terms: /* @__PURE__ */ new Map(), files: /* @__PURE__ */ new Map() };
|
|
17988
|
+
state44.cachedPath = rootPath;
|
|
17989
|
+
state44.fileCount = 0;
|
|
17990
|
+
state44.termCount = 0;
|
|
17991
|
+
state44.bytesIndexed = 0;
|
|
17992
|
+
state44.truncated = false;
|
|
17993
|
+
state44.reindexCount += 1;
|
|
17975
17994
|
const excludes = compileExcludes(cfg.excludePatterns);
|
|
17976
17995
|
let rootStats;
|
|
17977
17996
|
try {
|
|
17978
17997
|
rootStats = await fs2.stat(rootPath);
|
|
17979
17998
|
} catch {
|
|
17980
|
-
|
|
17999
|
+
state44.termCount = 0;
|
|
17981
18000
|
return;
|
|
17982
18001
|
}
|
|
17983
18002
|
if (rootStats.isFile()) {
|
|
17984
18003
|
const relPath = normalizeSlashes2(relative22(normalizeSlashes2(process.cwd()), rootPath));
|
|
17985
18004
|
await indexFileFromStats(rootPath, relPath === "" ? "." : relPath, rootStats, cfg);
|
|
17986
|
-
|
|
18005
|
+
state44.fileCount = state44.index.files.size;
|
|
17987
18006
|
} else if (rootStats.isDirectory()) {
|
|
17988
18007
|
const fileBatch = [];
|
|
17989
18008
|
await walkDirectory(rootPath, cfg, excludes, fileBatch);
|
|
17990
18009
|
await flushFileBatch(fileBatch, cfg);
|
|
17991
18010
|
}
|
|
17992
|
-
|
|
18011
|
+
state44.termCount = state44.index.terms.size;
|
|
17993
18012
|
}
|
|
17994
18013
|
async function ensureIndex(rootPath, cfg) {
|
|
17995
|
-
if (
|
|
17996
|
-
|
|
17997
|
-
|
|
18014
|
+
if (state44.index && state44.cachedPath === rootPath) return;
|
|
18015
|
+
state44.buildPromise ??= buildIndex(rootPath, cfg).finally(() => {
|
|
18016
|
+
state44.buildPromise = null;
|
|
17998
18017
|
});
|
|
17999
|
-
await
|
|
18000
|
-
if (!
|
|
18001
|
-
|
|
18002
|
-
|
|
18018
|
+
await state44.buildPromise;
|
|
18019
|
+
if (!state44.index || state44.cachedPath !== rootPath) {
|
|
18020
|
+
state44.buildPromise = buildIndex(rootPath, cfg).finally(() => {
|
|
18021
|
+
state44.buildPromise = null;
|
|
18003
18022
|
});
|
|
18004
|
-
await
|
|
18023
|
+
await state44.buildPromise;
|
|
18005
18024
|
}
|
|
18006
18025
|
}
|
|
18007
18026
|
function compareRankedCandidates(a, b) {
|
|
@@ -18020,14 +18039,14 @@ function insertTopCandidate(top, candidate, limit) {
|
|
|
18020
18039
|
if (top.length > limit) top.pop();
|
|
18021
18040
|
}
|
|
18022
18041
|
function runQuery(query, limit, cfg) {
|
|
18023
|
-
if (!
|
|
18042
|
+
if (!state44.index) return [];
|
|
18024
18043
|
const rawTokens = tokenize(query, cfg.minTokenLength);
|
|
18025
18044
|
const uniqueTokens = [...new Set(rawTokens)];
|
|
18026
18045
|
if (uniqueTokens.length === 0) return [];
|
|
18027
18046
|
const scores = /* @__PURE__ */ new Map();
|
|
18028
18047
|
const matchedTerms = /* @__PURE__ */ new Map();
|
|
18029
18048
|
for (const token of uniqueTokens) {
|
|
18030
|
-
const postings =
|
|
18049
|
+
const postings = state44.index.terms.get(token);
|
|
18031
18050
|
if (!postings) continue;
|
|
18032
18051
|
for (const [filePath, posting] of postings) {
|
|
18033
18052
|
scores.set(filePath, (scores.get(filePath) ?? 0) + posting.tf);
|
|
@@ -18052,7 +18071,7 @@ function runQuery(query, limit, cfg) {
|
|
|
18052
18071
|
);
|
|
18053
18072
|
}
|
|
18054
18073
|
return top.map(({ path, score, terms }) => {
|
|
18055
|
-
const entry =
|
|
18074
|
+
const entry = state44.index.files.get(path);
|
|
18056
18075
|
const matchedLines = [];
|
|
18057
18076
|
if (entry) {
|
|
18058
18077
|
const querySet = new Set(uniqueTokens);
|
|
@@ -18132,21 +18151,21 @@ var plugin48 = {
|
|
|
18132
18151
|
}
|
|
18133
18152
|
},
|
|
18134
18153
|
setup(api) {
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18138
|
-
|
|
18139
|
-
|
|
18140
|
-
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
if (
|
|
18154
|
+
state44.index = null;
|
|
18155
|
+
state44.cachedPath = null;
|
|
18156
|
+
state44.fileCount = 0;
|
|
18157
|
+
state44.termCount = 0;
|
|
18158
|
+
state44.bytesIndexed = 0;
|
|
18159
|
+
state44.truncated = false;
|
|
18160
|
+
state44.queryCount = 0;
|
|
18161
|
+
state44.reindexCount = 0;
|
|
18162
|
+
state44.buildPromise = null;
|
|
18163
|
+
if (state44.hookUnregister) {
|
|
18145
18164
|
try {
|
|
18146
|
-
|
|
18165
|
+
state44.hookUnregister();
|
|
18147
18166
|
} catch {
|
|
18148
18167
|
}
|
|
18149
|
-
|
|
18168
|
+
state44.hookUnregister = null;
|
|
18150
18169
|
}
|
|
18151
18170
|
const cfg = readConfig44(api.config.extensions?.["semantic-search-indexer"]);
|
|
18152
18171
|
api.tools.register({
|
|
@@ -18188,13 +18207,13 @@ var plugin48 = {
|
|
|
18188
18207
|
const limit = typeof input.limit === "number" && input.limit >= 1 ? Math.floor(input.limit) : cfg.defaultLimit;
|
|
18189
18208
|
const results = runQuery(query, limit, cfg);
|
|
18190
18209
|
const queryTokens = [...new Set(tokenize(query, cfg.minTokenLength))];
|
|
18191
|
-
|
|
18210
|
+
state44.queryCount += 1;
|
|
18192
18211
|
api.metrics.counter("queries");
|
|
18193
18212
|
return {
|
|
18194
18213
|
ok: true,
|
|
18195
18214
|
query,
|
|
18196
18215
|
queryTokens,
|
|
18197
|
-
indexedPath:
|
|
18216
|
+
indexedPath: state44.cachedPath,
|
|
18198
18217
|
totalResults: results.length,
|
|
18199
18218
|
limit,
|
|
18200
18219
|
results
|
|
@@ -18214,14 +18233,14 @@ var plugin48 = {
|
|
|
18214
18233
|
return {
|
|
18215
18234
|
ok: true,
|
|
18216
18235
|
enabled: cfg.enabled,
|
|
18217
|
-
indexedPath:
|
|
18218
|
-
fileCount:
|
|
18219
|
-
termCount:
|
|
18220
|
-
bytesIndexed:
|
|
18221
|
-
truncated:
|
|
18236
|
+
indexedPath: state44.cachedPath,
|
|
18237
|
+
fileCount: state44.fileCount,
|
|
18238
|
+
termCount: state44.termCount,
|
|
18239
|
+
bytesIndexed: state44.bytesIndexed,
|
|
18240
|
+
truncated: state44.truncated,
|
|
18222
18241
|
counters: {
|
|
18223
|
-
queries:
|
|
18224
|
-
reindexes:
|
|
18242
|
+
queries: state44.queryCount,
|
|
18243
|
+
reindexes: state44.reindexCount
|
|
18225
18244
|
}
|
|
18226
18245
|
};
|
|
18227
18246
|
}
|
|
@@ -18233,40 +18252,40 @@ var plugin48 = {
|
|
|
18233
18252
|
});
|
|
18234
18253
|
},
|
|
18235
18254
|
teardown(api) {
|
|
18236
|
-
if (
|
|
18255
|
+
if (state44.hookUnregister) {
|
|
18237
18256
|
try {
|
|
18238
|
-
|
|
18257
|
+
state44.hookUnregister();
|
|
18239
18258
|
} catch {
|
|
18240
18259
|
}
|
|
18241
|
-
|
|
18260
|
+
state44.hookUnregister = null;
|
|
18242
18261
|
}
|
|
18243
18262
|
const final = {
|
|
18244
|
-
fileCount:
|
|
18245
|
-
termCount:
|
|
18246
|
-
queries:
|
|
18247
|
-
reindexes:
|
|
18263
|
+
fileCount: state44.fileCount,
|
|
18264
|
+
termCount: state44.termCount,
|
|
18265
|
+
queries: state44.queryCount,
|
|
18266
|
+
reindexes: state44.reindexCount
|
|
18248
18267
|
};
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
|
|
18256
|
-
|
|
18257
|
-
|
|
18268
|
+
state44.index = null;
|
|
18269
|
+
state44.cachedPath = null;
|
|
18270
|
+
state44.fileCount = 0;
|
|
18271
|
+
state44.termCount = 0;
|
|
18272
|
+
state44.bytesIndexed = 0;
|
|
18273
|
+
state44.truncated = false;
|
|
18274
|
+
state44.queryCount = 0;
|
|
18275
|
+
state44.reindexCount = 0;
|
|
18276
|
+
state44.buildPromise = null;
|
|
18258
18277
|
api.log.info("semantic-search-indexer: teardown complete", { final });
|
|
18259
18278
|
},
|
|
18260
18279
|
async health() {
|
|
18261
18280
|
return {
|
|
18262
18281
|
ok: true,
|
|
18263
|
-
message: `semantic-search-indexer: ${
|
|
18282
|
+
message: `semantic-search-indexer: ${state44.fileCount} file(s), ${state44.termCount} term(s), ${state44.queryCount} query(ies)`,
|
|
18264
18283
|
counters: {
|
|
18265
|
-
fileCount:
|
|
18266
|
-
termCount:
|
|
18267
|
-
bytesIndexed:
|
|
18268
|
-
queries:
|
|
18269
|
-
reindexes:
|
|
18284
|
+
fileCount: state44.fileCount,
|
|
18285
|
+
termCount: state44.termCount,
|
|
18286
|
+
bytesIndexed: state44.bytesIndexed,
|
|
18287
|
+
queries: state44.queryCount,
|
|
18288
|
+
reindexes: state44.reindexCount
|
|
18270
18289
|
}
|
|
18271
18290
|
};
|
|
18272
18291
|
}
|
|
@@ -18288,7 +18307,7 @@ function resolveProjectRoot(rawCwd, root = process.cwd()) {
|
|
|
18288
18307
|
if (rel === "" || !rel.startsWith("..") && !isAbsolute23(rel)) return resolved;
|
|
18289
18308
|
return null;
|
|
18290
18309
|
}
|
|
18291
|
-
var
|
|
18310
|
+
var state45 = {
|
|
18292
18311
|
/** Total invocations across all three tools this session. */
|
|
18293
18312
|
invocationCount: 0,
|
|
18294
18313
|
/** Per-tool invocation counts so /diag can show "bumps: 2, current: 5". */
|
|
@@ -18487,9 +18506,9 @@ var plugin49 = {
|
|
|
18487
18506
|
}
|
|
18488
18507
|
},
|
|
18489
18508
|
setup(api) {
|
|
18490
|
-
|
|
18491
|
-
|
|
18492
|
-
|
|
18509
|
+
state45.invocationCount = 0;
|
|
18510
|
+
state45.perTool = { semver_bump: 0, semver_current: 0, semver_changelog: 0 };
|
|
18511
|
+
state45.lastBump = null;
|
|
18493
18512
|
const tagPrefix = api.config.extensions?.["semver-bump"]?.["tagPrefix"] ?? "v";
|
|
18494
18513
|
const autoTag = api.config.extensions?.["semver-bump"]?.["autoTag"] ?? true;
|
|
18495
18514
|
const VALID_PARTS = ["major", "minor", "patch", "auto"];
|
|
@@ -18613,7 +18632,7 @@ var plugin49 = {
|
|
|
18613
18632
|
to: newVersion,
|
|
18614
18633
|
bump: bumpPart
|
|
18615
18634
|
});
|
|
18616
|
-
|
|
18635
|
+
state45.lastBump = {
|
|
18617
18636
|
when: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18618
18637
|
from: currentVersion,
|
|
18619
18638
|
to: newVersion,
|
|
@@ -18649,8 +18668,8 @@ var plugin49 = {
|
|
|
18649
18668
|
permission: "confirm",
|
|
18650
18669
|
mutating: true,
|
|
18651
18670
|
async execute(input) {
|
|
18652
|
-
|
|
18653
|
-
|
|
18671
|
+
state45.invocationCount += 1;
|
|
18672
|
+
state45.perTool["semver_bump"] = (state45.perTool["semver_bump"] ?? 0) + 1;
|
|
18654
18673
|
const cwd = input["cwd"];
|
|
18655
18674
|
const dryRun = input["dry_run"] ?? false;
|
|
18656
18675
|
const part = input["part"] ?? defaultPart;
|
|
@@ -18727,8 +18746,8 @@ var plugin49 = {
|
|
|
18727
18746
|
permission: "auto",
|
|
18728
18747
|
mutating: false,
|
|
18729
18748
|
async execute(input) {
|
|
18730
|
-
|
|
18731
|
-
|
|
18749
|
+
state45.invocationCount += 1;
|
|
18750
|
+
state45.perTool["semver_current"] = (state45.perTool["semver_current"] ?? 0) + 1;
|
|
18732
18751
|
const cwdInput = input["cwd"];
|
|
18733
18752
|
const safeCwd = resolveProjectRoot(cwdInput);
|
|
18734
18753
|
if (!safeCwd) {
|
|
@@ -18775,8 +18794,8 @@ var plugin49 = {
|
|
|
18775
18794
|
permission: "auto",
|
|
18776
18795
|
mutating: false,
|
|
18777
18796
|
async execute(input) {
|
|
18778
|
-
|
|
18779
|
-
|
|
18797
|
+
state45.invocationCount += 1;
|
|
18798
|
+
state45.perTool["semver_changelog"] = (state45.perTool["semver_changelog"] ?? 0) + 1;
|
|
18780
18799
|
const from = input["from"];
|
|
18781
18800
|
const to = input["to"] ?? "HEAD";
|
|
18782
18801
|
const cwd = input["cwd"];
|
|
@@ -18824,11 +18843,11 @@ var plugin49 = {
|
|
|
18824
18843
|
api.log.info("semver-bump plugin loaded", { version: "0.1.0", tagPrefix, autoTag });
|
|
18825
18844
|
},
|
|
18826
18845
|
teardown(api) {
|
|
18827
|
-
const finalTotal =
|
|
18828
|
-
const finalPerTool = { ...
|
|
18829
|
-
|
|
18830
|
-
|
|
18831
|
-
|
|
18846
|
+
const finalTotal = state45.invocationCount;
|
|
18847
|
+
const finalPerTool = { ...state45.perTool };
|
|
18848
|
+
state45.invocationCount = 0;
|
|
18849
|
+
state45.perTool = { semver_bump: 0, semver_current: 0, semver_changelog: 0 };
|
|
18850
|
+
state45.lastBump = null;
|
|
18832
18851
|
api.log.info("semver-bump: teardown complete", {
|
|
18833
18852
|
invocations: finalTotal,
|
|
18834
18853
|
perTool: finalPerTool
|
|
@@ -18837,17 +18856,17 @@ var plugin49 = {
|
|
|
18837
18856
|
async health() {
|
|
18838
18857
|
return {
|
|
18839
18858
|
ok: true,
|
|
18840
|
-
message:
|
|
18841
|
-
invocationCount:
|
|
18842
|
-
perTool: { ...
|
|
18843
|
-
lastBump:
|
|
18859
|
+
message: state45.lastBump === null ? `semver-bump: ${state45.invocationCount} call(s) this session` : `semver-bump: last bump ${state45.lastBump.from} \u2192 ${state45.lastBump.to} (${state45.lastBump.type}) at ${state45.lastBump.when}`,
|
|
18860
|
+
invocationCount: state45.invocationCount,
|
|
18861
|
+
perTool: { ...state45.perTool },
|
|
18862
|
+
lastBump: state45.lastBump
|
|
18844
18863
|
};
|
|
18845
18864
|
}
|
|
18846
18865
|
};
|
|
18847
18866
|
var semver_bump_default = plugin49;
|
|
18848
18867
|
|
|
18849
18868
|
// src/session-recap/index.ts
|
|
18850
|
-
var
|
|
18869
|
+
var state46 = {
|
|
18851
18870
|
recapsPublished: 0,
|
|
18852
18871
|
recapsErrored: 0,
|
|
18853
18872
|
recapsSkipped: 0,
|
|
@@ -18884,23 +18903,23 @@ function readConfig45(raw) {
|
|
|
18884
18903
|
}
|
|
18885
18904
|
function touchActivity() {
|
|
18886
18905
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
18887
|
-
if (
|
|
18888
|
-
|
|
18906
|
+
if (state46.startedAt === null) state46.startedAt = now;
|
|
18907
|
+
state46.lastActivityAt = now;
|
|
18889
18908
|
}
|
|
18890
18909
|
function bumpModelUsage(model, inputTokens, outputTokens) {
|
|
18891
|
-
let m =
|
|
18910
|
+
let m = state46.perModel.get(model);
|
|
18892
18911
|
if (!m) {
|
|
18893
18912
|
m = { inputTokens: 0, outputTokens: 0, invocations: 0 };
|
|
18894
|
-
|
|
18913
|
+
state46.perModel.set(model, m);
|
|
18895
18914
|
}
|
|
18896
18915
|
m.inputTokens += inputTokens;
|
|
18897
18916
|
m.outputTokens += outputTokens;
|
|
18898
18917
|
m.invocations += 1;
|
|
18899
|
-
|
|
18900
|
-
|
|
18918
|
+
state46.totalInputTokens += inputTokens;
|
|
18919
|
+
state46.totalOutputTokens += outputTokens;
|
|
18901
18920
|
}
|
|
18902
18921
|
function bumpToolCount(name) {
|
|
18903
|
-
|
|
18922
|
+
state46.toolCounts.set(name, (state46.toolCounts.get(name) ?? 0) + 1);
|
|
18904
18923
|
}
|
|
18905
18924
|
function formatDuration(startedAt, lastActivityAt) {
|
|
18906
18925
|
if (!startedAt) return "0s";
|
|
@@ -19024,27 +19043,27 @@ var plugin50 = {
|
|
|
19024
19043
|
}
|
|
19025
19044
|
},
|
|
19026
19045
|
setup(api) {
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
for (const off of
|
|
19046
|
+
state46.recapsPublished = 0;
|
|
19047
|
+
state46.recapsErrored = 0;
|
|
19048
|
+
state46.recapsSkipped = 0;
|
|
19049
|
+
state46.aiSummariesWritten = 0;
|
|
19050
|
+
state46.aiSummaryErrors = 0;
|
|
19051
|
+
state46.stopInvocations = 0;
|
|
19052
|
+
state46.totalInputTokens = 0;
|
|
19053
|
+
state46.totalOutputTokens = 0;
|
|
19054
|
+
state46.perModel.clear();
|
|
19055
|
+
state46.toolCounts.clear();
|
|
19056
|
+
state46.commitCount = 0;
|
|
19057
|
+
state46.startedAt = null;
|
|
19058
|
+
state46.lastActivityAt = null;
|
|
19059
|
+
state46.stopHookUnregister = releaseHandle(state46.stopHookUnregister);
|
|
19060
|
+
for (const off of state46.eventUnsubscribers) {
|
|
19042
19061
|
try {
|
|
19043
19062
|
off();
|
|
19044
19063
|
} catch {
|
|
19045
19064
|
}
|
|
19046
19065
|
}
|
|
19047
|
-
|
|
19066
|
+
state46.eventUnsubscribers = [];
|
|
19048
19067
|
const cfg = readConfig45(api.config.extensions?.["session-recap"]);
|
|
19049
19068
|
const mailbox = api.mailbox;
|
|
19050
19069
|
if (api.onEvent) {
|
|
@@ -19056,7 +19075,7 @@ var plugin50 = {
|
|
|
19056
19075
|
const output = p?.usage?.output ?? 0;
|
|
19057
19076
|
bumpModelUsage(model, input, output);
|
|
19058
19077
|
});
|
|
19059
|
-
|
|
19078
|
+
state46.eventUnsubscribers.push(offUsage);
|
|
19060
19079
|
}
|
|
19061
19080
|
if (api.onPattern) {
|
|
19062
19081
|
const offTool = api.onPattern("tool.*", (eventName, payload) => {
|
|
@@ -19067,21 +19086,21 @@ var plugin50 = {
|
|
|
19067
19086
|
if (toolName === "git_autocommit" || toolName.startsWith("git ")) {
|
|
19068
19087
|
}
|
|
19069
19088
|
});
|
|
19070
|
-
|
|
19089
|
+
state46.eventUnsubscribers.push(offTool);
|
|
19071
19090
|
const offResult = api.onPattern("tool.result", (_event, payload) => {
|
|
19072
19091
|
const p = payload;
|
|
19073
19092
|
if (p?.tool === "git_autocommit" && p.isError === false) {
|
|
19074
|
-
|
|
19093
|
+
state46.commitCount += 1;
|
|
19075
19094
|
}
|
|
19076
19095
|
});
|
|
19077
|
-
|
|
19096
|
+
state46.eventUnsubscribers.push(offResult);
|
|
19078
19097
|
}
|
|
19079
19098
|
const stopHook = async (input) => {
|
|
19080
19099
|
if (!cfg.enabled) return;
|
|
19081
19100
|
touchActivity();
|
|
19082
|
-
|
|
19101
|
+
state46.stopInvocations += 1;
|
|
19083
19102
|
if (!mailbox) {
|
|
19084
|
-
|
|
19103
|
+
state46.recapsSkipped += 1;
|
|
19085
19104
|
api.log.warn(
|
|
19086
19105
|
"session-recap: no mailbox available on api \u2014 recap disabled. Add `mailbox` to the setupPlugins() call to enable cross-session summaries."
|
|
19087
19106
|
);
|
|
@@ -19089,18 +19108,18 @@ var plugin50 = {
|
|
|
19089
19108
|
}
|
|
19090
19109
|
const transcriptPath = api.session?.transcriptPath;
|
|
19091
19110
|
const tailEvents = await readTranscriptTail(transcriptPath, cfg.includeTranscriptTail);
|
|
19092
|
-
const duration = formatDuration(
|
|
19111
|
+
const duration = formatDuration(state46.startedAt, state46.lastActivityAt);
|
|
19093
19112
|
const recap = {
|
|
19094
19113
|
session: {
|
|
19095
19114
|
id: input.sessionId ?? null,
|
|
19096
19115
|
cwd: input.cwd ?? null,
|
|
19097
|
-
startedAt:
|
|
19098
|
-
endedAt:
|
|
19116
|
+
startedAt: state46.startedAt,
|
|
19117
|
+
endedAt: state46.lastActivityAt,
|
|
19099
19118
|
duration
|
|
19100
19119
|
},
|
|
19101
19120
|
tokens: {
|
|
19102
|
-
total: { input:
|
|
19103
|
-
perModel: topN(
|
|
19121
|
+
total: { input: state46.totalInputTokens, output: state46.totalOutputTokens },
|
|
19122
|
+
perModel: topN(state46.perModel, 10).map(([model, u]) => ({
|
|
19104
19123
|
model,
|
|
19105
19124
|
input: u.inputTokens,
|
|
19106
19125
|
output: u.outputTokens,
|
|
@@ -19108,11 +19127,11 @@ var plugin50 = {
|
|
|
19108
19127
|
}))
|
|
19109
19128
|
},
|
|
19110
19129
|
tools: {
|
|
19111
|
-
totalCalls: [...
|
|
19112
|
-
uniqueTools:
|
|
19113
|
-
top: topN(
|
|
19130
|
+
totalCalls: [...state46.toolCounts.values()].reduce((a, b) => a + b, 0),
|
|
19131
|
+
uniqueTools: state46.toolCounts.size,
|
|
19132
|
+
top: topN(state46.toolCounts, 5)
|
|
19114
19133
|
},
|
|
19115
|
-
commits:
|
|
19134
|
+
commits: state46.commitCount,
|
|
19116
19135
|
transcriptTail: tailEvents.flatMap((e) => {
|
|
19117
19136
|
const entry = {};
|
|
19118
19137
|
if (e.type !== void 0) entry.type = e.type;
|
|
@@ -19147,10 +19166,10 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
|
|
|
19147
19166
|
const text = result.text.trim();
|
|
19148
19167
|
if (text) {
|
|
19149
19168
|
aiSummary = text;
|
|
19150
|
-
|
|
19169
|
+
state46.aiSummariesWritten += 1;
|
|
19151
19170
|
}
|
|
19152
19171
|
} catch {
|
|
19153
|
-
|
|
19172
|
+
state46.aiSummaryErrors += 1;
|
|
19154
19173
|
}
|
|
19155
19174
|
}
|
|
19156
19175
|
const recapWithSummary = aiSummary ? { summary: aiSummary, ...recap } : recap;
|
|
@@ -19171,7 +19190,7 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
|
|
|
19171
19190
|
body,
|
|
19172
19191
|
priority: "low"
|
|
19173
19192
|
});
|
|
19174
|
-
|
|
19193
|
+
state46.recapsPublished += 1;
|
|
19175
19194
|
api.log.info("session-recap: published session summary", {
|
|
19176
19195
|
messageId: result.id ?? null,
|
|
19177
19196
|
duration,
|
|
@@ -19180,13 +19199,13 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
|
|
|
19180
19199
|
tokensOut: recap.tokens.total.output
|
|
19181
19200
|
});
|
|
19182
19201
|
} catch (err) {
|
|
19183
|
-
|
|
19202
|
+
state46.recapsErrored += 1;
|
|
19184
19203
|
api.log.warn("session-recap: mailbox.send failed", {
|
|
19185
19204
|
error: err instanceof Error ? err.message : String(err)
|
|
19186
19205
|
});
|
|
19187
19206
|
}
|
|
19188
19207
|
};
|
|
19189
|
-
|
|
19208
|
+
state46.stopHookUnregister = api.registerHook("Stop", void 0, stopHook);
|
|
19190
19209
|
api.tools.register({
|
|
19191
19210
|
name: "session_recap_status",
|
|
19192
19211
|
description: "Reports session-recap state: config, accumulated metrics (tokens, tool calls, commits), and last recap status.",
|
|
@@ -19205,33 +19224,33 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
|
|
|
19205
19224
|
aiSummary: cfg.aiSummary,
|
|
19206
19225
|
llmAvailable: Boolean(api.llm),
|
|
19207
19226
|
counters: {
|
|
19208
|
-
stopInvocations:
|
|
19209
|
-
recapsPublished:
|
|
19210
|
-
recapsErrored:
|
|
19211
|
-
recapsSkipped:
|
|
19212
|
-
aiSummariesWritten:
|
|
19213
|
-
aiSummaryErrors:
|
|
19227
|
+
stopInvocations: state46.stopInvocations,
|
|
19228
|
+
recapsPublished: state46.recapsPublished,
|
|
19229
|
+
recapsErrored: state46.recapsErrored,
|
|
19230
|
+
recapsSkipped: state46.recapsSkipped,
|
|
19231
|
+
aiSummariesWritten: state46.aiSummariesWritten,
|
|
19232
|
+
aiSummaryErrors: state46.aiSummaryErrors
|
|
19214
19233
|
},
|
|
19215
19234
|
metrics: {
|
|
19216
|
-
totalInputTokens:
|
|
19217
|
-
totalOutputTokens:
|
|
19218
|
-
perModel: topN(
|
|
19235
|
+
totalInputTokens: state46.totalInputTokens,
|
|
19236
|
+
totalOutputTokens: state46.totalOutputTokens,
|
|
19237
|
+
perModel: topN(state46.perModel, 10).map(([model, u]) => ({
|
|
19219
19238
|
model,
|
|
19220
19239
|
input: u.inputTokens,
|
|
19221
19240
|
output: u.outputTokens,
|
|
19222
19241
|
invocations: u.invocations
|
|
19223
19242
|
})),
|
|
19224
19243
|
toolCalls: {
|
|
19225
|
-
total: [...
|
|
19226
|
-
uniqueTools:
|
|
19227
|
-
top: topN(
|
|
19244
|
+
total: [...state46.toolCounts.values()].reduce((a, b) => a + b, 0),
|
|
19245
|
+
uniqueTools: state46.toolCounts.size,
|
|
19246
|
+
top: topN(state46.toolCounts, 5)
|
|
19228
19247
|
},
|
|
19229
|
-
commits:
|
|
19248
|
+
commits: state46.commitCount
|
|
19230
19249
|
},
|
|
19231
19250
|
timing: {
|
|
19232
|
-
startedAt:
|
|
19233
|
-
lastActivityAt:
|
|
19234
|
-
duration: formatDuration(
|
|
19251
|
+
startedAt: state46.startedAt,
|
|
19252
|
+
lastActivityAt: state46.lastActivityAt,
|
|
19253
|
+
duration: formatDuration(state46.startedAt, state46.lastActivityAt)
|
|
19235
19254
|
}
|
|
19236
19255
|
};
|
|
19237
19256
|
}
|
|
@@ -19243,62 +19262,62 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
|
|
|
19243
19262
|
});
|
|
19244
19263
|
},
|
|
19245
19264
|
teardown(api) {
|
|
19246
|
-
if (
|
|
19265
|
+
if (state46.stopHookUnregister) {
|
|
19247
19266
|
try {
|
|
19248
|
-
|
|
19267
|
+
state46.stopHookUnregister();
|
|
19249
19268
|
} catch {
|
|
19250
19269
|
}
|
|
19251
|
-
|
|
19270
|
+
state46.stopHookUnregister = null;
|
|
19252
19271
|
}
|
|
19253
|
-
for (const off of
|
|
19272
|
+
for (const off of state46.eventUnsubscribers) {
|
|
19254
19273
|
try {
|
|
19255
19274
|
off();
|
|
19256
19275
|
} catch {
|
|
19257
19276
|
}
|
|
19258
19277
|
}
|
|
19259
|
-
|
|
19278
|
+
state46.eventUnsubscribers = [];
|
|
19260
19279
|
const final = {
|
|
19261
|
-
recapsPublished:
|
|
19262
|
-
recapsErrored:
|
|
19263
|
-
recapsSkipped:
|
|
19264
|
-
aiSummariesWritten:
|
|
19265
|
-
totalInputTokens:
|
|
19266
|
-
totalOutputTokens:
|
|
19267
|
-
toolCalls: [...
|
|
19268
|
-
commits:
|
|
19280
|
+
recapsPublished: state46.recapsPublished,
|
|
19281
|
+
recapsErrored: state46.recapsErrored,
|
|
19282
|
+
recapsSkipped: state46.recapsSkipped,
|
|
19283
|
+
aiSummariesWritten: state46.aiSummariesWritten,
|
|
19284
|
+
totalInputTokens: state46.totalInputTokens,
|
|
19285
|
+
totalOutputTokens: state46.totalOutputTokens,
|
|
19286
|
+
toolCalls: [...state46.toolCounts.values()].reduce((a, b) => a + b, 0),
|
|
19287
|
+
commits: state46.commitCount
|
|
19269
19288
|
};
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19278
|
-
|
|
19279
|
-
|
|
19280
|
-
|
|
19281
|
-
|
|
19282
|
-
|
|
19289
|
+
state46.recapsPublished = 0;
|
|
19290
|
+
state46.recapsErrored = 0;
|
|
19291
|
+
state46.recapsSkipped = 0;
|
|
19292
|
+
state46.aiSummariesWritten = 0;
|
|
19293
|
+
state46.aiSummaryErrors = 0;
|
|
19294
|
+
state46.stopInvocations = 0;
|
|
19295
|
+
state46.totalInputTokens = 0;
|
|
19296
|
+
state46.totalOutputTokens = 0;
|
|
19297
|
+
state46.perModel.clear();
|
|
19298
|
+
state46.toolCounts.clear();
|
|
19299
|
+
state46.commitCount = 0;
|
|
19300
|
+
state46.startedAt = null;
|
|
19301
|
+
state46.lastActivityAt = null;
|
|
19283
19302
|
api.log.info("session-recap: teardown complete", { final });
|
|
19284
19303
|
},
|
|
19285
19304
|
async health() {
|
|
19286
19305
|
return {
|
|
19287
19306
|
ok: true,
|
|
19288
|
-
message: `session-recap: ${
|
|
19307
|
+
message: `session-recap: ${state46.stopInvocations} stop(s), ${state46.recapsPublished} recap(s) published (${state46.aiSummariesWritten} with AI summary), ${state46.recapsErrored} error(s), ${state46.totalInputTokens + state46.totalOutputTokens} tokens observed`,
|
|
19289
19308
|
counters: {
|
|
19290
|
-
stopInvocations:
|
|
19291
|
-
recapsPublished:
|
|
19292
|
-
recapsErrored:
|
|
19293
|
-
recapsSkipped:
|
|
19294
|
-
aiSummariesWritten:
|
|
19295
|
-
aiSummaryErrors:
|
|
19309
|
+
stopInvocations: state46.stopInvocations,
|
|
19310
|
+
recapsPublished: state46.recapsPublished,
|
|
19311
|
+
recapsErrored: state46.recapsErrored,
|
|
19312
|
+
recapsSkipped: state46.recapsSkipped,
|
|
19313
|
+
aiSummariesWritten: state46.aiSummariesWritten,
|
|
19314
|
+
aiSummaryErrors: state46.aiSummaryErrors
|
|
19296
19315
|
},
|
|
19297
19316
|
metrics: {
|
|
19298
|
-
totalInputTokens:
|
|
19299
|
-
totalOutputTokens:
|
|
19300
|
-
toolCalls: [...
|
|
19301
|
-
commits:
|
|
19317
|
+
totalInputTokens: state46.totalInputTokens,
|
|
19318
|
+
totalOutputTokens: state46.totalOutputTokens,
|
|
19319
|
+
toolCalls: [...state46.toolCounts.values()].reduce((a, b) => a + b, 0),
|
|
19320
|
+
commits: state46.commitCount
|
|
19302
19321
|
}
|
|
19303
19322
|
};
|
|
19304
19323
|
}
|
|
@@ -19321,7 +19340,7 @@ function withinProject6(p) {
|
|
|
19321
19340
|
return true;
|
|
19322
19341
|
}
|
|
19323
19342
|
var MAX_PATH_LEN = 4096;
|
|
19324
|
-
var
|
|
19343
|
+
var state47 = {
|
|
19325
19344
|
/** Per-session invocation count. */
|
|
19326
19345
|
invocationCount: 0,
|
|
19327
19346
|
/** Total issues found across all runs this session (success or fail). */
|
|
@@ -19447,9 +19466,9 @@ var plugin51 = {
|
|
|
19447
19466
|
}
|
|
19448
19467
|
},
|
|
19449
19468
|
setup(api) {
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
|
|
19469
|
+
state47.invocationCount = 0;
|
|
19470
|
+
state47.totalIssues = 0;
|
|
19471
|
+
state47.lastRun = null;
|
|
19453
19472
|
api.tools.register({
|
|
19454
19473
|
name: "shellcheck",
|
|
19455
19474
|
description: "Run shellcheck analysis on shell script files. Pass `files` for specific files, or `directory` (optionally with `pattern`) to recursively scan for .sh files. Returns issues with file, line, column, severity, code, and message.",
|
|
@@ -19493,7 +19512,7 @@ var plugin51 = {
|
|
|
19493
19512
|
const directory = inp.directory ?? ".";
|
|
19494
19513
|
const pattern = inp.pattern ?? "";
|
|
19495
19514
|
const severity = inp.severity ?? "warning";
|
|
19496
|
-
|
|
19515
|
+
state47.invocationCount += 1;
|
|
19497
19516
|
const pathIsSafe = (p) => typeof p === "string" && p.length > 0 && p.length <= MAX_PATH_LEN && withinProject6(p);
|
|
19498
19517
|
if (!pathIsSafe(directory)) {
|
|
19499
19518
|
return {
|
|
@@ -19522,7 +19541,7 @@ var plugin51 = {
|
|
|
19522
19541
|
scannedDirectories = true;
|
|
19523
19542
|
}
|
|
19524
19543
|
if (checkFiles.length === 0) {
|
|
19525
|
-
|
|
19544
|
+
state47.lastRun = {
|
|
19526
19545
|
when: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19527
19546
|
filesChecked: 0,
|
|
19528
19547
|
issues: 0,
|
|
@@ -19557,8 +19576,8 @@ var plugin51 = {
|
|
|
19557
19576
|
const styleCount = issues.filter((i) => i.level === "style").length;
|
|
19558
19577
|
api.metrics.counter("issues_found", issues.length, { severity });
|
|
19559
19578
|
api.metrics.histogram("issues_per_file", issues.length / Math.max(checkFiles.length, 1));
|
|
19560
|
-
|
|
19561
|
-
|
|
19579
|
+
state47.totalIssues += issues.length;
|
|
19580
|
+
state47.lastRun = {
|
|
19562
19581
|
when: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19563
19582
|
filesChecked: checkFiles.length,
|
|
19564
19583
|
issues: issues.length,
|
|
@@ -19586,11 +19605,11 @@ var plugin51 = {
|
|
|
19586
19605
|
api.log.info("shell-check plugin loaded", { version: "0.2.0" });
|
|
19587
19606
|
},
|
|
19588
19607
|
teardown(api) {
|
|
19589
|
-
const finalInvocations =
|
|
19590
|
-
const finalIssues =
|
|
19591
|
-
|
|
19592
|
-
|
|
19593
|
-
|
|
19608
|
+
const finalInvocations = state47.invocationCount;
|
|
19609
|
+
const finalIssues = state47.totalIssues;
|
|
19610
|
+
state47.invocationCount = 0;
|
|
19611
|
+
state47.totalIssues = 0;
|
|
19612
|
+
state47.lastRun = null;
|
|
19594
19613
|
api.log.info("shell-check: teardown complete", {
|
|
19595
19614
|
invocations: finalInvocations,
|
|
19596
19615
|
totalIssues: finalIssues
|
|
@@ -19599,10 +19618,10 @@ var plugin51 = {
|
|
|
19599
19618
|
async health() {
|
|
19600
19619
|
return {
|
|
19601
19620
|
ok: true,
|
|
19602
|
-
message:
|
|
19603
|
-
invocationCount:
|
|
19604
|
-
totalIssues:
|
|
19605
|
-
lastRun:
|
|
19621
|
+
message: state47.lastRun === null ? `shell-check: ${state47.invocationCount} run(s) this session` : `shell-check: last run checked ${state47.lastRun.filesChecked} file(s), ${state47.lastRun.issues} issue(s) at ${state47.lastRun.when}`,
|
|
19622
|
+
invocationCount: state47.invocationCount,
|
|
19623
|
+
totalIssues: state47.totalIssues,
|
|
19624
|
+
lastRun: state47.lastRun
|
|
19606
19625
|
};
|
|
19607
19626
|
}
|
|
19608
19627
|
};
|
|
@@ -19612,7 +19631,7 @@ var shell_check_default = plugin51;
|
|
|
19612
19631
|
import { readFileSync as readFileSync13, writeFileSync as writeFileSync2 } from "node:fs";
|
|
19613
19632
|
import { extname as extname6, isAbsolute as isAbsolute25, relative as relative25, resolve as resolve25 } from "node:path";
|
|
19614
19633
|
var API_VERSION34 = "^0.1.10";
|
|
19615
|
-
var
|
|
19634
|
+
var state48 = {
|
|
19616
19635
|
renameCount: 0,
|
|
19617
19636
|
replacementCount: 0,
|
|
19618
19637
|
errorCount: 0
|
|
@@ -19684,9 +19703,9 @@ var plugin52 = {
|
|
|
19684
19703
|
}
|
|
19685
19704
|
},
|
|
19686
19705
|
setup(api) {
|
|
19687
|
-
|
|
19688
|
-
|
|
19689
|
-
|
|
19706
|
+
state48.renameCount = 0;
|
|
19707
|
+
state48.replacementCount = 0;
|
|
19708
|
+
state48.errorCount = 0;
|
|
19690
19709
|
const cfg = readConfig46(api.config.extensions?.["smart-rename"]);
|
|
19691
19710
|
api.tools.register({
|
|
19692
19711
|
name: "smart_rename",
|
|
@@ -19740,17 +19759,17 @@ var plugin52 = {
|
|
|
19740
19759
|
try {
|
|
19741
19760
|
content = readFileSync13(resolved, "utf-8");
|
|
19742
19761
|
} catch (err) {
|
|
19743
|
-
|
|
19762
|
+
state48.errorCount += 1;
|
|
19744
19763
|
return { ok: false, error: String(err) };
|
|
19745
19764
|
}
|
|
19746
19765
|
const { preview, replacements } = renameInContent(content, oldName, newName);
|
|
19747
|
-
|
|
19748
|
-
|
|
19766
|
+
state48.renameCount += 1;
|
|
19767
|
+
state48.replacementCount += replacements;
|
|
19749
19768
|
if (input.apply) {
|
|
19750
19769
|
try {
|
|
19751
19770
|
writeFileSync2(resolved, preview, "utf-8");
|
|
19752
19771
|
} catch (err) {
|
|
19753
|
-
|
|
19772
|
+
state48.errorCount += 1;
|
|
19754
19773
|
return { ok: false, error: String(err) };
|
|
19755
19774
|
}
|
|
19756
19775
|
}
|
|
@@ -19770,23 +19789,23 @@ var plugin52 = {
|
|
|
19770
19789
|
},
|
|
19771
19790
|
teardown(api) {
|
|
19772
19791
|
const final = {
|
|
19773
|
-
renames:
|
|
19774
|
-
replacements:
|
|
19775
|
-
errors:
|
|
19792
|
+
renames: state48.renameCount,
|
|
19793
|
+
replacements: state48.replacementCount,
|
|
19794
|
+
errors: state48.errorCount
|
|
19776
19795
|
};
|
|
19777
|
-
|
|
19778
|
-
|
|
19779
|
-
|
|
19796
|
+
state48.renameCount = 0;
|
|
19797
|
+
state48.replacementCount = 0;
|
|
19798
|
+
state48.errorCount = 0;
|
|
19780
19799
|
api.log.info("smart-rename: teardown complete", { final });
|
|
19781
19800
|
},
|
|
19782
19801
|
async health() {
|
|
19783
19802
|
return {
|
|
19784
|
-
ok:
|
|
19785
|
-
message:
|
|
19803
|
+
ok: state48.errorCount === 0,
|
|
19804
|
+
message: state48.errorCount ? `smart-rename: ${state48.errorCount} error(s)` : `smart-rename: ${state48.renameCount} rename(s), ${state48.replacementCount} replacement(s)`,
|
|
19786
19805
|
counters: {
|
|
19787
|
-
renames:
|
|
19788
|
-
replacements:
|
|
19789
|
-
errors:
|
|
19806
|
+
renames: state48.renameCount,
|
|
19807
|
+
replacements: state48.replacementCount,
|
|
19808
|
+
errors: state48.errorCount
|
|
19790
19809
|
}
|
|
19791
19810
|
};
|
|
19792
19811
|
}
|
|
@@ -19959,7 +19978,7 @@ var PLUGIN_NAMES = Object.freeze(
|
|
|
19959
19978
|
);
|
|
19960
19979
|
|
|
19961
19980
|
// src/spec-linker/index.ts
|
|
19962
|
-
var
|
|
19981
|
+
var state49 = {
|
|
19963
19982
|
postInvocations: 0,
|
|
19964
19983
|
preInvocations: 0,
|
|
19965
19984
|
unlinkedCount: 0,
|
|
@@ -20118,15 +20137,15 @@ var plugin53 = {
|
|
|
20118
20137
|
}
|
|
20119
20138
|
},
|
|
20120
20139
|
setup(api) {
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20129
|
-
|
|
20140
|
+
state49.postInvocations = 0;
|
|
20141
|
+
state49.preInvocations = 0;
|
|
20142
|
+
state49.unlinkedCount = 0;
|
|
20143
|
+
state49.cleanCount = 0;
|
|
20144
|
+
state49.skippedNonMd = 0;
|
|
20145
|
+
state49.readErrorCount = 0;
|
|
20146
|
+
state49.autoFixApplied = 0;
|
|
20147
|
+
state49.postHookUnregister = releaseHandle(state49.postHookUnregister);
|
|
20148
|
+
state49.preHookUnregister = releaseHandle(state49.preHookUnregister);
|
|
20130
20149
|
const cfg = readConfig47(api.config.extensions?.["spec-linker"]);
|
|
20131
20150
|
const postHook = async (input) => {
|
|
20132
20151
|
if (!cfg.enabled) return;
|
|
@@ -20137,25 +20156,25 @@ var plugin53 = {
|
|
|
20137
20156
|
const filePath = inp.path;
|
|
20138
20157
|
if (!filePath || typeof filePath !== "string") return;
|
|
20139
20158
|
if (!fileMatchesGlobs(filePath, cfg.fileGlobs)) {
|
|
20140
|
-
|
|
20159
|
+
state49.skippedNonMd += 1;
|
|
20141
20160
|
return;
|
|
20142
20161
|
}
|
|
20143
|
-
|
|
20162
|
+
state49.postInvocations += 1;
|
|
20144
20163
|
let content;
|
|
20145
20164
|
try {
|
|
20146
20165
|
const stat8 = await fs3.stat(filePath);
|
|
20147
20166
|
if (!stat8.isFile()) return;
|
|
20148
20167
|
content = await fs3.readFile(filePath, "utf-8");
|
|
20149
20168
|
} catch {
|
|
20150
|
-
|
|
20169
|
+
state49.readErrorCount += 1;
|
|
20151
20170
|
return;
|
|
20152
20171
|
}
|
|
20153
20172
|
const unlinked = findUnlinkedReferences(content.split("\n"), [...PLUGIN_NAMES]);
|
|
20154
20173
|
if (unlinked.length === 0) {
|
|
20155
|
-
|
|
20174
|
+
state49.cleanCount += 1;
|
|
20156
20175
|
return;
|
|
20157
20176
|
}
|
|
20158
|
-
|
|
20177
|
+
state49.unlinkedCount += 1;
|
|
20159
20178
|
const limited = unlinked.slice(0, cfg.maxReferences);
|
|
20160
20179
|
const overflow = unlinked.length - limited.length;
|
|
20161
20180
|
const lines = limited.map(
|
|
@@ -20169,7 +20188,7 @@ var plugin53 = {
|
|
|
20169
20188
|
${lines}${overflowNote}`
|
|
20170
20189
|
};
|
|
20171
20190
|
};
|
|
20172
|
-
|
|
20191
|
+
state49.postHookUnregister = api.registerHook("PostToolUse", "write|edit", postHook, { background: true });
|
|
20173
20192
|
if (cfg.autoFix) {
|
|
20174
20193
|
const preHook = async (input) => {
|
|
20175
20194
|
if (!cfg.enabled) return;
|
|
@@ -20179,10 +20198,10 @@ ${lines}${overflowNote}`
|
|
|
20179
20198
|
if (!filePath || typeof filePath !== "string") return;
|
|
20180
20199
|
if (!fileMatchesGlobs(filePath, cfg.fileGlobs)) return;
|
|
20181
20200
|
if (typeof inp.content !== "string" || inp.content.length === 0) return;
|
|
20182
|
-
|
|
20201
|
+
state49.preInvocations += 1;
|
|
20183
20202
|
const fixed = wrapUnlinkedReferences(inp.content);
|
|
20184
20203
|
if (fixed === inp.content) return;
|
|
20185
|
-
|
|
20204
|
+
state49.autoFixApplied += 1;
|
|
20186
20205
|
return {
|
|
20187
20206
|
decision: "allow",
|
|
20188
20207
|
modifiedInput: { ...inp, content: fixed, path: filePath },
|
|
@@ -20190,7 +20209,7 @@ ${lines}${overflowNote}`
|
|
|
20190
20209
|
\u{1F517} spec-linker (autoFix): wrapped unlinked plugin reference(s) in '${filePath}'.`
|
|
20191
20210
|
};
|
|
20192
20211
|
};
|
|
20193
|
-
|
|
20212
|
+
state49.preHookUnregister = api.registerHook("PreToolUse", "write", preHook, {
|
|
20194
20213
|
name: "spec-linker-autofix",
|
|
20195
20214
|
stage: "mutate",
|
|
20196
20215
|
failurePolicy: "open"
|
|
@@ -20211,13 +20230,13 @@ ${lines}${overflowNote}`
|
|
|
20211
20230
|
maxReferences: cfg.maxReferences,
|
|
20212
20231
|
autoFix: cfg.autoFix,
|
|
20213
20232
|
counters: {
|
|
20214
|
-
postInvocations:
|
|
20215
|
-
preInvocations:
|
|
20216
|
-
unlinked:
|
|
20217
|
-
clean:
|
|
20218
|
-
skippedNonMd:
|
|
20219
|
-
readErrors:
|
|
20220
|
-
autoFixApplied:
|
|
20233
|
+
postInvocations: state49.postInvocations,
|
|
20234
|
+
preInvocations: state49.preInvocations,
|
|
20235
|
+
unlinked: state49.unlinkedCount,
|
|
20236
|
+
clean: state49.cleanCount,
|
|
20237
|
+
skippedNonMd: state49.skippedNonMd,
|
|
20238
|
+
readErrors: state49.readErrorCount,
|
|
20239
|
+
autoFixApplied: state49.autoFixApplied
|
|
20221
20240
|
},
|
|
20222
20241
|
catalogSize: PLUGIN_NAMES.length
|
|
20223
20242
|
};
|
|
@@ -20232,7 +20251,7 @@ ${lines}${overflowNote}`
|
|
|
20232
20251
|
});
|
|
20233
20252
|
},
|
|
20234
20253
|
teardown(api) {
|
|
20235
|
-
for (const off of [
|
|
20254
|
+
for (const off of [state49.postHookUnregister, state49.preHookUnregister]) {
|
|
20236
20255
|
if (off) {
|
|
20237
20256
|
try {
|
|
20238
20257
|
off();
|
|
@@ -20240,38 +20259,38 @@ ${lines}${overflowNote}`
|
|
|
20240
20259
|
}
|
|
20241
20260
|
}
|
|
20242
20261
|
}
|
|
20243
|
-
|
|
20244
|
-
|
|
20262
|
+
state49.postHookUnregister = null;
|
|
20263
|
+
state49.preHookUnregister = null;
|
|
20245
20264
|
const final = {
|
|
20246
|
-
postInvocations:
|
|
20247
|
-
preInvocations:
|
|
20248
|
-
unlinked:
|
|
20249
|
-
clean:
|
|
20250
|
-
skippedNonMd:
|
|
20251
|
-
readErrors:
|
|
20252
|
-
autoFixApplied:
|
|
20265
|
+
postInvocations: state49.postInvocations,
|
|
20266
|
+
preInvocations: state49.preInvocations,
|
|
20267
|
+
unlinked: state49.unlinkedCount,
|
|
20268
|
+
clean: state49.cleanCount,
|
|
20269
|
+
skippedNonMd: state49.skippedNonMd,
|
|
20270
|
+
readErrors: state49.readErrorCount,
|
|
20271
|
+
autoFixApplied: state49.autoFixApplied
|
|
20253
20272
|
};
|
|
20254
|
-
|
|
20255
|
-
|
|
20256
|
-
|
|
20257
|
-
|
|
20258
|
-
|
|
20259
|
-
|
|
20260
|
-
|
|
20273
|
+
state49.postInvocations = 0;
|
|
20274
|
+
state49.preInvocations = 0;
|
|
20275
|
+
state49.unlinkedCount = 0;
|
|
20276
|
+
state49.cleanCount = 0;
|
|
20277
|
+
state49.skippedNonMd = 0;
|
|
20278
|
+
state49.readErrorCount = 0;
|
|
20279
|
+
state49.autoFixApplied = 0;
|
|
20261
20280
|
api.log.info("spec-linker: teardown complete", { final });
|
|
20262
20281
|
},
|
|
20263
20282
|
async health() {
|
|
20264
20283
|
return {
|
|
20265
20284
|
ok: true,
|
|
20266
|
-
message: `spec-linker: post=${
|
|
20285
|
+
message: `spec-linker: post=${state49.postInvocations} pre=${state49.preInvocations}, unlinked=${state49.unlinkedCount}, autoFix=${state49.autoFixApplied}, clean=${state49.cleanCount}, non-md=${state49.skippedNonMd}`,
|
|
20267
20286
|
counters: {
|
|
20268
|
-
postInvocations:
|
|
20269
|
-
preInvocations:
|
|
20270
|
-
unlinked:
|
|
20271
|
-
clean:
|
|
20272
|
-
skippedNonMd:
|
|
20273
|
-
readErrors:
|
|
20274
|
-
autoFixApplied:
|
|
20287
|
+
postInvocations: state49.postInvocations,
|
|
20288
|
+
preInvocations: state49.preInvocations,
|
|
20289
|
+
unlinked: state49.unlinkedCount,
|
|
20290
|
+
clean: state49.cleanCount,
|
|
20291
|
+
skippedNonMd: state49.skippedNonMd,
|
|
20292
|
+
readErrors: state49.readErrorCount,
|
|
20293
|
+
autoFixApplied: state49.autoFixApplied
|
|
20275
20294
|
}
|
|
20276
20295
|
};
|
|
20277
20296
|
}
|
|
@@ -20679,7 +20698,7 @@ var template_engine_default = plugin54;
|
|
|
20679
20698
|
// src/test-coverage-gate/index.ts
|
|
20680
20699
|
import { readFileSync as readFileSync14 } from "node:fs";
|
|
20681
20700
|
var API_VERSION36 = "^0.1.10";
|
|
20682
|
-
var
|
|
20701
|
+
var state50 = {
|
|
20683
20702
|
invocationCount: 0,
|
|
20684
20703
|
runCount: 0,
|
|
20685
20704
|
passCount: 0,
|
|
@@ -20780,15 +20799,15 @@ var plugin55 = {
|
|
|
20780
20799
|
}
|
|
20781
20800
|
},
|
|
20782
20801
|
setup(api) {
|
|
20783
|
-
|
|
20784
|
-
|
|
20785
|
-
|
|
20786
|
-
|
|
20787
|
-
|
|
20788
|
-
|
|
20789
|
-
|
|
20790
|
-
|
|
20791
|
-
|
|
20802
|
+
state50.invocationCount = 0;
|
|
20803
|
+
state50.runCount = 0;
|
|
20804
|
+
state50.passCount = 0;
|
|
20805
|
+
state50.failCount = 0;
|
|
20806
|
+
state50.errorCount = 0;
|
|
20807
|
+
state50.skippedCount = 0;
|
|
20808
|
+
state50.lastOverallPct = null;
|
|
20809
|
+
state50.lastResult = null;
|
|
20810
|
+
state50.hookUnregister = releaseHandle(state50.hookUnregister);
|
|
20792
20811
|
const cfg = readConfig48(api.config.extensions?.["test-coverage-gate"]);
|
|
20793
20812
|
const hook = (input) => {
|
|
20794
20813
|
if (!cfg.enabled) return;
|
|
@@ -20799,27 +20818,27 @@ var plugin55 = {
|
|
|
20799
20818
|
if (!withinProject(sourcePath)) return;
|
|
20800
20819
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
20801
20820
|
if (!runOnChangeSet.has(ext)) {
|
|
20802
|
-
|
|
20821
|
+
state50.skippedCount += 1;
|
|
20803
20822
|
return;
|
|
20804
20823
|
}
|
|
20805
|
-
|
|
20824
|
+
state50.invocationCount += 1;
|
|
20806
20825
|
const summary = readCoverageSummary(cfg.coveragePath);
|
|
20807
20826
|
if (!summary) {
|
|
20808
|
-
|
|
20827
|
+
state50.errorCount += 1;
|
|
20809
20828
|
return;
|
|
20810
20829
|
}
|
|
20811
20830
|
const pct = overallPercent(summary);
|
|
20812
20831
|
if (pct === null) {
|
|
20813
|
-
|
|
20832
|
+
state50.errorCount += 1;
|
|
20814
20833
|
return;
|
|
20815
20834
|
}
|
|
20816
|
-
|
|
20817
|
-
const previous =
|
|
20818
|
-
|
|
20835
|
+
state50.runCount += 1;
|
|
20836
|
+
const previous = state50.lastOverallPct;
|
|
20837
|
+
state50.lastOverallPct = pct;
|
|
20819
20838
|
const belowThreshold = pct < cfg.threshold;
|
|
20820
20839
|
const dropped = previous !== null && previous - pct >= cfg.deltaThreshold;
|
|
20821
20840
|
const passed = !belowThreshold && !dropped;
|
|
20822
|
-
|
|
20841
|
+
state50.lastResult = {
|
|
20823
20842
|
overallPct: pct,
|
|
20824
20843
|
previousOverallPct: previous,
|
|
20825
20844
|
threshold: cfg.threshold,
|
|
@@ -20827,10 +20846,10 @@ var plugin55 = {
|
|
|
20827
20846
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
20828
20847
|
};
|
|
20829
20848
|
if (passed) {
|
|
20830
|
-
|
|
20849
|
+
state50.passCount += 1;
|
|
20831
20850
|
return;
|
|
20832
20851
|
}
|
|
20833
|
-
|
|
20852
|
+
state50.failCount += 1;
|
|
20834
20853
|
const parts = ["\n\u274C test-coverage-gate:"];
|
|
20835
20854
|
if (belowThreshold) {
|
|
20836
20855
|
parts.push(
|
|
@@ -20852,7 +20871,7 @@ var plugin55 = {
|
|
|
20852
20871
|
}
|
|
20853
20872
|
return { additionalContext: message };
|
|
20854
20873
|
};
|
|
20855
|
-
|
|
20874
|
+
state50.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook);
|
|
20856
20875
|
api.tools.register({
|
|
20857
20876
|
name: "coverage_gate_status",
|
|
20858
20877
|
description: "Reports test-coverage-gate state: threshold, mode, last coverage percentage, and counters.",
|
|
@@ -20868,16 +20887,16 @@ var plugin55 = {
|
|
|
20868
20887
|
threshold: cfg.threshold,
|
|
20869
20888
|
mode: cfg.mode,
|
|
20870
20889
|
deltaThreshold: cfg.deltaThreshold,
|
|
20871
|
-
lastOverallPct:
|
|
20890
|
+
lastOverallPct: state50.lastOverallPct,
|
|
20872
20891
|
counters: {
|
|
20873
|
-
invocations:
|
|
20874
|
-
runs:
|
|
20875
|
-
passed:
|
|
20876
|
-
failed:
|
|
20877
|
-
errors:
|
|
20878
|
-
skipped:
|
|
20892
|
+
invocations: state50.invocationCount,
|
|
20893
|
+
runs: state50.runCount,
|
|
20894
|
+
passed: state50.passCount,
|
|
20895
|
+
failed: state50.failCount,
|
|
20896
|
+
errors: state50.errorCount,
|
|
20897
|
+
skipped: state50.skippedCount
|
|
20879
20898
|
},
|
|
20880
|
-
lastResult:
|
|
20899
|
+
lastResult: state50.lastResult
|
|
20881
20900
|
};
|
|
20882
20901
|
}
|
|
20883
20902
|
});
|
|
@@ -20889,44 +20908,44 @@ var plugin55 = {
|
|
|
20889
20908
|
});
|
|
20890
20909
|
},
|
|
20891
20910
|
teardown(api) {
|
|
20892
|
-
if (
|
|
20911
|
+
if (state50.hookUnregister) {
|
|
20893
20912
|
try {
|
|
20894
|
-
|
|
20913
|
+
state50.hookUnregister();
|
|
20895
20914
|
} catch {
|
|
20896
20915
|
}
|
|
20897
|
-
|
|
20916
|
+
state50.hookUnregister = null;
|
|
20898
20917
|
}
|
|
20899
20918
|
const final = {
|
|
20900
|
-
invocations:
|
|
20901
|
-
runs:
|
|
20902
|
-
passed:
|
|
20903
|
-
failed:
|
|
20904
|
-
errors:
|
|
20905
|
-
skipped:
|
|
20919
|
+
invocations: state50.invocationCount,
|
|
20920
|
+
runs: state50.runCount,
|
|
20921
|
+
passed: state50.passCount,
|
|
20922
|
+
failed: state50.failCount,
|
|
20923
|
+
errors: state50.errorCount,
|
|
20924
|
+
skipped: state50.skippedCount
|
|
20906
20925
|
};
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
|
|
20910
|
-
|
|
20911
|
-
|
|
20912
|
-
|
|
20913
|
-
|
|
20914
|
-
|
|
20926
|
+
state50.invocationCount = 0;
|
|
20927
|
+
state50.runCount = 0;
|
|
20928
|
+
state50.passCount = 0;
|
|
20929
|
+
state50.failCount = 0;
|
|
20930
|
+
state50.errorCount = 0;
|
|
20931
|
+
state50.skippedCount = 0;
|
|
20932
|
+
state50.lastOverallPct = null;
|
|
20933
|
+
state50.lastResult = null;
|
|
20915
20934
|
api.log.info("test-coverage-gate: teardown complete", { final });
|
|
20916
20935
|
},
|
|
20917
20936
|
async health() {
|
|
20918
20937
|
return {
|
|
20919
20938
|
ok: true,
|
|
20920
|
-
message:
|
|
20939
|
+
message: state50.lastResult ? `test-coverage-gate: ${state50.runCount} run(s), last ${state50.lastResult.passed ? "PASSED" : "FAILED"} (${state50.lastResult.overallPct.toFixed(2)}%)` : `test-coverage-gate: ${state50.invocationCount} invocation(s), ${state50.runCount} run(s)`,
|
|
20921
20940
|
counters: {
|
|
20922
|
-
invocations:
|
|
20923
|
-
runs:
|
|
20924
|
-
passed:
|
|
20925
|
-
failed:
|
|
20926
|
-
errors:
|
|
20927
|
-
skipped:
|
|
20928
|
-
},
|
|
20929
|
-
lastResult:
|
|
20941
|
+
invocations: state50.invocationCount,
|
|
20942
|
+
runs: state50.runCount,
|
|
20943
|
+
passed: state50.passCount,
|
|
20944
|
+
failed: state50.failCount,
|
|
20945
|
+
errors: state50.errorCount,
|
|
20946
|
+
skipped: state50.skippedCount
|
|
20947
|
+
},
|
|
20948
|
+
lastResult: state50.lastResult
|
|
20930
20949
|
};
|
|
20931
20950
|
}
|
|
20932
20951
|
};
|
|
@@ -20938,7 +20957,7 @@ import { readFileSync as readFileSync15 } from "node:fs";
|
|
|
20938
20957
|
import { createRequire as createRequire3 } from "node:module";
|
|
20939
20958
|
import { dirname as dirname8, isAbsolute as isAbsolute27, relative as relative26, resolve as resolve26 } from "node:path";
|
|
20940
20959
|
var API_VERSION37 = "^0.1.10";
|
|
20941
|
-
var
|
|
20960
|
+
var state51 = {
|
|
20942
20961
|
invocationCount: 0,
|
|
20943
20962
|
runCount: 0,
|
|
20944
20963
|
errorCount: 0,
|
|
@@ -21144,10 +21163,10 @@ var plugin56 = {
|
|
|
21144
21163
|
}
|
|
21145
21164
|
},
|
|
21146
21165
|
setup(api) {
|
|
21147
|
-
|
|
21148
|
-
|
|
21149
|
-
|
|
21150
|
-
|
|
21166
|
+
state51.invocationCount = 0;
|
|
21167
|
+
state51.runCount = 0;
|
|
21168
|
+
state51.errorCount = 0;
|
|
21169
|
+
state51.lastResult = null;
|
|
21151
21170
|
const cfg = readConfig49(api.config.extensions?.["test-flake-detector"]);
|
|
21152
21171
|
api.tools.register({
|
|
21153
21172
|
name: "flake_detect",
|
|
@@ -21190,16 +21209,16 @@ var plugin56 = {
|
|
|
21190
21209
|
error: "Unsupported test command or unsafe testPattern. Use vitest, jest, or mocha through a supported package runner, and keep patterns inside the project."
|
|
21191
21210
|
};
|
|
21192
21211
|
}
|
|
21193
|
-
|
|
21212
|
+
state51.invocationCount += 1;
|
|
21194
21213
|
const start = Date.now();
|
|
21195
21214
|
const records = /* @__PURE__ */ new Map();
|
|
21196
21215
|
let runsCompleted = 0;
|
|
21197
21216
|
const runErrors = [];
|
|
21198
21217
|
for (let run = 1; run <= requestedRuns; run += 1) {
|
|
21199
21218
|
const { output, error } = await runOnce(command, cfg.timeoutMs);
|
|
21200
|
-
|
|
21219
|
+
state51.runCount += 1;
|
|
21201
21220
|
if (error) {
|
|
21202
|
-
|
|
21221
|
+
state51.errorCount += 1;
|
|
21203
21222
|
runErrors.push(`run ${run}: ${error}`);
|
|
21204
21223
|
}
|
|
21205
21224
|
const parsed = parseTestOutput(output);
|
|
@@ -21220,7 +21239,7 @@ var plugin56 = {
|
|
|
21220
21239
|
const alwaysFailing = all.filter((r) => r.passCount === 0 && r.failCount > 0);
|
|
21221
21240
|
const alwaysPassing = all.filter((r) => r.passCount > 0 && r.failCount === 0);
|
|
21222
21241
|
const durationMs = Date.now() - start;
|
|
21223
|
-
|
|
21242
|
+
state51.lastResult = {
|
|
21224
21243
|
runsRequested: requestedRuns,
|
|
21225
21244
|
runsCompleted,
|
|
21226
21245
|
flakyTests,
|
|
@@ -21259,11 +21278,11 @@ var plugin56 = {
|
|
|
21259
21278
|
maxRuns: cfg.maxRuns,
|
|
21260
21279
|
timeoutMs: cfg.timeoutMs,
|
|
21261
21280
|
counters: {
|
|
21262
|
-
invocations:
|
|
21263
|
-
runs:
|
|
21264
|
-
errors:
|
|
21281
|
+
invocations: state51.invocationCount,
|
|
21282
|
+
runs: state51.runCount,
|
|
21283
|
+
errors: state51.errorCount
|
|
21265
21284
|
},
|
|
21266
|
-
lastResult:
|
|
21285
|
+
lastResult: state51.lastResult
|
|
21267
21286
|
};
|
|
21268
21287
|
}
|
|
21269
21288
|
});
|
|
@@ -21275,26 +21294,26 @@ var plugin56 = {
|
|
|
21275
21294
|
},
|
|
21276
21295
|
teardown(api) {
|
|
21277
21296
|
const final = {
|
|
21278
|
-
invocations:
|
|
21279
|
-
runs:
|
|
21280
|
-
errors:
|
|
21297
|
+
invocations: state51.invocationCount,
|
|
21298
|
+
runs: state51.runCount,
|
|
21299
|
+
errors: state51.errorCount
|
|
21281
21300
|
};
|
|
21282
|
-
|
|
21283
|
-
|
|
21284
|
-
|
|
21285
|
-
|
|
21301
|
+
state51.invocationCount = 0;
|
|
21302
|
+
state51.runCount = 0;
|
|
21303
|
+
state51.errorCount = 0;
|
|
21304
|
+
state51.lastResult = null;
|
|
21286
21305
|
api.log.info("test-flake-detector: teardown complete", { final });
|
|
21287
21306
|
},
|
|
21288
21307
|
async health() {
|
|
21289
21308
|
return {
|
|
21290
21309
|
ok: true,
|
|
21291
|
-
message:
|
|
21310
|
+
message: state51.lastResult ? `test-flake-detector: ${state51.runCount} run(s), last detection found ${state51.lastResult.flakyTests.length} flaky test(s)` : `test-flake-detector: ${state51.invocationCount} invocation(s), ${state51.runCount} run(s)`,
|
|
21292
21311
|
counters: {
|
|
21293
|
-
invocations:
|
|
21294
|
-
runs:
|
|
21295
|
-
errors:
|
|
21312
|
+
invocations: state51.invocationCount,
|
|
21313
|
+
runs: state51.runCount,
|
|
21314
|
+
errors: state51.errorCount
|
|
21296
21315
|
},
|
|
21297
|
-
lastResult:
|
|
21316
|
+
lastResult: state51.lastResult
|
|
21298
21317
|
};
|
|
21299
21318
|
}
|
|
21300
21319
|
};
|
|
@@ -21304,7 +21323,7 @@ var test_flake_detector_default = plugin56;
|
|
|
21304
21323
|
import { readFileSync as readFileSync16 } from "node:fs";
|
|
21305
21324
|
import { isAbsolute as isAbsolute28, relative as relative27, resolve as resolve27 } from "node:path";
|
|
21306
21325
|
var API_VERSION38 = "^0.1.10";
|
|
21307
|
-
var
|
|
21326
|
+
var state52 = {
|
|
21308
21327
|
generateCount: 0,
|
|
21309
21328
|
exportCount: 0,
|
|
21310
21329
|
errorCount: 0,
|
|
@@ -21549,11 +21568,11 @@ var plugin57 = {
|
|
|
21549
21568
|
}
|
|
21550
21569
|
},
|
|
21551
21570
|
setup(api) {
|
|
21552
|
-
|
|
21553
|
-
|
|
21554
|
-
|
|
21555
|
-
|
|
21556
|
-
|
|
21571
|
+
state52.generateCount = 0;
|
|
21572
|
+
state52.exportCount = 0;
|
|
21573
|
+
state52.errorCount = 0;
|
|
21574
|
+
state52.llmGenerationCount = 0;
|
|
21575
|
+
state52.llmFallbackCount = 0;
|
|
21557
21576
|
const cfg = readConfig50(api.config.extensions?.["test-generator"]);
|
|
21558
21577
|
api.tools.register({
|
|
21559
21578
|
name: "generate_unit_tests",
|
|
@@ -21592,15 +21611,15 @@ var plugin57 = {
|
|
|
21592
21611
|
};
|
|
21593
21612
|
}
|
|
21594
21613
|
const resolved = resolve27(process.cwd(), rawPath);
|
|
21595
|
-
|
|
21614
|
+
state52.generateCount += 1;
|
|
21596
21615
|
let result;
|
|
21597
21616
|
try {
|
|
21598
21617
|
result = generateForFile(resolved, cfg);
|
|
21599
21618
|
} catch (err) {
|
|
21600
|
-
|
|
21619
|
+
state52.errorCount += 1;
|
|
21601
21620
|
return { ok: false, error: String(err) };
|
|
21602
21621
|
}
|
|
21603
|
-
|
|
21622
|
+
state52.exportCount += result.exports.length;
|
|
21604
21623
|
const requested = input.use_llm ?? cfg.useLlm;
|
|
21605
21624
|
const llm = await runOptionalPluginLlm({
|
|
21606
21625
|
requested,
|
|
@@ -21616,8 +21635,8 @@ var plugin57 = {
|
|
|
21616
21635
|
},
|
|
21617
21636
|
parse: parseGeneratedTest
|
|
21618
21637
|
});
|
|
21619
|
-
if (llm.used)
|
|
21620
|
-
else if (requested)
|
|
21638
|
+
if (llm.used) state52.llmGenerationCount += 1;
|
|
21639
|
+
else if (requested) state52.llmFallbackCount += 1;
|
|
21621
21640
|
api.metrics.counter("generations", 1, { framework: cfg.framework });
|
|
21622
21641
|
api.metrics.counter("exports_detected", result.exports.length);
|
|
21623
21642
|
if (llm.used) api.metrics.counter("llm_generations", 1);
|
|
@@ -21646,29 +21665,29 @@ var plugin57 = {
|
|
|
21646
21665
|
},
|
|
21647
21666
|
teardown(api) {
|
|
21648
21667
|
const final = {
|
|
21649
|
-
generated:
|
|
21650
|
-
exports:
|
|
21651
|
-
errors:
|
|
21652
|
-
llmGenerations:
|
|
21653
|
-
llmFallbacks:
|
|
21668
|
+
generated: state52.generateCount,
|
|
21669
|
+
exports: state52.exportCount,
|
|
21670
|
+
errors: state52.errorCount,
|
|
21671
|
+
llmGenerations: state52.llmGenerationCount,
|
|
21672
|
+
llmFallbacks: state52.llmFallbackCount
|
|
21654
21673
|
};
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21674
|
+
state52.generateCount = 0;
|
|
21675
|
+
state52.exportCount = 0;
|
|
21676
|
+
state52.errorCount = 0;
|
|
21677
|
+
state52.llmGenerationCount = 0;
|
|
21678
|
+
state52.llmFallbackCount = 0;
|
|
21660
21679
|
api.log.info("test-generator: teardown complete", { final });
|
|
21661
21680
|
},
|
|
21662
21681
|
async health() {
|
|
21663
21682
|
return {
|
|
21664
|
-
ok:
|
|
21665
|
-
message:
|
|
21683
|
+
ok: state52.errorCount === 0,
|
|
21684
|
+
message: state52.errorCount ? `test-generator: ${state52.errorCount} error(s)` : `test-generator: ${state52.generateCount} generation(s), ${state52.exportCount} export(s)`,
|
|
21666
21685
|
counters: {
|
|
21667
|
-
generated:
|
|
21668
|
-
exports:
|
|
21669
|
-
errors:
|
|
21670
|
-
llmGenerations:
|
|
21671
|
-
llmFallbacks:
|
|
21686
|
+
generated: state52.generateCount,
|
|
21687
|
+
exports: state52.exportCount,
|
|
21688
|
+
errors: state52.errorCount,
|
|
21689
|
+
llmGenerations: state52.llmGenerationCount,
|
|
21690
|
+
llmFallbacks: state52.llmFallbackCount
|
|
21672
21691
|
}
|
|
21673
21692
|
};
|
|
21674
21693
|
}
|
|
@@ -21690,7 +21709,7 @@ function resolveExec(command, args) {
|
|
|
21690
21709
|
return { cmd: resolved, args: [...args], windowsVerbatimArguments: false };
|
|
21691
21710
|
}
|
|
21692
21711
|
var API_VERSION39 = "^0.1.10";
|
|
21693
|
-
var
|
|
21712
|
+
var state53 = {
|
|
21694
21713
|
invocationCount: 0,
|
|
21695
21714
|
/** Times a test file was found and tests ran. */
|
|
21696
21715
|
runCount: 0,
|
|
@@ -22001,16 +22020,16 @@ var plugin58 = {
|
|
|
22001
22020
|
}
|
|
22002
22021
|
},
|
|
22003
22022
|
async setup(api) {
|
|
22004
|
-
|
|
22005
|
-
|
|
22006
|
-
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22023
|
+
state53.invocationCount = 0;
|
|
22024
|
+
state53.runCount = 0;
|
|
22025
|
+
state53.passCount = 0;
|
|
22026
|
+
state53.failCount = 0;
|
|
22027
|
+
state53.noTestCount = 0;
|
|
22028
|
+
state53.errorCount = 0;
|
|
22029
|
+
state53.extensionSkippedCount = 0;
|
|
22030
|
+
state53.cachedSkipCount = 0;
|
|
22031
|
+
state53.hookUnregister = releaseHandle(state53.hookUnregister);
|
|
22032
|
+
state53.lastResult = null;
|
|
22014
22033
|
lastPassedHash.clear();
|
|
22015
22034
|
const cfg = readConfig51(api.config.extensions?.["test-runner-gate"]);
|
|
22016
22035
|
const runner = await detectRunner(cfg.runner);
|
|
@@ -22036,19 +22055,19 @@ var plugin58 = {
|
|
|
22036
22055
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
22037
22056
|
const resolvable = getResolvableExtensions(cfg.testFilePatterns);
|
|
22038
22057
|
if (ext && !resolvable.has(ext) && !TESTABLE_DEFAULT_EXTS.has(ext)) {
|
|
22039
|
-
|
|
22058
|
+
state53.extensionSkippedCount += 1;
|
|
22040
22059
|
api.metrics.counter("extension_skipped");
|
|
22041
22060
|
return;
|
|
22042
22061
|
}
|
|
22043
22062
|
}
|
|
22044
|
-
|
|
22063
|
+
state53.invocationCount += 1;
|
|
22045
22064
|
if (cfg.enableContentHashCache) {
|
|
22046
22065
|
const content = input.toolName === "write" ? inp["content"] ?? "" : input.toolName === "edit" ? inp["new_string"] ?? "" : "";
|
|
22047
22066
|
if (typeof content === "string" && content.length > 0) {
|
|
22048
22067
|
const hash = pathContentHash(content);
|
|
22049
22068
|
const last = lastPassedHash.get(sourcePath);
|
|
22050
22069
|
if (last !== void 0 && last === hash) {
|
|
22051
|
-
|
|
22070
|
+
state53.cachedSkipCount += 1;
|
|
22052
22071
|
api.metrics.counter("cached_skip");
|
|
22053
22072
|
return;
|
|
22054
22073
|
}
|
|
@@ -22056,16 +22075,16 @@ var plugin58 = {
|
|
|
22056
22075
|
}
|
|
22057
22076
|
const testFile = await findTestFile(sourcePath, cfg.testFilePatterns);
|
|
22058
22077
|
if (!testFile) {
|
|
22059
|
-
|
|
22078
|
+
state53.noTestCount += 1;
|
|
22060
22079
|
return;
|
|
22061
22080
|
}
|
|
22062
22081
|
const result = await runTests(testFile, runner, cfg.command, cfg.timeoutMs);
|
|
22063
22082
|
if (!result) {
|
|
22064
|
-
|
|
22083
|
+
state53.errorCount += 1;
|
|
22065
22084
|
return;
|
|
22066
22085
|
}
|
|
22067
|
-
|
|
22068
|
-
|
|
22086
|
+
state53.runCount += 1;
|
|
22087
|
+
state53.lastResult = {
|
|
22069
22088
|
sourcePath,
|
|
22070
22089
|
testPath: testFile,
|
|
22071
22090
|
passed: result.passed,
|
|
@@ -22074,7 +22093,7 @@ var plugin58 = {
|
|
|
22074
22093
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
22075
22094
|
};
|
|
22076
22095
|
if (result.passed) {
|
|
22077
|
-
|
|
22096
|
+
state53.passCount += 1;
|
|
22078
22097
|
if (cfg.enableContentHashCache) {
|
|
22079
22098
|
const content = input.toolName === "write" ? inp["content"] ?? "" : input.toolName === "edit" ? inp["new_string"] ?? "" : "";
|
|
22080
22099
|
if (typeof content === "string" && content.length > 0) {
|
|
@@ -22087,7 +22106,7 @@ var plugin58 = {
|
|
|
22087
22106
|
\u2705 test-runner-gate: ${result.testCount} test(s) passed for ${testFile} (${result.duration}). Source: ${sourcePath}.`
|
|
22088
22107
|
};
|
|
22089
22108
|
}
|
|
22090
|
-
|
|
22109
|
+
state53.failCount += 1;
|
|
22091
22110
|
const failureList = result.failures.length > 0 ? "\n" + result.failures.map((f) => ` \u274C ${f}`).join("\n") : "";
|
|
22092
22111
|
const truncated = result.failCount > 5 ? `
|
|
22093
22112
|
\u2026 and ${result.failCount - 5} more failure(s)` : "";
|
|
@@ -22100,7 +22119,7 @@ var plugin58 = {
|
|
|
22100
22119
|
Fix the failing tests or revert the change if it broke something.`
|
|
22101
22120
|
};
|
|
22102
22121
|
};
|
|
22103
|
-
|
|
22122
|
+
state53.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, { background: true });
|
|
22104
22123
|
api.tools.register({
|
|
22105
22124
|
name: "test_gate_status",
|
|
22106
22125
|
description: "Reports test-runner-gate state: command, patterns, and per-session pass/fail/error/no-test counters.",
|
|
@@ -22118,16 +22137,16 @@ Fix the failing tests or revert the change if it broke something.`
|
|
|
22118
22137
|
testFilePatterns: cfg.testFilePatterns,
|
|
22119
22138
|
injectOnPass: cfg.injectOnPass,
|
|
22120
22139
|
counters: {
|
|
22121
|
-
invocations:
|
|
22122
|
-
runs:
|
|
22123
|
-
passed:
|
|
22124
|
-
failed:
|
|
22125
|
-
noTest:
|
|
22126
|
-
errors:
|
|
22127
|
-
extensionSkipped:
|
|
22128
|
-
cachedSkips:
|
|
22140
|
+
invocations: state53.invocationCount,
|
|
22141
|
+
runs: state53.runCount,
|
|
22142
|
+
passed: state53.passCount,
|
|
22143
|
+
failed: state53.failCount,
|
|
22144
|
+
noTest: state53.noTestCount,
|
|
22145
|
+
errors: state53.errorCount,
|
|
22146
|
+
extensionSkipped: state53.extensionSkippedCount,
|
|
22147
|
+
cachedSkips: state53.cachedSkipCount
|
|
22129
22148
|
},
|
|
22130
|
-
lastResult:
|
|
22149
|
+
lastResult: state53.lastResult
|
|
22131
22150
|
};
|
|
22132
22151
|
}
|
|
22133
22152
|
});
|
|
@@ -22138,57 +22157,57 @@ Fix the failing tests or revert the change if it broke something.`
|
|
|
22138
22157
|
});
|
|
22139
22158
|
},
|
|
22140
22159
|
teardown(api) {
|
|
22141
|
-
if (
|
|
22160
|
+
if (state53.hookUnregister) {
|
|
22142
22161
|
try {
|
|
22143
|
-
|
|
22162
|
+
state53.hookUnregister();
|
|
22144
22163
|
} catch {
|
|
22145
22164
|
}
|
|
22146
|
-
|
|
22165
|
+
state53.hookUnregister = null;
|
|
22147
22166
|
}
|
|
22148
22167
|
const final = {
|
|
22149
|
-
invocations:
|
|
22150
|
-
runs:
|
|
22151
|
-
passed:
|
|
22152
|
-
failed:
|
|
22153
|
-
noTest:
|
|
22154
|
-
errors:
|
|
22155
|
-
extensionSkipped:
|
|
22156
|
-
cachedSkips:
|
|
22168
|
+
invocations: state53.invocationCount,
|
|
22169
|
+
runs: state53.runCount,
|
|
22170
|
+
passed: state53.passCount,
|
|
22171
|
+
failed: state53.failCount,
|
|
22172
|
+
noTest: state53.noTestCount,
|
|
22173
|
+
errors: state53.errorCount,
|
|
22174
|
+
extensionSkipped: state53.extensionSkippedCount,
|
|
22175
|
+
cachedSkips: state53.cachedSkipCount
|
|
22157
22176
|
};
|
|
22158
|
-
|
|
22159
|
-
|
|
22160
|
-
|
|
22161
|
-
|
|
22162
|
-
|
|
22163
|
-
|
|
22164
|
-
|
|
22165
|
-
|
|
22166
|
-
|
|
22177
|
+
state53.invocationCount = 0;
|
|
22178
|
+
state53.runCount = 0;
|
|
22179
|
+
state53.passCount = 0;
|
|
22180
|
+
state53.failCount = 0;
|
|
22181
|
+
state53.noTestCount = 0;
|
|
22182
|
+
state53.errorCount = 0;
|
|
22183
|
+
state53.extensionSkippedCount = 0;
|
|
22184
|
+
state53.cachedSkipCount = 0;
|
|
22185
|
+
state53.lastResult = null;
|
|
22167
22186
|
lastPassedHash.clear();
|
|
22168
22187
|
api.log.info("test-runner-gate: teardown complete", { final });
|
|
22169
22188
|
},
|
|
22170
22189
|
async health() {
|
|
22171
22190
|
return {
|
|
22172
22191
|
ok: true,
|
|
22173
|
-
message:
|
|
22192
|
+
message: state53.lastResult === null ? `test-runner-gate: ${state53.invocationCount} invocation(s), ${state53.runCount} test run(s)` : state53.lastResult.passed ? `test-runner-gate: last run PASSED (${state53.lastResult.testCount} tests) on ${state53.lastResult.testPath}` : `test-runner-gate: last run FAILED (${state53.lastResult.testCount} tests) on ${state53.lastResult.testPath} at ${state53.lastResult.when}`,
|
|
22174
22193
|
counters: {
|
|
22175
|
-
invocations:
|
|
22176
|
-
runs:
|
|
22177
|
-
passed:
|
|
22178
|
-
failed:
|
|
22179
|
-
noTest:
|
|
22180
|
-
errors:
|
|
22181
|
-
extensionSkipped:
|
|
22182
|
-
cachedSkips:
|
|
22183
|
-
},
|
|
22184
|
-
lastResult:
|
|
22194
|
+
invocations: state53.invocationCount,
|
|
22195
|
+
runs: state53.runCount,
|
|
22196
|
+
passed: state53.passCount,
|
|
22197
|
+
failed: state53.failCount,
|
|
22198
|
+
noTest: state53.noTestCount,
|
|
22199
|
+
errors: state53.errorCount,
|
|
22200
|
+
extensionSkipped: state53.extensionSkippedCount,
|
|
22201
|
+
cachedSkips: state53.cachedSkipCount
|
|
22202
|
+
},
|
|
22203
|
+
lastResult: state53.lastResult
|
|
22185
22204
|
};
|
|
22186
22205
|
}
|
|
22187
22206
|
};
|
|
22188
22207
|
var test_runner_gate_default = plugin58;
|
|
22189
22208
|
|
|
22190
22209
|
// src/todo-listener/index.ts
|
|
22191
|
-
var
|
|
22210
|
+
var state54 = {
|
|
22192
22211
|
invocationCount: 0,
|
|
22193
22212
|
sentCount: 0,
|
|
22194
22213
|
skippedCount: 0,
|
|
@@ -22253,23 +22272,23 @@ var plugin59 = {
|
|
|
22253
22272
|
}
|
|
22254
22273
|
},
|
|
22255
22274
|
setup(api) {
|
|
22256
|
-
|
|
22257
|
-
|
|
22258
|
-
|
|
22259
|
-
|
|
22260
|
-
|
|
22261
|
-
|
|
22262
|
-
|
|
22263
|
-
|
|
22275
|
+
state54.invocationCount = 0;
|
|
22276
|
+
state54.sentCount = 0;
|
|
22277
|
+
state54.skippedCount = 0;
|
|
22278
|
+
state54.errorCount = 0;
|
|
22279
|
+
state54.lastMessageId = null;
|
|
22280
|
+
state54.lastPayloadHash = "";
|
|
22281
|
+
state54.lastBroadcastAt = 0;
|
|
22282
|
+
state54.hookUnregister = releaseHandle(state54.hookUnregister);
|
|
22264
22283
|
const cfg = readConfig52(api.config.extensions?.["todo-listener"]);
|
|
22265
22284
|
const mailbox = api.mailbox;
|
|
22266
22285
|
const hook = async (input) => {
|
|
22267
22286
|
if (!cfg.enabled) return;
|
|
22268
22287
|
if (input.toolName !== "todo") return;
|
|
22269
22288
|
if (input.toolResult?.isError) return;
|
|
22270
|
-
|
|
22289
|
+
state54.invocationCount += 1;
|
|
22271
22290
|
if (!mailbox) {
|
|
22272
|
-
|
|
22291
|
+
state54.skippedCount += 1;
|
|
22273
22292
|
api.log.warn(
|
|
22274
22293
|
"todo-listener: no mailbox available on api \u2014 broadcasts disabled. Add `mailbox` to the setupPlugins() call to enable cross-agent visibility."
|
|
22275
22294
|
);
|
|
@@ -22288,13 +22307,13 @@ var plugin59 = {
|
|
|
22288
22307
|
items: todos.map((t) => ({ id: t.id, status: t.status, content: t.content }))
|
|
22289
22308
|
};
|
|
22290
22309
|
const hash = hashTodos(todos);
|
|
22291
|
-
if (cfg.broadcastOnChange && hash ===
|
|
22292
|
-
|
|
22310
|
+
if (cfg.broadcastOnChange && hash === state54.lastPayloadHash) {
|
|
22311
|
+
state54.skippedCount += 1;
|
|
22293
22312
|
return;
|
|
22294
22313
|
}
|
|
22295
22314
|
const now = Date.now();
|
|
22296
|
-
if (now -
|
|
22297
|
-
|
|
22315
|
+
if (now - state54.lastBroadcastAt < cfg.cooldownMs) {
|
|
22316
|
+
state54.skippedCount += 1;
|
|
22298
22317
|
return;
|
|
22299
22318
|
}
|
|
22300
22319
|
const subject = `${cfg.subjectPrefix}${inProgress ? `working on '${inProgress.content}'` : `${todos.length} item(s)`}`.slice(
|
|
@@ -22313,23 +22332,23 @@ var plugin59 = {
|
|
|
22313
22332
|
try {
|
|
22314
22333
|
const result = await mailbox.send(sendInput);
|
|
22315
22334
|
const id = result.id ?? null;
|
|
22316
|
-
|
|
22317
|
-
|
|
22318
|
-
|
|
22319
|
-
|
|
22335
|
+
state54.sentCount += 1;
|
|
22336
|
+
state54.lastMessageId = id;
|
|
22337
|
+
state54.lastPayloadHash = hash;
|
|
22338
|
+
state54.lastBroadcastAt = now;
|
|
22320
22339
|
api.log.info(`todo-listener: broadcast todo update`, {
|
|
22321
22340
|
count: payload.count,
|
|
22322
22341
|
inProgress: payload.inProgress?.id ?? null,
|
|
22323
22342
|
messageId: id
|
|
22324
22343
|
});
|
|
22325
22344
|
} catch (err) {
|
|
22326
|
-
|
|
22345
|
+
state54.errorCount += 1;
|
|
22327
22346
|
api.log.warn("todo-listener: mailbox.send failed", {
|
|
22328
22347
|
error: err instanceof Error ? err.message : String(err)
|
|
22329
22348
|
});
|
|
22330
22349
|
}
|
|
22331
22350
|
};
|
|
22332
|
-
|
|
22351
|
+
state54.hookUnregister = api.registerHook("PostToolUse", "todo", hook);
|
|
22333
22352
|
api.tools.register({
|
|
22334
22353
|
name: "todo_listener_status",
|
|
22335
22354
|
description: "Reports todo-listener state: config + per-session counters (invocations, sent, skipped, errors) and last broadcast id.",
|
|
@@ -22346,13 +22365,13 @@ var plugin59 = {
|
|
|
22346
22365
|
cooldownMs: cfg.cooldownMs,
|
|
22347
22366
|
mailboxAvailable: Boolean(mailbox),
|
|
22348
22367
|
counters: {
|
|
22349
|
-
invocations:
|
|
22350
|
-
sent:
|
|
22351
|
-
skipped:
|
|
22352
|
-
errors:
|
|
22368
|
+
invocations: state54.invocationCount,
|
|
22369
|
+
sent: state54.sentCount,
|
|
22370
|
+
skipped: state54.skippedCount,
|
|
22371
|
+
errors: state54.errorCount
|
|
22353
22372
|
},
|
|
22354
|
-
lastMessageId:
|
|
22355
|
-
lastBroadcastAt:
|
|
22373
|
+
lastMessageId: state54.lastMessageId,
|
|
22374
|
+
lastBroadcastAt: state54.lastBroadcastAt > 0 ? new Date(state54.lastBroadcastAt).toISOString() : null
|
|
22356
22375
|
};
|
|
22357
22376
|
}
|
|
22358
22377
|
});
|
|
@@ -22363,40 +22382,40 @@ var plugin59 = {
|
|
|
22363
22382
|
});
|
|
22364
22383
|
},
|
|
22365
22384
|
teardown(api) {
|
|
22366
|
-
if (
|
|
22385
|
+
if (state54.hookUnregister) {
|
|
22367
22386
|
try {
|
|
22368
|
-
|
|
22387
|
+
state54.hookUnregister();
|
|
22369
22388
|
} catch {
|
|
22370
22389
|
}
|
|
22371
|
-
|
|
22390
|
+
state54.hookUnregister = null;
|
|
22372
22391
|
}
|
|
22373
22392
|
const final = {
|
|
22374
|
-
invocations:
|
|
22375
|
-
sent:
|
|
22376
|
-
skipped:
|
|
22377
|
-
errors:
|
|
22393
|
+
invocations: state54.invocationCount,
|
|
22394
|
+
sent: state54.sentCount,
|
|
22395
|
+
skipped: state54.skippedCount,
|
|
22396
|
+
errors: state54.errorCount
|
|
22378
22397
|
};
|
|
22379
|
-
|
|
22380
|
-
|
|
22381
|
-
|
|
22382
|
-
|
|
22383
|
-
|
|
22384
|
-
|
|
22385
|
-
|
|
22398
|
+
state54.invocationCount = 0;
|
|
22399
|
+
state54.sentCount = 0;
|
|
22400
|
+
state54.skippedCount = 0;
|
|
22401
|
+
state54.errorCount = 0;
|
|
22402
|
+
state54.lastMessageId = null;
|
|
22403
|
+
state54.lastPayloadHash = "";
|
|
22404
|
+
state54.lastBroadcastAt = 0;
|
|
22386
22405
|
api.log.info("todo-listener: teardown complete", { final });
|
|
22387
22406
|
},
|
|
22388
22407
|
async health() {
|
|
22389
|
-
const base = `todo-listener: ${
|
|
22408
|
+
const base = `todo-listener: ${state54.invocationCount} invocation(s), ${state54.sentCount} sent, ${state54.skippedCount} skipped, ${state54.errorCount} error(s)`;
|
|
22390
22409
|
return {
|
|
22391
22410
|
ok: true,
|
|
22392
|
-
message:
|
|
22411
|
+
message: state54.lastMessageId ? `${base}; last broadcast ${state54.lastMessageId}` : `${base}; no broadcast yet`,
|
|
22393
22412
|
counters: {
|
|
22394
|
-
invocations:
|
|
22395
|
-
sent:
|
|
22396
|
-
skipped:
|
|
22397
|
-
errors:
|
|
22413
|
+
invocations: state54.invocationCount,
|
|
22414
|
+
sent: state54.sentCount,
|
|
22415
|
+
skipped: state54.skippedCount,
|
|
22416
|
+
errors: state54.errorCount
|
|
22398
22417
|
},
|
|
22399
|
-
lastMessageId:
|
|
22418
|
+
lastMessageId: state54.lastMessageId
|
|
22400
22419
|
};
|
|
22401
22420
|
}
|
|
22402
22421
|
};
|
|
@@ -22438,7 +22457,7 @@ async function saveFile(filePath, file) {
|
|
|
22438
22457
|
await ensureDir3(filePath.replace(/[/\\][^/\\]+$/, ""));
|
|
22439
22458
|
await atomicWrite3(filePath, JSON.stringify(file, null, 2), { mode: 384 });
|
|
22440
22459
|
}
|
|
22441
|
-
var
|
|
22460
|
+
var state55 = {
|
|
22442
22461
|
filePath: null,
|
|
22443
22462
|
projectSlug: null,
|
|
22444
22463
|
file: null,
|
|
@@ -22454,23 +22473,23 @@ function nowIso() {
|
|
|
22454
22473
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
22455
22474
|
}
|
|
22456
22475
|
function ensureFile() {
|
|
22457
|
-
if (!
|
|
22458
|
-
|
|
22476
|
+
if (!state55.file) {
|
|
22477
|
+
state55.file = {
|
|
22459
22478
|
version: FILE_VERSION,
|
|
22460
|
-
projectSlug:
|
|
22479
|
+
projectSlug: state55.projectSlug ?? "unconfigured",
|
|
22461
22480
|
updatedAt: nowIso(),
|
|
22462
22481
|
items: []
|
|
22463
22482
|
};
|
|
22464
22483
|
}
|
|
22465
|
-
return
|
|
22484
|
+
return state55.file;
|
|
22466
22485
|
}
|
|
22467
22486
|
function recordMutation(op, itemId) {
|
|
22468
|
-
|
|
22469
|
-
if (op === "add")
|
|
22470
|
-
else if (op === "complete")
|
|
22471
|
-
else if (op === "drop")
|
|
22472
|
-
else if (op === "remove")
|
|
22473
|
-
else if (op === "pull")
|
|
22487
|
+
state55.lastMutation = { op, itemId, when: nowIso() };
|
|
22488
|
+
if (op === "add") state55.addCount += 1;
|
|
22489
|
+
else if (op === "complete") state55.completeCount += 1;
|
|
22490
|
+
else if (op === "drop") state55.dropCount += 1;
|
|
22491
|
+
else if (op === "remove") state55.removeCount += 1;
|
|
22492
|
+
else if (op === "pull") state55.pullCount += 1;
|
|
22474
22493
|
}
|
|
22475
22494
|
function findItemIndex(id) {
|
|
22476
22495
|
return ensureFile().items.findIndex((it) => it.id === id);
|
|
@@ -22500,13 +22519,13 @@ var plugin60 = {
|
|
|
22500
22519
|
}
|
|
22501
22520
|
},
|
|
22502
22521
|
async setup(api) {
|
|
22503
|
-
|
|
22504
|
-
|
|
22505
|
-
|
|
22506
|
-
|
|
22507
|
-
|
|
22508
|
-
|
|
22509
|
-
|
|
22522
|
+
state55.addCount = 0;
|
|
22523
|
+
state55.completeCount = 0;
|
|
22524
|
+
state55.dropCount = 0;
|
|
22525
|
+
state55.removeCount = 0;
|
|
22526
|
+
state55.pullCount = 0;
|
|
22527
|
+
state55.lastMutation = null;
|
|
22528
|
+
state55.file = null;
|
|
22510
22529
|
const derived = deriveFilePath(api);
|
|
22511
22530
|
if (derived.filePath === null) {
|
|
22512
22531
|
api.log.warn(
|
|
@@ -22514,13 +22533,13 @@ var plugin60 = {
|
|
|
22514
22533
|
);
|
|
22515
22534
|
return;
|
|
22516
22535
|
}
|
|
22517
|
-
|
|
22518
|
-
|
|
22519
|
-
|
|
22520
|
-
if (
|
|
22521
|
-
|
|
22536
|
+
state55.filePath = derived.filePath;
|
|
22537
|
+
state55.projectSlug = derived.projectSlug;
|
|
22538
|
+
state55.file = await loadFile(state55.filePath);
|
|
22539
|
+
if (state55.file === null) {
|
|
22540
|
+
state55.file = {
|
|
22522
22541
|
version: FILE_VERSION,
|
|
22523
|
-
projectSlug:
|
|
22542
|
+
projectSlug: state55.projectSlug ?? "tracker",
|
|
22524
22543
|
updatedAt: nowIso(),
|
|
22525
22544
|
items: []
|
|
22526
22545
|
};
|
|
@@ -22544,7 +22563,7 @@ var plugin60 = {
|
|
|
22544
22563
|
permission: "auto",
|
|
22545
22564
|
mutating: false,
|
|
22546
22565
|
async execute(input) {
|
|
22547
|
-
if (
|
|
22566
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22548
22567
|
const status = input["status"] ?? "active";
|
|
22549
22568
|
const priority = input["priority"];
|
|
22550
22569
|
const tag = input["tag"];
|
|
@@ -22592,7 +22611,7 @@ var plugin60 = {
|
|
|
22592
22611
|
permission: "auto",
|
|
22593
22612
|
mutating: true,
|
|
22594
22613
|
async execute(input) {
|
|
22595
|
-
if (
|
|
22614
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22596
22615
|
const content = typeof input["content"] === "string" ? input["content"].trim() : "";
|
|
22597
22616
|
if (!content) {
|
|
22598
22617
|
return { ok: false, error: "content is required and must be a non-empty string" };
|
|
@@ -22617,7 +22636,7 @@ var plugin60 = {
|
|
|
22617
22636
|
const file = ensureFile();
|
|
22618
22637
|
file.items.push(item);
|
|
22619
22638
|
file.updatedAt = now;
|
|
22620
|
-
await saveFile(
|
|
22639
|
+
await saveFile(state55.filePath, file);
|
|
22621
22640
|
recordMutation("add", item.id);
|
|
22622
22641
|
api.log.info("todo-tracker: added item", { id: item.id, content });
|
|
22623
22642
|
try {
|
|
@@ -22647,7 +22666,7 @@ var plugin60 = {
|
|
|
22647
22666
|
permission: "auto",
|
|
22648
22667
|
mutating: true,
|
|
22649
22668
|
async execute(input) {
|
|
22650
|
-
if (
|
|
22669
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22651
22670
|
const id = typeof input["id"] === "string" ? input["id"] : "";
|
|
22652
22671
|
if (!id) return { ok: false, error: "id is required" };
|
|
22653
22672
|
const idx = findItemIndex(id);
|
|
@@ -22662,7 +22681,7 @@ var plugin60 = {
|
|
|
22662
22681
|
item.updatedAt = now;
|
|
22663
22682
|
item.completedAt = now;
|
|
22664
22683
|
file.updatedAt = now;
|
|
22665
|
-
await saveFile(
|
|
22684
|
+
await saveFile(state55.filePath, file);
|
|
22666
22685
|
recordMutation("complete", id);
|
|
22667
22686
|
api.log.info("todo-tracker: completed item", { id });
|
|
22668
22687
|
return { ok: true, item };
|
|
@@ -22681,7 +22700,7 @@ var plugin60 = {
|
|
|
22681
22700
|
permission: "auto",
|
|
22682
22701
|
mutating: true,
|
|
22683
22702
|
async execute(input) {
|
|
22684
|
-
if (
|
|
22703
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22685
22704
|
const id = typeof input["id"] === "string" ? input["id"] : "";
|
|
22686
22705
|
if (!id) return { ok: false, error: "id is required" };
|
|
22687
22706
|
const idx = findItemIndex(id);
|
|
@@ -22696,7 +22715,7 @@ var plugin60 = {
|
|
|
22696
22715
|
item.updatedAt = now;
|
|
22697
22716
|
item.completedAt = now;
|
|
22698
22717
|
file.updatedAt = now;
|
|
22699
|
-
await saveFile(
|
|
22718
|
+
await saveFile(state55.filePath, file);
|
|
22700
22719
|
recordMutation("drop", id);
|
|
22701
22720
|
return { ok: true, item };
|
|
22702
22721
|
}
|
|
@@ -22714,7 +22733,7 @@ var plugin60 = {
|
|
|
22714
22733
|
permission: "confirm",
|
|
22715
22734
|
mutating: true,
|
|
22716
22735
|
async execute(input) {
|
|
22717
|
-
if (
|
|
22736
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22718
22737
|
const id = typeof input["id"] === "string" ? input["id"] : "";
|
|
22719
22738
|
if (!id) return { ok: false, error: "id is required" };
|
|
22720
22739
|
const idx = findItemIndex(id);
|
|
@@ -22722,7 +22741,7 @@ var plugin60 = {
|
|
|
22722
22741
|
const file = ensureFile();
|
|
22723
22742
|
const [removed] = file.items.splice(idx, 1);
|
|
22724
22743
|
file.updatedAt = nowIso();
|
|
22725
|
-
await saveFile(
|
|
22744
|
+
await saveFile(state55.filePath, file);
|
|
22726
22745
|
recordMutation("remove", id);
|
|
22727
22746
|
return { ok: true, removed };
|
|
22728
22747
|
}
|
|
@@ -22739,7 +22758,7 @@ var plugin60 = {
|
|
|
22739
22758
|
permission: "auto",
|
|
22740
22759
|
mutating: false,
|
|
22741
22760
|
async execute(input) {
|
|
22742
|
-
if (
|
|
22761
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22743
22762
|
const limit = Math.min(Math.max(Number(input["limit"] ?? 50) || 50, 1), 200);
|
|
22744
22763
|
const file = ensureFile();
|
|
22745
22764
|
const items = file.items.filter((it) => it.status === "pending" || it.status === "in_progress").slice(0, limit);
|
|
@@ -22761,7 +22780,7 @@ var plugin60 = {
|
|
|
22761
22780
|
permission: "auto",
|
|
22762
22781
|
mutating: false,
|
|
22763
22782
|
async execute() {
|
|
22764
|
-
if (
|
|
22783
|
+
if (state55.filePath === null) return notConfiguredError();
|
|
22765
22784
|
const file = ensureFile();
|
|
22766
22785
|
const byStatus = {
|
|
22767
22786
|
pending: 0,
|
|
@@ -22772,49 +22791,49 @@ var plugin60 = {
|
|
|
22772
22791
|
for (const it of file.items) byStatus[it.status] += 1;
|
|
22773
22792
|
return {
|
|
22774
22793
|
ok: true,
|
|
22775
|
-
filePath:
|
|
22776
|
-
projectSlug:
|
|
22794
|
+
filePath: state55.filePath,
|
|
22795
|
+
projectSlug: state55.projectSlug,
|
|
22777
22796
|
updatedAt: file.updatedAt,
|
|
22778
22797
|
counters: byStatus,
|
|
22779
22798
|
total: file.items.length,
|
|
22780
22799
|
session: {
|
|
22781
|
-
add:
|
|
22782
|
-
complete:
|
|
22783
|
-
drop:
|
|
22784
|
-
remove:
|
|
22785
|
-
pull:
|
|
22800
|
+
add: state55.addCount,
|
|
22801
|
+
complete: state55.completeCount,
|
|
22802
|
+
drop: state55.dropCount,
|
|
22803
|
+
remove: state55.removeCount,
|
|
22804
|
+
pull: state55.pullCount
|
|
22786
22805
|
},
|
|
22787
|
-
lastMutation:
|
|
22806
|
+
lastMutation: state55.lastMutation
|
|
22788
22807
|
};
|
|
22789
22808
|
}
|
|
22790
22809
|
});
|
|
22791
22810
|
api.log.info("todo-tracker plugin loaded", {
|
|
22792
|
-
filePath:
|
|
22793
|
-
projectSlug:
|
|
22794
|
-
initialItemCount:
|
|
22811
|
+
filePath: state55.filePath,
|
|
22812
|
+
projectSlug: state55.projectSlug,
|
|
22813
|
+
initialItemCount: state55.file.items.length
|
|
22795
22814
|
});
|
|
22796
22815
|
},
|
|
22797
22816
|
teardown(api) {
|
|
22798
22817
|
const finalCounts = {
|
|
22799
|
-
add:
|
|
22800
|
-
complete:
|
|
22801
|
-
drop:
|
|
22802
|
-
remove:
|
|
22803
|
-
pull:
|
|
22818
|
+
add: state55.addCount,
|
|
22819
|
+
complete: state55.completeCount,
|
|
22820
|
+
drop: state55.dropCount,
|
|
22821
|
+
remove: state55.removeCount,
|
|
22822
|
+
pull: state55.pullCount
|
|
22804
22823
|
};
|
|
22805
|
-
|
|
22806
|
-
|
|
22807
|
-
|
|
22808
|
-
|
|
22809
|
-
|
|
22810
|
-
|
|
22811
|
-
|
|
22812
|
-
|
|
22813
|
-
|
|
22824
|
+
state55.addCount = 0;
|
|
22825
|
+
state55.completeCount = 0;
|
|
22826
|
+
state55.dropCount = 0;
|
|
22827
|
+
state55.removeCount = 0;
|
|
22828
|
+
state55.pullCount = 0;
|
|
22829
|
+
state55.lastMutation = null;
|
|
22830
|
+
state55.file = null;
|
|
22831
|
+
state55.filePath = null;
|
|
22832
|
+
state55.projectSlug = null;
|
|
22814
22833
|
api.log.info("todo-tracker: teardown complete", { sessionCounts: finalCounts });
|
|
22815
22834
|
},
|
|
22816
22835
|
async health() {
|
|
22817
|
-
if (
|
|
22836
|
+
if (state55.filePath === null) {
|
|
22818
22837
|
return {
|
|
22819
22838
|
ok: false,
|
|
22820
22839
|
message: "todo-tracker: no file path configured \u2014 tools will error"
|
|
@@ -22823,18 +22842,18 @@ var plugin60 = {
|
|
|
22823
22842
|
const file = ensureFile();
|
|
22824
22843
|
return {
|
|
22825
22844
|
ok: true,
|
|
22826
|
-
message: `todo-tracker: ${file.items.length} item(s) at ${
|
|
22827
|
-
filePath:
|
|
22828
|
-
projectSlug:
|
|
22845
|
+
message: `todo-tracker: ${file.items.length} item(s) at ${state55.filePath}`,
|
|
22846
|
+
filePath: state55.filePath,
|
|
22847
|
+
projectSlug: state55.projectSlug,
|
|
22829
22848
|
total: file.items.length,
|
|
22830
22849
|
sessionCounts: {
|
|
22831
|
-
add:
|
|
22832
|
-
complete:
|
|
22833
|
-
drop:
|
|
22834
|
-
remove:
|
|
22835
|
-
pull:
|
|
22850
|
+
add: state55.addCount,
|
|
22851
|
+
complete: state55.completeCount,
|
|
22852
|
+
drop: state55.dropCount,
|
|
22853
|
+
remove: state55.removeCount,
|
|
22854
|
+
pull: state55.pullCount
|
|
22836
22855
|
},
|
|
22837
|
-
lastMutation:
|
|
22856
|
+
lastMutation: state55.lastMutation
|
|
22838
22857
|
};
|
|
22839
22858
|
}
|
|
22840
22859
|
};
|
|
@@ -22842,7 +22861,7 @@ var todo_tracker_default = plugin60;
|
|
|
22842
22861
|
|
|
22843
22862
|
// src/token-budget/index.ts
|
|
22844
22863
|
var API_VERSION40 = "^0.1.10";
|
|
22845
|
-
var
|
|
22864
|
+
var state56 = {
|
|
22846
22865
|
totalTokens: 0,
|
|
22847
22866
|
totalPromptTokens: 0,
|
|
22848
22867
|
totalCompletionTokens: 0,
|
|
@@ -22897,13 +22916,13 @@ function readConfig53(raw) {
|
|
|
22897
22916
|
}
|
|
22898
22917
|
function clearRegistrations2() {
|
|
22899
22918
|
for (const key of ["hookUnregister", "postHookUnregister"]) {
|
|
22900
|
-
const off =
|
|
22919
|
+
const off = state56[key];
|
|
22901
22920
|
if (!off) continue;
|
|
22902
22921
|
try {
|
|
22903
22922
|
off();
|
|
22904
22923
|
} catch {
|
|
22905
22924
|
}
|
|
22906
|
-
|
|
22925
|
+
state56[key] = null;
|
|
22907
22926
|
}
|
|
22908
22927
|
}
|
|
22909
22928
|
var plugin61 = {
|
|
@@ -22944,15 +22963,15 @@ var plugin61 = {
|
|
|
22944
22963
|
}
|
|
22945
22964
|
},
|
|
22946
22965
|
setup(api) {
|
|
22947
|
-
|
|
22948
|
-
|
|
22949
|
-
|
|
22950
|
-
|
|
22951
|
-
|
|
22952
|
-
|
|
22953
|
-
|
|
22954
|
-
|
|
22955
|
-
|
|
22966
|
+
state56.totalTokens = 0;
|
|
22967
|
+
state56.totalPromptTokens = 0;
|
|
22968
|
+
state56.totalCompletionTokens = 0;
|
|
22969
|
+
state56.requestCount = 0;
|
|
22970
|
+
state56.warningFired = false;
|
|
22971
|
+
state56.stopFired = false;
|
|
22972
|
+
state56.warnContextInjected = false;
|
|
22973
|
+
state56.stopContextInjected = false;
|
|
22974
|
+
state56.lastRequest = null;
|
|
22956
22975
|
clearRegistrations2();
|
|
22957
22976
|
const cfg = readConfig53(api.config.extensions?.["token-budget"]);
|
|
22958
22977
|
api.onEvent("provider.response", (payload) => {
|
|
@@ -22966,21 +22985,21 @@ var plugin61 = {
|
|
|
22966
22985
|
const promptTokens = usage.input ?? 0;
|
|
22967
22986
|
const completionTokens = usage.output ?? 0;
|
|
22968
22987
|
const total = promptTokens + completionTokens;
|
|
22969
|
-
|
|
22970
|
-
|
|
22971
|
-
|
|
22972
|
-
|
|
22973
|
-
|
|
22988
|
+
state56.totalPromptTokens += promptTokens;
|
|
22989
|
+
state56.totalCompletionTokens += completionTokens;
|
|
22990
|
+
state56.totalTokens += total;
|
|
22991
|
+
state56.requestCount += 1;
|
|
22992
|
+
state56.lastRequest = {
|
|
22974
22993
|
model: p?.ctx?.model ?? "unknown",
|
|
22975
22994
|
prompt: promptTokens,
|
|
22976
22995
|
completion: completionTokens,
|
|
22977
22996
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
22978
22997
|
};
|
|
22979
22998
|
if (cfg.limit <= 0) return;
|
|
22980
|
-
const percent =
|
|
22981
|
-
if (!
|
|
22982
|
-
|
|
22983
|
-
const remaining = cfg.limit -
|
|
22999
|
+
const percent = state56.totalTokens / cfg.limit * 100;
|
|
23000
|
+
if (!state56.warningFired && percent >= cfg.warnPercent && percent < cfg.stopPercent) {
|
|
23001
|
+
state56.warningFired = true;
|
|
23002
|
+
const remaining = cfg.limit - state56.totalTokens;
|
|
22984
23003
|
api.log.info("token-budget: warning threshold reached", {
|
|
22985
23004
|
percent: Math.round(percent),
|
|
22986
23005
|
remaining
|
|
@@ -22988,45 +23007,45 @@ var plugin61 = {
|
|
|
22988
23007
|
api.emitCustom("token-budget:warning", {
|
|
22989
23008
|
percent: Math.round(percent),
|
|
22990
23009
|
remaining,
|
|
22991
|
-
total:
|
|
23010
|
+
total: state56.totalTokens,
|
|
22992
23011
|
limit: cfg.limit
|
|
22993
23012
|
});
|
|
22994
23013
|
}
|
|
22995
|
-
if (!
|
|
22996
|
-
|
|
23014
|
+
if (!state56.stopFired && percent >= cfg.stopPercent) {
|
|
23015
|
+
state56.stopFired = true;
|
|
22997
23016
|
api.log.warn("token-budget: hard limit reached \u2014 agent loop will be stopped", {
|
|
22998
|
-
total:
|
|
23017
|
+
total: state56.totalTokens,
|
|
22999
23018
|
limit: cfg.limit
|
|
23000
23019
|
});
|
|
23001
23020
|
api.emitCustom("token-budget:limit_reached", {
|
|
23002
|
-
total:
|
|
23021
|
+
total: state56.totalTokens,
|
|
23003
23022
|
limit: cfg.limit
|
|
23004
23023
|
});
|
|
23005
23024
|
}
|
|
23006
23025
|
});
|
|
23007
|
-
|
|
23008
|
-
if (cfg.limit <= 0 || !
|
|
23026
|
+
state56.hookUnregister = api.registerHook("Stop", void 0, () => {
|
|
23027
|
+
if (cfg.limit <= 0 || !state56.stopFired) return;
|
|
23009
23028
|
return {
|
|
23010
23029
|
decision: "block",
|
|
23011
|
-
reason: `token-budget: session token limit reached (${
|
|
23030
|
+
reason: `token-budget: session token limit reached (${state56.totalTokens.toLocaleString()} / ${cfg.limit.toLocaleString()} tokens). The budget is exhausted \u2014 wrap up the current task and summarize what was accomplished.`
|
|
23012
23031
|
};
|
|
23013
23032
|
});
|
|
23014
|
-
|
|
23033
|
+
state56.postHookUnregister = api.registerHook("PostToolUse", "*", () => {
|
|
23015
23034
|
if (cfg.limit <= 0) return;
|
|
23016
|
-
const percent = Math.round(
|
|
23017
|
-
const remaining = Math.max(cfg.limit -
|
|
23018
|
-
if (
|
|
23019
|
-
|
|
23035
|
+
const percent = Math.round(state56.totalTokens / cfg.limit * 100);
|
|
23036
|
+
const remaining = Math.max(cfg.limit - state56.totalTokens, 0);
|
|
23037
|
+
if (state56.stopFired && !state56.stopContextInjected) {
|
|
23038
|
+
state56.stopContextInjected = true;
|
|
23020
23039
|
return {
|
|
23021
23040
|
additionalContext: `
|
|
23022
|
-
\u{1F6D1} token-budget: HARD LIMIT REACHED \u2014 ${
|
|
23041
|
+
\u{1F6D1} token-budget: HARD LIMIT REACHED \u2014 ${state56.totalTokens.toLocaleString()} / ${cfg.limit.toLocaleString()} tokens (${percent}%). You must stop here. Do NOT start any new task. Summarize what was accomplished and list any remaining work.`
|
|
23023
23042
|
};
|
|
23024
23043
|
}
|
|
23025
|
-
if (
|
|
23026
|
-
|
|
23044
|
+
if (state56.warningFired && !state56.warnContextInjected) {
|
|
23045
|
+
state56.warnContextInjected = true;
|
|
23027
23046
|
return {
|
|
23028
23047
|
additionalContext: `
|
|
23029
|
-
\u26A0\uFE0F token-budget: ${percent}% of budget used (${
|
|
23048
|
+
\u26A0\uFE0F token-budget: ${percent}% of budget used (${state56.totalTokens.toLocaleString()} / ${cfg.limit.toLocaleString()} tokens, ${remaining.toLocaleString()} remaining). Start wrapping up \u2014 prioritize finishing the current task over starting new ones.`
|
|
23030
23049
|
};
|
|
23031
23050
|
}
|
|
23032
23051
|
return;
|
|
@@ -23039,7 +23058,7 @@ var plugin61 = {
|
|
|
23039
23058
|
category: "Meta",
|
|
23040
23059
|
mutating: false,
|
|
23041
23060
|
async execute() {
|
|
23042
|
-
const consumed =
|
|
23061
|
+
const consumed = state56.totalTokens;
|
|
23043
23062
|
const limit = cfg.limit;
|
|
23044
23063
|
const percent = limit > 0 ? Math.round(consumed / limit * 100) : 0;
|
|
23045
23064
|
const remaining = limit > 0 ? Math.max(limit - consumed, 0) : Infinity;
|
|
@@ -23049,7 +23068,7 @@ var plugin61 = {
|
|
|
23049
23068
|
consumed,
|
|
23050
23069
|
remaining,
|
|
23051
23070
|
percent,
|
|
23052
|
-
requestCount:
|
|
23071
|
+
requestCount: state56.requestCount,
|
|
23053
23072
|
// The EFFECTIVE thresholds, after out-of-range values fall back to
|
|
23054
23073
|
// the defaults and warn/stop are ordered. Without these the user
|
|
23055
23074
|
// cannot tell that a rejected or clamped setting is not in force.
|
|
@@ -23057,12 +23076,12 @@ var plugin61 = {
|
|
|
23057
23076
|
stopPercent: cfg.stopPercent,
|
|
23058
23077
|
model: cfg.model === "" ? null : cfg.model,
|
|
23059
23078
|
breakdown: {
|
|
23060
|
-
prompt:
|
|
23061
|
-
completion:
|
|
23079
|
+
prompt: state56.totalPromptTokens,
|
|
23080
|
+
completion: state56.totalCompletionTokens
|
|
23062
23081
|
},
|
|
23063
|
-
warningFired:
|
|
23064
|
-
stopFired:
|
|
23065
|
-
lastRequest:
|
|
23082
|
+
warningFired: state56.warningFired,
|
|
23083
|
+
stopFired: state56.stopFired,
|
|
23084
|
+
lastRequest: state56.lastRequest
|
|
23066
23085
|
};
|
|
23067
23086
|
}
|
|
23068
23087
|
});
|
|
@@ -23076,30 +23095,30 @@ var plugin61 = {
|
|
|
23076
23095
|
teardown(api) {
|
|
23077
23096
|
clearRegistrations2();
|
|
23078
23097
|
const final = {
|
|
23079
|
-
totalTokens:
|
|
23080
|
-
requestCount:
|
|
23081
|
-
warningFired:
|
|
23082
|
-
stopFired:
|
|
23098
|
+
totalTokens: state56.totalTokens,
|
|
23099
|
+
requestCount: state56.requestCount,
|
|
23100
|
+
warningFired: state56.warningFired,
|
|
23101
|
+
stopFired: state56.stopFired
|
|
23083
23102
|
};
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
23089
|
-
|
|
23090
|
-
|
|
23091
|
-
|
|
23092
|
-
|
|
23103
|
+
state56.totalTokens = 0;
|
|
23104
|
+
state56.totalPromptTokens = 0;
|
|
23105
|
+
state56.totalCompletionTokens = 0;
|
|
23106
|
+
state56.requestCount = 0;
|
|
23107
|
+
state56.warningFired = false;
|
|
23108
|
+
state56.stopFired = false;
|
|
23109
|
+
state56.warnContextInjected = false;
|
|
23110
|
+
state56.stopContextInjected = false;
|
|
23111
|
+
state56.lastRequest = null;
|
|
23093
23112
|
api.log.info("token-budget: teardown complete", { final });
|
|
23094
23113
|
},
|
|
23095
23114
|
async health() {
|
|
23096
23115
|
return {
|
|
23097
23116
|
ok: true,
|
|
23098
|
-
message:
|
|
23099
|
-
totalTokens:
|
|
23100
|
-
requestCount:
|
|
23101
|
-
warningFired:
|
|
23102
|
-
stopFired:
|
|
23117
|
+
message: state56.lastRequest === null ? `token-budget: ${state56.totalTokens.toLocaleString()} tokens across ${state56.requestCount} request(s)` : `token-budget: ${state56.totalTokens.toLocaleString()} tokens, last ${state56.lastRequest.model} at ${state56.lastRequest.when}`,
|
|
23118
|
+
totalTokens: state56.totalTokens,
|
|
23119
|
+
requestCount: state56.requestCount,
|
|
23120
|
+
warningFired: state56.warningFired,
|
|
23121
|
+
stopFired: state56.stopFired
|
|
23103
23122
|
};
|
|
23104
23123
|
}
|
|
23105
23124
|
};
|
|
@@ -23145,7 +23164,7 @@ function computeThrottleDelay(entries, now, limit, projected) {
|
|
|
23145
23164
|
const oldest = sorted[0];
|
|
23146
23165
|
return oldest ? Math.max(0, oldest.at + WINDOW_MS - now) : 0;
|
|
23147
23166
|
}
|
|
23148
|
-
var
|
|
23167
|
+
var state57 = {
|
|
23149
23168
|
window: [],
|
|
23150
23169
|
invocations: 0,
|
|
23151
23170
|
throttled: 0,
|
|
@@ -23218,16 +23237,16 @@ var plugin62 = {
|
|
|
23218
23237
|
}
|
|
23219
23238
|
},
|
|
23220
23239
|
setup(api) {
|
|
23221
|
-
|
|
23222
|
-
|
|
23223
|
-
|
|
23224
|
-
|
|
23225
|
-
if (
|
|
23240
|
+
state57.window = [];
|
|
23241
|
+
state57.invocations = 0;
|
|
23242
|
+
state57.throttled = 0;
|
|
23243
|
+
state57.totalDelayMs = 0;
|
|
23244
|
+
if (state57.extensionUnregister) {
|
|
23226
23245
|
try {
|
|
23227
|
-
|
|
23246
|
+
state57.extensionUnregister();
|
|
23228
23247
|
} catch {
|
|
23229
23248
|
}
|
|
23230
|
-
|
|
23249
|
+
state57.extensionUnregister = null;
|
|
23231
23250
|
}
|
|
23232
23251
|
const cfg = readConfig54(api.config.extensions?.["token-throttle"]);
|
|
23233
23252
|
if (cfg.enabled) {
|
|
@@ -23236,21 +23255,21 @@ var plugin62 = {
|
|
|
23236
23255
|
kind: "throttle",
|
|
23237
23256
|
wraps: ["request"]
|
|
23238
23257
|
});
|
|
23239
|
-
|
|
23258
|
+
state57.extensionUnregister = api.extensions.register({
|
|
23240
23259
|
name: "token-throttle",
|
|
23241
23260
|
owner: "token-throttle",
|
|
23242
23261
|
async wrapProviderRunner(_ctx, request, inner) {
|
|
23243
23262
|
const signal = _ctx?.signal;
|
|
23244
23263
|
const req = request ?? {};
|
|
23245
|
-
|
|
23264
|
+
state57.invocations += 1;
|
|
23246
23265
|
const now = Date.now();
|
|
23247
|
-
|
|
23266
|
+
state57.window = pruneWindow(state57.window, now);
|
|
23248
23267
|
const projected = estimateRequestTokens(req, cfg.charsPerToken);
|
|
23249
|
-
const rawDelay = computeThrottleDelay(
|
|
23268
|
+
const rawDelay = computeThrottleDelay(state57.window, now, cfg.tokensPerMinute, projected);
|
|
23250
23269
|
const delay = Math.min(rawDelay, cfg.maxDelayMs);
|
|
23251
23270
|
if (delay > 0) {
|
|
23252
|
-
|
|
23253
|
-
|
|
23271
|
+
state57.throttled += 1;
|
|
23272
|
+
state57.totalDelayMs += delay;
|
|
23254
23273
|
api.metrics.counter("throttled");
|
|
23255
23274
|
api.metrics.histogram("delay_ms", delay);
|
|
23256
23275
|
api.log.info("token-throttle: delaying provider call", { delayMs: delay, projected });
|
|
@@ -23258,7 +23277,7 @@ var plugin62 = {
|
|
|
23258
23277
|
}
|
|
23259
23278
|
const response = await inner(_ctx, request);
|
|
23260
23279
|
const used = (response?.usage?.input ?? 0) + (response?.usage?.output ?? 0) || projected;
|
|
23261
|
-
|
|
23280
|
+
state57.window.push({ at: Date.now(), tokens: used });
|
|
23262
23281
|
return response;
|
|
23263
23282
|
}
|
|
23264
23283
|
});
|
|
@@ -23272,7 +23291,7 @@ var plugin62 = {
|
|
|
23272
23291
|
mutating: false,
|
|
23273
23292
|
async execute() {
|
|
23274
23293
|
const now = Date.now();
|
|
23275
|
-
const live = pruneWindow(
|
|
23294
|
+
const live = pruneWindow(state57.window, now);
|
|
23276
23295
|
return {
|
|
23277
23296
|
ok: true,
|
|
23278
23297
|
enabled: cfg.enabled,
|
|
@@ -23281,9 +23300,9 @@ var plugin62 = {
|
|
|
23281
23300
|
windowSpend: windowSpend(live),
|
|
23282
23301
|
windowEntries: live.length,
|
|
23283
23302
|
counters: {
|
|
23284
|
-
invocations:
|
|
23285
|
-
throttled:
|
|
23286
|
-
totalDelayMs:
|
|
23303
|
+
invocations: state57.invocations,
|
|
23304
|
+
throttled: state57.throttled,
|
|
23305
|
+
totalDelayMs: state57.totalDelayMs
|
|
23287
23306
|
}
|
|
23288
23307
|
};
|
|
23289
23308
|
}
|
|
@@ -23295,32 +23314,32 @@ var plugin62 = {
|
|
|
23295
23314
|
});
|
|
23296
23315
|
},
|
|
23297
23316
|
teardown(api) {
|
|
23298
|
-
if (
|
|
23317
|
+
if (state57.extensionUnregister) {
|
|
23299
23318
|
try {
|
|
23300
|
-
|
|
23319
|
+
state57.extensionUnregister();
|
|
23301
23320
|
} catch {
|
|
23302
23321
|
}
|
|
23303
|
-
|
|
23322
|
+
state57.extensionUnregister = null;
|
|
23304
23323
|
}
|
|
23305
23324
|
const final = {
|
|
23306
|
-
invocations:
|
|
23307
|
-
throttled:
|
|
23308
|
-
totalDelayMs:
|
|
23325
|
+
invocations: state57.invocations,
|
|
23326
|
+
throttled: state57.throttled,
|
|
23327
|
+
totalDelayMs: state57.totalDelayMs
|
|
23309
23328
|
};
|
|
23310
|
-
|
|
23311
|
-
|
|
23312
|
-
|
|
23313
|
-
|
|
23329
|
+
state57.window = [];
|
|
23330
|
+
state57.invocations = 0;
|
|
23331
|
+
state57.throttled = 0;
|
|
23332
|
+
state57.totalDelayMs = 0;
|
|
23314
23333
|
api.log.info("token-throttle: teardown complete", { final });
|
|
23315
23334
|
},
|
|
23316
23335
|
async health() {
|
|
23317
23336
|
return {
|
|
23318
23337
|
ok: true,
|
|
23319
|
-
message: `token-throttle: ${
|
|
23338
|
+
message: `token-throttle: ${state57.throttled} throttle(s) of ${state57.invocations} call(s), ${state57.totalDelayMs}ms total delay`,
|
|
23320
23339
|
counters: {
|
|
23321
|
-
invocations:
|
|
23322
|
-
throttled:
|
|
23323
|
-
totalDelayMs:
|
|
23340
|
+
invocations: state57.invocations,
|
|
23341
|
+
throttled: state57.throttled,
|
|
23342
|
+
totalDelayMs: state57.totalDelayMs
|
|
23324
23343
|
}
|
|
23325
23344
|
};
|
|
23326
23345
|
}
|
|
@@ -23330,7 +23349,7 @@ var token_throttle_default = plugin62;
|
|
|
23330
23349
|
// src/type-gate/index.ts
|
|
23331
23350
|
import { existsSync as existsSync6 } from "node:fs";
|
|
23332
23351
|
var API_VERSION41 = "^0.1.10";
|
|
23333
|
-
var
|
|
23352
|
+
var state58 = {
|
|
23334
23353
|
invocationCount: 0,
|
|
23335
23354
|
runCount: 0,
|
|
23336
23355
|
passCount: 0,
|
|
@@ -23493,14 +23512,14 @@ var plugin63 = {
|
|
|
23493
23512
|
}
|
|
23494
23513
|
},
|
|
23495
23514
|
setup(api) {
|
|
23496
|
-
|
|
23497
|
-
|
|
23498
|
-
|
|
23499
|
-
|
|
23500
|
-
|
|
23501
|
-
|
|
23502
|
-
|
|
23503
|
-
|
|
23515
|
+
state58.invocationCount = 0;
|
|
23516
|
+
state58.runCount = 0;
|
|
23517
|
+
state58.passCount = 0;
|
|
23518
|
+
state58.failCount = 0;
|
|
23519
|
+
state58.errorCount = 0;
|
|
23520
|
+
state58.skippedCount = 0;
|
|
23521
|
+
state58.lastResult = null;
|
|
23522
|
+
state58.hookUnregister = releaseHandle(state58.hookUnregister);
|
|
23504
23523
|
const cfg = readConfig55(api.config.extensions?.["type-gate"]);
|
|
23505
23524
|
const hook = async (input) => {
|
|
23506
23525
|
if (!cfg.enabled) return;
|
|
@@ -23511,27 +23530,27 @@ var plugin63 = {
|
|
|
23511
23530
|
if (!withinProject(sourcePath)) return;
|
|
23512
23531
|
const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
|
|
23513
23532
|
if (!runOnChangeSet2.has(ext)) {
|
|
23514
|
-
|
|
23533
|
+
state58.skippedCount += 1;
|
|
23515
23534
|
return;
|
|
23516
23535
|
}
|
|
23517
|
-
|
|
23536
|
+
state58.invocationCount += 1;
|
|
23518
23537
|
const result = await runTypeCheck(cfg);
|
|
23519
23538
|
if (!result) {
|
|
23520
|
-
|
|
23539
|
+
state58.errorCount += 1;
|
|
23521
23540
|
return;
|
|
23522
23541
|
}
|
|
23523
|
-
|
|
23524
|
-
|
|
23542
|
+
state58.runCount += 1;
|
|
23543
|
+
state58.lastResult = {
|
|
23525
23544
|
passed: result.passed,
|
|
23526
23545
|
errorCount: result.errorCount,
|
|
23527
23546
|
durationMs: result.durationMs,
|
|
23528
23547
|
when: (/* @__PURE__ */ new Date()).toISOString()
|
|
23529
23548
|
};
|
|
23530
23549
|
if (result.passed) {
|
|
23531
|
-
|
|
23550
|
+
state58.passCount += 1;
|
|
23532
23551
|
return;
|
|
23533
23552
|
}
|
|
23534
|
-
|
|
23553
|
+
state58.failCount += 1;
|
|
23535
23554
|
const errorList = result.errors.map((e) => ` \u274C ${e}`).join("\n");
|
|
23536
23555
|
const message = `
|
|
23537
23556
|
\u274C type-gate: Type check failed after editing ${sourcePath} (${result.durationMs}ms).
|
|
@@ -23546,7 +23565,7 @@ Fix the type error(s) or adjust the change.`;
|
|
|
23546
23565
|
}
|
|
23547
23566
|
return { additionalContext: message };
|
|
23548
23567
|
};
|
|
23549
|
-
|
|
23568
|
+
state58.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, { background: true });
|
|
23550
23569
|
api.tools.register({
|
|
23551
23570
|
name: "type_gate_status",
|
|
23552
23571
|
description: "Reports type-gate state: command, tsconfig, severity, and per-session pass/fail/error counters.",
|
|
@@ -23564,14 +23583,14 @@ Fix the type error(s) or adjust the change.`;
|
|
|
23564
23583
|
maxErrors: cfg.maxErrors,
|
|
23565
23584
|
runOnChange: cfg.runOnChange,
|
|
23566
23585
|
counters: {
|
|
23567
|
-
invocations:
|
|
23568
|
-
runs:
|
|
23569
|
-
passed:
|
|
23570
|
-
failed:
|
|
23571
|
-
errors:
|
|
23572
|
-
skipped:
|
|
23586
|
+
invocations: state58.invocationCount,
|
|
23587
|
+
runs: state58.runCount,
|
|
23588
|
+
passed: state58.passCount,
|
|
23589
|
+
failed: state58.failCount,
|
|
23590
|
+
errors: state58.errorCount,
|
|
23591
|
+
skipped: state58.skippedCount
|
|
23573
23592
|
},
|
|
23574
|
-
lastResult:
|
|
23593
|
+
lastResult: state58.lastResult
|
|
23575
23594
|
};
|
|
23576
23595
|
}
|
|
23577
23596
|
});
|
|
@@ -23583,43 +23602,43 @@ Fix the type error(s) or adjust the change.`;
|
|
|
23583
23602
|
});
|
|
23584
23603
|
},
|
|
23585
23604
|
teardown(api) {
|
|
23586
|
-
if (
|
|
23605
|
+
if (state58.hookUnregister) {
|
|
23587
23606
|
try {
|
|
23588
|
-
|
|
23607
|
+
state58.hookUnregister();
|
|
23589
23608
|
} catch {
|
|
23590
23609
|
}
|
|
23591
|
-
|
|
23610
|
+
state58.hookUnregister = null;
|
|
23592
23611
|
}
|
|
23593
23612
|
const final = {
|
|
23594
|
-
invocations:
|
|
23595
|
-
runs:
|
|
23596
|
-
passed:
|
|
23597
|
-
failed:
|
|
23598
|
-
errors:
|
|
23599
|
-
skipped:
|
|
23613
|
+
invocations: state58.invocationCount,
|
|
23614
|
+
runs: state58.runCount,
|
|
23615
|
+
passed: state58.passCount,
|
|
23616
|
+
failed: state58.failCount,
|
|
23617
|
+
errors: state58.errorCount,
|
|
23618
|
+
skipped: state58.skippedCount
|
|
23600
23619
|
};
|
|
23601
|
-
|
|
23602
|
-
|
|
23603
|
-
|
|
23604
|
-
|
|
23605
|
-
|
|
23606
|
-
|
|
23607
|
-
|
|
23620
|
+
state58.invocationCount = 0;
|
|
23621
|
+
state58.runCount = 0;
|
|
23622
|
+
state58.passCount = 0;
|
|
23623
|
+
state58.failCount = 0;
|
|
23624
|
+
state58.errorCount = 0;
|
|
23625
|
+
state58.skippedCount = 0;
|
|
23626
|
+
state58.lastResult = null;
|
|
23608
23627
|
api.log.info("type-gate: teardown complete", { final });
|
|
23609
23628
|
},
|
|
23610
23629
|
async health() {
|
|
23611
23630
|
return {
|
|
23612
23631
|
ok: true,
|
|
23613
|
-
message:
|
|
23632
|
+
message: state58.lastResult ? `type-gate: ${state58.runCount} run(s), last ${state58.lastResult.passed ? "PASSED" : "FAILED"} (${state58.lastResult.errorCount} errors)` : `type-gate: ${state58.invocationCount} invocation(s), ${state58.runCount} run(s)`,
|
|
23614
23633
|
counters: {
|
|
23615
|
-
invocations:
|
|
23616
|
-
runs:
|
|
23617
|
-
passed:
|
|
23618
|
-
failed:
|
|
23619
|
-
errors:
|
|
23620
|
-
skipped:
|
|
23621
|
-
},
|
|
23622
|
-
lastResult:
|
|
23634
|
+
invocations: state58.invocationCount,
|
|
23635
|
+
runs: state58.runCount,
|
|
23636
|
+
passed: state58.passCount,
|
|
23637
|
+
failed: state58.failCount,
|
|
23638
|
+
errors: state58.errorCount,
|
|
23639
|
+
skipped: state58.skippedCount
|
|
23640
|
+
},
|
|
23641
|
+
lastResult: state58.lastResult
|
|
23623
23642
|
};
|
|
23624
23643
|
}
|
|
23625
23644
|
};
|