nexus-agents 2.125.41 → 2.127.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/{chunk-6KQI4SJT.js → chunk-JE6K7PD6.js} +3 -3
- package/dist/{chunk-GWUMFIQP.js → chunk-M5QEWTVL.js} +360 -22
- package/dist/chunk-M5QEWTVL.js.map +1 -0
- package/dist/{chunk-323AIMTE.js → chunk-QPVEGYBW.js} +3 -3
- package/dist/{chunk-323AIMTE.js.map → chunk-QPVEGYBW.js.map} +1 -1
- package/dist/{chunk-UDIJ4XFZ.js → chunk-YJVTQZ2W.js} +2 -2
- package/dist/cli.d.ts +6 -1
- package/dist/cli.js +302 -43
- package/dist/cli.js.map +1 -1
- package/dist/{dist-NGFMLKZR.js → dist-QZLOLGIK.js} +1730 -1508
- package/dist/dist-QZLOLGIK.js.map +1 -0
- package/dist/{improvement-review-EQPHDV74.js → improvement-review-H4FDQV43.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{setup-command-U7RCPXX2.js → setup-command-DF6QJRUU.js} +3 -3
- package/package.json +7 -7
- package/dist/chunk-GWUMFIQP.js.map +0 -1
- package/dist/dist-NGFMLKZR.js.map +0 -1
- /package/dist/{chunk-6KQI4SJT.js.map → chunk-JE6K7PD6.js.map} +0 -0
- /package/dist/{chunk-UDIJ4XFZ.js.map → chunk-YJVTQZ2W.js.map} +0 -0
- /package/dist/{improvement-review-EQPHDV74.js.map → improvement-review-H4FDQV43.js.map} +0 -0
- /package/dist/{setup-command-U7RCPXX2.js.map → setup-command-DF6QJRUU.js.map} +0 -0
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
} from "./chunk-PI4RZNLE.js";
|
|
48
48
|
import {
|
|
49
49
|
withPrerequisite
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-M5QEWTVL.js";
|
|
51
51
|
import {
|
|
52
52
|
NOOP_NOTIFIER,
|
|
53
53
|
RateLimiter,
|
|
@@ -122,7 +122,7 @@ import {
|
|
|
122
122
|
DEFAULT_TASK_TTL_MS,
|
|
123
123
|
DEFAULT_TOOL_RATE_LIMITS,
|
|
124
124
|
clampTaskTtl
|
|
125
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-QPVEGYBW.js";
|
|
126
126
|
import {
|
|
127
127
|
resolveInsideRoot
|
|
128
128
|
} from "./chunk-NUBSJGQZ.js";
|
|
@@ -50477,4 +50477,4 @@ export {
|
|
|
50477
50477
|
shutdownFeedbackSubscriber,
|
|
50478
50478
|
createEventBusBridge
|
|
50479
50479
|
};
|
|
50480
|
-
//# sourceMappingURL=chunk-
|
|
50480
|
+
//# sourceMappingURL=chunk-JE6K7PD6.js.map
|
|
@@ -18,14 +18,15 @@ import {
|
|
|
18
18
|
getTimeProvider
|
|
19
19
|
} from "./chunk-QT3VRHNP.js";
|
|
20
20
|
import {
|
|
21
|
-
getNexusDataDir
|
|
21
|
+
getNexusDataDir,
|
|
22
|
+
nexusDataPath
|
|
22
23
|
} from "./chunk-ZGLIHPGJ.js";
|
|
23
24
|
|
|
24
25
|
// src/mcp/tools/improvement-review.ts
|
|
25
26
|
import { execFile as execFile2 } from "child_process";
|
|
26
27
|
import { readFile } from "fs/promises";
|
|
27
28
|
import { promisify as promisify2 } from "util";
|
|
28
|
-
import { z } from "zod";
|
|
29
|
+
import { z as z2 } from "zod";
|
|
29
30
|
|
|
30
31
|
// src/mcp/middleware/tool-prerequisites.ts
|
|
31
32
|
import { execFile } from "child_process";
|
|
@@ -741,6 +742,163 @@ function improvementSignalsToTasks(signals, existingTaskIds) {
|
|
|
741
742
|
return tasks;
|
|
742
743
|
}
|
|
743
744
|
|
|
745
|
+
// src/mcp/tools/improvement-remediation-shadow.ts
|
|
746
|
+
import { z } from "zod";
|
|
747
|
+
|
|
748
|
+
// src/config/jsonl-store.ts
|
|
749
|
+
import { appendFileSync, existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
750
|
+
import { dirname as dirname2 } from "path";
|
|
751
|
+
var DIR_MODE = 448;
|
|
752
|
+
var JsonlStore = class {
|
|
753
|
+
filePath;
|
|
754
|
+
schema;
|
|
755
|
+
maxRecords;
|
|
756
|
+
logger;
|
|
757
|
+
records = [];
|
|
758
|
+
constructor(config) {
|
|
759
|
+
this.filePath = config.filePath;
|
|
760
|
+
this.schema = config.schema;
|
|
761
|
+
this.maxRecords = Math.max(1, config.maxRecords);
|
|
762
|
+
this.logger = config.logger ?? createLogger({ component: config.component ?? "JsonlStore" });
|
|
763
|
+
this.ensureDir();
|
|
764
|
+
this.hydrate();
|
|
765
|
+
}
|
|
766
|
+
/** Append one record durably. Validates at the boundary; never throws. */
|
|
767
|
+
append(record) {
|
|
768
|
+
const result = this.schema.safeParse(record);
|
|
769
|
+
if (!result.success) {
|
|
770
|
+
this.logger.warn("Refusing to persist invalid JSONL record", {
|
|
771
|
+
path: this.filePath,
|
|
772
|
+
issues: result.error.issues.map((i) => i.message).join("; ")
|
|
773
|
+
});
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
this.records.push(result.data);
|
|
777
|
+
if (this.records.length > this.maxRecords) {
|
|
778
|
+
this.records.splice(0, this.records.length - this.maxRecords);
|
|
779
|
+
this.rewriteFile();
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
this.persistLine(result.data);
|
|
783
|
+
}
|
|
784
|
+
/** All retained records, oldest first. */
|
|
785
|
+
all() {
|
|
786
|
+
return this.records;
|
|
787
|
+
}
|
|
788
|
+
/** Number of retained records. */
|
|
789
|
+
count() {
|
|
790
|
+
return this.records.length;
|
|
791
|
+
}
|
|
792
|
+
// ==========================================================================
|
|
793
|
+
// Private
|
|
794
|
+
// ==========================================================================
|
|
795
|
+
ensureDir() {
|
|
796
|
+
try {
|
|
797
|
+
mkdirSync(dirname2(this.filePath), { recursive: true, mode: DIR_MODE });
|
|
798
|
+
} catch (error) {
|
|
799
|
+
this.logger.warn("Failed to create JSONL store directory", {
|
|
800
|
+
error: getErrorMessage(error),
|
|
801
|
+
path: this.filePath
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
hydrate() {
|
|
806
|
+
if (!existsSync2(this.filePath)) {
|
|
807
|
+
this.logger.debug("No JSONL file found, starting fresh", { path: this.filePath });
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
let loaded = 0;
|
|
811
|
+
let skipped = 0;
|
|
812
|
+
try {
|
|
813
|
+
const content = readFileSync2(this.filePath, "utf-8");
|
|
814
|
+
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
815
|
+
for (const line of lines) {
|
|
816
|
+
try {
|
|
817
|
+
const parsed = JSON.parse(line);
|
|
818
|
+
const result = this.schema.safeParse(parsed);
|
|
819
|
+
if (result.success) {
|
|
820
|
+
this.records.push(result.data);
|
|
821
|
+
loaded++;
|
|
822
|
+
} else {
|
|
823
|
+
skipped++;
|
|
824
|
+
}
|
|
825
|
+
} catch {
|
|
826
|
+
skipped++;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
} catch (error) {
|
|
830
|
+
this.logger.warn("Failed to hydrate JSONL store from disk", {
|
|
831
|
+
error: getErrorMessage(error),
|
|
832
|
+
path: this.filePath
|
|
833
|
+
});
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
if (this.records.length > this.maxRecords) {
|
|
837
|
+
this.records.splice(0, this.records.length - this.maxRecords);
|
|
838
|
+
this.rewriteFile();
|
|
839
|
+
}
|
|
840
|
+
this.logger.debug("Hydrated JSONL store from disk", {
|
|
841
|
+
loaded,
|
|
842
|
+
skipped,
|
|
843
|
+
retained: this.records.length,
|
|
844
|
+
path: this.filePath
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
persistLine(record) {
|
|
848
|
+
try {
|
|
849
|
+
appendFileSync(this.filePath, JSON.stringify(record) + "\n", "utf-8");
|
|
850
|
+
} catch (error) {
|
|
851
|
+
this.logger.warn("Failed to append JSONL record to disk", {
|
|
852
|
+
error: getErrorMessage(error),
|
|
853
|
+
path: this.filePath
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
rewriteFile() {
|
|
858
|
+
try {
|
|
859
|
+
const content = this.records.map((r) => JSON.stringify(r)).join("\n") + "\n";
|
|
860
|
+
writeFileSync(this.filePath, content, "utf-8");
|
|
861
|
+
} catch (error) {
|
|
862
|
+
this.logger.warn("Failed to rewrite JSONL store file", {
|
|
863
|
+
error: getErrorMessage(error),
|
|
864
|
+
path: this.filePath
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
// src/mcp/tools/diff-secret-scan.ts
|
|
871
|
+
var SECRET_PATTERNS = [
|
|
872
|
+
{ name: "private-key-block", re: /-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----/ },
|
|
873
|
+
{ name: "aws-access-key-id", re: /\bAKIA[0-9A-Z]{16}\b/ },
|
|
874
|
+
{ name: "github-token", re: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/ },
|
|
875
|
+
{ name: "slack-token", re: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/ },
|
|
876
|
+
{ name: "google-api-key", re: /\bAIza[0-9A-Za-z_-]{35}\b/ },
|
|
877
|
+
{ name: "openai-key", re: /\bsk-[A-Za-z0-9]{32,}\b/ },
|
|
878
|
+
{ name: "anthropic-key", re: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/ },
|
|
879
|
+
{ name: "jwt", re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/ },
|
|
880
|
+
// Generic `secret/token/password/api_key = "long-value"` assignments.
|
|
881
|
+
{
|
|
882
|
+
name: "generic-credential-assignment",
|
|
883
|
+
re: /(?:api[_-]?key|secret|token|password|passwd|credential)\s*[:=]\s*["'][A-Za-z0-9/+_-]{16,}["']/i
|
|
884
|
+
}
|
|
885
|
+
];
|
|
886
|
+
function scanForSecrets(text) {
|
|
887
|
+
const findings = [];
|
|
888
|
+
const lines = text.split("\n");
|
|
889
|
+
for (let i = 0; i < lines.length; i++) {
|
|
890
|
+
const line = lines[i] ?? "";
|
|
891
|
+
for (const { name, re } of SECRET_PATTERNS) {
|
|
892
|
+
if (re.test(line)) findings.push({ pattern: name, line: i + 1 });
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return { clean: findings.length === 0, findings };
|
|
896
|
+
}
|
|
897
|
+
function describeSecretFindings(result) {
|
|
898
|
+
if (result.clean) return "no secrets detected";
|
|
899
|
+
return result.findings.map((f) => `${f.pattern}@L${String(f.line)}`).join(", ");
|
|
900
|
+
}
|
|
901
|
+
|
|
744
902
|
// src/mcp/tools/improvement-remediation-shadow.ts
|
|
745
903
|
function isSecuritySignal(signal) {
|
|
746
904
|
if (signal.category === "security") return true;
|
|
@@ -787,6 +945,180 @@ function recordRemediationShadow(signals, sink = getRemediationShadowSink()) {
|
|
|
787
945
|
for (const record of records) sink.record(record);
|
|
788
946
|
return records;
|
|
789
947
|
}
|
|
948
|
+
var SoakVoteOutcomeSchema = z.object({
|
|
949
|
+
approved: z.boolean(),
|
|
950
|
+
/** Approval percentage at vote time, 0–100 (the consensus tally). */
|
|
951
|
+
approvalPercentage: z.number()
|
|
952
|
+
});
|
|
953
|
+
var RemediationSoakRecordSchema = z.object({
|
|
954
|
+
/** ISO-8601 capture time. */
|
|
955
|
+
timestamp: z.string(),
|
|
956
|
+
/** The improvement signal's stable key. */
|
|
957
|
+
signalKey: z.string(),
|
|
958
|
+
/** The signal's category. */
|
|
959
|
+
category: z.string(),
|
|
960
|
+
/** The classified remediation priority (p0–p4). */
|
|
961
|
+
priority: z.string(),
|
|
962
|
+
/** The signal's declared severity. */
|
|
963
|
+
severity: z.string(),
|
|
964
|
+
/** Vote outcome (approved/rejected + tally), undefined if the signal never reached a vote. */
|
|
965
|
+
voteOutcome: SoakVoteOutcomeSchema.optional(),
|
|
966
|
+
/** Number of plan steps research produced (0 if research/plan failed). */
|
|
967
|
+
planStepCount: z.number(),
|
|
968
|
+
/** p0 dry-run result detail (scrubbed); undefined for non-p0 or when no dry-run ran. */
|
|
969
|
+
dryRunResult: z.string().optional(),
|
|
970
|
+
/** Human-readable verdict reason (scrubbed). */
|
|
971
|
+
reason: z.string()
|
|
972
|
+
});
|
|
973
|
+
var SOAK_MAX_RECORDS = 1e4;
|
|
974
|
+
function getRemediationSoakFile() {
|
|
975
|
+
return nexusDataPath("learning", "remediation-soak.jsonl");
|
|
976
|
+
}
|
|
977
|
+
function scrubSoakRecord(record) {
|
|
978
|
+
const scrub = (text) => {
|
|
979
|
+
const result = scanForSecrets(text);
|
|
980
|
+
if (result.clean) return text;
|
|
981
|
+
return `[redacted: ${describeSecretFindings(result)}]`;
|
|
982
|
+
};
|
|
983
|
+
const scrubbed = {
|
|
984
|
+
...record,
|
|
985
|
+
reason: scrub(record.reason),
|
|
986
|
+
...record.dryRunResult !== void 0 ? { dryRunResult: scrub(record.dryRunResult) } : {}
|
|
987
|
+
};
|
|
988
|
+
return scrubbed;
|
|
989
|
+
}
|
|
990
|
+
function createRemediationSoakSink(filePath = getRemediationSoakFile(), maxRecords = SOAK_MAX_RECORDS) {
|
|
991
|
+
const store = new JsonlStore({
|
|
992
|
+
filePath,
|
|
993
|
+
schema: RemediationSoakRecordSchema,
|
|
994
|
+
maxRecords,
|
|
995
|
+
component: "RemediationSoakSink"
|
|
996
|
+
});
|
|
997
|
+
return {
|
|
998
|
+
record(record) {
|
|
999
|
+
store.append(scrubSoakRecord(record));
|
|
1000
|
+
},
|
|
1001
|
+
getRecords() {
|
|
1002
|
+
return store.all();
|
|
1003
|
+
}
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
var soakSingleton;
|
|
1007
|
+
function getRemediationSoakSink() {
|
|
1008
|
+
soakSingleton ??= createRemediationSoakSink();
|
|
1009
|
+
return soakSingleton;
|
|
1010
|
+
}
|
|
1011
|
+
function tallySoakRecord(t, r) {
|
|
1012
|
+
t.byCategory[r.category] = (t.byCategory[r.category] ?? 0) + 1;
|
|
1013
|
+
t.byPriority[r.priority] = (t.byPriority[r.priority] ?? 0) + 1;
|
|
1014
|
+
if (r.voteOutcome !== void 0) {
|
|
1015
|
+
t.voted++;
|
|
1016
|
+
if (r.voteOutcome.approved) t.approved++;
|
|
1017
|
+
}
|
|
1018
|
+
if (r.dryRunResult !== void 0) t.dryRunsCaptured++;
|
|
1019
|
+
}
|
|
1020
|
+
function summarizeRemediationSoak(records) {
|
|
1021
|
+
const t = {
|
|
1022
|
+
byCategory: {},
|
|
1023
|
+
byPriority: {},
|
|
1024
|
+
voted: 0,
|
|
1025
|
+
approved: 0,
|
|
1026
|
+
dryRunsCaptured: 0
|
|
1027
|
+
};
|
|
1028
|
+
for (const r of records) tallySoakRecord(t, r);
|
|
1029
|
+
const first = records[0]?.timestamp;
|
|
1030
|
+
const last = records[records.length - 1]?.timestamp;
|
|
1031
|
+
return {
|
|
1032
|
+
total: records.length,
|
|
1033
|
+
voted: t.voted,
|
|
1034
|
+
approved: t.approved,
|
|
1035
|
+
rejected: t.voted - t.approved,
|
|
1036
|
+
approvalRate: t.voted === 0 ? 0 : t.approved / t.voted,
|
|
1037
|
+
dryRunsCaptured: t.dryRunsCaptured,
|
|
1038
|
+
byCategory: t.byCategory,
|
|
1039
|
+
byPriority: t.byPriority,
|
|
1040
|
+
...first !== void 0 ? { firstTimestamp: first } : {},
|
|
1041
|
+
...last !== void 0 ? { lastTimestamp: last } : {}
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
function readRemediationSoakSummary(sink = getRemediationSoakSink()) {
|
|
1045
|
+
return summarizeRemediationSoak(sink.getRecords());
|
|
1046
|
+
}
|
|
1047
|
+
function parseVoteDetail(detail) {
|
|
1048
|
+
const approved = /\bapproved\b/.test(detail);
|
|
1049
|
+
const rejected = /\brejected\b/.test(detail);
|
|
1050
|
+
if (!approved && !rejected) return void 0;
|
|
1051
|
+
const pct = /(\d+(?:\.\d+)?)%/.exec(detail);
|
|
1052
|
+
return {
|
|
1053
|
+
approved,
|
|
1054
|
+
approvalPercentage: pct?.[1] !== void 0 ? Number(pct[1]) : approved ? 100 : 0
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
var SOAK_TERMINAL_REASON_STEPS = /* @__PURE__ */ new Set([
|
|
1058
|
+
"skip",
|
|
1059
|
+
"research-failed",
|
|
1060
|
+
"protected-path"
|
|
1061
|
+
]);
|
|
1062
|
+
function applySoakEvent(d, event) {
|
|
1063
|
+
if (event.step === "plan") {
|
|
1064
|
+
const n = /(\d+)\s*steps?/.exec(event.detail);
|
|
1065
|
+
d.planStepCount = n?.[1] !== void 0 ? Number(n[1]) : 0;
|
|
1066
|
+
if (d.reason === "") d.reason = "plan produced";
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
if (event.step === "vote") {
|
|
1070
|
+
const outcome = parseVoteDetail(event.detail);
|
|
1071
|
+
if (outcome !== void 0) d.voteOutcome = outcome;
|
|
1072
|
+
d.reason = event.detail;
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
if (event.step === "dry-run") {
|
|
1076
|
+
d.dryRunResult = event.detail;
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (SOAK_TERMINAL_REASON_STEPS.has(event.step)) d.reason = event.detail;
|
|
1080
|
+
}
|
|
1081
|
+
function draftToSoakRecord(d, meta, timestamp) {
|
|
1082
|
+
return {
|
|
1083
|
+
timestamp,
|
|
1084
|
+
signalKey: d.signalKey,
|
|
1085
|
+
category: meta?.category ?? "unknown",
|
|
1086
|
+
priority: meta?.priority ?? "unknown",
|
|
1087
|
+
severity: meta?.severity ?? "unknown",
|
|
1088
|
+
...d.voteOutcome !== void 0 ? { voteOutcome: d.voteOutcome } : {},
|
|
1089
|
+
planStepCount: d.planStepCount,
|
|
1090
|
+
...d.dryRunResult !== void 0 ? { dryRunResult: d.dryRunResult } : {},
|
|
1091
|
+
reason: d.reason === "" ? "no verdict recorded" : d.reason
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
function createRemediationSoakCollector(metaFor, sink = getRemediationSoakSink()) {
|
|
1095
|
+
const drafts = /* @__PURE__ */ new Map();
|
|
1096
|
+
const draftFor = (signalKey) => {
|
|
1097
|
+
let d = drafts.get(signalKey);
|
|
1098
|
+
if (d === void 0) {
|
|
1099
|
+
d = { signalKey, planStepCount: 0, reason: "" };
|
|
1100
|
+
drafts.set(signalKey, d);
|
|
1101
|
+
}
|
|
1102
|
+
return d;
|
|
1103
|
+
};
|
|
1104
|
+
return {
|
|
1105
|
+
observe(event) {
|
|
1106
|
+
if (event.signalKey === void 0) return;
|
|
1107
|
+
applySoakEvent(draftFor(event.signalKey), event);
|
|
1108
|
+
},
|
|
1109
|
+
flush() {
|
|
1110
|
+
const ts = new Date(getTimeProvider().now()).toISOString();
|
|
1111
|
+
const out = [];
|
|
1112
|
+
for (const d of drafts.values()) {
|
|
1113
|
+
const record = draftToSoakRecord(d, metaFor(d.signalKey), ts);
|
|
1114
|
+
sink.record(record);
|
|
1115
|
+
out.push(record);
|
|
1116
|
+
}
|
|
1117
|
+
drafts.clear();
|
|
1118
|
+
return out;
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
790
1122
|
|
|
791
1123
|
// src/mcp/tools/remediation-priority.ts
|
|
792
1124
|
function priorityLabel(priority) {
|
|
@@ -816,14 +1148,14 @@ function classifySignalPriority(signal) {
|
|
|
816
1148
|
|
|
817
1149
|
// src/mcp/tools/improvement-review.ts
|
|
818
1150
|
var execFileAsync2 = promisify2(execFile2);
|
|
819
|
-
var ImprovementReviewInputSchema =
|
|
820
|
-
lookbackDays:
|
|
821
|
-
fileIssues:
|
|
1151
|
+
var ImprovementReviewInputSchema = z2.object({
|
|
1152
|
+
lookbackDays: z2.number().int().min(1).max(90).optional().default(7).describe("Lookback window for outcome data, in days. Default 7."),
|
|
1153
|
+
fileIssues: z2.boolean().optional().default(false).describe(
|
|
822
1154
|
"When true, file candidate issues via `gh issue create` for crossed thresholds (rate-limited to 5 per run, deduped against open issues). When false (default), return signals only."
|
|
823
1155
|
),
|
|
824
|
-
minSampleSize:
|
|
825
|
-
fitnessFloor:
|
|
826
|
-
selfEvalReportPath:
|
|
1156
|
+
minSampleSize: z2.number().int().min(1).max(1e3).optional().default(5).describe("Minimum sample size before a CLI/category signal can fire."),
|
|
1157
|
+
fitnessFloor: z2.number().int().min(0).max(100).optional().default(90).describe("Fitness score below this threshold triggers a tech-debt signal."),
|
|
1158
|
+
selfEvalReportPath: z2.string().optional().describe(
|
|
827
1159
|
"Optional path to a self-eval JSON report (from `self-eval --json`). When set, high-confidence unanimous deprecate/refactor findings are surfaced as tech-debt signals through the same deduped/rate-limited issue path (#3224). Unreadable/malformed reports are skipped (no signal). Absent \u2192 no self-eval signals."
|
|
828
1160
|
)
|
|
829
1161
|
});
|
|
@@ -1021,14 +1353,14 @@ function detectFitnessSignals(audit, fitnessFloor) {
|
|
|
1021
1353
|
return signals;
|
|
1022
1354
|
}
|
|
1023
1355
|
var SELF_EVAL_CONFIDENCE_FLOOR = 0.8;
|
|
1024
|
-
var SelfEvalReportSchema =
|
|
1025
|
-
results:
|
|
1026
|
-
|
|
1027
|
-
component:
|
|
1028
|
-
finalRecommendation:
|
|
1029
|
-
confidence:
|
|
1030
|
-
dissent:
|
|
1031
|
-
evidenceQuality:
|
|
1356
|
+
var SelfEvalReportSchema = z2.object({
|
|
1357
|
+
results: z2.array(
|
|
1358
|
+
z2.object({
|
|
1359
|
+
component: z2.string(),
|
|
1360
|
+
finalRecommendation: z2.string(),
|
|
1361
|
+
confidence: z2.number(),
|
|
1362
|
+
dissent: z2.array(z2.unknown()).optional().default([]),
|
|
1363
|
+
evidenceQuality: z2.number().optional()
|
|
1032
1364
|
})
|
|
1033
1365
|
)
|
|
1034
1366
|
});
|
|
@@ -1243,13 +1575,13 @@ async function reviewHandler(args, ctx) {
|
|
|
1243
1575
|
}
|
|
1244
1576
|
var description = "Periodic threshold-gated observability-driven improvement loop. Reads OutcomeStore + fitness audit, surfaces patterns crossing documented thresholds as candidate findings. When fileIssues=true, files candidate GitHub issues via `gh issue create` (rate-limited to 5 per run, deduped against open issues). Never auto-merges. Replaces the deleted self-development engine (#2402).";
|
|
1245
1577
|
var TOOL_INPUT_SCHEMA = {
|
|
1246
|
-
lookbackDays:
|
|
1247
|
-
fileIssues:
|
|
1578
|
+
lookbackDays: z2.number().int().min(1).max(90).optional().describe("Lookback window for outcome data, in days. Default 7."),
|
|
1579
|
+
fileIssues: z2.boolean().optional().describe(
|
|
1248
1580
|
"When true, file candidate issues for crossed thresholds (default false \u2014 return signals only)"
|
|
1249
1581
|
),
|
|
1250
|
-
minSampleSize:
|
|
1251
|
-
fitnessFloor:
|
|
1252
|
-
selfEvalReportPath:
|
|
1582
|
+
minSampleSize: z2.number().int().min(1).max(1e3).optional().describe("Minimum sample size before a CLI/category signal fires (default 5)."),
|
|
1583
|
+
fitnessFloor: z2.number().int().min(0).max(100).optional().describe("Fitness score below this threshold triggers a tech-debt signal (default 90)."),
|
|
1584
|
+
selfEvalReportPath: z2.string().optional().describe(
|
|
1253
1585
|
"Optional path to a self-eval JSON report. High-confidence unanimous deprecate/refactor findings surface as tech-debt signals (#3224)."
|
|
1254
1586
|
)
|
|
1255
1587
|
};
|
|
@@ -1282,6 +1614,12 @@ export {
|
|
|
1282
1614
|
withPrerequisite,
|
|
1283
1615
|
createFitnessScoreCalculator,
|
|
1284
1616
|
calculateFitnessScore,
|
|
1617
|
+
JsonlStore,
|
|
1618
|
+
scanForSecrets,
|
|
1619
|
+
describeSecretFindings,
|
|
1620
|
+
getRemediationSoakSink,
|
|
1621
|
+
readRemediationSoakSummary,
|
|
1622
|
+
createRemediationSoakCollector,
|
|
1285
1623
|
consensusFor,
|
|
1286
1624
|
classifySignalPriority,
|
|
1287
1625
|
ImprovementReviewInputSchema,
|
|
@@ -1296,4 +1634,4 @@ export {
|
|
|
1296
1634
|
runImprovementReview,
|
|
1297
1635
|
registerImprovementReviewTool
|
|
1298
1636
|
};
|
|
1299
|
-
//# sourceMappingURL=chunk-
|
|
1637
|
+
//# sourceMappingURL=chunk-M5QEWTVL.js.map
|