@codacy/verity-cli 0.32.0-experimental.68ae2ee → 0.32.0-experimental.cc76941
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 +46 -0
- package/bin/verity.js +702 -345
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -911,18 +911,18 @@ var require_suggestSimilar = __commonJS({
|
|
|
911
911
|
}
|
|
912
912
|
return d[a.length][b.length];
|
|
913
913
|
}
|
|
914
|
-
function suggestSimilar(word,
|
|
915
|
-
if (!
|
|
916
|
-
|
|
914
|
+
function suggestSimilar(word, candidates2) {
|
|
915
|
+
if (!candidates2 || candidates2.length === 0) return "";
|
|
916
|
+
candidates2 = Array.from(new Set(candidates2));
|
|
917
917
|
const searchingOptions = word.startsWith("--");
|
|
918
918
|
if (searchingOptions) {
|
|
919
919
|
word = word.slice(2);
|
|
920
|
-
|
|
920
|
+
candidates2 = candidates2.map((candidate) => candidate.slice(2));
|
|
921
921
|
}
|
|
922
922
|
let similar = [];
|
|
923
923
|
let bestDistance = maxDistance;
|
|
924
924
|
const minSimilarity = 0.4;
|
|
925
|
-
|
|
925
|
+
candidates2.forEach((candidate) => {
|
|
926
926
|
if (candidate.length <= 1) return;
|
|
927
927
|
const distance = editDistance(word, candidate);
|
|
928
928
|
const length = Math.max(word.length, candidate.length);
|
|
@@ -6974,10 +6974,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
6974
6974
|
let offset = bm.offset;
|
|
6975
6975
|
let commentEnd = null;
|
|
6976
6976
|
for (const collItem of bm.items) {
|
|
6977
|
-
const { start, key, sep:
|
|
6977
|
+
const { start, key, sep: sep3, value } = collItem;
|
|
6978
6978
|
const keyProps = resolveProps.resolveProps(start, {
|
|
6979
6979
|
indicator: "explicit-key-ind",
|
|
6980
|
-
next: key ??
|
|
6980
|
+
next: key ?? sep3?.[0],
|
|
6981
6981
|
offset,
|
|
6982
6982
|
onError,
|
|
6983
6983
|
parentIndent: bm.indent,
|
|
@@ -6991,7 +6991,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
6991
6991
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
6992
6992
|
onError(offset, "BAD_INDENT", startColMsg);
|
|
6993
6993
|
}
|
|
6994
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
6994
|
+
if (!keyProps.anchor && !keyProps.tag && !sep3) {
|
|
6995
6995
|
commentEnd = keyProps.end;
|
|
6996
6996
|
if (keyProps.comment) {
|
|
6997
6997
|
if (map.comment)
|
|
@@ -7015,7 +7015,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
7015
7015
|
ctx.atKey = false;
|
|
7016
7016
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
7017
7017
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
7018
|
-
const valueProps = resolveProps.resolveProps(
|
|
7018
|
+
const valueProps = resolveProps.resolveProps(sep3 ?? [], {
|
|
7019
7019
|
indicator: "map-value-ind",
|
|
7020
7020
|
next: value,
|
|
7021
7021
|
offset: keyNode.range[2],
|
|
@@ -7031,7 +7031,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
7031
7031
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
7032
7032
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
7033
7033
|
}
|
|
7034
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset,
|
|
7034
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep3, null, valueProps, onError);
|
|
7035
7035
|
if (ctx.schema.compat)
|
|
7036
7036
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
7037
7037
|
offset = valueNode.range[2];
|
|
@@ -7122,7 +7122,7 @@ var require_resolve_end = __commonJS({
|
|
|
7122
7122
|
let comment = "";
|
|
7123
7123
|
if (end) {
|
|
7124
7124
|
let hasSpace = false;
|
|
7125
|
-
let
|
|
7125
|
+
let sep3 = "";
|
|
7126
7126
|
for (const token of end) {
|
|
7127
7127
|
const { source, type } = token;
|
|
7128
7128
|
switch (type) {
|
|
@@ -7136,13 +7136,13 @@ var require_resolve_end = __commonJS({
|
|
|
7136
7136
|
if (!comment)
|
|
7137
7137
|
comment = cb;
|
|
7138
7138
|
else
|
|
7139
|
-
comment +=
|
|
7140
|
-
|
|
7139
|
+
comment += sep3 + cb;
|
|
7140
|
+
sep3 = "";
|
|
7141
7141
|
break;
|
|
7142
7142
|
}
|
|
7143
7143
|
case "newline":
|
|
7144
7144
|
if (comment)
|
|
7145
|
-
|
|
7145
|
+
sep3 += source;
|
|
7146
7146
|
hasSpace = true;
|
|
7147
7147
|
break;
|
|
7148
7148
|
default:
|
|
@@ -7185,18 +7185,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
7185
7185
|
let offset = fc.offset + fc.start.source.length;
|
|
7186
7186
|
for (let i = 0; i < fc.items.length; ++i) {
|
|
7187
7187
|
const collItem = fc.items[i];
|
|
7188
|
-
const { start, key, sep:
|
|
7188
|
+
const { start, key, sep: sep3, value } = collItem;
|
|
7189
7189
|
const props = resolveProps.resolveProps(start, {
|
|
7190
7190
|
flow: fcName,
|
|
7191
7191
|
indicator: "explicit-key-ind",
|
|
7192
|
-
next: key ??
|
|
7192
|
+
next: key ?? sep3?.[0],
|
|
7193
7193
|
offset,
|
|
7194
7194
|
onError,
|
|
7195
7195
|
parentIndent: fc.indent,
|
|
7196
7196
|
startOnNewline: false
|
|
7197
7197
|
});
|
|
7198
7198
|
if (!props.found) {
|
|
7199
|
-
if (!props.anchor && !props.tag && !
|
|
7199
|
+
if (!props.anchor && !props.tag && !sep3 && !value) {
|
|
7200
7200
|
if (i === 0 && props.comma)
|
|
7201
7201
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
7202
7202
|
else if (i < fc.items.length - 1)
|
|
@@ -7250,8 +7250,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
7250
7250
|
}
|
|
7251
7251
|
}
|
|
7252
7252
|
}
|
|
7253
|
-
if (!isMap && !
|
|
7254
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
7253
|
+
if (!isMap && !sep3 && !props.found) {
|
|
7254
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep3, null, props, onError);
|
|
7255
7255
|
coll.items.push(valueNode);
|
|
7256
7256
|
offset = valueNode.range[2];
|
|
7257
7257
|
if (isBlock(value))
|
|
@@ -7263,7 +7263,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
7263
7263
|
if (isBlock(key))
|
|
7264
7264
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
7265
7265
|
ctx.atKey = false;
|
|
7266
|
-
const valueProps = resolveProps.resolveProps(
|
|
7266
|
+
const valueProps = resolveProps.resolveProps(sep3 ?? [], {
|
|
7267
7267
|
flow: fcName,
|
|
7268
7268
|
indicator: "map-value-ind",
|
|
7269
7269
|
next: value,
|
|
@@ -7274,8 +7274,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
7274
7274
|
});
|
|
7275
7275
|
if (valueProps.found) {
|
|
7276
7276
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
7277
|
-
if (
|
|
7278
|
-
for (const st of
|
|
7277
|
+
if (sep3)
|
|
7278
|
+
for (const st of sep3) {
|
|
7279
7279
|
if (st === valueProps.found)
|
|
7280
7280
|
break;
|
|
7281
7281
|
if (st.type === "newline") {
|
|
@@ -7292,7 +7292,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
7292
7292
|
else
|
|
7293
7293
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
7294
7294
|
}
|
|
7295
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
7295
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep3, null, valueProps, onError) : null;
|
|
7296
7296
|
if (valueNode) {
|
|
7297
7297
|
if (isBlock(value))
|
|
7298
7298
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -7472,7 +7472,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
7472
7472
|
chompStart = i + 1;
|
|
7473
7473
|
}
|
|
7474
7474
|
let value = "";
|
|
7475
|
-
let
|
|
7475
|
+
let sep3 = "";
|
|
7476
7476
|
let prevMoreIndented = false;
|
|
7477
7477
|
for (let i = 0; i < contentStart; ++i)
|
|
7478
7478
|
value += lines[i][0].slice(trimIndent) + "\n";
|
|
@@ -7489,24 +7489,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
7489
7489
|
indent = "";
|
|
7490
7490
|
}
|
|
7491
7491
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
7492
|
-
value +=
|
|
7493
|
-
|
|
7492
|
+
value += sep3 + indent.slice(trimIndent) + content;
|
|
7493
|
+
sep3 = "\n";
|
|
7494
7494
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
7495
|
-
if (
|
|
7496
|
-
|
|
7497
|
-
else if (!prevMoreIndented &&
|
|
7498
|
-
|
|
7499
|
-
value +=
|
|
7500
|
-
|
|
7495
|
+
if (sep3 === " ")
|
|
7496
|
+
sep3 = "\n";
|
|
7497
|
+
else if (!prevMoreIndented && sep3 === "\n")
|
|
7498
|
+
sep3 = "\n\n";
|
|
7499
|
+
value += sep3 + indent.slice(trimIndent) + content;
|
|
7500
|
+
sep3 = "\n";
|
|
7501
7501
|
prevMoreIndented = true;
|
|
7502
7502
|
} else if (content === "") {
|
|
7503
|
-
if (
|
|
7503
|
+
if (sep3 === "\n")
|
|
7504
7504
|
value += "\n";
|
|
7505
7505
|
else
|
|
7506
|
-
|
|
7506
|
+
sep3 = "\n";
|
|
7507
7507
|
} else {
|
|
7508
|
-
value +=
|
|
7509
|
-
|
|
7508
|
+
value += sep3 + content;
|
|
7509
|
+
sep3 = " ";
|
|
7510
7510
|
prevMoreIndented = false;
|
|
7511
7511
|
}
|
|
7512
7512
|
}
|
|
@@ -7684,25 +7684,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
7684
7684
|
if (!match)
|
|
7685
7685
|
return source;
|
|
7686
7686
|
let res = match[1];
|
|
7687
|
-
let
|
|
7687
|
+
let sep3 = " ";
|
|
7688
7688
|
let pos = first.lastIndex;
|
|
7689
7689
|
line.lastIndex = pos;
|
|
7690
7690
|
while (match = line.exec(source)) {
|
|
7691
7691
|
if (match[1] === "") {
|
|
7692
|
-
if (
|
|
7693
|
-
res +=
|
|
7692
|
+
if (sep3 === "\n")
|
|
7693
|
+
res += sep3;
|
|
7694
7694
|
else
|
|
7695
|
-
|
|
7695
|
+
sep3 = "\n";
|
|
7696
7696
|
} else {
|
|
7697
|
-
res +=
|
|
7698
|
-
|
|
7697
|
+
res += sep3 + match[1];
|
|
7698
|
+
sep3 = " ";
|
|
7699
7699
|
}
|
|
7700
7700
|
pos = line.lastIndex;
|
|
7701
7701
|
}
|
|
7702
7702
|
const last = /[ \t]*(.*)/sy;
|
|
7703
7703
|
last.lastIndex = pos;
|
|
7704
7704
|
match = last.exec(source);
|
|
7705
|
-
return res +
|
|
7705
|
+
return res + sep3 + (match?.[1] ?? "");
|
|
7706
7706
|
}
|
|
7707
7707
|
function doubleQuotedValue(source, onError) {
|
|
7708
7708
|
let res = "";
|
|
@@ -8509,14 +8509,14 @@ var require_cst_stringify = __commonJS({
|
|
|
8509
8509
|
}
|
|
8510
8510
|
}
|
|
8511
8511
|
}
|
|
8512
|
-
function stringifyItem({ start, key, sep:
|
|
8512
|
+
function stringifyItem({ start, key, sep: sep3, value }) {
|
|
8513
8513
|
let res = "";
|
|
8514
8514
|
for (const st of start)
|
|
8515
8515
|
res += st.source;
|
|
8516
8516
|
if (key)
|
|
8517
8517
|
res += stringifyToken(key);
|
|
8518
|
-
if (
|
|
8519
|
-
for (const st of
|
|
8518
|
+
if (sep3)
|
|
8519
|
+
for (const st of sep3)
|
|
8520
8520
|
res += st.source;
|
|
8521
8521
|
if (value)
|
|
8522
8522
|
res += stringifyToken(value);
|
|
@@ -9659,18 +9659,18 @@ var require_parser = __commonJS({
|
|
|
9659
9659
|
if (this.type === "map-value-ind") {
|
|
9660
9660
|
const prev = getPrevProps(this.peek(2));
|
|
9661
9661
|
const start = getFirstKeyStartProps(prev);
|
|
9662
|
-
let
|
|
9662
|
+
let sep3;
|
|
9663
9663
|
if (scalar.end) {
|
|
9664
|
-
|
|
9665
|
-
|
|
9664
|
+
sep3 = scalar.end;
|
|
9665
|
+
sep3.push(this.sourceToken);
|
|
9666
9666
|
delete scalar.end;
|
|
9667
9667
|
} else
|
|
9668
|
-
|
|
9668
|
+
sep3 = [this.sourceToken];
|
|
9669
9669
|
const map = {
|
|
9670
9670
|
type: "block-map",
|
|
9671
9671
|
offset: scalar.offset,
|
|
9672
9672
|
indent: scalar.indent,
|
|
9673
|
-
items: [{ start, key: scalar, sep:
|
|
9673
|
+
items: [{ start, key: scalar, sep: sep3 }]
|
|
9674
9674
|
};
|
|
9675
9675
|
this.onKeyLine = true;
|
|
9676
9676
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -9822,15 +9822,15 @@ var require_parser = __commonJS({
|
|
|
9822
9822
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
9823
9823
|
const start2 = getFirstKeyStartProps(it.start);
|
|
9824
9824
|
const key = it.key;
|
|
9825
|
-
const
|
|
9826
|
-
|
|
9825
|
+
const sep3 = it.sep;
|
|
9826
|
+
sep3.push(this.sourceToken);
|
|
9827
9827
|
delete it.key;
|
|
9828
9828
|
delete it.sep;
|
|
9829
9829
|
this.stack.push({
|
|
9830
9830
|
type: "block-map",
|
|
9831
9831
|
offset: this.offset,
|
|
9832
9832
|
indent: this.indent,
|
|
9833
|
-
items: [{ start: start2, key, sep:
|
|
9833
|
+
items: [{ start: start2, key, sep: sep3 }]
|
|
9834
9834
|
});
|
|
9835
9835
|
} else if (start.length > 0) {
|
|
9836
9836
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -10024,13 +10024,13 @@ var require_parser = __commonJS({
|
|
|
10024
10024
|
const prev = getPrevProps(parent);
|
|
10025
10025
|
const start = getFirstKeyStartProps(prev);
|
|
10026
10026
|
fixFlowSeqItems(fc);
|
|
10027
|
-
const
|
|
10028
|
-
|
|
10027
|
+
const sep3 = fc.end.splice(1, fc.end.length);
|
|
10028
|
+
sep3.push(this.sourceToken);
|
|
10029
10029
|
const map = {
|
|
10030
10030
|
type: "block-map",
|
|
10031
10031
|
offset: fc.offset,
|
|
10032
10032
|
indent: fc.indent,
|
|
10033
|
-
items: [{ start, key: fc, sep:
|
|
10033
|
+
items: [{ start, key: fc, sep: sep3 }]
|
|
10034
10034
|
};
|
|
10035
10035
|
this.onKeyLine = true;
|
|
10036
10036
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -11519,7 +11519,7 @@ function startSpinner(label2, opts = {}) {
|
|
|
11519
11519
|
}
|
|
11520
11520
|
|
|
11521
11521
|
// src/lib/provider-auth.ts
|
|
11522
|
-
var sleep = (ms) => new Promise((
|
|
11522
|
+
var sleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
11523
11523
|
var form = (fields) => new URLSearchParams(fields).toString();
|
|
11524
11524
|
async function githubAccountId(owner) {
|
|
11525
11525
|
try {
|
|
@@ -12735,6 +12735,7 @@ async function applyMomentSelection(moments) {
|
|
|
12735
12735
|
|
|
12736
12736
|
// src/lib/project-config.ts
|
|
12737
12737
|
var import_node_fs4 = require("node:fs");
|
|
12738
|
+
var import_node_path6 = require("node:path");
|
|
12738
12739
|
var DEFAULTS = { git_moments: [] };
|
|
12739
12740
|
function isMoment(value) {
|
|
12740
12741
|
return value === "commit" || value === "push";
|
|
@@ -12742,20 +12743,39 @@ function isMoment(value) {
|
|
|
12742
12743
|
function parseMoments(raw) {
|
|
12743
12744
|
return [...new Set(raw.split(",").map((s) => s.trim()).filter(isMoment))];
|
|
12744
12745
|
}
|
|
12745
|
-
function
|
|
12746
|
+
function readConfigFile(path) {
|
|
12746
12747
|
try {
|
|
12747
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
12748
|
-
const raw = JSON.parse((0, import_node_fs4.readFileSync)(
|
|
12748
|
+
if (!(0, import_node_fs4.existsSync)(path)) return null;
|
|
12749
|
+
const raw = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf-8"));
|
|
12749
12750
|
const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
|
|
12750
12751
|
return { git_moments: [...new Set(moments)] };
|
|
12751
12752
|
} catch {
|
|
12752
12753
|
return DEFAULTS;
|
|
12753
12754
|
}
|
|
12754
12755
|
}
|
|
12756
|
+
function candidates() {
|
|
12757
|
+
const local = projectPath(PROJECT_CONFIG_FILE);
|
|
12758
|
+
const out = [{ path: local, source: "local" }];
|
|
12759
|
+
const main = mainWorktreeRoot();
|
|
12760
|
+
if (main) {
|
|
12761
|
+
const inherited = (0, import_node_path6.join)(main, PROJECT_CONFIG_FILE);
|
|
12762
|
+
if (inherited !== local) out.push({ path: inherited, source: "main-worktree" });
|
|
12763
|
+
}
|
|
12764
|
+
return out;
|
|
12765
|
+
}
|
|
12766
|
+
function readProjectConfig() {
|
|
12767
|
+
for (const { path, source } of candidates()) {
|
|
12768
|
+
const cfg = readConfigFile(path);
|
|
12769
|
+
if (cfg) return { ...cfg, source, path };
|
|
12770
|
+
}
|
|
12771
|
+
return { ...DEFAULTS, source: "default" };
|
|
12772
|
+
}
|
|
12755
12773
|
function writeProjectConfig(patch) {
|
|
12756
|
-
const
|
|
12757
|
-
|
|
12758
|
-
|
|
12774
|
+
const { git_moments } = readProjectConfig();
|
|
12775
|
+
const next = { git_moments, ...patch };
|
|
12776
|
+
const target = projectPath(PROJECT_CONFIG_FILE);
|
|
12777
|
+
(0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(target), { recursive: true });
|
|
12778
|
+
(0, import_node_fs4.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
|
|
12759
12779
|
return next;
|
|
12760
12780
|
}
|
|
12761
12781
|
function resolveGuardMoments(explicit) {
|
|
@@ -12765,6 +12785,8 @@ function resolveGuardMoments(explicit) {
|
|
|
12765
12785
|
|
|
12766
12786
|
// src/lib/plugin-ownership.ts
|
|
12767
12787
|
var import_node_fs6 = require("node:fs");
|
|
12788
|
+
var import_node_os2 = require("node:os");
|
|
12789
|
+
var import_node_path7 = require("node:path");
|
|
12768
12790
|
|
|
12769
12791
|
// src/lib/stderr-log.ts
|
|
12770
12792
|
var import_node_fs5 = require("node:fs");
|
|
@@ -12825,10 +12847,13 @@ var MARKER_TTL_SECONDS = 24 * 60 * 60;
|
|
|
12825
12847
|
function isPluginInvocation() {
|
|
12826
12848
|
return !!process.env.VERITY_PLUGIN_ROOT;
|
|
12827
12849
|
}
|
|
12850
|
+
function markerPath() {
|
|
12851
|
+
return projectPath(PLUGIN_MARKER_FILE);
|
|
12852
|
+
}
|
|
12828
12853
|
function readMarker() {
|
|
12829
12854
|
try {
|
|
12830
|
-
if (!(0, import_node_fs6.existsSync)(
|
|
12831
|
-
const raw = JSON.parse((0, import_node_fs6.readFileSync)(
|
|
12855
|
+
if (!(0, import_node_fs6.existsSync)(markerPath())) return null;
|
|
12856
|
+
const raw = JSON.parse((0, import_node_fs6.readFileSync)(markerPath(), "utf-8"));
|
|
12832
12857
|
const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
|
|
12833
12858
|
if (!pluginRoot) return null;
|
|
12834
12859
|
return {
|
|
@@ -12845,16 +12870,75 @@ function recordPluginOwnership(sessionId) {
|
|
|
12845
12870
|
const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
|
|
12846
12871
|
if (!pluginRoot) return;
|
|
12847
12872
|
try {
|
|
12848
|
-
(0, import_node_fs6.mkdirSync)(VERITY_DIR, { recursive: true });
|
|
12873
|
+
(0, import_node_fs6.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
|
|
12849
12874
|
const marker = {
|
|
12850
12875
|
session_id: sessionId,
|
|
12851
12876
|
plugin_root: pluginRoot,
|
|
12852
12877
|
version: process.env.VERITY_PLUGIN_VERSION || null,
|
|
12853
12878
|
ts: Math.floor(Date.now() / 1e3)
|
|
12854
12879
|
};
|
|
12855
|
-
(0, import_node_fs6.writeFileSync)(
|
|
12880
|
+
(0, import_node_fs6.writeFileSync)(markerPath(), JSON.stringify(marker));
|
|
12881
|
+
} catch {
|
|
12882
|
+
}
|
|
12883
|
+
}
|
|
12884
|
+
function claudeConfigDir() {
|
|
12885
|
+
return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path7.join)((0, import_node_os2.homedir)(), ".claude");
|
|
12886
|
+
}
|
|
12887
|
+
function readJsonFile(path) {
|
|
12888
|
+
try {
|
|
12889
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf-8"));
|
|
12890
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
12891
|
+
} catch {
|
|
12892
|
+
return null;
|
|
12893
|
+
}
|
|
12894
|
+
}
|
|
12895
|
+
function enabledPluginSetting(key) {
|
|
12896
|
+
const files = [
|
|
12897
|
+
projectPath((0, import_node_path7.join)(".claude", "settings.local.json")),
|
|
12898
|
+
projectPath((0, import_node_path7.join)(".claude", "settings.json")),
|
|
12899
|
+
(0, import_node_path7.join)(claudeConfigDir(), "settings.json")
|
|
12900
|
+
];
|
|
12901
|
+
for (const file of files) {
|
|
12902
|
+
const map = readJsonFile(file)?.enabledPlugins;
|
|
12903
|
+
if (map && typeof map === "object" && key in map) {
|
|
12904
|
+
return map[key] !== false;
|
|
12905
|
+
}
|
|
12906
|
+
}
|
|
12907
|
+
return void 0;
|
|
12908
|
+
}
|
|
12909
|
+
function registrySays(pluginRoot) {
|
|
12910
|
+
const plugins = readJsonFile((0, import_node_path7.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
|
|
12911
|
+
if (!plugins || typeof plugins !== "object") return "unverified";
|
|
12912
|
+
const want = (0, import_node_path7.resolve)(pluginRoot);
|
|
12913
|
+
for (const [key, value] of Object.entries(plugins)) {
|
|
12914
|
+
for (const entry of Array.isArray(value) ? value : []) {
|
|
12915
|
+
const installPath = entry?.installPath;
|
|
12916
|
+
if (typeof installPath === "string" && (0, import_node_path7.resolve)(installPath) === want) {
|
|
12917
|
+
if (enabledPluginSetting(key) === false) return "gone";
|
|
12918
|
+
return (0, import_node_fs6.existsSync)(pluginRoot) ? "live" : "gone";
|
|
12919
|
+
}
|
|
12920
|
+
}
|
|
12921
|
+
}
|
|
12922
|
+
const managed = (0, import_node_path7.resolve)((0, import_node_path7.join)(claudeConfigDir(), "plugins", "cache"));
|
|
12923
|
+
return want === managed || want.startsWith(managed + import_node_path7.sep) ? "gone" : "unverified";
|
|
12924
|
+
}
|
|
12925
|
+
var _live = /* @__PURE__ */ new Map();
|
|
12926
|
+
function pluginLiveness(pluginRoot) {
|
|
12927
|
+
const cached2 = _live.get(pluginRoot);
|
|
12928
|
+
if (cached2 !== void 0) return cached2;
|
|
12929
|
+
const said = registrySays(pluginRoot);
|
|
12930
|
+
_live.set(pluginRoot, said);
|
|
12931
|
+
return said;
|
|
12932
|
+
}
|
|
12933
|
+
function clearStalePluginMarker() {
|
|
12934
|
+
const marker = readMarker();
|
|
12935
|
+
if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
|
|
12936
|
+
try {
|
|
12937
|
+
(0, import_node_fs6.rmSync)(markerPath(), { force: true });
|
|
12856
12938
|
} catch {
|
|
12939
|
+
return null;
|
|
12857
12940
|
}
|
|
12941
|
+
return { pluginRoot: marker.plugin_root, version: marker.version };
|
|
12858
12942
|
}
|
|
12859
12943
|
function shouldDeferToPlugin(sessionId) {
|
|
12860
12944
|
if (isPluginInvocation()) {
|
|
@@ -12863,13 +12947,24 @@ function shouldDeferToPlugin(sessionId) {
|
|
|
12863
12947
|
}
|
|
12864
12948
|
const marker = readMarker();
|
|
12865
12949
|
if (!marker) return false;
|
|
12866
|
-
|
|
12950
|
+
const liveness = pluginLiveness(marker.plugin_root);
|
|
12951
|
+
if (liveness === "gone") return false;
|
|
12867
12952
|
if (sessionId && marker.session_id) return sessionId === marker.session_id;
|
|
12953
|
+
if (liveness !== "live") {
|
|
12954
|
+
logToFileOnly(
|
|
12955
|
+
`plugin ownership: ignoring an unverified marker for ${marker.plugin_root} \u2014 no session id to match and Claude Code does not list that install.`
|
|
12956
|
+
);
|
|
12957
|
+
return false;
|
|
12958
|
+
}
|
|
12868
12959
|
return Math.floor(Date.now() / 1e3) - marker.ts < MARKER_TTL_SECONDS;
|
|
12869
12960
|
}
|
|
12870
12961
|
function pluginActiveHere() {
|
|
12962
|
+
return activePluginInstall() !== null;
|
|
12963
|
+
}
|
|
12964
|
+
function activePluginInstall() {
|
|
12871
12965
|
const marker = readMarker();
|
|
12872
|
-
|
|
12966
|
+
if (!marker || pluginLiveness(marker.plugin_root) !== "live") return null;
|
|
12967
|
+
return { pluginRoot: marker.plugin_root, version: marker.version };
|
|
12873
12968
|
}
|
|
12874
12969
|
function deferredToPlugin(command, sessionId) {
|
|
12875
12970
|
if (!shouldDeferToPlugin(sessionId)) return false;
|
|
@@ -12879,21 +12974,63 @@ function deferredToPlugin(command, sessionId) {
|
|
|
12879
12974
|
return true;
|
|
12880
12975
|
}
|
|
12881
12976
|
|
|
12977
|
+
// src/lib/hook-wiring.ts
|
|
12978
|
+
function carriesAnyVerityHook(s) {
|
|
12979
|
+
return s.stop || s.intent || s.baseline || s.compact || s.sessionEnd || s.guard;
|
|
12980
|
+
}
|
|
12981
|
+
async function resolveHookWiring() {
|
|
12982
|
+
const settings = await checkAllVerityHooks();
|
|
12983
|
+
const config = readProjectConfig();
|
|
12984
|
+
const gitMoments = { source: config.source, path: config.path };
|
|
12985
|
+
if (!pluginActiveHere()) {
|
|
12986
|
+
return { source: "settings", status: settings, settings, duplicateSettingsHooks: false, gitMoments };
|
|
12987
|
+
}
|
|
12988
|
+
const status = {
|
|
12989
|
+
stop: true,
|
|
12990
|
+
intent: true,
|
|
12991
|
+
baseline: true,
|
|
12992
|
+
compact: true,
|
|
12993
|
+
sessionEnd: true,
|
|
12994
|
+
guard: true,
|
|
12995
|
+
guardOn: config.git_moments
|
|
12996
|
+
};
|
|
12997
|
+
return {
|
|
12998
|
+
source: "plugin",
|
|
12999
|
+
status,
|
|
13000
|
+
settings,
|
|
13001
|
+
duplicateSettingsHooks: carriesAnyVerityHook(settings),
|
|
13002
|
+
gitMoments
|
|
13003
|
+
};
|
|
13004
|
+
}
|
|
13005
|
+
|
|
12882
13006
|
// src/commands/hooks.ts
|
|
12883
13007
|
var ALL_MOMENTS = ["stop", "pre-commit", "pre-push"];
|
|
12884
|
-
function
|
|
12885
|
-
const
|
|
12886
|
-
|
|
12887
|
-
|
|
13008
|
+
function parseMomentSelection(raw) {
|
|
13009
|
+
const parts = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
13010
|
+
if (parts.length === 1 && parts[0].toLowerCase() === "none") return { moments: [] };
|
|
13011
|
+
if (parts.length === 0) {
|
|
13012
|
+
return { error: `--moments was empty. Pass one or more of ${ALL_MOMENTS.join(", ")} \u2014 or "none" to gate nothing.` };
|
|
13013
|
+
}
|
|
13014
|
+
const unknown = parts.filter((p) => !ALL_MOMENTS.includes(p));
|
|
13015
|
+
if (unknown.length > 0) {
|
|
13016
|
+
return {
|
|
13017
|
+
error: `--moments: unrecognised ${unknown.length === 1 ? "moment" : "moments"} ${unknown.map((u) => `"${u}"`).join(", ")}. Valid: ${ALL_MOMENTS.join(", ")} \u2014 or "none" to gate nothing.`
|
|
13018
|
+
};
|
|
12888
13019
|
}
|
|
12889
|
-
|
|
13020
|
+
const seen = new Set(parts);
|
|
13021
|
+
return { moments: ALL_MOMENTS.filter((m) => seen.has(m)) };
|
|
12890
13022
|
}
|
|
12891
13023
|
function registerHooksCommands(program2) {
|
|
12892
13024
|
const hooks = program2.command("hooks").description("Manage Claude Code hook wiring");
|
|
12893
13025
|
hooks.command("install").description("Install Verity hooks into Claude Code settings").option("--force", "Overwrite existing Verity hooks").option("--moments <list>", "Reconcile to exactly these moments: stop,pre-commit,pre-push").action(async (opts) => {
|
|
12894
13026
|
const force = opts.force ?? false;
|
|
12895
13027
|
if (opts.moments != null) {
|
|
12896
|
-
const
|
|
13028
|
+
const parsed = parseMomentSelection(opts.moments);
|
|
13029
|
+
if ("error" in parsed) {
|
|
13030
|
+
printError(parsed.error);
|
|
13031
|
+
process.exit(1);
|
|
13032
|
+
}
|
|
13033
|
+
const moments = parsed.moments;
|
|
12897
13034
|
const gitMoments = [
|
|
12898
13035
|
...moments.includes("pre-commit") ? ["commit"] : [],
|
|
12899
13036
|
...moments.includes("pre-push") ? ["push"] : []
|
|
@@ -12954,20 +13091,22 @@ function registerHooksCommands(program2) {
|
|
|
12954
13091
|
printInfo(" SessionStart hook: verity baseline capture");
|
|
12955
13092
|
});
|
|
12956
13093
|
hooks.command("check").description("Check if Verity hooks are installed").action(async () => {
|
|
12957
|
-
const
|
|
12958
|
-
|
|
12959
|
-
|
|
13094
|
+
const wiring = await resolveHookWiring();
|
|
13095
|
+
const status = wiring.status;
|
|
13096
|
+
if (wiring.source === "plugin") {
|
|
13097
|
+
const moments = status.guardOn;
|
|
13098
|
+
const inherited = wiring.gitMoments.source === "main-worktree" && wiring.gitMoments.path ? ` (inherited from the main worktree: ${wiring.gitMoments.path})` : "";
|
|
12960
13099
|
printInfo("Wired by the Verity Claude Code plugin (not .claude/settings.json):");
|
|
12961
13100
|
printInfo(" Stop hook (verity analyze): installed");
|
|
12962
13101
|
printInfo(" Intent hook (verity intent capture): installed");
|
|
12963
13102
|
printInfo(" Baseline hook (verity baseline capture): installed");
|
|
12964
13103
|
printInfo(
|
|
12965
|
-
` Git-moment gate (verity guard): ${moments.length ? `installed [${moments.join(", ")}]` : "wired but gating nothing"}`
|
|
13104
|
+
` Git-moment gate (verity guard): ${moments.length ? `installed [${moments.join(", ")}]${inherited}` : "wired but gating nothing"}`
|
|
12966
13105
|
);
|
|
12967
13106
|
if (!moments.length) {
|
|
12968
13107
|
printInfo(' Enable it with "verity config git-moments commit,push".');
|
|
12969
13108
|
}
|
|
12970
|
-
if (
|
|
13109
|
+
if (wiring.duplicateSettingsHooks) {
|
|
12971
13110
|
printWarn(" Duplicate hooks also exist in .claude/settings.json. They stand down at run time,");
|
|
12972
13111
|
printWarn(' but remove them with "verity init --plugin-mode" so the wiring says what it does.');
|
|
12973
13112
|
}
|
|
@@ -13352,8 +13491,8 @@ function isCommandOnlyTurn(input) {
|
|
|
13352
13491
|
// src/lib/context-identity.ts
|
|
13353
13492
|
var import_node_crypto2 = require("node:crypto");
|
|
13354
13493
|
var import_node_fs8 = require("node:fs");
|
|
13355
|
-
var
|
|
13356
|
-
var
|
|
13494
|
+
var import_node_os3 = require("node:os");
|
|
13495
|
+
var import_node_path8 = require("node:path");
|
|
13357
13496
|
var SHARED_SENTINELS = /* @__PURE__ */ new Set([
|
|
13358
13497
|
"",
|
|
13359
13498
|
"-",
|
|
@@ -13407,13 +13546,13 @@ function contextIdentity(input) {
|
|
|
13407
13546
|
}
|
|
13408
13547
|
function verityHome() {
|
|
13409
13548
|
const override = process.env.VERITY_HOME;
|
|
13410
|
-
return override && override.trim() ? (0,
|
|
13549
|
+
return override && override.trim() ? (0, import_node_path8.resolve)(override) : (0, import_node_path8.join)((0, import_node_os3.homedir)(), ".verity");
|
|
13411
13550
|
}
|
|
13412
13551
|
function dossierDir(identity) {
|
|
13413
|
-
return (0,
|
|
13552
|
+
return (0, import_node_path8.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
|
|
13414
13553
|
}
|
|
13415
13554
|
function treeDir(identity) {
|
|
13416
|
-
return (0,
|
|
13555
|
+
return (0, import_node_path8.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
|
|
13417
13556
|
}
|
|
13418
13557
|
function scopeIdentity(token, sessionId) {
|
|
13419
13558
|
const t = (token ?? "").trim();
|
|
@@ -13429,7 +13568,7 @@ function sessionScopeKey(token, sessionId) {
|
|
|
13429
13568
|
// src/lib/task-context-buffer.ts
|
|
13430
13569
|
var import_promises6 = require("node:fs/promises");
|
|
13431
13570
|
var import_node_fs9 = require("node:fs");
|
|
13432
|
-
var
|
|
13571
|
+
var import_node_path9 = require("node:path");
|
|
13433
13572
|
var TASK_CONTEXT_DIR = `${VERITY_DIR}/.task-context`;
|
|
13434
13573
|
var MAX_BUFFER_BYTES = 500 * 1024;
|
|
13435
13574
|
var MAX_PROMPT_CHARS = 2e3;
|
|
@@ -13507,7 +13646,7 @@ async function cleanupTaskContextBuffers() {
|
|
|
13507
13646
|
const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
13508
13647
|
for (const file of files) {
|
|
13509
13648
|
if (!file.endsWith(".jsonl")) continue;
|
|
13510
|
-
const filePath = (0,
|
|
13649
|
+
const filePath = (0, import_node_path9.join)(TASK_CONTEXT_DIR, file);
|
|
13511
13650
|
try {
|
|
13512
13651
|
const stats = await (0, import_promises6.stat)(filePath);
|
|
13513
13652
|
if (stats.mtimeMs < cutoffMs) {
|
|
@@ -13521,7 +13660,7 @@ async function cleanupTaskContextBuffers() {
|
|
|
13521
13660
|
}
|
|
13522
13661
|
function bufferPath(taskId) {
|
|
13523
13662
|
const safe = taskId.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
13524
|
-
return (0,
|
|
13663
|
+
return (0, import_node_path9.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
|
|
13525
13664
|
}
|
|
13526
13665
|
async function appendEntry(taskId, entry) {
|
|
13527
13666
|
try {
|
|
@@ -13547,7 +13686,7 @@ async function appendEntry(taskId, entry) {
|
|
|
13547
13686
|
// src/lib/memory-retrieval.ts
|
|
13548
13687
|
var import_promises7 = require("node:fs/promises");
|
|
13549
13688
|
var import_node_fs10 = require("node:fs");
|
|
13550
|
-
var
|
|
13689
|
+
var import_node_path10 = require("node:path");
|
|
13551
13690
|
var memoryDir = () => projectPath(`${VERITY_DIR}/memory`);
|
|
13552
13691
|
var DOMAINS = ["decisions", "quality", "security", "intent", "gotchas", "patterns", "domain", "integrations"];
|
|
13553
13692
|
var DEFAULT_BUDGET_TOKENS = 2e3;
|
|
@@ -13645,14 +13784,14 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
|
|
|
13645
13784
|
const promptTokens = tokenize(promptText);
|
|
13646
13785
|
const nodes = [];
|
|
13647
13786
|
for (const domain of DOMAINS) {
|
|
13648
|
-
const domainDir = (0,
|
|
13787
|
+
const domainDir = (0, import_node_path10.join)(memoryDir(), domain);
|
|
13649
13788
|
if (!(0, import_node_fs10.existsSync)(domainDir)) continue;
|
|
13650
13789
|
try {
|
|
13651
13790
|
const files = await (0, import_promises7.readdir)(domainDir);
|
|
13652
13791
|
for (const file of files) {
|
|
13653
13792
|
if (!file.endsWith(".md")) continue;
|
|
13654
13793
|
try {
|
|
13655
|
-
const content = await (0, import_promises7.readFile)((0,
|
|
13794
|
+
const content = await (0, import_promises7.readFile)((0, import_node_path10.join)(domainDir, file), "utf-8");
|
|
13656
13795
|
const { fm, body } = parseFrontmatter(content);
|
|
13657
13796
|
if (fm.status && fm.status !== "active") continue;
|
|
13658
13797
|
nodes.push({
|
|
@@ -13712,26 +13851,26 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
|
|
|
13712
13851
|
// src/lib/memory-sync.ts
|
|
13713
13852
|
var import_promises8 = require("node:fs/promises");
|
|
13714
13853
|
var import_node_fs12 = require("node:fs");
|
|
13715
|
-
var
|
|
13854
|
+
var import_node_path12 = require("node:path");
|
|
13716
13855
|
var import_node_crypto3 = require("node:crypto");
|
|
13717
13856
|
|
|
13718
13857
|
// src/lib/safe-path.ts
|
|
13719
13858
|
var import_node_fs11 = require("node:fs");
|
|
13720
|
-
var
|
|
13859
|
+
var import_node_path11 = require("node:path");
|
|
13721
13860
|
function resolveInside(baseDir, candidate) {
|
|
13722
13861
|
if (typeof candidate !== "string" || candidate.length === 0) return null;
|
|
13723
|
-
if ((0,
|
|
13724
|
-
const baseAbs = (0,
|
|
13725
|
-
const full = (0,
|
|
13726
|
-
const baseSep = baseAbs.endsWith(
|
|
13862
|
+
if ((0, import_node_path11.isAbsolute)(candidate)) return null;
|
|
13863
|
+
const baseAbs = (0, import_node_path11.resolve)(baseDir);
|
|
13864
|
+
const full = (0, import_node_path11.resolve)(baseAbs, candidate);
|
|
13865
|
+
const baseSep = baseAbs.endsWith(import_node_path11.sep) ? baseAbs : baseAbs + import_node_path11.sep;
|
|
13727
13866
|
if (full !== baseAbs && !full.startsWith(baseSep)) return null;
|
|
13728
13867
|
try {
|
|
13729
13868
|
if ((0, import_node_fs11.existsSync)(baseAbs)) {
|
|
13730
13869
|
const realBase = (0, import_node_fs11.realpathSync)(baseAbs);
|
|
13731
|
-
const realBaseSep = realBase.endsWith(
|
|
13870
|
+
const realBaseSep = realBase.endsWith(import_node_path11.sep) ? realBase : realBase + import_node_path11.sep;
|
|
13732
13871
|
let probe = full;
|
|
13733
13872
|
while (!(0, import_node_fs11.existsSync)(probe)) {
|
|
13734
|
-
const parent = (0,
|
|
13873
|
+
const parent = (0, import_node_path11.dirname)(probe);
|
|
13735
13874
|
if (parent === probe) break;
|
|
13736
13875
|
probe = parent;
|
|
13737
13876
|
}
|
|
@@ -13812,16 +13951,16 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
|
|
|
13812
13951
|
async function ensureMemoryDir() {
|
|
13813
13952
|
await (0, import_promises8.mkdir)(memoryDir2(), { recursive: true });
|
|
13814
13953
|
for (const domain of DOMAINS2) {
|
|
13815
|
-
await (0, import_promises8.mkdir)((0,
|
|
13954
|
+
await (0, import_promises8.mkdir)((0, import_node_path12.join)(memoryDir2(), domain), { recursive: true });
|
|
13816
13955
|
}
|
|
13817
|
-
if (!(0, import_node_fs12.existsSync)((0,
|
|
13818
|
-
await (0, import_promises8.writeFile)((0,
|
|
13956
|
+
if (!(0, import_node_fs12.existsSync)((0, import_node_path12.join)(memoryDir2(), "SCHEMA.md"))) {
|
|
13957
|
+
await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
|
|
13819
13958
|
}
|
|
13820
|
-
if (!(0, import_node_fs12.existsSync)((0,
|
|
13821
|
-
await (0, import_promises8.writeFile)((0,
|
|
13959
|
+
if (!(0, import_node_fs12.existsSync)((0, import_node_path12.join)(memoryDir2(), "index.md"))) {
|
|
13960
|
+
await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
|
|
13822
13961
|
}
|
|
13823
|
-
if (!(0, import_node_fs12.existsSync)((0,
|
|
13824
|
-
await (0, import_promises8.writeFile)((0,
|
|
13962
|
+
if (!(0, import_node_fs12.existsSync)((0, import_node_path12.join)(memoryDir2(), "log.md"))) {
|
|
13963
|
+
await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
|
|
13825
13964
|
}
|
|
13826
13965
|
}
|
|
13827
13966
|
async function buildManifest() {
|
|
@@ -13830,14 +13969,14 @@ async function buildManifest() {
|
|
|
13830
13969
|
}
|
|
13831
13970
|
const nodes = [];
|
|
13832
13971
|
for (const domain of DOMAINS2) {
|
|
13833
|
-
const domainDir = (0,
|
|
13972
|
+
const domainDir = (0, import_node_path12.join)(memoryDir2(), domain);
|
|
13834
13973
|
if (!(0, import_node_fs12.existsSync)(domainDir)) continue;
|
|
13835
13974
|
try {
|
|
13836
13975
|
const files = await (0, import_promises8.readdir)(domainDir);
|
|
13837
13976
|
for (const file of files) {
|
|
13838
13977
|
if (!file.endsWith(".md")) continue;
|
|
13839
13978
|
const filePath = `${domain}/${file}`;
|
|
13840
|
-
const fullPath = (0,
|
|
13979
|
+
const fullPath = (0, import_node_path12.join)(memoryDir2(), filePath);
|
|
13841
13980
|
try {
|
|
13842
13981
|
const content = await (0, import_promises8.readFile)(fullPath, "utf-8");
|
|
13843
13982
|
const hash = (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
@@ -13850,13 +13989,13 @@ async function buildManifest() {
|
|
|
13850
13989
|
}
|
|
13851
13990
|
let indexHash = null;
|
|
13852
13991
|
try {
|
|
13853
|
-
const indexContent = await (0, import_promises8.readFile)((0,
|
|
13992
|
+
const indexContent = await (0, import_promises8.readFile)((0, import_node_path12.join)(memoryDir2(), "index.md"), "utf-8");
|
|
13854
13993
|
indexHash = `sha256:${(0, import_node_crypto3.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
|
|
13855
13994
|
} catch {
|
|
13856
13995
|
}
|
|
13857
13996
|
let logLength = 0;
|
|
13858
13997
|
try {
|
|
13859
|
-
const logContent = await (0, import_promises8.readFile)((0,
|
|
13998
|
+
const logContent = await (0, import_promises8.readFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), "utf-8");
|
|
13860
13999
|
logLength = logContent.split("\n").length;
|
|
13861
14000
|
} catch {
|
|
13862
14001
|
}
|
|
@@ -13869,13 +14008,13 @@ async function readOnDiskNodes() {
|
|
|
13869
14008
|
const out = /* @__PURE__ */ new Map();
|
|
13870
14009
|
if (!(0, import_node_fs12.existsSync)(memoryDir2())) return out;
|
|
13871
14010
|
for (const domain of DOMAINS2) {
|
|
13872
|
-
const domainDir = (0,
|
|
14011
|
+
const domainDir = (0, import_node_path12.join)(memoryDir2(), domain);
|
|
13873
14012
|
if (!(0, import_node_fs12.existsSync)(domainDir)) continue;
|
|
13874
14013
|
try {
|
|
13875
14014
|
for (const file of await (0, import_promises8.readdir)(domainDir)) {
|
|
13876
14015
|
if (!file.endsWith(".md")) continue;
|
|
13877
14016
|
try {
|
|
13878
|
-
out.set(`${domain}/${file}`, hashContent(await (0, import_promises8.readFile)((0,
|
|
14017
|
+
out.set(`${domain}/${file}`, hashContent(await (0, import_promises8.readFile)((0, import_node_path12.join)(domainDir, file), "utf-8")));
|
|
13879
14018
|
} catch {
|
|
13880
14019
|
}
|
|
13881
14020
|
}
|
|
@@ -13921,7 +14060,7 @@ async function computeEditedNodeUploads() {
|
|
|
13921
14060
|
const uploads = [];
|
|
13922
14061
|
for (const [path, prevHash] of prev) {
|
|
13923
14062
|
if (prevHash == null) continue;
|
|
13924
|
-
const full = (0,
|
|
14063
|
+
const full = (0, import_node_path12.join)(memoryDir2(), path);
|
|
13925
14064
|
if (!(0, import_node_fs12.existsSync)(full)) continue;
|
|
13926
14065
|
let content;
|
|
13927
14066
|
try {
|
|
@@ -13958,8 +14097,8 @@ async function applyMemoryWrites(writes, opts = {}) {
|
|
|
13958
14097
|
const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
|
|
13959
14098
|
for (const n of notes) logLines.push(` - ${n}`);
|
|
13960
14099
|
try {
|
|
13961
|
-
const existing = (0, import_node_fs12.existsSync)((0,
|
|
13962
|
-
await (0, import_promises8.writeFile)((0,
|
|
14100
|
+
const existing = (0, import_node_fs12.existsSync)((0, import_node_path12.join)(memoryDir2(), "log.md")) ? await (0, import_promises8.readFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
|
|
14101
|
+
await (0, import_promises8.writeFile)((0, import_node_path12.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
|
|
13963
14102
|
} catch {
|
|
13964
14103
|
}
|
|
13965
14104
|
await recordSyncedNodePaths();
|
|
@@ -13991,7 +14130,7 @@ async function applyOneWrite(write, treePaths) {
|
|
|
13991
14130
|
return { written: false, notes };
|
|
13992
14131
|
}
|
|
13993
14132
|
}
|
|
13994
|
-
await (0, import_promises8.mkdir)((0,
|
|
14133
|
+
await (0, import_promises8.mkdir)((0, import_node_path12.dirname)(fullPath), { recursive: true });
|
|
13995
14134
|
await (0, import_promises8.writeFile)(fullPath, content);
|
|
13996
14135
|
return { written: true, notes };
|
|
13997
14136
|
}
|
|
@@ -14032,7 +14171,7 @@ async function regenerateIndex() {
|
|
|
14032
14171
|
];
|
|
14033
14172
|
let totalNodes = 0;
|
|
14034
14173
|
for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
|
|
14035
|
-
const domainDir = (0,
|
|
14174
|
+
const domainDir = (0, import_node_path12.join)(memoryDir2(), domain);
|
|
14036
14175
|
if (!(0, import_node_fs12.existsSync)(domainDir)) continue;
|
|
14037
14176
|
try {
|
|
14038
14177
|
const files = await (0, import_promises8.readdir)(domainDir);
|
|
@@ -14043,7 +14182,7 @@ async function regenerateIndex() {
|
|
|
14043
14182
|
for (const file of mdFiles.sort()) {
|
|
14044
14183
|
const slug = file.replace(/\.md$/, "");
|
|
14045
14184
|
try {
|
|
14046
|
-
const content = await (0, import_promises8.readFile)((0,
|
|
14185
|
+
const content = await (0, import_promises8.readFile)((0, import_node_path12.join)(domainDir, file), "utf-8");
|
|
14047
14186
|
const title = pickFrontmatter(content, "title") ?? slug;
|
|
14048
14187
|
const kind = pickFrontmatter(content, "kind") ?? "-";
|
|
14049
14188
|
const confidence = pickFrontmatter(content, "confidence");
|
|
@@ -14067,7 +14206,7 @@ async function regenerateIndex() {
|
|
|
14067
14206
|
lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
|
|
14068
14207
|
}
|
|
14069
14208
|
const next = lines.join("\n") + "\n";
|
|
14070
|
-
const indexPath = (0,
|
|
14209
|
+
const indexPath = (0, import_node_path12.join)(memoryDir2(), "index.md");
|
|
14071
14210
|
let existing = null;
|
|
14072
14211
|
try {
|
|
14073
14212
|
existing = await (0, import_promises8.readFile)(indexPath, "utf-8");
|
|
@@ -14301,7 +14440,7 @@ function hasLegacyMemoryBlock(text) {
|
|
|
14301
14440
|
return findMarker(text, LEGACY_MD_START) !== -1;
|
|
14302
14441
|
}
|
|
14303
14442
|
async function ensureClaudeMdPointer(cwd = repoRoot()) {
|
|
14304
|
-
const claudeMdPath = (0,
|
|
14443
|
+
const claudeMdPath = (0, import_node_path12.join)(cwd, "CLAUDE.md");
|
|
14305
14444
|
let existing = "";
|
|
14306
14445
|
if ((0, import_node_fs12.existsSync)(claudeMdPath)) {
|
|
14307
14446
|
existing = await (0, import_promises8.readFile)(claudeMdPath, "utf-8");
|
|
@@ -14441,7 +14580,7 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
|
|
|
14441
14580
|
// src/lib/dossier-session.ts
|
|
14442
14581
|
var import_node_fs17 = require("node:fs");
|
|
14443
14582
|
var import_node_crypto7 = require("node:crypto");
|
|
14444
|
-
var
|
|
14583
|
+
var import_node_path15 = require("node:path");
|
|
14445
14584
|
|
|
14446
14585
|
// src/lib/pending-repeat.ts
|
|
14447
14586
|
var STOP = /* @__PURE__ */ new Set([
|
|
@@ -14547,7 +14686,7 @@ function statementAnchorKey(file, patternId) {
|
|
|
14547
14686
|
// src/lib/dossier/log.ts
|
|
14548
14687
|
var import_node_crypto4 = require("node:crypto");
|
|
14549
14688
|
var import_node_fs13 = require("node:fs");
|
|
14550
|
-
var
|
|
14689
|
+
var import_node_path13 = require("node:path");
|
|
14551
14690
|
var CRC_TABLE = (() => {
|
|
14552
14691
|
const t = new Int32Array(256);
|
|
14553
14692
|
for (let i = 0; i < 256; i++) {
|
|
@@ -14570,9 +14709,9 @@ function openDossier(identity) {
|
|
|
14570
14709
|
return {
|
|
14571
14710
|
dir,
|
|
14572
14711
|
identity,
|
|
14573
|
-
eventsPath: (0,
|
|
14574
|
-
foldPath: (0,
|
|
14575
|
-
rotatedDir: (0,
|
|
14712
|
+
eventsPath: (0, import_node_path13.join)(dir, "events.jsonl"),
|
|
14713
|
+
foldPath: (0, import_node_path13.join)(dir, "fold.json"),
|
|
14714
|
+
rotatedDir: (0, import_node_path13.join)(dir, "rotated")
|
|
14576
14715
|
};
|
|
14577
14716
|
} catch {
|
|
14578
14717
|
return null;
|
|
@@ -14645,11 +14784,11 @@ function rotateIfNeeded2(d) {
|
|
|
14645
14784
|
if (!(0, import_node_fs13.existsSync)(d.eventsPath)) return;
|
|
14646
14785
|
if ((0, import_node_fs13.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
|
|
14647
14786
|
(0, import_node_fs13.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
|
|
14648
|
-
(0, import_node_fs13.renameSync)(d.eventsPath, (0,
|
|
14787
|
+
(0, import_node_fs13.renameSync)(d.eventsPath, (0, import_node_path13.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
|
|
14649
14788
|
const kept = (0, import_node_fs13.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
|
|
14650
14789
|
for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
|
|
14651
14790
|
try {
|
|
14652
|
-
(0, import_node_fs13.renameSync)((0,
|
|
14791
|
+
(0, import_node_fs13.renameSync)((0, import_node_path13.join)(d.rotatedDir, stale), (0, import_node_path13.join)(d.rotatedDir, `${stale}.pruned`));
|
|
14653
14792
|
} catch {
|
|
14654
14793
|
}
|
|
14655
14794
|
}
|
|
@@ -14660,7 +14799,7 @@ function rotateIfNeeded2(d) {
|
|
|
14660
14799
|
// src/lib/dossier/fold-dossier.ts
|
|
14661
14800
|
var import_node_crypto5 = require("node:crypto");
|
|
14662
14801
|
var import_node_fs14 = require("node:fs");
|
|
14663
|
-
var
|
|
14802
|
+
var import_node_path14 = require("node:path");
|
|
14664
14803
|
var EMPTY_CAPABILITIES = () => ({
|
|
14665
14804
|
human_reachable: { value: "unknown", tier: "unknown" },
|
|
14666
14805
|
authorship_observability: { value: "unknown", tier: "unknown" },
|
|
@@ -14716,7 +14855,7 @@ function foldDossier(d, opts = {}) {
|
|
|
14716
14855
|
state.meta.rotations = files.length;
|
|
14717
14856
|
for (const f of files) {
|
|
14718
14857
|
try {
|
|
14719
|
-
ingest((0, import_node_fs14.readFileSync)((0,
|
|
14858
|
+
ingest((0, import_node_fs14.readFileSync)((0, import_node_path14.join)(d.rotatedDir, f), "utf8"));
|
|
14720
14859
|
} catch {
|
|
14721
14860
|
state.meta.dropped_lines++;
|
|
14722
14861
|
}
|
|
@@ -15573,16 +15712,16 @@ function foreignAuthoredPaths(identity, opts = {}) {
|
|
|
15573
15712
|
for (const entry of (0, import_node_fs17.readdirSync)(dir, { withFileTypes: true })) {
|
|
15574
15713
|
if (!entry.isDirectory()) continue;
|
|
15575
15714
|
if (entry.name === identity.sessionKey) continue;
|
|
15576
|
-
const log = (0,
|
|
15715
|
+
const log = (0, import_node_path15.join)(dir, entry.name, "events.jsonl");
|
|
15577
15716
|
try {
|
|
15578
15717
|
if (!(0, import_node_fs17.existsSync)(log)) continue;
|
|
15579
15718
|
if (now - (0, import_node_fs17.statSync)(log).mtimeMs > windowMs) continue;
|
|
15580
15719
|
const sib = {
|
|
15581
|
-
dir: (0,
|
|
15720
|
+
dir: (0, import_node_path15.join)(dir, entry.name),
|
|
15582
15721
|
identity,
|
|
15583
15722
|
eventsPath: log,
|
|
15584
|
-
foldPath: (0,
|
|
15585
|
-
rotatedDir: (0,
|
|
15723
|
+
foldPath: (0, import_node_path15.join)(dir, entry.name, "fold.json"),
|
|
15724
|
+
rotatedDir: (0, import_node_path15.join)(dir, entry.name, "rotated")
|
|
15586
15725
|
};
|
|
15587
15726
|
const state = readFoldCache(sib) ?? foldDossier(sib);
|
|
15588
15727
|
sessions++;
|
|
@@ -15610,22 +15749,22 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
|
|
|
15610
15749
|
let removed = 0;
|
|
15611
15750
|
try {
|
|
15612
15751
|
const mine = dossierDir(identity);
|
|
15613
|
-
const userDir = (0,
|
|
15752
|
+
const userDir = (0, import_node_path15.dirname)((0, import_node_path15.dirname)(mine));
|
|
15614
15753
|
if (!(0, import_node_fs17.existsSync)(userDir)) return 0;
|
|
15615
15754
|
const cutoff = Date.now() - maxAgeMs;
|
|
15616
15755
|
for (const tree of (0, import_node_fs17.readdirSync)(userDir, { withFileTypes: true })) {
|
|
15617
15756
|
if (!tree.isDirectory()) continue;
|
|
15618
|
-
const treePath = (0,
|
|
15757
|
+
const treePath = (0, import_node_path15.join)(userDir, tree.name);
|
|
15619
15758
|
let live = 0;
|
|
15620
15759
|
for (const entry of (0, import_node_fs17.readdirSync)(treePath, { withFileTypes: true })) {
|
|
15621
15760
|
if (!entry.isDirectory()) continue;
|
|
15622
|
-
const dir = (0,
|
|
15761
|
+
const dir = (0, import_node_path15.join)(treePath, entry.name);
|
|
15623
15762
|
if (dir === mine) {
|
|
15624
15763
|
live++;
|
|
15625
15764
|
continue;
|
|
15626
15765
|
}
|
|
15627
15766
|
try {
|
|
15628
|
-
const log = (0,
|
|
15767
|
+
const log = (0, import_node_path15.join)(dir, "events.jsonl");
|
|
15629
15768
|
const at = (0, import_node_fs17.existsSync)(log) ? (0, import_node_fs17.statSync)(log).mtimeMs : (0, import_node_fs17.statSync)(dir).mtimeMs;
|
|
15630
15769
|
if (at < cutoff) {
|
|
15631
15770
|
(0, import_node_fs17.rmSync)(dir, { recursive: true, force: true });
|
|
@@ -15680,7 +15819,7 @@ function recordTurn(d, t) {
|
|
|
15680
15819
|
for (const a of t.authored) {
|
|
15681
15820
|
const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
|
|
15682
15821
|
const prior = t.known?.authored?.get(a.p);
|
|
15683
|
-
const hash = fileHash((0,
|
|
15822
|
+
const hash = fileHash((0, import_node_path15.join)(root, a.p));
|
|
15684
15823
|
const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
|
|
15685
15824
|
const adds = Math.max(0, a.a - (prior?.adds ?? 0));
|
|
15686
15825
|
const dels = Math.max(0, a.d - (prior?.dels ?? 0));
|
|
@@ -15713,7 +15852,7 @@ function recordTurn(d, t) {
|
|
|
15713
15852
|
}
|
|
15714
15853
|
const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
|
|
15715
15854
|
for (const u of t.unobserved) {
|
|
15716
|
-
const hash = fileHash((0,
|
|
15855
|
+
const hash = fileHash((0, import_node_path15.join)(root, u.p));
|
|
15717
15856
|
if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
|
|
15718
15857
|
appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
|
|
15719
15858
|
}
|
|
@@ -15748,7 +15887,7 @@ function recordVerdict(d, v) {
|
|
|
15748
15887
|
if (!sent.has(f.file)) continue;
|
|
15749
15888
|
if (!lines.has(f.file)) {
|
|
15750
15889
|
try {
|
|
15751
|
-
const abs = (0,
|
|
15890
|
+
const abs = (0, import_node_path15.join)(root, f.file);
|
|
15752
15891
|
lines.set(f.file, (0, import_node_fs17.existsSync)(abs) ? (0, import_node_fs17.readFileSync)(abs, "utf8").split("\n") : null);
|
|
15753
15892
|
} catch {
|
|
15754
15893
|
lines.set(f.file, null);
|
|
@@ -15849,7 +15988,7 @@ function recallMemory(d, identity, opts) {
|
|
|
15849
15988
|
budgetBytes: opts.budgetBytes,
|
|
15850
15989
|
readFileLines: (file) => {
|
|
15851
15990
|
try {
|
|
15852
|
-
const abs = (0,
|
|
15991
|
+
const abs = (0, import_node_path15.join)(root, file);
|
|
15853
15992
|
return (0, import_node_fs17.existsSync)(abs) ? (0, import_node_fs17.readFileSync)(abs, "utf8").split("\n") : null;
|
|
15854
15993
|
} catch {
|
|
15855
15994
|
return null;
|
|
@@ -15995,21 +16134,21 @@ async function fireClassify(prompt, sessionId, globals) {
|
|
|
15995
16134
|
|
|
15996
16135
|
// src/commands/lifecycle.ts
|
|
15997
16136
|
var import_node_fs21 = require("node:fs");
|
|
15998
|
-
var
|
|
16137
|
+
var import_node_path19 = require("node:path");
|
|
15999
16138
|
|
|
16000
16139
|
// src/lib/baseline.ts
|
|
16001
16140
|
var import_node_fs20 = require("node:fs");
|
|
16002
|
-
var
|
|
16141
|
+
var import_node_path18 = require("node:path");
|
|
16003
16142
|
var import_node_crypto9 = require("node:crypto");
|
|
16004
16143
|
|
|
16005
16144
|
// src/lib/snapshot.ts
|
|
16006
16145
|
var import_node_fs19 = require("node:fs");
|
|
16007
|
-
var
|
|
16146
|
+
var import_node_path17 = require("node:path");
|
|
16008
16147
|
var import_node_child_process6 = require("node:child_process");
|
|
16009
16148
|
|
|
16010
16149
|
// src/lib/files.ts
|
|
16011
16150
|
var import_node_fs18 = require("node:fs");
|
|
16012
|
-
var
|
|
16151
|
+
var import_node_path16 = require("node:path");
|
|
16013
16152
|
var LANG_MAP = {
|
|
16014
16153
|
// Analyzable (static analysis + Gemini)
|
|
16015
16154
|
ts: "typescript",
|
|
@@ -16077,7 +16216,7 @@ var LANG_MAP = {
|
|
|
16077
16216
|
mk: "make"
|
|
16078
16217
|
};
|
|
16079
16218
|
function detectLanguage(filepath) {
|
|
16080
|
-
const ext = (0,
|
|
16219
|
+
const ext = (0, import_node_path16.extname)(filepath).slice(1);
|
|
16081
16220
|
return LANG_MAP[ext] ?? ext;
|
|
16082
16221
|
}
|
|
16083
16222
|
function sortByMtime(files) {
|
|
@@ -16180,7 +16319,7 @@ function generateSnapshotDiffs(files) {
|
|
|
16180
16319
|
const diffs = [];
|
|
16181
16320
|
for (const file of files) {
|
|
16182
16321
|
if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
|
|
16183
|
-
const snapshotPath = (0,
|
|
16322
|
+
const snapshotPath = (0, import_node_path17.join)(SNAPSHOT_DIR, file.path);
|
|
16184
16323
|
const language = file.language ?? detectLanguage(file.path);
|
|
16185
16324
|
if ((0, import_node_fs19.existsSync)(snapshotPath)) {
|
|
16186
16325
|
const oldContent = (0, import_node_fs19.readFileSync)(snapshotPath, "utf-8");
|
|
@@ -16208,16 +16347,16 @@ function saveSnapshots(files) {
|
|
|
16208
16347
|
const snapshotPaths = /* @__PURE__ */ new Set();
|
|
16209
16348
|
for (const file of files) {
|
|
16210
16349
|
if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
|
|
16211
|
-
const snapshotPath = (0,
|
|
16350
|
+
const snapshotPath = (0, import_node_path17.join)(SNAPSHOT_DIR, file.path);
|
|
16212
16351
|
snapshotPaths.add(snapshotPath);
|
|
16213
|
-
(0, import_node_fs19.mkdirSync)((0,
|
|
16352
|
+
(0, import_node_fs19.mkdirSync)((0, import_node_path17.dirname)(snapshotPath), { recursive: true });
|
|
16214
16353
|
(0, import_node_fs19.writeFileSync)(snapshotPath, file.content);
|
|
16215
16354
|
}
|
|
16216
16355
|
cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
|
|
16217
16356
|
}
|
|
16218
16357
|
function computeDiff(oldContent, newContent, filePath) {
|
|
16219
|
-
const tmpOld = (0,
|
|
16220
|
-
const tmpNew = (0,
|
|
16358
|
+
const tmpOld = (0, import_node_path17.join)(SNAPSHOT_DIR, ".diff-old.tmp");
|
|
16359
|
+
const tmpNew = (0, import_node_path17.join)(SNAPSHOT_DIR, ".diff-new.tmp");
|
|
16221
16360
|
try {
|
|
16222
16361
|
(0, import_node_fs19.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
|
|
16223
16362
|
(0, import_node_fs19.writeFileSync)(tmpOld, oldContent);
|
|
@@ -16250,7 +16389,7 @@ function cleanStaleSnapshots(dir, keepSet) {
|
|
|
16250
16389
|
const entries = (0, import_node_fs19.readdirSync)(dir, { withFileTypes: true });
|
|
16251
16390
|
for (const entry of entries) {
|
|
16252
16391
|
if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
|
|
16253
|
-
const fullPath = (0,
|
|
16392
|
+
const fullPath = (0, import_node_path17.join)(dir, entry.name);
|
|
16254
16393
|
if (entry.isDirectory()) {
|
|
16255
16394
|
cleanStaleSnapshots(fullPath, keepSet);
|
|
16256
16395
|
try {
|
|
@@ -16279,13 +16418,13 @@ function sessionKey(sessionId) {
|
|
|
16279
16418
|
return (0, import_node_crypto9.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
16280
16419
|
}
|
|
16281
16420
|
function sessionDir(key) {
|
|
16282
|
-
return (0,
|
|
16421
|
+
return (0, import_node_path18.join)(projectPath(BASELINE_DIR), key);
|
|
16283
16422
|
}
|
|
16284
16423
|
function manifestPath(dir) {
|
|
16285
|
-
return (0,
|
|
16424
|
+
return (0, import_node_path18.join)(dir, "manifest.json");
|
|
16286
16425
|
}
|
|
16287
16426
|
function mirrorPath(dir, repoRelPath) {
|
|
16288
|
-
return (0,
|
|
16427
|
+
return (0, import_node_path18.join)(dir, "files", repoRelPath);
|
|
16289
16428
|
}
|
|
16290
16429
|
var CARRY_FILE = `${BASELINE_DIR}/.carry`;
|
|
16291
16430
|
var CARRY_WINDOW_MS = 12e4;
|
|
@@ -16347,7 +16486,7 @@ function captureBaseline(opts = {}) {
|
|
|
16347
16486
|
(0, import_node_fs20.rmSync)(dir, { recursive: true, force: true });
|
|
16348
16487
|
} catch {
|
|
16349
16488
|
}
|
|
16350
|
-
const filesDir = (0,
|
|
16489
|
+
const filesDir = (0, import_node_path18.join)(dir, "files");
|
|
16351
16490
|
const mirrored = [];
|
|
16352
16491
|
try {
|
|
16353
16492
|
(0, import_node_fs20.mkdirSync)(filesDir, { recursive: true });
|
|
@@ -16357,7 +16496,7 @@ function captureBaseline(opts = {}) {
|
|
|
16357
16496
|
if (content === null) continue;
|
|
16358
16497
|
const dest = mirrorPath(dir, p);
|
|
16359
16498
|
try {
|
|
16360
|
-
(0, import_node_fs20.mkdirSync)((0,
|
|
16499
|
+
(0, import_node_fs20.mkdirSync)((0, import_node_path18.dirname)(dest), { recursive: true });
|
|
16361
16500
|
(0, import_node_fs20.writeFileSync)(dest, content);
|
|
16362
16501
|
mirrored.push(p);
|
|
16363
16502
|
} catch {
|
|
@@ -16465,7 +16604,7 @@ function absorbIntoBaseline(paths, sessionId) {
|
|
|
16465
16604
|
const content = safeReadForMirror(projectPath(p));
|
|
16466
16605
|
if (content === null) continue;
|
|
16467
16606
|
const dest = mirrorPath(dir, p);
|
|
16468
|
-
(0, import_node_fs20.mkdirSync)((0,
|
|
16607
|
+
(0, import_node_fs20.mkdirSync)((0, import_node_path18.dirname)(dest), { recursive: true });
|
|
16469
16608
|
(0, import_node_fs20.writeFileSync)(dest, content);
|
|
16470
16609
|
dirty.add(p);
|
|
16471
16610
|
adopted++;
|
|
@@ -16513,7 +16652,7 @@ function pruneOldBaselines() {
|
|
|
16513
16652
|
}
|
|
16514
16653
|
const now = Date.now();
|
|
16515
16654
|
for (const name of entries) {
|
|
16516
|
-
const dir = (0,
|
|
16655
|
+
const dir = (0, import_node_path18.join)(root, name);
|
|
16517
16656
|
const manifest = readManifest(dir);
|
|
16518
16657
|
if (!manifest) {
|
|
16519
16658
|
try {
|
|
@@ -16701,7 +16840,7 @@ function buildCompactionContext(session) {
|
|
|
16701
16840
|
commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
|
|
16702
16841
|
readFileLines: (file) => {
|
|
16703
16842
|
try {
|
|
16704
|
-
const abs = (0,
|
|
16843
|
+
const abs = (0, import_node_path19.join)(root, file);
|
|
16705
16844
|
return (0, import_node_fs21.existsSync)(abs) ? (0, import_node_fs21.readFileSync)(abs, "utf8").split("\n") : null;
|
|
16706
16845
|
} catch {
|
|
16707
16846
|
return null;
|
|
@@ -16738,17 +16877,17 @@ async function readHookStdin() {
|
|
|
16738
16877
|
try {
|
|
16739
16878
|
if (process.stdin.isTTY) return {};
|
|
16740
16879
|
const chunks = [];
|
|
16741
|
-
const timeout = new Promise((
|
|
16742
|
-
const read = new Promise((
|
|
16880
|
+
const timeout = new Promise((resolve5) => setTimeout(() => resolve5({}), 500));
|
|
16881
|
+
const read = new Promise((resolve5) => {
|
|
16743
16882
|
process.stdin.on("data", (c) => chunks.push(c));
|
|
16744
16883
|
process.stdin.on("end", () => {
|
|
16745
16884
|
try {
|
|
16746
|
-
|
|
16885
|
+
resolve5(JSON.parse(Buffer.concat(chunks).toString("utf-8").trim() || "{}"));
|
|
16747
16886
|
} catch {
|
|
16748
|
-
|
|
16887
|
+
resolve5({});
|
|
16749
16888
|
}
|
|
16750
16889
|
});
|
|
16751
|
-
process.stdin.on("error", () =>
|
|
16890
|
+
process.stdin.on("error", () => resolve5({}));
|
|
16752
16891
|
process.stdin.resume();
|
|
16753
16892
|
});
|
|
16754
16893
|
return await Promise.race([read, timeout]);
|
|
@@ -16766,17 +16905,17 @@ var import_yaml3 = __toESM(require_dist());
|
|
|
16766
16905
|
var import_node_child_process8 = require("node:child_process");
|
|
16767
16906
|
var import_node_fs24 = require("node:fs");
|
|
16768
16907
|
var import_promises9 = require("node:fs/promises");
|
|
16769
|
-
var
|
|
16908
|
+
var import_node_path22 = require("node:path");
|
|
16770
16909
|
var import_yaml = __toESM(require_dist());
|
|
16771
16910
|
|
|
16772
16911
|
// src/lib/data-dir.ts
|
|
16773
16912
|
var import_node_fs22 = require("node:fs");
|
|
16774
|
-
var
|
|
16913
|
+
var import_node_path20 = require("node:path");
|
|
16775
16914
|
function resolveDataDir() {
|
|
16776
|
-
const
|
|
16777
|
-
(0,
|
|
16915
|
+
const candidates2 = [
|
|
16916
|
+
(0, import_node_path20.join)(__dirname, "..", "data"),
|
|
16778
16917
|
// installed: node_modules/@codacy/verity-cli/data
|
|
16779
|
-
(0,
|
|
16918
|
+
(0, import_node_path20.join)(__dirname, "..", "..", "data"),
|
|
16780
16919
|
// edge case: nested resolution
|
|
16781
16920
|
// THE COMMITTED SOURCE, for a source checkout that has not been built.
|
|
16782
16921
|
// cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
|
|
@@ -16785,14 +16924,14 @@ function resolveDataDir() {
|
|
|
16785
16924
|
// without this the synthesizer throws "Could not find Verity skill data"
|
|
16786
16925
|
// for every test and every `verity` run from source. Resolved from this
|
|
16787
16926
|
// module's own location, never the cwd: see the warning below.
|
|
16788
|
-
(0,
|
|
16927
|
+
(0, import_node_path20.join)(__dirname, "..", "..", "client"),
|
|
16789
16928
|
// bundled: cli/bin/ → ../../client
|
|
16790
|
-
(0,
|
|
16929
|
+
(0, import_node_path20.join)(__dirname, "..", "..", "..", "client"),
|
|
16791
16930
|
// tsx: cli/src/lib/ → ../../../client
|
|
16792
16931
|
...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
|
|
16793
16932
|
];
|
|
16794
|
-
for (const candidate of
|
|
16795
|
-
if ((0, import_node_fs22.existsSync)((0,
|
|
16933
|
+
for (const candidate of candidates2) {
|
|
16934
|
+
if ((0, import_node_fs22.existsSync)((0, import_node_path20.join)(candidate, "skills"))) {
|
|
16796
16935
|
return candidate;
|
|
16797
16936
|
}
|
|
16798
16937
|
}
|
|
@@ -16801,13 +16940,13 @@ function resolveDataDir() {
|
|
|
16801
16940
|
);
|
|
16802
16941
|
}
|
|
16803
16942
|
function setupDataPath(file) {
|
|
16804
|
-
return (0,
|
|
16943
|
+
return (0, import_node_path20.join)(resolveDataDir(), "skills", "verity-setup", file);
|
|
16805
16944
|
}
|
|
16806
16945
|
|
|
16807
16946
|
// src/lib/detect.ts
|
|
16808
16947
|
var import_node_child_process7 = require("node:child_process");
|
|
16809
16948
|
var import_node_fs23 = require("node:fs");
|
|
16810
|
-
var
|
|
16949
|
+
var import_node_path21 = require("node:path");
|
|
16811
16950
|
var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
|
|
16812
16951
|
"typescript",
|
|
16813
16952
|
"javascript",
|
|
@@ -16870,18 +17009,18 @@ function walk(root) {
|
|
|
16870
17009
|
for (const entry of entries) {
|
|
16871
17010
|
if (found.length >= WALK_MAX_FILES) return;
|
|
16872
17011
|
if (IGNORED_SEGMENTS.includes(entry.name)) continue;
|
|
16873
|
-
const full = (0,
|
|
17012
|
+
const full = (0, import_node_path21.join)(dir, entry.name);
|
|
16874
17013
|
if (entry.isDirectory()) visit(full, depth + 1);
|
|
16875
|
-
else if (entry.isFile()) found.push((0,
|
|
17014
|
+
else if (entry.isFile()) found.push((0, import_node_path21.relative)(root, full));
|
|
16876
17015
|
}
|
|
16877
17016
|
};
|
|
16878
17017
|
visit(root, 0);
|
|
16879
17018
|
return found;
|
|
16880
17019
|
}
|
|
16881
17020
|
function languageOf(path) {
|
|
16882
|
-
const name = (0,
|
|
17021
|
+
const name = (0, import_node_path21.basename)(path);
|
|
16883
17022
|
if (/^Dockerfile(\..+)?$/i.test(name)) return "dockerfile";
|
|
16884
|
-
if (!(0,
|
|
17023
|
+
if (!(0, import_node_path21.extname)(name)) return null;
|
|
16885
17024
|
const lang = detectLanguage(path);
|
|
16886
17025
|
return lang || null;
|
|
16887
17026
|
}
|
|
@@ -16963,12 +17102,12 @@ function declaredDependencies(root, files) {
|
|
|
16963
17102
|
if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
|
|
16964
17103
|
}
|
|
16965
17104
|
};
|
|
16966
|
-
readPackageJson((0,
|
|
16967
|
-
const nested = files.filter((f) => f.includes("/") && (0,
|
|
16968
|
-
for (const rel of nested) readPackageJson((0,
|
|
17105
|
+
readPackageJson((0, import_node_path21.join)(root, "package.json"));
|
|
17106
|
+
const nested = files.filter((f) => f.includes("/") && (0, import_node_path21.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
|
|
17107
|
+
for (const rel of nested) readPackageJson((0, import_node_path21.join)(root, rel));
|
|
16969
17108
|
const pythonManifests = [
|
|
16970
|
-
...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0,
|
|
16971
|
-
...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0,
|
|
17109
|
+
...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path21.join)(root, f)),
|
|
17110
|
+
...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path21.join)(root, f))
|
|
16972
17111
|
];
|
|
16973
17112
|
for (const path of pythonManifests) {
|
|
16974
17113
|
if (!(0, import_node_fs23.existsSync)(path)) continue;
|
|
@@ -16983,8 +17122,8 @@ function declaredDependencies(root, files) {
|
|
|
16983
17122
|
}
|
|
16984
17123
|
}
|
|
16985
17124
|
const goMods = [
|
|
16986
|
-
(0,
|
|
16987
|
-
...files.filter((f) => f.includes("/") && (0,
|
|
17125
|
+
(0, import_node_path21.join)(root, "go.mod"),
|
|
17126
|
+
...files.filter((f) => f.includes("/") && (0, import_node_path21.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path21.join)(root, f))
|
|
16988
17127
|
];
|
|
16989
17128
|
for (const path of goMods) {
|
|
16990
17129
|
if (!(0, import_node_fs23.existsSync)(path)) continue;
|
|
@@ -16997,7 +17136,7 @@ function declaredDependencies(root, files) {
|
|
|
16997
17136
|
}
|
|
16998
17137
|
}
|
|
16999
17138
|
for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
|
|
17000
|
-
const path = (0,
|
|
17139
|
+
const path = (0, import_node_path21.join)(root, file);
|
|
17001
17140
|
if (!(0, import_node_fs23.existsSync)(path)) continue;
|
|
17002
17141
|
try {
|
|
17003
17142
|
const text = (0, import_node_fs23.readFileSync)(path, "utf-8");
|
|
@@ -17008,7 +17147,7 @@ function declaredDependencies(root, files) {
|
|
|
17008
17147
|
return names2;
|
|
17009
17148
|
}
|
|
17010
17149
|
function detectBuildSystem(root, files) {
|
|
17011
|
-
const has = (f) => (0, import_node_fs23.existsSync)((0,
|
|
17150
|
+
const has = (f) => (0, import_node_fs23.existsSync)((0, import_node_path21.join)(root, f)) || files.some((p) => (0, import_node_path21.basename)(p) === f);
|
|
17012
17151
|
if (has("pnpm-lock.yaml")) return "pnpm";
|
|
17013
17152
|
if (has("yarn.lock")) return "yarn";
|
|
17014
17153
|
if (has("bun.lock") || has("bun.lockb")) return "bun";
|
|
@@ -17025,8 +17164,8 @@ function detectBuildSystem(root, files) {
|
|
|
17025
17164
|
}
|
|
17026
17165
|
function detectArchitecture(root, files) {
|
|
17027
17166
|
const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
|
|
17028
|
-
if (workspaceMarkers.some((m) => (0, import_node_fs23.existsSync)((0,
|
|
17029
|
-
const pkg = readJson((0,
|
|
17167
|
+
if (workspaceMarkers.some((m) => (0, import_node_fs23.existsSync)((0, import_node_path21.join)(root, m)))) return "monorepo";
|
|
17168
|
+
const pkg = readJson((0, import_node_path21.join)(root, "package.json"));
|
|
17030
17169
|
if (pkg && "workspaces" in pkg) return "monorepo";
|
|
17031
17170
|
const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
|
|
17032
17171
|
const nested = manifests.filter((f) => f.includes("/"));
|
|
@@ -17039,16 +17178,16 @@ function detectArchitecture(root, files) {
|
|
|
17039
17178
|
var SAMPLE_LIMIT = 300;
|
|
17040
17179
|
function measureAvgFileLength(root, files, languages) {
|
|
17041
17180
|
const primary = new Set(languages.slice(0, 2));
|
|
17042
|
-
const
|
|
17181
|
+
const candidates2 = files.filter((f) => {
|
|
17043
17182
|
const lang = languageOf(f);
|
|
17044
17183
|
return lang !== null && primary.has(lang);
|
|
17045
17184
|
});
|
|
17046
|
-
if (
|
|
17047
|
-
const stride = Math.max(1, Math.floor(
|
|
17185
|
+
if (candidates2.length === 0) return null;
|
|
17186
|
+
const stride = Math.max(1, Math.floor(candidates2.length / SAMPLE_LIMIT));
|
|
17048
17187
|
let total = 0;
|
|
17049
17188
|
let counted = 0;
|
|
17050
|
-
for (let i = 0; i <
|
|
17051
|
-
const path = (0,
|
|
17189
|
+
for (let i = 0; i < candidates2.length; i += stride) {
|
|
17190
|
+
const path = (0, import_node_path21.join)(root, candidates2[i]);
|
|
17052
17191
|
try {
|
|
17053
17192
|
if ((0, import_node_fs23.statSync)(path).size > 2 * 1024 * 1024) continue;
|
|
17054
17193
|
total += (0, import_node_fs23.readFileSync)(path, "utf-8").split("\n").length;
|
|
@@ -17076,14 +17215,14 @@ function detectProject(root = repoRoot()) {
|
|
|
17076
17215
|
const existingToolConfigs = [];
|
|
17077
17216
|
for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
|
|
17078
17217
|
for (const marker of markers) {
|
|
17079
|
-
if ((0, import_node_fs23.existsSync)((0,
|
|
17218
|
+
if ((0, import_node_fs23.existsSync)((0, import_node_path21.join)(root, marker))) {
|
|
17080
17219
|
existingToolConfigs.push({ tool, path: `./${marker}` });
|
|
17081
17220
|
break;
|
|
17082
17221
|
}
|
|
17083
17222
|
}
|
|
17084
17223
|
}
|
|
17085
17224
|
return {
|
|
17086
|
-
projectName: (0,
|
|
17225
|
+
projectName: (0, import_node_path21.basename)(root),
|
|
17087
17226
|
languages,
|
|
17088
17227
|
languageCounts,
|
|
17089
17228
|
frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
|
|
@@ -17529,7 +17668,7 @@ async function correctVerityMdVersion(opts) {
|
|
|
17529
17668
|
}
|
|
17530
17669
|
async function writeFileTo(relative2, body) {
|
|
17531
17670
|
const target = projectPath(relative2);
|
|
17532
|
-
await (0, import_promises9.mkdir)((0,
|
|
17671
|
+
await (0, import_promises9.mkdir)((0, import_node_path22.dirname)(target), { recursive: true });
|
|
17533
17672
|
await (0, import_promises9.writeFile)(target, body);
|
|
17534
17673
|
}
|
|
17535
17674
|
async function deriveConfigForStandard(standard) {
|
|
@@ -18004,7 +18143,11 @@ function registerConfigCommands(program2) {
|
|
|
18004
18143
|
});
|
|
18005
18144
|
config.command("git-moments [moments]").description('Get or set the git moments the guard reviews: commit,push \u2014 or "none"').action((moments) => {
|
|
18006
18145
|
if (moments === void 0) {
|
|
18007
|
-
const
|
|
18146
|
+
const config2 = readProjectConfig();
|
|
18147
|
+
const current = config2.git_moments;
|
|
18148
|
+
if (config2.source === "main-worktree" && config2.path) {
|
|
18149
|
+
printInfo(`Inherited from the main worktree: ${config2.path}`);
|
|
18150
|
+
}
|
|
18008
18151
|
process.stdout.write((current.length ? current.join(",") : "none") + "\n");
|
|
18009
18152
|
return;
|
|
18010
18153
|
}
|
|
@@ -18474,8 +18617,14 @@ function timeAgo(isoDate) {
|
|
|
18474
18617
|
return `${days}d ago`;
|
|
18475
18618
|
}
|
|
18476
18619
|
function registerStatusCommand(program2) {
|
|
18477
|
-
program2.command("status").description("Show project quality status").option("--history", "Include recent run history").option("--limit <n>", "Number of history entries", "5").option("--json", "Output raw JSON").action(async (opts) => {
|
|
18620
|
+
program2.command("status").description("Show project quality status").option("--history", "Include recent run history").option("--limit <n>", "Number of history entries (1-100)", "5").option("--json", "Output raw JSON").action(async (opts) => {
|
|
18478
18621
|
const globals = program2.opts();
|
|
18622
|
+
const rawLimit = String(opts.limit).trim();
|
|
18623
|
+
const limit = /^\d{1,3}$/.test(rawLimit) ? Number(rawLimit) : Number.NaN;
|
|
18624
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
|
|
18625
|
+
printError(`--limit must be a whole number between 1 and 100 (got "${opts.limit}").`);
|
|
18626
|
+
process.exit(1);
|
|
18627
|
+
}
|
|
18479
18628
|
const tokenResult = await resolveToken(globals.token);
|
|
18480
18629
|
if (!tokenResult.ok) {
|
|
18481
18630
|
printError(tokenResult.error);
|
|
@@ -18513,7 +18662,7 @@ function registerStatusCommand(program2) {
|
|
|
18513
18662
|
if (opts.history && !denial) {
|
|
18514
18663
|
const runsResult = await apiRequest({
|
|
18515
18664
|
method: "GET",
|
|
18516
|
-
path: `/runs?limit=${
|
|
18665
|
+
path: `/runs?limit=${limit}`,
|
|
18517
18666
|
serviceUrl,
|
|
18518
18667
|
token,
|
|
18519
18668
|
verbose: globals.verbose
|
|
@@ -18553,12 +18702,14 @@ function registerStatusCommand(program2) {
|
|
|
18553
18702
|
printInfo(`Standard: v${s.version} (${s.quality_dimensions} quality, ${s.security_patterns} security, ${s.custom_patterns} custom)`);
|
|
18554
18703
|
printInfo(`Languages: ${s.languages.join(", ")}`);
|
|
18555
18704
|
}
|
|
18556
|
-
const
|
|
18705
|
+
const wiring = await resolveHookWiring();
|
|
18706
|
+
const hookStatus = wiring.status;
|
|
18557
18707
|
const moments = [];
|
|
18558
18708
|
if (hookStatus.stop) moments.push("stop");
|
|
18559
18709
|
if (hookStatus.guardOn.includes("commit")) moments.push("pre-commit");
|
|
18560
18710
|
if (hookStatus.guardOn.includes("push")) moments.push("pre-push/PR");
|
|
18561
|
-
|
|
18711
|
+
const via = wiring.source === "plugin" ? " (wired by the Verity plugin)" : "";
|
|
18712
|
+
printInfo(`Moments: ${moments.length > 0 ? `${moments.join(", ")}${via}` : 'none (run "verity init")'}`);
|
|
18562
18713
|
if (!mem) return;
|
|
18563
18714
|
if (mem.recent_runs) {
|
|
18564
18715
|
const r = mem.recent_runs;
|
|
@@ -18635,7 +18786,7 @@ function registerStatusCommand(program2) {
|
|
|
18635
18786
|
if (opts.history) {
|
|
18636
18787
|
const runsResult = await apiRequest({
|
|
18637
18788
|
method: "GET",
|
|
18638
|
-
path: `/runs?limit=${
|
|
18789
|
+
path: `/runs?limit=${limit}`,
|
|
18639
18790
|
serviceUrl,
|
|
18640
18791
|
token,
|
|
18641
18792
|
verbose: globals.verbose
|
|
@@ -18826,11 +18977,11 @@ var import_node_fs43 = require("node:fs");
|
|
|
18826
18977
|
|
|
18827
18978
|
// src/lib/repo-context.ts
|
|
18828
18979
|
var import_node_child_process9 = require("node:child_process");
|
|
18829
|
-
var
|
|
18980
|
+
var import_node_os4 = require("node:os");
|
|
18830
18981
|
function rgInvocations(env = process.env) {
|
|
18831
18982
|
const out = [{ cmd: "rg" }];
|
|
18832
18983
|
if (env.CLAUDE_CODE_EXECPATH) out.push({ cmd: env.CLAUDE_CODE_EXECPATH, argv0: "rg" });
|
|
18833
|
-
out.push({ cmd: `${(0,
|
|
18984
|
+
out.push({ cmd: `${(0, import_node_os4.homedir)()}/.local/bin/claude`, argv0: "rg" });
|
|
18834
18985
|
return out;
|
|
18835
18986
|
}
|
|
18836
18987
|
var MAX_SYMBOLS = 12;
|
|
@@ -19644,9 +19795,9 @@ function installRunEvidence(run2) {
|
|
|
19644
19795
|
// src/lib/git-frame.ts
|
|
19645
19796
|
var import_node_child_process10 = require("node:child_process");
|
|
19646
19797
|
var import_node_fs31 = require("node:fs");
|
|
19647
|
-
var
|
|
19648
|
-
var
|
|
19649
|
-
var
|
|
19798
|
+
var import_node_os5 = require("node:os");
|
|
19799
|
+
var import_node_path23 = require("node:path");
|
|
19800
|
+
var import_node_path24 = require("node:path");
|
|
19650
19801
|
var VALUE_TOKEN = `(?:'[^']*'|"[^"]*"|\\S+)`;
|
|
19651
19802
|
var GIT_GLOBAL_OPTS = `(?:\\s+(?:-[Cc]\\s+${VALUE_TOKEN}|--?[\\w-]+(?:=\\S+)?))*`;
|
|
19652
19803
|
var COMMIT_HEAD = `git${GIT_GLOBAL_OPTS}\\s+commit(?![\\w-])`;
|
|
@@ -19692,15 +19843,15 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
|
|
|
19692
19843
|
if (!m) continue;
|
|
19693
19844
|
named = true;
|
|
19694
19845
|
if (m[1] === void 0) {
|
|
19695
|
-
dir = (0,
|
|
19846
|
+
dir = (0, import_node_os5.homedir)();
|
|
19696
19847
|
continue;
|
|
19697
19848
|
}
|
|
19698
19849
|
const raw = unquote(m[1]);
|
|
19699
19850
|
if (SHELL_DYNAMIC.test(raw) || raw === "-") {
|
|
19700
19851
|
return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
|
|
19701
19852
|
}
|
|
19702
|
-
const expanded = raw === "~" ? (0,
|
|
19703
|
-
dir = (0,
|
|
19853
|
+
const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path24.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
|
|
19854
|
+
dir = (0, import_node_path23.isAbsolute)(expanded) ? expanded : (0, import_node_path23.resolve)(dir, expanded);
|
|
19704
19855
|
}
|
|
19705
19856
|
const seg = segments[segmentIndex];
|
|
19706
19857
|
const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
|
|
@@ -19718,8 +19869,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
|
|
|
19718
19869
|
if (SHELL_DYNAMIC.test(raw)) {
|
|
19719
19870
|
return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
|
|
19720
19871
|
}
|
|
19721
|
-
const expanded = raw === "~" ? (0,
|
|
19722
|
-
dir = (0,
|
|
19872
|
+
const expanded = raw === "~" ? (0, import_node_os5.homedir)() : raw.startsWith("~/") ? (0, import_node_path24.join)((0, import_node_os5.homedir)(), raw.slice(2)) : raw;
|
|
19873
|
+
dir = (0, import_node_path23.isAbsolute)(expanded) ? expanded : (0, import_node_path23.resolve)(dir, expanded);
|
|
19723
19874
|
}
|
|
19724
19875
|
}
|
|
19725
19876
|
return { dir, named, unresolvable: null };
|
|
@@ -19784,7 +19935,7 @@ function realpathOr(p) {
|
|
|
19784
19935
|
try {
|
|
19785
19936
|
return import_node_fs31.realpathSync.native(p);
|
|
19786
19937
|
} catch {
|
|
19787
|
-
return (0,
|
|
19938
|
+
return (0, import_node_path23.resolve)(p);
|
|
19788
19939
|
}
|
|
19789
19940
|
}
|
|
19790
19941
|
function resolveFrame(input) {
|
|
@@ -19823,7 +19974,7 @@ function resolveFrame(input) {
|
|
|
19823
19974
|
const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
|
|
19824
19975
|
const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
|
|
19825
19976
|
const gitDir = gitDirRaw ? realpathOr(gitDirRaw) : null;
|
|
19826
|
-
const commonDir = commonRaw ? realpathOr((0,
|
|
19977
|
+
const commonDir = commonRaw ? realpathOr((0, import_node_path23.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path23.resolve)(dir, commonRaw)) : null;
|
|
19827
19978
|
const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
19828
19979
|
return {
|
|
19829
19980
|
moment: found?.moment ?? null,
|
|
@@ -19848,14 +19999,172 @@ function refResolves(frame, ref) {
|
|
|
19848
19999
|
return frameGit(frame, ["rev-parse", "--verify", "-q", `${ref}^{commit}`]) !== "";
|
|
19849
20000
|
}
|
|
19850
20001
|
var SHA_RE2 = /^[0-9a-f]{40}$/;
|
|
19851
|
-
function
|
|
20002
|
+
function shellWords(segment) {
|
|
20003
|
+
return segment.match(/'[^']*'|"[^"]*"|\S+/g) ?? [];
|
|
20004
|
+
}
|
|
20005
|
+
var ADD_FLAGS_REPLAYABLE = /* @__PURE__ */ new Set([
|
|
20006
|
+
"-A",
|
|
20007
|
+
"--all",
|
|
20008
|
+
"--no-ignore-removal",
|
|
20009
|
+
"-u",
|
|
20010
|
+
"--update",
|
|
20011
|
+
"--no-all",
|
|
20012
|
+
"--ignore-removal",
|
|
20013
|
+
"-f",
|
|
20014
|
+
"--force",
|
|
20015
|
+
"-v",
|
|
20016
|
+
"--verbose",
|
|
20017
|
+
"-N",
|
|
20018
|
+
"--intent-to-add",
|
|
20019
|
+
"--renormalize",
|
|
20020
|
+
"--sparse",
|
|
20021
|
+
"--ignore-errors",
|
|
20022
|
+
"--refresh"
|
|
20023
|
+
]);
|
|
20024
|
+
var ADD_FLAGS_INTERACTIVE = /* @__PURE__ */ new Set(["-i", "--interactive", "-p", "--patch", "-e", "--edit"]);
|
|
20025
|
+
var PATHSPEC_UNRESOLVABLE = /[$`\\*?[\]{}~]/;
|
|
20026
|
+
var COMMIT_VALUE_OPTS = /* @__PURE__ */ new Set([
|
|
20027
|
+
"-m",
|
|
20028
|
+
"--message",
|
|
20029
|
+
"-F",
|
|
20030
|
+
"--file",
|
|
20031
|
+
"-C",
|
|
20032
|
+
"--reuse-message",
|
|
20033
|
+
"-c",
|
|
20034
|
+
"--reedit-message",
|
|
20035
|
+
"--author",
|
|
20036
|
+
"--date",
|
|
20037
|
+
"-t",
|
|
20038
|
+
"--template",
|
|
20039
|
+
"--fixup",
|
|
20040
|
+
"--squash",
|
|
20041
|
+
"--trailer",
|
|
20042
|
+
"--cleanup"
|
|
20043
|
+
]);
|
|
20044
|
+
var ADD_HEAD = `git${GIT_GLOBAL_OPTS}\\s+add(?![\\w-])`;
|
|
20045
|
+
var ADD_RE = new RegExp(`(?:^|[\\s;&|(])${ADD_HEAD}|(?:^|[;&|(])\\s*[^\\s;&|()'"]*\\/${ADD_HEAD}`);
|
|
20046
|
+
function pathspecOf(word) {
|
|
20047
|
+
const raw = unquote(word);
|
|
20048
|
+
if (!raw) return { reason: "an empty pathspec" };
|
|
20049
|
+
if (PATHSPEC_UNRESOLVABLE.test(raw)) {
|
|
20050
|
+
return { reason: `the shell rewrites the pathspec "${raw}" before git sees it` };
|
|
20051
|
+
}
|
|
20052
|
+
return { path: raw };
|
|
20053
|
+
}
|
|
20054
|
+
function parseAddSegment(segment) {
|
|
20055
|
+
const words = shellWords(segment);
|
|
20056
|
+
const at = words.indexOf("add");
|
|
20057
|
+
if (at === -1) return { reason: 'the "git add" arguments could not be read' };
|
|
20058
|
+
const flags = [];
|
|
20059
|
+
const paths = [];
|
|
20060
|
+
let literal = false;
|
|
20061
|
+
for (const word of words.slice(at + 1)) {
|
|
20062
|
+
if (literal || !word.startsWith("-") || word === "-") {
|
|
20063
|
+
if (word === "--" && !literal) {
|
|
20064
|
+
literal = true;
|
|
20065
|
+
continue;
|
|
20066
|
+
}
|
|
20067
|
+
const p = pathspecOf(word);
|
|
20068
|
+
if ("reason" in p) return p;
|
|
20069
|
+
paths.push(p.path);
|
|
20070
|
+
continue;
|
|
20071
|
+
}
|
|
20072
|
+
if (word === "--") {
|
|
20073
|
+
literal = true;
|
|
20074
|
+
continue;
|
|
20075
|
+
}
|
|
20076
|
+
const parts = /^-[A-Za-z]{2,}$/.test(word) ? [...word.slice(1)].map((c) => `-${c}`) : [word];
|
|
20077
|
+
for (const flag of parts) {
|
|
20078
|
+
if (ADD_FLAGS_INTERACTIVE.has(flag)) {
|
|
20079
|
+
return { reason: `"git add ${flag}" stages what a human picks at a prompt` };
|
|
20080
|
+
}
|
|
20081
|
+
if (!ADD_FLAGS_REPLAYABLE.has(flag.split("=")[0])) {
|
|
20082
|
+
return { reason: `unmodelled "git add" option ${flag}` };
|
|
20083
|
+
}
|
|
20084
|
+
flags.push(flag);
|
|
20085
|
+
}
|
|
20086
|
+
}
|
|
20087
|
+
return { flags, paths };
|
|
20088
|
+
}
|
|
20089
|
+
function commitStagesTrackedChanges(segment) {
|
|
20090
|
+
const words = shellWords(segment);
|
|
20091
|
+
const at = words.indexOf("commit");
|
|
20092
|
+
if (at === -1) return false;
|
|
20093
|
+
let skipValue = false;
|
|
20094
|
+
for (const word of words.slice(at + 1)) {
|
|
20095
|
+
if (skipValue) {
|
|
20096
|
+
skipValue = false;
|
|
20097
|
+
continue;
|
|
20098
|
+
}
|
|
20099
|
+
if (word === "--") break;
|
|
20100
|
+
if (!word.startsWith("-") || word === "-") continue;
|
|
20101
|
+
if (word.startsWith("--")) {
|
|
20102
|
+
const name = word.split("=")[0];
|
|
20103
|
+
if (name === "--all") return true;
|
|
20104
|
+
if (COMMIT_VALUE_OPTS.has(name) && !word.includes("=")) skipValue = true;
|
|
20105
|
+
continue;
|
|
20106
|
+
}
|
|
20107
|
+
for (let i = 1; i < word.length; i++) {
|
|
20108
|
+
const flag = `-${word[i]}`;
|
|
20109
|
+
if (flag === "-a") return true;
|
|
20110
|
+
if (COMMIT_VALUE_OPTS.has(flag)) {
|
|
20111
|
+
if (i === word.length - 1) skipValue = true;
|
|
20112
|
+
break;
|
|
20113
|
+
}
|
|
20114
|
+
}
|
|
20115
|
+
}
|
|
20116
|
+
return false;
|
|
20117
|
+
}
|
|
20118
|
+
function planInCommandStaging(frame, command) {
|
|
20119
|
+
const found = findMomentSegment(command, ["commit"]);
|
|
20120
|
+
if (!found) return { kind: "none" };
|
|
20121
|
+
const segments = splitSegments(command);
|
|
20122
|
+
if (commitStagesTrackedChanges(segments[found.segmentIndex])) {
|
|
20123
|
+
return {
|
|
20124
|
+
kind: "files",
|
|
20125
|
+
via: "index+commit-a",
|
|
20126
|
+
files: frameGit(frame, ["diff", "--name-only", "HEAD"]).split("\n").filter(Boolean)
|
|
20127
|
+
};
|
|
20128
|
+
}
|
|
20129
|
+
const addSegments = segments.slice(0, found.segmentIndex).filter((s) => ADD_RE.test(s));
|
|
20130
|
+
if (addSegments.length === 0) return { kind: "none" };
|
|
20131
|
+
const staged = new Set(
|
|
20132
|
+
frameGit(frame, ["diff", "--cached", "--name-only"]).split("\n").filter(Boolean)
|
|
20133
|
+
);
|
|
20134
|
+
for (const segment of addSegments) {
|
|
20135
|
+
const parsed = parseAddSegment(segment);
|
|
20136
|
+
if ("reason" in parsed) return { kind: "unpredictable", reason: parsed.reason };
|
|
20137
|
+
const args = ["add", "--dry-run", "--ignore-missing", ...parsed.flags];
|
|
20138
|
+
if (parsed.paths.length > 0) args.push("--", ...parsed.paths);
|
|
20139
|
+
for (const line of frameGit(frame, args).split("\n")) {
|
|
20140
|
+
const m = line.match(/^(?:add|remove) '(.*)'$/);
|
|
20141
|
+
if (m) staged.add(m[1]);
|
|
20142
|
+
}
|
|
20143
|
+
}
|
|
20144
|
+
return { kind: "files", via: "index+staged-in-command", files: [...staged] };
|
|
20145
|
+
}
|
|
20146
|
+
function stagedRange(frame, command) {
|
|
19852
20147
|
if (!frame.worktreeRoot) return { kind: "nothing", base: null, head: "INDEX", via: "refused" };
|
|
19853
|
-
const
|
|
20148
|
+
const plan = command ? planInCommandStaging(frame, command) : { kind: "none" };
|
|
20149
|
+
if (plan.kind === "unpredictable") {
|
|
20150
|
+
return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
|
|
20151
|
+
}
|
|
20152
|
+
const mergeHead = frame.gitDir ? (0, import_node_path24.join)(frame.gitDir, "MERGE_HEAD") : null;
|
|
19854
20153
|
if (mergeHead && (0, import_node_fs31.existsSync)(mergeHead)) {
|
|
19855
20154
|
const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
|
|
19856
20155
|
const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
|
|
19857
|
-
const resolutions = [...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f));
|
|
19858
|
-
|
|
20156
|
+
const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
|
|
20157
|
+
if (plan.kind === "files") {
|
|
20158
|
+
const wtVsHead = new Set(frameGit(frame, ["diff", "--name-only", "HEAD"]).split("\n").filter(Boolean));
|
|
20159
|
+
const wtVsMerge = new Set(frameGit(frame, ["diff", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
|
|
20160
|
+
for (const f of plan.files) {
|
|
20161
|
+
if (wtVsHead.has(f) && wtVsMerge.has(f) && !isVerityOwnedPath(f)) resolutions.add(f);
|
|
20162
|
+
}
|
|
20163
|
+
}
|
|
20164
|
+
return { kind: "merge", base: "HEAD", head: "INDEX", via: "merge-resolutions", files: [...resolutions] };
|
|
20165
|
+
}
|
|
20166
|
+
if (plan.kind === "files") {
|
|
20167
|
+
return { kind: "staged", base: "HEAD", head: "INDEX", via: plan.via, files: plan.files };
|
|
19859
20168
|
}
|
|
19860
20169
|
return { kind: "staged", base: "HEAD", head: "INDEX", via: "index" };
|
|
19861
20170
|
}
|
|
@@ -20247,7 +20556,7 @@ function sanitizeCommandWithLoss(rawCmd) {
|
|
|
20247
20556
|
const lost = lines.slice(1).some((l) => l.trim().length > 0);
|
|
20248
20557
|
const first = lines[0];
|
|
20249
20558
|
const cmd = sanitizeCommand(first);
|
|
20250
|
-
const hadSeparator = SEPARATORS.some((
|
|
20559
|
+
const hadSeparator = SEPARATORS.some((sep3) => first.indexOf(sep3) > 0);
|
|
20251
20560
|
return { cmd, lost: lost || !hadSeparator && first.length > MAX_COMMAND_CHARS };
|
|
20252
20561
|
}
|
|
20253
20562
|
var SEPARATORS = [" | ", " > ", " >> ", " 2>", " && ", " ; "];
|
|
@@ -20256,11 +20565,11 @@ function sanitizeCommand(rawCmd) {
|
|
|
20256
20565
|
let cmd = rawCmd.split("\n")[0];
|
|
20257
20566
|
let cut = -1;
|
|
20258
20567
|
let marker = "";
|
|
20259
|
-
for (const
|
|
20260
|
-
const idx = cmd.indexOf(
|
|
20568
|
+
for (const sep3 of SEPARATORS) {
|
|
20569
|
+
const idx = cmd.indexOf(sep3);
|
|
20261
20570
|
if (idx > 0 && (cut === -1 || idx < cut)) {
|
|
20262
20571
|
cut = idx;
|
|
20263
|
-
marker =
|
|
20572
|
+
marker = sep3.trim();
|
|
20264
20573
|
}
|
|
20265
20574
|
}
|
|
20266
20575
|
if (cut > -1) cmd = cmd.slice(0, cut);
|
|
@@ -20284,28 +20593,28 @@ async function readStopHookStdin() {
|
|
|
20284
20593
|
try {
|
|
20285
20594
|
if (process.stdin.isTTY) return empty;
|
|
20286
20595
|
const chunks = [];
|
|
20287
|
-
const timeout = new Promise((
|
|
20288
|
-
const read = new Promise((
|
|
20596
|
+
const timeout = new Promise((resolve5) => setTimeout(() => resolve5(empty), 500));
|
|
20597
|
+
const read = new Promise((resolve5) => {
|
|
20289
20598
|
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
20290
20599
|
process.stdin.on("end", () => {
|
|
20291
20600
|
const raw = Buffer.concat(chunks).toString("utf-8").trim();
|
|
20292
20601
|
if (!raw) {
|
|
20293
|
-
|
|
20602
|
+
resolve5(empty);
|
|
20294
20603
|
return;
|
|
20295
20604
|
}
|
|
20296
20605
|
try {
|
|
20297
20606
|
const data = JSON.parse(raw);
|
|
20298
|
-
|
|
20607
|
+
resolve5({
|
|
20299
20608
|
assistantMessage: typeof data.last_assistant_message === "string" ? data.last_assistant_message : null,
|
|
20300
20609
|
stopReason: typeof data.stop_reason === "string" ? data.stop_reason : null,
|
|
20301
20610
|
transcriptPath: typeof data.transcript_path === "string" ? data.transcript_path : null,
|
|
20302
20611
|
sessionId: typeof data.session_id === "string" ? data.session_id : null
|
|
20303
20612
|
});
|
|
20304
20613
|
} catch {
|
|
20305
|
-
|
|
20614
|
+
resolve5(empty);
|
|
20306
20615
|
}
|
|
20307
20616
|
});
|
|
20308
|
-
process.stdin.on("error", () =>
|
|
20617
|
+
process.stdin.on("error", () => resolve5(empty));
|
|
20309
20618
|
process.stdin.resume();
|
|
20310
20619
|
});
|
|
20311
20620
|
return await Promise.race([read, timeout]);
|
|
@@ -20509,7 +20818,7 @@ function channelSilence(input) {
|
|
|
20509
20818
|
// src/lib/cli-version.ts
|
|
20510
20819
|
function cliVersion() {
|
|
20511
20820
|
try {
|
|
20512
|
-
return true ? "0.32.0-experimental.
|
|
20821
|
+
return true ? "0.32.0-experimental.cc76941" : "dev";
|
|
20513
20822
|
} catch {
|
|
20514
20823
|
return "dev";
|
|
20515
20824
|
}
|
|
@@ -20868,7 +21177,7 @@ async function scope(run2) {
|
|
|
20868
21177
|
|
|
20869
21178
|
// src/lib/specs.ts
|
|
20870
21179
|
var import_node_fs34 = require("node:fs");
|
|
20871
|
-
var
|
|
21180
|
+
var import_node_path25 = require("node:path");
|
|
20872
21181
|
var SPEC_CANDIDATES = [
|
|
20873
21182
|
"CLAUDE.md",
|
|
20874
21183
|
"AGENTS.md",
|
|
@@ -20941,7 +21250,7 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
20941
21250
|
try {
|
|
20942
21251
|
const entries = (0, import_node_fs34.readdirSync)(dir, { withFileTypes: true });
|
|
20943
21252
|
for (const entry of entries) {
|
|
20944
|
-
const fullPath = (0,
|
|
21253
|
+
const fullPath = (0, import_node_path25.join)(dir, entry.name);
|
|
20945
21254
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
20946
21255
|
result.push(fullPath);
|
|
20947
21256
|
} else if (entry.isDirectory() && depth < maxDepth - 1) {
|
|
@@ -20953,9 +21262,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
|
|
|
20953
21262
|
return result;
|
|
20954
21263
|
}
|
|
20955
21264
|
function discoverPlans() {
|
|
20956
|
-
const homePlansDir = (0,
|
|
21265
|
+
const homePlansDir = (0, import_node_path25.join)(process.env.HOME ?? "", ".claude", "plans");
|
|
20957
21266
|
const localPlansDir = ".claude/plans";
|
|
20958
|
-
const
|
|
21267
|
+
const candidates2 = [];
|
|
20959
21268
|
const seen = /* @__PURE__ */ new Set();
|
|
20960
21269
|
for (const plansDir of [localPlansDir, homePlansDir]) {
|
|
20961
21270
|
if (!(0, import_node_fs34.existsSync)(plansDir)) continue;
|
|
@@ -20963,19 +21272,19 @@ function discoverPlans() {
|
|
|
20963
21272
|
for (const f of (0, import_node_fs34.readdirSync)(plansDir)) {
|
|
20964
21273
|
if (!f.endsWith(".md") || seen.has(f)) continue;
|
|
20965
21274
|
seen.add(f);
|
|
20966
|
-
const fullPath = (0,
|
|
21275
|
+
const fullPath = (0, import_node_path25.join)(plansDir, f);
|
|
20967
21276
|
try {
|
|
20968
21277
|
const stat3 = (0, import_node_fs34.statSync)(fullPath);
|
|
20969
|
-
|
|
21278
|
+
candidates2.push({ name: f, path: fullPath, mtime: stat3.mtimeMs, size: stat3.size });
|
|
20970
21279
|
} catch {
|
|
20971
21280
|
}
|
|
20972
21281
|
}
|
|
20973
21282
|
} catch {
|
|
20974
21283
|
}
|
|
20975
21284
|
}
|
|
20976
|
-
|
|
21285
|
+
candidates2.sort((a, b) => b.mtime - a.mtime);
|
|
20977
21286
|
const result = [];
|
|
20978
|
-
for (const entry of
|
|
21287
|
+
for (const entry of candidates2.slice(0, MAX_PLAN_FILES)) {
|
|
20979
21288
|
if (entry.size > MAX_PLAN_FILE_BYTES) continue;
|
|
20980
21289
|
try {
|
|
20981
21290
|
const content = (0, import_node_fs34.readFileSync)(entry.path, "utf-8");
|
|
@@ -21175,7 +21484,7 @@ async function mode(run2) {
|
|
|
21175
21484
|
|
|
21176
21485
|
// src/lib/fold.ts
|
|
21177
21486
|
var import_node_fs35 = require("node:fs");
|
|
21178
|
-
var
|
|
21487
|
+
var import_node_path26 = require("node:path");
|
|
21179
21488
|
var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
|
|
21180
21489
|
"user",
|
|
21181
21490
|
"assistant",
|
|
@@ -21407,9 +21716,9 @@ function fold(transcriptPath, opts = {}) {
|
|
|
21407
21716
|
return result;
|
|
21408
21717
|
}
|
|
21409
21718
|
try {
|
|
21410
|
-
const sidecarDir = (0,
|
|
21411
|
-
(0,
|
|
21412
|
-
(0,
|
|
21719
|
+
const sidecarDir = (0, import_node_path26.join)(
|
|
21720
|
+
(0, import_node_path26.dirname)(transcriptPath),
|
|
21721
|
+
(0, import_node_path26.basename)(transcriptPath).replace(/\.jsonl$/, ""),
|
|
21413
21722
|
"subagents"
|
|
21414
21723
|
);
|
|
21415
21724
|
if ((0, import_node_fs35.existsSync)(sidecarDir)) {
|
|
@@ -21419,7 +21728,7 @@ function fold(transcriptPath, opts = {}) {
|
|
|
21419
21728
|
const walk2 = (d, depth) => {
|
|
21420
21729
|
if (depth > 4) return;
|
|
21421
21730
|
for (const e of (0, import_node_fs35.readdirSync)(d, { withFileTypes: true })) {
|
|
21422
|
-
const p = (0,
|
|
21731
|
+
const p = (0, import_node_path26.join)(d, e.name);
|
|
21423
21732
|
if (e.isDirectory()) {
|
|
21424
21733
|
walk2(p, depth + 1);
|
|
21425
21734
|
} else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
|
|
@@ -21794,7 +22103,7 @@ async function evidence(run2) {
|
|
|
21794
22103
|
|
|
21795
22104
|
// src/lib/cache-cleanup.ts
|
|
21796
22105
|
var import_node_fs36 = require("node:fs");
|
|
21797
|
-
var
|
|
22106
|
+
var import_node_path27 = require("node:path");
|
|
21798
22107
|
var CACHE_TTL_DAYS = 7;
|
|
21799
22108
|
function pruneStaleCache() {
|
|
21800
22109
|
try {
|
|
@@ -21802,7 +22111,7 @@ function pruneStaleCache() {
|
|
|
21802
22111
|
const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
|
|
21803
22112
|
for (const entry of (0, import_node_fs36.readdirSync)(dir)) {
|
|
21804
22113
|
if (!entry.startsWith("pending-")) continue;
|
|
21805
|
-
const path = (0,
|
|
22114
|
+
const path = (0, import_node_path27.join)(dir, entry);
|
|
21806
22115
|
try {
|
|
21807
22116
|
const stat3 = (0, import_node_fs36.statSync)(path);
|
|
21808
22117
|
if (stat3.mtimeMs < cutoff) {
|
|
@@ -21821,7 +22130,7 @@ function pruneStaleCache() {
|
|
|
21821
22130
|
|
|
21822
22131
|
// src/lib/context-files.ts
|
|
21823
22132
|
var import_node_fs37 = require("node:fs");
|
|
21824
|
-
var
|
|
22133
|
+
var import_node_os6 = require("node:os");
|
|
21825
22134
|
var MAX_CONTEXT_FILES = 10;
|
|
21826
22135
|
var MAX_CONTEXT_FILE_BYTES = 10240;
|
|
21827
22136
|
var MAX_CONTEXT_TOTAL_BYTES = 24576;
|
|
@@ -21829,7 +22138,7 @@ function readSetContextPaths(summary, deltaFiles) {
|
|
|
21829
22138
|
const reads = summary?.files_read ?? [];
|
|
21830
22139
|
if (reads.length === 0) return [];
|
|
21831
22140
|
const root = process.cwd().replace(/\/+$/, "");
|
|
21832
|
-
const home = (0,
|
|
22141
|
+
const home = (0, import_node_os6.homedir)();
|
|
21833
22142
|
const toRepoRelative2 = (p) => {
|
|
21834
22143
|
if (!p) return null;
|
|
21835
22144
|
let abs;
|
|
@@ -21970,7 +22279,7 @@ async function repoContext(run2) {
|
|
|
21970
22279
|
// src/lib/seed-runner.ts
|
|
21971
22280
|
var import_promises14 = require("node:fs/promises");
|
|
21972
22281
|
var import_node_fs38 = require("node:fs");
|
|
21973
|
-
var
|
|
22282
|
+
var import_node_path28 = require("node:path");
|
|
21974
22283
|
var import_yaml4 = __toESM(require_dist());
|
|
21975
22284
|
|
|
21976
22285
|
// src/lib/seed.ts
|
|
@@ -22237,7 +22546,7 @@ async function runSeed(opts) {
|
|
|
22237
22546
|
}
|
|
22238
22547
|
}
|
|
22239
22548
|
}
|
|
22240
|
-
const
|
|
22549
|
+
const candidates2 = deriveSeedNodes({
|
|
22241
22550
|
knowledgeSpec: {
|
|
22242
22551
|
project_name: knowledgeSpec.project_name,
|
|
22243
22552
|
languages: knowledgeSpec.languages,
|
|
@@ -22249,20 +22558,20 @@ async function runSeed(opts) {
|
|
|
22249
22558
|
readmeContent,
|
|
22250
22559
|
claudeMdContent
|
|
22251
22560
|
});
|
|
22252
|
-
if (
|
|
22561
|
+
if (candidates2.length === 0) {
|
|
22253
22562
|
return { created: 0, failed: 0, skipped: "no_candidates", candidates: [] };
|
|
22254
22563
|
}
|
|
22255
|
-
const overviewPath = (0,
|
|
22564
|
+
const overviewPath = (0, import_node_path28.join)(MEMORY_DIR, "domain", "project-overview.md");
|
|
22256
22565
|
if ((0, import_node_fs38.existsSync)(overviewPath) && !opts.force) {
|
|
22257
|
-
return { created: 0, failed: 0, skipped: "already_seeded", candidates };
|
|
22566
|
+
return { created: 0, failed: 0, skipped: "already_seeded", candidates: candidates2 };
|
|
22258
22567
|
}
|
|
22259
22568
|
if (opts.dryRun) {
|
|
22260
|
-
return { created: 0, failed: 0, skipped: null, candidates };
|
|
22569
|
+
return { created: 0, failed: 0, skipped: null, candidates: candidates2 };
|
|
22261
22570
|
}
|
|
22262
22571
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
22263
22572
|
let created = 0;
|
|
22264
22573
|
let failed = 0;
|
|
22265
|
-
for (const c of
|
|
22574
|
+
for (const c of candidates2) {
|
|
22266
22575
|
const res = await apiRequest({
|
|
22267
22576
|
method: "POST",
|
|
22268
22577
|
path: "/compound/memory/nodes",
|
|
@@ -22295,7 +22604,7 @@ async function runSeed(opts) {
|
|
|
22295
22604
|
continue;
|
|
22296
22605
|
}
|
|
22297
22606
|
try {
|
|
22298
|
-
await (0, import_promises14.mkdir)((0,
|
|
22607
|
+
await (0, import_promises14.mkdir)((0, import_node_path28.dirname)(targetPath), { recursive: true });
|
|
22299
22608
|
await (0, import_promises14.writeFile)(targetPath, renderNodeMarkdown(c, nodeId, createdAt));
|
|
22300
22609
|
created++;
|
|
22301
22610
|
opts.onCreated?.(nodeId, filePathRel, c);
|
|
@@ -22304,12 +22613,12 @@ async function runSeed(opts) {
|
|
|
22304
22613
|
failed++;
|
|
22305
22614
|
}
|
|
22306
22615
|
}
|
|
22307
|
-
return { created, failed, skipped: null, candidates };
|
|
22616
|
+
return { created, failed, skipped: null, candidates: candidates2 };
|
|
22308
22617
|
}
|
|
22309
22618
|
|
|
22310
22619
|
// src/commands/analyze/phases/08-memory-manifest.ts
|
|
22311
22620
|
var import_node_fs39 = require("node:fs");
|
|
22312
|
-
var
|
|
22621
|
+
var import_node_path29 = require("node:path");
|
|
22313
22622
|
async function memoryManifest(run2) {
|
|
22314
22623
|
const { globals } = run2;
|
|
22315
22624
|
const { serviceUrl, token } = run2;
|
|
@@ -22319,7 +22628,7 @@ async function memoryManifest(run2) {
|
|
|
22319
22628
|
let autoSeedNotice = null;
|
|
22320
22629
|
try {
|
|
22321
22630
|
await ensureMemoryDir();
|
|
22322
|
-
const seedMarker = (0,
|
|
22631
|
+
const seedMarker = (0, import_node_path29.join)(VERITY_DIR, ".seeded");
|
|
22323
22632
|
const hasStandard = (0, import_node_fs39.existsSync)(STANDARD_FILE);
|
|
22324
22633
|
const alreadyTried = (0, import_node_fs39.existsSync)(seedMarker);
|
|
22325
22634
|
if (hasStandard && !alreadyTried) {
|
|
@@ -22437,7 +22746,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
|
|
|
22437
22746
|
}
|
|
22438
22747
|
|
|
22439
22748
|
// src/commands/analyze/phases/10-working-memory.ts
|
|
22440
|
-
var
|
|
22749
|
+
var import_node_path30 = require("node:path");
|
|
22441
22750
|
async function workingMemory(run2) {
|
|
22442
22751
|
const { opts } = run2;
|
|
22443
22752
|
const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run2;
|
|
@@ -22449,7 +22758,7 @@ async function workingMemory(run2) {
|
|
|
22449
22758
|
const priorState = foldForMarks(memorySession.d);
|
|
22450
22759
|
incrementReport = computeIncrement(
|
|
22451
22760
|
allForReview,
|
|
22452
|
-
(p) => fileHash((0,
|
|
22761
|
+
(p) => fileHash((0, import_node_path30.join)(repoRoot(), p)),
|
|
22453
22762
|
priorState.authored_all.map((a) => ({
|
|
22454
22763
|
path: a.path,
|
|
22455
22764
|
hash_at_last_verdict: a.hash_at_last_verdict
|
|
@@ -23014,7 +23323,7 @@ async function transmit(run2) {
|
|
|
23014
23323
|
|
|
23015
23324
|
// src/commands/analyze/phases/13-reconcile.ts
|
|
23016
23325
|
var import_node_fs42 = require("node:fs");
|
|
23017
|
-
var
|
|
23326
|
+
var import_node_path31 = require("node:path");
|
|
23018
23327
|
async function reconcile(run2) {
|
|
23019
23328
|
const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory, memorySession, response, reviewable, securityFiles, turnId } = run2;
|
|
23020
23329
|
const sentPaths = codeDelta.files.map((f) => f.path);
|
|
@@ -23043,7 +23352,7 @@ async function reconcile(run2) {
|
|
|
23043
23352
|
const st = foldDossier(memorySession.d);
|
|
23044
23353
|
openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line) => {
|
|
23045
23354
|
try {
|
|
23046
|
-
const src = (0, import_node_fs42.readFileSync)((0,
|
|
23355
|
+
const src = (0, import_node_fs42.readFileSync)((0, import_node_path31.join)(repoRoot(), file), "utf8").split("\n");
|
|
23047
23356
|
const at = src[line - 1];
|
|
23048
23357
|
return at === void 0 ? null : lineSha(at);
|
|
23049
23358
|
} catch {
|
|
@@ -23895,14 +24204,14 @@ async function runReview(opts, globals) {
|
|
|
23895
24204
|
|
|
23896
24205
|
// src/commands/guard.ts
|
|
23897
24206
|
var import_node_fs45 = require("node:fs");
|
|
23898
|
-
var
|
|
24207
|
+
var import_node_path32 = require("node:path");
|
|
23899
24208
|
var GUARD_BLOCK_CAP = 2;
|
|
23900
|
-
var GUARD_ITER_FILE = (0,
|
|
24209
|
+
var GUARD_ITER_FILE = (0, import_node_path32.join)(VERITY_DIR, ".guard-iteration");
|
|
23901
24210
|
function readPreToolUseStdin() {
|
|
23902
24211
|
const empty = { command: "", cwd: null, sessionId: null };
|
|
23903
|
-
return new Promise((
|
|
24212
|
+
return new Promise((resolve5) => {
|
|
23904
24213
|
try {
|
|
23905
|
-
if (process.stdin.isTTY) return
|
|
24214
|
+
if (process.stdin.isTTY) return resolve5(empty);
|
|
23906
24215
|
const chunks = [];
|
|
23907
24216
|
let timer;
|
|
23908
24217
|
let settled = false;
|
|
@@ -23915,7 +24224,7 @@ function readPreToolUseStdin() {
|
|
|
23915
24224
|
process.stdin.removeListener("end", onEnd);
|
|
23916
24225
|
process.stdin.removeListener("error", onError);
|
|
23917
24226
|
process.stdin.pause();
|
|
23918
|
-
|
|
24227
|
+
resolve5(value);
|
|
23919
24228
|
};
|
|
23920
24229
|
const onEnd = () => {
|
|
23921
24230
|
try {
|
|
@@ -23936,7 +24245,7 @@ function readPreToolUseStdin() {
|
|
|
23936
24245
|
process.stdin.on("error", onError);
|
|
23937
24246
|
process.stdin.resume();
|
|
23938
24247
|
} catch {
|
|
23939
|
-
|
|
24248
|
+
resolve5(empty);
|
|
23940
24249
|
}
|
|
23941
24250
|
});
|
|
23942
24251
|
}
|
|
@@ -23994,7 +24303,7 @@ function registerGuardCommand(program2) {
|
|
|
23994
24303
|
});
|
|
23995
24304
|
}
|
|
23996
24305
|
function resolveMomentRange(moment, frame, command, on) {
|
|
23997
|
-
return moment === "pre-commit" ? stagedRange(frame) : resolvePushRange(frame, command, on);
|
|
24306
|
+
return moment === "pre-commit" ? stagedRange(frame, command) : resolvePushRange(frame, command, on);
|
|
23998
24307
|
}
|
|
23999
24308
|
function describeRange(range) {
|
|
24000
24309
|
if (range.kind === "staged") return "staged";
|
|
@@ -24154,6 +24463,13 @@ async function runGuard(opts, globals) {
|
|
|
24154
24463
|
);
|
|
24155
24464
|
}
|
|
24156
24465
|
const range = resolveMomentRange(moment, frame, command, on);
|
|
24466
|
+
if (range.refusal) {
|
|
24467
|
+
logEvent("guard_frame", { moment, ...frameTelemetry(frame, range) });
|
|
24468
|
+
emitAllowNotice(
|
|
24469
|
+
`\u26A0 Verity ${moment}: could not tell what this ${verb} will include \u2014 ${verb === "commit" ? "committed" : "pushed"} WITHOUT review`,
|
|
24470
|
+
`Verity ${moment}: this command stages files as it runs and the resulting set could not be resolved (${range.refusal}); the ${verb} was allowed WITHOUT a Verity review. Stage first (\`git add \u2026\`) and re-run the ${verb} to have it reviewed.`
|
|
24471
|
+
);
|
|
24472
|
+
}
|
|
24157
24473
|
const files = rangeFiles(frame, range);
|
|
24158
24474
|
if (files.length === 0) process.exit(0);
|
|
24159
24475
|
const tokenResult = await resolveToken(globals.token);
|
|
@@ -24189,7 +24505,7 @@ async function runGuard(opts, globals) {
|
|
|
24189
24505
|
upgradeToExcerpts(repoContext2, {
|
|
24190
24506
|
readFile: (rel) => {
|
|
24191
24507
|
try {
|
|
24192
|
-
return (0, import_node_fs45.readFileSync)((0,
|
|
24508
|
+
return (0, import_node_fs45.readFileSync)((0, import_node_path32.join)(frame.worktreeRoot ?? process.cwd(), rel), "utf8");
|
|
24193
24509
|
} catch {
|
|
24194
24510
|
return null;
|
|
24195
24511
|
}
|
|
@@ -24258,21 +24574,28 @@ async function runGuard(opts, globals) {
|
|
|
24258
24574
|
${covDetail}${viewUrl ? `
|
|
24259
24575
|
Report: ${viewUrl}` : ""}`
|
|
24260
24576
|
);
|
|
24261
|
-
}
|
|
24262
|
-
if (decision === "WARN") {
|
|
24577
|
+
} else if (decision === "WARN") {
|
|
24263
24578
|
emitAllowNotice(
|
|
24264
24579
|
`\u26A0 Verity ${moment}: WARN \u2014 proceeding (${covLine})${link}`,
|
|
24265
24580
|
`Verity ${moment} review: WARN (proceeding).
|
|
24266
24581
|
${covDetail}${viewUrl ? `
|
|
24267
24582
|
Report: ${viewUrl}` : ""}`
|
|
24268
24583
|
);
|
|
24269
|
-
}
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24584
|
+
} else if (decision === "PASS") {
|
|
24585
|
+
emitAllowNotice(
|
|
24586
|
+
`\u2713 Verity ${moment}: PASS (${covLine})${link}`,
|
|
24587
|
+
`Verity ${moment} review: PASS.
|
|
24273
24588
|
${covDetail}${viewUrl ? `
|
|
24274
24589
|
Report: ${viewUrl}` : ""}`
|
|
24275
|
-
|
|
24590
|
+
);
|
|
24591
|
+
} else {
|
|
24592
|
+
emitAllowNotice(
|
|
24593
|
+
`\u26A0 Verity ${moment}: no verdict came back \u2014 ${verb === "commit" ? "committed" : "pushed"} WITHOUT a usable review (${covLine})${link}`,
|
|
24594
|
+
`Verity ${moment}: the service answered with no recognisable gate decision (${decision}); the ${verb} was allowed, but nothing reviewed it. Treat this as unreviewed, not as a pass.
|
|
24595
|
+
${covDetail}${viewUrl ? `
|
|
24596
|
+
Report: ${viewUrl}` : ""}`
|
|
24597
|
+
);
|
|
24598
|
+
}
|
|
24276
24599
|
}
|
|
24277
24600
|
function writeBlockMessage(moment, response, covDetail) {
|
|
24278
24601
|
const label2 = moment === "pre-commit" ? "pre-commit" : "pre-push";
|
|
@@ -24467,7 +24790,7 @@ function registerWaiveCommand(program2) {
|
|
|
24467
24790
|
var import_node_fs51 = require("node:fs");
|
|
24468
24791
|
var import_promises17 = require("node:fs/promises");
|
|
24469
24792
|
var import_yaml6 = __toESM(require_dist());
|
|
24470
|
-
var
|
|
24793
|
+
var import_node_path35 = require("node:path");
|
|
24471
24794
|
var import_node_child_process16 = require("node:child_process");
|
|
24472
24795
|
|
|
24473
24796
|
// src/lib/banner.ts
|
|
@@ -24504,8 +24827,8 @@ function printBanner(opts) {
|
|
|
24504
24827
|
const dim = (text) => color ? `${DIM3}${text}${RESET2}` : text;
|
|
24505
24828
|
process.stderr.write("\n");
|
|
24506
24829
|
if (!art) {
|
|
24507
|
-
const
|
|
24508
|
-
const text =
|
|
24830
|
+
const candidates2 = [`Verity ${version}`, "Verity"];
|
|
24831
|
+
const text = candidates2.find((c) => c.length + INDENT.length <= columns);
|
|
24509
24832
|
if (text) process.stderr.write(`${INDENT}${dim(text)}
|
|
24510
24833
|
`);
|
|
24511
24834
|
process.stderr.write("\n");
|
|
@@ -24612,13 +24935,13 @@ function checkAnalysisCli() {
|
|
|
24612
24935
|
}
|
|
24613
24936
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
24614
24937
|
function run(command, args, opts = {}) {
|
|
24615
|
-
return new Promise((
|
|
24938
|
+
return new Promise((resolve5) => {
|
|
24616
24939
|
const child = (0, import_node_child_process13.spawn)(command, args, {
|
|
24617
24940
|
stdio: opts.inherit ? "inherit" : "pipe",
|
|
24618
24941
|
timeout: INSTALL_TIMEOUT_MS
|
|
24619
24942
|
});
|
|
24620
|
-
child.on("error", () =>
|
|
24621
|
-
child.on("close", (code) =>
|
|
24943
|
+
child.on("error", () => resolve5(false));
|
|
24944
|
+
child.on("close", (code) => resolve5(code === 0));
|
|
24622
24945
|
});
|
|
24623
24946
|
}
|
|
24624
24947
|
async function installAnalysisCli() {
|
|
@@ -24717,8 +25040,8 @@ function ensureVerityGitignore() {
|
|
|
24717
25040
|
next = lines.map((l) => BREAKING_ENTRIES.has(l.trim()) ? ".verity/*" : l).join("\n");
|
|
24718
25041
|
}
|
|
24719
25042
|
if (!hasMarker) {
|
|
24720
|
-
const
|
|
24721
|
-
next = next +
|
|
25043
|
+
const sep3 = next === "" ? "" : next.endsWith("\n") ? "\n" : "\n\n";
|
|
25044
|
+
next = next + sep3 + VERITY_GITIGNORE_BLOCK;
|
|
24722
25045
|
}
|
|
24723
25046
|
(0, import_node_fs47.writeFileSync)(".gitignore", next);
|
|
24724
25047
|
return verified(needsRepair ? "repaired" : "added");
|
|
@@ -24845,7 +25168,8 @@ async function uninstallTelemetry() {
|
|
|
24845
25168
|
async function buildReport() {
|
|
24846
25169
|
const prereqs = await checkPrereqs({ install: false });
|
|
24847
25170
|
const state = await readSetupState();
|
|
24848
|
-
const
|
|
25171
|
+
const wiring = await resolveHookWiring();
|
|
25172
|
+
const hooks = wiring.status;
|
|
24849
25173
|
const telemetry = await checkTelemetry();
|
|
24850
25174
|
const hasConfig = (0, import_node_fs48.existsSync)(projectPath(CODACY_CONFIG_FILE));
|
|
24851
25175
|
const artifacts = {
|
|
@@ -24884,6 +25208,11 @@ async function buildReport() {
|
|
|
24884
25208
|
'Your analysis config names pattern ids that no longer resolve, so those tools run with nothing enabled and report zero issues. Fix: "verity standard synthesize --config-only" (or re-run "verity init").'
|
|
24885
25209
|
);
|
|
24886
25210
|
}
|
|
25211
|
+
if (wiring.duplicateSettingsHooks) {
|
|
25212
|
+
next.push(
|
|
25213
|
+
'Duplicate Verity hooks also exist in .claude/settings.json. They stand down at run time under the plugin, but remove them with "verity init --plugin-mode" so the wiring says what it does.'
|
|
25214
|
+
);
|
|
25215
|
+
}
|
|
24887
25216
|
if (state?.telemetry === "deferred") {
|
|
24888
25217
|
next.push('Telemetry was requested but needs a token \u2014 run "verity login", then "verity telemetry install".');
|
|
24889
25218
|
}
|
|
@@ -24899,7 +25228,12 @@ async function buildReport() {
|
|
|
24899
25228
|
moments: state?.moments ?? null,
|
|
24900
25229
|
telemetry: state?.telemetry ?? null
|
|
24901
25230
|
},
|
|
24902
|
-
hooks: {
|
|
25231
|
+
hooks: {
|
|
25232
|
+
source: wiring.source,
|
|
25233
|
+
...hooks,
|
|
25234
|
+
duplicateSettingsHooks: wiring.duplicateSettingsHooks,
|
|
25235
|
+
noAnalysisMoment
|
|
25236
|
+
},
|
|
24903
25237
|
telemetry: { enabled: telemetry.enabled, endpoint: telemetry.endpoint },
|
|
24904
25238
|
artifacts,
|
|
24905
25239
|
next
|
|
@@ -24922,8 +25256,9 @@ function registerDoctorCommand(program2) {
|
|
|
24922
25256
|
printInfo(` verity init: ${report.phases.init.done ? `done ${report.phases.init.completed_at ?? ""}`.trim() : "NOT run here"}`);
|
|
24923
25257
|
printInfo(` /verity-setup: ${report.phases.setup.done ? "done" : "not completed"}`);
|
|
24924
25258
|
printInfo(` intensity: ${report.answers.intensity ?? "\u2014"} moments: ${report.answers.moments?.join(", ") ?? "\u2014"}`);
|
|
24925
|
-
|
|
24926
|
-
printInfo(
|
|
25259
|
+
const plugin = report.hooks.source === "plugin";
|
|
25260
|
+
printInfo(plugin ? "Hooks: wired by the Verity Claude Code plugin (not .claude/settings.json)" : "Hooks:");
|
|
25261
|
+
printInfo(` Stop (verity analyze): ${report.hooks.stop ? plugin ? "on (plugin)" : "on" : "off"}`);
|
|
24927
25262
|
printInfo(` Git-moment gate: ${report.hooks.guardOn.length ? report.hooks.guardOn.join(", ") : "off"}`);
|
|
24928
25263
|
printInfo(` Infra (intent/baseline/compact/session-end): ${[report.hooks.intent, report.hooks.baseline, report.hooks.compact, report.hooks.sessionEnd].filter(Boolean).length}/4`);
|
|
24929
25264
|
printInfo(`Telemetry: ${report.telemetry.enabled ? `enabled \u2192 ${report.telemetry.endpoint}` : "disabled"}`);
|
|
@@ -24946,7 +25281,7 @@ function registerDoctorCommand(program2) {
|
|
|
24946
25281
|
|
|
24947
25282
|
// src/commands/migrate.ts
|
|
24948
25283
|
var import_node_fs49 = require("node:fs");
|
|
24949
|
-
var
|
|
25284
|
+
var import_node_path33 = require("node:path");
|
|
24950
25285
|
var import_node_child_process15 = require("node:child_process");
|
|
24951
25286
|
var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
|
|
24952
25287
|
function defaultNpmRemover(pkg) {
|
|
@@ -24983,8 +25318,8 @@ async function runMigration(opts = {}) {
|
|
|
24983
25318
|
return { actions, migrated: actions.length > 0 };
|
|
24984
25319
|
}
|
|
24985
25320
|
function migrateProjectDir(root, actions) {
|
|
24986
|
-
const gateDir = (0,
|
|
24987
|
-
const verityDir = (0,
|
|
25321
|
+
const gateDir = (0, import_node_path33.join)(root, ".gate");
|
|
25322
|
+
const verityDir = (0, import_node_path33.join)(root, ".verity");
|
|
24988
25323
|
if ((0, import_node_fs49.existsSync)(gateDir) && !(0, import_node_fs49.existsSync)(verityDir)) {
|
|
24989
25324
|
return migrateProjectDirRename(root, gateDir, verityDir, actions);
|
|
24990
25325
|
}
|
|
@@ -25038,11 +25373,11 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
|
|
|
25038
25373
|
}
|
|
25039
25374
|
function migrateGlobalCredentials(home, actions) {
|
|
25040
25375
|
if (!home) return;
|
|
25041
|
-
const gateCreds = (0,
|
|
25042
|
-
const verityCreds = (0,
|
|
25376
|
+
const gateCreds = (0, import_node_path33.join)(home, ".gate", "credentials");
|
|
25377
|
+
const verityCreds = (0, import_node_path33.join)(home, ".verity", "credentials");
|
|
25043
25378
|
if (!(0, import_node_fs49.existsSync)(gateCreds)) return;
|
|
25044
25379
|
if (!(0, import_node_fs49.existsSync)(verityCreds)) {
|
|
25045
|
-
(0, import_node_fs49.mkdirSync)((0,
|
|
25380
|
+
(0, import_node_fs49.mkdirSync)((0, import_node_path33.join)(home, ".verity"), { recursive: true });
|
|
25046
25381
|
moveFile(gateCreds, verityCreds);
|
|
25047
25382
|
actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
|
|
25048
25383
|
return;
|
|
@@ -25064,7 +25399,7 @@ async function migrateLegacyHooks(root, actions) {
|
|
|
25064
25399
|
}
|
|
25065
25400
|
}
|
|
25066
25401
|
async function migrateClaudeMd(root, actions) {
|
|
25067
|
-
const claudeMd = (0,
|
|
25402
|
+
const claudeMd = (0, import_node_path33.join)(root, "CLAUDE.md");
|
|
25068
25403
|
const hadLegacyBlock = (0, import_node_fs49.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
|
|
25069
25404
|
if (!hadLegacyBlock) return;
|
|
25070
25405
|
try {
|
|
@@ -25075,8 +25410,8 @@ async function migrateClaudeMd(root, actions) {
|
|
|
25075
25410
|
}
|
|
25076
25411
|
}
|
|
25077
25412
|
function migrateStandardFile(root, actions) {
|
|
25078
|
-
const gateMd = (0,
|
|
25079
|
-
const verityMd = (0,
|
|
25413
|
+
const gateMd = (0, import_node_path33.join)(root, "GATE.md");
|
|
25414
|
+
const verityMd = (0, import_node_path33.join)(root, "VERITY.md");
|
|
25080
25415
|
if (!(0, import_node_fs49.existsSync)(gateMd) || (0, import_node_fs49.existsSync)(verityMd)) return;
|
|
25081
25416
|
let moved = false;
|
|
25082
25417
|
if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
|
|
@@ -25093,7 +25428,7 @@ function migrateStandardFile(root, actions) {
|
|
|
25093
25428
|
actions.push("Renamed GATE.md \u2192 VERITY.md");
|
|
25094
25429
|
}
|
|
25095
25430
|
async function migrateTelemetryHeaders(root, actions) {
|
|
25096
|
-
const file = (0,
|
|
25431
|
+
const file = (0, import_node_path33.join)(root, ".claude", "settings.local.json");
|
|
25097
25432
|
if (!(0, import_node_fs49.existsSync)(file)) return;
|
|
25098
25433
|
let settings;
|
|
25099
25434
|
try {
|
|
@@ -25141,8 +25476,8 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
|
|
|
25141
25476
|
toAppend.push(line.replace(/\r$/, ""));
|
|
25142
25477
|
}
|
|
25143
25478
|
if (toAppend.length > 0) {
|
|
25144
|
-
const
|
|
25145
|
-
(0, import_node_fs49.writeFileSync)(verityCreds, verityContent +
|
|
25479
|
+
const sep3 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
|
|
25480
|
+
(0, import_node_fs49.writeFileSync)(verityCreds, verityContent + sep3 + toAppend.join("\n") + "\n");
|
|
25146
25481
|
}
|
|
25147
25482
|
(0, import_node_fs49.rmSync)(gateCreds, { force: true });
|
|
25148
25483
|
return toAppend.length;
|
|
@@ -25183,15 +25518,15 @@ function moveFile(from, to) {
|
|
|
25183
25518
|
function carryLegacyContents(gateDir, verityDir) {
|
|
25184
25519
|
let copied = 0;
|
|
25185
25520
|
const walk2 = (relDir) => {
|
|
25186
|
-
const srcDir = (0,
|
|
25521
|
+
const srcDir = (0, import_node_path33.join)(gateDir, relDir);
|
|
25187
25522
|
for (const entry of (0, import_node_fs49.readdirSync)(srcDir)) {
|
|
25188
|
-
const rel = relDir ? (0,
|
|
25189
|
-
const src = (0,
|
|
25190
|
-
const dest = (0,
|
|
25523
|
+
const rel = relDir ? (0, import_node_path33.join)(relDir, entry) : entry;
|
|
25524
|
+
const src = (0, import_node_path33.join)(gateDir, rel);
|
|
25525
|
+
const dest = (0, import_node_path33.join)(verityDir, rel);
|
|
25191
25526
|
if ((0, import_node_fs49.statSync)(src).isDirectory()) {
|
|
25192
25527
|
walk2(rel);
|
|
25193
25528
|
} else if (!(0, import_node_fs49.existsSync)(dest)) {
|
|
25194
|
-
(0, import_node_fs49.mkdirSync)((0,
|
|
25529
|
+
(0, import_node_fs49.mkdirSync)((0, import_node_path33.dirname)(dest), { recursive: true });
|
|
25195
25530
|
(0, import_node_fs49.cpSync)(src, dest);
|
|
25196
25531
|
copied++;
|
|
25197
25532
|
}
|
|
@@ -25201,22 +25536,22 @@ function carryLegacyContents(gateDir, verityDir) {
|
|
|
25201
25536
|
return copied;
|
|
25202
25537
|
}
|
|
25203
25538
|
async function needsMigration(root = repoRoot()) {
|
|
25204
|
-
const gateDir = (0,
|
|
25205
|
-
const verityDir = (0,
|
|
25539
|
+
const gateDir = (0, import_node_path33.join)(root, ".gate");
|
|
25540
|
+
const verityDir = (0, import_node_path33.join)(root, ".verity");
|
|
25206
25541
|
if ((0, import_node_fs49.existsSync)(gateDir) && !(0, import_node_fs49.existsSync)(verityDir)) return true;
|
|
25207
25542
|
if ((0, import_node_fs49.existsSync)(gateDir) && (0, import_node_fs49.existsSync)(verityDir)) {
|
|
25208
|
-
if ((0, import_node_fs49.existsSync)((0,
|
|
25543
|
+
if ((0, import_node_fs49.existsSync)((0, import_node_path33.join)(gateDir, "credentials")) && !(0, import_node_fs49.existsSync)((0, import_node_path33.join)(verityDir, "credentials"))) {
|
|
25209
25544
|
return true;
|
|
25210
25545
|
}
|
|
25211
|
-
if ((0, import_node_fs49.existsSync)((0,
|
|
25546
|
+
if ((0, import_node_fs49.existsSync)((0, import_node_path33.join)(gateDir, "memory")) && !(0, import_node_fs49.existsSync)((0, import_node_path33.join)(verityDir, "memory"))) {
|
|
25212
25547
|
return true;
|
|
25213
25548
|
}
|
|
25214
25549
|
}
|
|
25215
|
-
const claudeMd = (0,
|
|
25550
|
+
const claudeMd = (0, import_node_path33.join)(root, "CLAUDE.md");
|
|
25216
25551
|
if ((0, import_node_fs49.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
|
|
25217
25552
|
return true;
|
|
25218
25553
|
}
|
|
25219
|
-
if ((0, import_node_fs49.existsSync)((0,
|
|
25554
|
+
if ((0, import_node_fs49.existsSync)((0, import_node_path33.join)(root, "GATE.md")) && !(0, import_node_fs49.existsSync)((0, import_node_path33.join)(root, "VERITY.md"))) {
|
|
25220
25555
|
return true;
|
|
25221
25556
|
}
|
|
25222
25557
|
if (await hasLegacyHooksAt(root)) return true;
|
|
@@ -25339,7 +25674,7 @@ function runSelect(opts) {
|
|
|
25339
25674
|
cursor: initialIdx[0] ?? 0,
|
|
25340
25675
|
chosen: new Set(mode2 === "single" ? [initialIdx[0] ?? 0] : initialIdx)
|
|
25341
25676
|
};
|
|
25342
|
-
return new Promise((
|
|
25677
|
+
return new Promise((resolve5) => {
|
|
25343
25678
|
let painted = 0;
|
|
25344
25679
|
let settled = false;
|
|
25345
25680
|
const draw = () => {
|
|
@@ -25387,7 +25722,7 @@ function runSelect(opts) {
|
|
|
25387
25722
|
if (settled) return;
|
|
25388
25723
|
settled = true;
|
|
25389
25724
|
restore();
|
|
25390
|
-
|
|
25725
|
+
resolve5(value);
|
|
25391
25726
|
};
|
|
25392
25727
|
readline2.emitKeypressEvents(input);
|
|
25393
25728
|
input.setRawMode(true);
|
|
@@ -25408,9 +25743,9 @@ async function askLine(question, io = {}) {
|
|
|
25408
25743
|
output: io.output ?? process.stdout
|
|
25409
25744
|
});
|
|
25410
25745
|
try {
|
|
25411
|
-
return await new Promise((
|
|
25412
|
-
rl.question(question).then((a) =>
|
|
25413
|
-
rl.once("close", () => setImmediate(() =>
|
|
25746
|
+
return await new Promise((resolve5) => {
|
|
25747
|
+
rl.question(question).then((a) => resolve5(a.trim())).catch(() => resolve5(null));
|
|
25748
|
+
rl.once("close", () => setImmediate(() => resolve5(null)));
|
|
25414
25749
|
});
|
|
25415
25750
|
} finally {
|
|
25416
25751
|
rl.close();
|
|
@@ -25493,7 +25828,7 @@ async function promptMultiSelect(question, choices, fallback) {
|
|
|
25493
25828
|
// src/lib/remote-config.ts
|
|
25494
25829
|
var import_node_fs50 = require("node:fs");
|
|
25495
25830
|
var import_promises16 = require("node:fs/promises");
|
|
25496
|
-
var
|
|
25831
|
+
var import_node_path34 = require("node:path");
|
|
25497
25832
|
var import_yaml5 = __toESM(require_dist());
|
|
25498
25833
|
var IGNORE_RIDER = "verityignore";
|
|
25499
25834
|
async function fetchRemoteSetup(opts) {
|
|
@@ -25571,7 +25906,7 @@ async function adoptRemoteSetup(found, opts) {
|
|
|
25571
25906
|
}
|
|
25572
25907
|
async function writeOut(relative2, body) {
|
|
25573
25908
|
const target = projectPath(relative2);
|
|
25574
|
-
await (0, import_promises16.mkdir)((0,
|
|
25909
|
+
await (0, import_promises16.mkdir)((0, import_node_path34.dirname)(target), { recursive: true });
|
|
25575
25910
|
await (0, import_promises16.writeFile)(target, body);
|
|
25576
25911
|
}
|
|
25577
25912
|
function describeRemote(found) {
|
|
@@ -25687,16 +26022,16 @@ async function runOptionalAuth(resolution, opts = {}) {
|
|
|
25687
26022
|
}
|
|
25688
26023
|
}
|
|
25689
26024
|
function resolveDataDir2() {
|
|
25690
|
-
const
|
|
25691
|
-
(0,
|
|
26025
|
+
const candidates2 = [
|
|
26026
|
+
(0, import_node_path35.join)(__dirname, "..", "data"),
|
|
25692
26027
|
// installed: node_modules/@codacy/verity-cli/data
|
|
25693
|
-
(0,
|
|
26028
|
+
(0, import_node_path35.join)(__dirname, "..", "..", "data"),
|
|
25694
26029
|
// edge case: nested resolution
|
|
25695
|
-
(0,
|
|
26030
|
+
(0, import_node_path35.join)(process.cwd(), "cli", "data")
|
|
25696
26031
|
// local dev: running from repo root
|
|
25697
26032
|
];
|
|
25698
|
-
for (const candidate of
|
|
25699
|
-
if ((0, import_node_fs51.existsSync)((0,
|
|
26033
|
+
for (const candidate of candidates2) {
|
|
26034
|
+
if ((0, import_node_fs51.existsSync)((0, import_node_path35.join)(candidate, "skills"))) {
|
|
25700
26035
|
return candidate;
|
|
25701
26036
|
}
|
|
25702
26037
|
}
|
|
@@ -25714,7 +26049,7 @@ async function skillIsCurrent(src, dest) {
|
|
|
25714
26049
|
const walk2 = (d, prefix) => {
|
|
25715
26050
|
for (const e of (0, import_node_fs51.readdirSync)(d, { withFileTypes: true })) {
|
|
25716
26051
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
25717
|
-
if (e.isDirectory()) walk2((0,
|
|
26052
|
+
if (e.isDirectory()) walk2((0, import_node_path35.join)(d, e.name), rel);
|
|
25718
26053
|
else if (e.isFile()) out.push(rel);
|
|
25719
26054
|
}
|
|
25720
26055
|
};
|
|
@@ -25725,8 +26060,8 @@ async function skillIsCurrent(src, dest) {
|
|
|
25725
26060
|
const shipped = list2(src);
|
|
25726
26061
|
if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
|
|
25727
26062
|
for (const rel of shipped) {
|
|
25728
|
-
const a = await (0, import_promises17.readFile)((0,
|
|
25729
|
-
const b = await (0, import_promises17.readFile)((0,
|
|
26063
|
+
const a = await (0, import_promises17.readFile)((0, import_node_path35.join)(src, rel), "utf-8");
|
|
26064
|
+
const b = await (0, import_promises17.readFile)((0, import_node_path35.join)(dest, rel), "utf-8");
|
|
25730
26065
|
if (a !== b) return false;
|
|
25731
26066
|
}
|
|
25732
26067
|
return true;
|
|
@@ -26001,12 +26336,12 @@ async function handoffToSetup(enabled, claudeInstalled) {
|
|
|
26001
26336
|
async function installSkills(force, step) {
|
|
26002
26337
|
step("Installing skills");
|
|
26003
26338
|
const dataDir = resolveDataDir2();
|
|
26004
|
-
const skillsSource = (0,
|
|
26339
|
+
const skillsSource = (0, import_node_path35.join)(dataDir, "skills");
|
|
26005
26340
|
const skillsDest = ".claude/skills";
|
|
26006
26341
|
let skillsInstalled = 0;
|
|
26007
26342
|
for (const skill of SKILLS) {
|
|
26008
|
-
const src = (0,
|
|
26009
|
-
const dest = (0,
|
|
26343
|
+
const src = (0, import_node_path35.join)(skillsSource, skill);
|
|
26344
|
+
const dest = (0, import_node_path35.join)(skillsDest, skill);
|
|
26010
26345
|
if (!(0, import_node_fs51.existsSync)(src)) {
|
|
26011
26346
|
printWarn(` Skill data not found: ${skill}`);
|
|
26012
26347
|
continue;
|
|
@@ -26109,12 +26444,16 @@ function registerInitCommand(program2) {
|
|
|
26109
26444
|
program2.command("init").alias("setup").description("Set up Verity in the current project (asks the setup questions, then hands off to /verity-setup)").option("--force", "Reinstall the skills even when they are already up to date (hooks are always reconciled)").option("-y, --yes", "Take the recommended answer for every question (no prompts)").option("--no-setup", "Skip the /verity-setup handoff at the end").option(
|
|
26110
26445
|
"--plugin-mode",
|
|
26111
26446
|
"The Claude Code plugin owns the skills and hooks: install neither, and remove any this project already has"
|
|
26447
|
+
).option(
|
|
26448
|
+
"--no-plugin",
|
|
26449
|
+
"Ignore any Claude Code plugin here and wire this project's own skills and hooks"
|
|
26112
26450
|
).option("--no-adopt", "Don't offer this repository's existing Standard from the service; synthesize a new one").action(async (opts) => {
|
|
26113
26451
|
const force = opts.force ?? false;
|
|
26114
26452
|
const wantsHandoff = opts.setup !== false;
|
|
26115
26453
|
const wantsAdopt = opts.adopt !== false;
|
|
26116
26454
|
const defaultsOnly = (opts.yes ?? false) || !interactive();
|
|
26117
|
-
const
|
|
26455
|
+
const staleMarker = clearStalePluginMarker();
|
|
26456
|
+
const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
|
|
26118
26457
|
const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
|
|
26119
26458
|
const isProject = projectMarkers.some((m) => (0, import_node_fs51.existsSync)(m));
|
|
26120
26459
|
if (!isProject) {
|
|
@@ -26131,6 +26470,24 @@ function registerInitCommand(program2) {
|
|
|
26131
26470
|
} else {
|
|
26132
26471
|
printPhase(1, 2, "this machine", "prerequisites \xB7 skills \xB7 hooks \xB7 sign-in");
|
|
26133
26472
|
}
|
|
26473
|
+
if (staleMarker) {
|
|
26474
|
+
printInfo(`Cleared a stale plugin marker \u2014 ${staleMarker.pluginRoot} is no longer installed.`);
|
|
26475
|
+
}
|
|
26476
|
+
const install = pluginMode ? activePluginInstall() : null;
|
|
26477
|
+
if (pluginMode) {
|
|
26478
|
+
const where = install ? ` \u2014 ${install.pluginRoot}${install.version ? ` (v${install.version})` : ""}` : "";
|
|
26479
|
+
printInfo(`Hooks here: the Verity Claude Code plugin${where}.`);
|
|
26480
|
+
printInfo(" It wires every event for every project, so this one gets no skills or settings.json");
|
|
26481
|
+
printInfo(" hooks of its own, and any left by an earlier npm install are removed below.");
|
|
26482
|
+
printInfo(" Not what you want here? Re-run with --no-plugin.");
|
|
26483
|
+
} else if (opts.plugin === false && pluginActiveHere()) {
|
|
26484
|
+
printWarn("Hooks here: this project's .claude/settings.json (--no-plugin).");
|
|
26485
|
+
printWarn(" The Verity plugin is active on this machine and would otherwise own them. Both sets");
|
|
26486
|
+
printWarn(" will fire; the settings.json copy stands down at run time so each turn is gated once.");
|
|
26487
|
+
} else {
|
|
26488
|
+
printInfo("Hooks here: this project's .claude/settings.json (no Verity Claude Code plugin is active).");
|
|
26489
|
+
}
|
|
26490
|
+
console.log("");
|
|
26134
26491
|
const TOTAL_STEPS = 9;
|
|
26135
26492
|
let stepNo = 0;
|
|
26136
26493
|
const step = (label2) => {
|
|
@@ -26162,7 +26519,7 @@ function registerInitCommand(program2) {
|
|
|
26162
26519
|
printInfo(` intensity: ${intensity} \xB7 moments: ${moments.join(", ") || "none"} (no questions asked)`);
|
|
26163
26520
|
}
|
|
26164
26521
|
await scaffoldProject(step, defaultsOnly);
|
|
26165
|
-
const globalVerityDir = (0,
|
|
26522
|
+
const globalVerityDir = (0, import_node_path35.join)(process.env.HOME ?? "", ".verity");
|
|
26166
26523
|
await (0, import_promises17.mkdir)(globalVerityDir, { recursive: true });
|
|
26167
26524
|
console.log("");
|
|
26168
26525
|
step("Wiring Claude Code hooks");
|
|
@@ -26244,7 +26601,7 @@ function registerInitCommand(program2) {
|
|
|
26244
26601
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
26245
26602
|
init: {
|
|
26246
26603
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26247
|
-
cli_version: true ? "0.32.0-experimental.
|
|
26604
|
+
cli_version: true ? "0.32.0-experimental.cc76941" : "dev"
|
|
26248
26605
|
}
|
|
26249
26606
|
});
|
|
26250
26607
|
} catch (err) {
|
|
@@ -26284,7 +26641,7 @@ function registerInitCommand(program2) {
|
|
|
26284
26641
|
|
|
26285
26642
|
// src/commands/uninstall.ts
|
|
26286
26643
|
var import_node_fs52 = require("node:fs");
|
|
26287
|
-
var
|
|
26644
|
+
var import_node_path36 = require("node:path");
|
|
26288
26645
|
var SKILL_NAMES = [
|
|
26289
26646
|
"verity-setup",
|
|
26290
26647
|
"verity-analyze",
|
|
@@ -26303,7 +26660,7 @@ function registerUninstallCommand(program2) {
|
|
|
26303
26660
|
const actions = [];
|
|
26304
26661
|
const skillsRoot = projectPath(".claude/skills");
|
|
26305
26662
|
for (const name of SKILL_NAMES) {
|
|
26306
|
-
const dir = (0,
|
|
26663
|
+
const dir = (0, import_node_path36.join)(skillsRoot, name);
|
|
26307
26664
|
if ((0, import_node_fs52.existsSync)(dir)) {
|
|
26308
26665
|
actions.push({
|
|
26309
26666
|
label: `Remove .claude/skills/${name}/`,
|
|
@@ -26349,7 +26706,7 @@ function registerUninstallCommand(program2) {
|
|
|
26349
26706
|
}
|
|
26350
26707
|
});
|
|
26351
26708
|
const home = process.env.HOME ?? "";
|
|
26352
|
-
const globalVerityDir = (0,
|
|
26709
|
+
const globalVerityDir = (0, import_node_path36.join)(home, ".verity");
|
|
26353
26710
|
if (purgeGlobal && (0, import_node_fs52.existsSync)(globalVerityDir)) {
|
|
26354
26711
|
actions.push({
|
|
26355
26712
|
label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
|
|
@@ -26548,7 +26905,7 @@ function registerTaskCommands(program2) {
|
|
|
26548
26905
|
|
|
26549
26906
|
// src/commands/reset.ts
|
|
26550
26907
|
var import_node_fs53 = require("node:fs");
|
|
26551
|
-
var
|
|
26908
|
+
var import_node_path37 = require("node:path");
|
|
26552
26909
|
function registerResetCommand(program2) {
|
|
26553
26910
|
program2.command("reset").description("Close the current task and clear transient state").option("--keep-task", "Only purge caches; leave the current task open").option("--all", "Also purge diagnostic logs (.verity/.logs/)").action(async (opts) => {
|
|
26554
26911
|
const globals = program2.opts();
|
|
@@ -26589,7 +26946,7 @@ function registerResetCommand(program2) {
|
|
|
26589
26946
|
for (const entry of (0, import_node_fs53.readdirSync)(cacheDir)) {
|
|
26590
26947
|
if (entry.startsWith("pending-")) {
|
|
26591
26948
|
try {
|
|
26592
|
-
(0, import_node_fs53.unlinkSync)((0,
|
|
26949
|
+
(0, import_node_fs53.unlinkSync)((0, import_node_path37.join)(cacheDir, entry));
|
|
26593
26950
|
purged++;
|
|
26594
26951
|
} catch {
|
|
26595
26952
|
}
|
|
@@ -26616,7 +26973,7 @@ function registerResetCommand(program2) {
|
|
|
26616
26973
|
if ((0, import_node_fs53.existsSync)(logsDir)) {
|
|
26617
26974
|
for (const entry of (0, import_node_fs53.readdirSync)(logsDir)) {
|
|
26618
26975
|
try {
|
|
26619
|
-
(0, import_node_fs53.unlinkSync)((0,
|
|
26976
|
+
(0, import_node_fs53.unlinkSync)((0, import_node_path37.join)(logsDir, entry));
|
|
26620
26977
|
} catch {
|
|
26621
26978
|
}
|
|
26622
26979
|
}
|
|
@@ -26924,8 +27281,8 @@ function registerTelemetryCommands(program2) {
|
|
|
26924
27281
|
}
|
|
26925
27282
|
|
|
26926
27283
|
// src/cli.ts
|
|
26927
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.32.0-experimental.
|
|
26928
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.0-experimental.
|
|
27284
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.32.0-experimental.cc76941").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) => {
|
|
27285
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.0-experimental.cc76941");
|
|
26929
27286
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
26930
27287
|
try {
|
|
26931
27288
|
await foldLegacyLocalCredential();
|