@codacy/verity-cli 0.29.4-experimental.9a4e14c → 0.29.4-experimental.cfb4bd2
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/bin/verity.js +216 -18
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -10390,11 +10390,11 @@ var MAX_DELTA_BYTES = 194560;
|
|
|
10390
10390
|
var MAX_FILES = 40;
|
|
10391
10391
|
var MAX_FILE_BYTES = 51200;
|
|
10392
10392
|
var DEBOUNCE_SECONDS = 30;
|
|
10393
|
-
var MAX_SPEC_FILES =
|
|
10394
|
-
var MAX_SPEC_FILE_BYTES =
|
|
10395
|
-
var MAX_TOTAL_SPEC_BYTES =
|
|
10393
|
+
var MAX_SPEC_FILES = 6;
|
|
10394
|
+
var MAX_SPEC_FILE_BYTES = 512e3;
|
|
10395
|
+
var MAX_TOTAL_SPEC_BYTES = 512e3;
|
|
10396
10396
|
var MAX_PLAN_FILES = 3;
|
|
10397
|
-
var MAX_PLAN_FILE_BYTES =
|
|
10397
|
+
var MAX_PLAN_FILE_BYTES = 512e3;
|
|
10398
10398
|
var MAX_INTENT_CHARS = 2e3;
|
|
10399
10399
|
var SNAPSHOT_DIR = `${VERITY_DIR}/.snapshot`;
|
|
10400
10400
|
var BASELINE_DIR = `${VERITY_DIR}/.baseline`;
|
|
@@ -15060,8 +15060,10 @@ function recordVerdict(d, v) {
|
|
|
15060
15060
|
if (summary) appendEvent(d, { k: "goal_delivered", summary });
|
|
15061
15061
|
}
|
|
15062
15062
|
const lines = /* @__PURE__ */ new Map();
|
|
15063
|
+
const sent = new Set(v.sentPaths);
|
|
15063
15064
|
for (const f of v.findings) {
|
|
15064
15065
|
if (!f.file || typeof f.line !== "number" || !f.pattern_id) continue;
|
|
15066
|
+
if (!sent.has(f.file)) continue;
|
|
15065
15067
|
if (!lines.has(f.file)) {
|
|
15066
15068
|
try {
|
|
15067
15069
|
const abs = (0, import_node_path12.join)(root, f.file);
|
|
@@ -16570,6 +16572,7 @@ function createRun(opts, globals) {
|
|
|
16570
16572
|
opts,
|
|
16571
16573
|
globals,
|
|
16572
16574
|
phaseReached: "",
|
|
16575
|
+
phasesCompleted: [],
|
|
16573
16576
|
skipReason: null,
|
|
16574
16577
|
turnId: "",
|
|
16575
16578
|
// The value `resolveReachability` itself returns when every rung declines.
|
|
@@ -16600,6 +16603,7 @@ function createRun(opts, globals) {
|
|
|
16600
16603
|
urlResult: { ok: false, error: "unresolved" },
|
|
16601
16604
|
serviceUrl: "",
|
|
16602
16605
|
token: "",
|
|
16606
|
+
modeDecision: null,
|
|
16603
16607
|
sessionIdForMemory: "",
|
|
16604
16608
|
contextFilePaths: [],
|
|
16605
16609
|
analysisMode: "standard",
|
|
@@ -16710,7 +16714,19 @@ function formatRunEvidence(run, startedAt) {
|
|
|
16710
16714
|
out += row("turn", `${run.turnId || "(unminted)"}${run.sessionId ? ` \xB7 session ${run.sessionId}` : ""}`);
|
|
16711
16715
|
out += row("reached", `${run.phaseReached || "(none)"}${run.skipReason ? ` \xB7 SKIPPED: ${run.skipReason}` : ""} \xB7 ${ms}ms`);
|
|
16712
16716
|
out += row("changed", `${run.changedUniverse.length} from git \xB7 analyzable ${run.analyzable.length} \xB7 reviewable ${run.reviewable.length} \xB7 security ${run.securityFiles.length} \xB7 forReview ${run.allForReview.length}`);
|
|
16713
|
-
|
|
16717
|
+
const done = (phase) => run.phasesCompleted.includes(phase);
|
|
16718
|
+
const ifDone = (phase, value) => done(phase) ? value : "?";
|
|
16719
|
+
const md = run.modeDecision;
|
|
16720
|
+
if (md) {
|
|
16721
|
+
const how = md.forced ? "forced by --mode" : `predicted=${md.predicted ?? "none"} \u2192 ${md.resolved}`;
|
|
16722
|
+
out += row("mode", `${md.resolved} \xB7 ${how} \xB7 authored=${md.authored ? "yes" : "no"} \xB7 investigated=${md.investigated ? "yes" : "no"}`);
|
|
16723
|
+
} else {
|
|
16724
|
+
out += row("mode", `? (this run stopped in ${run.phaseReached || "no phase"}, before the mode was decided)`);
|
|
16725
|
+
}
|
|
16726
|
+
out += row("signals", `baseline=${ifDone("bootstrap", run.baseline ? "yes" : "no")} \xB7 authored=${ifDone("intentInputs", run.turnAuthoredCode ? "yes" : "no")} \xB7 observable=${ifDone("intentInputs", run.authorshipIsObservable ? "yes" : "no")}` + (run.actionSummary?.transcript_windowed ? ` \xB7 window=${run.actionSummary.transcript_windowed}` : ""));
|
|
16727
|
+
if (!done("intentInputs")) {
|
|
16728
|
+
out += row("", `(\`?\` = the phase that determines it did not complete \u2014 this run stopped in ${run.phaseReached})`);
|
|
16729
|
+
}
|
|
16714
16730
|
out += row("sent", `${sent.length} \xB7 ${list(sent)}`);
|
|
16715
16731
|
if (context.length > 0) out += row("context", `${context.length} \xB7 ${list(context)}`);
|
|
16716
16732
|
const withheld = run.reviewCoverage.notReviewed;
|
|
@@ -16735,6 +16751,46 @@ function formatRunEvidence(run, startedAt) {
|
|
|
16735
16751
|
out += row("withheld", "(nothing \u2014 every changed file was reviewed)");
|
|
16736
16752
|
}
|
|
16737
16753
|
}
|
|
16754
|
+
const cov = run.foldResult?.coverage;
|
|
16755
|
+
if (cov) {
|
|
16756
|
+
const delegated = run.foldResult.authored.filter((a) => a.owner === "subagent").length;
|
|
16757
|
+
if (cov.dispatched > 0 || cov.subagentFiles > 0 || cov.subagentSkipped > 0) {
|
|
16758
|
+
out += row("delegated", `${cov.dispatched} dispatched \xB7 ${cov.subagentFiles} agent log(s) read \xB7 ${delegated} path(s) attributed to subagents`);
|
|
16759
|
+
}
|
|
16760
|
+
if (cov.subagentSkipped > 0) {
|
|
16761
|
+
out += row("", `\u26A0 ${cov.subagentSkipped} agent log(s) REFUSED by the byte budget \u2014 the authored set above is PARTIAL`);
|
|
16762
|
+
}
|
|
16763
|
+
if (cov.dispatched > 0 && cov.subagentFiles === 0) {
|
|
16764
|
+
out += row("", `\u26A0 this turn dispatched ${cov.dispatched} agent(s) but no agent log was found \u2014 delegated work is unattributed (has the transcript layout moved?)`);
|
|
16765
|
+
}
|
|
16766
|
+
if (cov.outsideRepo > 0) {
|
|
16767
|
+
out += row("", `${cov.outsideRepo} authored path(s) refused as outside the repo`);
|
|
16768
|
+
}
|
|
16769
|
+
}
|
|
16770
|
+
if (run.foldResult?.tools?.length) {
|
|
16771
|
+
const shown = run.foldResult.tools.slice(0, 6).map((t) => {
|
|
16772
|
+
const outcome = t.failed > 0 ? `${t.failed} failed` : t.last_status === 0 ? "ok" : "?";
|
|
16773
|
+
const where = t.targets.length > 0 ? ` \u2192 ${t.targets.slice(0, 2).join(", ")}` : "";
|
|
16774
|
+
return `${t.runs}\xD7 ${t.name} (${outcome})${where}`;
|
|
16775
|
+
});
|
|
16776
|
+
const more = run.foldResult.tools.length > 6 ? ` \u2026 +${run.foldResult.tools.length - 6} more` : "";
|
|
16777
|
+
out += row("tools", shown.join(" \xB7 ") + more);
|
|
16778
|
+
if (run.foldResult.coverage.toolNamesDropped > 0) {
|
|
16779
|
+
out += row("", `\u26A0 ${run.foldResult.coverage.toolNamesDropped} tool name(s) refused by the cap`);
|
|
16780
|
+
}
|
|
16781
|
+
}
|
|
16782
|
+
if (run.foldResult?.tasks?.length) {
|
|
16783
|
+
const t = run.foldResult.tasks;
|
|
16784
|
+
const done2 = t.filter((x) => x.status === "completed").length;
|
|
16785
|
+
out += row("tasks", `${t.length} \xB7 ${done2} completed \xB7 ` + list(t.slice(0, 4).map((x) => `#${x.id} ${x.name} [${x.status}]`), 4));
|
|
16786
|
+
}
|
|
16787
|
+
if (run.specs?.length) {
|
|
16788
|
+
const readThisSession = new Set(run.actionSummary?.files_read ?? []);
|
|
16789
|
+
const labelled = run.specs.map(
|
|
16790
|
+
(s) => `${s.path}${readThisSession.has(s.path) ? " (read)" : " (positional)"}`
|
|
16791
|
+
);
|
|
16792
|
+
out += row("specs", `${run.specs.length} \xB7 ${list(labelled, 5)}`);
|
|
16793
|
+
}
|
|
16738
16794
|
if (run.staticResults.findings.length > 0) {
|
|
16739
16795
|
out += row("static", `${run.staticResults.findings.length} finding(s) from ${run.staticResults.summary.tools_run.join(", ") || "no tools"}`);
|
|
16740
16796
|
}
|
|
@@ -16930,6 +16986,8 @@ function buildSummary(lines) {
|
|
|
16930
16986
|
break;
|
|
16931
16987
|
case "Agent":
|
|
16932
16988
|
case "Task":
|
|
16989
|
+
case "Workflow":
|
|
16990
|
+
case "SendMessage":
|
|
16933
16991
|
subagents++;
|
|
16934
16992
|
break;
|
|
16935
16993
|
case "WebFetch":
|
|
@@ -17184,7 +17242,7 @@ function channelSilence(input) {
|
|
|
17184
17242
|
// src/lib/cli-version.ts
|
|
17185
17243
|
function cliVersion() {
|
|
17186
17244
|
try {
|
|
17187
|
-
return true ? "0.29.4-experimental.
|
|
17245
|
+
return true ? "0.29.4-experimental.cfb4bd2" : "dev";
|
|
17188
17246
|
} catch {
|
|
17189
17247
|
return "dev";
|
|
17190
17248
|
}
|
|
@@ -17535,18 +17593,26 @@ var SPEC_CANDIDATES = [
|
|
|
17535
17593
|
"docs/API.md",
|
|
17536
17594
|
"spec/ARCHITECTURE.md"
|
|
17537
17595
|
];
|
|
17538
|
-
|
|
17596
|
+
var DOC_EXT = /\.(md|mdx|ya?ml|txt|rst|adoc)$/i;
|
|
17597
|
+
var UNCONSULTED_FILE_BYTES = 10240;
|
|
17598
|
+
var UNCONSULTED_TOTAL_BYTES = 30720;
|
|
17599
|
+
function discoverSpecs(consulted = []) {
|
|
17539
17600
|
const result = [];
|
|
17540
17601
|
const seen = /* @__PURE__ */ new Set();
|
|
17541
17602
|
let totalBytes = 0;
|
|
17542
|
-
const
|
|
17603
|
+
const consultedDocs = new Set(
|
|
17604
|
+
consulted.filter((p) => DOC_EXT.test(p) && !p.startsWith("/") && !p.includes(".."))
|
|
17605
|
+
);
|
|
17606
|
+
const addSpec = (specPath, relevant = false) => {
|
|
17543
17607
|
if (result.length >= MAX_SPEC_FILES) return false;
|
|
17544
|
-
|
|
17608
|
+
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
17609
|
+
if (totalBytes >= totalCap) return false;
|
|
17545
17610
|
if (seen.has(specPath)) return true;
|
|
17546
17611
|
if (!(0, import_node_fs21.existsSync)(specPath)) return true;
|
|
17547
17612
|
seen.add(specPath);
|
|
17548
|
-
const remaining =
|
|
17549
|
-
const
|
|
17613
|
+
const remaining = totalCap - totalBytes;
|
|
17614
|
+
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
17615
|
+
const readBytes = Math.min(fileCap, remaining);
|
|
17550
17616
|
try {
|
|
17551
17617
|
const buf = Buffer.alloc(readBytes);
|
|
17552
17618
|
const fd = (0, import_node_fs21.openSync)(specPath, "r");
|
|
@@ -17560,6 +17626,9 @@ function discoverSpecs() {
|
|
|
17560
17626
|
}
|
|
17561
17627
|
return true;
|
|
17562
17628
|
};
|
|
17629
|
+
for (const doc of consultedDocs) {
|
|
17630
|
+
if (!addSpec(doc, true)) break;
|
|
17631
|
+
}
|
|
17563
17632
|
for (const candidate of SPEC_CANDIDATES) {
|
|
17564
17633
|
if (!addSpec(candidate)) break;
|
|
17565
17634
|
}
|
|
@@ -17630,7 +17699,7 @@ function discoverPlans() {
|
|
|
17630
17699
|
async function intentInputs(run) {
|
|
17631
17700
|
const { actionSummary, allForReview, assistantResponse, baseline, baselineSessionId } = run;
|
|
17632
17701
|
const conversation = await readAndClearConversationBuffer(baselineSessionId);
|
|
17633
|
-
const specs = discoverSpecs();
|
|
17702
|
+
const specs = discoverSpecs(actionSummary?.files_read ?? []);
|
|
17634
17703
|
const plans = discoverPlans();
|
|
17635
17704
|
const agentAuthoredCodeThisTurn = !!(actionSummary && (actionSummary.files_edited.length > 0 || actionSummary.files_created.length > 0));
|
|
17636
17705
|
const turnAuthoredCode = agentAuthoredCodeThisTurn || !!baseline && allForReview.some((f) => changedSinceBaseline(f, baseline));
|
|
@@ -17853,7 +17922,8 @@ async function mode(run) {
|
|
|
17853
17922
|
let analysisMode;
|
|
17854
17923
|
const sessionAuthoredCode = !!baseline && allForReview.some((f) => changedSinceBaseline(f, baseline));
|
|
17855
17924
|
const modeOverride = opts.mode;
|
|
17856
|
-
|
|
17925
|
+
const forced = !!modeOverride && ["standard", "plan", "debug", "skip"].includes(modeOverride);
|
|
17926
|
+
if (forced) {
|
|
17857
17927
|
analysisMode = modeOverride;
|
|
17858
17928
|
} else {
|
|
17859
17929
|
analysisMode = reconcileAnalysisMode(
|
|
@@ -17861,6 +17931,25 @@ async function mode(run) {
|
|
|
17861
17931
|
{ noFilesChanged, assistantResponse, actionSummary, conversationPrompts, sessionAuthoredCode }
|
|
17862
17932
|
);
|
|
17863
17933
|
}
|
|
17934
|
+
const investigated = didAgentInvestigate(actionSummary);
|
|
17935
|
+
run.modeDecision = {
|
|
17936
|
+
predicted: predictedMode ?? null,
|
|
17937
|
+
resolved: analysisMode,
|
|
17938
|
+
authored: turnAuthoredCode,
|
|
17939
|
+
investigated,
|
|
17940
|
+
forced
|
|
17941
|
+
};
|
|
17942
|
+
logEvent("mode_resolved", {
|
|
17943
|
+
predicted: predictedMode ?? null,
|
|
17944
|
+
resolved: analysisMode,
|
|
17945
|
+
forced,
|
|
17946
|
+
authored: turnAuthoredCode,
|
|
17947
|
+
investigated,
|
|
17948
|
+
// The two counters that decide `investigated`, so a false reading is
|
|
17949
|
+
// traceable to the tool that was not recognised.
|
|
17950
|
+
subagents: actionSummary?.subagents ?? null,
|
|
17951
|
+
files_read: actionSummary?.files_read.length ?? null
|
|
17952
|
+
});
|
|
17864
17953
|
if (analysisMode === "skip") {
|
|
17865
17954
|
await passAndExit(
|
|
17866
17955
|
run,
|
|
@@ -18126,6 +18215,18 @@ function commandShape(cmd) {
|
|
|
18126
18215
|
return out.join(" ").slice(0, COMMAND_HEAD_CHARS);
|
|
18127
18216
|
}
|
|
18128
18217
|
var COMMAND_HEAD_CHARS = 80;
|
|
18218
|
+
var MAX_TOOL_NAMES = 64;
|
|
18219
|
+
var MAX_TOOL_TARGETS = 3;
|
|
18220
|
+
var MAX_TASKS = 64;
|
|
18221
|
+
var TASK_NAME_CHARS = 120;
|
|
18222
|
+
function toolTarget(name, input) {
|
|
18223
|
+
if (name === "Bash") return null;
|
|
18224
|
+
for (const key of ["file_path", "notebook_path", "path", "filePath"]) {
|
|
18225
|
+
const v = input[key];
|
|
18226
|
+
if (typeof v === "string" && v) return v.slice(0, 120);
|
|
18227
|
+
}
|
|
18228
|
+
return null;
|
|
18229
|
+
}
|
|
18129
18230
|
var rootCandidateCache = /* @__PURE__ */ new Map();
|
|
18130
18231
|
function candidateRoots(repoRoot2) {
|
|
18131
18232
|
const cached2 = rootCandidateCache.get(repoRoot2);
|
|
@@ -18154,17 +18255,30 @@ function toRepoRelative(path, repoRoot2) {
|
|
|
18154
18255
|
}
|
|
18155
18256
|
return p.replace(/^\/+/, "");
|
|
18156
18257
|
}
|
|
18258
|
+
function isInsideRepo(path, repoRoot2) {
|
|
18259
|
+
const p = path.replace(/\\/g, "/");
|
|
18260
|
+
if (!isAbsolutePath(p)) return true;
|
|
18261
|
+
if (!repoRoot2) return true;
|
|
18262
|
+
return candidateRoots(repoRoot2).some((root) => p === root || p.startsWith(root + "/"));
|
|
18263
|
+
}
|
|
18264
|
+
function isAbsolutePath(p) {
|
|
18265
|
+
return p.startsWith("/") || /^[A-Za-z]:\//.test(p);
|
|
18266
|
+
}
|
|
18157
18267
|
function fold(transcriptPath, opts = {}) {
|
|
18158
18268
|
const result = {
|
|
18159
18269
|
authored: [],
|
|
18160
18270
|
unobserved: [],
|
|
18161
18271
|
commands: [],
|
|
18272
|
+
tools: [],
|
|
18273
|
+
tasks: [],
|
|
18162
18274
|
unknownTypes: [],
|
|
18163
18275
|
coverage: {
|
|
18164
18276
|
recordCounts: {},
|
|
18165
18277
|
totalRecords: 0,
|
|
18166
18278
|
malformed: 0,
|
|
18167
18279
|
subagentFiles: 0,
|
|
18280
|
+
outsideRepo: 0,
|
|
18281
|
+
toolNamesDropped: 0,
|
|
18168
18282
|
dispatched: 0,
|
|
18169
18283
|
userMessages: 0,
|
|
18170
18284
|
subagentSkipped: 0,
|
|
@@ -18175,6 +18289,10 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18175
18289
|
const byPath = /* @__PURE__ */ new Map();
|
|
18176
18290
|
const commandStats = /* @__PURE__ */ new Map();
|
|
18177
18291
|
const pendingByToolUse = /* @__PURE__ */ new Map();
|
|
18292
|
+
const toolStats = /* @__PURE__ */ new Map();
|
|
18293
|
+
const pendingToolName = /* @__PURE__ */ new Map();
|
|
18294
|
+
const taskById = /* @__PURE__ */ new Map();
|
|
18295
|
+
const pendingTaskName = /* @__PURE__ */ new Map();
|
|
18178
18296
|
const unknown = /* @__PURE__ */ new Set();
|
|
18179
18297
|
const ingest = (raw, owner) => {
|
|
18180
18298
|
for (const line of raw.split("\n")) {
|
|
@@ -18194,7 +18312,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18194
18312
|
result.coverage.compactions++;
|
|
18195
18313
|
}
|
|
18196
18314
|
if (type === "user" && hasUserText(record)) result.coverage.userMessages++;
|
|
18197
|
-
collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, opts.repoRoot, result.coverage);
|
|
18315
|
+
collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, toolStats, pendingToolName, taskById, pendingTaskName, opts.repoRoot, result.coverage);
|
|
18198
18316
|
}
|
|
18199
18317
|
};
|
|
18200
18318
|
try {
|
|
@@ -18205,7 +18323,11 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18205
18323
|
return result;
|
|
18206
18324
|
}
|
|
18207
18325
|
try {
|
|
18208
|
-
const sidecarDir = (0, import_node_path18.join)(
|
|
18326
|
+
const sidecarDir = (0, import_node_path18.join)(
|
|
18327
|
+
(0, import_node_path18.dirname)(transcriptPath),
|
|
18328
|
+
(0, import_node_path18.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
18329
|
+
"subagents"
|
|
18330
|
+
);
|
|
18209
18331
|
if ((0, import_node_fs23.existsSync)(sidecarDir)) {
|
|
18210
18332
|
const maxFiles = opts.maxSidecars ?? 200;
|
|
18211
18333
|
const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
|
|
@@ -18248,6 +18370,14 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18248
18370
|
result.authored = [...byPath.values()].sort((a, b) => a.p.localeCompare(b.p));
|
|
18249
18371
|
result.unknownTypes = [...unknown].sort();
|
|
18250
18372
|
result.commands = [...commandStats.entries()].map(([cls, s]) => ({ class: cls, ...s })).sort((a, b) => a.class.localeCompare(b.class));
|
|
18373
|
+
result.tools = [...toolStats.entries()].map(([name, s]) => ({
|
|
18374
|
+
name,
|
|
18375
|
+
runs: s.runs,
|
|
18376
|
+
failed: s.failed,
|
|
18377
|
+
last_status: s.last_status,
|
|
18378
|
+
targets: [...s.targets].map((t) => toRepoRelative(t, opts.repoRoot)).sort()
|
|
18379
|
+
})).sort((a, b) => b.runs - a.runs || a.name.localeCompare(b.name));
|
|
18380
|
+
result.tasks = [...taskById.entries()].map(([id, t]) => ({ id, name: t.name, status: t.status })).sort((a, b) => (Number(a.id) || 0) - (Number(b.id) || 0));
|
|
18251
18381
|
const authoredPaths = new Set(result.authored.map((a) => a.p));
|
|
18252
18382
|
for (const raw of opts.changedFiles ?? []) {
|
|
18253
18383
|
const p = toRepoRelative(raw, opts.repoRoot);
|
|
@@ -18266,7 +18396,7 @@ function classifyUnobserved(path) {
|
|
|
18266
18396
|
if (/\.(png|jpg|jpeg|gif|pdf|zip|woff2?|ico|mp4)$/i.test(path)) return "binary";
|
|
18267
18397
|
return "no_edit_record";
|
|
18268
18398
|
}
|
|
18269
|
-
function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, repoRoot2, tally) {
|
|
18399
|
+
function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, toolStats, pendingToolName, taskById, pendingTaskName, repoRoot2, tally) {
|
|
18270
18400
|
const message = record.message;
|
|
18271
18401
|
const content = message?.content ?? record.content;
|
|
18272
18402
|
const blocks = Array.isArray(content) ? content : content && typeof content === "object" ? [content] : [];
|
|
@@ -18275,8 +18405,38 @@ function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse
|
|
|
18275
18405
|
if (blockType === "tool_use") {
|
|
18276
18406
|
const name = String(block.name ?? "");
|
|
18277
18407
|
const input = block.input ?? {};
|
|
18408
|
+
if (name && toolStats.size < MAX_TOOL_NAMES) {
|
|
18409
|
+
const prev = toolStats.get(name) ?? { runs: 0, failed: 0, last_status: null, targets: /* @__PURE__ */ new Set() };
|
|
18410
|
+
prev.targets = prev.targets ?? /* @__PURE__ */ new Set();
|
|
18411
|
+
if (prev.targets.size < MAX_TOOL_TARGETS) {
|
|
18412
|
+
const target = toolTarget(name, input);
|
|
18413
|
+
if (target) prev.targets.add(target);
|
|
18414
|
+
}
|
|
18415
|
+
toolStats.set(name, { runs: prev.runs + 1, failed: prev.failed, last_status: null, targets: prev.targets });
|
|
18416
|
+
const toolId = typeof block.id === "string" ? block.id : null;
|
|
18417
|
+
if (toolId) pendingToolName.set(toolId, name);
|
|
18418
|
+
} else if (name && tally) {
|
|
18419
|
+
tally.toolNamesDropped += 1;
|
|
18420
|
+
}
|
|
18421
|
+
if (name === "TaskCreate") {
|
|
18422
|
+
const subject = typeof input.subject === "string" ? input.subject : "";
|
|
18423
|
+
const taskId = typeof block.id === "string" ? block.id : null;
|
|
18424
|
+
if (subject && taskId) pendingTaskName.set(taskId, subject.slice(0, TASK_NAME_CHARS));
|
|
18425
|
+
}
|
|
18426
|
+
if (name === "TaskUpdate") {
|
|
18427
|
+
const id = typeof input.taskId === "string" ? input.taskId : "";
|
|
18428
|
+
const status = typeof input.status === "string" ? input.status : "";
|
|
18429
|
+
if (id && status) {
|
|
18430
|
+
const entry = taskById.get(id);
|
|
18431
|
+
taskById.set(id, { name: entry?.name ?? `#${id}`, status });
|
|
18432
|
+
}
|
|
18433
|
+
}
|
|
18278
18434
|
if (EDIT_TOOLS.has(name)) {
|
|
18279
18435
|
const rawPath = typeof input.notebook_path === "string" ? input.notebook_path : typeof input.file_path === "string" ? input.file_path : null;
|
|
18436
|
+
if (rawPath && !isInsideRepo(rawPath, repoRoot2)) {
|
|
18437
|
+
if (tally) tally.outsideRepo += 1;
|
|
18438
|
+
continue;
|
|
18439
|
+
}
|
|
18280
18440
|
const path = rawPath ? toRepoRelative(rawPath, repoRoot2) : null;
|
|
18281
18441
|
if (path) {
|
|
18282
18442
|
const entry = byPath.get(path) ?? { p: path, h: 0, a: 0, d: 0, owner };
|
|
@@ -18310,6 +18470,31 @@ function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse
|
|
|
18310
18470
|
}
|
|
18311
18471
|
if (blockType === "tool_result") {
|
|
18312
18472
|
const id = typeof block.tool_use_id === "string" ? block.tool_use_id : null;
|
|
18473
|
+
const taskName = id ? pendingTaskName.get(id) : void 0;
|
|
18474
|
+
if (taskName) {
|
|
18475
|
+
pendingTaskName.delete(id);
|
|
18476
|
+
const body = typeof block.content === "string" ? block.content : "";
|
|
18477
|
+
const created = /Task #(\d+)/.exec(body);
|
|
18478
|
+
if (created && taskById.size < MAX_TASKS) {
|
|
18479
|
+
taskById.set(created[1], { name: taskName, status: taskById.get(created[1])?.status ?? "created" });
|
|
18480
|
+
}
|
|
18481
|
+
}
|
|
18482
|
+
const toolName = id ? pendingToolName.get(id) : void 0;
|
|
18483
|
+
if (toolName) {
|
|
18484
|
+
pendingToolName.delete(id);
|
|
18485
|
+
const prevTool = toolStats.get(toolName);
|
|
18486
|
+
if (prevTool) {
|
|
18487
|
+
const failed = block.is_error === true;
|
|
18488
|
+
toolStats.set(toolName, {
|
|
18489
|
+
runs: prevTool.runs,
|
|
18490
|
+
failed: prevTool.failed + (failed ? 1 : 0),
|
|
18491
|
+
last_status: block.is_error === true ? 1 : block.is_error === false ? 0 : null,
|
|
18492
|
+
// Carried, not rebuilt: the targets were collected on the `tool_use`
|
|
18493
|
+
// side and dropping them here would empty the ledger on every result.
|
|
18494
|
+
targets: prevTool.targets
|
|
18495
|
+
});
|
|
18496
|
+
}
|
|
18497
|
+
}
|
|
18313
18498
|
const cls = id ? pendingByToolUse.get(id) : void 0;
|
|
18314
18499
|
if (!cls) continue;
|
|
18315
18500
|
pendingByToolUse.delete(id);
|
|
@@ -18529,6 +18714,10 @@ function gatherContextFiles(contextPaths, deltaFiles) {
|
|
|
18529
18714
|
for (const filePath of contextPaths) {
|
|
18530
18715
|
if (result.length >= MAX_CONTEXT_FILES) break;
|
|
18531
18716
|
if (deltaPaths.has(filePath)) continue;
|
|
18717
|
+
if (isVerityOwnedPath(filePath)) {
|
|
18718
|
+
logEvent("context_file_skipped", { path: filePath, reason: "verity_owned" });
|
|
18719
|
+
continue;
|
|
18720
|
+
}
|
|
18532
18721
|
try {
|
|
18533
18722
|
const content = (0, import_node_fs25.readFileSync)(filePath, "utf8");
|
|
18534
18723
|
const bytes = Buffer.byteLength(content);
|
|
@@ -19299,6 +19488,8 @@ async function buildRequest(run) {
|
|
|
19299
19488
|
authored_since_verdict: memorySession ? foldDossier(memorySession.d).authored_all.filter((a) => a.hash_now !== a.hash_at_last_verdict).map((a) => a.path) : [],
|
|
19300
19489
|
unobserved: foldResult?.unobserved ?? [],
|
|
19301
19490
|
commands: foldResult?.commands ?? [],
|
|
19491
|
+
tools: foldResult?.tools ?? [],
|
|
19492
|
+
tasks: foldResult?.tasks ?? [],
|
|
19302
19493
|
unknown_types: foldResult?.unknownTypes ?? [],
|
|
19303
19494
|
coverage: foldResult?.coverage ?? { recordCounts: {}, totalRecords: 0, malformed: 0, subagentFiles: 0, subagentSkipped: 0, complete: false },
|
|
19304
19495
|
// INV-19, computed client-side and sent so a conservation failure is
|
|
@@ -19672,6 +19863,11 @@ async function reconcile(run) {
|
|
|
19672
19863
|
decision,
|
|
19673
19864
|
branch: getCurrentBranch(),
|
|
19674
19865
|
watermarkSha: watermarkIsPartial ? null : watermarkHash,
|
|
19866
|
+
// The byte witness — the same "only honest definition of reviewed" the
|
|
19867
|
+
// coverage column uses. A finding on a path outside this set records no
|
|
19868
|
+
// statement (plan-mode prose anchored to unsent files must not become
|
|
19869
|
+
// "STILL OPEN … the tree is not clean").
|
|
19870
|
+
sentPaths,
|
|
19675
19871
|
findings: response.findings?.map((f) => ({
|
|
19676
19872
|
file: f.file,
|
|
19677
19873
|
line: f.line,
|
|
@@ -20123,10 +20319,12 @@ async function runAnalyze(opts, globals) {
|
|
|
20123
20319
|
run.phaseReached = name;
|
|
20124
20320
|
if (!tracing()) {
|
|
20125
20321
|
await phase(run);
|
|
20322
|
+
run.phasesCompleted.push(name);
|
|
20126
20323
|
continue;
|
|
20127
20324
|
}
|
|
20128
20325
|
const started = Date.now();
|
|
20129
20326
|
await phase(run);
|
|
20327
|
+
run.phasesCompleted.push(name);
|
|
20130
20328
|
process.stderr.write(`verity\xB7phase ${name} ${Date.now() - started}ms
|
|
20131
20329
|
`);
|
|
20132
20330
|
}
|
|
@@ -21923,8 +22121,8 @@ function registerTelemetryCommands(program2) {
|
|
|
21923
22121
|
}
|
|
21924
22122
|
|
|
21925
22123
|
// src/cli.ts
|
|
21926
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.29.4-experimental.
|
|
21927
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.29.4-experimental.
|
|
22124
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.29.4-experimental.cfb4bd2").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
|
|
22125
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.29.4-experimental.cfb4bd2");
|
|
21928
22126
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
21929
22127
|
try {
|
|
21930
22128
|
await foldLegacyLocalCredential();
|
package/package.json
CHANGED