@codacy/verity-cli 0.31.1-experimental.b9b3862 → 0.31.1-experimental.f2f59c0
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 +25 -0
- package/README.md +3 -2
- package/bin/verity.js +166 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to Verity are documented here. This project follows
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
### ⌨️ The setup questions answer to arrow keys
|
|
9
|
+
|
|
10
|
+
- **`verity init` no longer asks you to type a number.** Analysis intensity and
|
|
11
|
+
the review moments are arrow-key lists: `↑↓` to move, `space` to toggle a
|
|
12
|
+
moment, `enter` to confirm — with the recommended answer already under the
|
|
13
|
+
cursor and the default set already ticked, so **Enter alone still gives exactly
|
|
14
|
+
what it gave before**.
|
|
15
|
+
- **Digits still work.** This prompt used to be "type a number", and muscle memory
|
|
16
|
+
should not be punished for an interface improvement — a digit moves the cursor
|
|
17
|
+
rather than confirming, so it composes with the arrows instead of being a
|
|
18
|
+
second, hidden way to answer. `j`/`k` move too.
|
|
19
|
+
- **An empty moment selection is refused, not accepted.** Unticking everything and
|
|
20
|
+
pressing Enter says so instead of installing a review tool that reviews nothing
|
|
21
|
+
— the same invariant the typed prompt held by falling back.
|
|
22
|
+
- **Three rungs of degradation, same default at each.** Arrow keys on a real
|
|
23
|
+
terminal; the typed number prompt when the terminal cannot do raw mode; the
|
|
24
|
+
default when there is no terminal at all or stdin ends. An interface improvement
|
|
25
|
+
must not become a new way for a setup to get stuck — CI, pipes and agent Bash
|
|
26
|
+
calls behave exactly as before.
|
|
27
|
+
- **The terminal is restored on every exit,** including Ctrl+C, which restores
|
|
28
|
+
before exiting: raw mode left on outlives the process and makes the user's next
|
|
29
|
+
shell prompt unusable.
|
|
30
|
+
|
|
31
|
+
## [Unreleased]
|
|
32
|
+
|
|
8
33
|
### 🤝 Joining a project that already has a Standard
|
|
9
34
|
|
|
10
35
|
- **`verity init` now offers the Standard the service already holds** for this
|
package/README.md
CHANGED
|
@@ -11,8 +11,9 @@ verity init
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
`verity init` is the whole setup. It asks how deeply to review and when
|
|
14
|
-
(on stop / before commit / before push)
|
|
15
|
-
|
|
14
|
+
(on stop / before commit / before push) with arrow-key lists — `↑↓` to move,
|
|
15
|
+
`space` to toggle, `enter` to confirm, and Enter alone takes the recommended
|
|
16
|
+
answers — wires everything, offers the optional GitHub login — then either **adopts the Standard your team already has**, or
|
|
16
17
|
launches Claude Code to synthesize one from your codebase (`/verity-setup`).
|
|
17
18
|
|
|
18
19
|
### Joining a project that already uses Verity
|
package/bin/verity.js
CHANGED
|
@@ -19364,7 +19364,7 @@ function channelSilence(input) {
|
|
|
19364
19364
|
// src/lib/cli-version.ts
|
|
19365
19365
|
function cliVersion() {
|
|
19366
19366
|
try {
|
|
19367
|
-
return true ? "0.31.1-experimental.
|
|
19367
|
+
return true ? "0.31.1-experimental.f2f59c0" : "dev";
|
|
19368
19368
|
} catch {
|
|
19369
19369
|
return "dev";
|
|
19370
19370
|
}
|
|
@@ -24075,12 +24075,168 @@ function registerMigrateCommand(program2) {
|
|
|
24075
24075
|
}
|
|
24076
24076
|
|
|
24077
24077
|
// src/lib/prompt.ts
|
|
24078
|
-
var
|
|
24078
|
+
var readline3 = __toESM(require("node:readline/promises"));
|
|
24079
|
+
|
|
24080
|
+
// src/lib/select.ts
|
|
24081
|
+
var readline2 = __toESM(require("node:readline"));
|
|
24082
|
+
function keyToAction(str, key) {
|
|
24083
|
+
const name = key?.name;
|
|
24084
|
+
if (key?.ctrl && (name === "c" || str === "")) return { type: "interrupt" };
|
|
24085
|
+
if (key?.ctrl && (name === "d" || str === "")) return { type: "eof" };
|
|
24086
|
+
switch (name) {
|
|
24087
|
+
case "up":
|
|
24088
|
+
return { type: "move", delta: -1 };
|
|
24089
|
+
case "down":
|
|
24090
|
+
return { type: "move", delta: 1 };
|
|
24091
|
+
case "k":
|
|
24092
|
+
return key?.ctrl ? null : { type: "move", delta: -1 };
|
|
24093
|
+
case "j":
|
|
24094
|
+
return key?.ctrl ? null : { type: "move", delta: 1 };
|
|
24095
|
+
case "space":
|
|
24096
|
+
return { type: "toggle" };
|
|
24097
|
+
case "return":
|
|
24098
|
+
case "enter":
|
|
24099
|
+
return { type: "confirm" };
|
|
24100
|
+
default:
|
|
24101
|
+
break;
|
|
24102
|
+
}
|
|
24103
|
+
if (str === " ") return { type: "toggle" };
|
|
24104
|
+
if (str === "\r" || str === "\n") return { type: "confirm" };
|
|
24105
|
+
if (str && /^[1-9]$/.test(str)) return { type: "jump", index: Number(str) - 1 };
|
|
24106
|
+
return null;
|
|
24107
|
+
}
|
|
24108
|
+
function applyKey(state, action, count, mode2) {
|
|
24109
|
+
switch (action.type) {
|
|
24110
|
+
case "move": {
|
|
24111
|
+
const cursor = (state.cursor + action.delta + count) % count;
|
|
24112
|
+
return { status: "open", state: { cursor, chosen: state.chosen } };
|
|
24113
|
+
}
|
|
24114
|
+
case "jump": {
|
|
24115
|
+
if (action.index >= count) return { status: "open", state };
|
|
24116
|
+
return { status: "open", state: { cursor: action.index, chosen: state.chosen } };
|
|
24117
|
+
}
|
|
24118
|
+
case "toggle": {
|
|
24119
|
+
if (mode2 === "single") {
|
|
24120
|
+
return { status: "open", state: { cursor: state.cursor, chosen: /* @__PURE__ */ new Set([state.cursor]) } };
|
|
24121
|
+
}
|
|
24122
|
+
const chosen = new Set(state.chosen);
|
|
24123
|
+
if (chosen.has(state.cursor)) chosen.delete(state.cursor);
|
|
24124
|
+
else chosen.add(state.cursor);
|
|
24125
|
+
return { status: "open", state: { cursor: state.cursor, chosen } };
|
|
24126
|
+
}
|
|
24127
|
+
case "confirm": {
|
|
24128
|
+
if (mode2 === "single") return { status: "confirmed", indices: [state.cursor] };
|
|
24129
|
+
if (state.chosen.size === 0) {
|
|
24130
|
+
return {
|
|
24131
|
+
status: "open",
|
|
24132
|
+
state: { ...state, hint: "Select at least one \u2014 space toggles the option under the cursor." }
|
|
24133
|
+
};
|
|
24134
|
+
}
|
|
24135
|
+
return { status: "confirmed", indices: [...state.chosen].sort((a, b) => a - b) };
|
|
24136
|
+
}
|
|
24137
|
+
case "interrupt":
|
|
24138
|
+
return { status: "interrupt" };
|
|
24139
|
+
case "eof":
|
|
24140
|
+
return { status: "eof" };
|
|
24141
|
+
}
|
|
24142
|
+
}
|
|
24143
|
+
var GREEN3 = "\x1B[0;32m";
|
|
24144
|
+
var DIM4 = "\x1B[2m";
|
|
24145
|
+
var BOLD2 = "\x1B[1m";
|
|
24146
|
+
var RESET3 = "\x1B[0m";
|
|
24147
|
+
function renderSelect(question, choices, state, mode2, color = colorEnabled()) {
|
|
24148
|
+
const paint = (text, code) => color ? `${code}${text}${RESET3}` : text;
|
|
24149
|
+
const lines = ["", ` ${question}`];
|
|
24150
|
+
const labelOf = (c) => `${c.label}${c.recommended ? " (recommended)" : ""}`;
|
|
24151
|
+
const gutter = Math.max(...choices.map((c) => labelOf(c).length));
|
|
24152
|
+
choices.forEach((choice, i) => {
|
|
24153
|
+
const here = i === state.cursor;
|
|
24154
|
+
const marker = state.chosen.has(i) ? "\u25C9" : "\u25CB";
|
|
24155
|
+
const cursor = here ? "\u276F" : " ";
|
|
24156
|
+
const label2 = labelOf(choice);
|
|
24157
|
+
const pad = choice.hint ? " ".repeat(gutter - label2.length) : "";
|
|
24158
|
+
const hint = choice.hint ? `${pad} ${paint(choice.hint, DIM4)}` : "";
|
|
24159
|
+
lines.push(` ${cursor} ${marker} ${here ? paint(label2, BOLD2) : label2}${hint}`);
|
|
24160
|
+
});
|
|
24161
|
+
const keys = mode2 === "multi" ? "\u2191\u2193 move \xB7 space toggle \xB7 enter confirm" : "\u2191\u2193 move \xB7 enter confirm";
|
|
24162
|
+
lines.push(` ${paint(state.hint ?? keys, state.hint ? GREEN3 : DIM4)}`);
|
|
24163
|
+
return lines;
|
|
24164
|
+
}
|
|
24165
|
+
function runSelect(opts) {
|
|
24166
|
+
const input = opts.input ?? process.stdin;
|
|
24167
|
+
const output = opts.output ?? process.stdout;
|
|
24168
|
+
const { choices, mode: mode2 } = opts;
|
|
24169
|
+
if (typeof input.setRawMode !== "function" || !input.isTTY) return Promise.resolve(null);
|
|
24170
|
+
const initialIdx = choices.map((c, i) => opts.initial.includes(c.id) ? i : -1).filter((i) => i >= 0);
|
|
24171
|
+
let state = {
|
|
24172
|
+
cursor: initialIdx[0] ?? 0,
|
|
24173
|
+
chosen: new Set(mode2 === "single" ? [initialIdx[0] ?? 0] : initialIdx)
|
|
24174
|
+
};
|
|
24175
|
+
return new Promise((resolve4) => {
|
|
24176
|
+
let painted = 0;
|
|
24177
|
+
let settled = false;
|
|
24178
|
+
const draw = () => {
|
|
24179
|
+
if (painted > 0) {
|
|
24180
|
+
readline2.moveCursor(output, 0, -painted);
|
|
24181
|
+
readline2.cursorTo(output, 0);
|
|
24182
|
+
readline2.clearScreenDown(output);
|
|
24183
|
+
}
|
|
24184
|
+
const lines = renderSelect(opts.question, choices, state, mode2);
|
|
24185
|
+
output.write(lines.join("\n") + "\n");
|
|
24186
|
+
painted = lines.length;
|
|
24187
|
+
};
|
|
24188
|
+
const onKey = (str, key) => {
|
|
24189
|
+
const action = keyToAction(str, key);
|
|
24190
|
+
if (!action) return;
|
|
24191
|
+
const outcome = applyKey(state, action, choices.length, mode2);
|
|
24192
|
+
if (outcome.status === "open") {
|
|
24193
|
+
state = outcome.state;
|
|
24194
|
+
draw();
|
|
24195
|
+
return;
|
|
24196
|
+
}
|
|
24197
|
+
if (outcome.status === "confirmed") {
|
|
24198
|
+
state = { ...state, hint: void 0 };
|
|
24199
|
+
draw();
|
|
24200
|
+
finish(outcome.indices.map((i) => choices[i].id));
|
|
24201
|
+
return;
|
|
24202
|
+
}
|
|
24203
|
+
if (outcome.status === "eof") {
|
|
24204
|
+
finish(null);
|
|
24205
|
+
return;
|
|
24206
|
+
}
|
|
24207
|
+
restore();
|
|
24208
|
+
output.write("\n");
|
|
24209
|
+
process.exit(130);
|
|
24210
|
+
};
|
|
24211
|
+
const restore = () => {
|
|
24212
|
+
input.removeListener("keypress", onKey);
|
|
24213
|
+
try {
|
|
24214
|
+
input.setRawMode(false);
|
|
24215
|
+
} catch {
|
|
24216
|
+
}
|
|
24217
|
+
input.pause();
|
|
24218
|
+
};
|
|
24219
|
+
const finish = (value) => {
|
|
24220
|
+
if (settled) return;
|
|
24221
|
+
settled = true;
|
|
24222
|
+
restore();
|
|
24223
|
+
resolve4(value);
|
|
24224
|
+
};
|
|
24225
|
+
readline2.emitKeypressEvents(input);
|
|
24226
|
+
input.setRawMode(true);
|
|
24227
|
+
input.resume();
|
|
24228
|
+
input.on("keypress", onKey);
|
|
24229
|
+
input.once("end", () => finish(null));
|
|
24230
|
+
draw();
|
|
24231
|
+
});
|
|
24232
|
+
}
|
|
24233
|
+
|
|
24234
|
+
// src/lib/prompt.ts
|
|
24079
24235
|
function interactive() {
|
|
24080
24236
|
return !!process.stdin.isTTY && !!process.stdout.isTTY;
|
|
24081
24237
|
}
|
|
24082
24238
|
async function askLine(question, io = {}) {
|
|
24083
|
-
const rl =
|
|
24239
|
+
const rl = readline3.createInterface({
|
|
24084
24240
|
input: io.input ?? process.stdin,
|
|
24085
24241
|
output: io.output ?? process.stdout
|
|
24086
24242
|
});
|
|
@@ -24138,6 +24294,8 @@ function printOptions(question, choices) {
|
|
|
24138
24294
|
}
|
|
24139
24295
|
async function promptChoice(question, choices, fallback) {
|
|
24140
24296
|
if (!interactive()) return fallback;
|
|
24297
|
+
const picked = await runSelect({ question, choices, initial: [fallback], mode: "single" });
|
|
24298
|
+
if (picked !== null) return picked[0] ?? fallback;
|
|
24141
24299
|
printOptions(question, choices);
|
|
24142
24300
|
const defaultIdx = choices.findIndex((c) => c.id === fallback);
|
|
24143
24301
|
const answer = await ask(` Choose [${defaultIdx + 1}]: `);
|
|
@@ -24151,6 +24309,8 @@ async function promptChoice(question, choices, fallback) {
|
|
|
24151
24309
|
}
|
|
24152
24310
|
async function promptMultiSelect(question, choices, fallback) {
|
|
24153
24311
|
if (!interactive()) return [...fallback];
|
|
24312
|
+
const picked = await runSelect({ question, choices, initial: fallback, mode: "multi" });
|
|
24313
|
+
if (picked !== null) return picked.length > 0 ? picked : [...fallback];
|
|
24154
24314
|
printOptions(question, choices);
|
|
24155
24315
|
const defaultLabel = choices.map((c, i) => fallback.includes(c.id) ? String(i + 1) : null).filter(Boolean).join(",");
|
|
24156
24316
|
const answer = await ask(` Choose one or more, comma-separated [${defaultLabel}]: `);
|
|
@@ -24853,7 +25013,7 @@ function registerInitCommand(program2) {
|
|
|
24853
25013
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
24854
25014
|
init: {
|
|
24855
25015
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24856
|
-
cli_version: true ? "0.31.1-experimental.
|
|
25016
|
+
cli_version: true ? "0.31.1-experimental.f2f59c0" : "dev"
|
|
24857
25017
|
}
|
|
24858
25018
|
});
|
|
24859
25019
|
} catch (err) {
|
|
@@ -25524,8 +25684,8 @@ function registerTelemetryCommands(program2) {
|
|
|
25524
25684
|
}
|
|
25525
25685
|
|
|
25526
25686
|
// src/cli.ts
|
|
25527
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.31.1-experimental.
|
|
25528
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.31.1-experimental.
|
|
25687
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.31.1-experimental.f2f59c0").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) => {
|
|
25688
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.31.1-experimental.f2f59c0");
|
|
25529
25689
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
25530
25690
|
try {
|
|
25531
25691
|
await foldLegacyLocalCredential();
|
package/package.json
CHANGED