@codacy/verity-cli 0.32.1-experimental.1371ba8 → 0.32.1-experimental.c640abd

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +232 -100
  2. package/bin/verity.js +58 -39
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,10 @@ All notable changes to Verity are documented here. This project follows
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ <!-- Shipped in 0.31.2 – 0.32.0 but deliberately not announced yet: the plugin
9
+ lane is being closed-loop tested first (Road to 1.0 · Phase 2.6). Cut it
10
+ into its own heading when it is ready to be announced. -->
11
+
8
12
  **Verity ships as a Claude Code plugin.** `/plugin marketplace add codacy/verity`
9
13
  then `/plugin install verity@codacy` gives a working gate with nothing else to
10
14
  install — the plugin carries the CLI as a pinned dependency, and Claude Code
@@ -24,16 +28,6 @@ installs and updates it for you.
24
28
  plugin is present it owns the hooks, and the settings.json copy stands down.
25
29
  `verity init` detects the plugin and removes the duplicate wiring.
26
30
 
27
- ### 🚪 A project that was never set up is left alone
28
-
29
- Every hook now asks the same question the same way. `verity analyze` used to run
30
- in a project that had never seen `verity init`, create `.verity/` there, and then —
31
- with no baseline to compare against — review nothing. It now stands down like the
32
- other hooks always have, so installing Verity no longer scatters state through
33
- directories you merely opened. On the first session in such a project, Claude is
34
- told once that the gate is off here and can offer `/verity:setup` (or `verity init`
35
- on an npm install). Works correctly from linked git worktrees.
36
-
37
31
  ### ⚙️ Git-moment gating moved into the project
38
32
 
39
33
  `verity guard` now reads `.verity/config.json` instead of taking its moments from
@@ -42,13 +36,140 @@ default gates nothing** — set it with `verity config git-moments commit,push`,
42
36
  answer the question in `verity init`. An explicit `--on` still wins, so existing
43
37
  installs are untouched.
44
38
 
