@codacy/verity-cli 0.29.4-experimental.5fcba03 → 0.29.4-experimental.7126d67
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 +179 -24
- 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);
|
|
@@ -16717,7 +16719,7 @@ function formatRunEvidence(run, startedAt) {
|
|
|
16717
16719
|
const md = run.modeDecision;
|
|
16718
16720
|
if (md) {
|
|
16719
16721
|
const how = md.forced ? "forced by --mode" : `predicted=${md.predicted ?? "none"} \u2192 ${md.resolved}`;
|
|
16720
|
-
out += row("mode", `${md.resolved} \xB7 ${how} \xB7 authored=${md.authored ? "yes" : "no"} \xB7 investigated=${md.investigated ? "yes" : "no"}`);
|
|
16722
|
+
out += row("mode", `${md.resolved} \xB7 ${how}` + (md.flip ? ` (flipped to plan: no delta at ${md.flip})` : "") + ` \xB7 authored=${md.authored ? "yes" : "no"} \xB7 investigated=${md.investigated ? "yes" : "no"}`);
|
|
16721
16723
|
} else {
|
|
16722
16724
|
out += row("mode", `? (this run stopped in ${run.phaseReached || "no phase"}, before the mode was decided)`);
|
|
16723
16725
|
}
|
|
@@ -16765,6 +16767,30 @@ function formatRunEvidence(run, startedAt) {
|
|
|
16765
16767
|
out += row("", `${cov.outsideRepo} authored path(s) refused as outside the repo`);
|
|
16766
16768
|
}
|
|
16767
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
|
+
}
|
|
16768
16794
|
if (run.staticResults.findings.length > 0) {
|
|
16769
16795
|
out += row("static", `${run.staticResults.findings.length} finding(s) from ${run.staticResults.summary.tools_run.join(", ") || "no tools"}`);
|
|
16770
16796
|
}
|
|
@@ -17216,7 +17242,7 @@ function channelSilence(input) {
|
|
|
17216
17242
|
// src/lib/cli-version.ts
|
|
17217
17243
|
function cliVersion() {
|
|
17218
17244
|
try {
|
|
17219
|
-
return true ? "0.29.4-experimental.
|
|
17245
|
+
return true ? "0.29.4-experimental.7126d67" : "dev";
|
|
17220
17246
|
} catch {
|
|
17221
17247
|
return "dev";
|
|
17222
17248
|
}
|
|
@@ -17567,18 +17593,26 @@ var SPEC_CANDIDATES = [
|
|
|
17567
17593
|
"docs/API.md",
|
|
17568
17594
|
"spec/ARCHITECTURE.md"
|
|
17569
17595
|
];
|
|
17570
|
-
|
|
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 = []) {
|
|
17571
17600
|
const result = [];
|
|
17572
17601
|
const seen = /* @__PURE__ */ new Set();
|
|
17573
17602
|
let totalBytes = 0;
|
|
17574
|
-
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) => {
|
|
17575
17607
|
if (result.length >= MAX_SPEC_FILES) return false;
|
|
17576
|
-
|
|
17608
|
+
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
17609
|
+
if (totalBytes >= totalCap) return false;
|
|
17577
17610
|
if (seen.has(specPath)) return true;
|
|
17578
17611
|
if (!(0, import_node_fs21.existsSync)(specPath)) return true;
|
|
17579
17612
|
seen.add(specPath);
|
|
17580
|
-
const remaining =
|
|
17581
|
-
const
|
|
17613
|
+
const remaining = totalCap - totalBytes;
|
|
17614
|
+
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
17615
|
+
const readBytes = Math.min(fileCap, remaining);
|
|
17582
17616
|
try {
|
|
17583
17617
|
const buf = Buffer.alloc(readBytes);
|
|
17584
17618
|
const fd = (0, import_node_fs21.openSync)(specPath, "r");
|
|
@@ -17592,6 +17626,9 @@ function discoverSpecs() {
|
|
|
17592
17626
|
}
|
|
17593
17627
|
return true;
|
|
17594
17628
|
};
|
|
17629
|
+
for (const doc of consultedDocs) {
|
|
17630
|
+
if (!addSpec(doc, true)) break;
|
|
17631
|
+
}
|
|
17595
17632
|
for (const candidate of SPEC_CANDIDATES) {
|
|
17596
17633
|
if (!addSpec(candidate)) break;
|
|
17597
17634
|
}
|
|
@@ -17662,7 +17699,7 @@ function discoverPlans() {
|
|
|
17662
17699
|
async function intentInputs(run) {
|
|
17663
17700
|
const { actionSummary, allForReview, assistantResponse, baseline, baselineSessionId } = run;
|
|
17664
17701
|
const conversation = await readAndClearConversationBuffer(baselineSessionId);
|
|
17665
|
-
const specs = discoverSpecs();
|
|
17702
|
+
const specs = discoverSpecs(actionSummary?.files_read ?? []);
|
|
17666
17703
|
const plans = discoverPlans();
|
|
17667
17704
|
const agentAuthoredCodeThisTurn = !!(actionSummary && (actionSummary.files_edited.length > 0 || actionSummary.files_created.length > 0));
|
|
17668
17705
|
const turnAuthoredCode = agentAuthoredCodeThisTurn || !!baseline && allForReview.some((f) => changedSinceBaseline(f, baseline));
|
|
@@ -18178,6 +18215,18 @@ function commandShape(cmd) {
|
|
|
18178
18215
|
return out.join(" ").slice(0, COMMAND_HEAD_CHARS);
|
|
18179
18216
|
}
|
|
18180
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
|
+
}
|
|
18181
18230
|
var rootCandidateCache = /* @__PURE__ */ new Map();
|
|
18182
18231
|
function candidateRoots(repoRoot2) {
|
|
18183
18232
|
const cached2 = rootCandidateCache.get(repoRoot2);
|
|
@@ -18208,15 +18257,20 @@ function toRepoRelative(path, repoRoot2) {
|
|
|
18208
18257
|
}
|
|
18209
18258
|
function isInsideRepo(path, repoRoot2) {
|
|
18210
18259
|
const p = path.replace(/\\/g, "/");
|
|
18211
|
-
if (!p
|
|
18260
|
+
if (!isAbsolutePath(p)) return true;
|
|
18212
18261
|
if (!repoRoot2) return true;
|
|
18213
18262
|
return candidateRoots(repoRoot2).some((root) => p === root || p.startsWith(root + "/"));
|
|
18214
18263
|
}
|
|
18264
|
+
function isAbsolutePath(p) {
|
|
18265
|
+
return p.startsWith("/") || /^[A-Za-z]:\//.test(p);
|
|
18266
|
+
}
|
|
18215
18267
|
function fold(transcriptPath, opts = {}) {
|
|
18216
18268
|
const result = {
|
|
18217
18269
|
authored: [],
|
|
18218
18270
|
unobserved: [],
|
|
18219
18271
|
commands: [],
|
|
18272
|
+
tools: [],
|
|
18273
|
+
tasks: [],
|
|
18220
18274
|
unknownTypes: [],
|
|
18221
18275
|
coverage: {
|
|
18222
18276
|
recordCounts: {},
|
|
@@ -18224,16 +18278,23 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18224
18278
|
malformed: 0,
|
|
18225
18279
|
subagentFiles: 0,
|
|
18226
18280
|
outsideRepo: 0,
|
|
18281
|
+
toolNamesDropped: 0,
|
|
18227
18282
|
dispatched: 0,
|
|
18228
18283
|
userMessages: 0,
|
|
18229
18284
|
subagentSkipped: 0,
|
|
18230
18285
|
compactions: 0,
|
|
18231
18286
|
complete: false
|
|
18232
|
-
}
|
|
18287
|
+
},
|
|
18288
|
+
planApproval: { approvals: 0, activeSinceLastPrompt: false }
|
|
18233
18289
|
};
|
|
18290
|
+
const flow = { seq: 0, lastPrompt: -1, lastApproval: -1, approvals: 0 };
|
|
18234
18291
|
const byPath = /* @__PURE__ */ new Map();
|
|
18235
18292
|
const commandStats = /* @__PURE__ */ new Map();
|
|
18236
18293
|
const pendingByToolUse = /* @__PURE__ */ new Map();
|
|
18294
|
+
const toolStats = /* @__PURE__ */ new Map();
|
|
18295
|
+
const pendingToolName = /* @__PURE__ */ new Map();
|
|
18296
|
+
const taskById = /* @__PURE__ */ new Map();
|
|
18297
|
+
const pendingTaskName = /* @__PURE__ */ new Map();
|
|
18237
18298
|
const unknown = /* @__PURE__ */ new Set();
|
|
18238
18299
|
const ingest = (raw, owner) => {
|
|
18239
18300
|
for (const line of raw.split("\n")) {
|
|
@@ -18252,8 +18313,12 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18252
18313
|
if (type === "system" && record.subtype === "compact_boundary") {
|
|
18253
18314
|
result.coverage.compactions++;
|
|
18254
18315
|
}
|
|
18255
|
-
if (type === "user" && hasUserText(record))
|
|
18256
|
-
|
|
18316
|
+
if (type === "user" && hasUserText(record)) {
|
|
18317
|
+
result.coverage.userMessages++;
|
|
18318
|
+
if (owner === "agent") flow.lastPrompt = flow.seq;
|
|
18319
|
+
}
|
|
18320
|
+
if (owner === "agent") flow.seq++;
|
|
18321
|
+
collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, toolStats, pendingToolName, taskById, pendingTaskName, opts.repoRoot, result.coverage, flow);
|
|
18257
18322
|
}
|
|
18258
18323
|
};
|
|
18259
18324
|
try {
|
|
@@ -18311,12 +18376,24 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18311
18376
|
result.authored = [...byPath.values()].sort((a, b) => a.p.localeCompare(b.p));
|
|
18312
18377
|
result.unknownTypes = [...unknown].sort();
|
|
18313
18378
|
result.commands = [...commandStats.entries()].map(([cls, s]) => ({ class: cls, ...s })).sort((a, b) => a.class.localeCompare(b.class));
|
|
18379
|
+
result.tools = [...toolStats.entries()].map(([name, s]) => ({
|
|
18380
|
+
name,
|
|
18381
|
+
runs: s.runs,
|
|
18382
|
+
failed: s.failed,
|
|
18383
|
+
last_status: s.last_status,
|
|
18384
|
+
targets: [...s.targets].map((t) => toRepoRelative(t, opts.repoRoot)).sort()
|
|
18385
|
+
})).sort((a, b) => b.runs - a.runs || a.name.localeCompare(b.name));
|
|
18386
|
+
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));
|
|
18314
18387
|
const authoredPaths = new Set(result.authored.map((a) => a.p));
|
|
18315
18388
|
for (const raw of opts.changedFiles ?? []) {
|
|
18316
18389
|
const p = toRepoRelative(raw, opts.repoRoot);
|
|
18317
18390
|
if (!p || authoredPaths.has(p)) continue;
|
|
18318
18391
|
result.unobserved.push({ p, cause: classifyUnobserved(raw) });
|
|
18319
18392
|
}
|
|
18393
|
+
result.planApproval = {
|
|
18394
|
+
approvals: flow.approvals,
|
|
18395
|
+
activeSinceLastPrompt: flow.lastApproval >= 0 && flow.lastApproval > flow.lastPrompt
|
|
18396
|
+
};
|
|
18320
18397
|
return result;
|
|
18321
18398
|
}
|
|
18322
18399
|
function classifyUnobserved(path) {
|
|
@@ -18329,7 +18406,7 @@ function classifyUnobserved(path) {
|
|
|
18329
18406
|
if (/\.(png|jpg|jpeg|gif|pdf|zip|woff2?|ico|mp4)$/i.test(path)) return "binary";
|
|
18330
18407
|
return "no_edit_record";
|
|
18331
18408
|
}
|
|
18332
|
-
function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, repoRoot2, tally) {
|
|
18409
|
+
function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, toolStats, pendingToolName, taskById, pendingTaskName, repoRoot2, tally, flow) {
|
|
18333
18410
|
const message = record.message;
|
|
18334
18411
|
const content = message?.content ?? record.content;
|
|
18335
18412
|
const blocks = Array.isArray(content) ? content : content && typeof content === "object" ? [content] : [];
|
|
@@ -18338,6 +18415,32 @@ function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse
|
|
|
18338
18415
|
if (blockType === "tool_use") {
|
|
18339
18416
|
const name = String(block.name ?? "");
|
|
18340
18417
|
const input = block.input ?? {};
|
|
18418
|
+
if (name && toolStats.size < MAX_TOOL_NAMES) {
|
|
18419
|
+
const prev = toolStats.get(name) ?? { runs: 0, failed: 0, last_status: null, targets: /* @__PURE__ */ new Set() };
|
|
18420
|
+
prev.targets = prev.targets ?? /* @__PURE__ */ new Set();
|
|
18421
|
+
if (prev.targets.size < MAX_TOOL_TARGETS) {
|
|
18422
|
+
const target = toolTarget(name, input);
|
|
18423
|
+
if (target) prev.targets.add(target);
|
|
18424
|
+
}
|
|
18425
|
+
toolStats.set(name, { runs: prev.runs + 1, failed: prev.failed, last_status: null, targets: prev.targets });
|
|
18426
|
+
const toolId = typeof block.id === "string" ? block.id : null;
|
|
18427
|
+
if (toolId) pendingToolName.set(toolId, name);
|
|
18428
|
+
} else if (name && tally) {
|
|
18429
|
+
tally.toolNamesDropped += 1;
|
|
18430
|
+
}
|
|
18431
|
+
if (name === "TaskCreate") {
|
|
18432
|
+
const subject = typeof input.subject === "string" ? input.subject : "";
|
|
18433
|
+
const taskId = typeof block.id === "string" ? block.id : null;
|
|
18434
|
+
if (subject && taskId) pendingTaskName.set(taskId, subject.slice(0, TASK_NAME_CHARS));
|
|
18435
|
+
}
|
|
18436
|
+
if (name === "TaskUpdate") {
|
|
18437
|
+
const id = typeof input.taskId === "string" ? input.taskId : "";
|
|
18438
|
+
const status = typeof input.status === "string" ? input.status : "";
|
|
18439
|
+
if (id && status) {
|
|
18440
|
+
const entry = taskById.get(id);
|
|
18441
|
+
taskById.set(id, { name: entry?.name ?? `#${id}`, status });
|
|
18442
|
+
}
|
|
18443
|
+
}
|
|
18341
18444
|
if (EDIT_TOOLS.has(name)) {
|
|
18342
18445
|
const rawPath = typeof input.notebook_path === "string" ? input.notebook_path : typeof input.file_path === "string" ? input.file_path : null;
|
|
18343
18446
|
if (rawPath && !isInsideRepo(rawPath, repoRoot2)) {
|
|
@@ -18377,6 +18480,38 @@ function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse
|
|
|
18377
18480
|
}
|
|
18378
18481
|
if (blockType === "tool_result") {
|
|
18379
18482
|
const id = typeof block.tool_use_id === "string" ? block.tool_use_id : null;
|
|
18483
|
+
const taskName = id ? pendingTaskName.get(id) : void 0;
|
|
18484
|
+
if (taskName) {
|
|
18485
|
+
pendingTaskName.delete(id);
|
|
18486
|
+
const body = typeof block.content === "string" ? block.content : "";
|
|
18487
|
+
const created = /Task #(\d+)/.exec(body);
|
|
18488
|
+
if (created && taskById.size < MAX_TASKS) {
|
|
18489
|
+
taskById.set(created[1], { name: taskName, status: taskById.get(created[1])?.status ?? "created" });
|
|
18490
|
+
}
|
|
18491
|
+
}
|
|
18492
|
+
const toolName = id ? pendingToolName.get(id) : void 0;
|
|
18493
|
+
if (toolName === "ExitPlanMode" && flow && block.is_error !== true) {
|
|
18494
|
+
const body = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c) => typeof c.text === "string" ? c.text : "").join(" ") : "";
|
|
18495
|
+
if (/approved your plan/i.test(body)) {
|
|
18496
|
+
flow.lastApproval = flow.seq;
|
|
18497
|
+
flow.approvals += 1;
|
|
18498
|
+
}
|
|
18499
|
+
}
|
|
18500
|
+
if (toolName) {
|
|
18501
|
+
pendingToolName.delete(id);
|
|
18502
|
+
const prevTool = toolStats.get(toolName);
|
|
18503
|
+
if (prevTool) {
|
|
18504
|
+
const failed = block.is_error === true;
|
|
18505
|
+
toolStats.set(toolName, {
|
|
18506
|
+
runs: prevTool.runs,
|
|
18507
|
+
failed: prevTool.failed + (failed ? 1 : 0),
|
|
18508
|
+
last_status: block.is_error === true ? 1 : block.is_error === false ? 0 : null,
|
|
18509
|
+
// Carried, not rebuilt: the targets were collected on the `tool_use`
|
|
18510
|
+
// side and dropping them here would empty the ledger on every result.
|
|
18511
|
+
targets: prevTool.targets
|
|
18512
|
+
});
|
|
18513
|
+
}
|
|
18514
|
+
}
|
|
18380
18515
|
const cls = id ? pendingByToolUse.get(id) : void 0;
|
|
18381
18516
|
if (!cls) continue;
|
|
18382
18517
|
pendingByToolUse.delete(id);
|
|
@@ -18419,8 +18554,13 @@ function checkConservation(changedFiles, result, repoRoot2) {
|
|
|
18419
18554
|
// src/commands/analyze/phases/06-evidence.ts
|
|
18420
18555
|
async function evidence(run) {
|
|
18421
18556
|
const { opts } = run;
|
|
18422
|
-
const { actionSummary, allForReview, analyzable, assistantResponse, authorshipIsObservable, baseline, baselineSessionId, hasRecentCommitFiles, reviewable, securityFiles, sessionAuthoredCode, transcriptPath } = run;
|
|
18557
|
+
const { actionSummary, allForReview, analyzable, assistantResponse, authorshipIsObservable, baseline, baselineSessionId, hasRecentCommitFiles, reviewable, securityFiles, sessionAuthoredCode, transcriptPath, turnAuthoredCode } = run;
|
|
18423
18558
|
let { analysisMode, earlyFold } = run;
|
|
18559
|
+
const recordFlip = (stage) => {
|
|
18560
|
+
if (run.modeDecision) run.modeDecision = { ...run.modeDecision, resolved: "plan", flip: stage };
|
|
18561
|
+
logEvent("mode_flipped", { stage, to: "plan" });
|
|
18562
|
+
};
|
|
18563
|
+
const planWorthy = !!assistantResponse && !turnAuthoredCode;
|
|
18424
18564
|
let staticResults = {
|
|
18425
18565
|
tool: "@codacy/analysis-cli",
|
|
18426
18566
|
findings: [],
|
|
@@ -18440,8 +18580,9 @@ async function evidence(run) {
|
|
|
18440
18580
|
const debounceSeconds = parseInt(opts.debounce, 10);
|
|
18441
18581
|
const debounceSkip = checkDebounce(debounceSeconds, baselineSessionId);
|
|
18442
18582
|
if (debounceSkip) {
|
|
18443
|
-
if (
|
|
18583
|
+
if (planWorthy) {
|
|
18444
18584
|
analysisMode = "plan";
|
|
18585
|
+
recordFlip("debounce");
|
|
18445
18586
|
} else {
|
|
18446
18587
|
await passAndExit(run, debounceSkip, "debounce");
|
|
18447
18588
|
}
|
|
@@ -18450,8 +18591,9 @@ async function evidence(run) {
|
|
|
18450
18591
|
const allCheckable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...reviewable, ...securityFiles]));
|
|
18451
18592
|
const mtimeSkip = checkMtime(allCheckable, hasRecentCommitFiles, baselineSessionId);
|
|
18452
18593
|
if (mtimeSkip) {
|
|
18453
|
-
if (
|
|
18594
|
+
if (planWorthy) {
|
|
18454
18595
|
analysisMode = "plan";
|
|
18596
|
+
recordFlip("mtime");
|
|
18455
18597
|
} else {
|
|
18456
18598
|
await passAndExit(run, mtimeSkip, "no-delta-since-last-review");
|
|
18457
18599
|
}
|
|
@@ -18462,8 +18604,9 @@ async function evidence(run) {
|
|
|
18462
18604
|
const allCheckable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...reviewable, ...securityFiles]));
|
|
18463
18605
|
const hashResult = checkContentHash(allCheckable, baselineSessionId);
|
|
18464
18606
|
if (hashResult.skip) {
|
|
18465
|
-
if (
|
|
18607
|
+
if (planWorthy) {
|
|
18466
18608
|
analysisMode = "plan";
|
|
18609
|
+
recordFlip("content-hash");
|
|
18467
18610
|
} else {
|
|
18468
18611
|
await passAndExit(run, hashResult.skip, "no-delta-since-last-review");
|
|
18469
18612
|
}
|
|
@@ -18525,8 +18668,9 @@ async function evidence(run) {
|
|
|
18525
18668
|
maxTotalBytes: parseInt(opts.maxTotalSize, 10)
|
|
18526
18669
|
});
|
|
18527
18670
|
if (codeDelta.files.length === 0 && staticResults.findings.length === 0) {
|
|
18528
|
-
if (
|
|
18671
|
+
if (planWorthy) {
|
|
18529
18672
|
analysisMode = "plan";
|
|
18673
|
+
recordFlip("empty-after-scoping");
|
|
18530
18674
|
} else {
|
|
18531
18675
|
await passAndExit(
|
|
18532
18676
|
run,
|
|
@@ -19370,6 +19514,8 @@ async function buildRequest(run) {
|
|
|
19370
19514
|
authored_since_verdict: memorySession ? foldDossier(memorySession.d).authored_all.filter((a) => a.hash_now !== a.hash_at_last_verdict).map((a) => a.path) : [],
|
|
19371
19515
|
unobserved: foldResult?.unobserved ?? [],
|
|
19372
19516
|
commands: foldResult?.commands ?? [],
|
|
19517
|
+
tools: foldResult?.tools ?? [],
|
|
19518
|
+
tasks: foldResult?.tasks ?? [],
|
|
19373
19519
|
unknown_types: foldResult?.unknownTypes ?? [],
|
|
19374
19520
|
coverage: foldResult?.coverage ?? { recordCounts: {}, totalRecords: 0, malformed: 0, subagentFiles: 0, subagentSkipped: 0, complete: false },
|
|
19375
19521
|
// INV-19, computed client-side and sent so a conservation failure is
|
|
@@ -19480,6 +19626,10 @@ async function buildRequest(run) {
|
|
|
19480
19626
|
intentContext.user_prompt = w4Task.goal;
|
|
19481
19627
|
logEvent("w4_issue_anchor", { issue: w4Task.number, via: w4Task.via });
|
|
19482
19628
|
}
|
|
19629
|
+
if (foldResult?.planApproval?.activeSinceLastPrompt && intentContext.user_prompt) {
|
|
19630
|
+
intentContext.plan_approved = true;
|
|
19631
|
+
logEvent("plan_approval_carried", { approvals: foldResult.planApproval.approvals });
|
|
19632
|
+
}
|
|
19483
19633
|
if (assistantResponse) {
|
|
19484
19634
|
const cap = analysisMode === "plan" ? MAX_ASSISTANT_RESPONSE_CHARS_PLAN : MAX_ASSISTANT_RESPONSE_CHARS_DEFAULT;
|
|
19485
19635
|
intentContext.assistant_response = assistantResponse.length > cap ? assistantResponse.slice(0, cap) : assistantResponse;
|
|
@@ -19743,6 +19893,11 @@ async function reconcile(run) {
|
|
|
19743
19893
|
decision,
|
|
19744
19894
|
branch: getCurrentBranch(),
|
|
19745
19895
|
watermarkSha: watermarkIsPartial ? null : watermarkHash,
|
|
19896
|
+
// The byte witness — the same "only honest definition of reviewed" the
|
|
19897
|
+
// coverage column uses. A finding on a path outside this set records no
|
|
19898
|
+
// statement (plan-mode prose anchored to unsent files must not become
|
|
19899
|
+
// "STILL OPEN … the tree is not clean").
|
|
19900
|
+
sentPaths,
|
|
19746
19901
|
findings: response.findings?.map((f) => ({
|
|
19747
19902
|
file: f.file,
|
|
19748
19903
|
line: f.line,
|
|
@@ -21996,8 +22151,8 @@ function registerTelemetryCommands(program2) {
|
|
|
21996
22151
|
}
|
|
21997
22152
|
|
|
21998
22153
|
// src/cli.ts
|
|
21999
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.29.4-experimental.
|
|
22000
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.29.4-experimental.
|
|
22154
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.29.4-experimental.7126d67").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) => {
|
|
22155
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.29.4-experimental.7126d67");
|
|
22001
22156
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
22002
22157
|
try {
|
|
22003
22158
|
await foldLegacyLocalCredential();
|
package/package.json
CHANGED