@codacy/verity-cli 0.32.4 → 0.32.5-experimental.4d91ca0
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 +16 -0
- package/bin/verity.js +104 -26
- package/data/skills/verity-init/SKILL.md +25 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -64,6 +64,22 @@ installs are untouched.
|
|
|
64
64
|
which is the ordinary case for someone whose first Verity install *is* the
|
|
65
65
|
plugin.
|
|
66
66
|
|
|
67
|
+
## [0.32.5] — 2026-09-11
|
|
68
|
+
|
|
69
|
+
**`/verity:init` fixes, reported from its first runs.**
|
|
70
|
+
|
|
71
|
+
- **An old global `verity` can no longer derail setup.** If the `verity` on your
|
|
72
|
+
PATH is a different version from the plugin's, Verity's skills now use the
|
|
73
|
+
plugin's own copy — the one its hooks run — so your setup answers always apply.
|
|
74
|
+
Verity also tells you when the session starts, before `/verity:init` asks
|
|
75
|
+
anything, with the `npm install -g` command that brings the global one in line.
|
|
76
|
+
- **"After every turn" says what it is.** With the plugin, the after-every-turn
|
|
77
|
+
review can't be turned off yet. The setup question now says so instead of
|
|
78
|
+
calling it "recommended".
|
|
79
|
+
- **The update instructions name commands that exist.** Claude Code has no
|
|
80
|
+
`/plugin update`. The README now explains auto-update, and `/reload-plugins`
|
|
81
|
+
picks up a new version without restarting.
|
|
82
|
+
|
|
67
83
|
## [0.32.4] — 2026-09-11
|
|
68
84
|
|
|
69
85
|
**Setup asks you how you want Verity to work.** Until now, installing the Claude
|
package/bin/verity.js
CHANGED
|
@@ -6849,6 +6849,7 @@ var require_resolve_props = __commonJS({
|
|
|
6849
6849
|
hasSpace = false;
|
|
6850
6850
|
break;
|
|
6851
6851
|
}
|
|
6852
|
+
// else fallthrough
|
|
6852
6853
|
default:
|
|
6853
6854
|
onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.type} token`);
|
|
6854
6855
|
atNewline = false;
|
|
@@ -7557,6 +7558,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
7557
7558
|
switch (token.type) {
|
|
7558
7559
|
case "space":
|
|
7559
7560
|
hasSpace = true;
|
|
7561
|
+
// fallthrough
|
|
7560
7562
|
case "newline":
|
|
7561
7563
|
length += token.source.length;
|
|
7562
7564
|
break;
|
|
@@ -7572,6 +7574,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
7572
7574
|
onError(token, "UNEXPECTED_TOKEN", token.message);
|
|
7573
7575
|
length += token.source.length;
|
|
7574
7576
|
break;
|
|
7577
|
+
/* istanbul ignore next should not happen */
|
|
7575
7578
|
default: {
|
|
7576
7579
|
const message = `Unexpected token in block scalar header: ${token.type}`;
|
|
7577
7580
|
onError(token, "UNEXPECTED_TOKEN", message);
|
|
@@ -7621,6 +7624,7 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
7621
7624
|
_type = Scalar.Scalar.QUOTE_DOUBLE;
|
|
7622
7625
|
value = doubleQuotedValue(source, _onError);
|
|
7623
7626
|
break;
|
|
7627
|
+
/* istanbul ignore next should not happen */
|
|
7624
7628
|
default:
|
|
7625
7629
|
onError(scalar, "UNEXPECTED_TOKEN", `Expected a flow scalar value, but found: ${type}`);
|
|
7626
7630
|
return {
|
|
@@ -7642,6 +7646,7 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
7642
7646
|
function plainValue(source, onError) {
|
|
7643
7647
|
let badChar = "";
|
|
7644
7648
|
switch (source[0]) {
|
|
7649
|
+
/* istanbul ignore next should not happen */
|
|
7645
7650
|
case " ":
|
|
7646
7651
|
badChar = "a tab character";
|
|
7647
7652
|
break;
|
|
@@ -8905,6 +8910,7 @@ var require_lexer = __commonJS({
|
|
|
8905
8910
|
switch (line[n]) {
|
|
8906
8911
|
case "#":
|
|
8907
8912
|
yield* this.pushCount(line.length - n);
|
|
8913
|
+
// fallthrough
|
|
8908
8914
|
case void 0:
|
|
8909
8915
|
yield* this.pushNewline();
|
|
8910
8916
|
return yield* this.parseLineStart();
|
|
@@ -9000,6 +9006,7 @@ var require_lexer = __commonJS({
|
|
|
9000
9006
|
return "flow";
|
|
9001
9007
|
}
|
|
9002
9008
|
}
|
|
9009
|
+
// fallthrough
|
|
9003
9010
|
default:
|
|
9004
9011
|
this.flowKey = false;
|
|
9005
9012
|
return yield* this.parsePlainScalar();
|
|
@@ -9077,6 +9084,7 @@ var require_lexer = __commonJS({
|
|
|
9077
9084
|
if (next === "\n")
|
|
9078
9085
|
break;
|
|
9079
9086
|
}
|
|
9087
|
+
// fallthrough
|
|
9080
9088
|
default:
|
|
9081
9089
|
break loop;
|
|
9082
9090
|
}
|
|
@@ -9194,7 +9202,9 @@ var require_lexer = __commonJS({
|
|
|
9194
9202
|
case "&":
|
|
9195
9203
|
return (yield* this.pushUntil(isNotAnchorChar)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
|
|
9196
9204
|
case "-":
|
|
9205
|
+
// this is an error
|
|
9197
9206
|
case "?":
|
|
9207
|
+
// this is an error outside flow collections
|
|
9198
9208
|
case ":": {
|
|
9199
9209
|
const inFlow = this.flowLevel > 0;
|
|
9200
9210
|
const ch1 = this.charAt(1);
|
|
@@ -9343,6 +9353,7 @@ var require_parser = __commonJS({
|
|
|
9343
9353
|
}
|
|
9344
9354
|
case "block-seq":
|
|
9345
9355
|
return parent.items[parent.items.length - 1].start;
|
|
9356
|
+
/* istanbul ignore next should not happen */
|
|
9346
9357
|
default:
|
|
9347
9358
|
return [];
|
|
9348
9359
|
}
|
|
@@ -9576,6 +9587,7 @@ var require_parser = __commonJS({
|
|
|
9576
9587
|
Object.assign(it, { key: token, sep: [] });
|
|
9577
9588
|
return;
|
|
9578
9589
|
}
|
|
9590
|
+
/* istanbul ignore next should not happen */
|
|
9579
9591
|
default:
|
|
9580
9592
|
yield* this.pop();
|
|
9581
9593
|
yield* this.pop(token);
|
|
@@ -9697,6 +9709,7 @@ var require_parser = __commonJS({
|
|
|
9697
9709
|
}
|
|
9698
9710
|
yield* this.pop();
|
|
9699
9711
|
break;
|
|
9712
|
+
/* istanbul ignore next should not happen */
|
|
9700
9713
|
default:
|
|
9701
9714
|
yield* this.pop();
|
|
9702
9715
|
yield* this.step();
|
|
@@ -10142,6 +10155,7 @@ var require_parser = __commonJS({
|
|
|
10142
10155
|
break;
|
|
10143
10156
|
case "newline":
|
|
10144
10157
|
this.onKeyLine = false;
|
|
10158
|
+
// fallthrough
|
|
10145
10159
|
case "space":
|
|
10146
10160
|
case "comment":
|
|
10147
10161
|
default:
|
|
@@ -10509,7 +10523,7 @@ var SECURITY_PATTERNS = [
|
|
|
10509
10523
|
/Dockerfile/
|
|
10510
10524
|
];
|
|
10511
10525
|
var PROD_SERVICE_URL = "https://ofcamwrjwrkazqvdchko.supabase.co/functions/v1";
|
|
10512
|
-
var DEFAULT_SERVICE_URL = "".length > 0 ? "" : PROD_SERVICE_URL;
|
|
10526
|
+
var DEFAULT_SERVICE_URL = "https://wukeddyzpijoegyajtnc.supabase.co/functions/v1".length > 0 ? "https://wukeddyzpijoegyajtnc.supabase.co/functions/v1" : PROD_SERVICE_URL;
|
|
10513
10527
|
var GITHUB_CLIENT_ID = "Iv23li88HxAi3ZrbYzWh";
|
|
10514
10528
|
var GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
|
|
10515
10529
|
var GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
@@ -11612,6 +11626,7 @@ async function githubDeviceFlow() {
|
|
|
11612
11626
|
switch (data.error) {
|
|
11613
11627
|
case "authorization_pending":
|
|
11614
11628
|
break;
|
|
11629
|
+
// user hasn't approved yet
|
|
11615
11630
|
case "slow_down":
|
|
11616
11631
|
interval += 5;
|
|
11617
11632
|
break;
|
|
@@ -12917,25 +12932,48 @@ function marketplaceLocations() {
|
|
|
12917
12932
|
}
|
|
12918
12933
|
return out;
|
|
12919
12934
|
}
|
|
12920
|
-
function
|
|
12935
|
+
function verityPathEntry() {
|
|
12921
12936
|
const path = process.env.PATH;
|
|
12922
|
-
if (!path) return
|
|
12937
|
+
if (!path) return null;
|
|
12923
12938
|
for (const dir of path.split(import_node_path7.delimiter)) {
|
|
12924
12939
|
if (!dir) continue;
|
|
12940
|
+
const candidate = (0, import_node_path7.join)(dir, "verity");
|
|
12925
12941
|
try {
|
|
12926
|
-
(0, import_node_fs6.accessSync)(
|
|
12927
|
-
return
|
|
12942
|
+
(0, import_node_fs6.accessSync)(candidate, import_node_fs6.constants.X_OK);
|
|
12943
|
+
return candidate;
|
|
12928
12944
|
} catch {
|
|
12929
12945
|
}
|
|
12930
12946
|
}
|
|
12931
|
-
return
|
|
12947
|
+
return null;
|
|
12948
|
+
}
|
|
12949
|
+
function verityOnPath() {
|
|
12950
|
+
return verityPathEntry() !== null;
|
|
12951
|
+
}
|
|
12952
|
+
function globalVerityVersion() {
|
|
12953
|
+
const entry = verityPathEntry();
|
|
12954
|
+
if (!entry) return null;
|
|
12955
|
+
try {
|
|
12956
|
+
const pkg = readJsonFile((0, import_node_path7.join)((0, import_node_path7.dirname)((0, import_node_fs6.realpathSync)(entry)), "..", "package.json"));
|
|
12957
|
+
if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
|
|
12958
|
+
return pkg.version;
|
|
12959
|
+
} catch {
|
|
12960
|
+
return null;
|
|
12961
|
+
}
|
|
12932
12962
|
}
|
|
12933
12963
|
function pluginCliInvocation() {
|
|
12934
12964
|
const root = process.env.VERITY_PLUGIN_ROOT;
|
|
12935
12965
|
if (!root) return null;
|
|
12936
|
-
|
|
12966
|
+
const onPath = globalVerityVersion();
|
|
12967
|
+
if (onPath !== null && onPath === activePluginVersion()) return null;
|
|
12937
12968
|
return `node ${JSON.stringify((0, import_node_path7.join)(root, "scripts", "verity.mjs"))}`;
|
|
12938
12969
|
}
|
|
12970
|
+
function cliVersionSkew() {
|
|
12971
|
+
if (!process.env.VERITY_PLUGIN_ROOT) return null;
|
|
12972
|
+
const onPath = globalVerityVersion();
|
|
12973
|
+
const plugin = activePluginVersion();
|
|
12974
|
+
if (!onPath || !plugin || onPath === plugin) return null;
|
|
12975
|
+
return { global: onPath, plugin };
|
|
12976
|
+
}
|
|
12939
12977
|
function activePluginVersion() {
|
|
12940
12978
|
const fromEnv = process.env.VERITY_PLUGIN_VERSION;
|
|
12941
12979
|
if (fromEnv) return fromEnv;
|
|
@@ -20596,6 +20634,15 @@ function buildSummary(lines) {
|
|
|
20596
20634
|
}
|
|
20597
20635
|
case "Agent":
|
|
20598
20636
|
case "Task":
|
|
20637
|
+
// Claude Code's actual subagent tool name (legacy 'Agent' kept)
|
|
20638
|
+
// ⚠ ORCHESTRATION IS DELEGATION. `Workflow` fans work out to many
|
|
20639
|
+
// subagents; `SendMessage` hands it to an existing one.
|
|
20640
|
+
//
|
|
20641
|
+
// Two consumers read this counter and both fail closed without it: a
|
|
20642
|
+
// delegated turn reads as a plain chat reply, so `didAgentInvestigate`
|
|
20643
|
+
// downgrades a plan-mode review to `skip`, and `hasNonEditAuthorship`
|
|
20644
|
+
// loses the rescue that stops delegated code exiting via
|
|
20645
|
+
// `zero-increment` with its PASS intact. See DECISIONS.md D21.
|
|
20599
20646
|
case "Workflow":
|
|
20600
20647
|
case "SendMessage":
|
|
20601
20648
|
subagents++;
|
|
@@ -20948,7 +20995,7 @@ function channelSilence(input) {
|
|
|
20948
20995
|
// src/lib/cli-version.ts
|
|
20949
20996
|
function cliVersion() {
|
|
20950
20997
|
try {
|
|
20951
|
-
return true ? "0.32.
|
|
20998
|
+
return true ? "0.32.5-experimental.4d91ca0" : "dev";
|
|
20952
20999
|
} catch {
|
|
20953
21000
|
return "dev";
|
|
20954
21001
|
}
|
|
@@ -24216,27 +24263,30 @@ function registerBaselineCommands(program2) {
|
|
|
24216
24263
|
process.chdir(repoRoot());
|
|
24217
24264
|
} catch {
|
|
24218
24265
|
}
|
|
24219
|
-
let sessionId = opts.sessionId;
|
|
24220
|
-
let source = opts.source;
|
|
24266
|
+
let sessionId = validSessionId(opts.sessionId);
|
|
24267
|
+
let source = hookSource(opts.source);
|
|
24221
24268
|
if (!process.stdin.isTTY) {
|
|
24222
24269
|
const input = (await readStdin()).trim();
|
|
24223
24270
|
if (input) {
|
|
24224
|
-
|
|
24225
|
-
|
|
24226
|
-
|
|
24227
|
-
source = source ?? event.source;
|
|
24228
|
-
} catch {
|
|
24229
|
-
}
|
|
24271
|
+
const event = parseHookEvent(input);
|
|
24272
|
+
if (opts.sessionId === void 0) sessionId = event.sessionId;
|
|
24273
|
+
if (opts.source === void 0) source = event.source;
|
|
24230
24274
|
}
|
|
24231
24275
|
}
|
|
24276
|
+
const session = sessionId ?? validSessionId(process.env.CLAUDE_SESSION_ID);
|
|
24232
24277
|
const cli = pluginCliInvocation();
|
|
24233
|
-
const
|
|
24278
|
+
const skew = cliVersionSkew();
|
|
24279
|
+
const why = skew ? `the \`verity\` on PATH is ${skew.global} but this plugin runs ${skew.plugin}, so it is not the CLI the hooks use` : verityOnPath() ? "the `verity` on PATH is a separate install whose version could not be read" : "this machine has no `verity` on PATH \u2014 the plugin carries its own copy";
|
|
24280
|
+
const cliLine = cli ? `Verity CLI: ${why}. When a Verity skill tells you to run \`verity <args>\`, run \`${cli} <args>\` instead. Everything else about the command is identical.` : null;
|
|
24281
|
+
const skewMsg = skew ? `Verity: your global \`verity\` CLI is ${skew.global} but the plugin runs ${skew.plugin}. Update it before using \`verity\` in a terminal: npm install -g @codacy/verity-cli@${skew.plugin}` : null;
|
|
24282
|
+
const skewNote = skew ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the plugin runs ${skew.plugin}, and \`npm install -g @codacy/verity-cli@${skew.plugin}\` fixes it. Until they have, do not send them to run \`verity login\` in a terminal: that runs the global one, which can sign this machine in to a different server.` : null;
|
|
24234
24283
|
if (!verityConfigured()) {
|
|
24235
24284
|
const how = isPluginInvocation() ? "Tell the user to run /verity:init \u2014 they type it; you cannot invoke it." : "Tell the user to run `verity init` in their terminal.";
|
|
24236
24285
|
const lines = [
|
|
24237
24286
|
`Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
|
|
24238
24287
|
];
|
|
24239
24288
|
if (cliLine) lines.push(cliLine);
|
|
24289
|
+
if (skewNote) lines.unshift(skewNote);
|
|
24240
24290
|
process.stdout.write(
|
|
24241
24291
|
JSON.stringify({
|
|
24242
24292
|
// ⚠ BOTH FIELDS, AND THEY ARE NOT THE SAME AUDIENCE.
|
|
@@ -24246,7 +24296,11 @@ function registerBaselineCommands(program2) {
|
|
|
24246
24296
|
// user who restarted Claude Code specifically to see it saw an
|
|
24247
24297
|
// empty screen. guard.ts has carried that distinction in a comment
|
|
24248
24298
|
// since 0.30 — the same lesson, unapplied here until someone hit it.
|
|
24249
|
-
|
|
24299
|
+
// The mismatch first: it decides whether the setup that follows can work.
|
|
24300
|
+
systemMessage: [
|
|
24301
|
+
skewMsg,
|
|
24302
|
+
isPluginInvocation() ? "Verity: this project is not set up yet, so nothing is being reviewed here. Run /verity:init to configure it." : "Verity: this project is not set up yet, so nothing is being reviewed here. Run `verity init` to configure it."
|
|
24303
|
+
].filter(Boolean).join("\n"),
|
|
24250
24304
|
hookSpecificOutput: {
|
|
24251
24305
|
hookEventName: "SessionStart",
|
|
24252
24306
|
additionalContext: lines.join("\n")
|
|
@@ -24261,6 +24315,7 @@ function registerBaselineCommands(program2) {
|
|
|
24261
24315
|
const state = await readSetupState().catch(() => null);
|
|
24262
24316
|
const stale = staleProjectSkills();
|
|
24263
24317
|
const notices = [];
|
|
24318
|
+
if (skewNote) notices.push(skewNote);
|
|
24264
24319
|
if (cliLine) notices.push(cliLine);
|
|
24265
24320
|
const neverRan = !state?.pluginSetup;
|
|
24266
24321
|
const ownsItsWiring = state?.wiring === "project";
|
|
@@ -24280,7 +24335,7 @@ function registerBaselineCommands(program2) {
|
|
|
24280
24335
|
if (notices.length > 0) {
|
|
24281
24336
|
process.stdout.write(
|
|
24282
24337
|
JSON.stringify({
|
|
24283
|
-
...userMsg ? { systemMessage: userMsg } : {},
|
|
24338
|
+
...userMsg || skewMsg ? { systemMessage: [skewMsg, userMsg].filter(Boolean).join("\n") } : {},
|
|
24284
24339
|
hookSpecificOutput: {
|
|
24285
24340
|
hookEventName: "SessionStart",
|
|
24286
24341
|
additionalContext: notices.join("\n")
|
|
@@ -24289,12 +24344,12 @@ function registerBaselineCommands(program2) {
|
|
|
24289
24344
|
);
|
|
24290
24345
|
}
|
|
24291
24346
|
}
|
|
24292
|
-
if (deferredToPlugin("baseline capture",
|
|
24347
|
+
if (deferredToPlugin("baseline capture", session ?? null)) {
|
|
24293
24348
|
process.exit(0);
|
|
24294
24349
|
}
|
|
24295
24350
|
const authForScope = await resolveToken(program2.opts().token);
|
|
24296
24351
|
const scopeToken = authForScope.ok ? authForScope.data.token : void 0;
|
|
24297
|
-
const scopeSession =
|
|
24352
|
+
const scopeSession = session;
|
|
24298
24353
|
const result = captureBaseline({ sessionId: sessionScopeKey(scopeToken, scopeSession), source });
|
|
24299
24354
|
logEvent("baseline_capture", {
|
|
24300
24355
|
created: result.created,
|
|
@@ -24307,12 +24362,35 @@ function registerBaselineCommands(program2) {
|
|
|
24307
24362
|
process.exit(0);
|
|
24308
24363
|
});
|
|
24309
24364
|
}
|
|
24365
|
+
var MAX_HOOK_EVENT_BYTES = 64 * 1024;
|
|
24366
|
+
var HOOK_SOURCES = /* @__PURE__ */ new Set(["startup", "resume", "clear", "compact"]);
|
|
24367
|
+
var SESSION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
|
|
24310
24368
|
async function readStdin() {
|
|
24311
24369
|
const chunks = [];
|
|
24370
|
+
let size = 0;
|
|
24312
24371
|
for await (const chunk of process.stdin) {
|
|
24313
|
-
|
|
24372
|
+
size += chunk.length;
|
|
24373
|
+
if (size <= MAX_HOOK_EVENT_BYTES) chunks.push(chunk);
|
|
24374
|
+
}
|
|
24375
|
+
return size > MAX_HOOK_EVENT_BYTES ? "" : Buffer.concat(chunks).toString("utf-8");
|
|
24376
|
+
}
|
|
24377
|
+
function parseHookEvent(input) {
|
|
24378
|
+
let event;
|
|
24379
|
+
try {
|
|
24380
|
+
event = JSON.parse(input);
|
|
24381
|
+
} catch {
|
|
24382
|
+
return {};
|
|
24314
24383
|
}
|
|
24315
|
-
|
|
24384
|
+
if (!event || typeof event !== "object" || Array.isArray(event)) return {};
|
|
24385
|
+
const { session_id: id, source } = event;
|
|
24386
|
+
return { sessionId: validSessionId(id), source: hookSource(source) };
|
|
24387
|
+
}
|
|
24388
|
+
function validSessionId(value) {
|
|
24389
|
+
return typeof value === "string" && SESSION_ID_RE.test(value) ? value : void 0;
|
|
24390
|
+
}
|
|
24391
|
+
function hookSource(value) {
|
|
24392
|
+
if (typeof value !== "string") return void 0;
|
|
24393
|
+
return HOOK_SOURCES.has(value) ? value : "unknown";
|
|
24316
24394
|
}
|
|
24317
24395
|
|
|
24318
24396
|
// src/commands/review.ts
|
|
@@ -26908,7 +26986,7 @@ function registerInitCommand(program2) {
|
|
|
26908
26986
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
26909
26987
|
init: {
|
|
26910
26988
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26911
|
-
cli_version: true ? "0.32.
|
|
26989
|
+
cli_version: true ? "0.32.5-experimental.4d91ca0" : "dev"
|
|
26912
26990
|
}
|
|
26913
26991
|
});
|
|
26914
26992
|
} catch (err) {
|
|
@@ -27589,8 +27667,8 @@ function registerTelemetryCommands(program2) {
|
|
|
27589
27667
|
}
|
|
27590
27668
|
|
|
27591
27669
|
// src/cli.ts
|
|
27592
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.32.
|
|
27593
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.
|
|
27670
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.32.5-experimental.4d91ca0").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) => {
|
|
27671
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.5-experimental.4d91ca0");
|
|
27594
27672
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
27595
27673
|
try {
|
|
27596
27674
|
await foldLegacyLocalCredential();
|
|
@@ -23,6 +23,17 @@ happens by accident. So **you** ask, in the session, where the user actually is.
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
+
## Step 0: Check the CLI before asking anything
|
|
27
|
+
|
|
28
|
+
If this session's context says the `verity` on PATH is a different version from
|
|
29
|
+
the plugin's, **tell the user that first**, in one line, before the questions —
|
|
30
|
+
with the `npm install -g` command the context gives. Finding out after they have
|
|
31
|
+
answered is the failure this step exists to prevent: an older CLI cannot take the
|
|
32
|
+
answers.
|
|
33
|
+
|
|
34
|
+
Then run every command below the way the context says (the plugin's own copy),
|
|
35
|
+
not with plain `verity`.
|
|
36
|
+
|
|
26
37
|
## Step 1: Ask both questions in ONE prompt
|
|
27
38
|
|
|
28
39
|
Use `AskUserQuestion` with **both** questions in a single call. Do not ask them
|
|
@@ -33,12 +44,14 @@ setup gets, so spend it once.
|
|
|
33
44
|
|
|
34
45
|
| Option | Description |
|
|
35
46
|
|---|---|
|
|
36
|
-
| `After every turn (
|
|
47
|
+
| `After every turn (always on with the plugin, for now)` | Reviews what the agent just wrote, as you work. Fast feedback, never blocks a commit. Under the Claude Code plugin it cannot be turned off yet. |
|
|
37
48
|
| `Before commit` | Reviews the staged diff and blocks the commit on a failing review. |
|
|
38
49
|
| `Before push / PR` | Reviews the commits about to be pushed and blocks on a failing review. |
|
|
39
50
|
|
|
40
|
-
Pre-select **After every turn
|
|
41
|
-
|
|
51
|
+
Pre-select **After every turn**, and do not call it "recommended": under the
|
|
52
|
+
plugin it runs whatever the answer, and a user who unticks it should not find
|
|
53
|
+
that out afterwards. Say plainly in the question text that choosing only the
|
|
54
|
+
first means **git commits and pushes are not gated**.
|
|
42
55
|
|
|
43
56
|
**Question 2 — "How deeply should Verity review?"** (single-select)
|
|
44
57
|
|
|
@@ -60,6 +73,10 @@ verity init --yes --no-setup --moments <stop[,pre-commit][,pre-push]> --intensit
|
|
|
60
73
|
`--moments none` is the deliberate way to gate nothing; an unrecognised value is
|
|
61
74
|
refused rather than dropped, so a typo cannot quietly remove a gate.
|
|
62
75
|
|
|
76
|
+
Pass `stop` only if they ticked it. Under the plugin the Stop review runs either
|
|
77
|
+
way and `verity init` says so; recording their real answer is what lets it be
|
|
78
|
+
honoured once Stop can be turned off.
|
|
79
|
+
|
|
63
80
|
This is idempotent and does the whole job: removes the project's own
|
|
64
81
|
`.claude/skills/verity-*` copies that the plugin supersedes (they are why the
|
|
65
82
|
slash-command list shows every skill twice), stands down duplicate
|
|
@@ -91,6 +108,11 @@ Say this, and stop:
|
|
|
91
108
|
|
|
92
109
|
If `verity status` already reports an account, skip this step and say so.
|
|
93
110
|
|
|
111
|
+
If Step 0 found a version mismatch, the `verity` in their terminal is the old
|
|
112
|
+
global one, not the plugin's: tell them to update it first (the `npm install -g`
|
|
113
|
+
command from Step 0), then log in. An older or experimental build can sign the
|
|
114
|
+
machine in to a different server, and the plugin follows that sign-in.
|
|
115
|
+
|
|
94
116
|
## Step 4: Offer the part a lookup cannot produce
|
|
95
117
|
|
|
96
118
|
The Standard `init` derives covers the research-backed patterns for the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codacy/verity-cli",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.5-experimental.4d91ca0",
|
|
4
4
|
"description": "CLI for Verity quality gate service",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://verity.md",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "node scripts/build.js",
|
|
26
|
-
"test": "node --import tsx --test $(find tests -name '*.test.ts' -not -path 'tests/e2e/*' | sort)",
|
|
26
|
+
"test": "npm run build && VERITY_TEST_PREBUILT=1 node --import tsx --test $(find tests -name '*.test.ts' -not -path 'tests/e2e/*' | sort)",
|
|
27
27
|
"test:e2e": "node --import tsx --test --test-concurrency=1 tests/e2e/*.test.ts",
|
|
28
28
|
"typecheck": "tsc --noEmit",
|
|
29
29
|
"prepublishOnly": "npm run typecheck && npm run build"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^20",
|
|
33
|
-
"esbuild": "^0.
|
|
33
|
+
"esbuild": "^0.25.12",
|
|
34
34
|
"tsx": "^4.21.0",
|
|
35
35
|
"typescript": "^5.4"
|
|
36
36
|
},
|