45
- Linked git worktrees inherit the setting from the main checkout: `.verity/` is
46
- gitignored, so a fresh `git worktree add` had no config of its own and the guard
47
- there gated nothing while `verity hooks check` said "wired but gating nothing".
48
- A worktree's own `.verity/config.json`, when present, still wins including an
49
- explicit `none` — and `hooks check` names the file it inherited from.
39
+ ### 🔧 Plugin fixes
40
+
41
+ - **Uninstalling the plugin left projects with no gate at all.** Whether the
42
+ plugin owned a project's hooks was decided by whether its install directory
43
+ existed on disk — and that directory survives an uninstall. Every project the
44
+ plugin had ever run in went on standing its own hooks down for a plugin that
45
+ was gone. Ownership now comes from Claude Code's install registry, and
46
+ `verity init` clears the stale marker.
47
+ - **A repository can no longer switch the gate off by shipping a file.**
48
+ Ownership was claimed by `.verity/.plugin-active`, a file inside the project,
49
+ and one naming any directory that happened to exist disabled every hook there.
50
+ An install Claude Code cannot vouch for is ignored — and "vouch" now means
51
+ *for this checkout*: the cache path a real install lives at is predictable, so
52
+ a marker naming a plugin installed for **somebody else's project** used to be
53
+ believed here.
54
+ - **A plugin installed from a local marketplace directory is recognised.**
55
+ Claude Code runs a marketplace served from a directory out of that directory
56
+ while recording the cache copy it made, so the two paths disagreed and a live,
57
+ gating install read as unverified — every reporter then said "no analysis
58
+ moment is active" about a project the plugin was gating on every turn.
59
+ - **`verity init` knows the plugin is here, and says so before it acts.** It
60
+ does two opposite things depending on that answer — write this project's own
61
+ hooks, or leave them to the plugin — and it used to choose silently. It now
62
+ names the install it found and the division of labour, and `--no-plugin`
63
+ overrules it. It detects a plugin in a project the plugin has never set up,
64
+ which is the ordinary case for someone whose first Verity install *is* the
65
+ plugin.
66
+
67
+
68
+ ## [0.32.1] — 2026-09-09
69
+
70
+ **The gate said it was on while it wasn't.** Every fix here is the same failure
71
+ seen from a different side: Verity reported itself wired and watching, and the
72
+ commit went through unreviewed. Two of them were shipped by 0.32.0 itself.
73
+
74
+ ```bash
75
+ npm install -g @codacy/verity-cli # binary only — no re-run of init needed
76
+ ```
77
+
78
+ ### 🔒 The gate is on when it says it is
79
+
80
+ - **Typing `2,3` at the setup question left you with no git gate.** The review
81
+ moments used to be answered by number — `2,3` *was* the answer — and 0.32.0's
82
+ arrow-key rewrite kept the digit shortcut on the single-select question and
83
+ lost it on this one. A digit moved the cursor without ticking anything, the
84
+ comma was ignored, and Enter then confirmed the untouched default. You got
85
+ `stop` alone: no pre-commit hook was wired, and the git gate silently did not
86
+ exist. Reported from the field as *"pre-commit hooks are not added any more"*.
87
+ A digit toggles again, and the prompt's own legend now names the keys it
88
+ accepts.
89
+ - **`git add … && git commit` was never reviewed.** The hook runs *before* the
90
+ command, so the index it inspected had not had the `add` applied yet: nothing
91
+ staged, and the gate took its "nothing to review" exit — a silent allow, with
92
+ no trace that a commit had gone unreviewed. It is the shape an agent writes by
93
+ default, so it was most of the commit gate's coverage. The gate now works out
94
+ what the command is about to stage, using git's own pathspec matching, and
95
+ understands `git commit -a` and `git commit <paths>`. Where it genuinely
96
+ cannot — a pathspec the shell expands before git sees it, an interactive
97
+ `git add -p` — it says so and lets the commit through **loudly**, rather than
98
+ reviewing a set it guessed at.
99
+ - **A verdict the CLI does not understand is no longer drawn as a pass.** An
100
+ absent or unrecognised gate decision — a truncated response, a proxy error
101
+ page — reached the `✓ PASS` line. It is reported as unreviewed.
102
+ - **`verity hooks install --moments <typo>` no longer removes every gate.**
103
+ Unrecognised moments were dropped in silence, so a single misspelling
104
+ reconciled the hooks down to nothing and printed success. It is an error now;
105
+ `--moments none` is still the way to turn them off on purpose.
106
+ - **`verity init` no longer overwrites the moments you chose.** Re-running init
107
+ to heal a config replaced an answer you had set with `verity config
108
+ git-moments`, substituting the shipped default. Your answer is now recorded
109
+ as yours, kept, and named when init keeps it.
110
+ - **A linked worktree gates what the main checkout gates.** `.verity/` is
111
+ gitignored, so a fresh `git worktree add` had no configuration of its own and
112
+ the guard there gated nothing while `verity hooks check` reported it wired. A
113
+ worktree's own `.verity/config.json` still wins when it has one — including an
114
+ explicit `none` — and `hooks check` names the file it inherited from.
115
+ - **`verity status`, `verity doctor` and `verity hooks check` answer from one
116
+ place.** They could disagree about whether a hook was wired, and two of them
117
+ were wrong from a subdirectory.
118
+
119
+ ### 🔧 Fixed
120
+
121
+ - `verity status --limit` rejects a value that is not a number instead of
122
+ quietly ignoring it.
123
+
124
+ ### Migrating
125
+
126
+ Upgrading the binary is enough for six of the seven — but not for the moments
127
+ question. If you set this project up **on 0.32.0** and answered that question by
128
+ typing numbers, the gates you asked for were never recorded, and a new binary
129
+ cannot know what you meant. Check and repair in one command each:
130
+
131
+ ```bash
132
+ verity status # Moments: is pre-commit / pre-push listed?
133
+ verity config git-moments commit,push # set what you meant; init now keeps it
134
+ ```
135
+
136
+ Projects set up before 0.32.0, or set up with the arrow keys, are unaffected.
137
+
138
+
139
+ ## [0.32.0] — 2026-09-08
140
+
141
+ **Setup takes seconds, not minutes — and the reviewer sees more than the diff.**
142
+ Installing Verity used to be two steps: `verity init`, then a Claude Code
143
+ session for `/verity-setup` to write your Standard, which took minutes and was
144
+ the step people skipped. It is now one command that takes seconds: `init`
145
+ builds the Standard from your codebase, or downloads the one your team already
146
+ registered. On the other side, the reviewer stops judging a change in a vacuum:
147
+ it sees the callers, tests and contracts around what you touched, and it can
148
+ only block on things it actually has evidence for. This entry folds in
149
+ 0.31.2 and 0.31.4, which shipped without their own headings; 0.31.3 and 0.31.1
150
+ are below.
151
+
152
+ ```bash
153
+ npm install -g @codacy/verity-cli
154
+ verity init # re-run in existing projects: heals the config, records your answers
155
+ ```
156
+
157
+ ### ⚡ One command, no second step
158
+
159
+ - **`verity init` finishes the whole job.** It used to stop halfway and hand you
160
+ off to `/verity-setup` in Claude Code to synthesize the Standard — a model
161
+ turn that took minutes, needed a session open, and was easy to skip. `init`
162
+ now does it on its own, in seconds, and the gate is live on your next session.
163
+ `/verity-setup` still exists but is optional: it is for adding
164
+ project-specific rules on top, not for getting started.
165
+ - **If your team already has a Standard, it comes down from the cloud.** Any
166
+ repository registered before — by a teammate, by you on another machine, by
167
+ CI — already has its Standard on Verity, and `init` fetches it and writes the
168
+ team's configuration to disk (when you are signed in). Cloning a repo that
169
+ already uses Verity is: install, `init`, done.
170
+ - **If nobody has one yet, `init` derives it** from the codebase — see below.
50
171
 
