@codacy/verity-cli 0.29.4-experimental.5fcba03 → 0.29.4-experimental.6f2ede0
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 +543 -159
- 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`;
|
|
@@ -10502,6 +10502,7 @@ var GITHUB_APP_INSTALL_URL = `https://github.com/apps/${GITHUB_APP_SLUG}/install
|
|
|
10502
10502
|
function githubAppInstallUrl(accountId) {
|
|
10503
10503
|
return accountId != null ? `https://github.com/apps/${GITHUB_APP_SLUG}/installations/new/permissions?target_id=${accountId}` : GITHUB_APP_INSTALL_URL;
|
|
10504
10504
|
}
|
|
10505
|
+
var ADVISORY_EPISODE_FILE = `${VERITY_DIR}/.advisory-episode`;
|
|
10505
10506
|
|
|
10506
10507
|
// src/lib/output.ts
|
|
10507
10508
|
var RED = "\x1B[0;31m";
|
|
@@ -15060,8 +15061,10 @@ function recordVerdict(d, v) {
|
|
|
15060
15061
|
if (summary) appendEvent(d, { k: "goal_delivered", summary });
|
|
15061
15062
|
}
|
|
15062
15063
|
const lines = /* @__PURE__ */ new Map();
|
|
15064
|
+
const sent = new Set(v.sentPaths);
|
|
15063
15065
|
for (const f of v.findings) {
|
|
15064
15066
|
if (!f.file || typeof f.line !== "number" || !f.pattern_id) continue;
|
|
15067
|
+
if (!sent.has(f.file)) continue;
|
|
15065
15068
|
if (!lines.has(f.file)) {
|
|
15066
15069
|
try {
|
|
15067
15070
|
const abs = (0, import_node_path12.join)(root, f.file);
|
|
@@ -16717,7 +16720,7 @@ function formatRunEvidence(run, startedAt) {
|
|
|
16717
16720
|
const md = run.modeDecision;
|
|
16718
16721
|
if (md) {
|
|
16719
16722
|
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"}`);
|
|
16723
|
+
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
16724
|
} else {
|
|
16722
16725
|
out += row("mode", `? (this run stopped in ${run.phaseReached || "no phase"}, before the mode was decided)`);
|
|
16723
16726
|
}
|
|
@@ -16765,6 +16768,30 @@ function formatRunEvidence(run, startedAt) {
|
|
|
16765
16768
|
out += row("", `${cov.outsideRepo} authored path(s) refused as outside the repo`);
|
|
16766
16769
|
}
|
|
16767
16770
|
}
|
|
16771
|
+
if (run.foldResult?.tools?.length) {
|
|
16772
|
+
const shown = run.foldResult.tools.slice(0, 6).map((t) => {
|
|
16773
|
+
const outcome = t.failed > 0 ? `${t.failed} failed` : t.last_status === 0 ? "ok" : "?";
|
|
16774
|
+
const where = t.targets.length > 0 ? ` \u2192 ${t.targets.slice(0, 2).join(", ")}` : "";
|
|
16775
|
+
return `${t.runs}\xD7 ${t.name} (${outcome})${where}`;
|
|
16776
|
+
});
|
|
16777
|
+
const more = run.foldResult.tools.length > 6 ? ` \u2026 +${run.foldResult.tools.length - 6} more` : "";
|
|
16778
|
+
out += row("tools", shown.join(" \xB7 ") + more);
|
|
16779
|
+
if (run.foldResult.coverage.toolNamesDropped > 0) {
|
|
16780
|
+
out += row("", `\u26A0 ${run.foldResult.coverage.toolNamesDropped} tool name(s) refused by the cap`);
|
|
16781
|
+
}
|
|
16782
|
+
}
|
|
16783
|
+
if (run.foldResult?.tasks?.length) {
|
|
16784
|
+
const t = run.foldResult.tasks;
|
|
16785
|
+
const done2 = t.filter((x) => x.status === "completed").length;
|
|
16786
|
+
out += row("tasks", `${t.length} \xB7 ${done2} completed \xB7 ` + list(t.slice(0, 4).map((x) => `#${x.id} ${x.name} [${x.status}]`), 4));
|
|
16787
|
+
}
|
|
16788
|
+
if (run.specs?.length) {
|
|
16789
|
+
const readThisSession = new Set(run.actionSummary?.files_read ?? []);
|
|
16790
|
+
const labelled = run.specs.map(
|
|
16791
|
+
(s) => `${s.path}${readThisSession.has(s.path) ? " (read)" : " (positional)"}`
|
|
16792
|
+
);
|
|
16793
|
+
out += row("specs", `${run.specs.length} \xB7 ${list(labelled, 5)}`);
|
|
16794
|
+
}
|
|
16768
16795
|
if (run.staticResults.findings.length > 0) {
|
|
16769
16796
|
out += row("static", `${run.staticResults.findings.length} finding(s) from ${run.staticResults.summary.tools_run.join(", ") || "no tools"}`);
|
|
16770
16797
|
}
|
|
@@ -17122,6 +17149,39 @@ async function bootstrap(run) {
|
|
|
17122
17149
|
Object.assign(run, { actionSummary, assistantResponse, baseline, baselineSessionId, reachability, sessionId, stopReason, tokenResult, transcriptPath, turnId });
|
|
17123
17150
|
}
|
|
17124
17151
|
|
|
17152
|
+
// src/lib/self-scope.ts
|
|
17153
|
+
var LEGACY_GATE_SKILLS = /* @__PURE__ */ new Set([
|
|
17154
|
+
"gate-setup",
|
|
17155
|
+
"gate-analyze",
|
|
17156
|
+
"gate-review",
|
|
17157
|
+
"gate-status",
|
|
17158
|
+
"gate-feedback",
|
|
17159
|
+
"gate-insights",
|
|
17160
|
+
"gate-learn",
|
|
17161
|
+
"gate-memory",
|
|
17162
|
+
"gate-reflect"
|
|
17163
|
+
]);
|
|
17164
|
+
function isVerityOwned(path) {
|
|
17165
|
+
const segments = path.replace(/\\/g, "/").split("/");
|
|
17166
|
+
for (let i = 0; i < segments.length; i++) {
|
|
17167
|
+
const seg = segments[i];
|
|
17168
|
+
if (seg === ".verity" || seg === ".codacy") return true;
|
|
17169
|
+
if (i === segments.length - 1 && (seg === "VERITY.md" || seg === "GATE.md")) return true;
|
|
17170
|
+
if (seg === ".claude" && segments[i + 1] === "skills" && typeof segments[i + 2] === "string") {
|
|
17171
|
+
const skill = segments[i + 2];
|
|
17172
|
+
if (skill.startsWith("verity-") || LEGACY_GATE_SKILLS.has(skill)) return true;
|
|
17173
|
+
}
|
|
17174
|
+
if (seg === ".claude" && segments[i + 1] === "settings.json") return true;
|
|
17175
|
+
}
|
|
17176
|
+
return false;
|
|
17177
|
+
}
|
|
17178
|
+
function partitionVerityOwned(paths) {
|
|
17179
|
+
const kept = [];
|
|
17180
|
+
const owned = [];
|
|
17181
|
+
for (const p of paths) (isVerityOwned(p) ? owned : kept).push(p);
|
|
17182
|
+
return { kept, owned };
|
|
17183
|
+
}
|
|
17184
|
+
|
|
17125
17185
|
// src/lib/channel.ts
|
|
17126
17186
|
var MAX_AGENT_CONTEXT_CHARS = 1500;
|
|
17127
17187
|
var MAX_AGENT_ITEMS = 5;
|
|
@@ -17131,6 +17191,29 @@ function renderItem(label2, text, patternId, file, line) {
|
|
|
17131
17191
|
const id = patternId ? ` [${patternId}]` : "";
|
|
17132
17192
|
return `- ${label2}${text}${where}${id}`;
|
|
17133
17193
|
}
|
|
17194
|
+
function channelInputFrom(response, intentRepeat = 0, priorPendingFingerprints = []) {
|
|
17195
|
+
const metadata = response.metadata ?? {};
|
|
17196
|
+
const intent = response.intent_alignment ?? {};
|
|
17197
|
+
return {
|
|
17198
|
+
intentRepeat,
|
|
17199
|
+
priorPendingFingerprints,
|
|
17200
|
+
gateDecision: String(response.gate_decision ?? ""),
|
|
17201
|
+
findings: response.findings ?? [],
|
|
17202
|
+
pendingItems: response.pending_items ?? [],
|
|
17203
|
+
reviewStatus: metadata.review_status,
|
|
17204
|
+
coverage: metadata.coverage,
|
|
17205
|
+
intentVerdict: intent.verdict,
|
|
17206
|
+
intentGaps: intent.gaps
|
|
17207
|
+
};
|
|
17208
|
+
}
|
|
17209
|
+
function classifyChannelContent(input) {
|
|
17210
|
+
const refusal = input.reviewStatus === "not_reviewed" || input.reviewStatus === "no_authorship_evidence";
|
|
17211
|
+
const intentFlag = input.intentVerdict === "misaligned" || input.intentVerdict === "partial";
|
|
17212
|
+
const advisory = (input.findings ?? []).some((f) => f.scope !== "pre-existing") || (input.pendingItems ?? []).some(
|
|
17213
|
+
(p) => p.pattern_id !== "intent-misalignment" && !!(p.description ?? p.title ?? p.reason)
|
|
17214
|
+
);
|
|
17215
|
+
return { refusal, intentFlag, advisory };
|
|
17216
|
+
}
|
|
17134
17217
|
function buildAgentContext(input) {
|
|
17135
17218
|
const lines = [];
|
|
17136
17219
|
if (input.reviewStatus === "not_reviewed") {
|
|
@@ -17216,7 +17299,7 @@ function channelSilence(input) {
|
|
|
17216
17299
|
// src/lib/cli-version.ts
|
|
17217
17300
|
function cliVersion() {
|
|
17218
17301
|
try {
|
|
17219
|
-
return true ? "0.29.4-experimental.
|
|
17302
|
+
return true ? "0.29.4-experimental.6f2ede0" : "dev";
|
|
17220
17303
|
} catch {
|
|
17221
17304
|
return "dev";
|
|
17222
17305
|
}
|
|
@@ -17538,9 +17621,10 @@ async function scope(run) {
|
|
|
17538
17621
|
const { assistantResponse } = run;
|
|
17539
17622
|
const { files: allChanged, hasRecentCommitFiles } = getChangedFiles();
|
|
17540
17623
|
run.changedUniverse = allChanged;
|
|
17541
|
-
const
|
|
17542
|
-
const
|
|
17543
|
-
const
|
|
17624
|
+
const { kept: external } = partitionVerityOwned(allChanged);
|
|
17625
|
+
const analyzable = filterAnalyzable(external);
|
|
17626
|
+
const reviewable = filterReviewable(external);
|
|
17627
|
+
const securityFiles = filterSecurity(external);
|
|
17544
17628
|
const noFilesChanged = analyzable.length === 0 && reviewable.length === 0 && securityFiles.length === 0;
|
|
17545
17629
|
if (noFilesChanged && !assistantResponse) {
|
|
17546
17630
|
await passAndExit(run, "No analyzable files changed", "no-analyzable-files");
|
|
@@ -17567,18 +17651,26 @@ var SPEC_CANDIDATES = [
|
|
|
17567
17651
|
"docs/API.md",
|
|
17568
17652
|
"spec/ARCHITECTURE.md"
|
|
17569
17653
|
];
|
|
17570
|
-
|
|
17654
|
+
var DOC_EXT = /\.(md|mdx|ya?ml|txt|rst|adoc)$/i;
|
|
17655
|
+
var UNCONSULTED_FILE_BYTES = 10240;
|
|
17656
|
+
var UNCONSULTED_TOTAL_BYTES = 30720;
|
|
17657
|
+
function discoverSpecs(consulted = []) {
|
|
17571
17658
|
const result = [];
|
|
17572
17659
|
const seen = /* @__PURE__ */ new Set();
|
|
17573
17660
|
let totalBytes = 0;
|
|
17574
|
-
const
|
|
17661
|
+
const consultedDocs = new Set(
|
|
17662
|
+
consulted.filter((p) => DOC_EXT.test(p) && !p.startsWith("/") && !p.includes(".."))
|
|
17663
|
+
);
|
|
17664
|
+
const addSpec = (specPath, relevant = false) => {
|
|
17575
17665
|
if (result.length >= MAX_SPEC_FILES) return false;
|
|
17576
|
-
|
|
17666
|
+
const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
|
|
17667
|
+
if (totalBytes >= totalCap) return false;
|
|
17577
17668
|
if (seen.has(specPath)) return true;
|
|
17578
17669
|
if (!(0, import_node_fs21.existsSync)(specPath)) return true;
|
|
17579
17670
|
seen.add(specPath);
|
|
17580
|
-
const remaining =
|
|
17581
|
-
const
|
|
17671
|
+
const remaining = totalCap - totalBytes;
|
|
17672
|
+
const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
|
|
17673
|
+
const readBytes = Math.min(fileCap, remaining);
|
|
17582
17674
|
try {
|
|
17583
17675
|
const buf = Buffer.alloc(readBytes);
|
|
17584
17676
|
const fd = (0, import_node_fs21.openSync)(specPath, "r");
|
|
@@ -17592,6 +17684,9 @@ function discoverSpecs() {
|
|
|
17592
17684
|
}
|
|
17593
17685
|
return true;
|
|
17594
17686
|
};
|
|
17687
|
+
for (const doc of consultedDocs) {
|
|
17688
|
+
if (!addSpec(doc, true)) break;
|
|
17689
|
+
}
|
|
17595
17690
|
for (const candidate of SPEC_CANDIDATES) {
|
|
17596
17691
|
if (!addSpec(candidate)) break;
|
|
17597
17692
|
}
|
|
@@ -17662,7 +17757,7 @@ function discoverPlans() {
|
|
|
17662
17757
|
async function intentInputs(run) {
|
|
17663
17758
|
const { actionSummary, allForReview, assistantResponse, baseline, baselineSessionId } = run;
|
|
17664
17759
|
const conversation = await readAndClearConversationBuffer(baselineSessionId);
|
|
17665
|
-
const specs = discoverSpecs();
|
|
17760
|
+
const specs = discoverSpecs(actionSummary?.files_read ?? []);
|
|
17666
17761
|
const plans = discoverPlans();
|
|
17667
17762
|
const agentAuthoredCodeThisTurn = !!(actionSummary && (actionSummary.files_edited.length > 0 || actionSummary.files_created.length > 0));
|
|
17668
17763
|
const turnAuthoredCode = agentAuthoredCodeThisTurn || !!baseline && allForReview.some((f) => changedSinceBaseline(f, baseline));
|
|
@@ -18022,26 +18117,50 @@ function narrowToRecent(files, sessionId) {
|
|
|
18022
18117
|
});
|
|
18023
18118
|
return recent.length > 0 ? recent : files;
|
|
18024
18119
|
}
|
|
18025
|
-
function
|
|
18026
|
-
|
|
18120
|
+
function readIteration(currentCommit, _contentHash) {
|
|
18121
|
+
return Math.max(1, readBlockState(currentCommit).attempts);
|
|
18122
|
+
}
|
|
18123
|
+
var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
|
|
18124
|
+
function readBlockState(currentCommit, opts) {
|
|
18125
|
+
if (opts?.newUserPrompt) return NO_BLOCKS;
|
|
18126
|
+
if (!(0, import_node_fs22.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
|
|
18027
18127
|
try {
|
|
18028
18128
|
const stored = (0, import_node_fs22.readFileSync)(ITERATION_FILE, "utf-8").trim();
|
|
18029
|
-
const
|
|
18030
|
-
|
|
18031
|
-
|
|
18032
|
-
|
|
18033
|
-
|
|
18034
|
-
if (isNaN(iter)) return { iteration: 1, fingerprint: null };
|
|
18035
|
-
if (storedCommit !== currentCommit) return { iteration: 1, fingerprint: null };
|
|
18036
|
-
if (storedTimestamp > 0) {
|
|
18037
|
-
const elapsed = Math.floor(Date.now() / 1e3) - storedTimestamp;
|
|
18038
|
-
if (elapsed > 600) return { iteration: 1, fingerprint: null };
|
|
18039
|
-
}
|
|
18040
|
-
return { iteration: iter, fingerprint };
|
|
18129
|
+
const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
|
|
18130
|
+
if (!parsed) return NO_BLOCKS;
|
|
18131
|
+
if (parsed.commit !== currentCommit) return NO_BLOCKS;
|
|
18132
|
+
if (parsed.ts > 0 && Math.floor(Date.now() / 1e3) - parsed.ts > 600) return NO_BLOCKS;
|
|
18133
|
+
return { attempts: parsed.attempts, blocks: parsed.blocks, fingerprint: parsed.fingerprint };
|
|
18041
18134
|
} catch {
|
|
18042
|
-
return
|
|
18135
|
+
return NO_BLOCKS;
|
|
18043
18136
|
}
|
|
18044
18137
|
}
|
|
18138
|
+
function parseJsonState(raw) {
|
|
18139
|
+
const o = JSON.parse(raw);
|
|
18140
|
+
const attempts = typeof o.attempts === "number" ? o.attempts : NaN;
|
|
18141
|
+
if (isNaN(attempts)) return null;
|
|
18142
|
+
return {
|
|
18143
|
+
attempts,
|
|
18144
|
+
blocks: typeof o.blocks === "number" ? o.blocks : attempts,
|
|
18145
|
+
fingerprint: typeof o.fingerprint === "string" && o.fingerprint ? o.fingerprint : null,
|
|
18146
|
+
commit: typeof o.commit === "string" ? o.commit : "",
|
|
18147
|
+
ts: typeof o.ts === "number" ? o.ts : 0
|
|
18148
|
+
};
|
|
18149
|
+
}
|
|
18150
|
+
function parseLegacyState(raw) {
|
|
18151
|
+
const parts = raw.split(":");
|
|
18152
|
+
const n = parseInt(parts[0], 10);
|
|
18153
|
+
if (isNaN(n)) return null;
|
|
18154
|
+
return {
|
|
18155
|
+
attempts: n,
|
|
18156
|
+
// The old file has no separate block count; the old counter is the closest
|
|
18157
|
+
// honest answer, and it errs toward releasing sooner rather than later.
|
|
18158
|
+
blocks: n,
|
|
18159
|
+
fingerprint: parts.slice(3).join(":") || null,
|
|
18160
|
+
commit: parts[1] ?? "",
|
|
18161
|
+
ts: parseInt(parts[2] ?? "0", 10)
|
|
18162
|
+
};
|
|
18163
|
+
}
|
|
18045
18164
|
function findingsFingerprint(findings) {
|
|
18046
18165
|
const keys = findings.map((f) => `${String(f.pattern_id ?? "?")}|${String(f.file ?? "?")}`).filter((k) => k !== "?|?");
|
|
18047
18166
|
return [...new Set(keys)].sort().join(",");
|
|
@@ -18051,11 +18170,22 @@ function isSameProblem(previous, current) {
|
|
|
18051
18170
|
const prev = new Set(previous.split(","));
|
|
18052
18171
|
return current.split(",").some((k) => prev.has(k));
|
|
18053
18172
|
}
|
|
18054
|
-
function
|
|
18173
|
+
function writeBlockState(commit, state) {
|
|
18055
18174
|
(0, import_node_fs22.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18175
|
+
(0, import_node_fs22.writeFileSync)(
|
|
18176
|
+
ITERATION_FILE,
|
|
18177
|
+
JSON.stringify({
|
|
18178
|
+
v: 2,
|
|
18179
|
+
attempts: state.attempts,
|
|
18180
|
+
blocks: state.blocks,
|
|
18181
|
+
commit,
|
|
18182
|
+
ts: Math.floor(Date.now() / 1e3),
|
|
18183
|
+
fingerprint: state.fingerprint ?? void 0
|
|
18184
|
+
})
|
|
18185
|
+
);
|
|
18186
|
+
}
|
|
18187
|
+
function resetBlockState(commit) {
|
|
18188
|
+
writeBlockState(commit, { attempts: 0, blocks: 0, fingerprint: null });
|
|
18059
18189
|
}
|
|
18060
18190
|
|
|
18061
18191
|
// src/lib/fold.ts
|
|
@@ -18178,6 +18308,18 @@ function commandShape(cmd) {
|
|
|
18178
18308
|
return out.join(" ").slice(0, COMMAND_HEAD_CHARS);
|
|
18179
18309
|
}
|
|
18180
18310
|
var COMMAND_HEAD_CHARS = 80;
|
|
18311
|
+
var MAX_TOOL_NAMES = 64;
|
|
18312
|
+
var MAX_TOOL_TARGETS = 3;
|
|
18313
|
+
var MAX_TASKS = 64;
|
|
18314
|
+
var TASK_NAME_CHARS = 120;
|
|
18315
|
+
function toolTarget(name, input) {
|
|
18316
|
+
if (name === "Bash") return null;
|
|
18317
|
+
for (const key of ["file_path", "notebook_path", "path", "filePath"]) {
|
|
18318
|
+
const v = input[key];
|
|
18319
|
+
if (typeof v === "string" && v) return v.slice(0, 120);
|
|
18320
|
+
}
|
|
18321
|
+
return null;
|
|
18322
|
+
}
|
|
18181
18323
|
var rootCandidateCache = /* @__PURE__ */ new Map();
|
|
18182
18324
|
function candidateRoots(repoRoot2) {
|
|
18183
18325
|
const cached2 = rootCandidateCache.get(repoRoot2);
|
|
@@ -18208,15 +18350,20 @@ function toRepoRelative(path, repoRoot2) {
|
|
|
18208
18350
|
}
|
|
18209
18351
|
function isInsideRepo(path, repoRoot2) {
|
|
18210
18352
|
const p = path.replace(/\\/g, "/");
|
|
18211
|
-
if (!p
|
|
18353
|
+
if (!isAbsolutePath(p)) return true;
|
|
18212
18354
|
if (!repoRoot2) return true;
|
|
18213
18355
|
return candidateRoots(repoRoot2).some((root) => p === root || p.startsWith(root + "/"));
|
|
18214
18356
|
}
|
|
18357
|
+
function isAbsolutePath(p) {
|
|
18358
|
+
return p.startsWith("/") || /^[A-Za-z]:\//.test(p);
|
|
18359
|
+
}
|
|
18215
18360
|
function fold(transcriptPath, opts = {}) {
|
|
18216
18361
|
const result = {
|
|
18217
18362
|
authored: [],
|
|
18218
18363
|
unobserved: [],
|
|
18219
18364
|
commands: [],
|
|
18365
|
+
tools: [],
|
|
18366
|
+
tasks: [],
|
|
18220
18367
|
unknownTypes: [],
|
|
18221
18368
|
coverage: {
|
|
18222
18369
|
recordCounts: {},
|
|
@@ -18224,16 +18371,23 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18224
18371
|
malformed: 0,
|
|
18225
18372
|
subagentFiles: 0,
|
|
18226
18373
|
outsideRepo: 0,
|
|
18374
|
+
toolNamesDropped: 0,
|
|
18227
18375
|
dispatched: 0,
|
|
18228
18376
|
userMessages: 0,
|
|
18229
18377
|
subagentSkipped: 0,
|
|
18230
18378
|
compactions: 0,
|
|
18231
18379
|
complete: false
|
|
18232
|
-
}
|
|
18380
|
+
},
|
|
18381
|
+
planApproval: { approvals: 0, activeSinceLastPrompt: false }
|
|
18233
18382
|
};
|
|
18383
|
+
const flow = { seq: 0, lastPrompt: -1, lastApproval: -1, approvals: 0 };
|
|
18234
18384
|
const byPath = /* @__PURE__ */ new Map();
|
|
18235
18385
|
const commandStats = /* @__PURE__ */ new Map();
|
|
18236
18386
|
const pendingByToolUse = /* @__PURE__ */ new Map();
|
|
18387
|
+
const toolStats = /* @__PURE__ */ new Map();
|
|
18388
|
+
const pendingToolName = /* @__PURE__ */ new Map();
|
|
18389
|
+
const taskById = /* @__PURE__ */ new Map();
|
|
18390
|
+
const pendingTaskName = /* @__PURE__ */ new Map();
|
|
18237
18391
|
const unknown = /* @__PURE__ */ new Set();
|
|
18238
18392
|
const ingest = (raw, owner) => {
|
|
18239
18393
|
for (const line of raw.split("\n")) {
|
|
@@ -18252,8 +18406,12 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18252
18406
|
if (type === "system" && record.subtype === "compact_boundary") {
|
|
18253
18407
|
result.coverage.compactions++;
|
|
18254
18408
|
}
|
|
18255
|
-
if (type === "user" && hasUserText(record))
|
|
18256
|
-
|
|
18409
|
+
if (type === "user" && hasUserText(record)) {
|
|
18410
|
+
result.coverage.userMessages++;
|
|
18411
|
+
if (owner === "agent") flow.lastPrompt = flow.seq;
|
|
18412
|
+
}
|
|
18413
|
+
if (owner === "agent") flow.seq++;
|
|
18414
|
+
collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, toolStats, pendingToolName, taskById, pendingTaskName, opts.repoRoot, result.coverage, flow);
|
|
18257
18415
|
}
|
|
18258
18416
|
};
|
|
18259
18417
|
try {
|
|
@@ -18311,12 +18469,24 @@ function fold(transcriptPath, opts = {}) {
|
|
|
18311
18469
|
result.authored = [...byPath.values()].sort((a, b) => a.p.localeCompare(b.p));
|
|
18312
18470
|
result.unknownTypes = [...unknown].sort();
|
|
18313
18471
|
result.commands = [...commandStats.entries()].map(([cls, s]) => ({ class: cls, ...s })).sort((a, b) => a.class.localeCompare(b.class));
|
|
18472
|
+
result.tools = [...toolStats.entries()].map(([name, s]) => ({
|
|
18473
|
+
name,
|
|
18474
|
+
runs: s.runs,
|
|
18475
|
+
failed: s.failed,
|
|
18476
|
+
last_status: s.last_status,
|
|
18477
|
+
targets: [...s.targets].map((t) => toRepoRelative(t, opts.repoRoot)).sort()
|
|
18478
|
+
})).sort((a, b) => b.runs - a.runs || a.name.localeCompare(b.name));
|
|
18479
|
+
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
18480
|
const authoredPaths = new Set(result.authored.map((a) => a.p));
|
|
18315
18481
|
for (const raw of opts.changedFiles ?? []) {
|
|
18316
18482
|
const p = toRepoRelative(raw, opts.repoRoot);
|
|
18317
18483
|
if (!p || authoredPaths.has(p)) continue;
|
|
18318
18484
|
result.unobserved.push({ p, cause: classifyUnobserved(raw) });
|
|
18319
18485
|
}
|
|
18486
|
+
result.planApproval = {
|
|
18487
|
+
approvals: flow.approvals,
|
|
18488
|
+
activeSinceLastPrompt: flow.lastApproval >= 0 && flow.lastApproval > flow.lastPrompt
|
|
18489
|
+
};
|
|
18320
18490
|
return result;
|
|
18321
18491
|
}
|
|
18322
18492
|
function classifyUnobserved(path) {
|
|
@@ -18329,7 +18499,7 @@ function classifyUnobserved(path) {
|
|
|
18329
18499
|
if (/\.(png|jpg|jpeg|gif|pdf|zip|woff2?|ico|mp4)$/i.test(path)) return "binary";
|
|
18330
18500
|
return "no_edit_record";
|
|
18331
18501
|
}
|
|
18332
|
-
function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, repoRoot2, tally) {
|
|
18502
|
+
function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse, toolStats, pendingToolName, taskById, pendingTaskName, repoRoot2, tally, flow) {
|
|
18333
18503
|
const message = record.message;
|
|
18334
18504
|
const content = message?.content ?? record.content;
|
|
18335
18505
|
const blocks = Array.isArray(content) ? content : content && typeof content === "object" ? [content] : [];
|
|
@@ -18338,6 +18508,32 @@ function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse
|
|
|
18338
18508
|
if (blockType === "tool_use") {
|
|
18339
18509
|
const name = String(block.name ?? "");
|
|
18340
18510
|
const input = block.input ?? {};
|
|
18511
|
+
if (name && toolStats.size < MAX_TOOL_NAMES) {
|
|
18512
|
+
const prev = toolStats.get(name) ?? { runs: 0, failed: 0, last_status: null, targets: /* @__PURE__ */ new Set() };
|
|
18513
|
+
prev.targets = prev.targets ?? /* @__PURE__ */ new Set();
|
|
18514
|
+
if (prev.targets.size < MAX_TOOL_TARGETS) {
|
|
18515
|
+
const target = toolTarget(name, input);
|
|
18516
|
+
if (target) prev.targets.add(target);
|
|
18517
|
+
}
|
|
18518
|
+
toolStats.set(name, { runs: prev.runs + 1, failed: prev.failed, last_status: null, targets: prev.targets });
|
|
18519
|
+
const toolId = typeof block.id === "string" ? block.id : null;
|
|
18520
|
+
if (toolId) pendingToolName.set(toolId, name);
|
|
18521
|
+
} else if (name && tally) {
|
|
18522
|
+
tally.toolNamesDropped += 1;
|
|
18523
|
+
}
|
|
18524
|
+
if (name === "TaskCreate") {
|
|
18525
|
+
const subject = typeof input.subject === "string" ? input.subject : "";
|
|
18526
|
+
const taskId = typeof block.id === "string" ? block.id : null;
|
|
18527
|
+
if (subject && taskId) pendingTaskName.set(taskId, subject.slice(0, TASK_NAME_CHARS));
|
|
18528
|
+
}
|
|
18529
|
+
if (name === "TaskUpdate") {
|
|
18530
|
+
const id = typeof input.taskId === "string" ? input.taskId : "";
|
|
18531
|
+
const status = typeof input.status === "string" ? input.status : "";
|
|
18532
|
+
if (id && status) {
|
|
18533
|
+
const entry = taskById.get(id);
|
|
18534
|
+
taskById.set(id, { name: entry?.name ?? `#${id}`, status });
|
|
18535
|
+
}
|
|
18536
|
+
}
|
|
18341
18537
|
if (EDIT_TOOLS.has(name)) {
|
|
18342
18538
|
const rawPath = typeof input.notebook_path === "string" ? input.notebook_path : typeof input.file_path === "string" ? input.file_path : null;
|
|
18343
18539
|
if (rawPath && !isInsideRepo(rawPath, repoRoot2)) {
|
|
@@ -18377,6 +18573,38 @@ function collectFromRecord(record, owner, byPath, commandStats, pendingByToolUse
|
|
|
18377
18573
|
}
|
|
18378
18574
|
if (blockType === "tool_result") {
|
|
18379
18575
|
const id = typeof block.tool_use_id === "string" ? block.tool_use_id : null;
|
|
18576
|
+
const taskName = id ? pendingTaskName.get(id) : void 0;
|
|
18577
|
+
if (taskName) {
|
|
18578
|
+
pendingTaskName.delete(id);
|
|
18579
|
+
const body = typeof block.content === "string" ? block.content : "";
|
|
18580
|
+
const created = /Task #(\d+)/.exec(body);
|
|
18581
|
+
if (created && taskById.size < MAX_TASKS) {
|
|
18582
|
+
taskById.set(created[1], { name: taskName, status: taskById.get(created[1])?.status ?? "created" });
|
|
18583
|
+
}
|
|
18584
|
+
}
|
|
18585
|
+
const toolName = id ? pendingToolName.get(id) : void 0;
|
|
18586
|
+
if (toolName === "ExitPlanMode" && flow && block.is_error !== true) {
|
|
18587
|
+
const body = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c) => typeof c.text === "string" ? c.text : "").join(" ") : "";
|
|
18588
|
+
if (/approved your plan/i.test(body)) {
|
|
18589
|
+
flow.lastApproval = flow.seq;
|
|
18590
|
+
flow.approvals += 1;
|
|
18591
|
+
}
|
|
18592
|
+
}
|
|
18593
|
+
if (toolName) {
|
|
18594
|
+
pendingToolName.delete(id);
|
|
18595
|
+
const prevTool = toolStats.get(toolName);
|
|
18596
|
+
if (prevTool) {
|
|
18597
|
+
const failed = block.is_error === true;
|
|
18598
|
+
toolStats.set(toolName, {
|
|
18599
|
+
runs: prevTool.runs,
|
|
18600
|
+
failed: prevTool.failed + (failed ? 1 : 0),
|
|
18601
|
+
last_status: block.is_error === true ? 1 : block.is_error === false ? 0 : null,
|
|
18602
|
+
// Carried, not rebuilt: the targets were collected on the `tool_use`
|
|
18603
|
+
// side and dropping them here would empty the ledger on every result.
|
|
18604
|
+
targets: prevTool.targets
|
|
18605
|
+
});
|
|
18606
|
+
}
|
|
18607
|
+
}
|
|
18380
18608
|
const cls = id ? pendingByToolUse.get(id) : void 0;
|
|
18381
18609
|
if (!cls) continue;
|
|
18382
18610
|
pendingByToolUse.delete(id);
|
|
@@ -18419,8 +18647,13 @@ function checkConservation(changedFiles, result, repoRoot2) {
|
|
|
18419
18647
|
// src/commands/analyze/phases/06-evidence.ts
|
|
18420
18648
|
async function evidence(run) {
|
|
18421
18649
|
const { opts } = run;
|
|
18422
|
-
const { actionSummary, allForReview, analyzable, assistantResponse, authorshipIsObservable, baseline, baselineSessionId, hasRecentCommitFiles, reviewable, securityFiles, sessionAuthoredCode, transcriptPath } = run;
|
|
18650
|
+
const { actionSummary, allForReview, analyzable, assistantResponse, authorshipIsObservable, baseline, baselineSessionId, hasRecentCommitFiles, reviewable, securityFiles, sessionAuthoredCode, transcriptPath, turnAuthoredCode } = run;
|
|
18423
18651
|
let { analysisMode, earlyFold } = run;
|
|
18652
|
+
const recordFlip = (stage) => {
|
|
18653
|
+
if (run.modeDecision) run.modeDecision = { ...run.modeDecision, resolved: "plan", flip: stage };
|
|
18654
|
+
logEvent("mode_flipped", { stage, to: "plan" });
|
|
18655
|
+
};
|
|
18656
|
+
const planWorthy = !!assistantResponse && !turnAuthoredCode;
|
|
18424
18657
|
let staticResults = {
|
|
18425
18658
|
tool: "@codacy/analysis-cli",
|
|
18426
18659
|
findings: [],
|
|
@@ -18440,8 +18673,9 @@ async function evidence(run) {
|
|
|
18440
18673
|
const debounceSeconds = parseInt(opts.debounce, 10);
|
|
18441
18674
|
const debounceSkip = checkDebounce(debounceSeconds, baselineSessionId);
|
|
18442
18675
|
if (debounceSkip) {
|
|
18443
|
-
if (
|
|
18676
|
+
if (planWorthy) {
|
|
18444
18677
|
analysisMode = "plan";
|
|
18678
|
+
recordFlip("debounce");
|
|
18445
18679
|
} else {
|
|
18446
18680
|
await passAndExit(run, debounceSkip, "debounce");
|
|
18447
18681
|
}
|
|
@@ -18450,8 +18684,9 @@ async function evidence(run) {
|
|
|
18450
18684
|
const allCheckable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...reviewable, ...securityFiles]));
|
|
18451
18685
|
const mtimeSkip = checkMtime(allCheckable, hasRecentCommitFiles, baselineSessionId);
|
|
18452
18686
|
if (mtimeSkip) {
|
|
18453
|
-
if (
|
|
18687
|
+
if (planWorthy) {
|
|
18454
18688
|
analysisMode = "plan";
|
|
18689
|
+
recordFlip("mtime");
|
|
18455
18690
|
} else {
|
|
18456
18691
|
await passAndExit(run, mtimeSkip, "no-delta-since-last-review");
|
|
18457
18692
|
}
|
|
@@ -18462,8 +18697,9 @@ async function evidence(run) {
|
|
|
18462
18697
|
const allCheckable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...reviewable, ...securityFiles]));
|
|
18463
18698
|
const hashResult = checkContentHash(allCheckable, baselineSessionId);
|
|
18464
18699
|
if (hashResult.skip) {
|
|
18465
|
-
if (
|
|
18700
|
+
if (planWorthy) {
|
|
18466
18701
|
analysisMode = "plan";
|
|
18702
|
+
recordFlip("content-hash");
|
|
18467
18703
|
} else {
|
|
18468
18704
|
await passAndExit(run, hashResult.skip, "no-delta-since-last-review");
|
|
18469
18705
|
}
|
|
@@ -18525,8 +18761,9 @@ async function evidence(run) {
|
|
|
18525
18761
|
maxTotalBytes: parseInt(opts.maxTotalSize, 10)
|
|
18526
18762
|
});
|
|
18527
18763
|
if (codeDelta.files.length === 0 && staticResults.findings.length === 0) {
|
|
18528
|
-
if (
|
|
18764
|
+
if (planWorthy) {
|
|
18529
18765
|
analysisMode = "plan";
|
|
18766
|
+
recordFlip("empty-after-scoping");
|
|
18530
18767
|
} else {
|
|
18531
18768
|
await passAndExit(
|
|
18532
18769
|
run,
|
|
@@ -18546,13 +18783,13 @@ async function evidence(run) {
|
|
|
18546
18783
|
snapshotResult = generateSnapshotDiffs(codeDelta.files);
|
|
18547
18784
|
}
|
|
18548
18785
|
currentCommit = getCurrentCommit();
|
|
18549
|
-
iteration =
|
|
18786
|
+
iteration = readIteration(currentCommit);
|
|
18550
18787
|
}
|
|
18551
18788
|
}
|
|
18552
18789
|
if (analysisMode === "plan") {
|
|
18553
18790
|
recordAnalysisStart();
|
|
18554
18791
|
currentCommit = getCurrentCommit();
|
|
18555
|
-
iteration =
|
|
18792
|
+
iteration = readIteration(currentCommit);
|
|
18556
18793
|
}
|
|
18557
18794
|
Object.assign(run, { analysisMode, codeDelta, contentHash, currentCommit, earlyFold, iteration, snapshotResult, staticResults });
|
|
18558
18795
|
}
|
|
@@ -18648,7 +18885,8 @@ function gatherContextFiles(contextPaths, deltaFiles) {
|
|
|
18648
18885
|
// src/commands/analyze/phases/07-context-files.ts
|
|
18649
18886
|
async function contextFiles(run) {
|
|
18650
18887
|
const { codeDelta, contextFilePaths } = run;
|
|
18651
|
-
const
|
|
18888
|
+
const { kept: externalContext } = partitionVerityOwned(contextFilePaths ?? []);
|
|
18889
|
+
const contextFiles2 = gatherContextFiles(externalContext, codeDelta.files);
|
|
18652
18890
|
for (const f of codeDelta.files) {
|
|
18653
18891
|
f.role = "delta";
|
|
18654
18892
|
}
|
|
@@ -19218,6 +19456,54 @@ async function workingMemory(run) {
|
|
|
19218
19456
|
Object.assign(run, { incrementReport, memory, memorySession, reachability });
|
|
19219
19457
|
}
|
|
19220
19458
|
|
|
19459
|
+
// src/lib/note-budget.ts
|
|
19460
|
+
var import_node_fs28 = require("node:fs");
|
|
19461
|
+
var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
|
|
19462
|
+
var EPISODE_STALE_SECONDS = 30 * 60;
|
|
19463
|
+
var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
|
|
19464
|
+
function resolveEpisode(prev, signals) {
|
|
19465
|
+
if (!prev) return { ...FRESH, tasksCompleted: signals.tasksCompleted, ts: signals.now };
|
|
19466
|
+
if (signals.humanSpoke) return { ...FRESH, tasksCompleted: signals.tasksCompleted, ts: signals.now };
|
|
19467
|
+
if (signals.rawFail) return { ...FRESH, tasksCompleted: signals.tasksCompleted, ts: signals.now };
|
|
19468
|
+
if (prev.tasksCompleted !== signals.tasksCompleted) {
|
|
19469
|
+
return { ...FRESH, tasksCompleted: signals.tasksCompleted, ts: signals.now };
|
|
19470
|
+
}
|
|
19471
|
+
if (prev.ts > 0 && signals.now - prev.ts > EPISODE_STALE_SECONDS) {
|
|
19472
|
+
return { ...FRESH, tasksCompleted: signals.tasksCompleted, ts: signals.now };
|
|
19473
|
+
}
|
|
19474
|
+
return prev;
|
|
19475
|
+
}
|
|
19476
|
+
function advisoryBudgetSpent(episode, rawDecision) {
|
|
19477
|
+
const budget = ADVISORY_BUDGET[rawDecision] ?? ADVISORY_BUDGET.WARN;
|
|
19478
|
+
return episode.delivered >= budget;
|
|
19479
|
+
}
|
|
19480
|
+
function readAdvisoryEpisode(sessionId) {
|
|
19481
|
+
const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
|
|
19482
|
+
if (!(0, import_node_fs28.existsSync)(file)) return null;
|
|
19483
|
+
try {
|
|
19484
|
+
const o = JSON.parse((0, import_node_fs28.readFileSync)(file, "utf-8")) ?? {};
|
|
19485
|
+
const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
|
|
19486
|
+
if (isNaN(delivered)) return null;
|
|
19487
|
+
return {
|
|
19488
|
+
delivered,
|
|
19489
|
+
tasksCompleted: typeof o.tasksCompleted === "number" ? o.tasksCompleted : 0,
|
|
19490
|
+
ts: typeof o.ts === "number" ? o.ts : 0
|
|
19491
|
+
};
|
|
19492
|
+
} catch {
|
|
19493
|
+
return null;
|
|
19494
|
+
}
|
|
19495
|
+
}
|
|
19496
|
+
function writeAdvisoryEpisode(episode, sessionId) {
|
|
19497
|
+
try {
|
|
19498
|
+
(0, import_node_fs28.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
19499
|
+
(0, import_node_fs28.writeFileSync)(
|
|
19500
|
+
scopedFile(ADVISORY_EPISODE_FILE, sessionId),
|
|
19501
|
+
JSON.stringify({ v: 1, ...episode })
|
|
19502
|
+
);
|
|
19503
|
+
} catch {
|
|
19504
|
+
}
|
|
19505
|
+
}
|
|
19506
|
+
|
|
19221
19507
|
// src/lib/run-mode.ts
|
|
19222
19508
|
function parseAutonomousEnv(raw) {
|
|
19223
19509
|
if (raw === void 0) return void 0;
|
|
@@ -19311,7 +19597,13 @@ async function buildRequest(run) {
|
|
|
19311
19597
|
excluded_by_reason: excludedByReason,
|
|
19312
19598
|
// was the transcript itself truncated? The 256 KB window means "this turn"
|
|
19313
19599
|
// can quietly mean "the last 256 KB of it".
|
|
19314
|
-
transcript_windowed: actionSummary?.transcript_windowed ?? null
|
|
19600
|
+
transcript_windowed: actionSummary?.transcript_windowed ?? null,
|
|
19601
|
+
// The advisory budget's fleet counter-metric (note-budget.ts): deliveries in
|
|
19602
|
+
// the episode as of the PREVIOUS turn — this runs before phase 13 updates
|
|
19603
|
+
// the state, so the number is one turn lagged by construction. The
|
|
19604
|
+
// degenerate win for the budget is a dead channel that looks like clean
|
|
19605
|
+
// code; this is what makes "did delivery rate collapse" a query.
|
|
19606
|
+
advisory_delivered_prior: readAdvisoryEpisode(run.baselineSessionId)?.delivered ?? 0
|
|
19315
19607
|
};
|
|
19316
19608
|
const requestBody = {
|
|
19317
19609
|
coverage_telemetry: coverageTelemetry,
|
|
@@ -19370,6 +19662,8 @@ async function buildRequest(run) {
|
|
|
19370
19662
|
authored_since_verdict: memorySession ? foldDossier(memorySession.d).authored_all.filter((a) => a.hash_now !== a.hash_at_last_verdict).map((a) => a.path) : [],
|
|
19371
19663
|
unobserved: foldResult?.unobserved ?? [],
|
|
19372
19664
|
commands: foldResult?.commands ?? [],
|
|
19665
|
+
tools: foldResult?.tools ?? [],
|
|
19666
|
+
tasks: foldResult?.tasks ?? [],
|
|
19373
19667
|
unknown_types: foldResult?.unknownTypes ?? [],
|
|
19374
19668
|
coverage: foldResult?.coverage ?? { recordCounts: {}, totalRecords: 0, malformed: 0, subagentFiles: 0, subagentSkipped: 0, complete: false },
|
|
19375
19669
|
// INV-19, computed client-side and sent so a conservation failure is
|
|
@@ -19448,7 +19742,8 @@ async function buildRequest(run) {
|
|
|
19448
19742
|
}
|
|
19449
19743
|
const noHumanPrompt = (conversation?.prompts?.length ?? 0) === 0;
|
|
19450
19744
|
const w4Task = noHumanPrompt && isExplicitlyAutonomous() ? resolveTaskContext() : null;
|
|
19451
|
-
const
|
|
19745
|
+
const planApprovalActive = foldResult?.planApproval?.activeSinceLastPrompt === true;
|
|
19746
|
+
const hasIntent = (conversation?.prompts?.length ?? 0) > 0 || specs.length > 0 || plans.length > 0 || !!assistantResponse || !!w4Task || planApprovalActive;
|
|
19452
19747
|
if (hasIntent) {
|
|
19453
19748
|
const intentContext = {};
|
|
19454
19749
|
if (conversation && conversation.prompts.length > 0) {
|
|
@@ -19480,6 +19775,10 @@ async function buildRequest(run) {
|
|
|
19480
19775
|
intentContext.user_prompt = w4Task.goal;
|
|
19481
19776
|
logEvent("w4_issue_anchor", { issue: w4Task.number, via: w4Task.via });
|
|
19482
19777
|
}
|
|
19778
|
+
if (planApprovalActive) {
|
|
19779
|
+
intentContext.plan_approved = true;
|
|
19780
|
+
logEvent("plan_approval_carried", { approvals: foldResult.planApproval.approvals });
|
|
19781
|
+
}
|
|
19483
19782
|
if (assistantResponse) {
|
|
19484
19783
|
const cap = analysisMode === "plan" ? MAX_ASSISTANT_RESPONSE_CHARS_PLAN : MAX_ASSISTANT_RESPONSE_CHARS_DEFAULT;
|
|
19485
19784
|
intentContext.assistant_response = assistantResponse.length > cap ? assistantResponse.slice(0, cap) : assistantResponse;
|
|
@@ -19499,14 +19798,14 @@ async function buildRequest(run) {
|
|
|
19499
19798
|
}
|
|
19500
19799
|
|
|
19501
19800
|
// src/lib/offline.ts
|
|
19502
|
-
var
|
|
19801
|
+
var import_node_fs29 = require("node:fs");
|
|
19503
19802
|
var import_node_crypto11 = require("node:crypto");
|
|
19504
19803
|
function cacheRequest(body) {
|
|
19505
19804
|
try {
|
|
19506
|
-
(0,
|
|
19805
|
+
(0, import_node_fs29.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
19507
19806
|
const suffix = (0, import_node_crypto11.randomBytes)(4).toString("hex");
|
|
19508
19807
|
const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
|
|
19509
|
-
(0,
|
|
19808
|
+
(0, import_node_fs29.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body)));
|
|
19510
19809
|
} catch {
|
|
19511
19810
|
}
|
|
19512
19811
|
}
|
|
@@ -19625,10 +19924,10 @@ async function transmit(run) {
|
|
|
19625
19924
|
}
|
|
19626
19925
|
|
|
19627
19926
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
19628
|
-
var
|
|
19927
|
+
var import_node_fs30 = require("node:fs");
|
|
19629
19928
|
var import_node_path23 = require("node:path");
|
|
19630
19929
|
async function reconcile(run) {
|
|
19631
|
-
const { actionSummary, allChanged, analyzable, baseline, codeDelta, contentHash, conversation, decision, memory, memorySession, response, reviewable, securityFiles, turnId } = run;
|
|
19930
|
+
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory, memorySession, response, reviewable, securityFiles, turnId } = run;
|
|
19632
19931
|
const sentPaths = codeDelta.files.map((f) => f.path);
|
|
19633
19932
|
let openElsewhere = [];
|
|
19634
19933
|
if (memorySession) {
|
|
@@ -19636,7 +19935,7 @@ async function reconcile(run) {
|
|
|
19636
19935
|
const st = foldDossier(memorySession.d);
|
|
19637
19936
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line) => {
|
|
19638
19937
|
try {
|
|
19639
|
-
const src = (0,
|
|
19938
|
+
const src = (0, import_node_fs30.readFileSync)((0, import_node_path23.join)(repoRoot(), file), "utf8").split("\n");
|
|
19640
19939
|
const at = src[line - 1];
|
|
19641
19940
|
return at === void 0 ? null : lineSha(at);
|
|
19642
19941
|
} catch {
|
|
@@ -19646,6 +19945,7 @@ async function reconcile(run) {
|
|
|
19646
19945
|
} catch {
|
|
19647
19946
|
}
|
|
19648
19947
|
}
|
|
19948
|
+
const { kept: externalChanged, owned: verityOwned } = partitionVerityOwned(allChanged);
|
|
19649
19949
|
const reviewCoverage = {
|
|
19650
19950
|
reviewed: sentPaths,
|
|
19651
19951
|
// Declared drops from the stages that DO report themselves today. The other
|
|
@@ -19687,11 +19987,20 @@ async function reconcile(run) {
|
|
|
19687
19987
|
stage: "baseline-scoping",
|
|
19688
19988
|
kind: "policy"
|
|
19689
19989
|
})),
|
|
19990
|
+
// ⚠ VERITY'S OWN FILES, named as such — not laundered into the
|
|
19991
|
+
// extension bucket below, where "we do not review our own installer's
|
|
19992
|
+
// dirt" would read as "a changed README". See self-scope.ts.
|
|
19993
|
+
...verityOwned.map((path) => ({
|
|
19994
|
+
path,
|
|
19995
|
+
reason: "verity-owned",
|
|
19996
|
+
stage: "self-scope",
|
|
19997
|
+
kind: "policy"
|
|
19998
|
+
})),
|
|
19690
19999
|
// The extension allowlist. POLICY: a changed README was never going to be
|
|
19691
20000
|
// reviewed, and calling that a coverage gap would downgrade nearly every
|
|
19692
20001
|
// PASS to WARN until WARN meant nothing. Recorded so the ledger balances and
|
|
19693
20002
|
// so "what did Verity ignore entirely" is answerable.
|
|
19694
|
-
...
|
|
20003
|
+
...externalChanged.filter((p) => !analyzable.includes(p) && !reviewable.includes(p) && !securityFiles.includes(p)).map((path) => ({
|
|
19695
20004
|
path,
|
|
19696
20005
|
reason: "not-a-reviewed-file-type",
|
|
19697
20006
|
stage: "extension-allowlist",
|
|
@@ -19728,6 +20037,29 @@ async function reconcile(run) {
|
|
|
19728
20037
|
decision
|
|
19729
20038
|
});
|
|
19730
20039
|
}
|
|
20040
|
+
const episodeSignals = {
|
|
20041
|
+
humanSpoke: (conversation?.prompts?.length ?? 0) > 0,
|
|
20042
|
+
rawFail: decision === "FAIL",
|
|
20043
|
+
tasksCompleted: (foldResult?.tasks ?? []).filter((t) => t.status === "completed").length,
|
|
20044
|
+
now: Math.floor(Date.now() / 1e3)
|
|
20045
|
+
};
|
|
20046
|
+
let episode = resolveEpisode(readAdvisoryEpisode(baselineSessionId), episodeSignals);
|
|
20047
|
+
const contentClass = classifyChannelContent(channelInputFrom(response));
|
|
20048
|
+
const wouldCarryAdvisory = contentClass.advisory || openElsewhere.length > 0;
|
|
20049
|
+
if (decision !== "FAIL" && !silenced && wouldCarryAdvisory && !contentClass.refusal && !contentClass.intentFlag && advisoryBudgetSpent(episode, decision)) {
|
|
20050
|
+
silenced = "note-budget";
|
|
20051
|
+
logEvent("channel_silenced", {
|
|
20052
|
+
reason: silenced,
|
|
20053
|
+
run_id: response.run_id ?? turnId,
|
|
20054
|
+
decision,
|
|
20055
|
+
episode_delivered: episode.delivered
|
|
20056
|
+
});
|
|
20057
|
+
}
|
|
20058
|
+
const deliveringAdvisory = decision !== "FAIL" && !silenced && wouldCarryAdvisory;
|
|
20059
|
+
writeAdvisoryEpisode(
|
|
20060
|
+
{ ...episode, delivered: episode.delivered + (deliveringAdvisory ? 1 : 0), ts: episodeSignals.now },
|
|
20061
|
+
baselineSessionId
|
|
20062
|
+
);
|
|
19731
20063
|
let intentRepeatCount = 0;
|
|
19732
20064
|
const priorPendingFingerprints = memorySession ? (() => {
|
|
19733
20065
|
try {
|
|
@@ -19743,6 +20075,11 @@ async function reconcile(run) {
|
|
|
19743
20075
|
decision,
|
|
19744
20076
|
branch: getCurrentBranch(),
|
|
19745
20077
|
watermarkSha: watermarkIsPartial ? null : watermarkHash,
|
|
20078
|
+
// The byte witness — the same "only honest definition of reviewed" the
|
|
20079
|
+
// coverage column uses. A finding on a path outside this set records no
|
|
20080
|
+
// statement (plan-mode prose anchored to unsent files must not become
|
|
20081
|
+
// "STILL OPEN … the tree is not clean").
|
|
20082
|
+
sentPaths,
|
|
19746
20083
|
findings: response.findings?.map((f) => ({
|
|
19747
20084
|
file: f.file,
|
|
19748
20085
|
line: f.line,
|
|
@@ -19809,6 +20146,39 @@ ${YELLOW2}${note}${NC2}
|
|
|
19809
20146
|
return exit(0);
|
|
19810
20147
|
}
|
|
19811
20148
|
|
|
20149
|
+
// src/lib/may-block.ts
|
|
20150
|
+
var HARD_BLOCK_CEILING = 5;
|
|
20151
|
+
function mayBlock(input) {
|
|
20152
|
+
const ceiling = input.ceiling ?? HARD_BLOCK_CEILING;
|
|
20153
|
+
if (input.reviewedFileCount === 0 && input.staticFindingCount === 0) {
|
|
20154
|
+
return { block: false, release: "no-code-reviewed" };
|
|
20155
|
+
}
|
|
20156
|
+
if (input.cycleCutFired) {
|
|
20157
|
+
return { block: false, release: "nothing-moved" };
|
|
20158
|
+
}
|
|
20159
|
+
if (input.attempts > input.maxIterations) {
|
|
20160
|
+
return { block: false, release: "same-problem-cap" };
|
|
20161
|
+
}
|
|
20162
|
+
if (input.blocks > ceiling) {
|
|
20163
|
+
return { block: false, release: "block-ceiling" };
|
|
20164
|
+
}
|
|
20165
|
+
return { block: true, release: null };
|
|
20166
|
+
}
|
|
20167
|
+
function describeRelease(release, input) {
|
|
20168
|
+
const ceiling = input.ceiling ?? HARD_BLOCK_CEILING;
|
|
20169
|
+
const open = input.findingCount > 0 ? `${input.findingCount} finding(s) remain OPEN and were NOT fixed. Human review required before deploying.` : "Human review required before deploying.";
|
|
20170
|
+
switch (release) {
|
|
20171
|
+
case "no-code-reviewed":
|
|
20172
|
+
return `Verity: WARN \u2014 NOT BLOCKING: no code was reviewed on this turn, so there is nothing here to fix. Reported as advice instead. ${open}`;
|
|
20173
|
+
case "nothing-moved":
|
|
20174
|
+
return `Verity: WARN \u2014 NOT BLOCKING: nothing has changed since the last verdict, so re-raising it cannot move anything forward. ${open}`;
|
|
20175
|
+
case "same-problem-cap":
|
|
20176
|
+
return `Verity: WARN \u2014 self-healing limit (${input.maxIterations}) reached on the same finding. NO LONGER BLOCKING, but ${open}`;
|
|
20177
|
+
case "block-ceiling":
|
|
20178
|
+
return `Verity: WARN \u2014 ${ceiling} consecutive blocking verdicts reached; releasing the block so this cannot loop. ${open}`;
|
|
20179
|
+
}
|
|
20180
|
+
}
|
|
20181
|
+
|
|
19812
20182
|
// src/lib/remediation-guard.ts
|
|
19813
20183
|
var TOOL_CONFIG_PATTERNS = [
|
|
19814
20184
|
/(^|\/)\.codacy\//,
|
|
@@ -19851,19 +20221,7 @@ function screenRemediation(fix, findingFile) {
|
|
|
19851
20221
|
|
|
19852
20222
|
// src/commands/analyze/phases/14-render.ts
|
|
19853
20223
|
function agentContextFor(response, intentRepeat = 0, priorPendingFingerprints = []) {
|
|
19854
|
-
|
|
19855
|
-
const intent = response.intent_alignment ?? {};
|
|
19856
|
-
return buildAgentContext({
|
|
19857
|
-
intentRepeat,
|
|
19858
|
-
priorPendingFingerprints,
|
|
19859
|
-
gateDecision: String(response.gate_decision ?? ""),
|
|
19860
|
-
findings: response.findings ?? [],
|
|
19861
|
-
pendingItems: response.pending_items ?? [],
|
|
19862
|
-
reviewStatus: metadata.review_status,
|
|
19863
|
-
coverage: metadata.coverage,
|
|
19864
|
-
intentVerdict: intent.verdict,
|
|
19865
|
-
intentGaps: intent.gaps
|
|
19866
|
-
});
|
|
20224
|
+
return buildAgentContext(channelInputFrom(response, intentRepeat, priorPendingFingerprints));
|
|
19867
20225
|
}
|
|
19868
20226
|
async function render(run) {
|
|
19869
20227
|
const { opts, globals } = run;
|
|
@@ -19957,38 +20315,63 @@ async function render(run) {
|
|
|
19957
20315
|
reverify_by: response.reverify_by
|
|
19958
20316
|
});
|
|
19959
20317
|
const grantNudge = grantWarning ? ` \u26A0\uFE0F ${grantWarning}` : "";
|
|
19960
|
-
let
|
|
20318
|
+
let release = null;
|
|
19961
20319
|
let effectiveDecision = decision;
|
|
19962
20320
|
if (decision === "FAIL") {
|
|
19963
|
-
const
|
|
20321
|
+
const findings = response.findings ?? [];
|
|
20322
|
+
const blocking = findings.filter((f) => {
|
|
19964
20323
|
const sev = String(f.severity ?? "").toLowerCase();
|
|
19965
20324
|
return sev === "critical" || sev === "high";
|
|
19966
20325
|
});
|
|
19967
20326
|
const fingerprint = findingsFingerprint(blocking);
|
|
19968
|
-
const prior =
|
|
20327
|
+
const prior = readBlockState(currentCommit, {
|
|
20328
|
+
newUserPrompt: (conversation?.prompts?.length ?? 0) > 0
|
|
20329
|
+
});
|
|
19969
20330
|
const sameProblem = isSameProblem(prior.fingerprint, fingerprint);
|
|
19970
|
-
const nextIteration = sameProblem ? prior.iteration + 1 : 1;
|
|
19971
20331
|
const maxIterations = parseInt(opts.maxIterations, 10);
|
|
19972
|
-
|
|
19973
|
-
|
|
19974
|
-
|
|
19975
|
-
|
|
20332
|
+
const attempts = sameProblem ? prior.attempts + 1 : 1;
|
|
20333
|
+
const blocks = prior.blocks + 1;
|
|
20334
|
+
const decisionNow = mayBlock({
|
|
20335
|
+
reviewedFileCount: codeDelta.files.length,
|
|
20336
|
+
staticFindingCount: run.staticResults?.findings?.length ?? 0,
|
|
20337
|
+
cycleCutFired: silenced !== null,
|
|
20338
|
+
attempts,
|
|
20339
|
+
blocks,
|
|
20340
|
+
maxIterations
|
|
20341
|
+
});
|
|
20342
|
+
if (decisionNow.block) {
|
|
20343
|
+
writeBlockState(currentCommit, { attempts, blocks, fingerprint });
|
|
20344
|
+
iteration = attempts;
|
|
20345
|
+
} else {
|
|
20346
|
+
release = decisionNow.release;
|
|
19976
20347
|
effectiveDecision = "WARN";
|
|
19977
|
-
logEvent("
|
|
20348
|
+
logEvent("block_released", {
|
|
20349
|
+
reason: release,
|
|
20350
|
+
attempts,
|
|
20351
|
+
blocks,
|
|
20352
|
+
reviewed_files: codeDelta.files.length,
|
|
20353
|
+
cycle_cut: silenced,
|
|
20354
|
+
fingerprint
|
|
20355
|
+
});
|
|
19978
20356
|
}
|
|
19979
20357
|
}
|
|
19980
|
-
if (
|
|
20358
|
+
if (release) {
|
|
19981
20359
|
const findings = response.findings ?? [];
|
|
19982
20360
|
const lines = findings.slice(0, 5).map((f) => ` [${String(f.severity ?? "?").toUpperCase()}] ${String(f.title ?? f.message ?? "")} (${String(f.file ?? "?")}:${String(f.line ?? "?")})`);
|
|
20361
|
+
const summary = describeRelease(release, {
|
|
20362
|
+
findingCount: findings.length,
|
|
20363
|
+
maxIterations: parseInt(opts.maxIterations, 10)
|
|
20364
|
+
});
|
|
19983
20365
|
emitVerdict({
|
|
19984
20366
|
proposed: "WARN",
|
|
19985
20367
|
changed: run.changedUniverse,
|
|
19986
20368
|
coverage: reviewCoverage,
|
|
19987
|
-
userSummary:
|
|
19988
|
-
${lines.join("\n")}
|
|
20369
|
+
userSummary: lines.length > 0 ? `${summary}
|
|
20370
|
+
${lines.join("\n")}` : summary,
|
|
19989
20371
|
agentContext: null,
|
|
19990
20372
|
silenced: true
|
|
19991
20373
|
});
|
|
20374
|
+
return;
|
|
19992
20375
|
}
|
|
19993
20376
|
switch (effectiveDecision) {
|
|
19994
20377
|
case "FAIL": {
|
|
@@ -20087,7 +20470,7 @@ ${YELLOW}${grantNudge.trim()}${NC}
|
|
|
20087
20470
|
break;
|
|
20088
20471
|
}
|
|
20089
20472
|
case "PASS": {
|
|
20090
|
-
|
|
20473
|
+
resetBlockState(currentCommit);
|
|
20091
20474
|
if (watermarkHash) recordPassHash(watermarkHash, baselineSessionId);
|
|
20092
20475
|
if (!watermarkIsPartial && currentCommit && currentCommit !== "no-git") writeBaselineSha(currentCommit);
|
|
20093
20476
|
let userSummary = response.user_summary ?? "Verity: PASS";
|
|
@@ -20108,6 +20491,7 @@ ${YELLOW}${grantNudge.trim()}${NC}
|
|
|
20108
20491
|
break;
|
|
20109
20492
|
}
|
|
20110
20493
|
case "WARN": {
|
|
20494
|
+
if (decision !== "FAIL") resetBlockState(currentCommit);
|
|
20111
20495
|
if (watermarkHash) recordPassHash(watermarkHash, baselineSessionId);
|
|
20112
20496
|
if (!watermarkIsPartial && currentCommit && currentCommit !== "no-git") writeBaselineSha(currentCommit);
|
|
20113
20497
|
let userSummary = response.user_summary ?? "Verity: WARN";
|
|
@@ -20206,7 +20590,7 @@ async function runAnalyze(opts, globals) {
|
|
|
20206
20590
|
}
|
|
20207
20591
|
|
|
20208
20592
|
// src/commands/baseline.ts
|
|
20209
|
-
var
|
|
20593
|
+
var import_node_fs31 = require("node:fs");
|
|
20210
20594
|
function registerBaselineCommands(program2) {
|
|
20211
20595
|
const baseline = program2.command("baseline").description("Manage the task-start working-tree baseline");
|
|
20212
20596
|
baseline.command("capture").description("Snapshot the working tree at task start (used by SessionStart hook)").option("--session-id <id>", "Session id (overrides any value from stdin)").option("--source <source>", "Lifecycle hint: startup|resume|clear|compact").action(async (opts) => {
|
|
@@ -20215,7 +20599,7 @@ function registerBaselineCommands(program2) {
|
|
|
20215
20599
|
process.chdir(repoRoot());
|
|
20216
20600
|
} catch {
|
|
20217
20601
|
}
|
|
20218
|
-
if (!(0,
|
|
20602
|
+
if (!(0, import_node_fs31.existsSync)(VERITY_DIR)) {
|
|
20219
20603
|
process.exit(0);
|
|
20220
20604
|
}
|
|
20221
20605
|
let sessionId = opts.sessionId;
|
|
@@ -20255,7 +20639,7 @@ async function readStdin() {
|
|
|
20255
20639
|
}
|
|
20256
20640
|
|
|
20257
20641
|
// src/commands/review.ts
|
|
20258
|
-
var
|
|
20642
|
+
var import_node_fs32 = require("node:fs");
|
|
20259
20643
|
function registerReviewCommand(program2) {
|
|
20260
20644
|
program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars)").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
|
|
20261
20645
|
const globals = program2.opts();
|
|
@@ -20274,7 +20658,7 @@ async function runReview(opts, globals) {
|
|
|
20274
20658
|
const securityFiles = filterSecurity(allFiles);
|
|
20275
20659
|
let staticResults;
|
|
20276
20660
|
if (isCodacyAvailable()) {
|
|
20277
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0,
|
|
20661
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs32.existsSync)(f) || resolveFile(f) !== null);
|
|
20278
20662
|
staticResults = runCodacyAnalysis(scannable);
|
|
20279
20663
|
} else {
|
|
20280
20664
|
staticResults = {
|
|
@@ -20300,10 +20684,10 @@ async function runReview(opts, globals) {
|
|
|
20300
20684
|
const specPaths = opts.specs.split(",").map((f) => f.trim()).filter(Boolean);
|
|
20301
20685
|
specs = [];
|
|
20302
20686
|
for (const p of specPaths) {
|
|
20303
|
-
if (!(0,
|
|
20687
|
+
if (!(0, import_node_fs32.existsSync)(p)) continue;
|
|
20304
20688
|
try {
|
|
20305
|
-
const { readFileSync:
|
|
20306
|
-
const content =
|
|
20689
|
+
const { readFileSync: readFileSync19 } = await import("node:fs");
|
|
20690
|
+
const content = readFileSync19(p, "utf-8");
|
|
20307
20691
|
specs.push({ path: p, content: content.slice(0, 10240) });
|
|
20308
20692
|
} catch {
|
|
20309
20693
|
}
|
|
@@ -20360,7 +20744,7 @@ async function runReview(opts, globals) {
|
|
|
20360
20744
|
}
|
|
20361
20745
|
|
|
20362
20746
|
// src/commands/guard.ts
|
|
20363
|
-
var
|
|
20747
|
+
var import_node_fs33 = require("node:fs");
|
|
20364
20748
|
var import_node_path24 = require("node:path");
|
|
20365
20749
|
var GUARD_BLOCK_CAP = 2;
|
|
20366
20750
|
var GUARD_ITER_FILE = (0, import_node_path24.join)(VERITY_DIR, ".guard-iteration");
|
|
@@ -20427,7 +20811,7 @@ function classifyCommand2(command, on) {
|
|
|
20427
20811
|
}
|
|
20428
20812
|
function readIterMap() {
|
|
20429
20813
|
try {
|
|
20430
|
-
const raw = JSON.parse((0,
|
|
20814
|
+
const raw = JSON.parse((0, import_node_fs33.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
20431
20815
|
if (raw && typeof raw === "object") {
|
|
20432
20816
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
20433
20817
|
return { [raw.moment]: raw.count };
|
|
@@ -20447,10 +20831,10 @@ function readIter(moment) {
|
|
|
20447
20831
|
}
|
|
20448
20832
|
function writeIter(moment, count) {
|
|
20449
20833
|
try {
|
|
20450
|
-
(0,
|
|
20834
|
+
(0, import_node_fs33.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
20451
20835
|
const map = readIterMap();
|
|
20452
20836
|
map[moment] = count;
|
|
20453
|
-
(0,
|
|
20837
|
+
(0, import_node_fs33.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
20454
20838
|
} catch {
|
|
20455
20839
|
}
|
|
20456
20840
|
}
|
|
@@ -20460,10 +20844,10 @@ function resetIter(moment) {
|
|
|
20460
20844
|
if (!(moment in map)) return;
|
|
20461
20845
|
delete map[moment];
|
|
20462
20846
|
if (Object.keys(map).length === 0) {
|
|
20463
|
-
if ((0,
|
|
20847
|
+
if ((0, import_node_fs33.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs33.unlinkSync)(GUARD_ITER_FILE);
|
|
20464
20848
|
} else {
|
|
20465
|
-
(0,
|
|
20466
|
-
(0,
|
|
20849
|
+
(0, import_node_fs33.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
20850
|
+
(0, import_node_fs33.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
20467
20851
|
}
|
|
20468
20852
|
} catch {
|
|
20469
20853
|
}
|
|
@@ -20527,7 +20911,7 @@ function buildGuardRequest(moment, files, iter, sessionId, command) {
|
|
|
20527
20911
|
const securityFiles = filterSecurity(files);
|
|
20528
20912
|
let staticResults;
|
|
20529
20913
|
if (isCodacyAvailable()) {
|
|
20530
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
20914
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs33.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
20531
20915
|
staticResults = runCodacyAnalysis(scannable);
|
|
20532
20916
|
} else {
|
|
20533
20917
|
staticResults = { tool: "@codacy/analysis-cli", findings: [], summary: { total_findings: 0, by_severity: {}, tools_run: [] } };
|
|
@@ -20572,7 +20956,7 @@ function emitAllowNotice(userMsg, agentMsg) {
|
|
|
20572
20956
|
async function runGuard(opts, globals) {
|
|
20573
20957
|
const on = opts.on.split(",").map((s) => s.trim()).filter((s) => s === "commit" || s === "push");
|
|
20574
20958
|
const { command, cwd, sessionId } = await readPreToolUseStdin();
|
|
20575
|
-
if (cwd && (0,
|
|
20959
|
+
if (cwd && (0, import_node_fs33.existsSync)(cwd)) {
|
|
20576
20960
|
try {
|
|
20577
20961
|
process.chdir(cwd);
|
|
20578
20962
|
} catch {
|
|
@@ -20678,14 +21062,14 @@ function writeBlockMessage(moment, response) {
|
|
|
20678
21062
|
}
|
|
20679
21063
|
|
|
20680
21064
|
// src/commands/init.ts
|
|
20681
|
-
var
|
|
21065
|
+
var import_node_fs35 = require("node:fs");
|
|
20682
21066
|
var import_promises13 = require("node:fs/promises");
|
|
20683
21067
|
var import_node_path26 = require("node:path");
|
|
20684
21068
|
var import_node_child_process10 = require("node:child_process");
|
|
20685
21069
|
var readline2 = __toESM(require("node:readline/promises"));
|
|
20686
21070
|
|
|
20687
21071
|
// src/commands/migrate.ts
|
|
20688
|
-
var
|
|
21072
|
+
var import_node_fs34 = require("node:fs");
|
|
20689
21073
|
var import_node_path25 = require("node:path");
|
|
20690
21074
|
var import_node_child_process9 = require("node:child_process");
|
|
20691
21075
|
|
|
@@ -20817,10 +21201,10 @@ async function runMigration(opts = {}) {
|
|
|
20817
21201
|
function migrateProjectDir(root, actions) {
|
|
20818
21202
|
const gateDir = (0, import_node_path25.join)(root, ".gate");
|
|
20819
21203
|
const verityDir = (0, import_node_path25.join)(root, ".verity");
|
|
20820
|
-
if ((0,
|
|
21204
|
+
if ((0, import_node_fs34.existsSync)(gateDir) && !(0, import_node_fs34.existsSync)(verityDir)) {
|
|
20821
21205
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
20822
21206
|
}
|
|
20823
|
-
if ((0,
|
|
21207
|
+
if ((0, import_node_fs34.existsSync)(gateDir) && (0, import_node_fs34.existsSync)(verityDir)) {
|
|
20824
21208
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
20825
21209
|
}
|
|
20826
21210
|
return false;
|
|
@@ -20841,13 +21225,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
20841
21225
|
}
|
|
20842
21226
|
}
|
|
20843
21227
|
if (moved) {
|
|
20844
|
-
if ((0,
|
|
21228
|
+
if ((0, import_node_fs34.existsSync)(gateDir)) {
|
|
20845
21229
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
20846
21230
|
if (carried > 0) {
|
|
20847
21231
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
20848
21232
|
}
|
|
20849
21233
|
try {
|
|
20850
|
-
(0,
|
|
21234
|
+
(0, import_node_fs34.rmSync)(gateDir, { recursive: true, force: true });
|
|
20851
21235
|
} catch {
|
|
20852
21236
|
}
|
|
20853
21237
|
}
|
|
@@ -20863,7 +21247,7 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
20863
21247
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
20864
21248
|
}
|
|
20865
21249
|
try {
|
|
20866
|
-
(0,
|
|
21250
|
+
(0, import_node_fs34.rmSync)(gateDir, { recursive: true, force: true });
|
|
20867
21251
|
} catch {
|
|
20868
21252
|
}
|
|
20869
21253
|
return carried > 0;
|
|
@@ -20872,9 +21256,9 @@ function migrateGlobalCredentials(home, actions) {
|
|
|
20872
21256
|
if (!home) return;
|
|
20873
21257
|
const gateCreds = (0, import_node_path25.join)(home, ".gate", "credentials");
|
|
20874
21258
|
const verityCreds = (0, import_node_path25.join)(home, ".verity", "credentials");
|
|
20875
|
-
if (!(0,
|
|
20876
|
-
if (!(0,
|
|
20877
|
-
(0,
|
|
21259
|
+
if (!(0, import_node_fs34.existsSync)(gateCreds)) return;
|
|
21260
|
+
if (!(0, import_node_fs34.existsSync)(verityCreds)) {
|
|
21261
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path25.join)(home, ".verity"), { recursive: true });
|
|
20878
21262
|
moveFile(gateCreds, verityCreds);
|
|
20879
21263
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
20880
21264
|
return;
|
|
@@ -20897,7 +21281,7 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
20897
21281
|
}
|
|
20898
21282
|
async function migrateClaudeMd(root, actions) {
|
|
20899
21283
|
const claudeMd = (0, import_node_path25.join)(root, "CLAUDE.md");
|
|
20900
|
-
const hadLegacyBlock = (0,
|
|
21284
|
+
const hadLegacyBlock = (0, import_node_fs34.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
20901
21285
|
if (!hadLegacyBlock) return;
|
|
20902
21286
|
try {
|
|
20903
21287
|
await ensureClaudeMdPointer(root);
|
|
@@ -20909,7 +21293,7 @@ async function migrateClaudeMd(root, actions) {
|
|
|
20909
21293
|
function migrateStandardFile(root, actions) {
|
|
20910
21294
|
const gateMd = (0, import_node_path25.join)(root, "GATE.md");
|
|
20911
21295
|
const verityMd = (0, import_node_path25.join)(root, "VERITY.md");
|
|
20912
|
-
if (!(0,
|
|
21296
|
+
if (!(0, import_node_fs34.existsSync)(gateMd) || (0, import_node_fs34.existsSync)(verityMd)) return;
|
|
20913
21297
|
let moved = false;
|
|
20914
21298
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
20915
21299
|
try {
|
|
@@ -20921,12 +21305,12 @@ function migrateStandardFile(root, actions) {
|
|
|
20921
21305
|
if (!moved) moveFile(gateMd, verityMd);
|
|
20922
21306
|
const content = readFileSyncSafe(verityMd);
|
|
20923
21307
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
20924
|
-
if (refreshed !== content) (0,
|
|
21308
|
+
if (refreshed !== content) (0, import_node_fs34.writeFileSync)(verityMd, refreshed);
|
|
20925
21309
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
20926
21310
|
}
|
|
20927
21311
|
async function migrateTelemetryHeaders(root, actions) {
|
|
20928
21312
|
const file = (0, import_node_path25.join)(root, ".claude", "settings.local.json");
|
|
20929
|
-
if (!(0,
|
|
21313
|
+
if (!(0, import_node_fs34.existsSync)(file)) return;
|
|
20930
21314
|
let settings;
|
|
20931
21315
|
try {
|
|
20932
21316
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -20974,14 +21358,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
20974
21358
|
}
|
|
20975
21359
|
if (toAppend.length > 0) {
|
|
20976
21360
|
const sep = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
20977
|
-
(0,
|
|
21361
|
+
(0, import_node_fs34.writeFileSync)(verityCreds, verityContent + sep + toAppend.join("\n") + "\n");
|
|
20978
21362
|
}
|
|
20979
|
-
(0,
|
|
21363
|
+
(0, import_node_fs34.rmSync)(gateCreds, { force: true });
|
|
20980
21364
|
return toAppend.length;
|
|
20981
21365
|
}
|
|
20982
21366
|
function readFileSyncSafe(path) {
|
|
20983
21367
|
try {
|
|
20984
|
-
return (0,
|
|
21368
|
+
return (0, import_node_fs34.readFileSync)(path, "utf-8");
|
|
20985
21369
|
} catch {
|
|
20986
21370
|
return "";
|
|
20987
21371
|
}
|
|
@@ -20996,35 +21380,35 @@ function hasStagedChanges(root) {
|
|
|
20996
21380
|
}
|
|
20997
21381
|
function moveDir(from, to) {
|
|
20998
21382
|
try {
|
|
20999
|
-
(0,
|
|
21383
|
+
(0, import_node_fs34.renameSync)(from, to);
|
|
21000
21384
|
} catch (err) {
|
|
21001
21385
|
if (err.code !== "EXDEV") throw err;
|
|
21002
|
-
(0,
|
|
21003
|
-
(0,
|
|
21386
|
+
(0, import_node_fs34.cpSync)(from, to, { recursive: true });
|
|
21387
|
+
(0, import_node_fs34.rmSync)(from, { recursive: true, force: true });
|
|
21004
21388
|
}
|
|
21005
21389
|
}
|
|
21006
21390
|
function moveFile(from, to) {
|
|
21007
21391
|
try {
|
|
21008
|
-
(0,
|
|
21392
|
+
(0, import_node_fs34.renameSync)(from, to);
|
|
21009
21393
|
} catch (err) {
|
|
21010
21394
|
if (err.code !== "EXDEV") throw err;
|
|
21011
|
-
(0,
|
|
21012
|
-
(0,
|
|
21395
|
+
(0, import_node_fs34.cpSync)(from, to);
|
|
21396
|
+
(0, import_node_fs34.rmSync)(from, { force: true });
|
|
21013
21397
|
}
|
|
21014
21398
|
}
|
|
21015
21399
|
function carryLegacyContents(gateDir, verityDir) {
|
|
21016
21400
|
let copied = 0;
|
|
21017
21401
|
const walk = (relDir) => {
|
|
21018
21402
|
const srcDir = (0, import_node_path25.join)(gateDir, relDir);
|
|
21019
|
-
for (const entry of (0,
|
|
21403
|
+
for (const entry of (0, import_node_fs34.readdirSync)(srcDir)) {
|
|
21020
21404
|
const rel = relDir ? (0, import_node_path25.join)(relDir, entry) : entry;
|
|
21021
21405
|
const src = (0, import_node_path25.join)(gateDir, rel);
|
|
21022
21406
|
const dest = (0, import_node_path25.join)(verityDir, rel);
|
|
21023
|
-
if ((0,
|
|
21407
|
+
if ((0, import_node_fs34.statSync)(src).isDirectory()) {
|
|
21024
21408
|
walk(rel);
|
|
21025
|
-
} else if (!(0,
|
|
21026
|
-
(0,
|
|
21027
|
-
(0,
|
|
21409
|
+
} else if (!(0, import_node_fs34.existsSync)(dest)) {
|
|
21410
|
+
(0, import_node_fs34.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
|
|
21411
|
+
(0, import_node_fs34.cpSync)(src, dest);
|
|
21028
21412
|
copied++;
|
|
21029
21413
|
}
|
|
21030
21414
|
}
|
|
@@ -21035,20 +21419,20 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
21035
21419
|
async function needsMigration(root = repoRoot()) {
|
|
21036
21420
|
const gateDir = (0, import_node_path25.join)(root, ".gate");
|
|
21037
21421
|
const verityDir = (0, import_node_path25.join)(root, ".verity");
|
|
21038
|
-
if ((0,
|
|
21039
|
-
if ((0,
|
|
21040
|
-
if ((0,
|
|
21422
|
+
if ((0, import_node_fs34.existsSync)(gateDir) && !(0, import_node_fs34.existsSync)(verityDir)) return true;
|
|
21423
|
+
if ((0, import_node_fs34.existsSync)(gateDir) && (0, import_node_fs34.existsSync)(verityDir)) {
|
|
21424
|
+
if ((0, import_node_fs34.existsSync)((0, import_node_path25.join)(gateDir, "credentials")) && !(0, import_node_fs34.existsSync)((0, import_node_path25.join)(verityDir, "credentials"))) {
|
|
21041
21425
|
return true;
|
|
21042
21426
|
}
|
|
21043
|
-
if ((0,
|
|
21427
|
+
if ((0, import_node_fs34.existsSync)((0, import_node_path25.join)(gateDir, "memory")) && !(0, import_node_fs34.existsSync)((0, import_node_path25.join)(verityDir, "memory"))) {
|
|
21044
21428
|
return true;
|
|
21045
21429
|
}
|
|
21046
21430
|
}
|
|
21047
21431
|
const claudeMd = (0, import_node_path25.join)(root, "CLAUDE.md");
|
|
21048
|
-
if ((0,
|
|
21432
|
+
if ((0, import_node_fs34.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
21049
21433
|
return true;
|
|
21050
21434
|
}
|
|
21051
|
-
if ((0,
|
|
21435
|
+
if ((0, import_node_fs34.existsSync)((0, import_node_path25.join)(root, "GATE.md")) && !(0, import_node_fs34.existsSync)((0, import_node_path25.join)(root, "VERITY.md"))) {
|
|
21052
21436
|
return true;
|
|
21053
21437
|
}
|
|
21054
21438
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -21190,7 +21574,7 @@ function resolveDataDir() {
|
|
|
21190
21574
|
// local dev: running from repo root
|
|
21191
21575
|
];
|
|
21192
21576
|
for (const candidate of candidates) {
|
|
21193
|
-
if ((0,
|
|
21577
|
+
if ((0, import_node_fs35.existsSync)((0, import_node_path26.join)(candidate, "skills"))) {
|
|
21194
21578
|
return candidate;
|
|
21195
21579
|
}
|
|
21196
21580
|
}
|
|
@@ -21206,7 +21590,7 @@ function registerInitCommand(program2) {
|
|
|
21206
21590
|
program2.command("init").description("Initialize Verity in the current project").option("--force", "Overwrite existing skills and hooks").action(async (opts) => {
|
|
21207
21591
|
const force = opts.force ?? false;
|
|
21208
21592
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
21209
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
21593
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs35.existsSync)(m));
|
|
21210
21594
|
if (!isProject) {
|
|
21211
21595
|
printError("No project detected in the current directory.");
|
|
21212
21596
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -21276,14 +21660,14 @@ function registerInitCommand(program2) {
|
|
|
21276
21660
|
for (const skill of skills) {
|
|
21277
21661
|
const src = (0, import_node_path26.join)(skillsSource, skill);
|
|
21278
21662
|
const dest = (0, import_node_path26.join)(skillsDest, skill);
|
|
21279
|
-
if (!(0,
|
|
21663
|
+
if (!(0, import_node_fs35.existsSync)(src)) {
|
|
21280
21664
|
printWarn(` Skill data not found: ${skill}`);
|
|
21281
21665
|
continue;
|
|
21282
21666
|
}
|
|
21283
|
-
if ((0,
|
|
21667
|
+
if ((0, import_node_fs35.existsSync)(dest) && !force) {
|
|
21284
21668
|
const srcSkill = (0, import_node_path26.join)(src, "SKILL.md");
|
|
21285
21669
|
const destSkill = (0, import_node_path26.join)(dest, "SKILL.md");
|
|
21286
|
-
if ((0,
|
|
21670
|
+
if ((0, import_node_fs35.existsSync)(destSkill)) {
|
|
21287
21671
|
try {
|
|
21288
21672
|
const srcContent = await (0, import_promises13.readFile)(srcSkill, "utf-8");
|
|
21289
21673
|
const destContent = await (0, import_promises13.readFile)(destSkill, "utf-8");
|
|
@@ -21355,7 +21739,7 @@ function registerInitCommand(program2) {
|
|
|
21355
21739
|
}
|
|
21356
21740
|
|
|
21357
21741
|
// src/commands/uninstall.ts
|
|
21358
|
-
var
|
|
21742
|
+
var import_node_fs36 = require("node:fs");
|
|
21359
21743
|
var import_node_path27 = require("node:path");
|
|
21360
21744
|
var SKILL_NAMES = [
|
|
21361
21745
|
"verity-setup",
|
|
@@ -21376,10 +21760,10 @@ function registerUninstallCommand(program2) {
|
|
|
21376
21760
|
const skillsRoot = projectPath(".claude/skills");
|
|
21377
21761
|
for (const name of SKILL_NAMES) {
|
|
21378
21762
|
const dir = (0, import_node_path27.join)(skillsRoot, name);
|
|
21379
|
-
if ((0,
|
|
21763
|
+
if ((0, import_node_fs36.existsSync)(dir)) {
|
|
21380
21764
|
actions.push({
|
|
21381
21765
|
label: `Remove .claude/skills/${name}/`,
|
|
21382
|
-
apply: () => (0,
|
|
21766
|
+
apply: () => (0, import_node_fs36.rmSync)(dir, { recursive: true, force: true })
|
|
21383
21767
|
});
|
|
21384
21768
|
}
|
|
21385
21769
|
}
|
|
@@ -21393,24 +21777,24 @@ function registerUninstallCommand(program2) {
|
|
|
21393
21777
|
});
|
|
21394
21778
|
}
|
|
21395
21779
|
const verityDir = projectPath(VERITY_DIR);
|
|
21396
|
-
if ((0,
|
|
21780
|
+
if ((0, import_node_fs36.existsSync)(verityDir)) {
|
|
21397
21781
|
actions.push({
|
|
21398
21782
|
label: `Remove ${VERITY_DIR}/`,
|
|
21399
|
-
apply: () => (0,
|
|
21783
|
+
apply: () => (0, import_node_fs36.rmSync)(verityDir, { recursive: true, force: true })
|
|
21400
21784
|
});
|
|
21401
21785
|
}
|
|
21402
21786
|
if (!keepVerityMd) {
|
|
21403
21787
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
21404
|
-
if ((0,
|
|
21788
|
+
if ((0, import_node_fs36.existsSync)(verityMd)) {
|
|
21405
21789
|
actions.push({
|
|
21406
21790
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
21407
|
-
apply: () => (0,
|
|
21791
|
+
apply: () => (0, import_node_fs36.rmSync)(verityMd, { force: true })
|
|
21408
21792
|
});
|
|
21409
21793
|
}
|
|
21410
21794
|
}
|
|
21411
21795
|
const cleanupEmptyDir = (path) => {
|
|
21412
|
-
if ((0,
|
|
21413
|
-
(0,
|
|
21796
|
+
if ((0, import_node_fs36.existsSync)(path) && (0, import_node_fs36.statSync)(path).isDirectory() && (0, import_node_fs36.readdirSync)(path).length === 0) {
|
|
21797
|
+
(0, import_node_fs36.rmdirSync)(path);
|
|
21414
21798
|
}
|
|
21415
21799
|
};
|
|
21416
21800
|
actions.push({
|
|
@@ -21422,10 +21806,10 @@ function registerUninstallCommand(program2) {
|
|
|
21422
21806
|
});
|
|
21423
21807
|
const home = process.env.HOME ?? "";
|
|
21424
21808
|
const globalVerityDir = (0, import_node_path27.join)(home, ".verity");
|
|
21425
|
-
if (purgeGlobal && (0,
|
|
21809
|
+
if (purgeGlobal && (0, import_node_fs36.existsSync)(globalVerityDir)) {
|
|
21426
21810
|
actions.push({
|
|
21427
21811
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
21428
|
-
apply: () => (0,
|
|
21812
|
+
apply: () => (0, import_node_fs36.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
21429
21813
|
});
|
|
21430
21814
|
}
|
|
21431
21815
|
if (actions.length === 0) {
|
|
@@ -21619,7 +22003,7 @@ function registerTaskCommands(program2) {
|
|
|
21619
22003
|
}
|
|
21620
22004
|
|
|
21621
22005
|
// src/commands/reset.ts
|
|
21622
|
-
var
|
|
22006
|
+
var import_node_fs37 = require("node:fs");
|
|
21623
22007
|
var import_node_path28 = require("node:path");
|
|
21624
22008
|
function registerResetCommand(program2) {
|
|
21625
22009
|
program2.command("reset").description("Close the current task and clear transient state").option("--keep-task", "Only purge caches; leave the current task open").option("--all", "Also purge diagnostic logs (.verity/.logs/)").action(async (opts) => {
|
|
@@ -21657,11 +22041,11 @@ function registerResetCommand(program2) {
|
|
|
21657
22041
|
}
|
|
21658
22042
|
const cacheDir = projectPath(CACHE_DIR);
|
|
21659
22043
|
let purged = 0;
|
|
21660
|
-
if ((0,
|
|
21661
|
-
for (const entry of (0,
|
|
22044
|
+
if ((0, import_node_fs37.existsSync)(cacheDir)) {
|
|
22045
|
+
for (const entry of (0, import_node_fs37.readdirSync)(cacheDir)) {
|
|
21662
22046
|
if (entry.startsWith("pending-")) {
|
|
21663
22047
|
try {
|
|
21664
|
-
(0,
|
|
22048
|
+
(0, import_node_fs37.unlinkSync)((0, import_node_path28.join)(cacheDir, entry));
|
|
21665
22049
|
purged++;
|
|
21666
22050
|
} catch {
|
|
21667
22051
|
}
|
|
@@ -21676,19 +22060,19 @@ function registerResetCommand(program2) {
|
|
|
21676
22060
|
projectPath(`${VERITY_DIR}/.last-analysis`)
|
|
21677
22061
|
];
|
|
21678
22062
|
for (const file of filesToClear) {
|
|
21679
|
-
if ((0,
|
|
22063
|
+
if ((0, import_node_fs37.existsSync)(file)) {
|
|
21680
22064
|
try {
|
|
21681
|
-
(0,
|
|
22065
|
+
(0, import_node_fs37.writeFileSync)(file, "");
|
|
21682
22066
|
} catch {
|
|
21683
22067
|
}
|
|
21684
22068
|
}
|
|
21685
22069
|
}
|
|
21686
22070
|
if (opts.all) {
|
|
21687
22071
|
const logsDir = projectPath(`${VERITY_DIR}/.logs`);
|
|
21688
|
-
if ((0,
|
|
21689
|
-
for (const entry of (0,
|
|
22072
|
+
if ((0, import_node_fs37.existsSync)(logsDir)) {
|
|
22073
|
+
for (const entry of (0, import_node_fs37.readdirSync)(logsDir)) {
|
|
21690
22074
|
try {
|
|
21691
|
-
(0,
|
|
22075
|
+
(0, import_node_fs37.unlinkSync)((0, import_node_path28.join)(logsDir, entry));
|
|
21692
22076
|
} catch {
|
|
21693
22077
|
}
|
|
21694
22078
|
}
|
|
@@ -21996,8 +22380,8 @@ function registerTelemetryCommands(program2) {
|
|
|
21996
22380
|
}
|
|
21997
22381
|
|
|
21998
22382
|
// 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.
|
|
22383
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.29.4-experimental.6f2ede0").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) => {
|
|
22384
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.29.4-experimental.6f2ede0");
|
|
22001
22385
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
22002
22386
|
try {
|
|
22003
22387
|
await foldLegacyLocalCredential();
|