@codacy/verity-cli 0.34.1-experimental.c910405 → 0.34.2-experimental.3b25de0
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/CHANGELOG.md +28 -0
- package/bin/verity.js +606 -393
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -6975,10 +6975,10 @@ var require_resolve_block_map = __commonJS2({
|
|
|
6975
6975
|
let offset = bm.offset;
|
|
6976
6976
|
let commentEnd = null;
|
|
6977
6977
|
for (const collItem of bm.items) {
|
|
6978
|
-
const { start: start2, key, sep:
|
|
6978
|
+
const { start: start2, key, sep: sep7, value } = collItem;
|
|
6979
6979
|
const keyProps = resolveProps.resolveProps(start2, {
|
|
6980
6980
|
indicator: "explicit-key-ind",
|
|
6981
|
-
next: key ??
|
|
6981
|
+
next: key ?? sep7?.[0],
|
|
6982
6982
|
offset,
|
|
6983
6983
|
onError,
|
|
6984
6984
|
parentIndent: bm.indent,
|
|
@@ -6992,7 +6992,7 @@ var require_resolve_block_map = __commonJS2({
|
|
|
6992
6992
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
6993
6993
|
onError(offset, "BAD_INDENT", startColMsg);
|
|
6994
6994
|
}
|
|
6995
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
6995
|
+
if (!keyProps.anchor && !keyProps.tag && !sep7) {
|
|
6996
6996
|
commentEnd = keyProps.end;
|
|
6997
6997
|
if (keyProps.comment) {
|
|
6998
6998
|
if (map.comment)
|
|
@@ -7016,7 +7016,7 @@ var require_resolve_block_map = __commonJS2({
|
|
|
7016
7016
|
ctx.atKey = false;
|
|
7017
7017
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
7018
7018
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
7019
|
-
const valueProps = resolveProps.resolveProps(
|
|
7019
|
+
const valueProps = resolveProps.resolveProps(sep7 ?? [], {
|
|
7020
7020
|
indicator: "map-value-ind",
|
|
7021
7021
|
next: value,
|
|
7022
7022
|
offset: keyNode.range[2],
|
|
@@ -7032,7 +7032,7 @@ var require_resolve_block_map = __commonJS2({
|
|
|
7032
7032
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
7033
7033
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
7034
7034
|
}
|
|
7035
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset,
|
|
7035
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep7, null, valueProps, onError);
|
|
7036
7036
|
if (ctx.schema.compat)
|
|
7037
7037
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
7038
7038
|
offset = valueNode.range[2];
|
|
@@ -7123,7 +7123,7 @@ var require_resolve_end = __commonJS2({
|
|
|
7123
7123
|
let comment = "";
|
|
7124
7124
|
if (end) {
|
|
7125
7125
|
let hasSpace = false;
|
|
7126
|
-
let
|
|
7126
|
+
let sep7 = "";
|
|
7127
7127
|
for (const token of end) {
|
|
7128
7128
|
const { source: source2, type } = token;
|
|
7129
7129
|
switch (type) {
|
|
@@ -7137,13 +7137,13 @@ var require_resolve_end = __commonJS2({
|
|
|
7137
7137
|
if (!comment)
|
|
7138
7138
|
comment = cb;
|
|
7139
7139
|
else
|
|
7140
|
-
comment +=
|
|
7141
|
-
|
|
7140
|
+
comment += sep7 + cb;
|
|
7141
|
+
sep7 = "";
|
|
7142
7142
|
break;
|
|
7143
7143
|
}
|
|
7144
7144
|
case "newline":
|
|
7145
7145
|
if (comment)
|
|
7146
|
-
|
|
7146
|
+
sep7 += source2;
|
|
7147
7147
|
hasSpace = true;
|
|
7148
7148
|
break;
|
|
7149
7149
|
default:
|
|
@@ -7186,18 +7186,18 @@ var require_resolve_flow_collection = __commonJS2({
|
|
|
7186
7186
|
let offset = fc.offset + fc.start.source.length;
|
|
7187
7187
|
for (let i2 = 0; i2 < fc.items.length; ++i2) {
|
|
7188
7188
|
const collItem = fc.items[i2];
|
|
7189
|
-
const { start: start2, key, sep:
|
|
7189
|
+
const { start: start2, key, sep: sep7, value } = collItem;
|
|
7190
7190
|
const props = resolveProps.resolveProps(start2, {
|
|
7191
7191
|
flow: fcName,
|
|
7192
7192
|
indicator: "explicit-key-ind",
|
|
7193
|
-
next: key ??
|
|
7193
|
+
next: key ?? sep7?.[0],
|
|
7194
7194
|
offset,
|
|
7195
7195
|
onError,
|
|
7196
7196
|
parentIndent: fc.indent,
|
|
7197
7197
|
startOnNewline: false
|
|
7198
7198
|
});
|
|
7199
7199
|
if (!props.found) {
|
|
7200
|
-
if (!props.anchor && !props.tag && !
|
|
7200
|
+
if (!props.anchor && !props.tag && !sep7 && !value) {
|
|
7201
7201
|
if (i2 === 0 && props.comma)
|
|
7202
7202
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
7203
7203
|
else if (i2 < fc.items.length - 1)
|
|
@@ -7251,8 +7251,8 @@ var require_resolve_flow_collection = __commonJS2({
|
|
|
7251
7251
|
}
|
|
7252
7252
|
}
|
|
7253
7253
|
}
|
|
7254
|
-
if (!isMap && !
|
|
7255
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
7254
|
+
if (!isMap && !sep7 && !props.found) {
|
|
7255
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep7, null, props, onError);
|
|
7256
7256
|
coll.items.push(valueNode);
|
|
7257
7257
|
offset = valueNode.range[2];
|
|
7258
7258
|
if (isBlock(value))
|
|
@@ -7264,7 +7264,7 @@ var require_resolve_flow_collection = __commonJS2({
|
|
|
7264
7264
|
if (isBlock(key))
|
|
7265
7265
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
7266
7266
|
ctx.atKey = false;
|
|
7267
|
-
const valueProps = resolveProps.resolveProps(
|
|
7267
|
+
const valueProps = resolveProps.resolveProps(sep7 ?? [], {
|
|
7268
7268
|
flow: fcName,
|
|
7269
7269
|
indicator: "map-value-ind",
|
|
7270
7270
|
next: value,
|
|
@@ -7275,8 +7275,8 @@ var require_resolve_flow_collection = __commonJS2({
|
|
|
7275
7275
|
});
|
|
7276
7276
|
if (valueProps.found) {
|
|
7277
7277
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
7278
|
-
if (
|
|
7279
|
-
for (const st of
|
|
7278
|
+
if (sep7)
|
|
7279
|
+
for (const st of sep7) {
|
|
7280
7280
|
if (st === valueProps.found)
|
|
7281
7281
|
break;
|
|
7282
7282
|
if (st.type === "newline") {
|
|
@@ -7293,7 +7293,7 @@ var require_resolve_flow_collection = __commonJS2({
|
|
|
7293
7293
|
else
|
|
7294
7294
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
7295
7295
|
}
|
|
7296
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
7296
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep7, null, valueProps, onError) : null;
|
|
7297
7297
|
if (valueNode) {
|
|
7298
7298
|
if (isBlock(value))
|
|
7299
7299
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -7473,7 +7473,7 @@ var require_resolve_block_scalar = __commonJS2({
|
|
|
7473
7473
|
chompStart = i2 + 1;
|
|
7474
7474
|
}
|
|
7475
7475
|
let value = "";
|
|
7476
|
-
let
|
|
7476
|
+
let sep7 = "";
|
|
7477
7477
|
let prevMoreIndented = false;
|
|
7478
7478
|
for (let i2 = 0; i2 < contentStart; ++i2)
|
|
7479
7479
|
value += lines[i2][0].slice(trimIndent) + "\n";
|
|
@@ -7490,24 +7490,24 @@ var require_resolve_block_scalar = __commonJS2({
|
|
|
7490
7490
|
indent = "";
|
|
7491
7491
|
}
|
|
7492
7492
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
7493
|
-
value +=
|
|
7494
|
-
|
|
7493
|
+
value += sep7 + indent.slice(trimIndent) + content;
|
|
7494
|
+
sep7 = "\n";
|
|
7495
7495
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
7496
|
-
if (
|
|
7497
|
-
|
|
7498
|
-
else if (!prevMoreIndented &&
|
|
7499
|
-
|
|
7500
|
-
value +=
|
|
7501
|
-
|
|
7496
|
+
if (sep7 === " ")
|
|
7497
|
+
sep7 = "\n";
|
|
7498
|
+
else if (!prevMoreIndented && sep7 === "\n")
|
|
7499
|
+
sep7 = "\n\n";
|
|
7500
|
+
value += sep7 + indent.slice(trimIndent) + content;
|
|
7501
|
+
sep7 = "\n";
|
|
7502
7502
|
prevMoreIndented = true;
|
|
7503
7503
|
} else if (content === "") {
|
|
7504
|
-
if (
|
|
7504
|
+
if (sep7 === "\n")
|
|
7505
7505
|
value += "\n";
|
|
7506
7506
|
else
|
|
7507
|
-
|
|
7507
|
+
sep7 = "\n";
|
|
7508
7508
|
} else {
|
|
7509
|
-
value +=
|
|
7510
|
-
|
|
7509
|
+
value += sep7 + content;
|
|
7510
|
+
sep7 = " ";
|
|
7511
7511
|
prevMoreIndented = false;
|
|
7512
7512
|
}
|
|
7513
7513
|
}
|
|
@@ -7689,25 +7689,25 @@ var require_resolve_flow_scalar = __commonJS2({
|
|
|
7689
7689
|
if (!match)
|
|
7690
7690
|
return source2;
|
|
7691
7691
|
let res = match[1];
|
|
7692
|
-
let
|
|
7692
|
+
let sep7 = " ";
|
|
7693
7693
|
let pos = first.lastIndex;
|
|
7694
7694
|
line2.lastIndex = pos;
|
|
7695
7695
|
while (match = line2.exec(source2)) {
|
|
7696
7696
|
if (match[1] === "") {
|
|
7697
|
-
if (
|
|
7698
|
-
res +=
|
|
7697
|
+
if (sep7 === "\n")
|
|
7698
|
+
res += sep7;
|
|
7699
7699
|
else
|
|
7700
|
-
|
|
7700
|
+
sep7 = "\n";
|
|
7701
7701
|
} else {
|
|
7702
|
-
res +=
|
|
7703
|
-
|
|
7702
|
+
res += sep7 + match[1];
|
|
7703
|
+
sep7 = " ";
|
|
7704
7704
|
}
|
|
7705
7705
|
pos = line2.lastIndex;
|
|
7706
7706
|
}
|
|
7707
7707
|
const last = /[ \t]*(.*)/sy;
|
|
7708
7708
|
last.lastIndex = pos;
|
|
7709
7709
|
match = last.exec(source2);
|
|
7710
|
-
return res +
|
|
7710
|
+
return res + sep7 + (match?.[1] ?? "");
|
|
7711
7711
|
}
|
|
7712
7712
|
function doubleQuotedValue(source2, onError) {
|
|
7713
7713
|
let res = "";
|
|
@@ -8514,14 +8514,14 @@ var require_cst_stringify = __commonJS2({
|
|
|
8514
8514
|
}
|
|
8515
8515
|
}
|
|
8516
8516
|
}
|
|
8517
|
-
function stringifyItem({ start: start2, key, sep:
|
|
8517
|
+
function stringifyItem({ start: start2, key, sep: sep7, value }) {
|
|
8518
8518
|
let res = "";
|
|
8519
8519
|
for (const st of start2)
|
|
8520
8520
|
res += st.source;
|
|
8521
8521
|
if (key)
|
|
8522
8522
|
res += stringifyToken(key);
|
|
8523
|
-
if (
|
|
8524
|
-
for (const st of
|
|
8523
|
+
if (sep7)
|
|
8524
|
+
for (const st of sep7)
|
|
8525
8525
|
res += st.source;
|
|
8526
8526
|
if (value)
|
|
8527
8527
|
res += stringifyToken(value);
|
|
@@ -9671,18 +9671,18 @@ var require_parser = __commonJS2({
|
|
|
9671
9671
|
if (this.type === "map-value-ind") {
|
|
9672
9672
|
const prev = getPrevProps(this.peek(2));
|
|
9673
9673
|
const start2 = getFirstKeyStartProps(prev);
|
|
9674
|
-
let
|
|
9674
|
+
let sep7;
|
|
9675
9675
|
if (scalar.end) {
|
|
9676
|
-
|
|
9677
|
-
|
|
9676
|
+
sep7 = scalar.end;
|
|
9677
|
+
sep7.push(this.sourceToken);
|
|
9678
9678
|
delete scalar.end;
|
|
9679
9679
|
} else
|
|
9680
|
-
|
|
9680
|
+
sep7 = [this.sourceToken];
|
|
9681
9681
|
const map = {
|
|
9682
9682
|
type: "block-map",
|
|
9683
9683
|
offset: scalar.offset,
|
|
9684
9684
|
indent: scalar.indent,
|
|
9685
|
-
items: [{ start: start2, key: scalar, sep:
|
|
9685
|
+
items: [{ start: start2, key: scalar, sep: sep7 }]
|
|
9686
9686
|
};
|
|
9687
9687
|
this.onKeyLine = true;
|
|
9688
9688
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -9835,15 +9835,15 @@ var require_parser = __commonJS2({
|
|
|
9835
9835
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
9836
9836
|
const start3 = getFirstKeyStartProps(it.start);
|
|
9837
9837
|
const key = it.key;
|
|
9838
|
-
const
|
|
9839
|
-
|
|
9838
|
+
const sep7 = it.sep;
|
|
9839
|
+
sep7.push(this.sourceToken);
|
|
9840
9840
|
delete it.key;
|
|
9841
9841
|
delete it.sep;
|
|
9842
9842
|
this.stack.push({
|
|
9843
9843
|
type: "block-map",
|
|
9844
9844
|
offset: this.offset,
|
|
9845
9845
|
indent: this.indent,
|
|
9846
|
-
items: [{ start: start3, key, sep:
|
|
9846
|
+
items: [{ start: start3, key, sep: sep7 }]
|
|
9847
9847
|
});
|
|
9848
9848
|
} else if (start2.length > 0) {
|
|
9849
9849
|
it.sep = it.sep.concat(start2, this.sourceToken);
|
|
@@ -10037,13 +10037,13 @@ var require_parser = __commonJS2({
|
|
|
10037
10037
|
const prev = getPrevProps(parent);
|
|
10038
10038
|
const start2 = getFirstKeyStartProps(prev);
|
|
10039
10039
|
fixFlowSeqItems(fc);
|
|
10040
|
-
const
|
|
10041
|
-
|
|
10040
|
+
const sep7 = fc.end.splice(1, fc.end.length);
|
|
10041
|
+
sep7.push(this.sourceToken);
|
|
10042
10042
|
const map = {
|
|
10043
10043
|
type: "block-map",
|
|
10044
10044
|
offset: fc.offset,
|
|
10045
10045
|
indent: fc.indent,
|
|
10046
|
-
items: [{ start: start2, key: fc, sep:
|
|
10046
|
+
items: [{ start: start2, key: fc, sep: sep7 }]
|
|
10047
10047
|
};
|
|
10048
10048
|
this.onKeyLine = true;
|
|
10049
10049
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -15172,8 +15172,8 @@ function filterReviewable(files) {
|
|
|
15172
15172
|
const ext = (0, import_node_path4.extname)(f).slice(1);
|
|
15173
15173
|
if (ANALYZABLE_EXTENSIONS.has(ext)) return false;
|
|
15174
15174
|
if (REVIEWABLE_EXTENSIONS.has(ext)) return true;
|
|
15175
|
-
const
|
|
15176
|
-
if (REVIEWABLE_FILENAMES.has(
|
|
15175
|
+
const basename11 = f.split("/").pop() ?? "";
|
|
15176
|
+
if (REVIEWABLE_FILENAMES.has(basename11)) return true;
|
|
15177
15177
|
if (REVIEWABLE_PATH_PATTERNS.some((p) => p.test(f))) return true;
|
|
15178
15178
|
return false;
|
|
15179
15179
|
});
|
|
@@ -16287,6 +16287,15 @@ async function reportLoginOutcome(out2, opts = {}) {
|
|
|
16287
16287
|
}
|
|
16288
16288
|
}
|
|
16289
16289
|
|
|
16290
|
+
// src/lib/session-env.ts
|
|
16291
|
+
function envSessionId(env = process.env) {
|
|
16292
|
+
for (const name2 of ["CLAUDE_SESSION_ID", "CLAUDE_CODE_SESSION_ID"]) {
|
|
16293
|
+
const value = env[name2];
|
|
16294
|
+
if (value) return value;
|
|
16295
|
+
}
|
|
16296
|
+
return void 0;
|
|
16297
|
+
}
|
|
16298
|
+
|
|
16290
16299
|
// src/commands/login.ts
|
|
16291
16300
|
function registerLoginCommand(program2) {
|
|
16292
16301
|
program2.command("login").description("Log in to Verity (one GitHub login grants access to all your repositories)").option("--force", "Re-authenticate even if already logged in").option("--start", "Show the GitHub code and return at once (finish with --finish); prints JSON").option("--finish", "Wait for approval of the code --start showed, then log in; prints JSON").option("--wait <seconds>", "With --finish: how long to wait for approval before returning", "100").option("--cancel", "Discard a code --start showed that will not be approved").action(async (opts) => {
|
|
@@ -16303,7 +16312,7 @@ function registerLoginCommand(program2) {
|
|
|
16303
16312
|
return;
|
|
16304
16313
|
}
|
|
16305
16314
|
const split = !!(opts.start || opts.finish);
|
|
16306
|
-
if (!split && !process.stdin.isTTY && (process.env.CLAUDECODE ||
|
|
16315
|
+
if (!split && !process.stdin.isTTY && (process.env.CLAUDECODE || envSessionId())) {
|
|
16307
16316
|
printWarn("Inside a Claude Code session the code below may not be visible until this command ends.");
|
|
16308
16317
|
printWarn(' Use "verity login --start", then "verity login --finish" once it is approved.');
|
|
16309
16318
|
}
|
|
@@ -19477,8 +19486,8 @@ function ensureVerityGitignore() {
|
|
|
19477
19486
|
}
|
|
19478
19487
|
let text = next.join("\n");
|
|
19479
19488
|
if (!hasMarker) {
|
|
19480
|
-
const
|
|
19481
|
-
text = text +
|
|
19489
|
+
const sep7 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
|
|
19490
|
+
text = text + sep7 + VERITY_GITIGNORE_BLOCK;
|
|
19482
19491
|
}
|
|
19483
19492
|
if (text !== content) (0, import_node_fs19.writeFileSync)(".gitignore", text);
|
|
19484
19493
|
return verified(
|
|
@@ -19508,8 +19517,8 @@ function writeFencedBlock() {
|
|
|
19508
19517
|
lines = fenceMemoryLines(lines);
|
|
19509
19518
|
let text = lines.join("\n");
|
|
19510
19519
|
if (!hasMarker) {
|
|
19511
|
-
const
|
|
19512
|
-
text = text +
|
|
19520
|
+
const sep7 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
|
|
19521
|
+
text = text + sep7 + VERITY_GITIGNORE_BLOCK;
|
|
19513
19522
|
}
|
|
19514
19523
|
try {
|
|
19515
19524
|
(0, import_node_fs19.writeFileSync)(".gitignore", text);
|
|
@@ -19559,8 +19568,8 @@ function keepMemoryTracked() {
|
|
|
19559
19568
|
}
|
|
19560
19569
|
if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
|
|
19561
19570
|
try {
|
|
19562
|
-
const
|
|
19563
|
-
(0, import_node_fs19.writeFileSync)(".gitignore", content +
|
|
19571
|
+
const sep7 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
|
|
19572
|
+
(0, import_node_fs19.writeFileSync)(".gitignore", content + sep7 + MEMORY_OPT_OUT_STANZA);
|
|
19564
19573
|
} catch {
|
|
19565
19574
|
return "failed";
|
|
19566
19575
|
}
|
|
@@ -22150,13 +22159,13 @@ function registerIntentCommands(program2) {
|
|
|
22150
22159
|
if (!prompt) {
|
|
22151
22160
|
process.exit(0);
|
|
22152
22161
|
}
|
|
22153
|
-
if (deferredToPlugin("intent capture", event.session_id ??
|
|
22162
|
+
if (deferredToPlugin("intent capture", event.session_id ?? envSessionId() ?? null)) {
|
|
22154
22163
|
process.exit(0);
|
|
22155
22164
|
}
|
|
22156
22165
|
const isPrimitive = isSlashCommand(prompt);
|
|
22157
22166
|
const authForScope = await resolveToken(program2.opts().token);
|
|
22158
22167
|
const scopeToken = authForScope.ok ? authForScope.data.token : void 0;
|
|
22159
|
-
const scopeSession = event.session_id ||
|
|
22168
|
+
const scopeSession = event.session_id || envSessionId() || "";
|
|
22160
22169
|
if (!isPrimitive) await appendToConversationBuffer(prompt, sessionScopeKey(scopeToken, scopeSession));
|
|
22161
22170
|
if (!isPrimitive) {
|
|
22162
22171
|
try {
|
|
@@ -22876,7 +22885,12 @@ function registerLifecycleCommands(program2) {
|
|
|
22876
22885
|
}
|
|
22877
22886
|
if (!verityConfigured()) process.exit(0);
|
|
22878
22887
|
const event = await readHookStdin();
|
|
22879
|
-
const
|
|
22888
|
+
const resolved = resolveHookSession(opts.sessionId, event, envSessionId());
|
|
22889
|
+
if (!resolved.ok) {
|
|
22890
|
+
logEvent("lifecycle_session_flag_refused", { command: "compact" });
|
|
22891
|
+
process.exit(0);
|
|
22892
|
+
}
|
|
22893
|
+
const sessionId = resolved.sessionId;
|
|
22880
22894
|
if (deferredToPlugin("compact", sessionId)) process.exit(0);
|
|
22881
22895
|
const globals = program2.opts();
|
|
22882
22896
|
const tok = await resolveToken(globals.token);
|
|
@@ -22905,9 +22919,14 @@ function registerLifecycleCommands(program2) {
|
|
|
22905
22919
|
}
|
|
22906
22920
|
if (!verityConfigured()) process.exit(0);
|
|
22907
22921
|
const event = await readHookStdin();
|
|
22908
|
-
const
|
|
22922
|
+
const resolved = resolveHookSession(opts.sessionId, event, envSessionId());
|
|
22923
|
+
if (!resolved.ok) {
|
|
22924
|
+
logEvent("lifecycle_session_flag_refused", { command: "session end" });
|
|
22925
|
+
process.exit(0);
|
|
22926
|
+
}
|
|
22927
|
+
const sessionId = resolved.sessionId;
|
|
22909
22928
|
if (deferredToPlugin("session end", sessionId)) process.exit(0);
|
|
22910
|
-
const reason = opts.reason ?? event.session_end_reason ?? event.reason ?? "other";
|
|
22929
|
+
const reason = hookWord(opts.reason) ?? event.session_end_reason ?? event.reason ?? "other";
|
|
22911
22930
|
if (reason === "clear") {
|
|
22912
22931
|
writeCarry(sessionId ?? void 0, getCurrentCommit());
|
|
22913
22932
|
}
|
|
@@ -22991,20 +23010,56 @@ function buildCompactionContext(session) {
|
|
|
22991
23010
|
const trimmed = [...lines.slice(0, 5), ...lines.slice(5, 5 + 2)].join("\n");
|
|
22992
23011
|
return trimmed.length <= MAX_CHARS ? trimmed : null;
|
|
22993
23012
|
}
|
|
23013
|
+
var MAX_HOOK_EVENT_BYTES = 64 * 1024;
|
|
23014
|
+
var SESSION_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
23015
|
+
var HOOK_WORD = /^[a-z][a-z_]{0,63}$/;
|
|
23016
|
+
function isHookSessionId(value) {
|
|
23017
|
+
return typeof value === "string" && SESSION_ID.test(value);
|
|
23018
|
+
}
|
|
23019
|
+
function hookWord(value) {
|
|
23020
|
+
return typeof value === "string" && HOOK_WORD.test(value) ? value : void 0;
|
|
23021
|
+
}
|
|
23022
|
+
function resolveHookSession(flag, event, env) {
|
|
23023
|
+
if (flag !== void 0) return isHookSessionId(flag) ? { ok: true, sessionId: flag } : { ok: false };
|
|
23024
|
+
if (event.session_id) return { ok: true, sessionId: event.session_id };
|
|
23025
|
+
return { ok: true, sessionId: isHookSessionId(env) ? env : null };
|
|
23026
|
+
}
|
|
23027
|
+
function parseHookEvent(raw) {
|
|
23028
|
+
let data;
|
|
23029
|
+
try {
|
|
23030
|
+
data = JSON.parse(raw.trim() || "{}");
|
|
23031
|
+
} catch {
|
|
23032
|
+
return {};
|
|
23033
|
+
}
|
|
23034
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) return {};
|
|
23035
|
+
const o = data;
|
|
23036
|
+
const event = {};
|
|
23037
|
+
if (isHookSessionId(o.session_id)) event.session_id = o.session_id;
|
|
23038
|
+
const compaction = hookWord(o.compaction_type);
|
|
23039
|
+
if (compaction) event.compaction_type = compaction;
|
|
23040
|
+
const endReason = hookWord(o.session_end_reason);
|
|
23041
|
+
if (endReason) event.session_end_reason = endReason;
|
|
23042
|
+
const reason = hookWord(o.reason);
|
|
23043
|
+
if (reason) event.reason = reason;
|
|
23044
|
+
return event;
|
|
23045
|
+
}
|
|
22994
23046
|
async function readHookStdin() {
|
|
22995
23047
|
try {
|
|
22996
23048
|
if (process.stdin.isTTY) return {};
|
|
22997
23049
|
const chunks = [];
|
|
23050
|
+
let size = 0;
|
|
22998
23051
|
const timeout = new Promise((resolve9) => setTimeout(() => resolve9({}), 500));
|
|
22999
23052
|
const read2 = new Promise((resolve9) => {
|
|
23000
|
-
process.stdin.on("data", (c) =>
|
|
23001
|
-
|
|
23002
|
-
|
|
23003
|
-
|
|
23004
|
-
} catch {
|
|
23053
|
+
process.stdin.on("data", (c) => {
|
|
23054
|
+
size += c.length;
|
|
23055
|
+
if (size > MAX_HOOK_EVENT_BYTES) {
|
|
23056
|
+
process.stdin.destroy();
|
|
23005
23057
|
resolve9({});
|
|
23058
|
+
return;
|
|
23006
23059
|
}
|
|
23060
|
+
chunks.push(c);
|
|
23007
23061
|
});
|
|
23062
|
+
process.stdin.on("end", () => resolve9(parseHookEvent(Buffer.concat(chunks).toString("utf-8"))));
|
|
23008
23063
|
process.stdin.on("error", () => resolve9({}));
|
|
23009
23064
|
process.stdin.resume();
|
|
23010
23065
|
});
|
|
@@ -23828,8 +23883,8 @@ async function correctVerityMdVersion(opts) {
|
|
|
23828
23883
|
origin: { kind: "synthesized", tools: opts.tools }
|
|
23829
23884
|
}));
|
|
23830
23885
|
}
|
|
23831
|
-
async function writeFileTo(
|
|
23832
|
-
const target = projectPath(
|
|
23886
|
+
async function writeFileTo(relative7, body2) {
|
|
23887
|
+
const target = projectPath(relative7);
|
|
23833
23888
|
await (0, import_promises10.mkdir)((0, import_node_path29.dirname)(target), { recursive: true });
|
|
23834
23889
|
await (0, import_promises10.writeFile)(target, body2);
|
|
23835
23890
|
}
|
|
@@ -24908,7 +24963,7 @@ function registerStatusCommand(program2) {
|
|
|
24908
24963
|
{
|
|
24909
24964
|
const tokenForScope = tokenResult.data.token;
|
|
24910
24965
|
const found = resolveIgnoreState(
|
|
24911
|
-
ignoreStateKeys(tokenForScope,
|
|
24966
|
+
ignoreStateKeys(tokenForScope, envSessionId())
|
|
24912
24967
|
);
|
|
24913
24968
|
const now = Math.floor(Date.now() / 1e3);
|
|
24914
24969
|
const active = resolveActive(found?.state ?? null, now);
|
|
@@ -25101,7 +25156,7 @@ async function sendGeneralFeedback(message, opts, globals) {
|
|
|
25101
25156
|
process.exit(1);
|
|
25102
25157
|
}
|
|
25103
25158
|
const body2 = { message };
|
|
25104
|
-
const sessionId = opts.sessionId ??
|
|
25159
|
+
const sessionId = opts.sessionId ?? envSessionId();
|
|
25105
25160
|
const model = opts.model ?? process.env.CLAUDE_MODEL ?? "unknown";
|
|
25106
25161
|
if (sessionId) body2.session_id = sessionId;
|
|
25107
25162
|
if (model) body2.agent_model = model;
|
|
@@ -26345,7 +26400,7 @@ function resolveFrame(input) {
|
|
|
26345
26400
|
const hookDirUsable = !!input.hookCwd && (0, import_node_fs40.existsSync)(input.hookCwd);
|
|
26346
26401
|
const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
|
|
26347
26402
|
let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
|
|
26348
|
-
const
|
|
26403
|
+
const refuse2 = (refusal) => ({
|
|
26349
26404
|
moment: found?.moment ?? null,
|
|
26350
26405
|
frame: { worktreeRoot: null, gitDir: null, commonDir: null, isLinkedWorktree: false, branch: null, anchor, refusal }
|
|
26351
26406
|
});
|
|
@@ -26359,19 +26414,19 @@ function resolveFrame(input) {
|
|
|
26359
26414
|
if (!kindRes.some((re) => re.test(segments[i2]))) continue;
|
|
26360
26415
|
const target = extractCommandTarget(input.command, i2, baseDir);
|
|
26361
26416
|
if (target.named) anchor = "command-target";
|
|
26362
|
-
if (target.unresolvable) return
|
|
26417
|
+
if (target.unresolvable) return refuse2(`target:${target.unresolvable}`);
|
|
26363
26418
|
dirs.add(target.dir ?? baseDir);
|
|
26364
26419
|
}
|
|
26365
|
-
if (dirs.size > 1) return
|
|
26420
|
+
if (dirs.size > 1) return refuse2(`target:multiple ${found.moment} targets in one command`);
|
|
26366
26421
|
const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
|
|
26367
26422
|
if (targetDir !== baseDir) {
|
|
26368
|
-
if (!(0, import_node_fs40.existsSync)(targetDir)) return
|
|
26423
|
+
if (!(0, import_node_fs40.existsSync)(targetDir)) return refuse2(`target:directory does not exist: ${targetDir}`);
|
|
26369
26424
|
dir = targetDir;
|
|
26370
26425
|
}
|
|
26371
26426
|
}
|
|
26372
26427
|
const toplevel = gitAt(dir, ["rev-parse", "--show-toplevel"]);
|
|
26373
26428
|
if (!toplevel) {
|
|
26374
|
-
return
|
|
26429
|
+
return refuse2(anchor === "command-target" ? `target:not a git repository: ${dir}` : `anchor:not a git repository: ${dir}`);
|
|
26375
26430
|
}
|
|
26376
26431
|
const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
|
|
26377
26432
|
const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
|
|
@@ -26967,7 +27022,7 @@ function sanitizeCommandWithLoss(rawCmd) {
|
|
|
26967
27022
|
const lost = lines.slice(1).some((l) => l.trim().length > 0);
|
|
26968
27023
|
const first = lines[0];
|
|
26969
27024
|
const cmd = sanitizeCommand(first);
|
|
26970
|
-
const hadSeparator = SEPARATORS.some((
|
|
27025
|
+
const hadSeparator = SEPARATORS.some((sep7) => first.indexOf(sep7) > 0);
|
|
26971
27026
|
return { cmd, lost: lost || !hadSeparator && first.length > MAX_COMMAND_CHARS };
|
|
26972
27027
|
}
|
|
26973
27028
|
var SEPARATORS = [" | ", " > ", " >> ", " 2>", " && ", " ; "];
|
|
@@ -26976,11 +27031,11 @@ function sanitizeCommand(rawCmd) {
|
|
|
26976
27031
|
let cmd = rawCmd.split("\n")[0];
|
|
26977
27032
|
let cut = -1;
|
|
26978
27033
|
let marker = "";
|
|
26979
|
-
for (const
|
|
26980
|
-
const idx = cmd.indexOf(
|
|
27034
|
+
for (const sep7 of SEPARATORS) {
|
|
27035
|
+
const idx = cmd.indexOf(sep7);
|
|
26981
27036
|
if (idx > 0 && (cut === -1 || idx < cut)) {
|
|
26982
27037
|
cut = idx;
|
|
26983
|
-
marker =
|
|
27038
|
+
marker = sep7.trim();
|
|
26984
27039
|
}
|
|
26985
27040
|
}
|
|
26986
27041
|
if (cut > -1) cmd = cmd.slice(0, cut);
|
|
@@ -27047,13 +27102,13 @@ async function bootstrap(run4) {
|
|
|
27047
27102
|
isTTY: process.stdout.isTTY === true
|
|
27048
27103
|
});
|
|
27049
27104
|
const { assistantMessage: assistantResponse, stopReason, transcriptPath, sessionId } = await readStopHookStdin();
|
|
27050
|
-
if (deferredToPlugin("analyze", sessionId ??
|
|
27105
|
+
if (deferredToPlugin("analyze", sessionId ?? envSessionId() ?? null)) {
|
|
27051
27106
|
process.exit(0);
|
|
27052
27107
|
}
|
|
27053
27108
|
const actionSummary = transcriptPath ? await extractActionSummary(transcriptPath) : null;
|
|
27054
27109
|
const tokenResult = await resolveToken(globals.token);
|
|
27055
27110
|
const scopeToken = tokenResult.ok ? tokenResult.data.token : void 0;
|
|
27056
|
-
const rawSessionId = sessionId ||
|
|
27111
|
+
const rawSessionId = sessionId || envSessionId();
|
|
27057
27112
|
const baselineSessionId = sessionScopeKey(scopeToken, rawSessionId);
|
|
27058
27113
|
if (tokenResult.ok) {
|
|
27059
27114
|
run4.beacon = {
|
|
@@ -27258,7 +27313,7 @@ function channelSilence(input) {
|
|
|
27258
27313
|
// src/lib/cli-version.ts
|
|
27259
27314
|
function cliVersion() {
|
|
27260
27315
|
try {
|
|
27261
|
-
return true ? "0.34.
|
|
27316
|
+
return true ? "0.34.2-experimental.3b25de0" : "dev";
|
|
27262
27317
|
} catch {
|
|
27263
27318
|
return "dev";
|
|
27264
27319
|
}
|
|
@@ -28059,7 +28114,7 @@ async function connect(run4) {
|
|
|
28059
28114
|
async function mode(run4) {
|
|
28060
28115
|
const { opts, globals } = run4;
|
|
28061
28116
|
const { actionSummary, allForReview, assistantResponse, baseline, conversation, memory: memory2, noFilesChanged, serviceUrl, sessionId, token, turnAuthoredCode } = run4;
|
|
28062
|
-
const sessionIdForMemory = sessionId ||
|
|
28117
|
+
const sessionIdForMemory = sessionId || envSessionId() || "";
|
|
28063
28118
|
let predictedMode;
|
|
28064
28119
|
try {
|
|
28065
28120
|
const memoryPath2 = sessionIdForMemory ? `/memory?session_id=${encodeURIComponent(sessionIdForMemory)}` : "/memory";
|
|
@@ -31952,7 +32007,7 @@ async function workingMemory(run4) {
|
|
|
31952
32007
|
const { opts } = run4;
|
|
31953
32008
|
const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run4;
|
|
31954
32009
|
let { reachability } = run4;
|
|
31955
|
-
const memorySession = sessionDossier(token, sessionId ??
|
|
32010
|
+
const memorySession = sessionDossier(token, sessionId ?? envSessionId() ?? null);
|
|
31956
32011
|
let memory2 = null;
|
|
31957
32012
|
let incrementReport = null;
|
|
31958
32013
|
if (memorySession) {
|
|
@@ -32225,7 +32280,7 @@ async function buildRequest(run4) {
|
|
|
32225
32280
|
context: {
|
|
32226
32281
|
agent_model: process.env.CLAUDE_MODEL ?? "unknown",
|
|
32227
32282
|
agent_harness: "claude-code",
|
|
32228
|
-
session_id: sessionId ||
|
|
32283
|
+
session_id: sessionId || envSessionId() || "unknown",
|
|
32229
32284
|
iteration,
|
|
32230
32285
|
// Makes fleet composition falsifiable — without it, no adoption-gated
|
|
32231
32286
|
// rollout decision can be checked against anything.
|
|
@@ -33522,12 +33577,12 @@ function registerBaselineCommands(program2) {
|
|
|
33522
33577
|
if (!process.stdin.isTTY) {
|
|
33523
33578
|
const input = (await readStdin()).trim();
|
|
33524
33579
|
if (input) {
|
|
33525
|
-
const event =
|
|
33580
|
+
const event = parseHookEvent2(input);
|
|
33526
33581
|
if (opts.sessionId === void 0) sessionId = event.sessionId;
|
|
33527
33582
|
if (opts.source === void 0) source2 = event.source;
|
|
33528
33583
|
}
|
|
33529
33584
|
}
|
|
33530
|
-
const session = sessionId ?? validSessionId(
|
|
33585
|
+
const session = sessionId ?? validSessionId(envSessionId());
|
|
33531
33586
|
const cli = pluginCliInvocation();
|
|
33532
33587
|
const skew = cliVersionSkew();
|
|
33533
33588
|
const why = skew ? `the \`verity\` on PATH is ${skew.global} but the hooks run ${skew.hooks}, so it is not the CLI they use` : verityOnPath() ? "the `verity` on PATH is a separate install whose version could not be read" : "this machine has no `verity` on PATH \u2014 the plugin carries its own copy";
|
|
@@ -33647,7 +33702,7 @@ function registerBaselineCommands(program2) {
|
|
|
33647
33702
|
process.exit(0);
|
|
33648
33703
|
});
|
|
33649
33704
|
}
|
|
33650
|
-
var
|
|
33705
|
+
var MAX_HOOK_EVENT_BYTES2 = 64 * 1024;
|
|
33651
33706
|
var HOOK_SOURCES = /* @__PURE__ */ new Set(["startup", "resume", "clear", "compact"]);
|
|
33652
33707
|
var SESSION_ID_RE2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
33653
33708
|
async function readStdin() {
|
|
@@ -33655,11 +33710,11 @@ async function readStdin() {
|
|
|
33655
33710
|
let size = 0;
|
|
33656
33711
|
for await (const chunk of process.stdin) {
|
|
33657
33712
|
size += chunk.length;
|
|
33658
|
-
if (size <=
|
|
33713
|
+
if (size <= MAX_HOOK_EVENT_BYTES2) chunks.push(chunk);
|
|
33659
33714
|
}
|
|
33660
|
-
return size >
|
|
33715
|
+
return size > MAX_HOOK_EVENT_BYTES2 ? "" : Buffer.concat(chunks).toString("utf-8");
|
|
33661
33716
|
}
|
|
33662
|
-
function
|
|
33717
|
+
function parseHookEvent2(input) {
|
|
33663
33718
|
let event;
|
|
33664
33719
|
try {
|
|
33665
33720
|
event = JSON.parse(input);
|
|
@@ -33680,6 +33735,34 @@ function hookSource(value) {
|
|
|
33680
33735
|
|
|
33681
33736
|
// src/commands/review.ts
|
|
33682
33737
|
var import_node_fs57 = require("node:fs");
|
|
33738
|
+
var import_node_path44 = require("node:path");
|
|
33739
|
+
function containReviewPaths(paths, base) {
|
|
33740
|
+
const kept = [];
|
|
33741
|
+
const refused2 = [];
|
|
33742
|
+
for (const raw of paths) {
|
|
33743
|
+
const candidate = (0, import_node_path44.isAbsolute)(raw) ? relativeForm(base, raw) : raw;
|
|
33744
|
+
if (candidate === "" || resolveInside(base, candidate) === null) refused2.push(raw);
|
|
33745
|
+
else kept.push(candidate);
|
|
33746
|
+
}
|
|
33747
|
+
return { kept, refused: refused2 };
|
|
33748
|
+
}
|
|
33749
|
+
function relativeForm(base, abs) {
|
|
33750
|
+
const lexical = (0, import_node_path44.relative)(base, abs);
|
|
33751
|
+
if (!(lexical === ".." || lexical.startsWith(`..${import_node_path44.sep}`) || (0, import_node_path44.isAbsolute)(lexical))) return lexical;
|
|
33752
|
+
try {
|
|
33753
|
+
let dir = (0, import_node_path44.dirname)(abs);
|
|
33754
|
+
let rest = (0, import_node_path44.basename)(abs);
|
|
33755
|
+
while (!(0, import_node_fs57.existsSync)(dir)) {
|
|
33756
|
+
const up = (0, import_node_path44.dirname)(dir);
|
|
33757
|
+
if (up === dir) return lexical;
|
|
33758
|
+
rest = (0, import_node_path44.join)((0, import_node_path44.basename)(dir), rest);
|
|
33759
|
+
dir = up;
|
|
33760
|
+
}
|
|
33761
|
+
return (0, import_node_path44.relative)((0, import_node_fs57.realpathSync)(base), (0, import_node_path44.join)((0, import_node_fs57.realpathSync)(dir), rest));
|
|
33762
|
+
} catch {
|
|
33763
|
+
return lexical;
|
|
33764
|
+
}
|
|
33765
|
+
}
|
|
33683
33766
|
function registerReviewCommand(program2) {
|
|
33684
33767
|
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); - reads it from stdin, so the words never pass through shell quoting").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
|
|
33685
33768
|
const globals = program2.opts();
|
|
@@ -33698,8 +33781,20 @@ function registerReviewCommand(program2) {
|
|
|
33698
33781
|
});
|
|
33699
33782
|
}
|
|
33700
33783
|
async function runReview(opts, globals) {
|
|
33701
|
-
const
|
|
33702
|
-
const
|
|
33784
|
+
const base = process.cwd();
|
|
33785
|
+
const files = containReviewPaths(opts.files.split(",").map((f) => f.trim()).filter(Boolean), base);
|
|
33786
|
+
const changed = opts.changed ? containReviewPaths(opts.changed.split(",").map((f) => f.trim()).filter(Boolean), base) : files;
|
|
33787
|
+
const refused2 = Array.from(/* @__PURE__ */ new Set([...files.refused, ...changed.refused]));
|
|
33788
|
+
if (refused2.length > 0) {
|
|
33789
|
+
printJsonCompact({
|
|
33790
|
+
gate_decision: "WARN",
|
|
33791
|
+
systemMessage: `Verity: refused ${refused2.length} path(s) outside this repository \u2014 nothing was reviewed. Pass paths inside the repository you run \`verity review\` from.`,
|
|
33792
|
+
refused_paths: refused2
|
|
33793
|
+
});
|
|
33794
|
+
process.exit(0);
|
|
33795
|
+
}
|
|
33796
|
+
const allFiles = files.kept;
|
|
33797
|
+
const changedFiles = changed.kept;
|
|
33703
33798
|
const analyzable = filterAnalyzable(allFiles);
|
|
33704
33799
|
const securityFiles = filterSecurity(allFiles);
|
|
33705
33800
|
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs57.existsSync)(f) || resolveFile(f) !== null);
|
|
@@ -33727,7 +33822,7 @@ async function runReview(opts, globals) {
|
|
|
33727
33822
|
context: {
|
|
33728
33823
|
agent_model: process.env.CLAUDE_MODEL ?? "unknown",
|
|
33729
33824
|
agent_harness: "claude-code",
|
|
33730
|
-
session_id:
|
|
33825
|
+
session_id: envSessionId() ?? "unknown",
|
|
33731
33826
|
trigger: "review",
|
|
33732
33827
|
iteration: 1
|
|
33733
33828
|
}
|
|
@@ -33768,12 +33863,12 @@ async function runReview(opts, globals) {
|
|
|
33768
33863
|
}
|
|
33769
33864
|
|
|
33770
33865
|
// src/commands/guard.ts
|
|
33771
|
-
var
|
|
33772
|
-
var
|
|
33866
|
+
var import_node_fs63 = require("node:fs");
|
|
33867
|
+
var import_node_path51 = require("node:path");
|
|
33773
33868
|
|
|
33774
33869
|
// src/lib/vendored.ts
|
|
33775
33870
|
var import_node_fs58 = require("node:fs");
|
|
33776
|
-
var
|
|
33871
|
+
var import_node_path45 = require("node:path");
|
|
33777
33872
|
var INSTALLED_SKILL = /^\.claude\/skills\/(verity-[a-z0-9-]+)\/(.+)$/;
|
|
33778
33873
|
function dataDirOrNull() {
|
|
33779
33874
|
try {
|
|
@@ -33788,7 +33883,7 @@ function shippedSkillFile(path, dataDir = dataDirOrNull()) {
|
|
|
33788
33883
|
const [, skill, rel] = m;
|
|
33789
33884
|
if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
|
|
33790
33885
|
try {
|
|
33791
|
-
return (0, import_node_fs58.readFileSync)((0,
|
|
33886
|
+
return (0, import_node_fs58.readFileSync)((0, import_node_path45.join)(dataDir, "skills", skill, rel), "utf8");
|
|
33792
33887
|
} catch {
|
|
33793
33888
|
return null;
|
|
33794
33889
|
}
|
|
@@ -33897,8 +33992,33 @@ async function runAgentReview(options) {
|
|
|
33897
33992
|
return { kind: "finished", response: finished.data };
|
|
33898
33993
|
}
|
|
33899
33994
|
|
|
33995
|
+
// src/lib/effort.ts
|
|
33996
|
+
var import_node_fs59 = require("node:fs");
|
|
33997
|
+
var import_node_path46 = require("node:path");
|
|
33998
|
+
var import_yaml5 = __toESM2(require_dist());
|
|
33999
|
+
var EFFORT_PROFILES = {
|
|
34000
|
+
default: { pushDeadlineMs: 18e4, formal: { tier: "fast", maxRounds: 2, minScore: 0.7, costCapUsd: 1, maxTargets: 1, relaxedGates: false, dailyModels: 5, dailyCostUsd: 5 } },
|
|
34001
|
+
high: { pushDeadlineMs: 22e4, formal: { tier: "deep", maxRounds: 2, minScore: 0.6, costCapUsd: 2, maxTargets: 2, relaxedGates: false, dailyModels: 15, dailyCostUsd: 15 } },
|
|
34002
|
+
max: { pushDeadlineMs: 27e4, formal: { tier: "deep", maxRounds: 3, minScore: 0.5, costCapUsd: 4, maxTargets: 3, relaxedGates: true, dailyModels: 30, dailyCostUsd: 30 } }
|
|
34003
|
+
};
|
|
34004
|
+
function asEffort(value) {
|
|
34005
|
+
return value === "high" || value === "max" ? value : "default";
|
|
34006
|
+
}
|
|
34007
|
+
function resolveEffort(root, env = process.env) {
|
|
34008
|
+
if (env.VERITY_EFFORT) return asEffort(env.VERITY_EFFORT);
|
|
34009
|
+
try {
|
|
34010
|
+
const standard = (0, import_yaml5.parse)((0, import_node_fs59.readFileSync)((0, import_node_path46.join)(root, STANDARD_FILE), "utf8"));
|
|
34011
|
+
return asEffort(standard?.process_constraints?.git_moment_effort);
|
|
34012
|
+
} catch {
|
|
34013
|
+
return "default";
|
|
34014
|
+
}
|
|
34015
|
+
}
|
|
34016
|
+
function effortProfile(root, env = process.env) {
|
|
34017
|
+
return EFFORT_PROFILES[resolveEffort(root, env)];
|
|
34018
|
+
}
|
|
34019
|
+
|
|
33900
34020
|
// src/lib/prove/auto.ts
|
|
33901
|
-
var
|
|
34021
|
+
var import_node_path50 = require("node:path");
|
|
33902
34022
|
var import_node_crypto19 = require("node:crypto");
|
|
33903
34023
|
|
|
33904
34024
|
// src/lib/prove/signals.ts
|
|
@@ -35585,9 +35705,9 @@ async function runReplay(brief, opts) {
|
|
|
35585
35705
|
if (opts.auth) return runReplayViaServer(brief, opts.auth, opts.timeoutMs);
|
|
35586
35706
|
const env = opts.env ?? process.env;
|
|
35587
35707
|
const none = { covered: 0, total: 0, ratio: 0, basis: "none" };
|
|
35588
|
-
const
|
|
35589
|
-
if (env.VERITY_PROVE_DIRECT !== "1") return
|
|
35590
|
-
if (!opts.apiKey) return
|
|
35708
|
+
const refuse2 = (error) => ({ claimed: null, verdict: "unverified", reason: "", downgrade: error, executedCalls: 0, shellCalls: 0, verbatim: none, executedOutput: "", harnessFiles: [], usage: null, durationMs: 0, containerId: null, error });
|
|
35709
|
+
if (env.VERITY_PROVE_DIRECT !== "1") return refuse2("not logged in (run `verity login`); replays run on the Verity service");
|
|
35710
|
+
if (!opts.apiKey) return refuse2("OPENAI_API_KEY is not set");
|
|
35591
35711
|
return runReplayInContainer(brief, { apiKey: opts.apiKey, model: opts.model, timeoutMs: opts.timeoutMs, maxRounds: opts.maxRounds, fetchImpl: opts.fetchImpl });
|
|
35592
35712
|
}
|
|
35593
35713
|
function renderReplay(model, property, r) {
|
|
@@ -35625,18 +35745,18 @@ function renderReplay(model, property, r) {
|
|
|
35625
35745
|
// src/lib/prove/runner.ts
|
|
35626
35746
|
var import_node_child_process15 = require("node:child_process");
|
|
35627
35747
|
var import_node_os8 = require("node:os");
|
|
35628
|
-
var
|
|
35748
|
+
var import_node_fs62 = require("node:fs");
|
|
35629
35749
|
var import_node_os9 = require("node:os");
|
|
35630
|
-
var
|
|
35750
|
+
var import_node_path49 = require("node:path");
|
|
35631
35751
|
|
|
35632
35752
|
// src/lib/prove/scaffold.ts
|
|
35633
|
-
var
|
|
35634
|
-
var
|
|
35753
|
+
var import_node_fs61 = require("node:fs");
|
|
35754
|
+
var import_node_path48 = require("node:path");
|
|
35635
35755
|
|
|
35636
35756
|
// src/lib/prove/safe-write.ts
|
|
35637
|
-
var
|
|
35757
|
+
var import_node_fs60 = require("node:fs");
|
|
35638
35758
|
var import_node_crypto15 = require("node:crypto");
|
|
35639
|
-
var
|
|
35759
|
+
var import_node_path47 = require("node:path");
|
|
35640
35760
|
var SafeWriteError = class extends Error {
|
|
35641
35761
|
constructor(reason, path) {
|
|
35642
35762
|
super(`refusing to write ${path}: ${reason}`);
|
|
@@ -35645,10 +35765,10 @@ var SafeWriteError = class extends Error {
|
|
|
35645
35765
|
this.name = "SafeWriteError";
|
|
35646
35766
|
}
|
|
35647
35767
|
};
|
|
35648
|
-
var FLAGS3 =
|
|
35768
|
+
var FLAGS3 = import_node_fs60.constants;
|
|
35649
35769
|
var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
|
|
35650
35770
|
function assertPlainRelative(rel) {
|
|
35651
|
-
if (!rel || (0,
|
|
35771
|
+
if (!rel || (0, import_node_path47.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
|
|
35652
35772
|
for (const part of rel.split(/[\\/]/)) {
|
|
35653
35773
|
if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
|
|
35654
35774
|
}
|
|
@@ -35657,34 +35777,34 @@ function ensureDirsNoFollow(root, rel) {
|
|
|
35657
35777
|
const parts2 = rel.split(/[\\/]/);
|
|
35658
35778
|
let cur = root;
|
|
35659
35779
|
for (const part of parts2.slice(0, -1)) {
|
|
35660
|
-
cur = (0,
|
|
35780
|
+
cur = (0, import_node_path47.join)(cur, part);
|
|
35661
35781
|
let st;
|
|
35662
35782
|
try {
|
|
35663
|
-
st = (0,
|
|
35783
|
+
st = (0, import_node_fs60.lstatSync)(cur);
|
|
35664
35784
|
} catch {
|
|
35665
|
-
(0,
|
|
35785
|
+
(0, import_node_fs60.mkdirSync)(cur);
|
|
35666
35786
|
continue;
|
|
35667
35787
|
}
|
|
35668
35788
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
|
|
35669
35789
|
if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
|
|
35670
35790
|
}
|
|
35671
|
-
return (0,
|
|
35791
|
+
return (0, import_node_path47.join)(root, rel);
|
|
35672
35792
|
}
|
|
35673
35793
|
function insideRoot(realRoot, realPath) {
|
|
35674
|
-
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(
|
|
35794
|
+
return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path47.sep) ? realRoot : realRoot + import_node_path47.sep);
|
|
35675
35795
|
}
|
|
35676
35796
|
function removeQuietly(path) {
|
|
35677
35797
|
try {
|
|
35678
|
-
(0,
|
|
35798
|
+
(0, import_node_fs60.unlinkSync)(path);
|
|
35679
35799
|
} catch {
|
|
35680
35800
|
}
|
|
35681
35801
|
}
|
|
35682
35802
|
function writeFileInRootNoFollow(root, rel, content) {
|
|
35683
35803
|
assertPlainRelative(rel);
|
|
35684
35804
|
const dest = ensureDirsNoFollow(root, rel);
|
|
35685
|
-
const dir = (0,
|
|
35805
|
+
const dir = (0, import_node_path47.dirname)(dest);
|
|
35686
35806
|
try {
|
|
35687
|
-
const st = (0,
|
|
35807
|
+
const st = (0, import_node_fs60.lstatSync)(dest);
|
|
35688
35808
|
if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
|
|
35689
35809
|
if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
|
|
35690
35810
|
} catch (err2) {
|
|
@@ -35692,41 +35812,41 @@ function writeFileInRootNoFollow(root, rel, content) {
|
|
|
35692
35812
|
}
|
|
35693
35813
|
let realRoot;
|
|
35694
35814
|
try {
|
|
35695
|
-
realRoot = (0,
|
|
35815
|
+
realRoot = (0, import_node_fs60.realpathSync)(root);
|
|
35696
35816
|
} catch {
|
|
35697
35817
|
throw new SafeWriteError("unwritable", root);
|
|
35698
35818
|
}
|
|
35699
|
-
const tmp = (0,
|
|
35819
|
+
const tmp = (0, import_node_path47.join)(dir, `.${(0, import_node_path47.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
|
|
35700
35820
|
let fd;
|
|
35701
35821
|
try {
|
|
35702
|
-
fd = (0,
|
|
35822
|
+
fd = (0, import_node_fs60.openSync)(tmp, import_node_fs60.constants.O_WRONLY | import_node_fs60.constants.O_CREAT | import_node_fs60.constants.O_EXCL | NOFOLLOW2, 420);
|
|
35703
35823
|
} catch {
|
|
35704
35824
|
throw new SafeWriteError("unwritable", tmp);
|
|
35705
35825
|
}
|
|
35706
35826
|
try {
|
|
35707
|
-
const opened = (0,
|
|
35827
|
+
const opened = (0, import_node_fs60.fstatSync)(fd, { bigint: true });
|
|
35708
35828
|
let realTmp;
|
|
35709
35829
|
try {
|
|
35710
|
-
realTmp = (0,
|
|
35830
|
+
realTmp = (0, import_node_fs60.realpathSync)(tmp);
|
|
35711
35831
|
} catch {
|
|
35712
35832
|
throw new SafeWriteError("escaped", tmp);
|
|
35713
35833
|
}
|
|
35714
|
-
const there = (0,
|
|
35834
|
+
const there = (0, import_node_fs60.lstatSync)(realTmp, { bigint: true });
|
|
35715
35835
|
if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
|
|
35716
35836
|
throw new SafeWriteError("escaped", tmp);
|
|
35717
35837
|
}
|
|
35718
35838
|
const buf = Buffer.from(content, "utf-8");
|
|
35719
35839
|
let off = 0;
|
|
35720
|
-
while (off < buf.length) off += (0,
|
|
35840
|
+
while (off < buf.length) off += (0, import_node_fs60.writeSync)(fd, buf, off, buf.length - off);
|
|
35721
35841
|
} catch (err2) {
|
|
35722
|
-
(0,
|
|
35842
|
+
(0, import_node_fs60.closeSync)(fd);
|
|
35723
35843
|
removeQuietly(tmp);
|
|
35724
35844
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
|
|
35725
35845
|
}
|
|
35726
|
-
(0,
|
|
35846
|
+
(0, import_node_fs60.closeSync)(fd);
|
|
35727
35847
|
try {
|
|
35728
|
-
if (!insideRoot(realRoot, (0,
|
|
35729
|
-
(0,
|
|
35848
|
+
if (!insideRoot(realRoot, (0, import_node_fs60.realpathSync)(dir)) || (0, import_node_fs60.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
|
|
35849
|
+
(0, import_node_fs60.renameSync)(tmp, dest);
|
|
35730
35850
|
} catch (err2) {
|
|
35731
35851
|
removeQuietly(tmp);
|
|
35732
35852
|
throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
|
|
@@ -35740,9 +35860,9 @@ function pathHasNoLink(root, rel) {
|
|
|
35740
35860
|
}
|
|
35741
35861
|
let cur = root;
|
|
35742
35862
|
for (const part of rel.split(/[\\/]/)) {
|
|
35743
|
-
cur = cur +
|
|
35863
|
+
cur = cur + import_node_path47.sep + part;
|
|
35744
35864
|
try {
|
|
35745
|
-
if ((0,
|
|
35865
|
+
if ((0, import_node_fs60.lstatSync)(cur).isSymbolicLink()) return false;
|
|
35746
35866
|
} catch {
|
|
35747
35867
|
return true;
|
|
35748
35868
|
}
|
|
@@ -36052,20 +36172,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
|
|
|
36052
36172
|
never committed; what reaches the team is the bug report and the fix.
|
|
36053
36173
|
`;
|
|
36054
36174
|
function scaffoldProofs(root) {
|
|
36055
|
-
const proofsDir = (0,
|
|
36175
|
+
const proofsDir = (0, import_node_path48.join)(root, PROOFS_DIR);
|
|
36056
36176
|
const written = [];
|
|
36057
36177
|
const kept = [];
|
|
36058
36178
|
for (const stray of ["lakefile.lean"]) {
|
|
36059
36179
|
const rel = `${PROOFS_DIR}/${stray}`;
|
|
36060
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
36180
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path48.join)(root, rel));
|
|
36061
36181
|
try {
|
|
36062
|
-
(0,
|
|
36182
|
+
(0, import_node_fs61.rmSync)((0, import_node_path48.join)(root, rel), { force: true });
|
|
36063
36183
|
} catch {
|
|
36064
36184
|
}
|
|
36065
36185
|
}
|
|
36066
36186
|
for (const f of PROOFS_TEMPLATE_FILES) {
|
|
36067
36187
|
const rel = `${PROOFS_DIR}/${f.path}`;
|
|
36068
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
36188
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path48.join)(root, rel));
|
|
36069
36189
|
const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
|
|
36070
36190
|
if (current.ok && current.content === f.content) {
|
|
36071
36191
|
kept.push(rel);
|
|
@@ -36078,8 +36198,8 @@ function scaffoldProofs(root) {
|
|
|
36078
36198
|
[`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
|
|
36079
36199
|
[`${MODELS_DIR}/README.md`, MODELS_README]
|
|
36080
36200
|
]) {
|
|
36081
|
-
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0,
|
|
36082
|
-
if (existsNoFollow((0,
|
|
36201
|
+
if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path48.join)(root, rel));
|
|
36202
|
+
if (existsNoFollow((0, import_node_path48.join)(root, rel))) {
|
|
36083
36203
|
kept.push(rel);
|
|
36084
36204
|
continue;
|
|
36085
36205
|
}
|
|
@@ -36090,7 +36210,7 @@ function scaffoldProofs(root) {
|
|
|
36090
36210
|
}
|
|
36091
36211
|
function existsNoFollow(abs) {
|
|
36092
36212
|
try {
|
|
36093
|
-
(0,
|
|
36213
|
+
(0, import_node_fs61.lstatSync)(abs);
|
|
36094
36214
|
return true;
|
|
36095
36215
|
} catch {
|
|
36096
36216
|
return false;
|
|
@@ -36348,17 +36468,17 @@ function renderReport(r) {
|
|
|
36348
36468
|
|
|
36349
36469
|
// src/lib/prove/runner.ts
|
|
36350
36470
|
function verityLeanHome(env = process.env) {
|
|
36351
|
-
return env.VERITY_LEAN_HOME ?? (0,
|
|
36471
|
+
return env.VERITY_LEAN_HOME ?? (0, import_node_path49.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
|
|
36352
36472
|
}
|
|
36353
36473
|
function findToolchain(env = process.env) {
|
|
36354
|
-
const managedBin = (0,
|
|
36355
|
-
const elanBin = (0,
|
|
36356
|
-
const elanHas = (0,
|
|
36357
|
-
const userPath = (env.PATH ?? "").split(
|
|
36358
|
-
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(
|
|
36474
|
+
const managedBin = (0, import_node_path49.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
|
|
36475
|
+
const elanBin = (0, import_node_path49.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
|
|
36476
|
+
const elanHas = (0, import_node_fs62.existsSync)((0, import_node_path49.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
|
|
36477
|
+
const userPath = (env.PATH ?? "").split(import_node_path49.delimiter).filter((d) => d && (elanHas || (0, import_node_path49.resolve)(d) !== (0, import_node_path49.resolve)(elanBin)));
|
|
36478
|
+
const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path49.delimiter);
|
|
36359
36479
|
const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
|
|
36360
36480
|
const exe = process.platform === "win32" ? "lake.exe" : "lake";
|
|
36361
|
-
const candidates2 = [(0,
|
|
36481
|
+
const candidates2 = [(0, import_node_path49.join)(managedBin, exe), ...elanHas ? [(0, import_node_path49.join)(elanBin, exe)] : [], exe];
|
|
36362
36482
|
for (const candidate of candidates2) {
|
|
36363
36483
|
try {
|
|
36364
36484
|
(0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
|
|
@@ -36437,7 +36557,7 @@ function proofsWorkspaceProblem(root) {
|
|
|
36437
36557
|
for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
|
|
36438
36558
|
let st;
|
|
36439
36559
|
try {
|
|
36440
|
-
st = (0,
|
|
36560
|
+
st = (0, import_node_fs62.lstatSync)((0, import_node_path49.join)(root, rel));
|
|
36441
36561
|
} catch {
|
|
36442
36562
|
break;
|
|
36443
36563
|
}
|
|
@@ -36457,44 +36577,44 @@ function refused(problem) {
|
|
|
36457
36577
|
function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36458
36578
|
const problem = proofsWorkspaceProblem(root);
|
|
36459
36579
|
if (problem) return refused(problem);
|
|
36460
|
-
return run2(tc, (0,
|
|
36580
|
+
return run2(tc, (0, import_node_path49.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36461
36581
|
}
|
|
36462
36582
|
async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
|
|
36463
36583
|
const problem = proofsWorkspaceProblem(root);
|
|
36464
36584
|
if (problem) return refused(problem);
|
|
36465
|
-
return runAsync(tc, (0,
|
|
36585
|
+
return runAsync(tc, (0, import_node_path49.join)(root, PROOFS_DIR), ["build"], timeoutMs);
|
|
36466
36586
|
}
|
|
36467
36587
|
function isModelInRoot(modelsAbs, rel) {
|
|
36468
|
-
if (!rel.endsWith(".lean") || (0,
|
|
36588
|
+
if (!rel.endsWith(".lean") || (0, import_node_path49.isAbsolute)(rel) || rel.startsWith("..")) return false;
|
|
36469
36589
|
return statRegularInRoot(modelsAbs, rel).ok;
|
|
36470
36590
|
}
|
|
36471
36591
|
function resolveModelFile(root, arg) {
|
|
36472
|
-
const modelsAbs = (0,
|
|
36473
|
-
const asPath = (0,
|
|
36592
|
+
const modelsAbs = (0, import_node_path49.join)(root, MODELS_DIR);
|
|
36593
|
+
const asPath = (0, import_node_path49.relative)(modelsAbs, (0, import_node_path49.isAbsolute)(arg) ? arg : (0, import_node_path49.resolve)(root, arg));
|
|
36474
36594
|
const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
|
|
36475
36595
|
for (const rel of candidates2) {
|
|
36476
|
-
if (isModelInRoot(modelsAbs, rel)) return (0,
|
|
36596
|
+
if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path49.join)(modelsAbs, rel);
|
|
36477
36597
|
}
|
|
36478
36598
|
return null;
|
|
36479
36599
|
}
|
|
36480
36600
|
function listModelFiles(root) {
|
|
36481
|
-
const modelsAbs = (0,
|
|
36482
|
-
if (!(0,
|
|
36483
|
-
return (0,
|
|
36601
|
+
const modelsAbs = (0, import_node_path49.join)(root, MODELS_DIR);
|
|
36602
|
+
if (!(0, import_node_fs62.existsSync)(modelsAbs)) return [];
|
|
36603
|
+
return (0, import_node_fs62.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path49.join)(modelsAbs, f));
|
|
36484
36604
|
}
|
|
36485
36605
|
function trimDiagnostics(text) {
|
|
36486
36606
|
return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36487
36607
|
}
|
|
36488
36608
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36489
|
-
const proofsAbs = (0,
|
|
36490
|
-
const rel = (0,
|
|
36609
|
+
const proofsAbs = (0, import_node_path49.join)(root, PROOFS_DIR);
|
|
36610
|
+
const rel = (0, import_node_path49.relative)(proofsAbs, modelFile);
|
|
36491
36611
|
const problem = proofsWorkspaceProblem(root);
|
|
36492
36612
|
const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36493
36613
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36494
36614
|
}
|
|
36495
36615
|
async function checkModelAsync(tc, root, modelFile, opts = {}) {
|
|
36496
|
-
const proofsAbs = (0,
|
|
36497
|
-
const rel = (0,
|
|
36616
|
+
const proofsAbs = (0, import_node_path49.join)(root, PROOFS_DIR);
|
|
36617
|
+
const rel = (0, import_node_path49.relative)(proofsAbs, modelFile);
|
|
36498
36618
|
const problem = proofsWorkspaceProblem(root);
|
|
36499
36619
|
const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
36500
36620
|
return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
|
|
@@ -36503,10 +36623,10 @@ function toReport(res, root, modelFile, timeoutMs) {
|
|
|
36503
36623
|
const parsed = parseVerityLines(res.stdout);
|
|
36504
36624
|
const combined = `${res.stdout}
|
|
36505
36625
|
${res.stderr}`;
|
|
36506
|
-
const name2 = parsed.header?.model ?? (0,
|
|
36626
|
+
const name2 = parsed.header?.model ?? (0, import_node_path49.basename)(modelFile, ".lean");
|
|
36507
36627
|
const report = {
|
|
36508
36628
|
model: name2,
|
|
36509
|
-
file: (0,
|
|
36629
|
+
file: (0, import_node_path49.relative)(root, modelFile),
|
|
36510
36630
|
ok: res.ok,
|
|
36511
36631
|
header: parsed.header,
|
|
36512
36632
|
properties: parsed.properties,
|
|
@@ -36901,7 +37021,7 @@ async function runFormalPhase(input) {
|
|
|
36901
37021
|
}
|
|
36902
37022
|
}
|
|
36903
37023
|
if (kept.length !== persisted.length) writePersistedFindings(root, kept);
|
|
36904
|
-
if (standing.length > 0) {
|
|
37024
|
+
if (standing.length > 0 && !input.skipStanding) {
|
|
36905
37025
|
const first = kept.find((f) => f.file === standing[0].file);
|
|
36906
37026
|
return done({
|
|
36907
37027
|
status: "checked",
|
|
@@ -36929,7 +37049,7 @@ async function runFormalPhase(input) {
|
|
|
36929
37049
|
return a.source === "tree-sitter" && a.value.effects.length >= 2;
|
|
36930
37050
|
})());
|
|
36931
37051
|
};
|
|
36932
|
-
const eligible = signals.filter((s) => isEligible(s, largePush).ok || mapEligible(s.file)).slice(0, 5);
|
|
37052
|
+
const eligible = signals.filter((s) => input.relaxedGates || isEligible(s, largePush).ok || mapEligible(s.file)).slice(0, 5);
|
|
36933
37053
|
if (eligible.length === 0) {
|
|
36934
37054
|
const best = signals[0];
|
|
36935
37055
|
return done({ status: "skipped", skip: "not-eligible", detail: `${best.file}: ${isEligible(best, largePush).why}` });
|
|
@@ -36983,6 +37103,10 @@ async function runFormalPhase(input) {
|
|
|
36983
37103
|
}
|
|
36984
37104
|
}
|
|
36985
37105
|
if (d.resolved && d.resolved !== c.ai.symbol) c.ai.symbol = d.resolved;
|
|
37106
|
+
if (input.exclude?.has(`${c.file}#${c.ai.symbol}`)) {
|
|
37107
|
+
note("verified", `${c.ai.symbol}: modelled earlier in this push`);
|
|
37108
|
+
continue;
|
|
37109
|
+
}
|
|
36986
37110
|
if (input.changedLines) {
|
|
36987
37111
|
const changed = input.changedLines.get(c.file) ?? [];
|
|
36988
37112
|
if (changed.length === 0) {
|
|
@@ -37024,7 +37148,7 @@ async function runFormalPhase(input) {
|
|
|
37024
37148
|
const hazard = hasHazard(functionHazard(d.numbered));
|
|
37025
37149
|
const shared = contextHazard(context);
|
|
37026
37150
|
const judged = (c.ai.criteria?.hazard ?? 0) >= 0.8;
|
|
37027
|
-
if (!hazard.ok && !shared?.ok && !judged) {
|
|
37151
|
+
if (!input.relaxedGates && !hazard.ok && !shared?.ok && !judged) {
|
|
37028
37152
|
note("no-hazard", `${c.ai.symbol}: ${hazard.why}`);
|
|
37029
37153
|
continue;
|
|
37030
37154
|
}
|
|
@@ -37057,7 +37181,7 @@ async function runFormalPhase(input) {
|
|
|
37057
37181
|
let report = null;
|
|
37058
37182
|
let modelName = "";
|
|
37059
37183
|
let rounds = 0;
|
|
37060
|
-
for (let round = 1; round <= 2; round++) {
|
|
37184
|
+
for (let round = 1; round <= (input.maxRounds ?? 2); round++) {
|
|
37061
37185
|
if (round > 1 && overCap()) return done({ status: "skipped", skip: "cost-cap", detail: `$${usage.costUsd.toFixed(2)} spent, cap $${costCap.toFixed(2)}; no retry`, target, model: { name: modelName, file: `${AUTO_MODELS_DIR}/${modelName}.lean`, rounds } });
|
|
37062
37186
|
if (cancelled()) return done({ status: "skipped", skip: "deadline", detail: "cut off before generation", target });
|
|
37063
37187
|
rounds = round;
|
|
@@ -37076,7 +37200,7 @@ async function runFormalPhase(input) {
|
|
|
37076
37200
|
modelName = gen.name;
|
|
37077
37201
|
const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
|
|
37078
37202
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
37079
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
37203
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path50.join)(root, rel);
|
|
37080
37204
|
progress.model = { name: gen.name, file: rel, rounds: round };
|
|
37081
37205
|
progress.step = "check";
|
|
37082
37206
|
report = await deps.check(root, abs);
|
|
@@ -37198,7 +37322,7 @@ async function runFormalPhase(input) {
|
|
|
37198
37322
|
return done({
|
|
37199
37323
|
status: "checked",
|
|
37200
37324
|
target,
|
|
37201
|
-
model: { name: modelName, file: (0,
|
|
37325
|
+
model: { name: modelName, file: (0, import_node_path50.relative)(root, (0, import_node_path50.join)(root, modelFile)), rounds },
|
|
37202
37326
|
properties: report.properties,
|
|
37203
37327
|
findings
|
|
37204
37328
|
});
|
|
@@ -37275,7 +37399,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
37275
37399
|
}
|
|
37276
37400
|
const rel = `${dir}/${gen.name}.lean`;
|
|
37277
37401
|
writeFileInRootNoFollow(root, rel, gen.source);
|
|
37278
|
-
const abs = resolveModelFile(root, rel) ?? (0,
|
|
37402
|
+
const abs = resolveModelFile(root, rel) ?? (0, import_node_path50.join)(root, rel);
|
|
37279
37403
|
const report = await opts.deps.check(root, abs);
|
|
37280
37404
|
const abstracts = report.header?.abstracts ?? [];
|
|
37281
37405
|
const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
|
|
@@ -37307,7 +37431,7 @@ async function generateAndCheck(root, req, opts) {
|
|
|
37307
37431
|
function skippedOutcome(skip, detail) {
|
|
37308
37432
|
return { status: "skipped", skip, ...detail ? { detail } : {}, findings: [], usage: { inputTokens: 0, outputTokens: 0, costUsd: 0, unpriced: 0 }, durationMs: 0 };
|
|
37309
37433
|
}
|
|
37310
|
-
async function prepareFormalPhase(root, env = process.env, auth2, readSource, codeSource) {
|
|
37434
|
+
async function prepareFormalPhase(root, env = process.env, auth2, readSource, codeSource, opts = {}) {
|
|
37311
37435
|
const direct = env.VERITY_PROVE_DIRECT === "1" && !!env.OPENAI_API_KEY;
|
|
37312
37436
|
if (!auth2 && !direct) return { ok: false, skip: "not-logged-in" };
|
|
37313
37437
|
const apiKey = direct ? env.OPENAI_API_KEY : void 0;
|
|
@@ -37323,7 +37447,7 @@ async function prepareFormalPhase(root, env = process.env, auth2, readSource, co
|
|
|
37323
37447
|
const build = await buildLibraryAsync(toolchain, root, 9e4);
|
|
37324
37448
|
if (!build.ok) return { ok: false, skip: "library-build-failed", detail: build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).join(" ").slice(0, 200) };
|
|
37325
37449
|
const code = await loadCodeContext(root, env, codeSource);
|
|
37326
|
-
return { ok: true, deps: { ...defaultDeps({ auth: auth2, apiKey, env, toolchain, readSource, ...code }), codeSource: code.codeSource } };
|
|
37450
|
+
return { ok: true, deps: { ...defaultDeps({ auth: auth2, apiKey, env, toolchain, readSource, ...opts.tier ? { tier: opts.tier } : {}, ...code }), codeSource: code.codeSource } };
|
|
37327
37451
|
}
|
|
37328
37452
|
async function loadCodeContext(root, env = process.env, codeSource) {
|
|
37329
37453
|
const loaded = await loadCodeMap(env);
|
|
@@ -37376,10 +37500,52 @@ function runFormalPhaseWithin(input) {
|
|
|
37376
37500
|
resolve9(cutOffOutcome(progress, `hard stop after ${Math.round(left / 1e3)} s during ${progress.step ?? "setup"}`, left));
|
|
37377
37501
|
}, left);
|
|
37378
37502
|
});
|
|
37379
|
-
return Promise.race([
|
|
37503
|
+
return Promise.race([runFormalPhaseTargets({ ...input, progress }), cutoff]).finally(() => {
|
|
37380
37504
|
if (timer) clearTimeout(timer);
|
|
37381
37505
|
});
|
|
37382
37506
|
}
|
|
37507
|
+
var NOTHING_ELSE_QUALIFIES = /* @__PURE__ */ new Set(["no-source-files", "not-eligible", "no-candidate", "no-symbol", "symbol-not-in-push", "verified", "no-hazard", "too-large"]);
|
|
37508
|
+
async function runFormalPhaseTargets(input) {
|
|
37509
|
+
const first = await runFormalPhase(input);
|
|
37510
|
+
const max = Math.max(1, Math.floor(input.maxTargets ?? 1));
|
|
37511
|
+
if (max === 1 || first.status !== "checked" || !first.target) return first;
|
|
37512
|
+
const outcomes = [first];
|
|
37513
|
+
const exclude = /* @__PURE__ */ new Set([`${first.target.file}#${first.target.symbol}`]);
|
|
37514
|
+
const cap2 = input.costCapUsd ?? PUSH_COST_CAP_USD;
|
|
37515
|
+
let stoppedAt;
|
|
37516
|
+
while (outcomes.length < max) {
|
|
37517
|
+
if (input.progress?.cancelled) {
|
|
37518
|
+
stoppedAt = { skip: "deadline", detail: "cut off between targets" };
|
|
37519
|
+
break;
|
|
37520
|
+
}
|
|
37521
|
+
const left = input.deadlineAt - input.deps.now();
|
|
37522
|
+
if (left < GENERATE_RESERVE_MS + REPLAY_RESERVE_MS) {
|
|
37523
|
+
stoppedAt = { skip: "not-enough-time", detail: `${Math.round(left / 1e3)} s left before target ${outcomes.length + 1}` };
|
|
37524
|
+
break;
|
|
37525
|
+
}
|
|
37526
|
+
const spent = outcomes.reduce((sum, o) => sum + o.usage.costUsd, 0);
|
|
37527
|
+
if (spent >= cap2) {
|
|
37528
|
+
stoppedAt = { skip: "cost-cap", detail: `$${spent.toFixed(2)} spent, cap $${cap2.toFixed(2)}` };
|
|
37529
|
+
break;
|
|
37530
|
+
}
|
|
37531
|
+
const next = await runFormalPhase({ ...input, exclude, skipStanding: true, costCapUsd: cap2 - spent, progress: {} });
|
|
37532
|
+
if (next.status !== "checked" && next.skip && !NOTHING_ELSE_QUALIFIES.has(next.skip)) stoppedAt = { skip: next.skip, ...next.detail ? { detail: next.detail } : {} };
|
|
37533
|
+
if (!next.target) break;
|
|
37534
|
+
exclude.add(`${next.target.file}#${next.target.symbol}`);
|
|
37535
|
+
outcomes.push(next);
|
|
37536
|
+
if (next.status !== "checked") break;
|
|
37537
|
+
}
|
|
37538
|
+
if (outcomes.length === 1) return stoppedAt ? { ...first, stoppedAt } : first;
|
|
37539
|
+
return {
|
|
37540
|
+
...first,
|
|
37541
|
+
...stoppedAt ? { stoppedAt } : {},
|
|
37542
|
+
findings: outcomes.flatMap((o) => o.findings),
|
|
37543
|
+
properties: outcomes.flatMap((o) => o.properties ?? []),
|
|
37544
|
+
targets: outcomes.flatMap((o) => o.target ? [{ file: o.target.file, symbol: o.target.symbol, status: o.status, ...o.skip ? { skip: o.skip } : {}, findings: o.findings.length }] : []),
|
|
37545
|
+
usage: outcomes.reduce((u, o) => ({ inputTokens: u.inputTokens + o.usage.inputTokens, outputTokens: u.outputTokens + o.usage.outputTokens, costUsd: Math.round((u.costUsd + o.usage.costUsd) * 1e6) / 1e6, unpriced: u.unpriced + o.usage.unpriced }), { inputTokens: 0, outputTokens: 0, costUsd: 0, unpriced: 0 }),
|
|
37546
|
+
durationMs: outcomes.reduce((sum, o) => sum + o.durationMs, 0)
|
|
37547
|
+
};
|
|
37548
|
+
}
|
|
37383
37549
|
function cutOffOutcome(p, detail, elapsedMs) {
|
|
37384
37550
|
const usage = p.usage ?? { inputTokens: 0, outputTokens: 0, costUsd: 0, unpriced: 0 };
|
|
37385
37551
|
if (!p.report || !p.target || !p.model) {
|
|
@@ -37537,7 +37703,7 @@ var WRITERS_BUDGET_MS = 1500;
|
|
|
37537
37703
|
var EXCERPT_MAX_LINES2 = 30;
|
|
37538
37704
|
var VENDORED_READ_MAX_BYTES = 256 * 1024;
|
|
37539
37705
|
var GUARD_BLOCK_CAP = 2;
|
|
37540
|
-
var GUARD_ITER_FILE = (0,
|
|
37706
|
+
var GUARD_ITER_FILE = (0, import_node_path51.join)(VERITY_DIR, ".guard-iteration");
|
|
37541
37707
|
function readPreToolUseStdin() {
|
|
37542
37708
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
37543
37709
|
return new Promise((resolve9) => {
|
|
@@ -37582,7 +37748,7 @@ function readPreToolUseStdin() {
|
|
|
37582
37748
|
}
|
|
37583
37749
|
function readIterMap() {
|
|
37584
37750
|
try {
|
|
37585
|
-
const raw = JSON.parse((0,
|
|
37751
|
+
const raw = JSON.parse((0, import_node_fs63.readFileSync)(GUARD_ITER_FILE, "utf-8"));
|
|
37586
37752
|
if (raw && typeof raw === "object") {
|
|
37587
37753
|
if (typeof raw.moment === "string" && typeof raw.count === "number") {
|
|
37588
37754
|
return { [raw.moment]: raw.count };
|
|
@@ -37602,10 +37768,10 @@ function readIter(moment) {
|
|
|
37602
37768
|
}
|
|
37603
37769
|
function writeIter(moment, count) {
|
|
37604
37770
|
try {
|
|
37605
|
-
(0,
|
|
37771
|
+
(0, import_node_fs63.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37606
37772
|
const map = readIterMap();
|
|
37607
37773
|
map[moment] = count;
|
|
37608
|
-
(0,
|
|
37774
|
+
(0, import_node_fs63.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37609
37775
|
} catch {
|
|
37610
37776
|
}
|
|
37611
37777
|
}
|
|
@@ -37615,10 +37781,10 @@ function resetIter(moment) {
|
|
|
37615
37781
|
if (!(moment in map)) return;
|
|
37616
37782
|
delete map[moment];
|
|
37617
37783
|
if (Object.keys(map).length === 0) {
|
|
37618
|
-
if ((0,
|
|
37784
|
+
if ((0, import_node_fs63.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs63.unlinkSync)(GUARD_ITER_FILE);
|
|
37619
37785
|
} else {
|
|
37620
|
-
(0,
|
|
37621
|
-
(0,
|
|
37786
|
+
(0, import_node_fs63.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
37787
|
+
(0, import_node_fs63.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
|
|
37622
37788
|
}
|
|
37623
37789
|
} catch {
|
|
37624
37790
|
}
|
|
@@ -37688,7 +37854,7 @@ function hasBlockingFinding(response, sentFiles) {
|
|
|
37688
37854
|
function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
|
|
37689
37855
|
const analyzable = filterAnalyzable(files);
|
|
37690
37856
|
const securityFiles = filterSecurity(files);
|
|
37691
|
-
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0,
|
|
37857
|
+
const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs63.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
|
|
37692
37858
|
const staticResults = runCodacyAnalysisIfAvailable(scannable);
|
|
37693
37859
|
const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
|
|
37694
37860
|
const requestBody = {
|
|
@@ -37701,7 +37867,7 @@ function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedInte
|
|
|
37701
37867
|
agent_harness: "claude-code",
|
|
37702
37868
|
// Prefer the session id Claude Code passes on the hook payload; fall back
|
|
37703
37869
|
// to the env var, then 'unknown'.
|
|
37704
|
-
session_id: sessionId ??
|
|
37870
|
+
session_id: sessionId ?? envSessionId() ?? "unknown",
|
|
37705
37871
|
trigger,
|
|
37706
37872
|
iteration: iter + 1
|
|
37707
37873
|
}
|
|
@@ -37832,7 +37998,8 @@ function startAgentReview(input) {
|
|
|
37832
37998
|
http: http2,
|
|
37833
37999
|
executeTools: makeToolExecutor(ctx),
|
|
37834
38000
|
startedAt: input.hookStartedAt,
|
|
37835
|
-
|
|
38001
|
+
// The push's deadline follows the review effort (lib/effort.ts); the commit's never does.
|
|
38002
|
+
deadlineMs: input.moment === "pre-push" ? effortProfile(input.root).pushDeadlineMs : AGENT_DEADLINE_MS[input.moment],
|
|
37836
38003
|
start: {
|
|
37837
38004
|
moment: input.moment,
|
|
37838
38005
|
iteration: input.iteration,
|
|
@@ -37857,7 +38024,8 @@ function startFormalPhase(input) {
|
|
|
37857
38024
|
const env = process.env.VERITY_GIT_MOMENT_FORMAL;
|
|
37858
38025
|
if (env === "off") return null;
|
|
37859
38026
|
if (env !== "push" && readProjectConfig().formal !== "push") return null;
|
|
37860
|
-
const
|
|
38027
|
+
const profile = effortProfile(input.root);
|
|
38028
|
+
const deadlineAt = input.hookStartedAt + profile.pushDeadlineMs - 1e4;
|
|
37861
38029
|
const ig = loadVerityIgnore();
|
|
37862
38030
|
const files = input.files.filter((f) => !isVerityOwnedPath(f) && !isIgnored3(ig, f));
|
|
37863
38031
|
let changedLines = /* @__PURE__ */ new Map();
|
|
@@ -37879,9 +38047,9 @@ function startFormalPhase(input) {
|
|
|
37879
38047
|
return { ok: true, content };
|
|
37880
38048
|
} : void 0;
|
|
37881
38049
|
const run4 = async () => {
|
|
37882
|
-
const prep = await prepareFormalPhase(input.root, process.env, input.auth, readSource, withoutPaths(tip ? revisionSource(input.root, tip) : worktreeSource(input.root), isDeniedPath));
|
|
38050
|
+
const prep = await prepareFormalPhase(input.root, process.env, input.auth, readSource, withoutPaths(tip ? revisionSource(input.root, tip) : worktreeSource(input.root), isDeniedPath), { tier: profile.formal.tier });
|
|
37883
38051
|
if (!prep.ok) return skippedOutcome(prep.skip, prep.detail);
|
|
37884
|
-
return runFormalPhaseWithin({ root: input.root, files, changedLines, deadlineAt, deps: prep.deps });
|
|
38052
|
+
return runFormalPhaseWithin({ root: input.root, files, changedLines, deadlineAt, deps: prep.deps, minScore: profile.formal.minScore, maxRounds: profile.formal.maxRounds, costCapUsd: profile.formal.costCapUsd, maxTargets: profile.formal.maxTargets, relaxedGates: profile.formal.relaxedGates, dailyCap: profile.formal.dailyModels, dailyCostCapUsd: profile.formal.dailyCostUsd });
|
|
37885
38053
|
};
|
|
37886
38054
|
return run4().catch((err2) => skippedOutcome("error", String(err2?.message ?? err2).slice(0, 200)));
|
|
37887
38055
|
}
|
|
@@ -38073,6 +38241,9 @@ async function runGuard(opts, globals) {
|
|
|
38073
38241
|
rounds: formalOutcome.model?.rounds ?? null,
|
|
38074
38242
|
properties: formalOutcome.properties?.map((p) => `${p.id}:${p.result}`) ?? [],
|
|
38075
38243
|
findings: formalOutcome.findings.map((f) => `${f.property}:${f.verdict}`),
|
|
38244
|
+
// Review effort "max" models more than one function: each one, and why the search stopped early.
|
|
38245
|
+
targets: (formalOutcome.targets ?? []).map((t) => `${t.file}#${t.symbol}:${t.status}${t.skip ? `(${t.skip})` : ""}`),
|
|
38246
|
+
stopped_at: formalOutcome.stoppedAt?.skip ?? null,
|
|
38076
38247
|
// Decision 81: what each property rests on (a rule, or "line"), what was
|
|
38077
38248
|
// sent back or dropped as ungrounded, and which counterexamples lack their
|
|
38078
38249
|
// property's trigger (shadow). Ids and rule names only, never code.
|
|
@@ -38229,7 +38400,7 @@ function writeBlockMessage(moment, response, covDetail) {
|
|
|
38229
38400
|
|
|
38230
38401
|
// src/commands/ignore.ts
|
|
38231
38402
|
function registerIgnoreCommand(program2) {
|
|
38232
|
-
const ignore = program2.command("ignore").description("Declare the next turn (or a short window) as housekeeping \u2014 no review needed").option("--turn", "Cover the next turn only (the default)").option("--for <duration>", "Cover a window: 30m, 45s, 1h (max 60m)").option("--reason <reason>", "Why this window needs no review \u2014 required, and recorded").option("--agent", "Mark the declaration as agent-invoked (a ledger label, not a permission)").option("--session-id <id>", "Session id (defaults to $CLAUDE_SESSION_ID)").option("--json", "Output raw JSON").action(async (opts) => {
|
|
38403
|
+
const ignore = program2.command("ignore").description("Declare the next turn (or a short window) as housekeeping \u2014 no review needed").option("--turn", "Cover the next turn only (the default)").option("--for <duration>", "Cover a window: 30m, 45s, 1h (max 60m)").option("--reason <reason>", "Why this window needs no review \u2014 required, and recorded").option("--agent", "Mark the declaration as agent-invoked (a ledger label, not a permission)").option("--session-id <id>", "Session id (defaults to $CLAUDE_SESSION_ID, then $CLAUDE_CODE_SESSION_ID)").option("--json", "Output raw JSON").action(async (opts) => {
|
|
38233
38404
|
const globals = program2.opts();
|
|
38234
38405
|
const now = Math.floor(Date.now() / 1e3);
|
|
38235
38406
|
const reason = opts.reason?.trim();
|
|
@@ -38256,7 +38427,7 @@ function registerIgnoreCommand(program2) {
|
|
|
38256
38427
|
}
|
|
38257
38428
|
const tokenResult = await resolveToken(globals.token);
|
|
38258
38429
|
const token = tokenResult.ok ? tokenResult.data.token : void 0;
|
|
38259
|
-
const sessionId = opts.sessionId ||
|
|
38430
|
+
const sessionId = opts.sessionId || envSessionId();
|
|
38260
38431
|
const keys = ignoreStateKeys(token, sessionId);
|
|
38261
38432
|
const existing = resolveIgnoreState(keys);
|
|
38262
38433
|
const spent = existing?.state.spent ?? 0;
|
|
@@ -38302,11 +38473,11 @@ function registerIgnoreCommand(program2) {
|
|
|
38302
38473
|
printInfo(`Verity will skip ${window2} \u2014 "${reason}" (${spent + 1}/${IGNORE_BUDGET} this session).`);
|
|
38303
38474
|
printInfo("It covers turns that author nothing. If anything is written, the declaration voids and the review runs.");
|
|
38304
38475
|
});
|
|
38305
|
-
ignore.command("clear").description("Cancel the active declaration (the spent budget is not refunded)").option("--session-id <id>", "Session id (defaults to $CLAUDE_SESSION_ID)").action(async (opts) => {
|
|
38476
|
+
ignore.command("clear").description("Cancel the active declaration (the spent budget is not refunded)").option("--session-id <id>", "Session id (defaults to $CLAUDE_SESSION_ID, then $CLAUDE_CODE_SESSION_ID)").action(async (opts) => {
|
|
38306
38477
|
const globals = program2.opts();
|
|
38307
38478
|
const tokenResult = await resolveToken(globals.token);
|
|
38308
38479
|
const token = tokenResult.ok ? tokenResult.data.token : void 0;
|
|
38309
|
-
const sessionId = opts.sessionId ||
|
|
38480
|
+
const sessionId = opts.sessionId || envSessionId();
|
|
38310
38481
|
const found = resolveIgnoreState(ignoreStateKeys(token, sessionId));
|
|
38311
38482
|
const active = resolveActive(found?.state ?? null, Math.floor(Date.now() / 1e3));
|
|
38312
38483
|
if (!found || !active) {
|
|
@@ -38321,7 +38492,7 @@ function registerIgnoreCommand(program2) {
|
|
|
38321
38492
|
|
|
38322
38493
|
// src/commands/waive.ts
|
|
38323
38494
|
var import_node_crypto20 = require("node:crypto");
|
|
38324
|
-
var
|
|
38495
|
+
var import_node_fs64 = require("node:fs");
|
|
38325
38496
|
function registerWaiveCommand(program2) {
|
|
38326
38497
|
program2.command("waive <pattern-id>").description("Record an accepted-risk disposition for an open finding (voids when the file changes)").option("--file <path>", "File the finding is anchored to, REPO-RELATIVE (recommended \u2014 narrows the waive)").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action(async (patternId, opts) => {
|
|
38327
38498
|
const globals = program2.opts();
|
|
@@ -38350,7 +38521,7 @@ function registerWaiveCommand(program2) {
|
|
|
38350
38521
|
if (opts.file) {
|
|
38351
38522
|
body2.file = opts.file;
|
|
38352
38523
|
try {
|
|
38353
|
-
body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0,
|
|
38524
|
+
body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs64.readFileSync)(opts.file)).digest("hex");
|
|
38354
38525
|
} catch {
|
|
38355
38526
|
printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
|
|
38356
38527
|
process.exit(1);
|
|
@@ -38375,10 +38546,10 @@ function registerWaiveCommand(program2) {
|
|
|
38375
38546
|
}
|
|
38376
38547
|
|
|
38377
38548
|
// src/commands/init.ts
|
|
38378
|
-
var
|
|
38549
|
+
var import_node_fs69 = require("node:fs");
|
|
38379
38550
|
var import_promises20 = require("node:fs/promises");
|
|
38380
|
-
var
|
|
38381
|
-
var
|
|
38551
|
+
var import_yaml7 = __toESM2(require_dist());
|
|
38552
|
+
var import_node_path55 = require("node:path");
|
|
38382
38553
|
var import_node_os11 = require("node:os");
|
|
38383
38554
|
var import_node_child_process19 = require("node:child_process");
|
|
38384
38555
|
|
|
@@ -38458,7 +38629,7 @@ function printPhase(n, of, title, subtitle) {
|
|
|
38458
38629
|
}
|
|
38459
38630
|
|
|
38460
38631
|
// src/commands/doctor.ts
|
|
38461
|
-
var
|
|
38632
|
+
var import_node_fs65 = require("node:fs");
|
|
38462
38633
|
|
|
38463
38634
|
// src/lib/prereqs.ts
|
|
38464
38635
|
var import_node_child_process16 = require("node:child_process");
|
|
@@ -38666,11 +38837,11 @@ async function buildReport() {
|
|
|
38666
38837
|
const hooks = wiring.status;
|
|
38667
38838
|
const provenance = cliProvenance();
|
|
38668
38839
|
const telemetry = await checkTelemetry();
|
|
38669
|
-
const hasConfig = (0,
|
|
38840
|
+
const hasConfig = (0, import_node_fs65.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
38670
38841
|
const artifacts = {
|
|
38671
|
-
standard: (0,
|
|
38842
|
+
standard: (0, import_node_fs65.existsSync)(projectPath(STANDARD_FILE)),
|
|
38672
38843
|
analysisConfig: hasConfig,
|
|
38673
|
-
verityMd: (0,
|
|
38844
|
+
verityMd: (0, import_node_fs65.existsSync)(projectPath(VERITY_MD_FILE)),
|
|
38674
38845
|
analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
|
|
38675
38846
|
};
|
|
38676
38847
|
const next = [];
|
|
@@ -38829,8 +39000,8 @@ function registerDoctorCommand(program2) {
|
|
|
38829
39000
|
}
|
|
38830
39001
|
|
|
38831
39002
|
// src/commands/migrate.ts
|
|
38832
|
-
var
|
|
38833
|
-
var
|
|
39003
|
+
var import_node_fs66 = require("node:fs");
|
|
39004
|
+
var import_node_path52 = require("node:path");
|
|
38834
39005
|
var import_node_child_process17 = require("node:child_process");
|
|
38835
39006
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
38836
39007
|
function defaultNpmRemover(pkg) {
|
|
@@ -38867,12 +39038,12 @@ async function runMigration(opts = {}) {
|
|
|
38867
39038
|
return { actions, migrated: actions.length > 0 };
|
|
38868
39039
|
}
|
|
38869
39040
|
function migrateProjectDir(root, actions) {
|
|
38870
|
-
const gateDir = (0,
|
|
38871
|
-
const verityDir = (0,
|
|
38872
|
-
if ((0,
|
|
39041
|
+
const gateDir = (0, import_node_path52.join)(root, ".gate");
|
|
39042
|
+
const verityDir = (0, import_node_path52.join)(root, ".verity");
|
|
39043
|
+
if ((0, import_node_fs66.existsSync)(gateDir) && !(0, import_node_fs66.existsSync)(verityDir)) {
|
|
38873
39044
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
38874
39045
|
}
|
|
38875
|
-
if ((0,
|
|
39046
|
+
if ((0, import_node_fs66.existsSync)(gateDir) && (0, import_node_fs66.existsSync)(verityDir)) {
|
|
38876
39047
|
return migrateProjectDirCarry(gateDir, verityDir, actions);
|
|
38877
39048
|
}
|
|
38878
39049
|
return false;
|
|
@@ -38893,13 +39064,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
|
|
|
38893
39064
|
}
|
|
38894
39065
|
}
|
|
38895
39066
|
if (moved) {
|
|
38896
|
-
if ((0,
|
|
39067
|
+
if ((0, import_node_fs66.existsSync)(gateDir)) {
|
|
38897
39068
|
const carried = carryLegacyContents(gateDir, verityDir);
|
|
38898
39069
|
if (carried > 0) {
|
|
38899
39070
|
actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
|
|
38900
39071
|
}
|
|
38901
39072
|
try {
|
|
38902
|
-
(0,
|
|
39073
|
+
(0, import_node_fs66.rmSync)(gateDir, { recursive: true, force: true });
|
|
38903
39074
|
} catch {
|
|
38904
39075
|
}
|
|
38905
39076
|
}
|
|
@@ -38915,18 +39086,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
38915
39086
|
actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
|
|
38916
39087
|
}
|
|
38917
39088
|
try {
|
|
38918
|
-
(0,
|
|
39089
|
+
(0, import_node_fs66.rmSync)(gateDir, { recursive: true, force: true });
|
|
38919
39090
|
} catch {
|
|
38920
39091
|
}
|
|
38921
39092
|
return carried > 0;
|
|
38922
39093
|
}
|
|
38923
39094
|
function migrateGlobalCredentials(home, actions) {
|
|
38924
39095
|
if (!home) return;
|
|
38925
|
-
const gateCreds = (0,
|
|
38926
|
-
const verityCreds = (0,
|
|
38927
|
-
if (!(0,
|
|
38928
|
-
if (!(0,
|
|
38929
|
-
(0,
|
|
39096
|
+
const gateCreds = (0, import_node_path52.join)(home, ".gate", "credentials");
|
|
39097
|
+
const verityCreds = (0, import_node_path52.join)(home, ".verity", "credentials");
|
|
39098
|
+
if (!(0, import_node_fs66.existsSync)(gateCreds)) return;
|
|
39099
|
+
if (!(0, import_node_fs66.existsSync)(verityCreds)) {
|
|
39100
|
+
(0, import_node_fs66.mkdirSync)((0, import_node_path52.join)(home, ".verity"), { recursive: true });
|
|
38930
39101
|
moveFile(gateCreds, verityCreds);
|
|
38931
39102
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
38932
39103
|
return;
|
|
@@ -38948,8 +39119,8 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
38948
39119
|
}
|
|
38949
39120
|
}
|
|
38950
39121
|
async function migrateClaudeMd(root, actions) {
|
|
38951
|
-
const claudeMd = (0,
|
|
38952
|
-
const hadLegacyBlock = (0,
|
|
39122
|
+
const claudeMd = (0, import_node_path52.join)(root, "CLAUDE.md");
|
|
39123
|
+
const hadLegacyBlock = (0, import_node_fs66.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
38953
39124
|
if (!hadLegacyBlock) return;
|
|
38954
39125
|
try {
|
|
38955
39126
|
await ensureClaudeMdPointer(root);
|
|
@@ -38959,9 +39130,9 @@ async function migrateClaudeMd(root, actions) {
|
|
|
38959
39130
|
}
|
|
38960
39131
|
}
|
|
38961
39132
|
function migrateStandardFile(root, actions) {
|
|
38962
|
-
const gateMd = (0,
|
|
38963
|
-
const verityMd = (0,
|
|
38964
|
-
if (!(0,
|
|
39133
|
+
const gateMd = (0, import_node_path52.join)(root, "GATE.md");
|
|
39134
|
+
const verityMd = (0, import_node_path52.join)(root, "VERITY.md");
|
|
39135
|
+
if (!(0, import_node_fs66.existsSync)(gateMd) || (0, import_node_fs66.existsSync)(verityMd)) return;
|
|
38965
39136
|
let moved = false;
|
|
38966
39137
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
38967
39138
|
try {
|
|
@@ -38973,12 +39144,12 @@ function migrateStandardFile(root, actions) {
|
|
|
38973
39144
|
if (!moved) moveFile(gateMd, verityMd);
|
|
38974
39145
|
const content = readFileSyncSafe(verityMd);
|
|
38975
39146
|
const refreshed = content.split("GATE.md").join("VERITY.md");
|
|
38976
|
-
if (refreshed !== content) (0,
|
|
39147
|
+
if (refreshed !== content) (0, import_node_fs66.writeFileSync)(verityMd, refreshed);
|
|
38977
39148
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
38978
39149
|
}
|
|
38979
39150
|
async function migrateTelemetryHeaders(root, actions) {
|
|
38980
|
-
const file = (0,
|
|
38981
|
-
if (!(0,
|
|
39151
|
+
const file = (0, import_node_path52.join)(root, ".claude", "settings.local.json");
|
|
39152
|
+
if (!(0, import_node_fs66.existsSync)(file)) return;
|
|
38982
39153
|
let settings;
|
|
38983
39154
|
try {
|
|
38984
39155
|
settings = JSON.parse(readFileSyncSafe(file) || "{}");
|
|
@@ -39025,15 +39196,15 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
39025
39196
|
toAppend.push(line2.replace(/\r$/, ""));
|
|
39026
39197
|
}
|
|
39027
39198
|
if (toAppend.length > 0) {
|
|
39028
|
-
const
|
|
39029
|
-
(0,
|
|
39199
|
+
const sep7 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
39200
|
+
(0, import_node_fs66.writeFileSync)(verityCreds, verityContent + sep7 + toAppend.join("\n") + "\n");
|
|
39030
39201
|
}
|
|
39031
|
-
(0,
|
|
39202
|
+
(0, import_node_fs66.rmSync)(gateCreds, { force: true });
|
|
39032
39203
|
return toAppend.length;
|
|
39033
39204
|
}
|
|
39034
39205
|
function readFileSyncSafe(path) {
|
|
39035
39206
|
try {
|
|
39036
|
-
return (0,
|
|
39207
|
+
return (0, import_node_fs66.readFileSync)(path, "utf-8");
|
|
39037
39208
|
} catch {
|
|
39038
39209
|
return "";
|
|
39039
39210
|
}
|
|
@@ -39048,35 +39219,35 @@ function hasStagedChanges(root) {
|
|
|
39048
39219
|
}
|
|
39049
39220
|
function moveDir(from, to) {
|
|
39050
39221
|
try {
|
|
39051
|
-
(0,
|
|
39222
|
+
(0, import_node_fs66.renameSync)(from, to);
|
|
39052
39223
|
} catch (err2) {
|
|
39053
39224
|
if (err2.code !== "EXDEV") throw err2;
|
|
39054
|
-
(0,
|
|
39055
|
-
(0,
|
|
39225
|
+
(0, import_node_fs66.cpSync)(from, to, { recursive: true });
|
|
39226
|
+
(0, import_node_fs66.rmSync)(from, { recursive: true, force: true });
|
|
39056
39227
|
}
|
|
39057
39228
|
}
|
|
39058
39229
|
function moveFile(from, to) {
|
|
39059
39230
|
try {
|
|
39060
|
-
(0,
|
|
39231
|
+
(0, import_node_fs66.renameSync)(from, to);
|
|
39061
39232
|
} catch (err2) {
|
|
39062
39233
|
if (err2.code !== "EXDEV") throw err2;
|
|
39063
|
-
(0,
|
|
39064
|
-
(0,
|
|
39234
|
+
(0, import_node_fs66.cpSync)(from, to);
|
|
39235
|
+
(0, import_node_fs66.rmSync)(from, { force: true });
|
|
39065
39236
|
}
|
|
39066
39237
|
}
|
|
39067
39238
|
function carryLegacyContents(gateDir, verityDir) {
|
|
39068
39239
|
let copied = 0;
|
|
39069
39240
|
const walk2 = (relDir) => {
|
|
39070
|
-
const srcDir = (0,
|
|
39071
|
-
for (const entry of (0,
|
|
39072
|
-
const rel = relDir ? (0,
|
|
39073
|
-
const src = (0,
|
|
39074
|
-
const dest = (0,
|
|
39075
|
-
if ((0,
|
|
39241
|
+
const srcDir = (0, import_node_path52.join)(gateDir, relDir);
|
|
39242
|
+
for (const entry of (0, import_node_fs66.readdirSync)(srcDir)) {
|
|
39243
|
+
const rel = relDir ? (0, import_node_path52.join)(relDir, entry) : entry;
|
|
39244
|
+
const src = (0, import_node_path52.join)(gateDir, rel);
|
|
39245
|
+
const dest = (0, import_node_path52.join)(verityDir, rel);
|
|
39246
|
+
if ((0, import_node_fs66.statSync)(src).isDirectory()) {
|
|
39076
39247
|
walk2(rel);
|
|
39077
|
-
} else if (!(0,
|
|
39078
|
-
(0,
|
|
39079
|
-
(0,
|
|
39248
|
+
} else if (!(0, import_node_fs66.existsSync)(dest)) {
|
|
39249
|
+
(0, import_node_fs66.mkdirSync)((0, import_node_path52.dirname)(dest), { recursive: true });
|
|
39250
|
+
(0, import_node_fs66.cpSync)(src, dest);
|
|
39080
39251
|
copied++;
|
|
39081
39252
|
}
|
|
39082
39253
|
}
|
|
@@ -39085,22 +39256,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
39085
39256
|
return copied;
|
|
39086
39257
|
}
|
|
39087
39258
|
async function needsMigration(root = repoRoot()) {
|
|
39088
|
-
const gateDir = (0,
|
|
39089
|
-
const verityDir = (0,
|
|
39090
|
-
if ((0,
|
|
39091
|
-
if ((0,
|
|
39092
|
-
if ((0,
|
|
39259
|
+
const gateDir = (0, import_node_path52.join)(root, ".gate");
|
|
39260
|
+
const verityDir = (0, import_node_path52.join)(root, ".verity");
|
|
39261
|
+
if ((0, import_node_fs66.existsSync)(gateDir) && !(0, import_node_fs66.existsSync)(verityDir)) return true;
|
|
39262
|
+
if ((0, import_node_fs66.existsSync)(gateDir) && (0, import_node_fs66.existsSync)(verityDir)) {
|
|
39263
|
+
if ((0, import_node_fs66.existsSync)((0, import_node_path52.join)(gateDir, "credentials")) && !(0, import_node_fs66.existsSync)((0, import_node_path52.join)(verityDir, "credentials"))) {
|
|
39093
39264
|
return true;
|
|
39094
39265
|
}
|
|
39095
|
-
if ((0,
|
|
39266
|
+
if ((0, import_node_fs66.existsSync)((0, import_node_path52.join)(gateDir, "memory")) && !(0, import_node_fs66.existsSync)((0, import_node_path52.join)(verityDir, "memory"))) {
|
|
39096
39267
|
return true;
|
|
39097
39268
|
}
|
|
39098
39269
|
}
|
|
39099
|
-
const claudeMd = (0,
|
|
39100
|
-
if ((0,
|
|
39270
|
+
const claudeMd = (0, import_node_path52.join)(root, "CLAUDE.md");
|
|
39271
|
+
if ((0, import_node_fs66.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
39101
39272
|
return true;
|
|
39102
39273
|
}
|
|
39103
|
-
if ((0,
|
|
39274
|
+
if ((0, import_node_fs66.existsSync)((0, import_node_path52.join)(root, "GATE.md")) && !(0, import_node_fs66.existsSync)((0, import_node_path52.join)(root, "VERITY.md"))) {
|
|
39104
39275
|
return true;
|
|
39105
39276
|
}
|
|
39106
39277
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -39381,11 +39552,11 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
39381
39552
|
}
|
|
39382
39553
|
|
|
39383
39554
|
// src/lib/prove/lean-install.ts
|
|
39384
|
-
var
|
|
39555
|
+
var import_node_fs67 = require("node:fs");
|
|
39385
39556
|
var import_node_crypto21 = require("node:crypto");
|
|
39386
39557
|
var import_node_child_process18 = require("node:child_process");
|
|
39387
39558
|
var import_node_os10 = require("node:os");
|
|
39388
|
-
var
|
|
39559
|
+
var import_node_path53 = require("node:path");
|
|
39389
39560
|
var import_promises18 = require("node:stream/promises");
|
|
39390
39561
|
var import_node_stream = require("node:stream");
|
|
39391
39562
|
var RELEASES = "https://releases.lean-lang.org/lean4";
|
|
@@ -39396,10 +39567,10 @@ function freeBytes(dir) {
|
|
|
39396
39567
|
let d = dir;
|
|
39397
39568
|
for (let i2 = 0; i2 < 64; i2++) {
|
|
39398
39569
|
try {
|
|
39399
|
-
const st = (0,
|
|
39570
|
+
const st = (0, import_node_fs67.statfsSync)(d);
|
|
39400
39571
|
return Number(st.bavail) * Number(st.bsize);
|
|
39401
39572
|
} catch {
|
|
39402
|
-
const up = (0,
|
|
39573
|
+
const up = (0, import_node_path53.join)(d, "..");
|
|
39403
39574
|
if (up === d) return null;
|
|
39404
39575
|
d = up;
|
|
39405
39576
|
}
|
|
@@ -39421,7 +39592,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
|
|
|
39421
39592
|
function sha256File(path) {
|
|
39422
39593
|
return new Promise((resolve9, reject) => {
|
|
39423
39594
|
const hash = (0, import_node_crypto21.createHash)("sha256");
|
|
39424
|
-
(0,
|
|
39595
|
+
(0, import_node_fs67.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
|
|
39425
39596
|
});
|
|
39426
39597
|
}
|
|
39427
39598
|
async function verifyDownload(zip, asset, version = pinnedVersion()) {
|
|
@@ -39441,7 +39612,7 @@ function leanAssetName(version = pinnedVersion()) {
|
|
|
39441
39612
|
return suffix ? `lean-${v}-${suffix}.zip` : null;
|
|
39442
39613
|
}
|
|
39443
39614
|
function pinnedVersionDir(env = process.env) {
|
|
39444
|
-
return (0,
|
|
39615
|
+
return (0, import_node_path53.join)(verityLeanHome(env), pinnedVersion());
|
|
39445
39616
|
}
|
|
39446
39617
|
function lakeBinary() {
|
|
39447
39618
|
return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
|
|
@@ -39452,12 +39623,12 @@ function unzip(zip, dest) {
|
|
|
39452
39623
|
for (const [cmd, args2] of attempts) {
|
|
39453
39624
|
try {
|
|
39454
39625
|
(0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
|
|
39455
|
-
if ((0,
|
|
39626
|
+
if ((0, import_node_fs67.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
|
|
39456
39627
|
errors.push(`${cmd}: produced nothing`);
|
|
39457
39628
|
} catch (err2) {
|
|
39458
39629
|
errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
|
|
39459
39630
|
try {
|
|
39460
|
-
for (const e of (0,
|
|
39631
|
+
for (const e of (0, import_node_fs67.readdirSync)(dest)) (0, import_node_fs67.rmSync)((0, import_node_path53.join)(dest, e), { recursive: true, force: true });
|
|
39461
39632
|
} catch {
|
|
39462
39633
|
}
|
|
39463
39634
|
}
|
|
@@ -39483,7 +39654,7 @@ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
|
|
|
39483
39654
|
seen += chunk.length;
|
|
39484
39655
|
onProgress(seen, total);
|
|
39485
39656
|
});
|
|
39486
|
-
await (0, import_promises18.pipeline)(stream, (0,
|
|
39657
|
+
await (0, import_promises18.pipeline)(stream, (0, import_node_fs67.createWriteStream)(dest), { signal: ctrl.signal });
|
|
39487
39658
|
} catch (err2) {
|
|
39488
39659
|
if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
|
|
39489
39660
|
throw err2;
|
|
@@ -39533,10 +39704,10 @@ async function installLean(opts = {}) {
|
|
|
39533
39704
|
const gb = (n) => (n / 1024 ** 3).toFixed(1);
|
|
39534
39705
|
return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
|
|
39535
39706
|
}
|
|
39536
|
-
const tmp = (0,
|
|
39537
|
-
(0,
|
|
39538
|
-
(0,
|
|
39539
|
-
const zip = (0,
|
|
39707
|
+
const tmp = (0, import_node_path53.join)(home, ".tmp");
|
|
39708
|
+
(0, import_node_fs67.rmSync)(tmp, { recursive: true, force: true });
|
|
39709
|
+
(0, import_node_fs67.mkdirSync)(tmp, { recursive: true });
|
|
39710
|
+
const zip = (0, import_node_path53.join)(tmp, asset);
|
|
39540
39711
|
say(`downloading ${url}`);
|
|
39541
39712
|
let lastPct = -1;
|
|
39542
39713
|
try {
|
|
@@ -39549,41 +39720,41 @@ async function installLean(opts = {}) {
|
|
|
39549
39720
|
}
|
|
39550
39721
|
});
|
|
39551
39722
|
} catch (err2) {
|
|
39552
|
-
(0,
|
|
39723
|
+
(0, import_node_fs67.rmSync)(tmp, { recursive: true, force: true });
|
|
39553
39724
|
return { ok: false, error: err2.message };
|
|
39554
39725
|
}
|
|
39555
39726
|
say("verifying checksum");
|
|
39556
39727
|
const verified = await verifyDownload(zip, asset);
|
|
39557
39728
|
if (!verified.ok) {
|
|
39558
|
-
(0,
|
|
39729
|
+
(0, import_node_fs67.rmSync)(tmp, { recursive: true, force: true });
|
|
39559
39730
|
return { ok: false, error: verified.error };
|
|
39560
39731
|
}
|
|
39561
39732
|
say("unpacking (this takes a minute)");
|
|
39562
|
-
const unpack = (0,
|
|
39563
|
-
(0,
|
|
39733
|
+
const unpack = (0, import_node_path53.join)(tmp, "unpack");
|
|
39734
|
+
(0, import_node_fs67.mkdirSync)(unpack);
|
|
39564
39735
|
const unpacked = unzip(zip, unpack);
|
|
39565
39736
|
if (!unpacked.ok) {
|
|
39566
|
-
(0,
|
|
39737
|
+
(0, import_node_fs67.rmSync)(tmp, { recursive: true, force: true });
|
|
39567
39738
|
return { ok: false, error: `unpack failed: ${unpacked.error}` };
|
|
39568
39739
|
}
|
|
39569
|
-
const entries = (0,
|
|
39570
|
-
const top = entries.length === 1 && (0,
|
|
39571
|
-
if (!(0,
|
|
39572
|
-
(0,
|
|
39740
|
+
const entries = (0, import_node_fs67.readdirSync)(unpack);
|
|
39741
|
+
const top = entries.length === 1 && (0, import_node_fs67.statSync)((0, import_node_path53.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path53.join)(unpack, entries[0]) : unpack;
|
|
39742
|
+
if (!(0, import_node_fs67.existsSync)((0, import_node_path53.join)(top, "bin", lakeBinary()))) {
|
|
39743
|
+
(0, import_node_fs67.rmSync)(tmp, { recursive: true, force: true });
|
|
39573
39744
|
return { ok: false, error: "the archive did not contain bin/lake" };
|
|
39574
39745
|
}
|
|
39575
|
-
(0,
|
|
39576
|
-
(0,
|
|
39577
|
-
(0,
|
|
39578
|
-
(0,
|
|
39746
|
+
(0, import_node_fs67.rmSync)(dir, { recursive: true, force: true });
|
|
39747
|
+
(0, import_node_fs67.mkdirSync)(home, { recursive: true });
|
|
39748
|
+
(0, import_node_fs67.renameSync)(top, dir);
|
|
39749
|
+
(0, import_node_fs67.rmSync)(tmp, { recursive: true, force: true });
|
|
39579
39750
|
return { ok: true, dir };
|
|
39580
39751
|
}
|
|
39581
39752
|
|
|
39582
39753
|
// src/lib/remote-config.ts
|
|
39583
|
-
var
|
|
39754
|
+
var import_node_fs68 = require("node:fs");
|
|
39584
39755
|
var import_promises19 = require("node:fs/promises");
|
|
39585
|
-
var
|
|
39586
|
-
var
|
|
39756
|
+
var import_node_path54 = require("node:path");
|
|
39757
|
+
var import_yaml6 = __toESM2(require_dist());
|
|
39587
39758
|
var IGNORE_RIDER = "verityignore";
|
|
39588
39759
|
async function fetchRemoteSetup(opts) {
|
|
39589
39760
|
const standard = await apiRequest({
|
|
@@ -39623,11 +39794,11 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39623
39794
|
const content = { ...found.standard.content };
|
|
39624
39795
|
const rider = typeof content[IGNORE_RIDER] === "string" ? content[IGNORE_RIDER] : null;
|
|
39625
39796
|
delete content[IGNORE_RIDER];
|
|
39626
|
-
await writeOut(STANDARD_FILE, (0,
|
|
39797
|
+
await writeOut(STANDARD_FILE, (0, import_yaml6.stringify)(content));
|
|
39627
39798
|
written.push(STANDARD_FILE);
|
|
39628
39799
|
if (rider !== null) {
|
|
39629
39800
|
const localIgnore = projectPath(VERITYIGNORE_FILE);
|
|
39630
|
-
if (!(0,
|
|
39801
|
+
if (!(0, import_node_fs68.existsSync)(localIgnore)) {
|
|
39631
39802
|
await writeOut(VERITYIGNORE_FILE, rider);
|
|
39632
39803
|
written.push(VERITYIGNORE_FILE);
|
|
39633
39804
|
} else {
|
|
@@ -39658,9 +39829,9 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
39658
39829
|
written.push(VERITY_MD_FILE);
|
|
39659
39830
|
return { written, notes };
|
|
39660
39831
|
}
|
|
39661
|
-
async function writeOut(
|
|
39662
|
-
const target = projectPath(
|
|
39663
|
-
await (0, import_promises19.mkdir)((0,
|
|
39832
|
+
async function writeOut(relative7, body2) {
|
|
39833
|
+
const target = projectPath(relative7);
|
|
39834
|
+
await (0, import_promises19.mkdir)((0, import_node_path54.dirname)(target), { recursive: true });
|
|
39664
39835
|
await (0, import_promises19.writeFile)(target, body2);
|
|
39665
39836
|
}
|
|
39666
39837
|
function describeRemote(found) {
|
|
@@ -39777,15 +39948,15 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
39777
39948
|
}
|
|
39778
39949
|
function resolveDataDir2() {
|
|
39779
39950
|
const candidates2 = [
|
|
39780
|
-
(0,
|
|
39951
|
+
(0, import_node_path55.join)(__dirname, "..", "data"),
|
|
39781
39952
|
// installed: node_modules/@codacy/verity-cli/data
|
|
39782
|
-
(0,
|
|
39953
|
+
(0, import_node_path55.join)(__dirname, "..", "..", "data"),
|
|
39783
39954
|
// edge case: nested resolution
|
|
39784
|
-
(0,
|
|
39955
|
+
(0, import_node_path55.join)(process.cwd(), "cli", "data")
|
|
39785
39956
|
// local dev: running from repo root
|
|
39786
39957
|
];
|
|
39787
39958
|
for (const candidate of candidates2) {
|
|
39788
|
-
if ((0,
|
|
39959
|
+
if ((0, import_node_fs69.existsSync)((0, import_node_path55.join)(candidate, "skills"))) {
|
|
39789
39960
|
return candidate;
|
|
39790
39961
|
}
|
|
39791
39962
|
}
|
|
@@ -39801,9 +39972,9 @@ async function skillIsCurrent(src, dest) {
|
|
|
39801
39972
|
const list2 = (dir) => {
|
|
39802
39973
|
const out2 = [];
|
|
39803
39974
|
const walk2 = (d, prefix) => {
|
|
39804
|
-
for (const e of (0,
|
|
39975
|
+
for (const e of (0, import_node_fs69.readdirSync)(d, { withFileTypes: true })) {
|
|
39805
39976
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
39806
|
-
if (e.isDirectory()) walk2((0,
|
|
39977
|
+
if (e.isDirectory()) walk2((0, import_node_path55.join)(d, e.name), rel);
|
|
39807
39978
|
else if (e.isFile()) out2.push(rel);
|
|
39808
39979
|
}
|
|
39809
39980
|
};
|
|
@@ -39814,8 +39985,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
39814
39985
|
const shipped = list2(src);
|
|
39815
39986
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
39816
39987
|
for (const rel of shipped) {
|
|
39817
|
-
const a = await (0, import_promises20.readFile)((0,
|
|
39818
|
-
const b = await (0, import_promises20.readFile)((0,
|
|
39988
|
+
const a = await (0, import_promises20.readFile)((0, import_node_path55.join)(src, rel), "utf-8");
|
|
39989
|
+
const b = await (0, import_promises20.readFile)((0, import_node_path55.join)(dest, rel), "utf-8");
|
|
39819
39990
|
if (a !== b) return false;
|
|
39820
39991
|
}
|
|
39821
39992
|
return true;
|
|
@@ -39911,7 +40082,7 @@ function parseTelemetryAnswer(raw) {
|
|
|
39911
40082
|
return null;
|
|
39912
40083
|
}
|
|
39913
40084
|
function insideClaudeCode() {
|
|
39914
|
-
return !!process.env.CLAUDECODE || !!
|
|
40085
|
+
return !!process.env.CLAUDECODE || !!envSessionId();
|
|
39915
40086
|
}
|
|
39916
40087
|
function resumeDeferredPending(previous) {
|
|
39917
40088
|
return previous?.telemetry === "deferred";
|
|
@@ -40018,13 +40189,13 @@ async function synthesizeLocally(opts) {
|
|
|
40018
40189
|
async function healStaleAnalysisConfig(globals) {
|
|
40019
40190
|
const configPath = projectPath(CODACY_CONFIG_FILE);
|
|
40020
40191
|
const standardPath = projectPath(STANDARD_FILE);
|
|
40021
|
-
if (!(0,
|
|
40192
|
+
if (!(0, import_node_fs69.existsSync)(configPath) || !(0, import_node_fs69.existsSync)(standardPath)) return;
|
|
40022
40193
|
const validation = validatePatternIds();
|
|
40023
40194
|
if (validation.status !== "invalid") return;
|
|
40024
40195
|
printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
|
|
40025
40196
|
printWarn(" running silently with nothing enabled. Re-deriving it from your Standard\u2026");
|
|
40026
40197
|
try {
|
|
40027
|
-
const content = (0,
|
|
40198
|
+
const content = (0, import_yaml7.parse)(await (0, import_promises20.readFile)(standardPath, "utf-8"));
|
|
40028
40199
|
const derived = await deriveConfigForStandard(content);
|
|
40029
40200
|
for (const path of derived.written) printInfo(` ${path} \u2713 (re-derived)`);
|
|
40030
40201
|
for (const note of derived.notes) printWarn(` ${note}`);
|
|
@@ -40115,17 +40286,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
40115
40286
|
async function installSkills(force, step) {
|
|
40116
40287
|
step("Installing skills");
|
|
40117
40288
|
const dataDir = resolveDataDir2();
|
|
40118
|
-
const skillsSource = (0,
|
|
40289
|
+
const skillsSource = (0, import_node_path55.join)(dataDir, "skills");
|
|
40119
40290
|
const skillsDest = ".claude/skills";
|
|
40120
40291
|
let skillsInstalled = 0;
|
|
40121
40292
|
for (const skill of SKILLS) {
|
|
40122
|
-
const src = (0,
|
|
40123
|
-
const dest = (0,
|
|
40124
|
-
if (!(0,
|
|
40293
|
+
const src = (0, import_node_path55.join)(skillsSource, skill);
|
|
40294
|
+
const dest = (0, import_node_path55.join)(skillsDest, skill);
|
|
40295
|
+
if (!(0, import_node_fs69.existsSync)(src)) {
|
|
40125
40296
|
printWarn(` Skill data not found: ${skill}`);
|
|
40126
40297
|
continue;
|
|
40127
40298
|
}
|
|
40128
|
-
if ((0,
|
|
40299
|
+
if ((0, import_node_fs69.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
|
|
40129
40300
|
skillsInstalled++;
|
|
40130
40301
|
continue;
|
|
40131
40302
|
}
|
|
@@ -40274,7 +40445,7 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
|
|
|
40274
40445
|
if (!toolchain) {
|
|
40275
40446
|
const dir = pinnedVersionDir();
|
|
40276
40447
|
const home = (0, import_node_os11.homedir)();
|
|
40277
|
-
const shown = dir.startsWith(home +
|
|
40448
|
+
const shown = dir.startsWith(home + import_node_path55.sep) ? `~${dir.slice(home.length)}` : dir;
|
|
40278
40449
|
console.log("");
|
|
40279
40450
|
console.log(` "yes" installs Lean 4 (${LEAN_DOWNLOAD_SIZE}) into ${shown}`);
|
|
40280
40451
|
}
|
|
@@ -40333,7 +40504,7 @@ function registerInitCommand(program2) {
|
|
|
40333
40504
|
const staleMarker = clearStalePluginMarker();
|
|
40334
40505
|
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
40335
40506
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
40336
|
-
const isProject = projectMarkers.some((m) => (0,
|
|
40507
|
+
const isProject = projectMarkers.some((m) => (0, import_node_fs69.existsSync)(m));
|
|
40337
40508
|
if (!isProject) {
|
|
40338
40509
|
printError("No project detected in the current directory.");
|
|
40339
40510
|
printInfo('Run "verity init" from your project root.');
|
|
@@ -40436,7 +40607,7 @@ function registerInitCommand(program2) {
|
|
|
40436
40607
|
untrackMemory: opts.untrackMemory === true,
|
|
40437
40608
|
untrackState: opts.untrackState === true
|
|
40438
40609
|
});
|
|
40439
|
-
const globalVerityDir = (0,
|
|
40610
|
+
const globalVerityDir = (0, import_node_path55.join)(process.env.HOME ?? "", ".verity");
|
|
40440
40611
|
await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
|
|
40441
40612
|
console.log("");
|
|
40442
40613
|
step("Wiring Claude Code hooks");
|
|
@@ -40511,7 +40682,7 @@ function registerInitCommand(program2) {
|
|
|
40511
40682
|
}
|
|
40512
40683
|
step("Your project's Standard");
|
|
40513
40684
|
let haveStandard = false;
|
|
40514
|
-
if ((0,
|
|
40685
|
+
if ((0, import_node_fs69.existsSync)(projectPath(STANDARD_FILE))) {
|
|
40515
40686
|
printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
|
|
40516
40687
|
haveStandard = true;
|
|
40517
40688
|
} else {
|
|
@@ -40541,7 +40712,7 @@ function registerInitCommand(program2) {
|
|
|
40541
40712
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
40542
40713
|
init: {
|
|
40543
40714
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40544
|
-
cli_version: true ? "0.34.
|
|
40715
|
+
cli_version: true ? "0.34.2-experimental.3b25de0" : "dev"
|
|
40545
40716
|
}
|
|
40546
40717
|
});
|
|
40547
40718
|
} catch (err2) {
|
|
@@ -40591,8 +40762,8 @@ function registerInitCommand(program2) {
|
|
|
40591
40762
|
}
|
|
40592
40763
|
|
|
40593
40764
|
// src/commands/uninstall.ts
|
|
40594
|
-
var
|
|
40595
|
-
var
|
|
40765
|
+
var import_node_fs70 = require("node:fs");
|
|
40766
|
+
var import_node_path56 = require("node:path");
|
|
40596
40767
|
function registerUninstallCommand(program2) {
|
|
40597
40768
|
program2.command("uninstall").description("Remove Verity from this project (skills, hooks, .verity/, VERITY.md)").option("--dry-run", "Show what would be removed without doing it").option("--purge-global", "Also remove ~/.verity/ (deletes saved tokens \u2014 reconnect requires re-registration)").option("--keep-verity-md", "Keep the project root VERITY.md file").action(async (opts) => {
|
|
40598
40769
|
const dryRun = opts.dryRun ?? false;
|
|
@@ -40601,11 +40772,11 @@ function registerUninstallCommand(program2) {
|
|
|
40601
40772
|
const actions = [];
|
|
40602
40773
|
const skillsRoot = projectPath(".claude/skills");
|
|
40603
40774
|
for (const name2 of PROJECT_SKILL_NAMES) {
|
|
40604
|
-
const dir = (0,
|
|
40605
|
-
if ((0,
|
|
40775
|
+
const dir = (0, import_node_path56.join)(skillsRoot, name2);
|
|
40776
|
+
if ((0, import_node_fs70.existsSync)(dir)) {
|
|
40606
40777
|
actions.push({
|
|
40607
40778
|
label: `Remove .claude/skills/${name2}/`,
|
|
40608
|
-
apply: () => (0,
|
|
40779
|
+
apply: () => (0, import_node_fs70.rmSync)(dir, { recursive: true, force: true })
|
|
40609
40780
|
});
|
|
40610
40781
|
}
|
|
40611
40782
|
}
|
|
@@ -40619,24 +40790,24 @@ function registerUninstallCommand(program2) {
|
|
|
40619
40790
|
});
|
|
40620
40791
|
}
|
|
40621
40792
|
const verityDir = projectPath(VERITY_DIR);
|
|
40622
|
-
if ((0,
|
|
40793
|
+
if ((0, import_node_fs70.existsSync)(verityDir)) {
|
|
40623
40794
|
actions.push({
|
|
40624
40795
|
label: `Remove ${VERITY_DIR}/`,
|
|
40625
|
-
apply: () => (0,
|
|
40796
|
+
apply: () => (0, import_node_fs70.rmSync)(verityDir, { recursive: true, force: true })
|
|
40626
40797
|
});
|
|
40627
40798
|
}
|
|
40628
40799
|
if (!keepVerityMd) {
|
|
40629
40800
|
const verityMd = projectPath(VERITY_MD_FILE);
|
|
40630
|
-
if ((0,
|
|
40801
|
+
if ((0, import_node_fs70.existsSync)(verityMd)) {
|
|
40631
40802
|
actions.push({
|
|
40632
40803
|
label: `Remove ${VERITY_MD_FILE}`,
|
|
40633
|
-
apply: () => (0,
|
|
40804
|
+
apply: () => (0, import_node_fs70.rmSync)(verityMd, { force: true })
|
|
40634
40805
|
});
|
|
40635
40806
|
}
|
|
40636
40807
|
}
|
|
40637
40808
|
const cleanupEmptyDir = (path) => {
|
|
40638
|
-
if ((0,
|
|
40639
|
-
(0,
|
|
40809
|
+
if ((0, import_node_fs70.existsSync)(path) && (0, import_node_fs70.statSync)(path).isDirectory() && (0, import_node_fs70.readdirSync)(path).length === 0) {
|
|
40810
|
+
(0, import_node_fs70.rmdirSync)(path);
|
|
40640
40811
|
}
|
|
40641
40812
|
};
|
|
40642
40813
|
actions.push({
|
|
@@ -40647,11 +40818,11 @@ function registerUninstallCommand(program2) {
|
|
|
40647
40818
|
}
|
|
40648
40819
|
});
|
|
40649
40820
|
const home = process.env.HOME ?? "";
|
|
40650
|
-
const globalVerityDir = (0,
|
|
40651
|
-
if (purgeGlobal && (0,
|
|
40821
|
+
const globalVerityDir = (0, import_node_path56.join)(home, ".verity");
|
|
40822
|
+
if (purgeGlobal && (0, import_node_fs70.existsSync)(globalVerityDir)) {
|
|
40652
40823
|
actions.push({
|
|
40653
40824
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
40654
|
-
apply: () => (0,
|
|
40825
|
+
apply: () => (0, import_node_fs70.rmSync)(globalVerityDir, { recursive: true, force: true })
|
|
40655
40826
|
});
|
|
40656
40827
|
}
|
|
40657
40828
|
if (actions.length === 0) {
|
|
@@ -40678,9 +40849,26 @@ function registerUninstallCommand(program2) {
|
|
|
40678
40849
|
|
|
40679
40850
|
// src/commands/task.ts
|
|
40680
40851
|
function memoryPath() {
|
|
40681
|
-
const sid =
|
|
40852
|
+
const sid = envSessionId();
|
|
40682
40853
|
return sid ? `/memory?session_id=${encodeURIComponent(sid)}` : "/memory";
|
|
40683
40854
|
}
|
|
40855
|
+
var TASK_STATUSES = ["active", "closed", "merged"];
|
|
40856
|
+
var TASK_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
40857
|
+
function isTaskId(value) {
|
|
40858
|
+
return typeof value === "string" && TASK_ID.test(value);
|
|
40859
|
+
}
|
|
40860
|
+
function taskListPath(status) {
|
|
40861
|
+
if (status === void 0) return "/tasks";
|
|
40862
|
+
if (!TASK_STATUSES.includes(status)) return null;
|
|
40863
|
+
return `/tasks?status=${encodeURIComponent(status)}`;
|
|
40864
|
+
}
|
|
40865
|
+
function taskActionPath(taskId, action) {
|
|
40866
|
+
return isTaskId(taskId) ? `/tasks/${encodeURIComponent(taskId)}/${action}` : null;
|
|
40867
|
+
}
|
|
40868
|
+
function refuse(message) {
|
|
40869
|
+
printError(message);
|
|
40870
|
+
process.exit(1);
|
|
40871
|
+
}
|
|
40684
40872
|
function timeAgo2(isoDate) {
|
|
40685
40873
|
const ms = Date.now() - new Date(isoDate).getTime();
|
|
40686
40874
|
const mins = Math.floor(ms / 6e4);
|
|
@@ -40708,10 +40896,11 @@ function registerTaskCommands(program2) {
|
|
|
40708
40896
|
task.command("list").description("List tasks").option("--status <status>", "Filter by status (active, closed, merged)").action(async (opts) => {
|
|
40709
40897
|
const globals = program2.opts();
|
|
40710
40898
|
const { token, serviceUrl } = await getAuth(globals);
|
|
40711
|
-
const
|
|
40899
|
+
const listPath = taskListPath(opts.status);
|
|
40900
|
+
if (!listPath) refuse(`Unknown status ${JSON.stringify(String(opts.status).slice(0, 40))} \u2014 use one of: ${TASK_STATUSES.join(", ")}`);
|
|
40712
40901
|
const result = await apiRequest({
|
|
40713
40902
|
method: "GET",
|
|
40714
|
-
path:
|
|
40903
|
+
path: listPath,
|
|
40715
40904
|
serviceUrl,
|
|
40716
40905
|
token,
|
|
40717
40906
|
verbose: globals.verbose,
|
|
@@ -40760,9 +40949,11 @@ function registerTaskCommands(program2) {
|
|
|
40760
40949
|
}
|
|
40761
40950
|
taskId = ct.id;
|
|
40762
40951
|
}
|
|
40952
|
+
const closePath = taskActionPath(taskId, "close");
|
|
40953
|
+
if (!closePath) refuse(`Not a task id (expected a UUID): ${JSON.stringify(String(taskId).slice(0, 80))}`);
|
|
40763
40954
|
const result = await apiRequest({
|
|
40764
40955
|
method: "POST",
|
|
40765
|
-
path:
|
|
40956
|
+
path: closePath,
|
|
40766
40957
|
serviceUrl,
|
|
40767
40958
|
token,
|
|
40768
40959
|
verbose: globals.verbose,
|
|
@@ -40809,9 +41000,11 @@ function registerTaskCommands(program2) {
|
|
|
40809
41000
|
}
|
|
40810
41001
|
taskId = ct.id;
|
|
40811
41002
|
}
|
|
41003
|
+
const renamePath = taskActionPath(taskId, "rename");
|
|
41004
|
+
if (!renamePath) refuse(`Not a task id (expected a UUID): ${JSON.stringify(String(taskId).slice(0, 80))}`);
|
|
40812
41005
|
const result = await apiRequest({
|
|
40813
41006
|
method: "POST",
|
|
40814
|
-
path:
|
|
41007
|
+
path: renamePath,
|
|
40815
41008
|
serviceUrl,
|
|
40816
41009
|
token,
|
|
40817
41010
|
body: { label: label2.slice(0, 120) },
|
|
@@ -40826,6 +41019,9 @@ function registerTaskCommands(program2) {
|
|
|
40826
41019
|
});
|
|
40827
41020
|
task.command("merge <source> <target>").description("Merge source task into target task").action(async (source2, target) => {
|
|
40828
41021
|
const globals = program2.opts();
|
|
41022
|
+
if (!isTaskId(source2) || !isTaskId(target)) {
|
|
41023
|
+
refuse("task merge takes two task ids (UUIDs): `verity task merge <source> <target>`");
|
|
41024
|
+
}
|
|
40829
41025
|
const { token, serviceUrl } = await getAuth(globals);
|
|
40830
41026
|
const result = await apiRequest({
|
|
40831
41027
|
method: "POST",
|
|
@@ -40845,8 +41041,8 @@ function registerTaskCommands(program2) {
|
|
|
40845
41041
|
}
|
|
40846
41042
|
|
|
40847
41043
|
// src/commands/reset.ts
|
|
40848
|
-
var
|
|
40849
|
-
var
|
|
41044
|
+
var import_node_fs71 = require("node:fs");
|
|
41045
|
+
var import_node_path57 = require("node:path");
|
|
40850
41046
|
function registerResetCommand(program2) {
|
|
40851
41047
|
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) => {
|
|
40852
41048
|
const globals = program2.opts();
|
|
@@ -40855,78 +41051,95 @@ function registerResetCommand(program2) {
|
|
|
40855
41051
|
const tokenResult = await resolveToken(globals.token);
|
|
40856
41052
|
const urlResult = await resolveServiceUrl(globals.serviceUrl);
|
|
40857
41053
|
if (tokenResult.ok && urlResult.ok) {
|
|
41054
|
+
const sessionId = envSessionId();
|
|
40858
41055
|
const mem = await apiRequest({
|
|
40859
41056
|
method: "GET",
|
|
40860
|
-
path:
|
|
41057
|
+
path: sessionId ? `/memory?session_id=${encodeURIComponent(sessionId)}` : "/memory",
|
|
40861
41058
|
serviceUrl: urlResult.data,
|
|
40862
41059
|
token: tokenResult.data.token,
|
|
40863
41060
|
timeout: 1e4,
|
|
40864
41061
|
cmd: "reset_lookup"
|
|
40865
41062
|
});
|
|
40866
41063
|
const ct = mem.ok ? mem.data.current_task : null;
|
|
40867
|
-
|
|
41064
|
+
const closePath = ct?.id ? taskActionPath(ct.id, "close") : null;
|
|
41065
|
+
if (ct?.id && !closePath) {
|
|
41066
|
+
printError("The current task in the service response has a malformed id \u2014 not closing it.");
|
|
41067
|
+
}
|
|
41068
|
+
if (closePath) {
|
|
40868
41069
|
const closeResult = await apiRequest({
|
|
40869
41070
|
method: "POST",
|
|
40870
|
-
path:
|
|
41071
|
+
path: closePath,
|
|
40871
41072
|
serviceUrl: urlResult.data,
|
|
40872
41073
|
token: tokenResult.data.token,
|
|
40873
41074
|
timeout: 1e4,
|
|
40874
41075
|
cmd: "reset_close"
|
|
40875
41076
|
});
|
|
40876
41077
|
if (closeResult.ok) {
|
|
40877
|
-
printInfo(`Closed task: "${ct
|
|
41078
|
+
printInfo(`Closed task: "${terminalText(ct?.label, 200) || "(unnamed)"}"`);
|
|
40878
41079
|
}
|
|
40879
41080
|
}
|
|
40880
41081
|
}
|
|
40881
41082
|
} catch {
|
|
40882
41083
|
}
|
|
40883
41084
|
}
|
|
40884
|
-
const
|
|
40885
|
-
|
|
40886
|
-
|
|
40887
|
-
for (const entry of (0, import_node_fs70.readdirSync)(cacheDir)) {
|
|
40888
|
-
if (entry.startsWith("pending-")) {
|
|
40889
|
-
try {
|
|
40890
|
-
(0, import_node_fs70.unlinkSync)((0, import_node_path55.join)(cacheDir, entry));
|
|
40891
|
-
purged++;
|
|
40892
|
-
} catch {
|
|
40893
|
-
}
|
|
40894
|
-
}
|
|
40895
|
-
}
|
|
40896
|
-
}
|
|
41085
|
+
const purged = purgeVerityDir((0, import_node_path57.basename)(CACHE_DIR), (name2) => name2.startsWith("pending-"));
|
|
41086
|
+
if (purged === null) printError(`Did not purge ${CACHE_DIR}: it is not a directory inside ${VERITY_DIR}.`);
|
|
41087
|
+
const stateDir2 = projectPath(VERITY_DIR);
|
|
40897
41088
|
const filesToClear = [
|
|
40898
|
-
|
|
40899
|
-
|
|
40900
|
-
|
|
40901
|
-
|
|
40902
|
-
|
|
41089
|
+
(0, import_node_path57.basename)(INTENT_FILE),
|
|
41090
|
+
(0, import_node_path57.basename)(HASH_FILE),
|
|
41091
|
+
(0, import_node_path57.basename)(BASELINE_SHA_FILE),
|
|
41092
|
+
".iteration-count",
|
|
41093
|
+
".last-analysis"
|
|
40903
41094
|
];
|
|
40904
|
-
for (const
|
|
40905
|
-
if ((0,
|
|
40906
|
-
|
|
40907
|
-
(0, import_node_fs70.writeFileSync)(file, "");
|
|
40908
|
-
} catch {
|
|
40909
|
-
}
|
|
41095
|
+
for (const name2 of filesToClear) {
|
|
41096
|
+
if (lstatOrNull((0, import_node_path57.join)(stateDir2, name2)) && !replaceInRoot(stateDir2, name2, "")) {
|
|
41097
|
+
printError(`Did not clear ${VERITY_DIR}/${name2}: it is not a regular file inside ${VERITY_DIR}.`);
|
|
40910
41098
|
}
|
|
40911
41099
|
}
|
|
40912
41100
|
if (opts.all) {
|
|
40913
|
-
const
|
|
40914
|
-
if (
|
|
40915
|
-
|
|
40916
|
-
try {
|
|
40917
|
-
(0, import_node_fs70.unlinkSync)((0, import_node_path55.join)(logsDir, entry));
|
|
40918
|
-
} catch {
|
|
40919
|
-
}
|
|
40920
|
-
}
|
|
40921
|
-
}
|
|
40922
|
-
printInfo("Cleared diagnostic logs.");
|
|
41101
|
+
const logs = purgeVerityDir(".logs", () => true);
|
|
41102
|
+
if (logs === null) printError(`Did not clear ${VERITY_DIR}/.logs: it is not a directory inside ${VERITY_DIR}.`);
|
|
41103
|
+
else printInfo("Cleared diagnostic logs.");
|
|
40923
41104
|
}
|
|
40924
|
-
|
|
41105
|
+
const count = purged ?? 0;
|
|
41106
|
+
printInfo(`Reset complete. Purged ${count} cached request${count !== 1 ? "s" : ""}.${opts.keepTask ? "" : " Next run starts a new task."}`);
|
|
40925
41107
|
});
|
|
40926
41108
|
}
|
|
41109
|
+
function lstatOrNull(path) {
|
|
41110
|
+
try {
|
|
41111
|
+
return (0, import_node_fs71.lstatSync)(path);
|
|
41112
|
+
} catch {
|
|
41113
|
+
return null;
|
|
41114
|
+
}
|
|
41115
|
+
}
|
|
41116
|
+
function purgeVerityDir(child, select) {
|
|
41117
|
+
const verityDir = projectPath(VERITY_DIR);
|
|
41118
|
+
const dir = (0, import_node_path57.join)(verityDir, child);
|
|
41119
|
+
const parent = lstatOrNull(verityDir);
|
|
41120
|
+
const st = lstatOrNull(dir);
|
|
41121
|
+
if (!st) return 0;
|
|
41122
|
+
if (!parent || parent.isSymbolicLink() || !parent.isDirectory()) return null;
|
|
41123
|
+
if (st.isSymbolicLink() || !st.isDirectory()) return null;
|
|
41124
|
+
try {
|
|
41125
|
+
if ((0, import_node_fs71.realpathSync)(dir) !== (0, import_node_path57.join)((0, import_node_fs71.realpathSync)(verityDir), child)) return null;
|
|
41126
|
+
} catch {
|
|
41127
|
+
return null;
|
|
41128
|
+
}
|
|
41129
|
+
let removed = 0;
|
|
41130
|
+
for (const entry of (0, import_node_fs71.readdirSync)(dir, { withFileTypes: true })) {
|
|
41131
|
+
if (entry.isDirectory() || !select(entry.name)) continue;
|
|
41132
|
+
try {
|
|
41133
|
+
(0, import_node_fs71.unlinkSync)((0, import_node_path57.join)(dir, entry.name));
|
|
41134
|
+
removed++;
|
|
41135
|
+
} catch {
|
|
41136
|
+
}
|
|
41137
|
+
}
|
|
41138
|
+
return removed;
|
|
41139
|
+
}
|
|
40927
41140
|
|
|
40928
41141
|
// src/commands/reflect.ts
|
|
40929
|
-
var
|
|
41142
|
+
var import_node_fs72 = require("node:fs");
|
|
40930
41143
|
|
|
40931
41144
|
// src/lib/reflection-globs.ts
|
|
40932
41145
|
var MAX_GLOBS = 6;
|
|
@@ -40964,7 +41177,7 @@ async function writeNodeToDisk(args2) {
|
|
|
40964
41177
|
{ treePaths: listTrackedFiles(), recordBaseline: false }
|
|
40965
41178
|
);
|
|
40966
41179
|
if (written === 0) return false;
|
|
40967
|
-
return (0,
|
|
41180
|
+
return (0, import_node_fs72.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
|
|
40968
41181
|
} catch {
|
|
40969
41182
|
return false;
|
|
40970
41183
|
}
|
|
@@ -40995,7 +41208,7 @@ function registerReflectCommand(program2) {
|
|
|
40995
41208
|
let taskResolution = "flag";
|
|
40996
41209
|
let inheritedGlobs = [];
|
|
40997
41210
|
if (!taskId) {
|
|
40998
|
-
const sessionId =
|
|
41211
|
+
const sessionId = envSessionId() ?? "";
|
|
40999
41212
|
const memPath = sessionId ? `/memory?session_id=${encodeURIComponent(sessionId)}` : "/memory";
|
|
41000
41213
|
const mem = await apiRequest({
|
|
41001
41214
|
method: "GET",
|
|
@@ -41401,9 +41614,9 @@ function registerRunCommand(program2) {
|
|
|
41401
41614
|
}
|
|
41402
41615
|
|
|
41403
41616
|
// src/commands/telemetry.ts
|
|
41404
|
-
var
|
|
41617
|
+
var import_node_fs73 = require("node:fs");
|
|
41405
41618
|
async function recordTelemetryChoice(choice) {
|
|
41406
|
-
if (!(0,
|
|
41619
|
+
if (!(0, import_node_fs73.existsSync)(projectPath(SETUP_STATE_FILE))) return;
|
|
41407
41620
|
try {
|
|
41408
41621
|
if ((await readSetupState())?.telemetry === choice) return;
|
|
41409
41622
|
await writeSetupState({ telemetry: choice });
|
|
@@ -41480,8 +41693,8 @@ function registerTelemetryCommands(program2) {
|
|
|
41480
41693
|
}
|
|
41481
41694
|
|
|
41482
41695
|
// src/commands/prove.ts
|
|
41483
|
-
var
|
|
41484
|
-
var
|
|
41696
|
+
var import_node_fs74 = require("node:fs");
|
|
41697
|
+
var import_node_path58 = require("node:path");
|
|
41485
41698
|
|
|
41486
41699
|
// src/lib/prove/hint-pool.ts
|
|
41487
41700
|
var STOP2 = /* @__PURE__ */ new Set([
|
|
@@ -41623,7 +41836,7 @@ function registerProveCommand(program2) {
|
|
|
41623
41836
|
process.exit(2);
|
|
41624
41837
|
}
|
|
41625
41838
|
const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
|
|
41626
|
-
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0,
|
|
41839
|
+
let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path58.relative)(root, (0, import_node_path58.resolve)(p)) || ".") });
|
|
41627
41840
|
if (opts.hint && paths.length === 0) {
|
|
41628
41841
|
const hit = hintMatches(root, opts.hint);
|
|
41629
41842
|
if (hit.files.length > 0) {
|
|
@@ -41677,7 +41890,7 @@ function registerProveCommand(program2) {
|
|
|
41677
41890
|
});
|
|
41678
41891
|
prove.command("check [model]").description("Elaborate a model (or every model) with the local Lean toolchain and report each property").option("--timeout <ms>", "Per-model timeout in ms", "120000").option("--json", "Machine-readable output").action((model, opts) => {
|
|
41679
41892
|
const root = repoRoot();
|
|
41680
|
-
if (!(0,
|
|
41893
|
+
if (!(0, import_node_fs74.existsSync)((0, import_node_path58.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41681
41894
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41682
41895
|
process.exit(2);
|
|
41683
41896
|
}
|
|
@@ -41701,7 +41914,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41701
41914
|
const reports = [];
|
|
41702
41915
|
for (const f of files) {
|
|
41703
41916
|
const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
|
|
41704
|
-
report.file = (0,
|
|
41917
|
+
report.file = (0, import_node_path58.relative)(root, f);
|
|
41705
41918
|
reports.push(report);
|
|
41706
41919
|
try {
|
|
41707
41920
|
writeResult(root, report);
|
|
@@ -41739,7 +41952,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
|
|
|
41739
41952
|
printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
|
|
41740
41953
|
process.exit(2);
|
|
41741
41954
|
}
|
|
41742
|
-
if (!(0,
|
|
41955
|
+
if (!(0, import_node_fs74.existsSync)((0, import_node_path58.join)(root, PROOFS_DIR, "lakefile.toml"))) {
|
|
41743
41956
|
printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
|
|
41744
41957
|
process.exit(2);
|
|
41745
41958
|
}
|
|
@@ -41770,7 +41983,7 @@ ${report.error ?? ""}`);
|
|
|
41770
41983
|
printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
|
|
41771
41984
|
return;
|
|
41772
41985
|
}
|
|
41773
|
-
const modelSource = readRegularFileInRoot(root, (0,
|
|
41986
|
+
const modelSource = readRegularFileInRoot(root, (0, import_node_path58.relative)(root, file), 512 * 1024);
|
|
41774
41987
|
if (!opts.json) printInfo(`replaying ${targets.length} counterexample(s) of ${model} in network-less containers (${Math.min(targets.length, REPLAY_CONCURRENCY)} at a time)\u2026`);
|
|
41775
41988
|
const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
|
|
41776
41989
|
const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
|
|
@@ -41790,7 +42003,7 @@ ${report.error ?? ""}`);
|
|
|
41790
42003
|
});
|
|
41791
42004
|
prove.command("auto [files...]").description("The formal phase the pre-push guard runs: select one risky symbol among changed files, generate a model, check it, replay counterexamples (default files: the commits ahead of upstream)").option("--deadline <ms>", "Budget for the whole phase", "170000").option("--json", "Machine-readable output").action(async (paths, opts) => {
|
|
41792
42005
|
const root = repoRoot();
|
|
41793
|
-
let files = paths.map((p) => (0,
|
|
42006
|
+
let files = paths.map((p) => (0, import_node_path58.relative)(root, (0, import_node_path58.resolve)(p)));
|
|
41794
42007
|
if (files.length === 0) {
|
|
41795
42008
|
const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
|
|
41796
42009
|
const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
|
|
@@ -41864,7 +42077,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41864
42077
|
let revise;
|
|
41865
42078
|
if (opts.revise) {
|
|
41866
42079
|
const existing = resolveModelFile(root, opts.revise);
|
|
41867
|
-
const src = existing ? readRegularFileInRoot(root, (0,
|
|
42080
|
+
const src = existing ? readRegularFileInRoot(root, (0, import_node_path58.relative)(root, existing), 64 * 1024) : null;
|
|
41868
42081
|
if (!src || !src.ok || !opts.note) {
|
|
41869
42082
|
printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
|
|
41870
42083
|
process.exit(2);
|
|
@@ -41904,8 +42117,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41904
42117
|
});
|
|
41905
42118
|
prove.command("waive <file>").description("Dismiss the remembered formal finding(s) on a file for its current bytes \u2014 the accepted-risk path for a formal block").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action((file, opts) => {
|
|
41906
42119
|
const root = repoRoot();
|
|
41907
|
-
const rel0 = (0,
|
|
41908
|
-
const rel = rel0.startsWith("..") || (0,
|
|
42120
|
+
const rel0 = (0, import_node_path58.relative)(root, (0, import_node_path58.isAbsolute)(file) ? file : (0, import_node_path58.join)(root, file)).replace(/\\/g, "/");
|
|
42121
|
+
const rel = rel0.startsWith("..") || (0, import_node_path58.isAbsolute)(rel0) ? null : rel0;
|
|
41909
42122
|
if (!rel) {
|
|
41910
42123
|
printError(`${file} is not inside this repository`);
|
|
41911
42124
|
process.exit(2);
|
|
@@ -41921,8 +42134,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
|
|
|
41921
42134
|
});
|
|
41922
42135
|
prove.command("hash <file>").description("Print the sha256 of a file, for a model header (Verity.model \u2026 sha256). Path is REPO-relative, as in the header").action((file) => {
|
|
41923
42136
|
const root = repoRoot();
|
|
41924
|
-
const rel = (0,
|
|
41925
|
-
const digest = rel.startsWith("..") || (0,
|
|
42137
|
+
const rel = (0, import_node_path58.relative)(root, (0, import_node_path58.isAbsolute)(file) ? file : (0, import_node_path58.join)(root, file));
|
|
42138
|
+
const digest = rel.startsWith("..") || (0, import_node_path58.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
|
|
41926
42139
|
if (!digest) {
|
|
41927
42140
|
printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
|
|
41928
42141
|
process.exit(2);
|
|
@@ -41956,10 +42169,10 @@ function refreshScaffold(root) {
|
|
|
41956
42169
|
}
|
|
41957
42170
|
|
|
41958
42171
|
// src/commands/lean.ts
|
|
41959
|
-
var
|
|
42172
|
+
var import_node_fs75 = require("node:fs");
|
|
41960
42173
|
var import_node_child_process20 = require("node:child_process");
|
|
41961
42174
|
var import_node_os12 = require("node:os");
|
|
41962
|
-
var
|
|
42175
|
+
var import_node_path59 = require("node:path");
|
|
41963
42176
|
function registerLeanCommand(program2) {
|
|
41964
42177
|
const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
|
|
41965
42178
|
lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
|
|
@@ -41976,7 +42189,7 @@ function registerLeanCommand(program2) {
|
|
|
41976
42189
|
const managed = pinnedVersionDir();
|
|
41977
42190
|
const matches = version ? version.includes(pin) : false;
|
|
41978
42191
|
if (opts.json) {
|
|
41979
|
-
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0,
|
|
42192
|
+
printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs75.existsSync)((0, import_node_path59.join)(managed, "bin")), asset: leanAssetName() });
|
|
41980
42193
|
return;
|
|
41981
42194
|
}
|
|
41982
42195
|
printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
|
|
@@ -41994,7 +42207,7 @@ function registerLeanCommand(program2) {
|
|
|
41994
42207
|
process.exit(2);
|
|
41995
42208
|
}
|
|
41996
42209
|
const dir = pinnedVersionDir();
|
|
41997
|
-
if ((0,
|
|
42210
|
+
if ((0, import_node_fs75.existsSync)((0, import_node_path59.join)(dir, "bin", "lake")) && !opts.force) {
|
|
41998
42211
|
printInfo(`already installed at ${dir}`);
|
|
41999
42212
|
return;
|
|
42000
42213
|
}
|
|
@@ -42030,18 +42243,18 @@ function registerLeanCommand(program2) {
|
|
|
42030
42243
|
});
|
|
42031
42244
|
lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
|
|
42032
42245
|
const dir = pinnedVersionDir();
|
|
42033
|
-
if (!(0,
|
|
42246
|
+
if (!(0, import_node_fs75.existsSync)(dir)) {
|
|
42034
42247
|
printInfo("nothing to remove");
|
|
42035
42248
|
return;
|
|
42036
42249
|
}
|
|
42037
|
-
(0,
|
|
42250
|
+
(0, import_node_fs75.rmSync)(dir, { recursive: true, force: true });
|
|
42038
42251
|
printInfo(`removed ${dir}`);
|
|
42039
42252
|
});
|
|
42040
42253
|
}
|
|
42041
42254
|
|
|
42042
42255
|
// src/cli.ts
|
|
42043
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.34.
|
|
42044
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.
|
|
42256
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.34.2-experimental.3b25de0").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) => {
|
|
42257
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.2-experimental.3b25de0");
|
|
42045
42258
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
42046
42259
|
try {
|
|
42047
42260
|
await foldLegacyLocalCredential();
|