51
- ### 🎯 Setup finishes in one command
172
+ ### 🎯 `init` derives the Standard when there is nothing to adopt
52
173
 
53
174
  - **`verity init` now derives the Standard itself.** When the service has nothing
54
175
  for this repository, the CLI reads the codebase — languages counted, frameworks
@@ -117,30 +238,6 @@ rule list degrades into a filter over it (VRT-108); Semgrep's ids are deliberate
117
238
  not derived yet, so the tool is dropped rather than configured empty. Every one of
118
239
  those is now an assertion.
119
240
 
120
- ### ⌨️ The setup questions answer to arrow keys
121
-
122
- - **`verity init` no longer asks you to type a number.** Analysis intensity and
123
- the review moments are arrow-key lists: `↑↓` to move, `space` to toggle a
124
- moment, `enter` to confirm — with the recommended answer already under the
125
- cursor and the default set already ticked, so **Enter alone still gives exactly
126
- what it gave before**.
127
- - **Digits still work.** This prompt used to be "type a number", and muscle memory
128
- should not be punished for an interface improvement — a digit moves the cursor
129
- rather than confirming, so it composes with the arrows instead of being a
130
- second, hidden way to answer. `j`/`k` move too.
131
- - **An empty moment selection is refused, not accepted.** Unticking everything and
132
- pressing Enter says so instead of installing a review tool that reviews nothing
133
- — the same invariant the typed prompt held by falling back.
134
- - **Three rungs of degradation, same default at each.** Arrow keys on a real
135
- terminal; the typed number prompt when the terminal cannot do raw mode; the
136
- default when there is no terminal at all or stdin ends. An interface improvement
137
- must not become a new way for a setup to get stuck — CI, pipes and agent Bash
138
- calls behave exactly as before.
139
- - **The terminal is restored on every exit,** including Ctrl+C, which restores
140
- before exiting: raw mode left on outlives the process and makes the user's next
141
- shell prompt unusable.
142
-
143
-
144
241
  ### 🤝 Joining a project that already has a Standard
