@codacy/verity-cli 0.35.1-experimental.19ce23f → 0.35.2
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 +29 -3
- package/bin/verity.js +792 -571
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -2928,7 +2928,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2928
2928
|
* @param {(string | Function)} text - string to add, or a function returning a string
|
|
2929
2929
|
* @return {Command} `this` command for chaining
|
|
2930
2930
|
*/
|
|
2931
|
-
addHelpText(position,
|
|
2931
|
+
addHelpText(position, text3) {
|
|
2932
2932
|
const allowedValues = ["beforeAll", "before", "after", "afterAll"];
|
|
2933
2933
|
if (!allowedValues.includes(position)) {
|
|
2934
2934
|
throw new Error(`Unexpected value for position to addHelpText.
|
|
@@ -2937,10 +2937,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2937
2937
|
const helpEvent = `${position}Help`;
|
|
2938
2938
|
this.on(helpEvent, (context) => {
|
|
2939
2939
|
let helpStr;
|
|
2940
|
-
if (typeof
|
|
2941
|
-
helpStr =
|
|
2940
|
+
if (typeof text3 === "function") {
|
|
2941
|
+
helpStr = text3({ error: context.error, command: context.command });
|
|
2942
2942
|
} else {
|
|
2943
|
-
helpStr =
|
|
2943
|
+
helpStr = text3;
|
|
2944
2944
|
}
|
|
2945
2945
|
if (helpStr) {
|
|
2946
2946
|
context.write(`${helpStr}
|
|
@@ -3750,13 +3750,13 @@ var require_createNode = __commonJS2({
|
|
|
3750
3750
|
var defaultTagPrefix = "tag:yaml.org,2002:";
|
|
3751
3751
|
function findTagObject(value, tagName, tags) {
|
|
3752
3752
|
if (tagName) {
|
|
3753
|
-
const match = tags.filter((
|
|
3754
|
-
const tagObj = match.find((
|
|
3753
|
+
const match = tags.filter((t2) => t2.tag === tagName);
|
|
3754
|
+
const tagObj = match.find((t2) => !t2.format) ?? match[0];
|
|
3755
3755
|
if (!tagObj)
|
|
3756
3756
|
throw new Error(`Tag ${tagName} not found`);
|
|
3757
3757
|
return tagObj;
|
|
3758
3758
|
}
|
|
3759
|
-
return tags.find((
|
|
3759
|
+
return tags.find((t2) => t2.identify?.(value) && !t2.format);
|
|
3760
3760
|
}
|
|
3761
3761
|
function createNode(value, tagName, ctx) {
|
|
3762
3762
|
if (identity.isDocument(value))
|
|
@@ -3982,14 +3982,14 @@ var require_foldFlowLines = __commonJS2({
|
|
|
3982
3982
|
var FOLD_FLOW = "flow";
|
|
3983
3983
|
var FOLD_BLOCK = "block";
|
|
3984
3984
|
var FOLD_QUOTED = "quoted";
|
|
3985
|
-
function foldFlowLines(
|
|
3985
|
+
function foldFlowLines(text3, indent, mode2 = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
|
|
3986
3986
|
if (!lineWidth || lineWidth < 0)
|
|
3987
|
-
return
|
|
3987
|
+
return text3;
|
|
3988
3988
|
if (lineWidth < minContentWidth)
|
|
3989
3989
|
minContentWidth = 0;
|
|
3990
3990
|
const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
|
|
3991
|
-
if (
|
|
3992
|
-
return
|
|
3991
|
+
if (text3.length <= endStep)
|
|
3992
|
+
return text3;
|
|
3993
3993
|
const folds = [];
|
|
3994
3994
|
const escapedFolds = {};
|
|
3995
3995
|
let end = lineWidth - indent.length;
|
|
@@ -4006,14 +4006,14 @@ var require_foldFlowLines = __commonJS2({
|
|
|
4006
4006
|
let escStart = -1;
|
|
4007
4007
|
let escEnd = -1;
|
|
4008
4008
|
if (mode2 === FOLD_BLOCK) {
|
|
4009
|
-
i2 = consumeMoreIndentedLines(
|
|
4009
|
+
i2 = consumeMoreIndentedLines(text3, i2, indent.length);
|
|
4010
4010
|
if (i2 !== -1)
|
|
4011
4011
|
end = i2 + endStep;
|
|
4012
4012
|
}
|
|
4013
|
-
for (let ch; ch =
|
|
4013
|
+
for (let ch; ch = text3[i2 += 1]; ) {
|
|
4014
4014
|
if (mode2 === FOLD_QUOTED && ch === "\\") {
|
|
4015
4015
|
escStart = i2;
|
|
4016
|
-
switch (
|
|
4016
|
+
switch (text3[i2 + 1]) {
|
|
4017
4017
|
case "x":
|
|
4018
4018
|
i2 += 3;
|
|
4019
4019
|
break;
|
|
@@ -4030,12 +4030,12 @@ var require_foldFlowLines = __commonJS2({
|
|
|
4030
4030
|
}
|
|
4031
4031
|
if (ch === "\n") {
|
|
4032
4032
|
if (mode2 === FOLD_BLOCK)
|
|
4033
|
-
i2 = consumeMoreIndentedLines(
|
|
4033
|
+
i2 = consumeMoreIndentedLines(text3, i2, indent.length);
|
|
4034
4034
|
end = i2 + indent.length + endStep;
|
|
4035
4035
|
split = void 0;
|
|
4036
4036
|
} else {
|
|
4037
4037
|
if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
|
|
4038
|
-
const next =
|
|
4038
|
+
const next = text3[i2 + 1];
|
|
4039
4039
|
if (next && next !== " " && next !== "\n" && next !== " ")
|
|
4040
4040
|
split = i2;
|
|
4041
4041
|
}
|
|
@@ -4047,12 +4047,12 @@ var require_foldFlowLines = __commonJS2({
|
|
|
4047
4047
|
} else if (mode2 === FOLD_QUOTED) {
|
|
4048
4048
|
while (prev === " " || prev === " ") {
|
|
4049
4049
|
prev = ch;
|
|
4050
|
-
ch =
|
|
4050
|
+
ch = text3[i2 += 1];
|
|
4051
4051
|
overflow = true;
|
|
4052
4052
|
}
|
|
4053
4053
|
const j = i2 > escEnd + 1 ? i2 - 2 : escStart - 1;
|
|
4054
4054
|
if (escapedFolds[j])
|
|
4055
|
-
return
|
|
4055
|
+
return text3;
|
|
4056
4056
|
folds.push(j);
|
|
4057
4057
|
escapedFolds[j] = true;
|
|
4058
4058
|
end = j + endStep;
|
|
@@ -4067,39 +4067,39 @@ var require_foldFlowLines = __commonJS2({
|
|
|
4067
4067
|
if (overflow && onOverflow)
|
|
4068
4068
|
onOverflow();
|
|
4069
4069
|
if (folds.length === 0)
|
|
4070
|
-
return
|
|
4070
|
+
return text3;
|
|
4071
4071
|
if (onFold)
|
|
4072
4072
|
onFold();
|
|
4073
|
-
let res =
|
|
4073
|
+
let res = text3.slice(0, folds[0]);
|
|
4074
4074
|
for (let i3 = 0; i3 < folds.length; ++i3) {
|
|
4075
4075
|
const fold2 = folds[i3];
|
|
4076
|
-
const end2 = folds[i3 + 1] ||
|
|
4076
|
+
const end2 = folds[i3 + 1] || text3.length;
|
|
4077
4077
|
if (fold2 === 0)
|
|
4078
4078
|
res = `
|
|
4079
|
-
${indent}${
|
|
4079
|
+
${indent}${text3.slice(0, end2)}`;
|
|
4080
4080
|
else {
|
|
4081
4081
|
if (mode2 === FOLD_QUOTED && escapedFolds[fold2])
|
|
4082
|
-
res += `${
|
|
4082
|
+
res += `${text3[fold2]}\\`;
|
|
4083
4083
|
res += `
|
|
4084
|
-
${indent}${
|
|
4084
|
+
${indent}${text3.slice(fold2 + 1, end2)}`;
|
|
4085
4085
|
}
|
|
4086
4086
|
}
|
|
4087
4087
|
return res;
|
|
4088
4088
|
}
|
|
4089
|
-
function consumeMoreIndentedLines(
|
|
4089
|
+
function consumeMoreIndentedLines(text3, i2, indent) {
|
|
4090
4090
|
let end = i2;
|
|
4091
4091
|
let start2 = i2 + 1;
|
|
4092
|
-
let ch =
|
|
4092
|
+
let ch = text3[start2];
|
|
4093
4093
|
while (ch === " " || ch === " ") {
|
|
4094
4094
|
if (i2 < start2 + indent) {
|
|
4095
|
-
ch =
|
|
4095
|
+
ch = text3[++i2];
|
|
4096
4096
|
} else {
|
|
4097
4097
|
do {
|
|
4098
|
-
ch =
|
|
4098
|
+
ch = text3[++i2];
|
|
4099
4099
|
} while (ch && ch !== "\n");
|
|
4100
4100
|
end = i2;
|
|
4101
4101
|
start2 = i2 + 1;
|
|
4102
|
-
ch =
|
|
4102
|
+
ch = text3[start2];
|
|
4103
4103
|
}
|
|
4104
4104
|
}
|
|
4105
4105
|
return end;
|
|
@@ -4383,10 +4383,10 @@ ${indent}`);
|
|
|
4383
4383
|
let res = _stringify(type);
|
|
4384
4384
|
if (res === null) {
|
|
4385
4385
|
const { defaultKeyType, defaultStringType } = ctx.options;
|
|
4386
|
-
const
|
|
4387
|
-
res = _stringify(
|
|
4386
|
+
const t2 = implicitKey && defaultKeyType || defaultStringType;
|
|
4387
|
+
res = _stringify(t2);
|
|
4388
4388
|
if (res === null)
|
|
4389
|
-
throw new Error(`Unsupported default string type ${
|
|
4389
|
+
throw new Error(`Unsupported default string type ${t2}`);
|
|
4390
4390
|
}
|
|
4391
4391
|
return res;
|
|
4392
4392
|
}
|
|
@@ -4446,24 +4446,24 @@ var require_stringify = __commonJS2({
|
|
|
4446
4446
|
}
|
|
4447
4447
|
function getTagObject(tags, item) {
|
|
4448
4448
|
if (item.tag) {
|
|
4449
|
-
const match = tags.filter((
|
|
4449
|
+
const match = tags.filter((t2) => t2.tag === item.tag);
|
|
4450
4450
|
if (match.length > 0)
|
|
4451
|
-
return match.find((
|
|
4451
|
+
return match.find((t2) => t2.format === item.format) ?? match[0];
|
|
4452
4452
|
}
|
|
4453
4453
|
let tagObj = void 0;
|
|
4454
4454
|
let obj;
|
|
4455
4455
|
if (identity.isScalar(item)) {
|
|
4456
4456
|
obj = item.value;
|
|
4457
|
-
let match = tags.filter((
|
|
4457
|
+
let match = tags.filter((t2) => t2.identify?.(obj));
|
|
4458
4458
|
if (match.length > 1) {
|
|
4459
|
-
const testMatch = match.filter((
|
|
4459
|
+
const testMatch = match.filter((t2) => t2.test);
|
|
4460
4460
|
if (testMatch.length > 0)
|
|
4461
4461
|
match = testMatch;
|
|
4462
4462
|
}
|
|
4463
|
-
tagObj = match.find((
|
|
4463
|
+
tagObj = match.find((t2) => t2.format === item.format) ?? match.find((t2) => !t2.format);
|
|
4464
4464
|
} else {
|
|
4465
4465
|
obj = item;
|
|
4466
|
-
tagObj = tags.find((
|
|
4466
|
+
tagObj = tags.find((t2) => t2.nodeClass && obj instanceof t2.nodeClass);
|
|
4467
4467
|
}
|
|
4468
4468
|
if (!tagObj) {
|
|
4469
4469
|
const name2 = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
|
|
@@ -7389,7 +7389,7 @@ var require_compose_collection = __commonJS2({
|
|
|
7389
7389
|
if (!tagToken || !tagName || tagName === "!" || tagName === YAMLMap.YAMLMap.tagName && expType === "map" || tagName === YAMLSeq.YAMLSeq.tagName && expType === "seq") {
|
|
7390
7390
|
return resolveCollection(CN, ctx, token, onError, tagName);
|
|
7391
7391
|
}
|
|
7392
|
-
let tag = ctx.schema.tags.find((
|
|
7392
|
+
let tag = ctx.schema.tags.find((t2) => t2.tag === tagName && t2.collection === expType);
|
|
7393
7393
|
if (!tag) {
|
|
7394
7394
|
const kt = ctx.schema.knownTags[tagName];
|
|
7395
7395
|
if (kt?.collection === expType) {
|
|
@@ -13882,11 +13882,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
13882
13882
|
for (const c of captures) {
|
|
13883
13883
|
if (c.name === captureName) nodes.push(c.node.text);
|
|
13884
13884
|
}
|
|
13885
|
-
const test = /* @__PURE__ */ __name((
|
|
13886
|
-
return positive ? regex.test(
|
|
13885
|
+
const test = /* @__PURE__ */ __name((text3, positive) => {
|
|
13886
|
+
return positive ? regex.test(text3) : !regex.test(text3);
|
|
13887
13887
|
}, "test");
|
|
13888
13888
|
if (nodes.length === 0) return !isPositive;
|
|
13889
|
-
return matchAll2 ? nodes.every((
|
|
13889
|
+
return matchAll2 ? nodes.every((text3) => test(text3, isPositive)) : nodes.some((text3) => test(text3, isPositive));
|
|
13890
13890
|
});
|
|
13891
13891
|
}
|
|
13892
13892
|
__name(parseMatchPredicate, "parseMatchPredicate");
|
|
@@ -13916,7 +13916,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
13916
13916
|
if (c.name === captureName) nodes.push(c.node.text);
|
|
13917
13917
|
}
|
|
13918
13918
|
if (nodes.length === 0) return !isPositive;
|
|
13919
|
-
return nodes.every((
|
|
13919
|
+
return nodes.every((text3) => values.includes(text3)) === isPositive;
|
|
13920
13920
|
});
|
|
13921
13921
|
}
|
|
13922
13922
|
__name(parseAnyOfPredicate, "parseAnyOfPredicate");
|
|
@@ -14517,9 +14517,9 @@ function treeDir(identity) {
|
|
|
14517
14517
|
return (0, import_node_path.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
|
|
14518
14518
|
}
|
|
14519
14519
|
function scopeIdentity(token, sessionId) {
|
|
14520
|
-
const
|
|
14520
|
+
const t2 = (token ?? "").trim();
|
|
14521
14521
|
const s = (sessionId ?? "").trim();
|
|
14522
|
-
const userKey =
|
|
14522
|
+
const userKey = t2.length > 0 ? (0, import_node_crypto.createHash)("sha256").update(t2).digest("hex").slice(0, 12) : "anon";
|
|
14523
14523
|
const sessionKey2 = s.length > 0 ? (0, import_node_crypto.createHash)("sha256").update(s).digest("hex").slice(0, 16) : "_default";
|
|
14524
14524
|
return { userKey, sessionKey: sessionKey2, bucket: `${userKey}/${sessionKey2}` };
|
|
14525
14525
|
}
|
|
@@ -14733,7 +14733,7 @@ var SECURITY_PATTERNS = [
|
|
|
14733
14733
|
/(^|\/)gradle\.lockfile$/
|
|
14734
14734
|
];
|
|
14735
14735
|
var PROD_SERVICE_URL = "https://ofcamwrjwrkazqvdchko.supabase.co/functions/v1";
|
|
14736
|
-
var DEFAULT_SERVICE_URL = "
|
|
14736
|
+
var DEFAULT_SERVICE_URL = "".length > 0 ? "" : PROD_SERVICE_URL;
|
|
14737
14737
|
var GITHUB_CLIENT_ID = "Iv23li88HxAi3ZrbYzWh";
|
|
14738
14738
|
var GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
|
|
14739
14739
|
var GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
@@ -15325,7 +15325,7 @@ function pinRefusalMessage(verdict, targetUrl) {
|
|
|
15325
15325
|
// src/lib/cli-version.ts
|
|
15326
15326
|
function cliVersion() {
|
|
15327
15327
|
try {
|
|
15328
|
-
return true ? "0.35.
|
|
15328
|
+
return true ? "0.35.2" : "dev";
|
|
15329
15329
|
} catch {
|
|
15330
15330
|
return "dev";
|
|
15331
15331
|
}
|
|
@@ -15758,14 +15758,14 @@ function clipboards(platform4, env) {
|
|
|
15758
15758
|
if (env.DISPLAY) out2.push(["xclip", ["-selection", "clipboard"]], ["xsel", ["--clipboard", "--input"]]);
|
|
15759
15759
|
return out2;
|
|
15760
15760
|
}
|
|
15761
|
-
function copyToClipboard(
|
|
15761
|
+
function copyToClipboard(text3, opts = {}) {
|
|
15762
15762
|
const env = opts.env ?? process.env;
|
|
15763
15763
|
const platform4 = opts.platform ?? process.platform;
|
|
15764
|
-
if (!/^[A-Za-z0-9-]{1,32}$/.test(
|
|
15764
|
+
if (!/^[A-Za-z0-9-]{1,32}$/.test(text3)) return false;
|
|
15765
15765
|
if (env.SSH_CONNECTION || env.SSH_TTY || env.CI) return false;
|
|
15766
15766
|
for (const [cmd, args2] of clipboards(platform4, env)) {
|
|
15767
15767
|
try {
|
|
15768
|
-
const r = (opts.run ?? import_node_child_process4.spawnSync)(cmd, args2, { input:
|
|
15768
|
+
const r = (opts.run ?? import_node_child_process4.spawnSync)(cmd, args2, { input: text3, stdio: ["pipe", "ignore", "ignore"], timeout: 2e3 });
|
|
15769
15769
|
if (!r.error && r.status === 0) return true;
|
|
15770
15770
|
} catch {
|
|
15771
15771
|
}
|
|
@@ -15835,11 +15835,11 @@ function startSpinner(label2, opts = {}) {
|
|
|
15835
15835
|
},
|
|
15836
15836
|
succeed(message) {
|
|
15837
15837
|
finish(() => {
|
|
15838
|
-
const
|
|
15838
|
+
const text3 = message ?? current;
|
|
15839
15839
|
const clock2 = showElapsed ? ` (${secondsSince(start2)})` : "";
|
|
15840
15840
|
stream.write(
|
|
15841
|
-
color ? ` ${GREEN2}\u2713${RESET} ${
|
|
15842
|
-
` : ` \u2713 ${
|
|
15841
|
+
color ? ` ${GREEN2}\u2713${RESET} ${text3}${DIM2}${clock2}${RESET}
|
|
15842
|
+
` : ` \u2713 ${text3}${clock2}
|
|
15843
15843
|
`
|
|
15844
15844
|
);
|
|
15845
15845
|
});
|
|
@@ -16365,11 +16365,11 @@ function clearPendingLogin() {
|
|
|
16365
16365
|
// src/lib/login-report.ts
|
|
16366
16366
|
async function describeLoginOutcome(out2, opts = {}) {
|
|
16367
16367
|
const lines = [];
|
|
16368
|
-
const info2 = (
|
|
16369
|
-
lines.push({ level: "info", text:
|
|
16368
|
+
const info2 = (text3) => {
|
|
16369
|
+
lines.push({ level: "info", text: text3 });
|
|
16370
16370
|
};
|
|
16371
|
-
const warn = (
|
|
16372
|
-
lines.push({ level: "warn", text:
|
|
16371
|
+
const warn = (text3) => {
|
|
16372
|
+
lines.push({ level: "warn", text: text3 });
|
|
16373
16373
|
};
|
|
16374
16374
|
const identity = out2.email ?? (out2.userId != null ? `user #${out2.userId}` : "your account");
|
|
16375
16375
|
info2(`Logged in as ${identity}. \u2713`);
|
|
@@ -16683,12 +16683,14 @@ function removeIfOurs(fd, path) {
|
|
|
16683
16683
|
} catch {
|
|
16684
16684
|
}
|
|
16685
16685
|
}
|
|
16686
|
-
function openTarget(path, append2) {
|
|
16686
|
+
function openTarget(path, append2, createOnly = false) {
|
|
16687
16687
|
const base = import_node_fs7.constants.O_WRONLY | (append2 ? import_node_fs7.constants.O_APPEND : 0) | O_NOFOLLOW;
|
|
16688
|
-
|
|
16689
|
-
|
|
16690
|
-
|
|
16691
|
-
|
|
16688
|
+
if (!createOnly) {
|
|
16689
|
+
try {
|
|
16690
|
+
return { fd: (0, import_node_fs7.openSync)(path, base), created: false };
|
|
16691
|
+
} catch (e) {
|
|
16692
|
+
if (e.code !== "ENOENT") return null;
|
|
16693
|
+
}
|
|
16692
16694
|
}
|
|
16693
16695
|
try {
|
|
16694
16696
|
return { fd: (0, import_node_fs7.openSync)(path, base | import_node_fs7.constants.O_CREAT | import_node_fs7.constants.O_EXCL, 384), created: true };
|
|
@@ -16696,13 +16698,13 @@ function openTarget(path, append2) {
|
|
|
16696
16698
|
return null;
|
|
16697
16699
|
}
|
|
16698
16700
|
}
|
|
16699
|
-
function writeVerified(root, name2, hooks, append2, write) {
|
|
16701
|
+
function writeVerified(root, name2, hooks, append2, write, createOnly = false) {
|
|
16700
16702
|
const r = validateRoot(root);
|
|
16701
16703
|
if (!r || !bareName(name2)) return false;
|
|
16702
16704
|
const path = (0, import_node_path7.join)(r.real, name2);
|
|
16703
16705
|
if (!absentOrRegular(path)) return false;
|
|
16704
16706
|
if (!runHook(hooks)) return false;
|
|
16705
|
-
const opened = openTarget(path, append2);
|
|
16707
|
+
const opened = openTarget(path, append2, createOnly);
|
|
16706
16708
|
if (!opened) return false;
|
|
16707
16709
|
try {
|
|
16708
16710
|
if (!verifyOpened(opened.fd, path, r)) {
|
|
@@ -16728,17 +16730,22 @@ function runHook(hooks) {
|
|
|
16728
16730
|
return false;
|
|
16729
16731
|
}
|
|
16730
16732
|
}
|
|
16731
|
-
function appendInRoot(root, name2,
|
|
16733
|
+
function appendInRoot(root, name2, text3, hooks = {}) {
|
|
16732
16734
|
return writeVerified(root, name2, hooks, true, (fd) => {
|
|
16733
|
-
(0, import_node_fs7.writeSync)(fd,
|
|
16735
|
+
(0, import_node_fs7.writeSync)(fd, text3);
|
|
16734
16736
|
});
|
|
16735
16737
|
}
|
|
16736
|
-
function replaceInRoot(root, name2,
|
|
16738
|
+
function replaceInRoot(root, name2, text3, hooks = {}) {
|
|
16737
16739
|
return writeVerified(root, name2, hooks, false, (fd) => {
|
|
16738
16740
|
(0, import_node_fs7.ftruncateSync)(fd, 0);
|
|
16739
|
-
(0, import_node_fs7.writeSync)(fd,
|
|
16741
|
+
(0, import_node_fs7.writeSync)(fd, text3, 0);
|
|
16740
16742
|
});
|
|
16741
16743
|
}
|
|
16744
|
+
function createInRoot(root, name2, text3, hooks = {}) {
|
|
16745
|
+
return writeVerified(root, name2, hooks, false, (fd) => {
|
|
16746
|
+
(0, import_node_fs7.writeSync)(fd, text3, 0);
|
|
16747
|
+
}, true);
|
|
16748
|
+
}
|
|
16742
16749
|
|
|
16743
16750
|
// src/lib/repo-file.ts
|
|
16744
16751
|
var DEFAULT_MAX_BYTES = 512 * 1024;
|
|
@@ -16748,6 +16755,16 @@ function writeRepoFile(relative9, body2) {
|
|
|
16748
16755
|
throw new Error(`refused to write ${relative9}: it, or its folder, is a link or not a regular file`);
|
|
16749
16756
|
}
|
|
16750
16757
|
}
|
|
16758
|
+
var COPY_NAMES = 10;
|
|
16759
|
+
function keepStandardCopy(body2, now = /* @__PURE__ */ new Date()) {
|
|
16760
|
+
const stamp2 = now.toISOString().replace(/[:.]/g, "-");
|
|
16761
|
+
for (let n2 = 0; n2 < COPY_NAMES; n2++) {
|
|
16762
|
+
const relative9 = `${VERITY_DIR}/standard.${stamp2}${n2 === 0 ? "" : `-${n2}`}.yaml`;
|
|
16763
|
+
const path = projectPath(relative9);
|
|
16764
|
+
if (createInRoot((0, import_node_path8.dirname)(path), (0, import_node_path8.basename)(path), body2)) return relative9;
|
|
16765
|
+
}
|
|
16766
|
+
throw new Error(`refused to create ${VERITY_DIR}/standard.${stamp2}.yaml: ${VERITY_DIR} is a link or not a folder, or ${COPY_NAMES} copies with that time exist`);
|
|
16767
|
+
}
|
|
16751
16768
|
function readRepoFile(relative9, maxBytes = DEFAULT_MAX_BYTES) {
|
|
16752
16769
|
const root = repoRoot();
|
|
16753
16770
|
if (throughLinkedFolder(root, relative9)) return null;
|
|
@@ -17321,9 +17338,9 @@ function declaredDependencies(root, files) {
|
|
|
17321
17338
|
for (const path of pythonManifests) {
|
|
17322
17339
|
if (!(0, import_node_fs10.existsSync)(path)) continue;
|
|
17323
17340
|
try {
|
|
17324
|
-
const
|
|
17325
|
-
for (const m of
|
|
17326
|
-
for (const line2 of
|
|
17341
|
+
const text3 = (0, import_node_fs10.readFileSync)(path, "utf-8");
|
|
17342
|
+
for (const m of text3.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
|
|
17343
|
+
for (const line2 of text3.split("\n")) {
|
|
17327
17344
|
if (!/dependencies\s*=/.test(line2)) continue;
|
|
17328
17345
|
for (const m of line2.matchAll(/["']([A-Za-z][A-Za-z0-9._-]+)/g)) names2.push(m[1]);
|
|
17329
17346
|
}
|
|
@@ -17337,8 +17354,8 @@ function declaredDependencies(root, files) {
|
|
|
17337
17354
|
for (const path of goMods) {
|
|
17338
17355
|
if (!(0, import_node_fs10.existsSync)(path)) continue;
|
|
17339
17356
|
try {
|
|
17340
|
-
const
|
|
17341
|
-
for (const m of
|
|
17357
|
+
const text3 = (0, import_node_fs10.readFileSync)(path, "utf-8");
|
|
17358
|
+
for (const m of text3.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
|
|
17342
17359
|
names2.push(m[1].replace(/^github\.com\//, ""));
|
|
17343
17360
|
}
|
|
17344
17361
|
} catch {
|
|
@@ -17348,9 +17365,9 @@ function declaredDependencies(root, files) {
|
|
|
17348
17365
|
const path = (0, import_node_path10.join)(root, file);
|
|
17349
17366
|
if (!(0, import_node_fs10.existsSync)(path)) continue;
|
|
17350
17367
|
try {
|
|
17351
|
-
const
|
|
17352
|
-
for (const m of
|
|
17353
|
-
if (file === "Cargo.toml") names2.push(...cargoDependencyKeys(
|
|
17368
|
+
const text3 = (0, import_node_fs10.readFileSync)(path, "utf-8");
|
|
17369
|
+
for (const m of text3.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
|
|
17370
|
+
if (file === "Cargo.toml") names2.push(...cargoDependencyKeys(text3));
|
|
17354
17371
|
} catch {
|
|
17355
17372
|
}
|
|
17356
17373
|
}
|
|
@@ -17365,8 +17382,8 @@ function declaredDependencies(root, files) {
|
|
|
17365
17382
|
for (const rel of composerFiles) {
|
|
17366
17383
|
let composer = null;
|
|
17367
17384
|
try {
|
|
17368
|
-
const
|
|
17369
|
-
composer =
|
|
17385
|
+
const text3 = manifest(rel);
|
|
17386
|
+
composer = text3 === null ? null : JSON.parse(text3);
|
|
17370
17387
|
} catch {
|
|
17371
17388
|
}
|
|
17372
17389
|
if (!composer || typeof composer !== "object") continue;
|
|
@@ -17376,20 +17393,20 @@ function declaredDependencies(root, files) {
|
|
|
17376
17393
|
}
|
|
17377
17394
|
}
|
|
17378
17395
|
for (const rel of files.filter((f) => /\.(cs|fs)proj$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT)) {
|
|
17379
|
-
const
|
|
17380
|
-
if (
|
|
17381
|
-
for (const m of
|
|
17396
|
+
const text3 = manifest(rel);
|
|
17397
|
+
if (text3 === null) continue;
|
|
17398
|
+
for (const m of text3.matchAll(/<PackageReference\b[^>]*?\bInclude="([A-Za-z][A-Za-z0-9._-]+)"/g)) names2.push(m[1]);
|
|
17382
17399
|
}
|
|
17383
17400
|
for (const rel of files.filter((f) => f.includes("/") && (0, import_node_path10.basename)(f) === "Cargo.toml").slice(0, NESTED_MANIFEST_LIMIT)) {
|
|
17384
|
-
const
|
|
17385
|
-
if (
|
|
17401
|
+
const text3 = manifest(rel);
|
|
17402
|
+
if (text3 !== null) names2.push(...cargoDependencyKeys(text3));
|
|
17386
17403
|
}
|
|
17387
17404
|
return names2;
|
|
17388
17405
|
}
|
|
17389
|
-
function cargoDependencyKeys(
|
|
17406
|
+
function cargoDependencyKeys(text3) {
|
|
17390
17407
|
const names2 = [];
|
|
17391
17408
|
let inDeps = false;
|
|
17392
|
-
for (const raw of
|
|
17409
|
+
for (const raw of text3.split("\n")) {
|
|
17393
17410
|
const line2 = raw.trim();
|
|
17394
17411
|
const header = /^\[([^\]]+)\]$/.exec(line2);
|
|
17395
17412
|
if (header) {
|
|
@@ -17651,30 +17668,30 @@ function shipsCli(root, files) {
|
|
|
17651
17668
|
};
|
|
17652
17669
|
const candidates2 = files.filter((f) => Object.hasOwn(CLI_DECLARATION, (0, import_node_path11.basename)(f))).sort((a, b) => a.split("/").length - b.split("/").length || a.localeCompare(b));
|
|
17653
17670
|
for (const rel of candidates2) {
|
|
17654
|
-
const
|
|
17655
|
-
if (
|
|
17671
|
+
const text3 = read2(rel);
|
|
17672
|
+
if (text3 !== null && CLI_DECLARATION[(0, import_node_path11.basename)(rel)](text3)) return true;
|
|
17656
17673
|
}
|
|
17657
17674
|
return false;
|
|
17658
17675
|
}
|
|
17659
17676
|
var CLI_DECLARATION = {
|
|
17660
|
-
"package.json": (
|
|
17677
|
+
"package.json": (text3) => {
|
|
17661
17678
|
try {
|
|
17662
|
-
const bin = JSON.parse(
|
|
17679
|
+
const bin = JSON.parse(text3).bin;
|
|
17663
17680
|
return typeof bin === "string" && bin.length > 0 || isRecord(bin) && Object.keys(bin).length > 0;
|
|
17664
17681
|
} catch {
|
|
17665
17682
|
return false;
|
|
17666
17683
|
}
|
|
17667
17684
|
},
|
|
17668
|
-
"pyproject.toml": (
|
|
17669
|
-
"setup.py": (
|
|
17670
|
-
"setup.cfg": (
|
|
17671
|
-
"Cargo.toml": (
|
|
17685
|
+
"pyproject.toml": (text3) => /^\s*\[(project\.scripts|tool\.poetry\.scripts)\]\s*$/m.test(text3),
|
|
17686
|
+
"setup.py": (text3) => /console_scripts/.test(text3),
|
|
17687
|
+
"setup.cfg": (text3) => /console_scripts/.test(text3),
|
|
17688
|
+
"Cargo.toml": (text3) => /^\s*\[\[bin\]\]\s*$/m.test(text3)
|
|
17672
17689
|
};
|
|
17673
17690
|
|
|
17674
17691
|
// src/lib/verity-md.ts
|
|
17675
17692
|
var UNPRINTABLE = /[\u0000-\u001f\u007f-\u009f\u2028\u2029\u202a-\u202e\u2066-\u2069]+/g;
|
|
17676
|
-
function markdownPlain(
|
|
17677
|
-
const oneLine2 =
|
|
17693
|
+
function markdownPlain(text3, max = 200) {
|
|
17694
|
+
const oneLine2 = text3.replace(UNPRINTABLE, " ").replace(/\s+/g, " ").trim();
|
|
17678
17695
|
const bounded = oneLine2.length > max ? `${oneLine2.slice(0, max - 1)}\u2026` : oneLine2;
|
|
17679
17696
|
return bounded.replace(/[\\`*_{}[\]()<>#+!|~]/g, (c) => `\\${c}`);
|
|
17680
17697
|
}
|
|
@@ -17715,7 +17732,7 @@ function describeOrigin(origin) {
|
|
|
17715
17732
|
if (origin.kind === "adopted") {
|
|
17716
17733
|
return `adopted from the service${origin.createdBy ? `, created by ${markdownPlain(origin.createdBy, 120)}` : ""}`;
|
|
17717
17734
|
}
|
|
17718
|
-
return `derived from this codebase${origin.tools.length > 0 ? ` \xB7 ${origin.tools.map((
|
|
17735
|
+
return `derived from this codebase${origin.tools.length > 0 ? ` \xB7 ${origin.tools.map((t2) => markdownPlain(t2, 60)).join(", ")}` : ""}`;
|
|
17719
17736
|
}
|
|
17720
17737
|
function closingNote(origin) {
|
|
17721
17738
|
if (origin.kind === "adopted") {
|
|
@@ -17748,7 +17765,7 @@ ${list2(dimensions, DEFAULT_DIMENSIONS)}
|
|
|
17748
17765
|
${packs.length > 0 ? `## Review Packs
|
|
17749
17766
|
${list2(packs, [])}
|
|
17750
17767
|
|
|
17751
|
-
The Verity service expands each pack into its patterns.
|
|
17768
|
+
The Verity service expands each pack into its patterns. What each pack holds: \`verity standard catalogue <pack>\`, or https://verity.md/review-packs. What this project's review reads: \`verity standard get --resolved\`
|
|
17752
17769
|
` : `## Security Patterns
|
|
17753
17770
|
${list2(patterns, DEFAULT_SECURITY)}
|
|
17754
17771
|
`}${custom.length > 0 ? `
|
|
@@ -18400,11 +18417,11 @@ function registerTokenCommand(program2) {
|
|
|
18400
18417
|
printInfo("No tokens found for this repository.");
|
|
18401
18418
|
return;
|
|
18402
18419
|
}
|
|
18403
|
-
for (const
|
|
18404
|
-
const type =
|
|
18405
|
-
const expires =
|
|
18406
|
-
const lastUsed =
|
|
18407
|
-
printInfo(`${
|
|
18420
|
+
for (const t2 of tokens) {
|
|
18421
|
+
const type = t2.token_type ?? "user";
|
|
18422
|
+
const expires = t2.expires_at ? `expires ${t2.expires_at.slice(0, 10)}` : "no expiry";
|
|
18423
|
+
const lastUsed = t2.last_used_at ? `last used ${t2.last_used_at.slice(0, 10)}` : "never used";
|
|
18424
|
+
printInfo(`${t2.id} [${type}] ${t2.agent_name ?? "unnamed"} (${expires}, ${lastUsed})`);
|
|
18408
18425
|
}
|
|
18409
18426
|
});
|
|
18410
18427
|
token.command("revoke <id>").description("Revoke a token by id (service tokens: any current writer may revoke)").action(async (id) => {
|
|
@@ -19340,13 +19357,13 @@ function scrub(s) {
|
|
|
19340
19357
|
var installed = false;
|
|
19341
19358
|
var wroteBanner = false;
|
|
19342
19359
|
var banner = "";
|
|
19343
|
-
function append(
|
|
19360
|
+
function append(text3) {
|
|
19344
19361
|
try {
|
|
19345
19362
|
const dir = projectPath(DEBUG_LOG_DIR);
|
|
19346
19363
|
const file = projectPath(STDERR_LOG_FILE);
|
|
19347
19364
|
(0, import_node_fs16.mkdirSync)(dir, { recursive: true });
|
|
19348
19365
|
rotateIfNeeded(file);
|
|
19349
|
-
(0, import_node_fs16.appendFileSync)(file,
|
|
19366
|
+
(0, import_node_fs16.appendFileSync)(file, text3);
|
|
19350
19367
|
} catch {
|
|
19351
19368
|
}
|
|
19352
19369
|
}
|
|
@@ -19368,19 +19385,19 @@ function installStderrLog(cmd, argv, version) {
|
|
|
19368
19385
|
const result = original(...args2);
|
|
19369
19386
|
try {
|
|
19370
19387
|
const chunk = args2[0];
|
|
19371
|
-
const
|
|
19388
|
+
const text3 = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf-8") : String(chunk);
|
|
19372
19389
|
ensureBanner();
|
|
19373
|
-
append(scrub(
|
|
19390
|
+
append(scrub(text3));
|
|
19374
19391
|
} catch {
|
|
19375
19392
|
}
|
|
19376
19393
|
return result;
|
|
19377
19394
|
};
|
|
19378
19395
|
process.stderr.write = tee;
|
|
19379
19396
|
}
|
|
19380
|
-
function logToFileOnly(
|
|
19397
|
+
function logToFileOnly(text3) {
|
|
19381
19398
|
if (!installed) return;
|
|
19382
19399
|
ensureBanner();
|
|
19383
|
-
append(
|
|
19400
|
+
append(text3.endsWith("\n") ? text3 : `${text3}
|
|
19384
19401
|
`);
|
|
19385
19402
|
}
|
|
19386
19403
|
|
|
@@ -19954,8 +19971,8 @@ var import_promises5 = require("node:fs/promises");
|
|
|
19954
19971
|
var import_node_fs19 = require("node:fs");
|
|
19955
19972
|
var import_node_child_process8 = require("node:child_process");
|
|
19956
19973
|
var import_node_crypto2 = require("node:crypto");
|
|
19957
|
-
function stripImageReferences(
|
|
19958
|
-
return
|
|
19974
|
+
function stripImageReferences(text3) {
|
|
19975
|
+
return text3.replace(/\[Image #\d+\]/g, "[screenshot \u2014 not available for review]");
|
|
19959
19976
|
}
|
|
19960
19977
|
function bufferTmpPath() {
|
|
19961
19978
|
return `${CONVERSATION_BUFFER_FILE}.${process.pid}.${(0, import_node_crypto2.randomBytes)(4).toString("hex")}.tmp`;
|
|
@@ -20192,7 +20209,7 @@ function isNonAuthoringCommand(cmd) {
|
|
|
20192
20209
|
function hasNonEditAuthorship(actionSummary, sessionAuthoredCode) {
|
|
20193
20210
|
if (!actionSummary) return sessionAuthoredCode;
|
|
20194
20211
|
if ((actionSummary.subagents ?? 0) > 0) return true;
|
|
20195
|
-
if (Object.keys(actionSummary.tool_counts ?? {}).some((
|
|
20212
|
+
if (Object.keys(actionSummary.tool_counts ?? {}).some((t2) => t2.startsWith("mcp__"))) return true;
|
|
20196
20213
|
const commands = actionSummary.commands ?? [];
|
|
20197
20214
|
if (commands.some((c) => FILE_MUTATE_RE.test(c))) return true;
|
|
20198
20215
|
if (sessionAuthoredCode) {
|
|
@@ -20221,7 +20238,7 @@ function narrowToAgentAuthored(files, actionSummary) {
|
|
|
20221
20238
|
if (touched.length === 0) return files;
|
|
20222
20239
|
return files.filter((f) => {
|
|
20223
20240
|
const suffix = "/" + f;
|
|
20224
|
-
return touched.some((
|
|
20241
|
+
return touched.some((t2) => t2 === f || t2.endsWith(suffix));
|
|
20225
20242
|
});
|
|
20226
20243
|
}
|
|
20227
20244
|
|
|
@@ -20731,9 +20748,9 @@ var STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
20731
20748
|
"within",
|
|
20732
20749
|
"without"
|
|
20733
20750
|
]);
|
|
20734
|
-
function tokenize(
|
|
20751
|
+
function tokenize(text3) {
|
|
20735
20752
|
return new Set(
|
|
20736
|
-
|
|
20753
|
+
text3.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 2 && !STOPWORDS.has(w))
|
|
20737
20754
|
);
|
|
20738
20755
|
}
|
|
20739
20756
|
function jaccardKeywords(a, b) {
|
|
@@ -20750,9 +20767,9 @@ function relevance(node, ctx) {
|
|
|
20750
20767
|
if (nodeTags.length > 0 && ctx.changeTags && ctx.changeTags.length > 0) {
|
|
20751
20768
|
const change = new Set(ctx.changeTags);
|
|
20752
20769
|
let hit = 0;
|
|
20753
|
-
for (const
|
|
20754
|
-
if (!change.has(
|
|
20755
|
-
hit +=
|
|
20770
|
+
for (const t2 of nodeTags) {
|
|
20771
|
+
if (!change.has(t2)) continue;
|
|
20772
|
+
hit += t2.startsWith("pkg:") || t2.startsWith("tbl:") ? 1 : t2.startsWith("sym:") ? 0.8 : t2.startsWith("dir:") ? 0.4 : 0.15;
|
|
20756
20773
|
}
|
|
20757
20774
|
tagScore = Math.min(1, hit / TAG_SATURATION);
|
|
20758
20775
|
}
|
|
@@ -20810,9 +20827,9 @@ var MAX_BUDGET_TOKENS = 4e3;
|
|
|
20810
20827
|
var MAX_NODE_FILE_BYTES = 64 * 1024;
|
|
20811
20828
|
var MIN_SCORE = RELEVANCE_FLOOR * 0.5;
|
|
20812
20829
|
var ORG_MIN_SHARED_TERMS = 2;
|
|
20813
|
-
function orgTerms(
|
|
20830
|
+
function orgTerms(text3) {
|
|
20814
20831
|
return new Set(
|
|
20815
|
-
|
|
20832
|
+
text3.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length > 2)
|
|
20816
20833
|
);
|
|
20817
20834
|
}
|
|
20818
20835
|
function sharedTerms(a, b) {
|
|
@@ -21171,12 +21188,12 @@ function ensureVerityGitignore() {
|
|
|
21171
21188
|
if (hasSupersededMemory && !memoryIsCommitted) {
|
|
21172
21189
|
next = fenceMemoryLines(next);
|
|
21173
21190
|
}
|
|
21174
|
-
let
|
|
21191
|
+
let text3 = next.join("\n");
|
|
21175
21192
|
if (!hasMarker) {
|
|
21176
|
-
const sep7 =
|
|
21177
|
-
|
|
21193
|
+
const sep7 = text3 === "" ? "" : text3.endsWith("\n") ? "\n" : "\n\n";
|
|
21194
|
+
text3 = text3 + sep7 + VERITY_GITIGNORE_BLOCK;
|
|
21178
21195
|
}
|
|
21179
|
-
if (
|
|
21196
|
+
if (text3 !== content) (0, import_node_fs24.writeFileSync)(".gitignore", text3);
|
|
21180
21197
|
return verified(
|
|
21181
21198
|
memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
|
|
21182
21199
|
);
|
|
@@ -21202,13 +21219,13 @@ function writeFencedBlock() {
|
|
|
21202
21219
|
const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
|
|
21203
21220
|
let lines = content.split("\n").map((l) => BREAKING_ENTRIES.has(l.trim()) ? ".verity/*" : l);
|
|
21204
21221
|
lines = fenceMemoryLines(lines);
|
|
21205
|
-
let
|
|
21222
|
+
let text3 = lines.join("\n");
|
|
21206
21223
|
if (!hasMarker) {
|
|
21207
|
-
const sep7 =
|
|
21208
|
-
|
|
21224
|
+
const sep7 = text3 === "" ? "" : text3.endsWith("\n") ? "\n" : "\n\n";
|
|
21225
|
+
text3 = text3 + sep7 + VERITY_GITIGNORE_BLOCK;
|
|
21209
21226
|
}
|
|
21210
21227
|
try {
|
|
21211
|
-
(0, import_node_fs24.writeFileSync)(".gitignore",
|
|
21228
|
+
(0, import_node_fs24.writeFileSync)(".gitignore", text3);
|
|
21212
21229
|
return true;
|
|
21213
21230
|
} catch {
|
|
21214
21231
|
return false;
|
|
@@ -22234,26 +22251,26 @@ var CLAUDE_MD_PROSE_LEGACY = [
|
|
|
22234
22251
|
"superseded \u2014 ignore them unless investigating history."
|
|
22235
22252
|
].join("\n");
|
|
22236
22253
|
var PRESERVE_PLACEHOLDER = "<!-- Add binding, hand-curated guidance here; it survives Verity regeneration. -->";
|
|
22237
|
-
function* scanLines(
|
|
22254
|
+
function* scanLines(text3) {
|
|
22238
22255
|
let offset = 0;
|
|
22239
22256
|
let inFence = false;
|
|
22240
|
-
for (const line2 of
|
|
22257
|
+
for (const line2 of text3.split("\n")) {
|
|
22241
22258
|
const isFence = /^(`{3,}|~{3,})/.test(line2.trim());
|
|
22242
22259
|
if (isFence) inFence = !inFence;
|
|
22243
22260
|
yield { line: line2, start: offset, inFence: inFence || isFence };
|
|
22244
22261
|
offset += line2.length + 1;
|
|
22245
22262
|
}
|
|
22246
22263
|
}
|
|
22247
|
-
function findMarker(
|
|
22248
|
-
for (const { line: line2, start: start2, inFence } of scanLines(
|
|
22264
|
+
function findMarker(text3, marker, from = 0) {
|
|
22265
|
+
for (const { line: line2, start: start2, inFence } of scanLines(text3)) {
|
|
22249
22266
|
if (!inFence && start2 >= from && line2.startsWith(marker)) {
|
|
22250
22267
|
return start2;
|
|
22251
22268
|
}
|
|
22252
22269
|
}
|
|
22253
22270
|
return -1;
|
|
22254
22271
|
}
|
|
22255
|
-
function hasLegacyMemoryBlock(
|
|
22256
|
-
return findMarker(
|
|
22272
|
+
function hasLegacyMemoryBlock(text3) {
|
|
22273
|
+
return findMarker(text3, LEGACY_MD_START) !== -1;
|
|
22257
22274
|
}
|
|
22258
22275
|
async function ensureClaudeMdPointer(cwd = repoRoot()) {
|
|
22259
22276
|
const claudeMdPath = (0, import_node_path23.join)(cwd, "CLAUDE.md");
|
|
@@ -22454,10 +22471,10 @@ var STOP = /* @__PURE__ */ new Set([
|
|
|
22454
22471
|
"verify",
|
|
22455
22472
|
"check"
|
|
22456
22473
|
]);
|
|
22457
|
-
function pendingTokens(
|
|
22458
|
-
if (!
|
|
22474
|
+
function pendingTokens(text3) {
|
|
22475
|
+
if (!text3 || typeof text3 !== "string") return [];
|
|
22459
22476
|
const out2 = /* @__PURE__ */ new Set();
|
|
22460
|
-
for (const raw of
|
|
22477
|
+
for (const raw of text3.toLowerCase().split(/[^a-z0-9]+/)) {
|
|
22461
22478
|
if (raw.length <= 3) continue;
|
|
22462
22479
|
if (STOP.has(raw)) continue;
|
|
22463
22480
|
out2.add(raw);
|
|
@@ -22469,11 +22486,11 @@ function overlapCoefficient(a, b) {
|
|
|
22469
22486
|
if (a.length === 0 || b.length === 0) return 0;
|
|
22470
22487
|
const setB = new Set(b);
|
|
22471
22488
|
let shared = 0;
|
|
22472
|
-
for (const
|
|
22489
|
+
for (const t2 of a) if (setB.has(t2)) shared++;
|
|
22473
22490
|
return shared / Math.min(a.length, b.length);
|
|
22474
22491
|
}
|
|
22475
|
-
function isRepeatOfAny(
|
|
22476
|
-
const tokens = pendingTokens(
|
|
22492
|
+
function isRepeatOfAny(text3, priorFingerprints, threshold = REPEAT_THRESHOLD) {
|
|
22493
|
+
const tokens = pendingTokens(text3);
|
|
22477
22494
|
if (tokens.length === 0) return false;
|
|
22478
22495
|
return priorFingerprints.some((prior) => overlapCoefficient(tokens, prior) >= threshold);
|
|
22479
22496
|
}
|
|
@@ -22519,13 +22536,13 @@ var import_node_crypto6 = require("node:crypto");
|
|
|
22519
22536
|
var import_node_fs27 = require("node:fs");
|
|
22520
22537
|
var import_node_path24 = require("node:path");
|
|
22521
22538
|
var CRC_TABLE = (() => {
|
|
22522
|
-
const
|
|
22539
|
+
const t2 = new Int32Array(256);
|
|
22523
22540
|
for (let i2 = 0; i2 < 256; i2++) {
|
|
22524
22541
|
let c = i2;
|
|
22525
22542
|
for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
22526
|
-
|
|
22543
|
+
t2[i2] = c;
|
|
22527
22544
|
}
|
|
22528
|
-
return
|
|
22545
|
+
return t2;
|
|
22529
22546
|
})();
|
|
22530
22547
|
function crc32(s) {
|
|
22531
22548
|
let c = -1;
|
|
@@ -22550,8 +22567,8 @@ function openDossier(identity) {
|
|
|
22550
22567
|
}
|
|
22551
22568
|
var lastSeq = 0;
|
|
22552
22569
|
function nextSeq() {
|
|
22553
|
-
const
|
|
22554
|
-
lastSeq =
|
|
22570
|
+
const t2 = Date.now() * 1e3;
|
|
22571
|
+
lastSeq = t2 > lastSeq ? t2 : lastSeq + 1;
|
|
22555
22572
|
return lastSeq;
|
|
22556
22573
|
}
|
|
22557
22574
|
function encodeEvent(ev) {
|
|
@@ -22996,7 +23013,7 @@ function expandState(raw) {
|
|
|
22996
23013
|
const g = raw.g;
|
|
22997
23014
|
const a = raw.a;
|
|
22998
23015
|
const n2 = raw.n;
|
|
22999
|
-
const
|
|
23016
|
+
const t2 = raw.t;
|
|
23000
23017
|
const c = raw.c;
|
|
23001
23018
|
const dv = raw.d;
|
|
23002
23019
|
const m = raw.m;
|
|
@@ -23047,7 +23064,7 @@ function expandState(raw) {
|
|
|
23047
23064
|
at: iso(x[2]),
|
|
23048
23065
|
head_sha: x[3]
|
|
23049
23066
|
})) ?? null,
|
|
23050
|
-
statements:
|
|
23067
|
+
statements: t2.map((x) => ({
|
|
23051
23068
|
anchor_key: x[0],
|
|
23052
23069
|
file: x[1],
|
|
23053
23070
|
line: x[2],
|
|
@@ -23163,8 +23180,8 @@ function assessContinuity(i2) {
|
|
|
23163
23180
|
// src/lib/dossier/reanchor.ts
|
|
23164
23181
|
var import_node_crypto8 = require("node:crypto");
|
|
23165
23182
|
var import_node_fs30 = require("node:fs");
|
|
23166
|
-
function lineSha(
|
|
23167
|
-
return (0, import_node_crypto8.createHash)("sha256").update(
|
|
23183
|
+
function lineSha(text3) {
|
|
23184
|
+
return (0, import_node_crypto8.createHash)("sha256").update(text3.trim()).digest("hex").slice(0, HASH_WIDTH);
|
|
23168
23185
|
}
|
|
23169
23186
|
function fileHash(path) {
|
|
23170
23187
|
try {
|
|
@@ -23637,20 +23654,20 @@ function recordGoal(d, prompt, source2 = "prompt") {
|
|
|
23637
23654
|
appendEvent(d, { k: "goal_continue", text: prompt.slice(0, 64) });
|
|
23638
23655
|
return;
|
|
23639
23656
|
}
|
|
23640
|
-
const
|
|
23657
|
+
const text3 = prompt.slice(0, MAX_GOAL_CHARS);
|
|
23641
23658
|
appendEvent(d, {
|
|
23642
23659
|
k: "goal",
|
|
23643
|
-
text:
|
|
23660
|
+
text: text3,
|
|
23644
23661
|
text_len: prompt.length,
|
|
23645
23662
|
source: source2,
|
|
23646
23663
|
...prompt.length > MAX_GOAL_CHARS && { truncated: true }
|
|
23647
23664
|
});
|
|
23648
23665
|
}
|
|
23649
|
-
function recordTurn(d,
|
|
23666
|
+
function recordTurn(d, t2) {
|
|
23650
23667
|
const root = repoRoot();
|
|
23651
|
-
for (const a of
|
|
23668
|
+
for (const a of t2.authored) {
|
|
23652
23669
|
const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
|
|
23653
|
-
const prior =
|
|
23670
|
+
const prior = t2.known?.authored?.get(a.p);
|
|
23654
23671
|
const hash = fileHash((0, import_node_path26.join)(root, a.p));
|
|
23655
23672
|
const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
|
|
23656
23673
|
const adds = Math.max(0, a.a - (prior?.adds ?? 0));
|
|
@@ -23658,7 +23675,7 @@ function recordTurn(d, t) {
|
|
|
23658
23675
|
if (prior && hunks === 0 && adds === 0 && dels === 0 && prior.hash_now === hash) continue;
|
|
23659
23676
|
appendEvent(d, { k: "authored", path: a.p, origin, adds, dels, hunks, hash_now: hash });
|
|
23660
23677
|
}
|
|
23661
|
-
for (const c of
|
|
23678
|
+
for (const c of t2.commands) {
|
|
23662
23679
|
appendEvent(d, {
|
|
23663
23680
|
k: "command",
|
|
23664
23681
|
cls: normaliseClass(c.class),
|
|
@@ -23671,20 +23688,20 @@ function recordTurn(d, t) {
|
|
|
23671
23688
|
});
|
|
23672
23689
|
}
|
|
23673
23690
|
const head = getCurrentCommit();
|
|
23674
|
-
for (const p of
|
|
23691
|
+
for (const p of t2.dirtyAtStart ?? []) {
|
|
23675
23692
|
appendEvent(d, { k: "not_mine", path: p, reason: "dirty_at_start", head_sha: head });
|
|
23676
23693
|
}
|
|
23677
|
-
for (const p of
|
|
23694
|
+
for (const p of t2.foreign ?? []) {
|
|
23678
23695
|
appendEvent(d, { k: "not_mine", path: p, reason: "other_session", head_sha: head });
|
|
23679
23696
|
}
|
|
23680
|
-
for (const u of
|
|
23697
|
+
for (const u of t2.unobserved) {
|
|
23681
23698
|
if (isGeneratedPath(u.p)) {
|
|
23682
23699
|
appendEvent(d, { k: "not_mine", path: u.p, reason: "generated", head_sha: head });
|
|
23683
23700
|
}
|
|
23684
23701
|
}
|
|
23685
|
-
const seenDivergence =
|
|
23702
|
+
const seenDivergence = t2.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
23686
23703
|
const fresh = [];
|
|
23687
|
-
for (const u of
|
|
23704
|
+
for (const u of t2.unobserved) {
|
|
23688
23705
|
const hash = fileHash((0, import_node_path26.join)(root, u.p));
|
|
23689
23706
|
const key = divergenceKey(u.p, hash);
|
|
23690
23707
|
const digest = packedDivergenceDigest(key);
|
|
@@ -23701,13 +23718,13 @@ function recordTurn(d, t) {
|
|
|
23701
23718
|
appendEvent(d, { k: "divergence", kind: "external_mutation", path: f.path, hash: f.hash });
|
|
23702
23719
|
}
|
|
23703
23720
|
}
|
|
23704
|
-
const newCompactions = (
|
|
23721
|
+
const newCompactions = (t2.compactions ?? 0) - (t2.known?.compactions ?? 0);
|
|
23705
23722
|
for (let i2 = 0; i2 < newCompactions; i2++) {
|
|
23706
23723
|
appendEvent(d, { k: "mark", kind: "compaction", from: null, to: null });
|
|
23707
23724
|
}
|
|
23708
|
-
const known =
|
|
23709
|
-
if (known &&
|
|
23710
|
-
appendEvent(d, { k: "mark", kind: "branch_switch", from: known, to:
|
|
23725
|
+
const known = t2.known?.branch ?? null;
|
|
23726
|
+
if (known && t2.branch && known !== t2.branch) {
|
|
23727
|
+
appendEvent(d, { k: "mark", kind: "branch_switch", from: known, to: t2.branch });
|
|
23711
23728
|
}
|
|
23712
23729
|
}
|
|
23713
23730
|
function normaliseClass(cls) {
|
|
@@ -23772,7 +23789,7 @@ function recordVerdict(d, v) {
|
|
|
23772
23789
|
// actually spoke — a silenced turn delivered nothing, so nothing was "said
|
|
23773
23790
|
// before" and labelling the next turn's items as repeats would be a lie.
|
|
23774
23791
|
...v.emitted === true && v.pendingTexts && v.pendingTexts.length > 0 && {
|
|
23775
|
-
pending_sigs: v.pendingTexts.slice(0, 8).map((
|
|
23792
|
+
pending_sigs: v.pendingTexts.slice(0, 8).map((t2) => pendingTokens(t2).slice(0, 16))
|
|
23776
23793
|
},
|
|
23777
23794
|
emitted: v.emitted === true,
|
|
23778
23795
|
idle: v.idle !== false,
|
|
@@ -24580,8 +24597,8 @@ function buildCompactionContext(session) {
|
|
|
24580
24597
|
`${r.projection.fold.refused} earlier finding(s) were dropped because the code they pointed at no longer matches. They are resolved; do not revisit them.`
|
|
24581
24598
|
);
|
|
24582
24599
|
}
|
|
24583
|
-
const
|
|
24584
|
-
if (
|
|
24600
|
+
const text3 = lines.join("\n");
|
|
24601
|
+
if (text3.length <= MAX_CHARS) return text3;
|
|
24585
24602
|
const trimmed = [...lines.slice(0, 5), ...lines.slice(5, 5 + 2)].join("\n");
|
|
24586
24603
|
return trimmed.length <= MAX_CHARS ? trimmed : null;
|
|
24587
24604
|
}
|
|
@@ -24647,7 +24664,7 @@ async function readHookStdin() {
|
|
|
24647
24664
|
// src/commands/standard.ts
|
|
24648
24665
|
var import_node_fs38 = require("node:fs");
|
|
24649
24666
|
var import_node_path31 = require("node:path");
|
|
24650
|
-
var
|
|
24667
|
+
var import_yaml8 = __toESM2(require_dist());
|
|
24651
24668
|
|
|
24652
24669
|
// src/lib/synthesize.ts
|
|
24653
24670
|
var import_node_fs36 = require("node:fs");
|
|
@@ -24858,14 +24875,14 @@ function trackedSourceFiles(root, opts = {}) {
|
|
|
24858
24875
|
return files.slice(0, opts.maxFiles ?? 5e3);
|
|
24859
24876
|
}
|
|
24860
24877
|
var EFFECT_LINE = /\bawait\b|\basync\s+with\b|\.then\(|\bsetTimeout\(|\bsetInterval\(|\bwith\s+\w[\w.]*\.(?:lock|acquire)\b|\bLock\(\)/;
|
|
24861
|
-
function countEffects(
|
|
24878
|
+
function countEffects(text3) {
|
|
24862
24879
|
let n2 = 0;
|
|
24863
|
-
for (const line2 of
|
|
24880
|
+
for (const line2 of text3.split("\n")) if (EFFECT_LINE.test(line2)) n2++;
|
|
24864
24881
|
return n2;
|
|
24865
24882
|
}
|
|
24866
|
-
function scanRisk(
|
|
24883
|
+
function scanRisk(text3) {
|
|
24867
24884
|
const counts = Object.fromEntries(RISK_PATTERNS.map(([c]) => [c, 0]));
|
|
24868
|
-
for (const line2 of
|
|
24885
|
+
for (const line2 of text3.split("\n")) {
|
|
24869
24886
|
for (const [category, re] of RISK_PATTERNS) {
|
|
24870
24887
|
if (re.test(line2)) counts[category]++;
|
|
24871
24888
|
}
|
|
@@ -24961,14 +24978,14 @@ var SECRET_PATTERNS = [
|
|
|
24961
24978
|
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
24962
24979
|
var URL_CREDENTIALS = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/:@]+:[^\s/@]+@/gi;
|
|
24963
24980
|
var CONTROL3 = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f\u2028-\u202e\u2066-\u2069]/g;
|
|
24964
|
-
function redact(
|
|
24965
|
-
let out2 =
|
|
24981
|
+
function redact(text3) {
|
|
24982
|
+
let out2 = text3.replace(CONTROL3, "");
|
|
24966
24983
|
for (const re of SECRET_PATTERNS) out2 = out2.replace(re, "[redacted]");
|
|
24967
24984
|
out2 = out2.replace(URL_CREDENTIALS, "$1[redacted]@");
|
|
24968
24985
|
return out2.replace(EMAIL, "[email]");
|
|
24969
24986
|
}
|
|
24970
|
-
function oneLine(
|
|
24971
|
-
return redact(
|
|
24987
|
+
function oneLine(text3, max) {
|
|
24988
|
+
return redact(text3.replace(/[\r\n\t]+/g, " ")).trim().slice(0, max);
|
|
24972
24989
|
}
|
|
24973
24990
|
function safePath(p) {
|
|
24974
24991
|
if (!p || p.length > PATH_MAX || p.startsWith("/") || p.includes("\\")) return null;
|
|
@@ -25010,11 +25027,11 @@ function indentWidth(line2) {
|
|
|
25010
25027
|
}
|
|
25011
25028
|
return w;
|
|
25012
25029
|
}
|
|
25013
|
-
function stripCode(
|
|
25030
|
+
function stripCode(text3) {
|
|
25014
25031
|
const out2 = [];
|
|
25015
25032
|
let fence = null;
|
|
25016
25033
|
let underItem = false;
|
|
25017
|
-
for (const line2 of
|
|
25034
|
+
for (const line2 of text3.split("\n")) {
|
|
25018
25035
|
const body2 = line2.replace(QUOTE, "");
|
|
25019
25036
|
if (fence) {
|
|
25020
25037
|
const close = FENCE_CLOSE.exec(body2);
|
|
@@ -25042,27 +25059,27 @@ function stripCode(text2) {
|
|
|
25042
25059
|
return out2.join("\n");
|
|
25043
25060
|
}
|
|
25044
25061
|
function docText(raw) {
|
|
25045
|
-
let
|
|
25046
|
-
const start2 =
|
|
25047
|
-
const end = start2 >= 0 ?
|
|
25062
|
+
let text3 = raw;
|
|
25063
|
+
const start2 = text3.indexOf(MANAGED_START);
|
|
25064
|
+
const end = start2 >= 0 ? text3.indexOf(MANAGED_END, start2) : -1;
|
|
25048
25065
|
if (start2 >= 0 && end > start2) {
|
|
25049
|
-
const block =
|
|
25066
|
+
const block = text3.slice(start2, end);
|
|
25050
25067
|
const ps = block.indexOf(PRESERVE_START2);
|
|
25051
25068
|
const pe = ps >= 0 ? block.indexOf(PRESERVE_END2, ps) : -1;
|
|
25052
25069
|
const kept = ps >= 0 && pe > ps ? block.slice(ps + PRESERVE_START2.length, pe) : "";
|
|
25053
|
-
|
|
25070
|
+
text3 = text3.slice(0, start2) + kept + text3.slice(end + MANAGED_END.length);
|
|
25054
25071
|
}
|
|
25055
|
-
|
|
25056
|
-
return redact(
|
|
25072
|
+
text3 = stripCode(text3.replace(/<!--[\s\S]*?-->/g, "").replace(/<!--[\s\S]*$/, "")).replace(/\n{3,}/g, "\n\n");
|
|
25073
|
+
return redact(text3).trim();
|
|
25057
25074
|
}
|
|
25058
25075
|
var RULE_TITLE = /convention|pattern|rule|gotcha|footgun|pitfall|best practice|guideline|principle|standard|style|architecture|design|security|database|migration|schema|\bapi\b|error|state|naming|structure|i18n|internationali[sz]|translation|important|critical|warning|do not|don't|never|must|avoid/i;
|
|
25059
25076
|
var SETUP_TITLE = /setup|set up|install|getting started|quick ?start|command|script|\bci\b|release|deploy|reference|link|troubleshoot|licen[cs]e|faq|contact|support|changelog|prerequisite|environment|on the web|cloud|skill|documentation/i;
|
|
25060
25077
|
var NORMATIVE = /\b(must|never|always|do not|don't|should|shouldn't|avoid|prefer|required|only|instead of|make sure|ensure)\b/i;
|
|
25061
|
-
function docSections(
|
|
25078
|
+
function docSections(text3) {
|
|
25062
25079
|
const out2 = [];
|
|
25063
25080
|
const open = [];
|
|
25064
25081
|
let current = { order: 0, heading: null, path: "", parents: [], lines: [] };
|
|
25065
|
-
for (const line2 of
|
|
25082
|
+
for (const line2 of text3.split("\n")) {
|
|
25066
25083
|
const m = /^(#{1,6})\s+(.*)$/.exec(line2);
|
|
25067
25084
|
if (!m) {
|
|
25068
25085
|
current.lines.push(line2);
|
|
@@ -25084,9 +25101,9 @@ function sectionRank(s) {
|
|
|
25084
25101
|
const title = rule && !setup ? 2 : setup && !rule ? 0 : 1;
|
|
25085
25102
|
return title * 1e3 + Math.min(999, s.lines.filter((l) => NORMATIVE.test(l)).length);
|
|
25086
25103
|
}
|
|
25087
|
-
function fitDoc(
|
|
25088
|
-
if (utf8(
|
|
25089
|
-
const all = docSections(
|
|
25104
|
+
function fitDoc(text3, budget) {
|
|
25105
|
+
if (utf8(text3) <= budget) return text3;
|
|
25106
|
+
const all = docSections(text3);
|
|
25090
25107
|
const lineBytes = (line2) => utf8(line2) + 1;
|
|
25091
25108
|
const GAP = lineBytes("\u2026");
|
|
25092
25109
|
const chosen = /* @__PURE__ */ new Map();
|
|
@@ -25127,14 +25144,14 @@ function fitDoc(text2, budget) {
|
|
|
25127
25144
|
}
|
|
25128
25145
|
return cutToBytes(out2.join("\n").replace(/\n{3,}/g, "\n\n").trim(), budget);
|
|
25129
25146
|
}
|
|
25130
|
-
function utf8(
|
|
25131
|
-
return Buffer.byteLength(
|
|
25147
|
+
function utf8(text3) {
|
|
25148
|
+
return Buffer.byteLength(text3, "utf8");
|
|
25132
25149
|
}
|
|
25133
|
-
function cutToBytes(
|
|
25134
|
-
if (utf8(
|
|
25150
|
+
function cutToBytes(text3, max) {
|
|
25151
|
+
if (utf8(text3) <= max) return text3;
|
|
25135
25152
|
let out2 = "";
|
|
25136
25153
|
let n2 = 0;
|
|
25137
|
-
for (const ch of
|
|
25154
|
+
for (const ch of text3) {
|
|
25138
25155
|
const b = utf8(ch);
|
|
25139
25156
|
if (n2 + b > max) break;
|
|
25140
25157
|
out2 += ch;
|
|
@@ -25161,11 +25178,11 @@ function readDocs(root, files) {
|
|
|
25161
25178
|
const read2 = readRegularFileInRoot(root, name2, 256 * 1024);
|
|
25162
25179
|
if (!read2.ok) continue;
|
|
25163
25180
|
const fresh = docText(read2.content).split("\n").filter((l) => /^#{1,6}\s/.test(l) || normal(l).length < 25 || !sent.has(normal(l))).join("\n");
|
|
25164
|
-
const
|
|
25165
|
-
if (!
|
|
25166
|
-
for (const l of
|
|
25167
|
-
total += utf8(
|
|
25168
|
-
out2.push({ name: name2, text:
|
|
25181
|
+
const text3 = fitDoc(fresh, room);
|
|
25182
|
+
if (!text3) continue;
|
|
25183
|
+
for (const l of text3.split("\n")) if (normal(l).length >= 25) sent.add(normal(l));
|
|
25184
|
+
total += utf8(text3);
|
|
25185
|
+
out2.push({ name: name2, text: text3 });
|
|
25169
25186
|
}
|
|
25170
25187
|
return out2;
|
|
25171
25188
|
}
|
|
@@ -25633,8 +25650,8 @@ async function writeSetupState(patch) {
|
|
|
25633
25650
|
} catch {
|
|
25634
25651
|
}
|
|
25635
25652
|
}
|
|
25636
|
-
const
|
|
25637
|
-
if (!replaceInRoot(projectPath(VERITY_DIR), "setup.json",
|
|
25653
|
+
const text3 = JSON.stringify(next, null, raw !== null ? detectJsonIndent(raw) : 2) + "\n";
|
|
25654
|
+
if (!replaceInRoot(projectPath(VERITY_DIR), "setup.json", text3)) {
|
|
25638
25655
|
throw new Error(`Could not write ${SETUP_STATE_FILE}: it is a link, or ${VERITY_DIR} is not a folder of this repository`);
|
|
25639
25656
|
}
|
|
25640
25657
|
return next;
|
|
@@ -25786,9 +25803,8 @@ async function pullStandard(globals, opts = {}) {
|
|
|
25786
25803
|
if (local && typeof local === "object" && !Array.isArray(local) && sameStandard(local, remote.standard.content)) {
|
|
25787
25804
|
return { status: "same", version };
|
|
25788
25805
|
}
|
|
25789
|
-
backup = `.verity/standard.${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.yaml`;
|
|
25790
25806
|
try {
|
|
25791
|
-
|
|
25807
|
+
backup = keepStandardCopy(raw);
|
|
25792
25808
|
} catch (err2) {
|
|
25793
25809
|
return { status: "failed", message: `Could not keep a copy of ${STANDARD_FILE} (${terminalText(err2 instanceof Error ? err2.message : String(err2), 200)}), so it was not replaced. Nothing changed.` };
|
|
25794
25810
|
}
|
|
@@ -25823,6 +25839,174 @@ async function runPull(globals) {
|
|
|
25823
25839
|
for (const note of r.notes) printWarn(terminalText(note, 300));
|
|
25824
25840
|
}
|
|
25825
25841
|
|
|
25842
|
+
// src/commands/standard-catalogue.ts
|
|
25843
|
+
var import_yaml7 = __toESM2(require_dist());
|
|
25844
|
+
var PAGE = "verity.md/review-packs";
|
|
25845
|
+
var t = (v, max = 300) => terminalText(typeof v === "string" ? v : String(v ?? ""), max);
|
|
25846
|
+
function extendedPacks(yamlText) {
|
|
25847
|
+
if (!yamlText) return /* @__PURE__ */ new Set();
|
|
25848
|
+
try {
|
|
25849
|
+
const doc = (0, import_yaml7.parse)(yamlText);
|
|
25850
|
+
if (!Array.isArray(doc?.extends)) return /* @__PURE__ */ new Set();
|
|
25851
|
+
return new Set(doc.extends.filter((e) => typeof e === "string").map((e) => e.replace(/^verity\//, "").replace(/@.*$/, "")));
|
|
25852
|
+
} catch {
|
|
25853
|
+
return /* @__PURE__ */ new Set();
|
|
25854
|
+
}
|
|
25855
|
+
}
|
|
25856
|
+
function whenText(pack) {
|
|
25857
|
+
if (pack.always) return "always on";
|
|
25858
|
+
const items = pack.when?.any ?? pack.when?.all;
|
|
25859
|
+
if (!items || items.length === 0) return "add it by hand";
|
|
25860
|
+
const list2 = (label2, v) => `${label2} ${v.slice(0, 4).join(", ")}${v.length > 4 ? `, +${v.length - 4} more` : ""}`;
|
|
25861
|
+
const parts2 = items.map((s) => {
|
|
25862
|
+
if (s.bin) return "the repository ships a CLI";
|
|
25863
|
+
if (s.language) return list2("languages", s.language);
|
|
25864
|
+
if (s.framework) return list2("frameworks", s.framework);
|
|
25865
|
+
if (s.dep) return list2("dependencies", s.dep);
|
|
25866
|
+
if (s.path) return list2("paths", s.path);
|
|
25867
|
+
return "another signal";
|
|
25868
|
+
});
|
|
25869
|
+
return `when ${parts2.join(pack.when?.all ? " and " : " or ")}`;
|
|
25870
|
+
}
|
|
25871
|
+
function renderPackList(c, extended) {
|
|
25872
|
+
const width = Math.max(...c.packs.map((p) => p.ref.length));
|
|
25873
|
+
const lines = [`Review packs (catalogue ${t(c.catalogue_version, 40)}). The full catalogue: ${PAGE}`];
|
|
25874
|
+
for (const p of c.packs) {
|
|
25875
|
+
const mark = extended.has(p.id) ? "\u2713" : " ";
|
|
25876
|
+
const n2 = `${p.rules.length} rule${p.rules.length === 1 ? "" : "s"}`;
|
|
25877
|
+
lines.push(` ${mark} ${t(p.ref, 60).padEnd(width)} ${n2.padStart(8)} ${t(whenText(p), 200)}`);
|
|
25878
|
+
}
|
|
25879
|
+
if (extended.size > 0) lines.push(`\u2713 = in "extends" in ${STANDARD_FILE}`);
|
|
25880
|
+
lines.push("The rules of one pack: verity standard catalogue <pack>");
|
|
25881
|
+
return lines;
|
|
25882
|
+
}
|
|
25883
|
+
function renderPack(p, extended) {
|
|
25884
|
+
const head = `${t(p.ref, 60)}: ${t(p.title, 60)} (${p.rules.length} rule${p.rules.length === 1 ? "" : "s"}, ${t(whenText(p), 200)})${extended.has(p.id) ? ". This project extends it." : ""}`;
|
|
25885
|
+
const lines = [head, ` ${t(p.summary, 400)}`];
|
|
25886
|
+
for (const r of p.rules) {
|
|
25887
|
+
const refs = [...r.maps_to.cwe ?? [], ...r.maps_to.owasp ?? [], ...r.maps_to.owasp_api ?? [], ...r.maps_to.owasp_llm ?? []];
|
|
25888
|
+
lines.push("");
|
|
25889
|
+
lines.push(` ${t(r.id, 80)} ${t(r.severity, 10)} ${t(r.category, 20)} ${t(r.title, 120)}${refs.length ? ` [${t(refs.slice(0, 4).join(", "), 120)}]` : ""}`);
|
|
25890
|
+
lines.push(` ${t(r.rule, 600)}`);
|
|
25891
|
+
if (!r.reviewed_in_diff) lines.push(" Not given to the diff reviewer yet: it is seen in commands or the session, not in the code change.");
|
|
25892
|
+
if (r.also_in.length) lines.push(` Also in: ${t(r.also_in.join(", "), 200)}`);
|
|
25893
|
+
}
|
|
25894
|
+
lines.push("");
|
|
25895
|
+
lines.push(`Turn one rule off in ${STANDARD_FILE}: overrides: { <rule-id>: off }, then verity standard push. Examples: ${PAGE}#${t(p.id, 40)}`);
|
|
25896
|
+
return lines;
|
|
25897
|
+
}
|
|
25898
|
+
var LIMITS2 = { packs: 32, rules: 200, list: 200, id: 120, text: 8e3, item: 200 };
|
|
25899
|
+
var text = (v, max = LIMITS2.text) => typeof v === "string" && v.length <= max;
|
|
25900
|
+
var strings = (v) => Array.isArray(v) && v.length <= LIMITS2.list && v.every((x) => text(x, LIMITS2.item));
|
|
25901
|
+
var optionalStrings = (v) => v === void 0 || strings(v);
|
|
25902
|
+
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
25903
|
+
function isSignal(v) {
|
|
25904
|
+
if (!isObject(v)) return false;
|
|
25905
|
+
const keys = Object.keys(v);
|
|
25906
|
+
if (keys.length !== 1) return false;
|
|
25907
|
+
const [k] = keys;
|
|
25908
|
+
if (k === "bin") return v.bin === true;
|
|
25909
|
+
return ["language", "framework", "dep", "path"].includes(k) && strings(v[k]);
|
|
25910
|
+
}
|
|
25911
|
+
function isWhen(v) {
|
|
25912
|
+
if (v === null) return true;
|
|
25913
|
+
if (!isObject(v)) return false;
|
|
25914
|
+
const keys = Object.keys(v);
|
|
25915
|
+
if (keys.length !== 1 || keys[0] !== "any" && keys[0] !== "all") return false;
|
|
25916
|
+
const items = v[keys[0]];
|
|
25917
|
+
return Array.isArray(items) && items.length <= LIMITS2.list && items.every(isSignal);
|
|
25918
|
+
}
|
|
25919
|
+
function isRule(v) {
|
|
25920
|
+
if (!isObject(v)) return false;
|
|
25921
|
+
const m = v.maps_to;
|
|
25922
|
+
return text(v.id, LIMITS2.id) && text(v.severity, LIMITS2.id) && text(v.category, LIMITS2.id) && text(v.title, LIMITS2.item) && text(v.rule) && text(v.evidence_required) && typeof v.reviewed_in_diff === "boolean" && strings(v.also_in) && isObject(m) && ["cwe", "owasp", "owasp_api", "owasp_llm"].every((k) => optionalStrings(m[k]));
|
|
25923
|
+
}
|
|
25924
|
+
function isPack(v) {
|
|
25925
|
+
if (!isObject(v)) return false;
|
|
25926
|
+
return text(v.id, LIMITS2.id) && text(v.ref, LIMITS2.id) && text(v.title, LIMITS2.item) && text(v.summary) && typeof v.always === "boolean" && isWhen(v.when) && Array.isArray(v.rules) && v.rules.length <= LIMITS2.rules && v.rules.every(isRule);
|
|
25927
|
+
}
|
|
25928
|
+
var copyStrings = (v) => [...v];
|
|
25929
|
+
function copyRule(v) {
|
|
25930
|
+
const m = v.maps_to;
|
|
25931
|
+
const maps = {};
|
|
25932
|
+
for (const k of ["cwe", "owasp", "owasp_api", "owasp_llm"]) if (m[k] !== void 0) maps[k] = copyStrings(m[k]);
|
|
25933
|
+
return {
|
|
25934
|
+
id: v.id,
|
|
25935
|
+
title: v.title,
|
|
25936
|
+
rule: v.rule,
|
|
25937
|
+
evidence_required: v.evidence_required,
|
|
25938
|
+
category: v.category,
|
|
25939
|
+
severity: v.severity,
|
|
25940
|
+
reviewed_in_diff: v.reviewed_in_diff,
|
|
25941
|
+
maps_to: maps,
|
|
25942
|
+
also_in: copyStrings(v.also_in)
|
|
25943
|
+
};
|
|
25944
|
+
}
|
|
25945
|
+
function copyWhen(v) {
|
|
25946
|
+
if (v === null) return null;
|
|
25947
|
+
const w = v;
|
|
25948
|
+
const key = "any" in w ? "any" : "all";
|
|
25949
|
+
const signals = w[key].map((s) => {
|
|
25950
|
+
const [k, val] = Object.entries(s)[0];
|
|
25951
|
+
return k === "bin" ? { bin: true } : { [k]: copyStrings(val) };
|
|
25952
|
+
});
|
|
25953
|
+
return key === "any" ? { any: signals } : { all: signals };
|
|
25954
|
+
}
|
|
25955
|
+
function asCatalogue(v) {
|
|
25956
|
+
if (!isObject(v) || !text(v.catalogue_version, LIMITS2.id) || !Array.isArray(v.packs) || v.packs.length > LIMITS2.packs || !v.packs.every(isPack)) return null;
|
|
25957
|
+
return {
|
|
25958
|
+
catalogue_version: v.catalogue_version,
|
|
25959
|
+
packs: v.packs.map((p) => ({
|
|
25960
|
+
id: p.id,
|
|
25961
|
+
ref: p.ref,
|
|
25962
|
+
title: p.title,
|
|
25963
|
+
summary: p.summary,
|
|
25964
|
+
always: p.always,
|
|
25965
|
+
when: copyWhen(p.when),
|
|
25966
|
+
rules: p.rules.map(copyRule)
|
|
25967
|
+
}))
|
|
25968
|
+
};
|
|
25969
|
+
}
|
|
25970
|
+
async function runCatalogue(globals, pack, opts) {
|
|
25971
|
+
const url = await resolveServiceUrl(globals.serviceUrl);
|
|
25972
|
+
if (!url.ok) {
|
|
25973
|
+
printError(t(url.error));
|
|
25974
|
+
process.exit(1);
|
|
25975
|
+
}
|
|
25976
|
+
const res = await apiRequest({
|
|
25977
|
+
method: "GET",
|
|
25978
|
+
path: "/standards/catalogue/packs",
|
|
25979
|
+
serviceUrl: url.data,
|
|
25980
|
+
verbose: globals.verbose,
|
|
25981
|
+
cmd: "standard catalogue",
|
|
25982
|
+
withoutRemote: true,
|
|
25983
|
+
timeout: 15e3
|
|
25984
|
+
});
|
|
25985
|
+
if (!res.ok) {
|
|
25986
|
+
printError(`Could not read the review-pack catalogue from the Verity service: ${t(res.error)}. See ${PAGE}`);
|
|
25987
|
+
process.exit(1);
|
|
25988
|
+
}
|
|
25989
|
+
const catalogue = asCatalogue(res.data);
|
|
25990
|
+
if (!catalogue) {
|
|
25991
|
+
printError(`The Verity service answered with something that is not a review-pack catalogue. See ${PAGE}`);
|
|
25992
|
+
process.exit(1);
|
|
25993
|
+
}
|
|
25994
|
+
const extended = extendedPacks(readRepoFile(STANDARD_FILE));
|
|
25995
|
+
if (pack === void 0) {
|
|
25996
|
+
if (opts.json) printJson(catalogue);
|
|
25997
|
+
else for (const line2 of renderPackList(catalogue, extended)) printInfo(line2);
|
|
25998
|
+
return;
|
|
25999
|
+
}
|
|
26000
|
+
const id = pack.replace(/^verity\//, "").replace(/@.*$/, "");
|
|
26001
|
+
const found = catalogue.packs.find((p) => p.id === id);
|
|
26002
|
+
if (!found) {
|
|
26003
|
+
printError(`No review pack named "${t(pack, 60)}". The packs: ${t(catalogue.packs.map((p) => p.id).join(", "), 300)}.`);
|
|
26004
|
+
process.exit(1);
|
|
26005
|
+
}
|
|
26006
|
+
if (opts.json) printJson(found);
|
|
26007
|
+
else for (const line2 of renderPack(found, extended)) printInfo(line2);
|
|
26008
|
+
}
|
|
26009
|
+
|
|
25826
26010
|
// src/commands/standard.ts
|
|
25827
26011
|
function registerStandardCommands(program2) {
|
|
25828
26012
|
const standard = program2.command("standard").description("Manage the project Standard");
|
|
@@ -25860,6 +26044,7 @@ function registerStandardCommands(program2) {
|
|
|
25860
26044
|
});
|
|
25861
26045
|
standard.command("generate").description("Have Verity write project-specific rules from a profile of this repository (asks before sending it)").option("--yes", `Send the profile without asking (you have read ${PROFILE_FILE})`).option("--status", "Print whether the service writes project rules for this project: on, off, unsupported or unknown. Sends nothing.").action((opts) => runGenerate(program2.opts(), opts));
|
|
25862
26046
|
standard.command("pull").description("Write the team's Standard on the service into .verity/standard.yaml (keeps a copy of yours)").action(() => runPull(program2.opts()));
|
|
26047
|
+
standard.command("catalogue [pack]").description("What each review pack holds: every pack, or the rules of one (core, api, data, \u2026)").option("--json", "Print the catalogue as JSON").action((pack, opts) => runCatalogue(program2.opts(), pack, opts));
|
|
25863
26048
|
standard.command("push").description("Upload the project Standard to the service").option("--file <path>", "Path to standard YAML file", STANDARD_FILE).option("--created-by <name>", "Who created this version", "claude-code").action(async (opts) => {
|
|
25864
26049
|
const globals = program2.opts();
|
|
25865
26050
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -25997,7 +26182,7 @@ function standardUploadBody(yamlText, file, ignoreRaw, createdBy) {
|
|
|
25997
26182
|
if (!author.ok) return { ok: false, error: `--created-by: ${author.error}. Nothing was sent.` };
|
|
25998
26183
|
let parsed;
|
|
25999
26184
|
try {
|
|
26000
|
-
parsed = (0,
|
|
26185
|
+
parsed = (0, import_yaml8.parse)(yamlText);
|
|
26001
26186
|
} catch (err2) {
|
|
26002
26187
|
return { ok: false, error: `Invalid YAML in ${shown}: ${terminalText(err2.message, 300)}` };
|
|
26003
26188
|
}
|
|
@@ -27087,15 +27272,15 @@ function renderSeatUsage(d, now = /* @__PURE__ */ new Date()) {
|
|
|
27087
27272
|
lines.push(` ${pad("Turn reviews", 24)}session ${pad(used(me.session.turn, ml?.turn.session), 12)}week ${pad(used(w.turn, memberWeek("turn")), 14)}busiest session ${n(w.peak_session.turn)}`);
|
|
27088
27273
|
lines.push(` This week: ${n(w.blocked)} blocked, ${n(w.warned)} warned \xB7 review time p50 ${secs(w.latency_ms.p50)}, p90 ${secs(w.latency_ms.p90)}`);
|
|
27089
27274
|
}
|
|
27090
|
-
const
|
|
27275
|
+
const t2 = d.totals.weeks[0];
|
|
27091
27276
|
lines.push("");
|
|
27092
27277
|
lines.push(`Team \xB7 ${n(d.totals.active_members)} active this week`);
|
|
27093
|
-
const poolUsed = pool?.used ?? (pool ? { commit:
|
|
27278
|
+
const poolUsed = pool?.used ?? (pool ? { commit: t2.commit, turn: t2.turn } : null);
|
|
27094
27279
|
if (pool && poolUsed && d.plan) {
|
|
27095
27280
|
lines.push(
|
|
27096
27281
|
` Week pool: ${n(poolUsed.commit)} / ${n(pool.commit)} commit & push, ${n(poolUsed.turn)} / ${n(pool.turn)} turn (${poolText(d.plan, pool.members)}; the session limit is each member's)`
|
|
27097
27282
|
);
|
|
27098
|
-
if (pool.used) lines.push(` Everyone in ${d.organization.name} this week, members or not: ${n(
|
|
27283
|
+
if (pool.used) lines.push(` Everyone in ${d.organization.name} this week, members or not: ${n(t2.commit)} commit & push, ${n(t2.turn)} turn.`);
|
|
27099
27284
|
}
|
|
27100
27285
|
if (d.viewer !== "member" && d.members.length > 0) {
|
|
27101
27286
|
const rows = d.members.map((m) => [
|
|
@@ -27113,19 +27298,19 @@ function renderSeatUsage(d, now = /* @__PURE__ */ new Date()) {
|
|
|
27113
27298
|
const total = [
|
|
27114
27299
|
"Team total",
|
|
27115
27300
|
n(d.totals.session.commit),
|
|
27116
|
-
used(
|
|
27117
|
-
n(
|
|
27301
|
+
used(t2.commit, totalLimit("commit")),
|
|
27302
|
+
n(t2.peak_session.commit),
|
|
27118
27303
|
n(d.totals.session.turn),
|
|
27119
|
-
used(
|
|
27120
|
-
n(
|
|
27121
|
-
`${secs(
|
|
27304
|
+
used(t2.turn, totalLimit("turn")),
|
|
27305
|
+
n(t2.blocked),
|
|
27306
|
+
`${secs(t2.latency_ms.p50)} / ${secs(t2.latency_ms.p90)}`
|
|
27122
27307
|
];
|
|
27123
27308
|
const widths = head.map((h, i2) => Math.max(h.length, ...rows.map((r) => r[i2].length), total[i2].length) + 2);
|
|
27124
27309
|
lines.push(" " + head.map((h, i2) => pad(h, widths[i2])).join("").trimEnd());
|
|
27125
27310
|
for (const r of rows) lines.push(" " + r.map((c, i2) => pad(c, widths[i2])).join("").trimEnd());
|
|
27126
27311
|
lines.push(" " + total.map((c, i2) => pad(c, widths[i2])).join("").trimEnd());
|
|
27127
27312
|
} else {
|
|
27128
|
-
lines.push(` This week: ${n(
|
|
27313
|
+
lines.push(` This week: ${n(t2.commit)} commit & push reviews, ${n(t2.turn)} turn reviews, ${n(t2.blocked)} blocked.`);
|
|
27129
27314
|
if (d.viewer === "member") lines.push(` Only the admins of ${d.organization.name} see every member.`);
|
|
27130
27315
|
}
|
|
27131
27316
|
if (d.truncated) lines.push(" (Partial: the org has more reviews than one report reads.)");
|
|
@@ -27250,16 +27435,16 @@ function readTextInput(value, flag, readStdin2 = () => (0, import_node_fs42.read
|
|
|
27250
27435
|
if (raw.length > MAX_STDIN_BYTES) {
|
|
27251
27436
|
return { ok: false, error: `${flag} from stdin is ${raw.length} bytes; the limit is ${MAX_STDIN_BYTES}.` };
|
|
27252
27437
|
}
|
|
27253
|
-
const
|
|
27254
|
-
if (!
|
|
27255
|
-
return { ok: true, text:
|
|
27438
|
+
const text3 = raw.toString("utf8").replace(/\r?\n$/, "");
|
|
27439
|
+
if (!text3.trim()) return { ok: false, error: `${flag} from stdin is empty.` };
|
|
27440
|
+
return { ok: true, text: text3 };
|
|
27256
27441
|
}
|
|
27257
27442
|
|
|
27258
27443
|
// src/commands/feedback.ts
|
|
27259
27444
|
function registerFeedbackCommand(program2) {
|
|
27260
27445
|
const feedbackCmd = program2.command("feedback").description("Send feedback to the Verity team");
|
|
27261
|
-
feedbackCmd.command("message <text>").description("Send general feedback (- reads the message from stdin, so the words never pass through shell quoting)").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (
|
|
27262
|
-
await sendMessageArg(
|
|
27446
|
+
feedbackCmd.command("message <text>").description("Send general feedback (- reads the message from stdin, so the words never pass through shell quoting)").option("--session-id <id>", "Session identifier").option("--model <name>", "Agent model name").action(async (text3, opts) => {
|
|
27447
|
+
await sendMessageArg(text3, opts, program2.opts());
|
|
27263
27448
|
});
|
|
27264
27449
|
feedbackCmd.command("finding <run-id> <pattern-id> <action> [note]").description("Submit per-finding feedback (false_positive, acknowledged, useful, etc.); a note of - is read from stdin").option("--file <path>", "File path the finding applies to").option("--line <n>", "Line number", parseInt).action(async (runId, patternId, action, inlineNote, opts) => {
|
|
27265
27450
|
const globals = program2.opts();
|
|
@@ -27865,28 +28050,28 @@ function parseRgLine(line2) {
|
|
|
27865
28050
|
return { file: line2.slice(0, first), line: n2, text: line2.slice(second + 1) };
|
|
27866
28051
|
}
|
|
27867
28052
|
var isWordChar = (c) => c !== void 0 && /[A-Za-z0-9_]/.test(c);
|
|
27868
|
-
function wordHit(
|
|
28053
|
+
function wordHit(text3, symbol) {
|
|
27869
28054
|
let from = 0;
|
|
27870
28055
|
for (; ; ) {
|
|
27871
|
-
const at =
|
|
28056
|
+
const at = text3.indexOf(symbol, from);
|
|
27872
28057
|
if (at < 0) return false;
|
|
27873
|
-
const before = at === 0 ? void 0 :
|
|
27874
|
-
const after =
|
|
28058
|
+
const before = at === 0 ? void 0 : text3[at - 1];
|
|
28059
|
+
const after = text3[at + symbol.length];
|
|
27875
28060
|
if (!isWordChar(before) && !isWordChar(after)) return true;
|
|
27876
28061
|
from = at + 1;
|
|
27877
28062
|
}
|
|
27878
28063
|
}
|
|
27879
|
-
function isContractLine(
|
|
28064
|
+
function isContractLine(text3, symbol) {
|
|
27880
28065
|
for (const kw of ["implements", "extends"]) {
|
|
27881
28066
|
let from = 0;
|
|
27882
28067
|
for (; ; ) {
|
|
27883
|
-
const at =
|
|
28068
|
+
const at = text3.indexOf(kw, from);
|
|
27884
28069
|
if (at < 0) break;
|
|
27885
28070
|
from = at + 1;
|
|
27886
|
-
const before = at === 0 ? void 0 :
|
|
27887
|
-
const after =
|
|
28071
|
+
const before = at === 0 ? void 0 : text3[at - 1];
|
|
28072
|
+
const after = text3[at + kw.length];
|
|
27888
28073
|
if (isWordChar(before) || isWordChar(after)) continue;
|
|
27889
|
-
let clause =
|
|
28074
|
+
let clause = text3.slice(at + kw.length);
|
|
27890
28075
|
const stop2 = Math.min(
|
|
27891
28076
|
...[clause.indexOf(";"), clause.indexOf("{")].filter((i2) => i2 >= 0)
|
|
27892
28077
|
);
|
|
@@ -27918,20 +28103,20 @@ function partitionSites(rgLines, symbols, opts) {
|
|
|
27918
28103
|
if (opts.sentPaths.has(h.file)) continue;
|
|
27919
28104
|
if (opts.isExcluded(h.file)) continue;
|
|
27920
28105
|
if (!isCodeSiteFile(h.file)) continue;
|
|
27921
|
-
const
|
|
27922
|
-
if (
|
|
27923
|
-
if (COMMENT_LINE.test(
|
|
27924
|
-
if (BARE_MEMBER_LINE.test(
|
|
28106
|
+
const text3 = h.text.trim();
|
|
28107
|
+
if (text3.length === 0 || IMPORT_LINE.test(h.text)) continue;
|
|
28108
|
+
if (COMMENT_LINE.test(text3)) continue;
|
|
28109
|
+
if (BARE_MEMBER_LINE.test(text3) || GO_IMPORT_PATH_LINE.test(text3)) continue;
|
|
27925
28110
|
const n2 = perFile.get(h.file) ?? 0;
|
|
27926
28111
|
if (n2 >= MAX_SITES_PER_FILE) continue;
|
|
27927
28112
|
const site = {
|
|
27928
28113
|
file: h.file,
|
|
27929
28114
|
line: h.line,
|
|
27930
|
-
text:
|
|
28115
|
+
text: text3.slice(0, SITE_TEXT_MAX),
|
|
27931
28116
|
symbol: h.symbol,
|
|
27932
28117
|
// R2 falls out of R1 for free: a word search for `Sym` already matches
|
|
27933
28118
|
// `implements Sym` / `extends Sym` lines — classification is all R2 is.
|
|
27934
|
-
...isContractLine(
|
|
28119
|
+
...isContractLine(text3, h.symbol) ? { kind: "contract" } : {}
|
|
27935
28120
|
};
|
|
27936
28121
|
if (isTestPath(h.file)) {
|
|
27937
28122
|
if (tests.length < MAX_TEST_SLOTS) {
|
|
@@ -27951,8 +28136,8 @@ var MAX_IMPORTERS_PER_FILE = 2;
|
|
|
27951
28136
|
function moduleKey(path) {
|
|
27952
28137
|
return path.replace(/\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/i, "").replace(/\/index$/, "");
|
|
27953
28138
|
}
|
|
27954
|
-
function importSpecifier(
|
|
27955
|
-
const m = /(?:\bfrom|\brequire\s*\(|\bimport\s*\(|^\s*import)\s*['"]([^'"\n]+)['"]/.exec(
|
|
28139
|
+
function importSpecifier(text3) {
|
|
28140
|
+
const m = /(?:\bfrom|\brequire\s*\(|\bimport\s*\(|^\s*import)\s*['"]([^'"\n]+)['"]/.exec(text3);
|
|
27956
28141
|
return m?.[1] ?? null;
|
|
27957
28142
|
}
|
|
27958
28143
|
function resolveSpecifier(fromFile, spec) {
|
|
@@ -28222,8 +28407,8 @@ function extractEnclosingExcerpt(content, siteLine, path) {
|
|
|
28222
28407
|
start2 = Math.max(1, siteLine - (EXCERPT_MAX_LINES - 6));
|
|
28223
28408
|
}
|
|
28224
28409
|
const end = Math.min(lines.length, start2 + EXCERPT_MAX_LINES - 1);
|
|
28225
|
-
const
|
|
28226
|
-
return { start_line: start2, text:
|
|
28410
|
+
const text3 = lines.slice(start2 - 1, end).join("\n").slice(0, EXCERPT_MAX_CHARS);
|
|
28411
|
+
return { start_line: start2, text: text3 };
|
|
28227
28412
|
}
|
|
28228
28413
|
function upgradeToExcerpts(rc, opts) {
|
|
28229
28414
|
if (rc.state !== "ok") return;
|
|
@@ -28357,10 +28542,10 @@ function formatRunEvidence(run4, startedAt) {
|
|
|
28357
28542
|
}
|
|
28358
28543
|
}
|
|
28359
28544
|
if (run4.foldResult?.tools?.length) {
|
|
28360
|
-
const shown = run4.foldResult.tools.slice(0, 6).map((
|
|
28361
|
-
const outcome =
|
|
28362
|
-
const where2 =
|
|
28363
|
-
return `${
|
|
28545
|
+
const shown = run4.foldResult.tools.slice(0, 6).map((t2) => {
|
|
28546
|
+
const outcome = t2.failed > 0 ? `${t2.failed} failed` : t2.last_status === 0 ? "ok" : "?";
|
|
28547
|
+
const where2 = t2.targets.length > 0 ? ` \u2192 ${t2.targets.slice(0, 2).join(", ")}` : "";
|
|
28548
|
+
return `${t2.runs}\xD7 ${t2.name} (${outcome})${where2}`;
|
|
28364
28549
|
});
|
|
28365
28550
|
const more = run4.foldResult.tools.length > 6 ? ` \u2026 +${run4.foldResult.tools.length - 6} more` : "";
|
|
28366
28551
|
out2 += row("tools", shown.join(" \xB7 ") + more);
|
|
@@ -28369,9 +28554,9 @@ function formatRunEvidence(run4, startedAt) {
|
|
|
28369
28554
|
}
|
|
28370
28555
|
}
|
|
28371
28556
|
if (run4.foldResult?.tasks?.length) {
|
|
28372
|
-
const
|
|
28373
|
-
const done2 =
|
|
28374
|
-
out2 += row("tasks", `${
|
|
28557
|
+
const t2 = run4.foldResult.tasks;
|
|
28558
|
+
const done2 = t2.filter((x) => x.status === "completed").length;
|
|
28559
|
+
out2 += row("tasks", `${t2.length} \xB7 ${done2} completed \xB7 ` + list(t2.slice(0, 4).map((x) => `#${x.id} ${x.name} [${x.status}]`), 4));
|
|
28375
28560
|
}
|
|
28376
28561
|
if (run4.specs?.length) {
|
|
28377
28562
|
const readThisSession = new Set(run4.actionSummary?.files_read ?? []);
|
|
@@ -28525,31 +28710,31 @@ function parsePushTarget(segment) {
|
|
|
28525
28710
|
let refspec = null;
|
|
28526
28711
|
let isDelete = false;
|
|
28527
28712
|
for (let i2 = 0; i2 < tokens.length; i2++) {
|
|
28528
|
-
const
|
|
28529
|
-
if (
|
|
28713
|
+
const t2 = tokens[i2];
|
|
28714
|
+
if (t2 === "-d" || t2 === "--delete") {
|
|
28530
28715
|
isDelete = true;
|
|
28531
28716
|
continue;
|
|
28532
28717
|
}
|
|
28533
|
-
if (
|
|
28534
|
-
remote =
|
|
28718
|
+
if (t2.startsWith("--repo=")) {
|
|
28719
|
+
remote = t2.slice("--repo=".length);
|
|
28535
28720
|
continue;
|
|
28536
28721
|
}
|
|
28537
|
-
if (
|
|
28722
|
+
if (t2 === "--repo") {
|
|
28538
28723
|
remote = tokens[++i2] ?? null;
|
|
28539
28724
|
continue;
|
|
28540
28725
|
}
|
|
28541
|
-
if (PUSH_VALUE_FLAGS.has(
|
|
28726
|
+
if (PUSH_VALUE_FLAGS.has(t2)) {
|
|
28542
28727
|
i2++;
|
|
28543
28728
|
continue;
|
|
28544
28729
|
}
|
|
28545
|
-
if (
|
|
28546
|
-
if (SHELL_DYNAMIC.test(
|
|
28730
|
+
if (t2.startsWith("-")) continue;
|
|
28731
|
+
if (SHELL_DYNAMIC.test(t2)) return none;
|
|
28547
28732
|
if (remote === null) {
|
|
28548
|
-
remote =
|
|
28733
|
+
remote = t2;
|
|
28549
28734
|
continue;
|
|
28550
28735
|
}
|
|
28551
28736
|
if (refspec === null) {
|
|
28552
|
-
refspec =
|
|
28737
|
+
refspec = t2;
|
|
28553
28738
|
continue;
|
|
28554
28739
|
}
|
|
28555
28740
|
break;
|
|
@@ -28875,21 +29060,21 @@ function rangeMessages(frame, range) {
|
|
|
28875
29060
|
return frameGit(frame, ["show", "-s", "--format=%B%x00", ...commits]).split("\0").map((s) => s.trim()).filter(Boolean).join("\n\n");
|
|
28876
29061
|
}
|
|
28877
29062
|
function frameTelemetry(frame, range, divergence) {
|
|
28878
|
-
const
|
|
29063
|
+
const t2 = {
|
|
28879
29064
|
anchor: frame.anchor,
|
|
28880
29065
|
linked_worktree: frame.isLinkedWorktree,
|
|
28881
29066
|
range_via: range?.via ?? null,
|
|
28882
29067
|
refusal: frame.refusal
|
|
28883
29068
|
};
|
|
28884
29069
|
if (divergence) {
|
|
28885
|
-
|
|
29070
|
+
t2.root_differs = !!frame.worktreeRoot && !!divergence.actualRoot && realpathOr2(frame.worktreeRoot) !== realpathOr2(divergence.actualRoot);
|
|
28886
29071
|
const a = [...divergence.actualFiles].sort().join("\n");
|
|
28887
29072
|
const b = [...divergence.frameFiles].sort().join("\n");
|
|
28888
|
-
|
|
28889
|
-
|
|
28890
|
-
|
|
29073
|
+
t2.files_differ = a !== b;
|
|
29074
|
+
t2.frame_file_count = divergence.frameFiles.length;
|
|
29075
|
+
t2.actual_file_count = divergence.actualFiles.length;
|
|
28891
29076
|
}
|
|
28892
|
-
return
|
|
29077
|
+
return t2;
|
|
28893
29078
|
}
|
|
28894
29079
|
|
|
28895
29080
|
// src/lib/transcript-path.ts
|
|
@@ -29388,12 +29573,12 @@ function parseKnowledgeNote(raw) {
|
|
|
29388
29573
|
if (!raw || typeof raw !== "object") return null;
|
|
29389
29574
|
const o = raw;
|
|
29390
29575
|
const node_id = typeof o.node_id === "string" ? o.node_id.trim() : "";
|
|
29391
|
-
const
|
|
29392
|
-
if (!node_id || !
|
|
29393
|
-
if (
|
|
29576
|
+
const text3 = typeof o.text === "string" ? o.text.trim() : "";
|
|
29577
|
+
if (!node_id || !text3) return null;
|
|
29578
|
+
if (text3.length > 1e3) return null;
|
|
29394
29579
|
return {
|
|
29395
29580
|
node_id,
|
|
29396
|
-
text:
|
|
29581
|
+
text: text3,
|
|
29397
29582
|
file: typeof o.file === "string" && o.file ? o.file : null,
|
|
29398
29583
|
line: typeof o.line === "number" && Number.isFinite(o.line) && o.line > 0 ? Math.floor(o.line) : null
|
|
29399
29584
|
};
|
|
@@ -29441,10 +29626,10 @@ function judgedSeverity(f) {
|
|
|
29441
29626
|
var MAX_AGENT_CONTEXT_CHARS = 1500;
|
|
29442
29627
|
var MAX_AGENT_ITEMS = 5;
|
|
29443
29628
|
var REPORT_PREFIX = "Verity review (a report on the code just written \u2014 relay what matters to the user; it is not an instruction to you):";
|
|
29444
|
-
function renderItem(label2,
|
|
29629
|
+
function renderItem(label2, text3, patternId, file, line2) {
|
|
29445
29630
|
const where2 = file ? ` (${file}${line2 !== void 0 && line2 !== "" ? `:${line2}` : ""})` : "";
|
|
29446
29631
|
const id = patternId ? ` [${patternId}]` : "";
|
|
29447
|
-
return `- ${label2}${
|
|
29632
|
+
return `- ${label2}${text3}${where2}${id}`;
|
|
29448
29633
|
}
|
|
29449
29634
|
function channelInputFrom(response, intentRepeat = 0, priorPendingFingerprints = []) {
|
|
29450
29635
|
const metadata2 = response.metadata ?? {};
|
|
@@ -29535,24 +29720,24 @@ function composeAgentContext(input) {
|
|
|
29535
29720
|
for (const p of input.pendingItems ?? []) {
|
|
29536
29721
|
if (lines.length >= MAX_AGENT_ITEMS) break;
|
|
29537
29722
|
if (p.pattern_id === "intent-misalignment") continue;
|
|
29538
|
-
const
|
|
29539
|
-
if (!
|
|
29540
|
-
const seenBefore = isRepeatOfAny(
|
|
29723
|
+
const text4 = p.description ?? p.title ?? p.reason;
|
|
29724
|
+
if (!text4) continue;
|
|
29725
|
+
const seenBefore = isRepeatOfAny(text4, input.priorPendingFingerprints ?? []);
|
|
29541
29726
|
lines.push(
|
|
29542
|
-
renderItem("",
|
|
29727
|
+
renderItem("", text4, p.pattern_id, p.file, p.line) + (seenBefore ? "\n (raised earlier this session and still open \u2014 do not re-explain it; act on it or carry on)" : "")
|
|
29543
29728
|
);
|
|
29544
29729
|
}
|
|
29545
29730
|
if (lines.length === 0) return { text: null, shown: [] };
|
|
29546
29731
|
const body2 = `${REPORT_PREFIX}
|
|
29547
29732
|
${lines.slice(0, MAX_AGENT_ITEMS).join("\n")}`;
|
|
29548
|
-
const
|
|
29549
|
-
return { text:
|
|
29733
|
+
const text3 = truncateToCap(body2);
|
|
29734
|
+
return { text: text3, shown: shown.filter((s) => text3.split("\n").includes(s.line)).map((s) => s.finding) };
|
|
29550
29735
|
}
|
|
29551
|
-
function truncateToCap(
|
|
29552
|
-
if (
|
|
29736
|
+
function truncateToCap(text3) {
|
|
29737
|
+
if (text3.length <= MAX_AGENT_CONTEXT_CHARS) return text3;
|
|
29553
29738
|
const marker = "\n- (truncated)";
|
|
29554
29739
|
const budget = MAX_AGENT_CONTEXT_CHARS - marker.length;
|
|
29555
|
-
const lines =
|
|
29740
|
+
const lines = text3.slice(0, budget).split("\n");
|
|
29556
29741
|
lines.pop();
|
|
29557
29742
|
return `${lines.join("\n")}${marker}`;
|
|
29558
29743
|
}
|
|
@@ -30728,9 +30913,9 @@ function fold(transcriptPath, opts = {}) {
|
|
|
30728
30913
|
runs: s.runs,
|
|
30729
30914
|
failed: s.failed,
|
|
30730
30915
|
last_status: s.last_status,
|
|
30731
|
-
targets: [...s.targets].map((
|
|
30916
|
+
targets: [...s.targets].map((t2) => toRepoRelative(t2, opts.repoRoot)).sort()
|
|
30732
30917
|
})).sort((a, b) => b.runs - a.runs || a.name.localeCompare(b.name));
|
|
30733
|
-
result.tasks = [...taskById.entries()].map(([id,
|
|
30918
|
+
result.tasks = [...taskById.entries()].map(([id, t2]) => ({ id, name: t2.name, status: t2.status })).sort((a, b) => (Number(a.id) || 0) - (Number(b.id) || 0));
|
|
30734
30919
|
const authoredPaths = new Set(result.authored.map((a) => a.p));
|
|
30735
30920
|
for (const raw of opts.changedFiles ?? []) {
|
|
30736
30921
|
const p = toRepoRelative(raw, opts.repoRoot);
|
|
@@ -31416,8 +31601,8 @@ var cap = (s, n2) => {
|
|
|
31416
31601
|
function qualifierOf(node, spec) {
|
|
31417
31602
|
if (spec.id === "go" && node.type === "method_declaration") {
|
|
31418
31603
|
const receiver = node.childForFieldName("receiver");
|
|
31419
|
-
const
|
|
31420
|
-
return
|
|
31604
|
+
const t2 = receiver?.descendantsOfType("type_identifier")[0];
|
|
31605
|
+
return t2 ? t2.text : null;
|
|
31421
31606
|
}
|
|
31422
31607
|
for (let p = node.parent; p; p = p.parent) {
|
|
31423
31608
|
if (spec.classes.has(p.type)) return p.childForFieldName("name")?.text ?? null;
|
|
@@ -31572,10 +31757,10 @@ function factsOf(def, spec, defs, path) {
|
|
|
31572
31757
|
const walk2 = (n2, ctx) => {
|
|
31573
31758
|
const anonymousMember = n2.parent?.type === "class_body" && n2.parent.parent?.type === "object_creation_expression";
|
|
31574
31759
|
if (n2.id !== def.fn.id && !anonymousMember && (defs.has(n2.id) || spec.classes.has(n2.type) || spec.definitions[n2.type])) return;
|
|
31575
|
-
const
|
|
31760
|
+
const t2 = n2.type;
|
|
31576
31761
|
bind(n2);
|
|
31577
31762
|
const down = (c, next = ctx) => walk2(c, next);
|
|
31578
|
-
if (spec.calls.has(
|
|
31763
|
+
if (spec.calls.has(t2)) {
|
|
31579
31764
|
const { receiver, name: name2, args: args2 } = callParts(n2, spec);
|
|
31580
31765
|
if (name2) {
|
|
31581
31766
|
calls.push({
|
|
@@ -31596,29 +31781,29 @@ function factsOf(def, spec, defs, path) {
|
|
|
31596
31781
|
return;
|
|
31597
31782
|
}
|
|
31598
31783
|
}
|
|
31599
|
-
if (spec.awaits.has(
|
|
31600
|
-
if (
|
|
31784
|
+
if (spec.awaits.has(t2)) awaits.push(line(n2));
|
|
31785
|
+
if (t2 === "defer_statement") {
|
|
31601
31786
|
for (const c of n2.namedChildren) down(c, { ...ctx, within: [...ctx.within, "defer"] });
|
|
31602
31787
|
return;
|
|
31603
31788
|
}
|
|
31604
|
-
if (spec.lockNodes.has(
|
|
31789
|
+
if (spec.lockNodes.has(t2)) {
|
|
31605
31790
|
locks.push(line(n2));
|
|
31606
31791
|
for (const c of n2.namedChildren) down(c, { ...ctx, within: [...ctx.within, "synchronized"] });
|
|
31607
31792
|
return;
|
|
31608
31793
|
}
|
|
31609
|
-
if (
|
|
31794
|
+
if (t2 === "with_statement") {
|
|
31610
31795
|
const item = n2.namedChildren[0];
|
|
31611
31796
|
if (PY_LOCK_ITEM.test(item?.text ?? "")) locks.push(line(n2));
|
|
31612
31797
|
const label2 = withLabel(item);
|
|
31613
31798
|
for (const c of n2.namedChildren) down(c, c.type === "block" && label2 ? { ...ctx, within: [...ctx.within, label2] } : ctx);
|
|
31614
31799
|
return;
|
|
31615
31800
|
}
|
|
31616
|
-
if (spec.loops.has(
|
|
31801
|
+
if (spec.loops.has(t2)) {
|
|
31617
31802
|
loops.push(line(n2));
|
|
31618
31803
|
for (const c of n2.namedChildren) down(c, { ...ctx, inLoop: true });
|
|
31619
31804
|
return;
|
|
31620
31805
|
}
|
|
31621
|
-
if (spec.tries.has(
|
|
31806
|
+
if (spec.tries.has(t2)) {
|
|
31622
31807
|
const handlers = n2.namedChildren.filter((c) => spec.handlers.has(c.type));
|
|
31623
31808
|
tries.push({ line: line(n2), end: n2.endPosition.row + 1, catches: handlers.length > 0, rethrows: handlers.some(throwsIn) });
|
|
31624
31809
|
const body2 = n2.childForFieldName("body");
|
|
@@ -31737,9 +31922,9 @@ function literalName(literal) {
|
|
|
31737
31922
|
return prefix.length >= 2 ? { name: prefix, confidence: "prefix" } : null;
|
|
31738
31923
|
}
|
|
31739
31924
|
var SIMPLE_EXPRESSION = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*(?:\(\))?$/;
|
|
31740
|
-
var STABLE_EXPRESSION = (
|
|
31741
|
-
if (
|
|
31742
|
-
const root =
|
|
31925
|
+
var STABLE_EXPRESSION = (t2) => {
|
|
31926
|
+
if (t2.endsWith("()")) return true;
|
|
31927
|
+
const root = t2.split(".")[0];
|
|
31743
31928
|
return root === "this" || root === "self" || /^[A-Z]/.test(root);
|
|
31744
31929
|
};
|
|
31745
31930
|
function argResource(kind2, arg) {
|
|
@@ -31752,13 +31937,13 @@ function argResource(kind2, arg) {
|
|
|
31752
31937
|
const keyed = keyedCall(arg.text);
|
|
31753
31938
|
return keyed ? { kind: kind2, name: keyed, confidence: "expression" } : { kind: kind2, name: null, confidence: "unknown" };
|
|
31754
31939
|
}
|
|
31755
|
-
function keyedCall(
|
|
31756
|
-
const
|
|
31757
|
-
const open =
|
|
31758
|
-
if (open <= 0 || !
|
|
31759
|
-
const callee =
|
|
31940
|
+
function keyedCall(text3) {
|
|
31941
|
+
const t2 = text3.trim();
|
|
31942
|
+
const open = t2.indexOf("(");
|
|
31943
|
+
if (open <= 0 || !t2.endsWith(")")) return null;
|
|
31944
|
+
const callee = t2.slice(0, open);
|
|
31760
31945
|
if (!/^[A-Za-z_$][\w$.]*$/.test(callee)) return null;
|
|
31761
|
-
const constant = /\b[A-Z][A-Z0-9_]{2,}\b/.exec(
|
|
31946
|
+
const constant = /\b[A-Z][A-Z0-9_]{2,}\b/.exec(t2.slice(open + 1, -1));
|
|
31762
31947
|
return constant ? `${callee}(${constant[0]})` : null;
|
|
31763
31948
|
}
|
|
31764
31949
|
function snake(s) {
|
|
@@ -31787,16 +31972,16 @@ var SQL_TABLE = [
|
|
|
31787
31972
|
[/\bfrom\s+[`"[]?([\w.]+)/i, "read"]
|
|
31788
31973
|
];
|
|
31789
31974
|
function sqlLiteral(c) {
|
|
31790
|
-
const
|
|
31791
|
-
if (!
|
|
31975
|
+
const text3 = c.args.find((a) => a.literal !== null && SQL.test(a.literal))?.literal;
|
|
31976
|
+
if (!text3) return null;
|
|
31792
31977
|
for (const [re, op] of SQL_TABLE) {
|
|
31793
|
-
const m = re.exec(
|
|
31978
|
+
const m = re.exec(text3);
|
|
31794
31979
|
if (m) {
|
|
31795
31980
|
const name2 = m[1].split(".").pop();
|
|
31796
|
-
return { op, resource: table(name2), rule: "sql.literal", lock: op === "read" && /\bfor\s+(?:no\s+key\s+)?update\b/i.test(
|
|
31981
|
+
return { op, resource: table(name2), rule: "sql.literal", lock: op === "read" && /\bfor\s+(?:no\s+key\s+)?update\b/i.test(text3) };
|
|
31797
31982
|
}
|
|
31798
31983
|
}
|
|
31799
|
-
return { op: /^\s*select\b/i.test(
|
|
31984
|
+
return { op: /^\s*select\b/i.test(text3) ? "read" : "write", resource: { kind: "table", name: null, confidence: "unknown" }, rule: "sql.literal" };
|
|
31800
31985
|
}
|
|
31801
31986
|
var SB_WRITE = /* @__PURE__ */ new Set(["insert", "update", "upsert", "delete"]);
|
|
31802
31987
|
var SB_FROM = /\bfrom\(\s*(['"`])([\w.-]+)\1\s*\)\s*$/;
|
|
@@ -31973,7 +32158,7 @@ function heldAt(fn, line2) {
|
|
|
31973
32158
|
}
|
|
31974
32159
|
function contextOf(c, fn) {
|
|
31975
32160
|
const recvRoot = (c.receiver ?? "").split(".")[0];
|
|
31976
|
-
const tryBlock = c.tryAt === null ? null : fn.tries.find((
|
|
32161
|
+
const tryBlock = c.tryAt === null ? null : fn.tries.find((t2) => t2.line === c.tryAt) ?? null;
|
|
31977
32162
|
return {
|
|
31978
32163
|
txn: c.within.some((w) => TXN.has(w)) || recvRoot === "tx" || recvRoot === "trx",
|
|
31979
32164
|
// A lock this call runs inside, or a statement lock taken earlier and still held.
|
|
@@ -32192,42 +32377,42 @@ var ALIAS_OF = "alias-of:";
|
|
|
32192
32377
|
var FIELD_OF = "field-of:";
|
|
32193
32378
|
var IDENT_CHAR = /[\w$]/;
|
|
32194
32379
|
var isIdent = (s) => /^[A-Za-z_$][\w$]*$/.test(s);
|
|
32195
|
-
function wordAt(
|
|
32380
|
+
function wordAt(text3, word) {
|
|
32196
32381
|
const out2 = [];
|
|
32197
|
-
for (let i2 =
|
|
32198
|
-
if (IDENT_CHAR.test(
|
|
32382
|
+
for (let i2 = text3.indexOf(word); i2 >= 0; i2 = text3.indexOf(word, i2 + 1)) {
|
|
32383
|
+
if (IDENT_CHAR.test(text3[i2 - 1] ?? "") || IDENT_CHAR.test(text3[i2 + word.length] ?? "")) continue;
|
|
32199
32384
|
out2.push(i2);
|
|
32200
32385
|
}
|
|
32201
32386
|
return out2;
|
|
32202
32387
|
}
|
|
32203
32388
|
var GO_NOT_TYPES = /* @__PURE__ */ new Set(["int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "float32", "float64", "complex64", "complex128", "string", "bool", "byte", "rune", "error", "any", "func", "chan", "map", "struct", "interface", "range", "make", "new", "nil", "true", "false"]);
|
|
32204
|
-
function typeAt(
|
|
32389
|
+
function typeAt(text3, i2, lang) {
|
|
32205
32390
|
let j = i2;
|
|
32206
32391
|
const skip = () => {
|
|
32207
|
-
while (j <
|
|
32392
|
+
while (j < text3.length && /[\s?*&]/.test(text3[j])) j++;
|
|
32208
32393
|
};
|
|
32209
32394
|
skip();
|
|
32210
|
-
for (const kw of ["new ", "readonly ", "await "]) if (
|
|
32395
|
+
for (const kw of ["new ", "readonly ", "await "]) if (text3.startsWith(kw, j)) {
|
|
32211
32396
|
j += kw.length;
|
|
32212
32397
|
skip();
|
|
32213
32398
|
}
|
|
32214
32399
|
let k = j;
|
|
32215
|
-
while (k <
|
|
32216
|
-
const name2 =
|
|
32400
|
+
while (k < text3.length && /[\w$.]/.test(text3[k])) k++;
|
|
32401
|
+
const name2 = text3.slice(j, k).split(".").pop() ?? "";
|
|
32217
32402
|
if (lang === "go") return /^[A-Za-z_]\w*$/.test(name2) && !GO_NOT_TYPES.has(name2) ? name2 : null;
|
|
32218
32403
|
return /^[A-Z][\w$]*$/.test(name2) ? name2 : null;
|
|
32219
32404
|
}
|
|
32220
32405
|
function declaredType(scope2, v, lang) {
|
|
32221
32406
|
for (const i2 of wordAt(scope2, v)) {
|
|
32222
32407
|
const after = scope2.slice(i2 + v.length);
|
|
32223
|
-
const
|
|
32224
|
-
if (lang !== "go" && lang !== "java" &&
|
|
32408
|
+
const t2 = after.trimStart();
|
|
32409
|
+
if (lang !== "go" && lang !== "java" && t2.startsWith(":") && !t2.startsWith("::")) {
|
|
32225
32410
|
const ty = typeAt(after, after.indexOf(":") + 1, lang);
|
|
32226
32411
|
if (ty) return ty;
|
|
32227
32412
|
}
|
|
32228
|
-
const eq =
|
|
32413
|
+
const eq = t2.startsWith(":=") ? 2 : t2.startsWith("=") && !t2.startsWith("==") ? 1 : 0;
|
|
32229
32414
|
if (eq) {
|
|
32230
|
-
const rhs =
|
|
32415
|
+
const rhs = t2.slice(eq).trimStart();
|
|
32231
32416
|
if (lang === "go" && rhs.startsWith("new(")) {
|
|
32232
32417
|
const ty2 = typeAt(rhs, 4, lang);
|
|
32233
32418
|
if (ty2) return ty2;
|
|
@@ -32338,8 +32523,8 @@ function receiverType(content, lang, caller, receiver, callLine) {
|
|
|
32338
32523
|
if (lang === "go" && caller && caller.params.includes(receiver)) {
|
|
32339
32524
|
const body2 = lines.slice(caller.start.line, callLine).join("\n");
|
|
32340
32525
|
if (rebindsInGo(body2, receiver)) {
|
|
32341
|
-
const
|
|
32342
|
-
return
|
|
32526
|
+
const t2 = declaredType(body2, receiver, lang);
|
|
32527
|
+
return t2 && !t2.includes(":") ? t2 : null;
|
|
32343
32528
|
}
|
|
32344
32529
|
}
|
|
32345
32530
|
const goReceiver = lang === "go" && caller && caller.params[0] === receiver && caller.qualified.includes(".");
|
|
@@ -32363,10 +32548,10 @@ function boundInGo(fnText, name2) {
|
|
|
32363
32548
|
const brace = fnText.indexOf("{");
|
|
32364
32549
|
return wordAt(brace < 0 ? fnText : fnText.slice(0, brace), name2).length > 0;
|
|
32365
32550
|
}
|
|
32366
|
-
function rebindsInGo(
|
|
32367
|
-
for (const i2 of wordAt(
|
|
32368
|
-
const lineEnd =
|
|
32369
|
-
const rest =
|
|
32551
|
+
function rebindsInGo(text3, name2) {
|
|
32552
|
+
for (const i2 of wordAt(text3, name2)) {
|
|
32553
|
+
const lineEnd = text3.indexOf("\n", i2);
|
|
32554
|
+
const rest = text3.slice(i2 + name2.length, lineEnd < 0 ? void 0 : lineEnd);
|
|
32370
32555
|
const decl = rest.indexOf(":=");
|
|
32371
32556
|
if (decl >= 0 && /^[\s\w,]*$/.test(rest.slice(0, decl))) return true;
|
|
32372
32557
|
}
|
|
@@ -32391,15 +32576,15 @@ function localType(content, lang, caller, name2, lines, classes, depth) {
|
|
|
32391
32576
|
const fnText = caller ? lines.slice(caller.start.line - 1, caller.end.line).join("\n") : "";
|
|
32392
32577
|
const local = caller ? declaredType(fnText, name2, lang) : null;
|
|
32393
32578
|
if (!local && caller && lang === "go" && boundInGo(fnText, name2)) return null;
|
|
32394
|
-
const
|
|
32395
|
-
if (!
|
|
32396
|
-
if (
|
|
32397
|
-
const [fn, idx] =
|
|
32579
|
+
const t2 = local ?? declaredType(lang === "go" ? goPackageVars(content) : content, name2, lang);
|
|
32580
|
+
if (!t2) return null;
|
|
32581
|
+
if (t2.startsWith(RESULT_OF)) {
|
|
32582
|
+
const [fn, idx] = t2.slice(RESULT_OF.length).split("#");
|
|
32398
32583
|
return resultTypeOf(content, fn, lang, Number(idx ?? 0)) ?? `${RESULT_OF}${fn}#${idx ?? 0}`;
|
|
32399
32584
|
}
|
|
32400
|
-
if (
|
|
32401
|
-
if (
|
|
32402
|
-
const [base, field] =
|
|
32585
|
+
if (t2.startsWith(ALIAS_OF)) return localType(content, lang, caller, t2.slice(ALIAS_OF.length), lines, classes, depth + 1);
|
|
32586
|
+
if (t2.startsWith(FIELD_OF)) {
|
|
32587
|
+
const [base, field] = t2.slice(FIELD_OF.length).split(".");
|
|
32403
32588
|
const baseType = localType(content, lang, caller, base, lines, classes, depth + 1);
|
|
32404
32589
|
const cls = baseType ? classes.find((c) => c.name === baseType) : null;
|
|
32405
32590
|
if (!cls) return null;
|
|
@@ -32407,7 +32592,7 @@ function localType(content, lang, caller, name2, lines, classes, depth) {
|
|
|
32407
32592
|
const self2 = lang === "python" ? "self" : "this";
|
|
32408
32593
|
return declaredType(body2, field, lang) ?? declaredType(body2, `${self2}.${field}`, lang);
|
|
32409
32594
|
}
|
|
32410
|
-
return
|
|
32595
|
+
return t2;
|
|
32411
32596
|
}
|
|
32412
32597
|
function classFiles(type, fromPath, content, lang, source2, resolveImport, importOf2) {
|
|
32413
32598
|
if (classesIn(content, lang).some((c) => c.name === type)) return [fromPath];
|
|
@@ -32592,15 +32777,15 @@ function importOf(content, lang, name2, receiver) {
|
|
|
32592
32777
|
return null;
|
|
32593
32778
|
}
|
|
32594
32779
|
var TS_EXTS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
|
|
32595
|
-
function parseJsonc(
|
|
32780
|
+
function parseJsonc(text3) {
|
|
32596
32781
|
let out2 = "";
|
|
32597
32782
|
let inString = false;
|
|
32598
|
-
for (let i2 = 0; i2 <
|
|
32599
|
-
const c =
|
|
32783
|
+
for (let i2 = 0; i2 < text3.length; i2++) {
|
|
32784
|
+
const c = text3[i2];
|
|
32600
32785
|
if (inString) {
|
|
32601
32786
|
out2 += c;
|
|
32602
32787
|
if (c === "\\") {
|
|
32603
|
-
out2 +=
|
|
32788
|
+
out2 += text3[++i2] ?? "";
|
|
32604
32789
|
continue;
|
|
32605
32790
|
}
|
|
32606
32791
|
if (c === '"') inString = false;
|
|
@@ -32611,14 +32796,14 @@ function parseJsonc(text2) {
|
|
|
32611
32796
|
out2 += c;
|
|
32612
32797
|
continue;
|
|
32613
32798
|
}
|
|
32614
|
-
if (c === "/" &&
|
|
32615
|
-
while (i2 <
|
|
32799
|
+
if (c === "/" && text3[i2 + 1] === "/") {
|
|
32800
|
+
while (i2 < text3.length && text3[i2] !== "\n") i2++;
|
|
32616
32801
|
out2 += "\n";
|
|
32617
32802
|
continue;
|
|
32618
32803
|
}
|
|
32619
|
-
if (c === "/" &&
|
|
32804
|
+
if (c === "/" && text3[i2 + 1] === "*") {
|
|
32620
32805
|
i2 += 2;
|
|
32621
|
-
while (i2 <
|
|
32806
|
+
while (i2 < text3.length && !(text3[i2] === "*" && text3[i2 + 1] === "/")) i2++;
|
|
32622
32807
|
i2++;
|
|
32623
32808
|
continue;
|
|
32624
32809
|
}
|
|
@@ -32659,8 +32844,8 @@ function tsCandidates(spec, fromPath, cfg) {
|
|
|
32659
32844
|
const star = pattern.indexOf("*");
|
|
32660
32845
|
const matched = star < 0 ? spec === pattern ? "" : null : spec.startsWith(pattern.slice(0, star)) && spec.endsWith(pattern.slice(star + 1)) ? spec.slice(star, spec.length - (pattern.length - star - 1)) : null;
|
|
32661
32846
|
if (matched === null) continue;
|
|
32662
|
-
for (const
|
|
32663
|
-
const b = joinPath(root ?? "",
|
|
32847
|
+
for (const t2 of targets) {
|
|
32848
|
+
const b = joinPath(root ?? "", t2.replace("*", matched));
|
|
32664
32849
|
if (b !== null) bases.push(b);
|
|
32665
32850
|
}
|
|
32666
32851
|
}
|
|
@@ -32827,36 +33012,36 @@ function definitionOf(input) {
|
|
|
32827
33012
|
}
|
|
32828
33013
|
var MAX_CALLER_SCAN_FILES = 60;
|
|
32829
33014
|
var isWordChar2 = (c) => c !== void 0 && /[\w$]/.test(c);
|
|
32830
|
-
function callStarts(
|
|
33015
|
+
function callStarts(text3, name2) {
|
|
32831
33016
|
const out2 = [];
|
|
32832
|
-
for (let i2 =
|
|
33017
|
+
for (let i2 = text3.indexOf(name2); i2 >= 0; i2 = text3.indexOf(name2, i2 + 1)) {
|
|
32833
33018
|
let j = i2 + name2.length;
|
|
32834
|
-
if (
|
|
33019
|
+
if (text3[j] === "<") {
|
|
32835
33020
|
let depth = 0;
|
|
32836
|
-
for (; j <
|
|
32837
|
-
if (
|
|
32838
|
-
else if (
|
|
33021
|
+
for (; j < text3.length; j++) {
|
|
33022
|
+
if (text3[j] === "<") depth++;
|
|
33023
|
+
else if (text3[j] === ">" && --depth === 0) break;
|
|
32839
33024
|
}
|
|
32840
33025
|
j++;
|
|
32841
33026
|
}
|
|
32842
|
-
if (
|
|
33027
|
+
if (text3[j] === "(") out2.push({ index: i2, open: j });
|
|
32843
33028
|
}
|
|
32844
33029
|
return out2;
|
|
32845
33030
|
}
|
|
32846
|
-
function callsName(
|
|
32847
|
-
const
|
|
32848
|
-
if (
|
|
32849
|
-
for (const at of callStarts(
|
|
33031
|
+
function callsName(text3, name2) {
|
|
33032
|
+
const t2 = text3.trim();
|
|
33033
|
+
if (t2.startsWith("//") || t2.startsWith("*") || t2.startsWith("/*") || t2.startsWith("#")) return false;
|
|
33034
|
+
for (const at of callStarts(text3, name2)) {
|
|
32850
33035
|
const i2 = at.index;
|
|
32851
|
-
const spread =
|
|
32852
|
-
if (isWordChar2(
|
|
33036
|
+
const spread = text3.slice(Math.max(0, i2 - 3), i2) === "...";
|
|
33037
|
+
if (isWordChar2(text3[i2 - 1]) || text3[i2 - 1] === "." && !spread) continue;
|
|
32853
33038
|
let depth = 0;
|
|
32854
33039
|
let j = at.open;
|
|
32855
|
-
for (; j <
|
|
32856
|
-
if (
|
|
32857
|
-
else if (
|
|
33040
|
+
for (; j < text3.length; j++) {
|
|
33041
|
+
if (text3[j] === "(") depth++;
|
|
33042
|
+
else if (text3[j] === ")" && --depth === 0) break;
|
|
32858
33043
|
}
|
|
32859
|
-
const after =
|
|
33044
|
+
const after = text3.slice(j + 1).trimStart();
|
|
32860
33045
|
if (after.startsWith(":") || after.startsWith("{")) continue;
|
|
32861
33046
|
return true;
|
|
32862
33047
|
}
|
|
@@ -32946,11 +33131,11 @@ function callersOf(input) {
|
|
|
32946
33131
|
if (seen.has(line2) || declared.has(line2)) continue;
|
|
32947
33132
|
const inside2 = r.value.some((f) => f.start.line <= line2 && line2 <= f.end.line && f.calls.some((c) => c.line === line2 && c.name === name2));
|
|
32948
33133
|
if (inside2) continue;
|
|
32949
|
-
const
|
|
32950
|
-
if (!callsName(
|
|
33134
|
+
const text3 = lines[line2 - 1] ?? "";
|
|
33135
|
+
if (!callsName(text3, name2) || /^\s*(?:export\s+)?(?:async\s+)?(?:function|def|func)\b/.test(text3)) continue;
|
|
32951
33136
|
const enclosing = r.value.filter((f) => f.start.line <= line2 && line2 <= f.end.line).sort((a, b) => a.end.line - a.start.line - (b.end.line - b.start.line))[0];
|
|
32952
33137
|
seen.add(line2);
|
|
32953
|
-
callers.push({ path: p, caller: enclosing ? enclosing.qualified : null, line: line2, text:
|
|
33138
|
+
callers.push({ path: p, caller: enclosing ? enclosing.qualified : null, line: line2, text: text3.trim().slice(0, 200), provenance: fileTie });
|
|
32954
33139
|
}
|
|
32955
33140
|
}
|
|
32956
33141
|
}
|
|
@@ -33257,24 +33442,24 @@ ${m.accessors.map((x) => ` ${x.fn.path}:${x.fn.start.line} ${x.fn.qualified} \u
|
|
|
33257
33442
|
return { ok: true, value: lines.join("\n") };
|
|
33258
33443
|
};
|
|
33259
33444
|
var KINDS = ["table", "cache", "file", "http", "queue", "service", "memory"];
|
|
33260
|
-
function parseResource(
|
|
33261
|
-
const colon =
|
|
33262
|
-
const kind2 = colon > 0 ?
|
|
33263
|
-
if (KINDS.includes(kind2)) return { kinds: [kind2], name:
|
|
33264
|
-
return { kinds: KINDS, name:
|
|
33445
|
+
function parseResource(text3) {
|
|
33446
|
+
const colon = text3.indexOf(":");
|
|
33447
|
+
const kind2 = colon > 0 ? text3.slice(0, colon) : "";
|
|
33448
|
+
if (KINDS.includes(kind2)) return { kinds: [kind2], name: text3.slice(colon + 1) };
|
|
33449
|
+
return { kinds: KINDS, name: text3 };
|
|
33265
33450
|
}
|
|
33266
33451
|
var writersOfTool = async (ctx, args2) => {
|
|
33267
|
-
const
|
|
33268
|
-
if (!
|
|
33269
|
-
const { kinds, name: name2 } = parseResource(
|
|
33452
|
+
const text3 = str2(args2.resource, 300, "resource");
|
|
33453
|
+
if (!text3.ok) return text3;
|
|
33454
|
+
const { kinds, name: name2 } = parseResource(text3.value);
|
|
33270
33455
|
if (name2.length < 2) return { ok: false, error: "resource name too short to search for" };
|
|
33271
33456
|
const deadline = Date.now() + TOOL_MS;
|
|
33272
33457
|
const src = source(ctx);
|
|
33273
33458
|
const terms = [.../* @__PURE__ */ new Set([name2, ...searchTerms({ kind: "table", name: name2, confidence: "inferred" })])];
|
|
33274
33459
|
const files = /* @__PURE__ */ new Set();
|
|
33275
33460
|
let truncated = false;
|
|
33276
|
-
for (const
|
|
33277
|
-
const found = src.search(
|
|
33461
|
+
for (const t2 of terms) {
|
|
33462
|
+
const found = src.search(t2, { maxHits: 300, timeoutMs: Math.max(100, deadline - Date.now()) });
|
|
33278
33463
|
if (!found.ok) {
|
|
33279
33464
|
truncated = true;
|
|
33280
33465
|
continue;
|
|
@@ -33305,7 +33490,7 @@ var writersOfTool = async (ctx, args2) => {
|
|
|
33305
33490
|
if (files.size > 25) truncated = true;
|
|
33306
33491
|
const list2 = (xs) => xs.length ? xs.slice(0, MAX_LIST).map((x) => ` ${x}`).join("\n") + (xs.length > MAX_LIST ? `
|
|
33307
33492
|
\u2026 ${xs.length - MAX_LIST} more` : "") : " none found";
|
|
33308
|
-
return { ok: true, value: `${
|
|
33493
|
+
return { ok: true, value: `${text3.value} (${where(ctx)}), heuristic${truncated ? ", search cut short" : ""}
|
|
33309
33494
|
writers:
|
|
33310
33495
|
${list2(writers)}
|
|
33311
33496
|
readers:
|
|
@@ -33363,9 +33548,9 @@ function validateRepoPath(value, { allowRoot = false } = {}) {
|
|
|
33363
33548
|
function lineNumber(value, fallback) {
|
|
33364
33549
|
return typeof value === "number" && Number.isInteger(value) && value >= 1 ? value : fallback;
|
|
33365
33550
|
}
|
|
33366
|
-
function capOutput(
|
|
33367
|
-
return
|
|
33368
|
-
[truncated at ${TOOL_LIMITS.outputChars} characters]` :
|
|
33551
|
+
function capOutput(text3) {
|
|
33552
|
+
return text3.length > TOOL_LIMITS.outputChars ? `${text3.slice(0, TOOL_LIMITS.outputChars)}
|
|
33553
|
+
[truncated at ${TOOL_LIMITS.outputChars} characters]` : text3;
|
|
33369
33554
|
}
|
|
33370
33555
|
function git(ctx, args2, opts = {}) {
|
|
33371
33556
|
return runGit(ctx.root, args2, { timeoutMs: opts.timeoutMs ?? TOOL_LIMITS.gitTimeoutMs, maxBuffer: opts.maxBuffer ?? TOOL_LIMITS.fileBytes });
|
|
@@ -33499,8 +33684,8 @@ var listFilesTool = async (ctx, args2) => {
|
|
|
33499
33684
|
\u2026 ${more} more` : ""}` : "no matching files" };
|
|
33500
33685
|
};
|
|
33501
33686
|
var searchTool = async (ctx, args2) => {
|
|
33502
|
-
const
|
|
33503
|
-
if (typeof
|
|
33687
|
+
const text3 = args2.text;
|
|
33688
|
+
if (typeof text3 !== "string" || text3.length === 0 || text3.length > TOOL_LIMITS.textChars || /[\n\r]/.test(text3)) {
|
|
33504
33689
|
return { ok: false, error: `text must be 1-${TOOL_LIMITS.textChars} characters on one line` };
|
|
33505
33690
|
}
|
|
33506
33691
|
const glob = typeof args2.path_glob === "string" && args2.path_glob.length > 0 ? args2.path_glob : null;
|
|
@@ -33509,7 +33694,7 @@ var searchTool = async (ctx, args2) => {
|
|
|
33509
33694
|
}
|
|
33510
33695
|
const pathspec = glob ? [`:(glob)${glob}`] : [];
|
|
33511
33696
|
const revision = ctx.range.kind === "push" ? [ctx.range.head] : ["--cached"];
|
|
33512
|
-
const res = await git(ctx, ["grep", "-n", "-I", "-F", "--no-color", ...revision.filter((r) => r === "--cached"), "-e",
|
|
33697
|
+
const res = await git(ctx, ["grep", "-n", "-I", "-F", "--no-color", ...revision.filter((r) => r === "--cached"), "-e", text3, ...revision.filter((r) => r !== "--cached"), "--", ...pathspec]);
|
|
33513
33698
|
if (!res.ok) {
|
|
33514
33699
|
if (res.error === "failed" && res.stderr.trim() === "") return { ok: true, value: "no matches" };
|
|
33515
33700
|
return { ok: false, error: gitFailure(res, "search") };
|
|
@@ -33643,10 +33828,10 @@ function writerExcerpts(codeMap, writers, read2, maxLines, maxChars, budget) {
|
|
|
33643
33828
|
if (content === null) continue;
|
|
33644
33829
|
const win = functionWindow(codeMap, w.file, content, w.line, maxLines);
|
|
33645
33830
|
if (!win) continue;
|
|
33646
|
-
const
|
|
33647
|
-
if (used2 +
|
|
33648
|
-
used2 +=
|
|
33649
|
-
out2.push({ file: w.file, start_line: win.start_line, symbol: `${w.symbol} (writes ${w.resource}, like ${w.changed})`, kind: "writer", text:
|
|
33831
|
+
const text3 = content.split("\n").slice(win.start_line - 1, win.end_line).join("\n").slice(0, maxChars);
|
|
33832
|
+
if (used2 + text3.length > budget) break;
|
|
33833
|
+
used2 += text3.length;
|
|
33834
|
+
out2.push({ file: w.file, start_line: win.start_line, symbol: `${w.symbol} (writes ${w.resource}, like ${w.changed})`, kind: "writer", text: text3 });
|
|
33650
33835
|
}
|
|
33651
33836
|
return out2;
|
|
33652
33837
|
}
|
|
@@ -33706,7 +33891,7 @@ async function repoContext(run4) {
|
|
|
33706
33891
|
var import_promises11 = require("node:fs/promises");
|
|
33707
33892
|
var import_node_fs53 = require("node:fs");
|
|
33708
33893
|
var import_node_path42 = require("node:path");
|
|
33709
|
-
var
|
|
33894
|
+
var import_yaml9 = __toESM2(require_dist());
|
|
33710
33895
|
|
|
33711
33896
|
// src/lib/seed.ts
|
|
33712
33897
|
function extractReadmeIntro(content) {
|
|
@@ -34017,7 +34202,7 @@ async function runSeed(opts) {
|
|
|
34017
34202
|
let standardDoc;
|
|
34018
34203
|
try {
|
|
34019
34204
|
const raw = await (0, import_promises11.readFile)(STANDARD_FILE, "utf-8");
|
|
34020
|
-
standardDoc = (0,
|
|
34205
|
+
standardDoc = (0, import_yaml9.parse)(raw);
|
|
34021
34206
|
} catch {
|
|
34022
34207
|
return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
|
|
34023
34208
|
}
|
|
@@ -35093,7 +35278,7 @@ async function reconcile(run4) {
|
|
|
35093
35278
|
const episodeSignals = {
|
|
35094
35279
|
humanSpoke: (conversation?.prompts?.length ?? 0) > 0,
|
|
35095
35280
|
rawFail: decision === "FAIL",
|
|
35096
|
-
tasksCompleted: (foldResult?.tasks ?? []).filter((
|
|
35281
|
+
tasksCompleted: (foldResult?.tasks ?? []).filter((t2) => t2.status === "completed").length,
|
|
35097
35282
|
now: Math.floor(Date.now() / 1e3)
|
|
35098
35283
|
};
|
|
35099
35284
|
let episode = resolveEpisode(readAdvisoryEpisode(baselineSessionId), episodeSignals);
|
|
@@ -36317,7 +36502,7 @@ var IDENT2 = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$/;
|
|
|
36317
36502
|
var SHA256 = /^(sha256:)?[0-9a-f]{64}$/;
|
|
36318
36503
|
var KINDS2 = /* @__PURE__ */ new Set(["structural", "intent"]);
|
|
36319
36504
|
var RESULTS = /* @__PURE__ */ new Set(["holds", "counterexample", "exhausted", "proved"]);
|
|
36320
|
-
var
|
|
36505
|
+
var LIMITS3 = {
|
|
36321
36506
|
text: 1e3,
|
|
36322
36507
|
// desc, source
|
|
36323
36508
|
state: 4e3,
|
|
@@ -36348,22 +36533,22 @@ function strArr(v, maxItems, maxItem) {
|
|
|
36348
36533
|
return out2;
|
|
36349
36534
|
}
|
|
36350
36535
|
function nat(v) {
|
|
36351
|
-
return typeof v === "number" && Number.isInteger(v) && v >= 0 && v <=
|
|
36536
|
+
return typeof v === "number" && Number.isInteger(v) && v >= 0 && v <= LIMITS3.int ? v : null;
|
|
36352
36537
|
}
|
|
36353
36538
|
function repoPath2(v) {
|
|
36354
|
-
const s = str3(v,
|
|
36539
|
+
const s = str3(v, LIMITS3.path);
|
|
36355
36540
|
if (!s || s.startsWith("/") || /^[A-Za-z]:[\\/]/.test(s)) return null;
|
|
36356
36541
|
if (s.split(/[\\/]/).some((p) => p === ".." || p === "")) return null;
|
|
36357
36542
|
return s;
|
|
36358
36543
|
}
|
|
36359
36544
|
function parseHeader(obj) {
|
|
36360
36545
|
const model = ident(obj.model);
|
|
36361
|
-
if (!model || !Array.isArray(obj.abstracts) || obj.abstracts.length >
|
|
36546
|
+
if (!model || !Array.isArray(obj.abstracts) || obj.abstracts.length > LIMITS3.abstracts) return null;
|
|
36362
36547
|
const abstracts = [];
|
|
36363
36548
|
for (const a of obj.abstracts) {
|
|
36364
36549
|
if (!isPlainObject2(a)) return null;
|
|
36365
36550
|
const file = repoPath2(a.file);
|
|
36366
|
-
const symbol = str3(a.symbol,
|
|
36551
|
+
const symbol = str3(a.symbol, LIMITS3.symbol);
|
|
36367
36552
|
const sha = a.sha256 === void 0 ? "" : str3(a.sha256, 80);
|
|
36368
36553
|
if (!file || !symbol || sha === null) return null;
|
|
36369
36554
|
if (sha !== "" && sha !== "TBD" && !SHA256.test(sha)) return null;
|
|
@@ -36385,8 +36570,8 @@ function parseProperty(obj) {
|
|
|
36385
36570
|
const id = ident(obj.id);
|
|
36386
36571
|
const kind2 = typeof obj.kind === "string" && KINDS2.has(obj.kind) ? obj.kind : null;
|
|
36387
36572
|
const result = typeof obj.result === "string" && RESULTS.has(obj.result) ? obj.result : null;
|
|
36388
|
-
const source2 = obj.source === void 0 ? "" : str3(obj.source,
|
|
36389
|
-
const desc = obj.desc === void 0 ? "" : str3(obj.desc,
|
|
36573
|
+
const source2 = obj.source === void 0 ? "" : str3(obj.source, LIMITS3.text);
|
|
36574
|
+
const desc = obj.desc === void 0 ? "" : str3(obj.desc, LIMITS3.text);
|
|
36390
36575
|
if (!model || !id || !kind2 || !result || source2 === null || desc === null) return null;
|
|
36391
36576
|
const p = { model, id, kind: kind2, source: source2, desc, result };
|
|
36392
36577
|
if (obj.bound !== void 0) {
|
|
@@ -36400,24 +36585,24 @@ function parseProperty(obj) {
|
|
|
36400
36585
|
p.states = n2;
|
|
36401
36586
|
}
|
|
36402
36587
|
if (obj.trace !== void 0) {
|
|
36403
|
-
const
|
|
36404
|
-
if (!
|
|
36405
|
-
p.trace =
|
|
36588
|
+
const t2 = strArr(obj.trace, LIMITS3.traceItems, LIMITS3.traceItem);
|
|
36589
|
+
if (!t2) return null;
|
|
36590
|
+
p.trace = t2;
|
|
36406
36591
|
}
|
|
36407
36592
|
if (obj.states_along !== void 0) {
|
|
36408
|
-
const s = strArr(obj.states_along,
|
|
36593
|
+
const s = strArr(obj.states_along, LIMITS3.traceItems, LIMITS3.state);
|
|
36409
36594
|
if (!s) return null;
|
|
36410
36595
|
p.states_along = s;
|
|
36411
36596
|
}
|
|
36412
36597
|
if (obj.final !== void 0) {
|
|
36413
|
-
const f = str3(obj.final,
|
|
36598
|
+
const f = str3(obj.final, LIMITS3.state);
|
|
36414
36599
|
if (f === null) return null;
|
|
36415
36600
|
p.final = f;
|
|
36416
36601
|
}
|
|
36417
36602
|
if (obj.theorem !== void 0) {
|
|
36418
|
-
const
|
|
36419
|
-
if (
|
|
36420
|
-
p.theorem =
|
|
36603
|
+
const t2 = str3(obj.theorem, LIMITS3.symbol);
|
|
36604
|
+
if (t2 === null) return null;
|
|
36605
|
+
p.theorem = t2;
|
|
36421
36606
|
}
|
|
36422
36607
|
return p;
|
|
36423
36608
|
}
|
|
@@ -36696,8 +36881,8 @@ function listModelFiles(root) {
|
|
|
36696
36881
|
if (!(0, import_node_fs61.existsSync)(modelsAbs)) return [];
|
|
36697
36882
|
return (0, import_node_fs61.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path49.join)(modelsAbs, f));
|
|
36698
36883
|
}
|
|
36699
|
-
function trimDiagnostics(
|
|
36700
|
-
return
|
|
36884
|
+
function trimDiagnostics(text3) {
|
|
36885
|
+
return text3.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
|
|
36701
36886
|
}
|
|
36702
36887
|
function checkModel(tc, root, modelFile, opts = {}) {
|
|
36703
36888
|
const proofsAbs = (0, import_node_path49.join)(root, PROOFS_DIR);
|
|
@@ -37709,9 +37894,9 @@ var HAS_FAILURE = /fail|error|throw|time[sd]?[\s_-]*out|reject|exception|unavail
|
|
|
37709
37894
|
var HAS_CRASH = /crash|die|kill|abort|restart/i;
|
|
37710
37895
|
function missingTrigger(desc, trace) {
|
|
37711
37896
|
const d = desc.toLowerCase();
|
|
37712
|
-
const
|
|
37713
|
-
if (NEEDS_CRASH.test(d) && !HAS_CRASH.test(
|
|
37714
|
-
if (NEEDS_FAILURE.test(d) && !HAS_FAILURE.test(
|
|
37897
|
+
const t2 = trace.join(" ");
|
|
37898
|
+
if (NEEDS_CRASH.test(d) && !HAS_CRASH.test(t2)) return "a crash";
|
|
37899
|
+
if (NEEDS_FAILURE.test(d) && !HAS_FAILURE.test(t2)) return "a failure";
|
|
37715
37900
|
return null;
|
|
37716
37901
|
}
|
|
37717
37902
|
function ungroundedMessage(list2) {
|
|
@@ -37911,13 +38096,13 @@ var lunaRanker = {
|
|
|
37911
38096
|
signal: controller.signal
|
|
37912
38097
|
});
|
|
37913
38098
|
if (!res.ok) {
|
|
37914
|
-
const
|
|
37915
|
-
return { ok: false, ranker: "luna", error: `OpenAI ${res.status}: ${
|
|
38099
|
+
const text4 = await res.text().catch(() => "");
|
|
38100
|
+
return { ok: false, ranker: "luna", error: `OpenAI ${res.status}: ${text4.slice(0, 200)}`, ranked: fallback };
|
|
37916
38101
|
}
|
|
37917
38102
|
const data = await res.json();
|
|
37918
|
-
const
|
|
37919
|
-
if (!
|
|
37920
|
-
const parsed = JSON.parse(
|
|
38103
|
+
const text3 = (data.output ?? []).flatMap((o) => o.content ?? []).find((c) => c.type === "output_text")?.text;
|
|
38104
|
+
if (!text3) return { ok: false, ranker: "luna", error: "no output_text in response", ranked: fallback };
|
|
38105
|
+
const parsed = JSON.parse(text3);
|
|
37921
38106
|
const items = parsed.items.map((i2) => {
|
|
37922
38107
|
const legacy = i2.critical === void 0 && i2.hazard === void 0 && i2.error_prone === void 0;
|
|
37923
38108
|
const criteria = legacy ? { critical: Number(i2.score) || 0, hazard: Number(i2.score) || 0, error_prone: Number(i2.score) || 0 } : { critical: Number(i2.critical) || 0, hazard: Number(i2.hazard) || 0, error_prone: Number(i2.error_prone) || 0 };
|
|
@@ -38235,42 +38420,42 @@ function lintModelSource(source2) {
|
|
|
38235
38420
|
let sawCheck = false;
|
|
38236
38421
|
for (const raw of code.split("\n")) {
|
|
38237
38422
|
const line2 = raw.trimEnd();
|
|
38238
|
-
const
|
|
38239
|
-
if (
|
|
38240
|
-
if (/^import\b/.test(
|
|
38241
|
-
if (
|
|
38423
|
+
const t2 = line2.trim();
|
|
38424
|
+
if (t2 === "") continue;
|
|
38425
|
+
if (/^import\b/.test(t2)) {
|
|
38426
|
+
if (t2 !== "import Verity") reasons.push(`only \`import Verity\` is allowed (got \`${t2.slice(0, 40)}\`)`);
|
|
38242
38427
|
sawImport = true;
|
|
38243
38428
|
continue;
|
|
38244
38429
|
}
|
|
38245
|
-
if (/^open\b/.test(
|
|
38246
|
-
if (
|
|
38430
|
+
if (/^open\b/.test(t2)) {
|
|
38431
|
+
if (t2 !== "open Verity") reasons.push(`only \`open Verity\` is allowed (got \`${t2.slice(0, 40)}\`)`);
|
|
38247
38432
|
continue;
|
|
38248
38433
|
}
|
|
38249
|
-
if (/^namespace\b/.test(
|
|
38250
|
-
if (!/^namespace Models\.[A-Za-z][A-Za-z0-9_]*$/.test(
|
|
38434
|
+
if (/^namespace\b/.test(t2)) {
|
|
38435
|
+
if (!/^namespace Models\.[A-Za-z][A-Za-z0-9_]*$/.test(t2)) reasons.push(`namespace must be \`Models.<Name>\` (got \`${t2.slice(0, 40)}\`)`);
|
|
38251
38436
|
continue;
|
|
38252
38437
|
}
|
|
38253
|
-
if (/^end\b/.test(
|
|
38254
|
-
if (!/^end( Models\.[A-Za-z][A-Za-z0-9_]*)?$/.test(
|
|
38438
|
+
if (/^end\b/.test(t2)) {
|
|
38439
|
+
if (!/^end( Models\.[A-Za-z][A-Za-z0-9_]*)?$/.test(t2)) reasons.push(`unexpected \`${t2.slice(0, 40)}\``);
|
|
38255
38440
|
continue;
|
|
38256
38441
|
}
|
|
38257
|
-
if (/^section\b|^mutual\b/.test(
|
|
38258
|
-
reasons.push(`\`${
|
|
38442
|
+
if (/^section\b|^mutual\b/.test(t2)) {
|
|
38443
|
+
reasons.push(`\`${t2.split(/\s/)[0]}\` is not allowed in a model`);
|
|
38259
38444
|
continue;
|
|
38260
38445
|
}
|
|
38261
|
-
const hashes = [...
|
|
38446
|
+
const hashes = [...t2.matchAll(/#/g)];
|
|
38262
38447
|
for (const h of hashes) {
|
|
38263
38448
|
const at = h.index ?? 0;
|
|
38264
|
-
if (
|
|
38265
|
-
if (at === 0 && /^#eval\s+Verity\.(model|check|checkData|proved)\b/.test(
|
|
38266
|
-
if (EFFECT_OPERATORS.test(
|
|
38267
|
-
if (/#eval\s+Verity\.model\b/.test(
|
|
38449
|
+
if (t2[at + 1] === "[") continue;
|
|
38450
|
+
if (at === 0 && /^#eval\s+Verity\.(model|check|checkData|proved)\b/.test(t2)) {
|
|
38451
|
+
if (EFFECT_OPERATORS.test(t2.slice(5))) reasons.push(`effect operator on an #eval line: \`${t2.slice(0, 60)}\``);
|
|
38452
|
+
if (/#eval\s+Verity\.model\b/.test(t2)) sawModelHeader = true;
|
|
38268
38453
|
else sawCheck = true;
|
|
38269
38454
|
continue;
|
|
38270
38455
|
}
|
|
38271
|
-
reasons.push(`command not allowed: \`${
|
|
38456
|
+
reasons.push(`command not allowed: \`${t2.slice(Math.max(0, at - 5), at + 40)}\` (only \`#eval Verity.model|check|checkData|proved\` at line start)`);
|
|
38272
38457
|
}
|
|
38273
|
-
if (/^\s/.test(raw) && EFFECT_OPERATORS.test(
|
|
38458
|
+
if (/^\s/.test(raw) && EFFECT_OPERATORS.test(t2) && /\bVerity\./.test(t2)) reasons.push(`effect operator near a Verity call: \`${t2.slice(0, 60)}\``);
|
|
38274
38459
|
}
|
|
38275
38460
|
if (!sawImport) reasons.push("missing `import Verity`");
|
|
38276
38461
|
if (!sawModelHeader) reasons.push("no `#eval Verity.model` header");
|
|
@@ -38288,11 +38473,11 @@ function joinBrokenLiterals(source2) {
|
|
|
38288
38473
|
let i2 = 0;
|
|
38289
38474
|
while (i2 < raw.length) {
|
|
38290
38475
|
let r = raw[i2];
|
|
38291
|
-
let
|
|
38476
|
+
let t2 = tok[i2];
|
|
38292
38477
|
i2++;
|
|
38293
38478
|
for (; ; ) {
|
|
38294
|
-
const d = depth + braceDelta(
|
|
38295
|
-
const end =
|
|
38479
|
+
const d = depth + braceDelta(t2);
|
|
38480
|
+
const end = t2.trimEnd();
|
|
38296
38481
|
if (!(d > 0 && end.endsWith(",") && i2 < raw.length)) break;
|
|
38297
38482
|
while (i2 < raw.length && tok[i2].trim() === "") i2++;
|
|
38298
38483
|
if (i2 >= raw.length) break;
|
|
@@ -38301,10 +38486,10 @@ function joinBrokenLiterals(source2) {
|
|
|
38301
38486
|
const nextTok = tok[i2];
|
|
38302
38487
|
const lead = nextTok.length - nextTok.trimStart().length;
|
|
38303
38488
|
r = r.slice(0, cut) + " " + nextRaw.slice(lead);
|
|
38304
|
-
|
|
38489
|
+
t2 = t2.slice(0, cut) + " " + nextTok.slice(lead);
|
|
38305
38490
|
i2++;
|
|
38306
38491
|
}
|
|
38307
|
-
depth = Math.max(0, depth + braceDelta(
|
|
38492
|
+
depth = Math.max(0, depth + braceDelta(t2));
|
|
38308
38493
|
outRaw.push(r);
|
|
38309
38494
|
}
|
|
38310
38495
|
return outRaw.join("\n");
|
|
@@ -38576,19 +38761,19 @@ var PURE_METHODS2 = /* @__PURE__ */ new Set([
|
|
|
38576
38761
|
"test",
|
|
38577
38762
|
"match"
|
|
38578
38763
|
]);
|
|
38579
|
-
function callsOn(
|
|
38764
|
+
function callsOn(text3, name2) {
|
|
38580
38765
|
const needle = `${name2}.`;
|
|
38581
|
-
for (let i2 =
|
|
38582
|
-
if (i2 > 0 && IDENT_CHAR2.test(
|
|
38583
|
-
const call = CALL_AFTER_DOT.exec(
|
|
38766
|
+
for (let i2 = text3.indexOf(needle); i2 >= 0; i2 = text3.indexOf(needle, i2 + 1)) {
|
|
38767
|
+
if (i2 > 0 && IDENT_CHAR2.test(text3[i2 - 1])) continue;
|
|
38768
|
+
const call = CALL_AFTER_DOT.exec(text3.slice(i2 + needle.length));
|
|
38584
38769
|
if (call && !PURE_METHODS2.has(call[1])) return true;
|
|
38585
38770
|
}
|
|
38586
38771
|
return false;
|
|
38587
38772
|
}
|
|
38588
|
-
function callsDirect(
|
|
38773
|
+
function callsDirect(text3, name2) {
|
|
38589
38774
|
const needle = `${name2}(`;
|
|
38590
|
-
for (let i2 =
|
|
38591
|
-
if (i2 > 0 && IDENT_CHAR2.test(
|
|
38775
|
+
for (let i2 = text3.indexOf(needle); i2 >= 0; i2 = text3.indexOf(needle, i2 + 1)) {
|
|
38776
|
+
if (i2 > 0 && IDENT_CHAR2.test(text3[i2 - 1])) continue;
|
|
38592
38777
|
return true;
|
|
38593
38778
|
}
|
|
38594
38779
|
return false;
|
|
@@ -38610,12 +38795,12 @@ function effectSites(numbered2) {
|
|
|
38610
38795
|
const out2 = [];
|
|
38611
38796
|
for (const [i2, r] of rows.entries()) {
|
|
38612
38797
|
if (i2 === 0) continue;
|
|
38613
|
-
const
|
|
38614
|
-
if (!
|
|
38615
|
-
const onParam = [...params].some((p) => callsOn(
|
|
38616
|
-
const kind2 = EFFECT_LINE2.test(
|
|
38798
|
+
const t2 = r.text.trim();
|
|
38799
|
+
if (!t2 || t2.startsWith("//") || t2.startsWith("#") || t2.startsWith("*")) continue;
|
|
38800
|
+
const onParam = [...params].some((p) => callsOn(t2, p) || callsDirect(t2, p));
|
|
38801
|
+
const kind2 = EFFECT_LINE2.test(t2) || onParam ? "effect" : CONTROL_LINE.test(t2) ? "control" : null;
|
|
38617
38802
|
if (!kind2) continue;
|
|
38618
|
-
out2.push(`L${r.n} [${kind2}] ${
|
|
38803
|
+
out2.push(`L${r.n} [${kind2}] ${t2.length > 160 ? t2.slice(0, 157) + "\u2026" : t2}`);
|
|
38619
38804
|
if (out2.length >= MAX_EFFECT_SITES) break;
|
|
38620
38805
|
}
|
|
38621
38806
|
return out2;
|
|
@@ -38624,7 +38809,7 @@ function starChanged(numbered2, changed) {
|
|
|
38624
38809
|
const isChanged = (n2) => !!changed?.some((r) => n2 >= r.from && n2 <= r.to);
|
|
38625
38810
|
const starred = [];
|
|
38626
38811
|
let total = 0;
|
|
38627
|
-
const
|
|
38812
|
+
const text3 = numbered2.split("\n").map((raw) => {
|
|
38628
38813
|
const m = NUMBERED_LINE.exec(raw);
|
|
38629
38814
|
if (!m) return raw;
|
|
38630
38815
|
total++;
|
|
@@ -38640,43 +38825,43 @@ function starChanged(numbered2, changed) {
|
|
|
38640
38825
|
runs.push(i2 === j ? `${starred[i2]}` : `${starred[i2]}\u2013${starred[j]}`);
|
|
38641
38826
|
i2 = j;
|
|
38642
38827
|
}
|
|
38643
|
-
return { text:
|
|
38828
|
+
return { text: text3, ranges: runs.join(", "), count: starred.length, total };
|
|
38644
38829
|
}
|
|
38645
|
-
function renderGenerateInput(
|
|
38830
|
+
function renderGenerateInput(t2, previous) {
|
|
38646
38831
|
const parts2 = [];
|
|
38647
|
-
parts2.push(`# Target: ${
|
|
38648
|
-
parts2.push(`Header values: file := "${
|
|
38649
|
-
if (
|
|
38650
|
-
if (
|
|
38651
|
-
if (
|
|
38652
|
-
if (
|
|
38653
|
-
${
|
|
38654
|
-
const numbered2 =
|
|
38832
|
+
parts2.push(`# Target: ${t2.file} \u2014 \`${t2.symbol}\`${t2.lines ? ` (lines ${t2.lines.from}\u2013${t2.lines.to})` : ""}`);
|
|
38833
|
+
parts2.push(`Header values: file := "${t2.file}", symbol := "${t2.symbol}", sha256 := "${t2.sha256}", lines := "${t2.lines ? `${t2.lines.from}-${t2.lines.to}` : ""}"`);
|
|
38834
|
+
if (t2.reasons.length) parts2.push(`Why it was selected: ${t2.reasons.join(" \xB7 ")}`);
|
|
38835
|
+
if (t2.properties.length) parts2.push(`Suggested properties: ${t2.properties.join(", ")}`);
|
|
38836
|
+
if (t2.lens === "security") parts2.push("SECURITY: an attacker outside the trust boundary can drive this code. Follow AN ATTACKER.");
|
|
38837
|
+
if (t2.hypotheses?.length) parts2.push(`Hypotheses from the selector (questions to try, not verdicts):
|
|
38838
|
+
${t2.hypotheses.slice(0, MAX_HYPOTHESES2).map((h) => ` - ${h}`).join("\n")}`);
|
|
38839
|
+
const numbered2 = t2.numbered.slice(0, MAX_NUMBERED_BYTES);
|
|
38655
38840
|
const sites = effectSites(numbered2);
|
|
38656
|
-
const push = starChanged(numbered2,
|
|
38841
|
+
const push = starChanged(numbered2, t2.changed);
|
|
38657
38842
|
if (push.count > 0) parts2.push(`A push: it changed ${push.count} of these ${push.total} lines (${push.ranges}), marked \`*|\` below. Look first for a bug the change introduced.`);
|
|
38658
38843
|
parts2.push("", sites.length ? `Effect sites (STEP 1 \u2014 where the real world can interleave, fail or crash):
|
|
38659
38844
|
${sites.map((s) => ` ${s}`).join("\n")}` : "Effect sites: none \u2014 a pure computation (STEP 3: Verity.checkData on concrete inputs).");
|
|
38660
38845
|
parts2.push("", "```", push.count > 0 ? push.text : numbered2, "```");
|
|
38661
|
-
if (
|
|
38846
|
+
if (t2.effects?.length) {
|
|
38662
38847
|
parts2.push("", `State this function touches (from the parser; "via" names the helper that does it):
|
|
38663
|
-
${
|
|
38848
|
+
${t2.effects.slice(0, MAX_CONTEXT_EFFECTS).map((e) => ` ${e}`).join("\n")}`);
|
|
38664
38849
|
}
|
|
38665
|
-
if (
|
|
38850
|
+
if (t2.coAccessors?.length) {
|
|
38666
38851
|
parts2.push("", "# Other functions that touch the same state (STEP 2 \u2014 the second actor)");
|
|
38667
|
-
for (const c of
|
|
38852
|
+
for (const c of t2.coAccessors.slice(0, MAX_CO_ACCESSORS)) {
|
|
38668
38853
|
parts2.push("", `## ${c.file} \u2014 \`${c.symbol}\` (lines ${c.lines.from}\u2013${c.lines.to})`, `Header values: file := "${c.file}", symbol := "${c.symbol}", sha256 := "${c.sha256}", lines := "${c.lines.from}-${c.lines.to}"`);
|
|
38669
38854
|
if (c.touches.length) parts2.push(`It touches: ${c.touches.slice(0, MAX_CONTEXT_EFFECTS).join(" \xB7 ")}`);
|
|
38670
38855
|
parts2.push("```", c.numbered, "```");
|
|
38671
38856
|
}
|
|
38672
38857
|
}
|
|
38673
|
-
if (
|
|
38858
|
+
if (t2.helpers?.length) {
|
|
38674
38859
|
parts2.push("", "# Helpers it calls (their effects happen at the line that calls them)");
|
|
38675
|
-
for (const h of
|
|
38860
|
+
for (const h of t2.helpers.slice(0, MAX_HELPERS2)) parts2.push("", `## ${h.file} \u2014 \`${h.symbol}\` (lines ${h.lines.from}\u2013${h.lines.to})`, "```", h.numbered, "```");
|
|
38676
38861
|
}
|
|
38677
|
-
if (
|
|
38862
|
+
if (t2.callers?.length) {
|
|
38678
38863
|
parts2.push("", "# Where it is called (a caller's guard bounds the inputs it can get)");
|
|
38679
|
-
for (const c of
|
|
38864
|
+
for (const c of t2.callers.slice(0, MAX_CALLERS2)) parts2.push("", `## ${c.file}:${c.line}${c.caller ? ` \u2014 in \`${c.caller}\`` : ""}`, "```", c.numbered, "```");
|
|
38680
38865
|
}
|
|
38681
38866
|
if (previous) {
|
|
38682
38867
|
parts2.push("", "# Your previous attempt was not accepted \u2014 the diagnostics say why. Fix it (same model, same properties):", "```lean", previous.source.slice(0, 32 * 1024), "```", "Diagnostics:", "```", previous.error.slice(0, 4e3), "```");
|
|
@@ -38771,11 +38956,11 @@ async function generateModel(target, opts) {
|
|
|
38771
38956
|
return { ok: false, error: name2 === "TimeoutError" || name2 === "AbortError" ? "timed out" : err2.message };
|
|
38772
38957
|
}
|
|
38773
38958
|
const usage = data.usage ? { inputTokens: Number(data.usage.input_tokens ?? 0), outputTokens: Number(data.usage.output_tokens ?? 0) } : null;
|
|
38774
|
-
const
|
|
38775
|
-
if (!
|
|
38959
|
+
const text3 = (data.output ?? []).flatMap((o) => o.content ?? []).find((c) => c.type === "output_text")?.text;
|
|
38960
|
+
if (!text3) return { ok: false, error: "no output_text in response", usage };
|
|
38776
38961
|
let parsed;
|
|
38777
38962
|
try {
|
|
38778
|
-
parsed = JSON.parse(
|
|
38963
|
+
parsed = JSON.parse(text3);
|
|
38779
38964
|
} catch {
|
|
38780
38965
|
return { ok: false, error: "answer was not JSON", usage };
|
|
38781
38966
|
}
|
|
@@ -38785,8 +38970,8 @@ async function generateModel(target, opts) {
|
|
|
38785
38970
|
// src/lib/prove/replay.ts
|
|
38786
38971
|
var MAX_SOURCE_BYTES = 96 * 1024;
|
|
38787
38972
|
var MAX_MODEL_BYTES = 32 * 1024;
|
|
38788
|
-
function numberLines(
|
|
38789
|
-
return
|
|
38973
|
+
function numberLines(text3, from = 1) {
|
|
38974
|
+
return text3.split("\n").map((l, i2) => `${String(i2 + from).padStart(5)}| ${l}`).join("\n");
|
|
38790
38975
|
}
|
|
38791
38976
|
var PY_DECL = /^\s*(?:async\s+)?def\s+([A-Za-z_]\w*)\s*\(/;
|
|
38792
38977
|
var TS_DECLS = [
|
|
@@ -38803,8 +38988,8 @@ function copiedLines(brief) {
|
|
|
38803
38988
|
const out2 = /* @__PURE__ */ new Set();
|
|
38804
38989
|
for (const src of brief.sources) {
|
|
38805
38990
|
for (const l of (src.content ?? "").split("\n")) {
|
|
38806
|
-
const
|
|
38807
|
-
if (
|
|
38991
|
+
const t2 = l.trim();
|
|
38992
|
+
if (t2) out2.add(t2);
|
|
38808
38993
|
}
|
|
38809
38994
|
}
|
|
38810
38995
|
return out2;
|
|
@@ -38812,8 +38997,8 @@ function copiedLines(brief) {
|
|
|
38812
38997
|
function harnessInvokes(texts, symbol, py, copied = /* @__PURE__ */ new Set()) {
|
|
38813
38998
|
if (!/^[A-Za-z_$][\w$]*$/.test(symbol)) return null;
|
|
38814
38999
|
let declared = false;
|
|
38815
|
-
for (const
|
|
38816
|
-
for (const line2 of
|
|
39000
|
+
for (const t2 of texts) {
|
|
39001
|
+
for (const line2 of t2.split("\n")) {
|
|
38817
39002
|
if (declaresSymbol(line2, symbol, py)) {
|
|
38818
39003
|
declared = true;
|
|
38819
39004
|
continue;
|
|
@@ -38860,9 +39045,9 @@ function extractSymbolBody(source2, symbol, file, range) {
|
|
|
38860
39045
|
}
|
|
38861
39046
|
return null;
|
|
38862
39047
|
}
|
|
38863
|
-
function significantLines(
|
|
39048
|
+
function significantLines(text3) {
|
|
38864
39049
|
const out2 = [];
|
|
38865
|
-
for (const raw of
|
|
39050
|
+
for (const raw of text3.split("\n")) {
|
|
38866
39051
|
const l = raw.trim();
|
|
38867
39052
|
if (l.length < 12) continue;
|
|
38868
39053
|
if (/^(\/\/|\/\*|\*|#)/.test(l)) continue;
|
|
@@ -38875,7 +39060,7 @@ function verbatimCoverage(symbolBody, texts) {
|
|
|
38875
39060
|
const wanted = significantLines(symbolBody);
|
|
38876
39061
|
if (wanted.length === 0) return { covered: 0, total: 0, ratio: 0 };
|
|
38877
39062
|
const have = /* @__PURE__ */ new Set();
|
|
38878
|
-
for (const
|
|
39063
|
+
for (const t2 of texts) for (const l of t2.split("\n")) have.add(l.trim());
|
|
38879
39064
|
const covered = wanted.filter((l) => have.has(l)).length;
|
|
38880
39065
|
return { covered, total: wanted.length, ratio: covered / wanted.length };
|
|
38881
39066
|
}
|
|
@@ -38887,14 +39072,14 @@ function isTrackedInRoot(root, file) {
|
|
|
38887
39072
|
function buildReplayBrief(root, report, property, modelSource, readSource) {
|
|
38888
39073
|
const sources = (report.header?.abstracts ?? []).map((a) => {
|
|
38889
39074
|
const read2 = readSource ? readSource(a.file, MAX_SOURCE_BYTES) : isTrackedInRoot(root, a.file) ? readRegularFileInRoot(root, a.file, MAX_SOURCE_BYTES) : { ok: false, reason: "not tracked by git \u2014 models may only abstract tracked source" };
|
|
38890
|
-
const
|
|
39075
|
+
const text3 = read2.ok ? read2.content : "";
|
|
38891
39076
|
return {
|
|
38892
39077
|
file: a.file,
|
|
38893
39078
|
symbol: a.symbol,
|
|
38894
|
-
numbered:
|
|
38895
|
-
symbolBody:
|
|
39079
|
+
numbered: text3 ? numberLines(text3) : `(could not read ${a.file}: ${read2.ok ? "" : read2.reason})`,
|
|
39080
|
+
symbolBody: text3 ? extractSymbolBody(text3, a.symbol, a.file, a.lines) : null,
|
|
38896
39081
|
lines: a.lines,
|
|
38897
|
-
content:
|
|
39082
|
+
content: text3
|
|
38898
39083
|
};
|
|
38899
39084
|
});
|
|
38900
39085
|
return { model: report.model, property, modelSource: modelSource.slice(0, MAX_MODEL_BYTES), sources };
|
|
@@ -38976,7 +39161,7 @@ function parseReplayOutput(output) {
|
|
|
38976
39161
|
let executedCalls = 0;
|
|
38977
39162
|
const shellTexts = [];
|
|
38978
39163
|
const outputTexts = [];
|
|
38979
|
-
let
|
|
39164
|
+
let text3 = null;
|
|
38980
39165
|
for (const item of output) {
|
|
38981
39166
|
if (item.type === "shell_call") {
|
|
38982
39167
|
shellCalls++;
|
|
@@ -38991,14 +39176,14 @@ function parseReplayOutput(output) {
|
|
|
38991
39176
|
if (typeof o.stderr === "string" && o.stderr) outputTexts.push(o.stderr);
|
|
38992
39177
|
}
|
|
38993
39178
|
} else if (item.type === "message" && Array.isArray(item.content)) {
|
|
38994
|
-
const
|
|
38995
|
-
if (typeof
|
|
39179
|
+
const t2 = item.content.find((c) => c.type === "output_text")?.text;
|
|
39180
|
+
if (typeof t2 === "string") text3 = t2;
|
|
38996
39181
|
}
|
|
38997
39182
|
}
|
|
38998
39183
|
let claim = null;
|
|
38999
|
-
if (
|
|
39184
|
+
if (text3) {
|
|
39000
39185
|
try {
|
|
39001
|
-
const o = JSON.parse(
|
|
39186
|
+
const o = JSON.parse(text3);
|
|
39002
39187
|
const verdict = o.verdict;
|
|
39003
39188
|
if (verdict === "reproduced" || verdict === "diverged" || verdict === "unreplayable") {
|
|
39004
39189
|
claim = {
|
|
@@ -39016,7 +39201,7 @@ function parseReplayOutput(output) {
|
|
|
39016
39201
|
var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b/g;
|
|
39017
39202
|
function printedResult(outputTexts) {
|
|
39018
39203
|
let last = null;
|
|
39019
|
-
for (const
|
|
39204
|
+
for (const t2 of outputTexts) for (const m of t2.matchAll(RESULT_LINE)) last = m[1];
|
|
39020
39205
|
return last;
|
|
39021
39206
|
}
|
|
39022
39207
|
var RESULT_MISSING = "the harness never printed REPLAY_RESULT=reproduced on its own stdout \u2014 the verdict was the model's word, not the run's";
|
|
@@ -39057,7 +39242,7 @@ function judgeReplay(brief, parsed) {
|
|
|
39057
39242
|
return { claimed, verdict: "unverified", reason: parsed.claim.reason, downgrade: RESULT_MISSING, verbatim };
|
|
39058
39243
|
}
|
|
39059
39244
|
const copied = copiedLines(brief);
|
|
39060
|
-
if (claimed === "reproduced" && !texts.some((
|
|
39245
|
+
if (claimed === "reproduced" && !texts.some((t2) => t2.split("\n").some((l) => !copied.has(l.trim()) && l.includes("diverged")))) {
|
|
39061
39246
|
return { claimed, verdict: "unverified", reason: parsed.claim.reason, downgrade: FIXED_VERDICT, verbatim };
|
|
39062
39247
|
}
|
|
39063
39248
|
if (claimed === "reproduced" && primary && harnessInvokes(texts, primary.symbol, /\.py$/.test(primary.file), copied) === false) {
|
|
@@ -39418,10 +39603,10 @@ function semanticFingerprint(numbered2) {
|
|
|
39418
39603
|
const kept = [];
|
|
39419
39604
|
for (const raw of numbered2.split("\n")) {
|
|
39420
39605
|
const line2 = raw.replace(/^\s*\d+\| ?/, "");
|
|
39421
|
-
const
|
|
39422
|
-
if (!
|
|
39423
|
-
if (LOG_LINE.test(
|
|
39424
|
-
kept.push(
|
|
39606
|
+
const t2 = line2.trim();
|
|
39607
|
+
if (!t2 || t2.startsWith("//") || t2.startsWith("#") || t2.startsWith("*") || t2.startsWith("/*")) continue;
|
|
39608
|
+
if (LOG_LINE.test(t2)) continue;
|
|
39609
|
+
kept.push(t2.replace(/\s+/g, " "));
|
|
39425
39610
|
}
|
|
39426
39611
|
return (0, import_node_crypto19.createHash)("sha256").update(kept.join("\n")).digest("hex");
|
|
39427
39612
|
}
|
|
@@ -40311,7 +40496,7 @@ var MAX_TURNS2 = 14;
|
|
|
40311
40496
|
var VERDICTS = ["REAL", "REAL-LOW", "PREVENTED", "ARTIFACT", "UNSURE"];
|
|
40312
40497
|
var verdictOf = (v) => typeof v === "string" && VERDICTS.includes(v) ? v : null;
|
|
40313
40498
|
var introducedOf = (v) => v === "yes" || v === "no" ? v : "unknown";
|
|
40314
|
-
var
|
|
40499
|
+
var text2 = (v, n2) => typeof v === "string" ? v.slice(0, n2) : "";
|
|
40315
40500
|
function verifyPost(auth3) {
|
|
40316
40501
|
return async (body2, timeoutMs) => {
|
|
40317
40502
|
const res = await apiRequest({
|
|
@@ -40367,8 +40552,8 @@ async function verifyFinding(input, opts) {
|
|
|
40367
40552
|
const res = await opts.post({ ...body2, remaining_ms: remaining() }, Math.max(1, remaining()));
|
|
40368
40553
|
if (!res.ok) return end("failed", { error: res.error.slice(0, 200) });
|
|
40369
40554
|
const d = res.data;
|
|
40370
|
-
if (d.enabled === false) return end("disabled", { error:
|
|
40371
|
-
if (d.error && typeof d.error === "object") return end("failed", { error:
|
|
40555
|
+
if (d.enabled === false) return end("disabled", { error: text2(d.reason, 60) });
|
|
40556
|
+
if (d.error && typeof d.error === "object") return end("failed", { error: text2(d.error.code, 60) || "SERVICE_ERROR" });
|
|
40372
40557
|
rounds = typeof d.round === "number" && Number.isInteger(d.round) && d.round >= 0 ? d.round : rounds + 1;
|
|
40373
40558
|
if (typeof d.cost_usd === "number") {
|
|
40374
40559
|
if (!Number.isFinite(d.cost_usd) || d.cost_usd < 0) return end("failed", { error: "invalid cost" });
|
|
@@ -40376,17 +40561,17 @@ async function verifyFinding(input, opts) {
|
|
|
40376
40561
|
} else unpriced++;
|
|
40377
40562
|
if (d.done) {
|
|
40378
40563
|
const a = d.answer;
|
|
40379
|
-
if (!a) return end("failed", { error:
|
|
40564
|
+
if (!a) return end("failed", { error: text2(d.error, 60) || "no verdict" });
|
|
40380
40565
|
const verdict = verdictOf(a.verdict);
|
|
40381
40566
|
if (!verdict) return end("failed", { error: "unknown verdict" });
|
|
40382
40567
|
return end("answered", {
|
|
40383
40568
|
verdict,
|
|
40384
40569
|
claimed: verdictOf(a.claimed),
|
|
40385
40570
|
introduced: introducedOf(a.introduced),
|
|
40386
|
-
trigger:
|
|
40571
|
+
trigger: text2(a.trigger, 400),
|
|
40387
40572
|
preventedBy: typeof a.prevented_by === "string" ? a.prevented_by.slice(0, 600) : null,
|
|
40388
|
-
effect:
|
|
40389
|
-
reason:
|
|
40573
|
+
effect: text2(a.effect, 600),
|
|
40574
|
+
reason: text2(a.reason, 2e3),
|
|
40390
40575
|
quotes: (Array.isArray(a.quotes) ? a.quotes : []).slice(0, 12).flatMap((q) => {
|
|
40391
40576
|
const o = q ?? {};
|
|
40392
40577
|
return typeof o.path === "string" && typeof o.text === "string" ? [{ path: o.path.slice(0, 400), text: o.text.slice(0, 600), witnessed: o.witnessed === true }] : [];
|
|
@@ -40668,17 +40853,17 @@ function parsePrIntent(command) {
|
|
|
40668
40853
|
}
|
|
40669
40854
|
var TRIVIAL_INTENT = /^(wip|tmp|temp|test|fix|chore|amend|\.+|fixup!.*|squash!.*|merge\b.*)$/i;
|
|
40670
40855
|
var SHELL_PLUMBING = /\$\(|`|<<-?\s*['"]?[A-Za-z_]/;
|
|
40671
|
-
function isSubstantiveIntent(
|
|
40672
|
-
if (!
|
|
40673
|
-
const
|
|
40674
|
-
if (
|
|
40675
|
-
if (TRIVIAL_INTENT.test(
|
|
40676
|
-
if (SHELL_PLUMBING.test(
|
|
40856
|
+
function isSubstantiveIntent(text3) {
|
|
40857
|
+
if (!text3) return false;
|
|
40858
|
+
const t2 = text3.trim();
|
|
40859
|
+
if (t2.length < 12) return false;
|
|
40860
|
+
if (TRIVIAL_INTENT.test(t2)) return false;
|
|
40861
|
+
if (SHELL_PLUMBING.test(t2)) return false;
|
|
40677
40862
|
return true;
|
|
40678
40863
|
}
|
|
40679
40864
|
function extractStatedIntent(moment, command, pushedMessages = null) {
|
|
40680
|
-
const
|
|
40681
|
-
return isSubstantiveIntent(
|
|
40865
|
+
const text3 = moment === "pre-commit" ? parseCommitMessage(command) : parsePrIntent(command) ?? pushedMessages;
|
|
40866
|
+
return isSubstantiveIntent(text3) ? text3 : null;
|
|
40682
40867
|
}
|
|
40683
40868
|
function hasBlockingFinding(response, sentFiles) {
|
|
40684
40869
|
return ofThisChange(response, sentFiles).some((f) => SERIOUS.has(String(f.severity ?? "").toLowerCase()));
|
|
@@ -41101,7 +41286,7 @@ async function runGuard(opts, globals) {
|
|
|
41101
41286
|
properties: formalOutcome.properties?.map((p) => `${p.id}:${p.result}`) ?? [],
|
|
41102
41287
|
findings: formalOutcome.findings.map((f) => `${f.property}:${f.verdict}`),
|
|
41103
41288
|
// Review effort "max" models more than one function: each one, and why the search stopped early.
|
|
41104
|
-
targets: (formalOutcome.targets ?? []).map((
|
|
41289
|
+
targets: (formalOutcome.targets ?? []).map((t2) => `${t2.file}#${t2.symbol}:${t2.status}${t2.skip ? `(${t2.skip})` : ""}`),
|
|
41105
41290
|
stopped_at: formalOutcome.stoppedAt?.skip ?? null,
|
|
41106
41291
|
// Decision 81: what each property rests on (a rule, or "line"), what was
|
|
41107
41292
|
// sent back or dropped as ungrounded, and which counterexamples lack their
|
|
@@ -41604,10 +41789,10 @@ var utcDay2 = (d) => d.toISOString().slice(0, 10);
|
|
|
41604
41789
|
var DAY_MS2 = 864e5;
|
|
41605
41790
|
function plausibleDay(day, now) {
|
|
41606
41791
|
if (!DAY.test(day)) return false;
|
|
41607
|
-
const
|
|
41608
|
-
if (Number.isNaN(
|
|
41792
|
+
const t2 = Date.parse(`${day}T00:00:00Z`);
|
|
41793
|
+
if (Number.isNaN(t2) || new Date(t2).toISOString().slice(0, 10) !== day) return false;
|
|
41609
41794
|
const today2 = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
41610
|
-
return
|
|
41795
|
+
return t2 >= today2 - MAX_RUN_AGE_DAYS * DAY_MS2 && t2 <= today2 + DAY_MS2;
|
|
41611
41796
|
}
|
|
41612
41797
|
function readPending(now) {
|
|
41613
41798
|
try {
|
|
@@ -41761,21 +41946,21 @@ var PALETTE = {
|
|
|
41761
41946
|
glow: [220, 255, 240],
|
|
41762
41947
|
text: [235, 238, 240]
|
|
41763
41948
|
};
|
|
41764
|
-
function styles(
|
|
41765
|
-
const fg = (c, basic) => !
|
|
41949
|
+
function styles(t2) {
|
|
41950
|
+
const fg = (c, basic) => !t2.color ? "" : t2.truecolor ? `\x1B[38;2;${c.join(";")}m` : basic;
|
|
41766
41951
|
return {
|
|
41767
|
-
reset:
|
|
41768
|
-
bold:
|
|
41952
|
+
reset: t2.color ? "\x1B[0m" : "",
|
|
41953
|
+
bold: t2.color ? "\x1B[1m" : "",
|
|
41769
41954
|
green: fg(PALETTE.green, "\x1B[32m"),
|
|
41770
41955
|
teal: fg(PALETTE.teal, "\x1B[36m"),
|
|
41771
41956
|
gray: fg(PALETTE.gray, "\x1B[90m"),
|
|
41772
41957
|
faint: fg(PALETTE.faint, "\x1B[90m"),
|
|
41773
|
-
yellow:
|
|
41774
|
-
rgb: (c) =>
|
|
41958
|
+
yellow: t2.color ? "\x1B[33m" : "",
|
|
41959
|
+
rgb: (c) => t2.truecolor ? `\x1B[38;2;${c.join(";")}m` : ""
|
|
41775
41960
|
};
|
|
41776
41961
|
}
|
|
41777
|
-
var mix = (a, b,
|
|
41778
|
-
var ease = (
|
|
41962
|
+
var mix = (a, b, t2) => [0, 1, 2].map((i2) => Math.round(a[i2] + (b[i2] - a[i2]) * t2));
|
|
41963
|
+
var ease = (t2) => 1 - Math.pow(1 - t2, 3);
|
|
41779
41964
|
var ANSI = /\x1b\[[0-9;?]*[A-Za-z]/g;
|
|
41780
41965
|
function visibleWidth(s) {
|
|
41781
41966
|
return [...s.replace(ANSI, "")].length;
|
|
@@ -41796,8 +41981,8 @@ function fitLine(s, width) {
|
|
|
41796
41981
|
}
|
|
41797
41982
|
return out2 + "\u2026" + (s.includes("\x1B[") ? "\x1B[0m" : "");
|
|
41798
41983
|
}
|
|
41799
|
-
function wrapText(
|
|
41800
|
-
const words =
|
|
41984
|
+
function wrapText(text3, width, hang = "") {
|
|
41985
|
+
const words = text3.split(/\s+/).filter(Boolean);
|
|
41801
41986
|
if (words.length === 0) return [""];
|
|
41802
41987
|
const indent = visibleWidth(hang) < width - 1 ? hang : "";
|
|
41803
41988
|
const lines = [];
|
|
@@ -41854,12 +42039,12 @@ var Screen = class {
|
|
|
41854
42039
|
this.term = term;
|
|
41855
42040
|
this.s = styles(term);
|
|
41856
42041
|
}
|
|
41857
|
-
write(
|
|
41858
|
-
this.term.out.write(
|
|
42042
|
+
write(text3) {
|
|
42043
|
+
this.term.out.write(text3);
|
|
41859
42044
|
}
|
|
41860
42045
|
/** One frame: one write, inside a synchronized update when motion is on. */
|
|
41861
|
-
frame(
|
|
41862
|
-
this.write(this.term.motion ? SYNC_ON +
|
|
42046
|
+
frame(text3) {
|
|
42047
|
+
this.write(this.term.motion ? SYNC_ON + text3 + SYNC_OFF : text3);
|
|
41863
42048
|
}
|
|
41864
42049
|
hideCursor() {
|
|
41865
42050
|
if (!this.term.screen || this.hidden) return;
|
|
@@ -41976,8 +42161,8 @@ var Screen = class {
|
|
|
41976
42161
|
this.hideCursor();
|
|
41977
42162
|
const start2 = Date.now();
|
|
41978
42163
|
const draw = () => {
|
|
41979
|
-
const
|
|
41980
|
-
const dot = this.term.truecolor ? `${this.s.rgb(mix(PALETTE.faint, PALETTE.green,
|
|
42164
|
+
const t2 = (Math.sin((Date.now() - start2) / 1400 * Math.PI * 2 - Math.PI / 2) + 1) / 2;
|
|
42165
|
+
const dot = this.term.truecolor ? `${this.s.rgb(mix(PALETTE.faint, PALETTE.green, t2))}\u25CF${this.s.reset}` : `${t2 > 0.5 ? this.s.green : this.s.faint}\u25CF${this.s.reset}`;
|
|
41981
42166
|
const line2 = `${prefix}${dot} ${label2()} ${this.s.gray}${clock(start2)}${this.s.reset}`;
|
|
41982
42167
|
this.frame(CLEAR_LINE + fitLine(line2, this.term.columns() - 1));
|
|
41983
42168
|
};
|
|
@@ -42001,9 +42186,9 @@ var Screen = class {
|
|
|
42001
42186
|
this.hideCursor();
|
|
42002
42187
|
const start2 = Date.now();
|
|
42003
42188
|
for (; ; ) {
|
|
42004
|
-
const
|
|
42005
|
-
this.frame(CLEAR_LINE + fitLine(prefix + render2(targets.map((n2) => Math.round(n2 * ease(
|
|
42006
|
-
if (
|
|
42189
|
+
const t2 = Math.min(1, (Date.now() - start2) / ms);
|
|
42190
|
+
this.frame(CLEAR_LINE + fitLine(prefix + render2(targets.map((n2) => Math.round(n2 * ease(t2)))), width));
|
|
42191
|
+
if (t2 >= 1) break;
|
|
42007
42192
|
await sleep2(30);
|
|
42008
42193
|
}
|
|
42009
42194
|
this.write("\n");
|
|
@@ -42014,17 +42199,17 @@ var sleep2 = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
|
42014
42199
|
|
|
42015
42200
|
// src/lib/ui/rail-motion.ts
|
|
42016
42201
|
async function drawLanguages(rail, input) {
|
|
42017
|
-
const
|
|
42202
|
+
const t2 = rail.screen.term;
|
|
42018
42203
|
const s = rail.screen.s;
|
|
42019
42204
|
const langs = input.map((l) => ({ name: terminalText(l.name, 40), pct: l.pct }));
|
|
42020
|
-
if (!
|
|
42205
|
+
if (!t2.screen || langs.length === 0) {
|
|
42021
42206
|
if (langs.length) rail.line(langs.map((l) => `${l.name} ${l.pct}%`).join(", "));
|
|
42022
42207
|
return;
|
|
42023
42208
|
}
|
|
42024
|
-
const width = Math.max(10, Math.min(44,
|
|
42209
|
+
const width = Math.max(10, Math.min(44, t2.columns() - 8));
|
|
42025
42210
|
const tones = [s.green, s.teal, s.gray];
|
|
42026
42211
|
const bar = (shown) => {
|
|
42027
|
-
const track =
|
|
42212
|
+
const track = t2.color ? `${s.faint}\u2501` : "\u2500";
|
|
42028
42213
|
let out2 = "";
|
|
42029
42214
|
let cell = 0;
|
|
42030
42215
|
langs.forEach((l, i2) => {
|
|
@@ -42035,7 +42220,7 @@ async function drawLanguages(rail, input) {
|
|
|
42035
42220
|
return out2 + s.reset;
|
|
42036
42221
|
};
|
|
42037
42222
|
const prefix = `${s.gray}\u2502${s.reset} `;
|
|
42038
|
-
if (
|
|
42223
|
+
if (t2.motion) {
|
|
42039
42224
|
rail.screen.hideCursor();
|
|
42040
42225
|
const start2 = Date.now();
|
|
42041
42226
|
for (; ; ) {
|
|
@@ -42053,7 +42238,7 @@ async function drawLanguages(rail, input) {
|
|
|
42053
42238
|
rail.emitLine(prefix + langs.map((l, i2) => `${tones[Math.min(i2, 2)]}\u25CF${s.reset} ${l.name} ${s.gray}${l.pct}%${s.reset}`).join(" "));
|
|
42054
42239
|
}
|
|
42055
42240
|
async function drawRules(rail, input) {
|
|
42056
|
-
const
|
|
42241
|
+
const t2 = rail.screen.term;
|
|
42057
42242
|
const s = rail.screen.s;
|
|
42058
42243
|
const w = rail.lineWidth();
|
|
42059
42244
|
const rules = input.map((r) => ({
|
|
@@ -42063,7 +42248,7 @@ async function drawRules(rail, input) {
|
|
|
42063
42248
|
basis: terminalText(r.basis, 300)
|
|
42064
42249
|
}));
|
|
42065
42250
|
for (const r of rules) {
|
|
42066
|
-
if (!
|
|
42251
|
+
if (!t2.screen) {
|
|
42067
42252
|
rail.emitLine(` - ${r.id}: ${r.description}`);
|
|
42068
42253
|
rail.emitLine(` Applies: ${r.scope} \xB7 ${r.basis}`);
|
|
42069
42254
|
continue;
|
|
@@ -42075,7 +42260,7 @@ async function drawRules(rail, input) {
|
|
|
42075
42260
|
...desc.map((d) => `${edge} ${c2}${d}${s.reset}`),
|
|
42076
42261
|
`${edge} ${c3}${r.scope} \xB7 from ${r.basis}${s.reset}`
|
|
42077
42262
|
];
|
|
42078
|
-
if (!
|
|
42263
|
+
if (!t2.motion || !t2.truecolor) {
|
|
42079
42264
|
for (const l of lines(s.green, "", s.gray)) rail.emitLine(l);
|
|
42080
42265
|
continue;
|
|
42081
42266
|
}
|
|
@@ -42123,16 +42308,16 @@ function lightRow(screen, row2, r, center) {
|
|
|
42123
42308
|
return out2 + screen.s.reset;
|
|
42124
42309
|
}
|
|
42125
42310
|
async function wordmark(screen, opts) {
|
|
42126
|
-
const
|
|
42127
|
-
if (!
|
|
42311
|
+
const t2 = screen.term;
|
|
42312
|
+
if (!t2.screen) return;
|
|
42128
42313
|
screen.write("\n");
|
|
42129
|
-
if (
|
|
42314
|
+
if (t2.columns() < 50) {
|
|
42130
42315
|
screen.write(` ${screen.s.green}Verity${screen.s.reset}
|
|
42131
42316
|
|
|
42132
42317
|
`);
|
|
42133
42318
|
return;
|
|
42134
42319
|
}
|
|
42135
|
-
if (!opts.reveal || !
|
|
42320
|
+
if (!opts.reveal || !t2.motion || !t2.truecolor) {
|
|
42136
42321
|
for (const row2 of WORDMARK) screen.write(` ${screen.s.green}${row2}${screen.s.reset}
|
|
42137
42322
|
`);
|
|
42138
42323
|
} else {
|
|
@@ -42150,7 +42335,7 @@ async function wordmark(screen, opts) {
|
|
|
42150
42335
|
}
|
|
42151
42336
|
screen.showCursor();
|
|
42152
42337
|
}
|
|
42153
|
-
if (TAGLINE.length + 2 <=
|
|
42338
|
+
if (TAGLINE.length + 2 <= t2.columns()) screen.write(` ${screen.s.gray}${TAGLINE}${screen.s.reset}
|
|
42154
42339
|
`);
|
|
42155
42340
|
screen.write("\n");
|
|
42156
42341
|
}
|
|
@@ -42230,23 +42415,23 @@ var Rail = class {
|
|
|
42230
42415
|
* yellow: something the reader must act on.
|
|
42231
42416
|
*/
|
|
42232
42417
|
line(raw, tone = "muted") {
|
|
42233
|
-
const
|
|
42418
|
+
const text3 = terminalText(raw, Number.MAX_SAFE_INTEGER);
|
|
42234
42419
|
if (!this.t.screen) {
|
|
42235
|
-
this.emit(` ${
|
|
42420
|
+
this.emit(` ${text3}`);
|
|
42236
42421
|
return;
|
|
42237
42422
|
}
|
|
42238
42423
|
const color = tone === "muted" ? this.s.gray : tone === "warn" ? this.s.yellow : "";
|
|
42239
42424
|
const reset = tone === "plain" ? "" : this.s.reset;
|
|
42240
|
-
for (const l of wrapText(
|
|
42425
|
+
for (const l of wrapText(text3, this.width() - 3)) this.emit(`${this.s.gray}\u2502${this.s.reset} ${color}${l}${reset}`);
|
|
42241
42426
|
}
|
|
42242
42427
|
/**
|
|
42243
42428
|
* A line that belongs to the NEXT step, said before it starts (where a token
|
|
42244
42429
|
* is about to go). On a screen it sits on the rail; in a log it stands alone,
|
|
42245
42430
|
* so it does not read as a detail of the step above.
|
|
42246
42431
|
*/
|
|
42247
|
-
note(
|
|
42248
|
-
if (this.t.screen) this.line(
|
|
42249
|
-
else this.emit(terminalText(
|
|
42432
|
+
note(text3) {
|
|
42433
|
+
if (this.t.screen) this.line(text3);
|
|
42434
|
+
else this.emit(terminalText(text3, Number.MAX_SAFE_INTEGER));
|
|
42250
42435
|
}
|
|
42251
42436
|
/** Key hints: Enter send v view the profile n skip (a screen only). */
|
|
42252
42437
|
keys(pairs) {
|
|
@@ -42293,8 +42478,8 @@ var Rail = class {
|
|
|
42293
42478
|
this.block++;
|
|
42294
42479
|
}
|
|
42295
42480
|
/** A finished sub-result under the active step (a screen only). */
|
|
42296
|
-
ticked(
|
|
42297
|
-
if (this.t.screen) this.emit(`${this.s.gray}\u2502${this.s.reset} ${this.s.green}\u2713${this.s.reset} ${
|
|
42481
|
+
ticked(text3) {
|
|
42482
|
+
if (this.t.screen) this.emit(`${this.s.gray}\u2502${this.s.reset} ${this.s.green}\u2713${this.s.reset} ${text3}`);
|
|
42298
42483
|
}
|
|
42299
42484
|
/** The end of the rail, and the one next step. */
|
|
42300
42485
|
end(title, next) {
|
|
@@ -42999,7 +43184,7 @@ function classifyCodacyConfig(root = repoRoot()) {
|
|
|
42999
43184
|
return "foreign";
|
|
43000
43185
|
}
|
|
43001
43186
|
const tools = typeof parsed === "object" && parsed !== null ? parsed.tools : void 0;
|
|
43002
|
-
const pointsAtVerity2 = Array.isArray(tools) && tools.some((
|
|
43187
|
+
const pointsAtVerity2 = Array.isArray(tools) && tools.some((t2) => typeof t2 === "object" && t2 !== null && t2.localConfigurationFile === VERITY_ESLINT_LOCAL_PATH);
|
|
43003
43188
|
if (!pointsAtVerity2) return "foreign";
|
|
43004
43189
|
const eslint = readRegularFileInRoot(root, VERITY_ESLINT_CONFIG_FILE, MAX_BYTES);
|
|
43005
43190
|
return eslint.ok && eslint.content.startsWith(VERITY_ESLINT_FIRST_LINE) ? "verity" : "foreign";
|
|
@@ -43272,7 +43457,7 @@ async function hooksStep(ui, ctx) {
|
|
|
43272
43457
|
// src/commands/init/standard.ts
|
|
43273
43458
|
var import_node_fs77 = require("node:fs");
|
|
43274
43459
|
var import_node_path66 = require("node:path");
|
|
43275
|
-
var
|
|
43460
|
+
var import_yaml10 = __toESM2(require_dist());
|
|
43276
43461
|
|
|
43277
43462
|
// src/lib/catalogue-client.ts
|
|
43278
43463
|
async function fetchCatalogue(opts) {
|
|
@@ -43310,7 +43495,7 @@ async function choosePacks(globals) {
|
|
|
43310
43495
|
}
|
|
43311
43496
|
}
|
|
43312
43497
|
function sayPacks(ui, plan) {
|
|
43313
|
-
ui.rail.line(terminalText(`Review packs: ${describePacks(plan.packs)}`, 400));
|
|
43498
|
+
ui.rail.line(terminalText(`Review packs: ${describePacks(plan.packs)}. What each holds: verity standard catalogue`, 400));
|
|
43314
43499
|
}
|
|
43315
43500
|
|
|
43316
43501
|
// src/commands/init/team-standard.ts
|
|
@@ -43369,11 +43554,21 @@ function sayAdopted(ui, team) {
|
|
|
43369
43554
|
}
|
|
43370
43555
|
|
|
43371
43556
|
// src/commands/init/standard.ts
|
|
43557
|
+
function usesReviewPacks() {
|
|
43558
|
+
const raw = readRepoFile(STANDARD_FILE);
|
|
43559
|
+
if (raw === null) return true;
|
|
43560
|
+
try {
|
|
43561
|
+
const content = (0, import_yaml10.parse)(raw);
|
|
43562
|
+
return Array.isArray(content?.extends);
|
|
43563
|
+
} catch {
|
|
43564
|
+
return true;
|
|
43565
|
+
}
|
|
43566
|
+
}
|
|
43372
43567
|
function hasProjectRules() {
|
|
43373
43568
|
const raw = readRepoFile(STANDARD_FILE);
|
|
43374
43569
|
if (raw === null) return true;
|
|
43375
43570
|
try {
|
|
43376
|
-
const content = (0,
|
|
43571
|
+
const content = (0, import_yaml10.parse)(raw);
|
|
43377
43572
|
const rules = content?.custom_patterns;
|
|
43378
43573
|
if (rules === void 0 || rules === null) return false;
|
|
43379
43574
|
return !Array.isArray(rules) || rules.length > 0;
|
|
@@ -43424,7 +43619,7 @@ function localStandardProblem() {
|
|
|
43424
43619
|
if (raw === null) return `${STANDARD_FILE} is a link, not a regular file, or larger than 512 KB.`;
|
|
43425
43620
|
let parsed;
|
|
43426
43621
|
try {
|
|
43427
|
-
parsed = (0,
|
|
43622
|
+
parsed = (0, import_yaml10.parse)(raw);
|
|
43428
43623
|
} catch (err2) {
|
|
43429
43624
|
return `${STANDARD_FILE} is not valid YAML: ${terminalText(err2 instanceof Error ? err2.message : String(err2), 200)}`;
|
|
43430
43625
|
}
|
|
@@ -43433,7 +43628,7 @@ function localStandardProblem() {
|
|
|
43433
43628
|
if (!valid.ok) return `${STANDARD_FILE} is not a Standard the service accepts: ${terminalText(valid.error, 200)}`;
|
|
43434
43629
|
return null;
|
|
43435
43630
|
}
|
|
43436
|
-
function
|
|
43631
|
+
function removeLocalStandard() {
|
|
43437
43632
|
const path = projectPath(STANDARD_FILE);
|
|
43438
43633
|
try {
|
|
43439
43634
|
const folder = (0, import_node_fs77.lstatSync)((0, import_node_path66.dirname)(path));
|
|
@@ -43442,6 +43637,19 @@ function removeDerivedStandard() {
|
|
|
43442
43637
|
} catch {
|
|
43443
43638
|
}
|
|
43444
43639
|
}
|
|
43640
|
+
function setLocalStandardAside(now = /* @__PURE__ */ new Date(), remove = removeLocalStandard) {
|
|
43641
|
+
const raw = readRepoFile(STANDARD_FILE);
|
|
43642
|
+
if (raw === null) return { ok: false, message: `${STANDARD_FILE} is a link, not a regular file, or larger than 512 KB, so it was not set aside.` };
|
|
43643
|
+
let path;
|
|
43644
|
+
try {
|
|
43645
|
+
path = keepStandardCopy(raw, now);
|
|
43646
|
+
} catch (err2) {
|
|
43647
|
+
return { ok: false, message: `Could not keep a copy of ${STANDARD_FILE} (${terminalText(err2 instanceof Error ? err2.message : String(err2), 200)}), so it was not set aside.` };
|
|
43648
|
+
}
|
|
43649
|
+
remove();
|
|
43650
|
+
if ((0, import_node_fs77.existsSync)(projectPath(STANDARD_FILE))) return { ok: false, message: `Could not remove ${STANDARD_FILE} after copying it to ${path}.` };
|
|
43651
|
+
return { ok: true, path };
|
|
43652
|
+
}
|
|
43445
43653
|
async function standardStep(ui, ctx) {
|
|
43446
43654
|
const { rail } = ui;
|
|
43447
43655
|
const s = ui.screen.s;
|
|
@@ -43470,7 +43678,7 @@ async function standardStep(ui, ctx) {
|
|
|
43470
43678
|
sayAdopted(ui, again);
|
|
43471
43679
|
return end({ source: "adopted", version: again.version, profile: profile2 });
|
|
43472
43680
|
}
|
|
43473
|
-
|
|
43681
|
+
removeLocalStandard();
|
|
43474
43682
|
if (again.status === "write-failed" || again.status === "unavailable") rail.line(terminalText(again.reason, 300));
|
|
43475
43683
|
return { ...leaveTeamStandard(again.status === "write-failed" ? "write-failed" : "unavailable", null), profile: profile2 };
|
|
43476
43684
|
};
|
|
@@ -43501,12 +43709,25 @@ async function standardStep(ui, ctx) {
|
|
|
43501
43709
|
rail.line(team2.status === "none" ? `There is no Standard on the service either, so reviews have no rules. Fix ${STANDARD_FILE}, or delete it, then run verity init again.` : team2.status === "unavailable" ? `The Verity service did not answer (${terminalText(team2.reason, 200)}), so no Standard is confirmed. Fix ${STANDARD_FILE}, then run verity init again.` : `No Standard on the service was looked up. Fix ${STANDARD_FILE}, or sign in, then run verity init again.`);
|
|
43502
43710
|
return end({ source: "none", version: null, profile: notAsked });
|
|
43503
43711
|
};
|
|
43712
|
+
if (ctx.standard === "new" && (0, import_node_fs77.lstatSync)(projectPath(STANDARD_FILE), { throwIfNoEntry: false })) {
|
|
43713
|
+
const aside = setLocalStandardAside();
|
|
43714
|
+
if (!aside.ok) {
|
|
43715
|
+
rail.warn("Could not set your Standard aside for a new one");
|
|
43716
|
+
rail.line(terminalText(aside.message, 300));
|
|
43717
|
+
rail.line("Your Standard is as it was. Fix the cause, or move the file yourself, then run verity init --standard new again.");
|
|
43718
|
+
return end({ source: "none", version: null, profile: notAsked });
|
|
43719
|
+
}
|
|
43720
|
+
rail.done(`Set your Standard aside ${s.gray}\xB7 a copy is in ${aside.path}${s.reset}`);
|
|
43721
|
+
}
|
|
43504
43722
|
if ((0, import_node_fs77.existsSync)(projectPath(STANDARD_FILE))) {
|
|
43505
43723
|
const problem = localStandardProblem();
|
|
43506
43724
|
if (problem !== null) return unusableHere(problem);
|
|
43507
43725
|
const sync = await pushLocalStandardIfMissing(ctx.globals);
|
|
43508
43726
|
rail.done("Kept your Standard");
|
|
43509
43727
|
rail.line(`${STANDARD_FILE} is already here, so this run leaves it as it is. Edit it there, then share the change: verity standard push`);
|
|
43728
|
+
if (!usesReviewPacks()) {
|
|
43729
|
+
rail.line("It does not use review packs. To move it to packs and keep your rules: verity standard push. To build a new one: verity init --standard new", "muted");
|
|
43730
|
+
}
|
|
43510
43731
|
if (sync.status === "pushed") {
|
|
43511
43732
|
rail.line(sync.version !== null ? `It was only on this machine. It is shared now as v${sync.version}.` : "It is only on this machine:", sync.version !== null ? "muted" : "warn");
|
|
43512
43733
|
for (const line2 of sync.lines) if (!line2.startsWith("Standard pushed")) rail.line(terminalText(line2, 600), "warn");
|
|
@@ -44191,7 +44412,7 @@ async function recordAnswers(ui, momentIds, telemetry, completed) {
|
|
|
44191
44412
|
moments: momentIds,
|
|
44192
44413
|
...telemetry ? { telemetry } : {},
|
|
44193
44414
|
// A failed run also clears an earlier stamp: "done" describes this checkout now.
|
|
44194
|
-
init: completed ? { completed_at: (/* @__PURE__ */ new Date()).toISOString(), cli_version: true ? "0.35.
|
|
44415
|
+
init: completed ? { completed_at: (/* @__PURE__ */ new Date()).toISOString(), cli_version: true ? "0.35.2" : "dev" } : void 0
|
|
44195
44416
|
});
|
|
44196
44417
|
} catch (err2) {
|
|
44197
44418
|
ui.rail.line(`Could not record the setup answers: ${terminalText(err2.message, 200)}`, "warn");
|
|
@@ -44656,13 +44877,13 @@ function registerTaskCommands(program2) {
|
|
|
44656
44877
|
return;
|
|
44657
44878
|
}
|
|
44658
44879
|
printInfo("Tasks:");
|
|
44659
|
-
for (const
|
|
44660
|
-
const status =
|
|
44880
|
+
for (const t2 of tasks) {
|
|
44881
|
+
const status = t2.status ?? "active";
|
|
44661
44882
|
const statusTag = status !== "active" ? ` [${status}]` : "";
|
|
44662
|
-
const runs =
|
|
44663
|
-
const ago =
|
|
44883
|
+
const runs = t2.run_count;
|
|
44884
|
+
const ago = t2.last_run_at ? timeAgo2(t2.last_run_at) : "";
|
|
44664
44885
|
const detail2 = runs != null ? `${runs} run${runs === 1 ? "" : "s"}${ago ? ", " + ago : ""}` : "";
|
|
44665
|
-
printInfo(` ${
|
|
44886
|
+
printInfo(` ${t2.label}${statusTag}${detail2 ? " (" + detail2 + ")" : ""}`);
|
|
44666
44887
|
}
|
|
44667
44888
|
});
|
|
44668
44889
|
task.command("close").description("Close the current task (next run starts a new task)").option("--id <taskId>", "Close a specific task by ID").action(async (opts) => {
|
|
@@ -44893,11 +45114,11 @@ function resolve8(token, treePaths) {
|
|
|
44893
45114
|
const matches = treePaths.filter((p) => p.endsWith(suffix));
|
|
44894
45115
|
return matches.length === 1 ? matches[0] : null;
|
|
44895
45116
|
}
|
|
44896
|
-
function deriveFileGlobs(
|
|
44897
|
-
if (!
|
|
45117
|
+
function deriveFileGlobs(text3, treePaths) {
|
|
45118
|
+
if (!text3 || treePaths.length === 0) return [];
|
|
44898
45119
|
const out2 = [];
|
|
44899
45120
|
const seen = /* @__PURE__ */ new Set();
|
|
44900
|
-
for (const raw of
|
|
45121
|
+
for (const raw of text3.match(PATH_TOKEN) ?? []) {
|
|
44901
45122
|
const token = clean(raw);
|
|
44902
45123
|
if (!token) continue;
|
|
44903
45124
|
const path = resolve8(token, treePaths);
|
|
@@ -44967,15 +45188,15 @@ function registerReflectCommand(program2) {
|
|
|
44967
45188
|
}
|
|
44968
45189
|
if (!taskId) {
|
|
44969
45190
|
const recent = mem.data.recent_tasks ?? [];
|
|
44970
|
-
for (const
|
|
44971
|
-
const label2 =
|
|
45191
|
+
for (const t2 of recent) {
|
|
45192
|
+
const label2 = t2.label;
|
|
44972
45193
|
if (isMetaTaskLabel(label2)) continue;
|
|
44973
|
-
const lastRunAt =
|
|
45194
|
+
const lastRunAt = t2.last_run_at;
|
|
44974
45195
|
if (lastRunAt) {
|
|
44975
45196
|
const age = Date.now() - new Date(lastRunAt).getTime();
|
|
44976
45197
|
if (Number.isFinite(age) && age > STALE_TASK_MS) continue;
|
|
44977
45198
|
}
|
|
44978
|
-
taskId =
|
|
45199
|
+
taskId = t2.id;
|
|
44979
45200
|
taskResolution = "recent";
|
|
44980
45201
|
break;
|
|
44981
45202
|
}
|
|
@@ -46114,10 +46335,10 @@ function registerLeanCommand(program2) {
|
|
|
46114
46335
|
}
|
|
46115
46336
|
|
|
46116
46337
|
// src/cli.ts
|
|
46117
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.35.
|
|
46338
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.35.2").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) => {
|
|
46118
46339
|
const isTelemetryHelper = actionCommand.name() === "headers" && actionCommand.parent?.name() === "telemetry";
|
|
46119
46340
|
if (!isTelemetryHelper) {
|
|
46120
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.35.
|
|
46341
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.35.2");
|
|
46121
46342
|
}
|
|
46122
46343
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
46123
46344
|
try {
|