145
242
 
146
243
  - **`verity init` now offers the Standard the service already holds** for this
@@ -169,20 +266,28 @@ those is now an assertion.
169
266
  silent-forever failure: decline on Monday meaning to synthesize later, forget,
170
267
  and every later run stays quiet while the project has no local config at all.
171
268
 
172
- ### 🔧 Fixed
173
-
174
- - **An upgrade no longer removes the gates you chose.** `.verity/setup.json` only
175
- exists from this release, so every project configured before it had no recorded
176
- answer — including everyone who picked commit/push gates through the old
177
- `/verity-setup`. The first upgraded `verity init` fell back to the shipped
178
- default and reconciled those gates away, turning Stop back on. What you chose is
179
- still legible in `.claude/settings.json`, so init reads it.
180
- - `verity doctor` names the artifact that is actually missing instead of telling
181
- you to run a phase that will decline: with a Standard adopted and no analysis
182
- config, `/verity-setup` would have answered "already configured".
183
- - The setup skill learned the same case — Standard present, analysis config
184
- missing — and writes only the config rather than re-synthesizing the Standard.
269
+ ### ⌨️ The setup questions answer to arrow keys
185
270
 
271
+ - **`verity init` no longer asks you to type a number.** Analysis intensity and
272
+ the review moments are arrow-key lists: `↑↓` to move, `space` to toggle a
273
+ moment, `enter` to confirm — with the recommended answer already under the
274
+ cursor and the default set already ticked, so **Enter alone still gives exactly
275
+ what it gave before**.
276
+ - **Digits still work.** This prompt used to be "type a number", and muscle memory
277
+ should not be punished for an interface improvement — a digit moves the cursor
278
+ rather than confirming, so it composes with the arrows instead of being a
279
+ second, hidden way to answer. `j`/`k` move too.
280
+ - **An empty moment selection is refused, not accepted.** Unticking everything and
281
+ pressing Enter says so instead of installing a review tool that reviews nothing
282
+ — the same invariant the typed prompt held by falling back.
283
+ - **Three rungs of degradation, same default at each.** Arrow keys on a real
284
+ terminal; the typed number prompt when the terminal cannot do raw mode; the
285
+ default when there is no terminal at all or stdin ends. An interface improvement
286
+ must not become a new way for a setup to get stuck — CI, pipes and agent Bash
287
+ calls behave exactly as before.
288
+ - **The terminal is restored on every exit,** including Ctrl+C, which restores
289
+ before exiting: raw mode left on outlives the process and makes the user's next
290
+ shell prompt unusable.
186
291
 
187
292
  **Setup is one command.** `verity init` and `/verity-setup` were two half-flows
188
293
  that overlapped — and the overlap was not harmless: init wired the Stop hook,
@@ -195,10 +300,11 @@ with one entry point.
195
300
  - **It asks the questions whose answers it acts on** — analysis intensity, when
196
301
  to review (on stop / before commit / before push), and cost & usage telemetry.
197
302
  On the terminal, before anything is wired to them.
198
- - **Then it hands off to Claude Code** to finish the half that needs a model:
199
- reading the codebase and synthesizing the Standard (`/verity-setup`). If Claude
200
- Code isn't installed, or you are already inside a session, it prints the one
201
- command instead. `verity setup` is an alias for the same command.
303
+ - **Then it finishes the Standard itself** (adopted from the service or derived
304
+ from the codebase see above). Handing off to Claude Code for `/verity-setup`
305
+ survives only as the fallback when neither produced one, and if you are
306
+ already inside a session it prints the one command instead. `verity setup` is
307
+ an alias for the same command.
202
308
  - **`--yes` takes every recommended answer and asks nothing** (CI, scripts,
203
309
  agents) — including the GitHub login, whose unattended answer is skip, so the
204
310
  project stays local-only until you run `verity login`. `--no-setup` stops after
@@ -259,50 +365,76 @@ with one entry point.
259
365
  terminal (Ctrl+D, a pty that ends) falls back to the default instead of
260
366
  crashing init between copying the skills and wiring the hooks.
261
367
 
262
- ### 🔒 Fixed four ways the gate could be off while reporting itself on
368
+ ### 🚪 A project that was never set up is left alone
369
+
370
+ Every hook now asks the same question the same way. `verity analyze` used to run
371
+ in a project that had never seen `verity init`, create `.verity/` there, and then —
372
+ with no baseline to compare against — review nothing. It now stands down like the
373
+ other hooks always have, so installing Verity no longer scatters state through
374
+ directories you merely opened. On the first session in such a project, Claude is
375
+ told once that the gate is off here and can offer to run `verity init`. Works
376
+ correctly from linked git worktrees.
377
+
378
+ ### 🔭 The reviewer sees the neighborhood
379
+
380
+ Measured on real commits: every change had at least one caller outside the
381
+ diff (median five), and more than half had a test referencing a changed symbol.
382
+ Verity sent none of it. Now it does — server-side, so it reached every
383
+ installed CLI on deploy day:
384
+
385
+ - **Context is what the agent actually read.** The files sent alongside your
386
+ change are the ones the agent opened this task — not the ten most recently
387
+ touched files in the repo, which is what it was.
388
+ - **Call sites of changed symbols**, one line each — including callers of a
389
+ function whose body you edited but whose name isn't in the diff.
390
+ - **At commit and push, full excerpts.** Contracts first (interfaces your change
391
+ implements), then tests, then callers, with real line numbers so the reviewer
392
+ can cite them.
393
+ - **Findings stay anchored on your change.** A problem your edit causes at a
394
+ call site is reported against the file you changed. A pre-existing problem in
395
+ a file Verity only glanced at is out of scope and cannot block you.
396
+ - **Every run says whether this fired**, and why not when it didn't (no tool, no
397
+ diff, no symbols, no sites, timeout) — in the evidence log and the guard's
398
+ coverage block. "Never fires" and "not deployed" can no longer look the same.
399
+ - Fixed on the way: the Stop-hook review was running at half its intended file
400
+ budget (20 files, not 40), and context files reached the reviewer without the
401
+ line numbers the prompt promised.
402
+
403
+ ### ⚖️ The gate only blocks on evidence it has
404
+
405
+ Raised from a customer's production runs: 134 of 655 runs blocked, and only a
406
+ third of those blocks cited a line of production source. Two things decide
407
+ whether a finding blocks — how bad *this instance* is, and what *kind* of rule
408
+ it is — and both were owned by the wrong party.
409
+
410
+ - **Severity is the reviewer's.** It used to be overwritten with the Standard's
411
+ per-pattern constant, so a finding the reviewer rated `low` (*"appears to be a
412
+ fixture value"*) blocked as `critical`. The reviewer's judgement now stands.
413
+ - **Category comes from your Standard.** It used to be a label the model
414
+ re-picked every run — the same pattern landed as `security` on one run and
415
+ `quality` on the next, and at `high` that label *is* the block. It is now
416
+ derived from where the pattern sits in your Standard. Note the direction: for
417
+ patterns you declared under security, every high instance now blocks where the
418
+ coin flip previously let some through.
419
+ - **A secrets finding needs a witness.** `no-hardcoded-secrets` blocks only when
420
+ a static tool saw it too, not on the model's word alone.
421
+ - **`exclude_paths` in your Standard actually excludes now.** It was advertised
422
+ and read by nothing.
423
+
424
+ ### 🔧 Fixed
425
+
426
+ - **An upgrade no longer removes the gates you chose.** `.verity/setup.json` only
427
+ exists from this release, so every project configured before it had no recorded
428
+ answer — including everyone who picked commit/push gates through the old
429
+ `/verity-setup`. The first upgraded `verity init` fell back to the shipped
430
+ default and reconciled those gates away, turning Stop back on. What you chose is
431
+ still legible in `.claude/settings.json`, so init reads it.
432
+ - `verity doctor` names the artifact that is actually missing instead of telling
433
+ you to run a phase that will decline: with a Standard adopted and no analysis
434
+ config, `/verity-setup` would have answered "already configured".
435
+ - The setup skill learned the same case — Standard present, analysis config
436
+ missing — and writes only the config rather than re-synthesizing the Standard.
263
437
 
264
- - **`git add x && git commit` was never reviewed.** A Claude Code hook runs
265
- *before* the command, so the index it read had not had the `add` applied:
266
- no files, and the gate's "nothing staged" exit — a silent allow, with no
267
- trace that a commit had gone unreviewed. It is the shape an agent writes by
268
- default, so it was most of the pre-commit gate's coverage. The gate now works
269
- out what the command will stage, using git's own pathspec matching, and
270
- handles `git commit -a`. Where it cannot — a pathspec the shell expands,
271
- `git add -p` — it says so and lets the commit through **loudly** rather than
272
- reviewing a set it guessed at.
273
- - **Uninstalling the Claude Code plugin left projects with no gate at all.**
274
- Whether the plugin owned a project's hooks was decided by whether its install
275
- directory existed — and that directory survives an uninstall. Every project
276
- the plugin had ever run in went on standing its own hooks down for a plugin
277
- that was gone. Ownership now comes from Claude Code's install registry, and
278
- `verity init` clears the stale marker.
279
- - **`verity init` now says which mode it is in before it acts on it** — the
280
- plugin's hooks or this project's own — with the install it found and
281
- `--no-plugin` to overrule it. It does two opposite things depending on that
282
- answer, and it used to make the choice silently.
283
- - **A plugin installed from a local marketplace is recognised too.** Claude Code
284
- runs a marketplace served from a *directory* out of that directory while
285
- recording the cache copy it made, so the two paths disagree and a live,
286
- gating install read as unverified — every reporter then said "no analysis
287
- moment is active" about a project the plugin was gating on every turn.
288
- - **A repository can no longer switch the gate off by shipping a file.**
289
- Ownership was claimed by `.verity/.plugin-active`, which is a file inside the
290
- project. One naming any directory that happened to exist disabled every hook
291
- in that project. An install Claude Code cannot vouch for is now ignored.
292
- - **`verity status` and `verity doctor` agree with `verity hooks check`.** Under
293
- the plugin both used to report "Stop: off" and tell you to install hooks that
294
- were firing on every turn. All three read one answer now, and it is correct
295
- from a subdirectory too.
296
- - **A commit gate on a linked worktree gates what the main checkout gates.**
297
- `.verity/config.json` is machine-local, so every `git worktree add` started
298
- with no moments and reviewed nothing.
299
- - **A verdict the client does not understand is no longer rendered as a pass.**
300
- An absent or unrecognised gate decision — a truncated response, a proxy error
301
- page — reached the "✓ PASS" line. It is reported as unreviewed.
302
- - **`verity hooks install --moments <typo>` no longer removes every gate.**
303
- Unrecognised moments were dropped, so a misspelling reconciled to nothing and
304
- reported success. It is an error now; `--moments none` turns them off on
305
- purpose.
306
438
 
307
439
  ## [0.31.3] — 2026-09-03
308
440
 
package/bin/verity.js CHANGED
@@ -12927,18 +12927,27 @@ function realpathOr(p) {
12927
12927
  function isWithin(want, dir) {
12928
12928
  return want === dir || want.startsWith(dir + import_node_path7.sep);
12929
12929
  }
12930
+ function entryAppliesHere(entry, here) {
12931
+ const e = entry;
12932
+ const scope2 = typeof e?.scope === "string" ? e.scope : "user";
12933
+ if (scope2 === "user") return true;
12934
+ const forProject = typeof e?.projectPath === "string" ? realpathOr(e.projectPath) : "";
12935
+ return forProject === here;
12936
+ }
12930
12937
  function registrySays(pluginRoot) {
12931
12938
  const plugins = readJsonFile((0, import_node_path7.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
12932
12939
  if (!plugins || typeof plugins !== "object") return "unverified";
12933
12940
  const want = (0, import_node_path7.resolve)(pluginRoot);
12941
+ const here = realpathOr(repoRoot());
12934
12942
  const markets = marketplaceLocations();
12935
12943
  for (const [key, value] of Object.entries(plugins)) {
12936
12944
  const at = key.lastIndexOf("@");
12937
12945
  const source = at > 0 ? markets.get(key.slice(at + 1)) : void 0;
12938
- const claims = (Array.isArray(value) ? value : []).some((entry) => {
12946
+ const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
12947
+ const claims = applicable.some((entry) => {
12939
12948
  const installPath = entry?.installPath;
12940
12949
  return typeof installPath === "string" && (0, import_node_path7.resolve)(installPath) === want;
12941
- }) || source !== void 0 && isWithin(want, source);
12950
+ }) || source !== void 0 && applicable.length > 0 && isWithin(want, source);
12942
12951
  if (claims) {
12943
12952
  if (enabledPluginSetting(key) === false) return "gone";
12944
12953
  return (0, import_node_fs6.existsSync)(pluginRoot) ? "live" : "gone";
@@ -12998,11 +13007,7 @@ function registeredVerityPlugin() {
12998
13007
  const e = entry;
12999
13008
  const installPath = typeof e.installPath === "string" ? e.installPath : "";
13000
13009
  if (!installPath || !(0, import_node_fs6.existsSync)(installPath)) continue;
13001
- const scope2 = typeof e.scope === "string" ? e.scope : "user";
13002
- if (scope2 !== "user") {
13003
- const forProject = typeof e.projectPath === "string" ? realpathOr(e.projectPath) : "";
13004
- if (forProject !== here) continue;
13005
- }
13010
+ if (!entryAppliesHere(entry, here)) continue;
13006
13011
  return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
13007
13012
  }
13008
13013
  }
@@ -20867,7 +20872,7 @@ function channelSilence(input) {
20867
20872
  // src/lib/cli-version.ts
20868
20873
  function cliVersion() {
20869
20874
  try {
20870
- return true ? "0.32.1-experimental.1371ba8" : "dev";
20875
+ return true ? "0.32.1-experimental.c640abd" : "dev";
20871
20876
  } catch {
20872
20877
  return "dev";
20873
20878
  }
@@ -24615,36 +24620,50 @@ async function runGuard(opts, globals) {
24615
24620
  process.exit(2);
24616
24621
  }
24617
24622
  resetIter(moment);
24623
+ const notice = verdictNotice({
24624
+ decision,
24625
+ moment,
24626
+ verb,
24627
+ covLine,
24628
+ covDetail,
24629
+ link,
24630
+ viewUrl,
24631
+ narrative: response.assessment?.narrative ?? ""
24632
+ });
24633
+ emitAllowNotice(notice.user, notice.agent);
24634
+ }
24635
+ function verdictNotice(ctx) {
24636
+ const { moment, verb, covLine, covDetail, link, viewUrl } = ctx;
24637
+ const decision = ctx.decision ?? "(unrecognised)";
24638
+ const report = viewUrl ? `
24639
+ Report: ${viewUrl}` : "";
24618
24640
  if (decision === "FAIL") {
24619
- const narrative = response.assessment?.narrative ?? "";
24620
- emitAllowNotice(
24621
- `\u26A0 Verity ${moment}: the ${verb} may not match its stated purpose \u2014 proceeding (${covLine})${link}`,
24622
- `Verity ${moment}: intent-alignment WARNING (not blocked).${narrative ? " " + narrative : ""}
24623
- ${covDetail}${viewUrl ? `
24624
- Report: ${viewUrl}` : ""}`
24625
- );
24626
- } else if (decision === "WARN") {
24627
- emitAllowNotice(
24628
- `\u26A0 Verity ${moment}: WARN \u2014 proceeding (${covLine})${link}`,
24629
- `Verity ${moment} review: WARN (proceeding).
24630
- ${covDetail}${viewUrl ? `
24631
- Report: ${viewUrl}` : ""}`
24632
- );
24633
- } else if (decision === "PASS") {
24634
- emitAllowNotice(
24635
- `\u2713 Verity ${moment}: PASS (${covLine})${link}`,
24636
- `Verity ${moment} review: PASS.
24637
- ${covDetail}${viewUrl ? `
24638
- Report: ${viewUrl}` : ""}`
24639
- );
24640
- } else {
24641
- emitAllowNotice(
24642
- `\u26A0 Verity ${moment}: no verdict came back \u2014 ${verb === "commit" ? "committed" : "pushed"} WITHOUT a usable review (${covLine})${link}`,
24643
- `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.
24644
- ${covDetail}${viewUrl ? `
24645
- Report: ${viewUrl}` : ""}`
24646
- );
24641
+ const narrative = ctx.narrative ?? "";
24642
+ return {
24643
+ user: `\u26A0 Verity ${moment}: the ${verb} may not match its stated purpose \u2014 proceeding (${covLine})${link}`,
24644
+ agent: `Verity ${moment}: intent-alignment WARNING (not blocked).${narrative ? " " + narrative : ""}
24645
+ ${covDetail}${report}`
24646
+ };
24647
+ }
24648
+ if (decision === "WARN") {
24649
+ return {
24650
+ user: `\u26A0 Verity ${moment}: WARN \u2014 proceeding (${covLine})${link}`,
24651
+ agent: `Verity ${moment} review: WARN (proceeding).
24652
+ ${covDetail}${report}`
24653
+ };
24654
+ }
24655
+ if (decision === "PASS") {
24656
+ return {
24657
+ user: `\u2713 Verity ${moment}: PASS (${covLine})${link}`,
24658
+ agent: `Verity ${moment} review: PASS.
24659
+ ${covDetail}${report}`
24660
+ };
24647
24661
  }
24662
+ return {
24663
+ user: `\u26A0 Verity ${moment}: no verdict came back \u2014 ${verb === "commit" ? "committed" : "pushed"} WITHOUT a usable review (${covLine})${link}`,
24664
+ agent: `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.
24665
+ ${covDetail}${report}`
24666
+ };
24648
24667
  }
24649
24668
  function writeBlockMessage(moment, response, covDetail) {
24650
24669
  const label2 = moment === "pre-commit" ? "pre-commit" : "pre-push";
@@ -26667,7 +26686,7 @@ function registerInitCommand(program2) {
26667
26686
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
26668
26687
  init: {
26669
26688
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
26670
- cli_version: true ? "0.32.1-experimental.1371ba8" : "dev"
26689
+ cli_version: true ? "0.32.1-experimental.c640abd" : "dev"
26671
26690
  }
26672
26691
  });
26673
26692
  } catch (err) {
@@ -27347,8 +27366,8 @@ function registerTelemetryCommands(program2) {
27347
27366
  }
27348
27367
 
27349
27368
  // src/cli.ts
27350
- program.name("verity").description("CLI for Verity quality gate service").version("0.32.1-experimental.1371ba8").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) => {
27351
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.1-experimental.1371ba8");
27369
+ program.name("verity").description("CLI for Verity quality gate service").version("0.32.1-experimental.c640abd").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) => {
27370
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.32.1-experimental.c640abd");
27352
27371
  setUserNamedServiceUrl(program.opts().serviceUrl);
27353
27372
  try {
27354
27373
  await foldLegacyLocalCredential();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codacy/verity-cli",
3
- "version": "0.32.1-experimental.1371ba8",
3
+ "version": "0.32.1-experimental.c640abd",
4
4
  "description": "CLI for Verity quality gate service",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://verity.md",