@vigilbase/cli 0.2.2 → 0.2.4

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 (77) hide show
  1. package/CLOUDFLARE.md +2 -2
  2. package/COMMANDS.md +128 -42
  3. package/LOCAL.md +99 -38
  4. package/ONE.md +1 -1
  5. package/README.md +217 -66
  6. package/SECURITY.md +1 -1
  7. package/dist/auth/acl.d.ts +6 -0
  8. package/dist/auth/acl.js +45 -0
  9. package/dist/auth/device-auth.d.ts +3 -0
  10. package/dist/auth/device-auth.js +13 -3
  11. package/dist/auth/provider.js +4 -4
  12. package/dist/auth/refresh.d.ts +5 -4
  13. package/dist/auth/refresh.js +82 -41
  14. package/dist/auth/store.d.ts +25 -0
  15. package/dist/auth/store.js +91 -11
  16. package/dist/bin.js +13 -1
  17. package/dist/cli.js +205 -81
  18. package/dist/commands/account.js +11 -7
  19. package/dist/commands/auth.d.ts +6 -0
  20. package/dist/commands/auth.js +75 -24
  21. package/dist/commands/billing.js +2 -2
  22. package/dist/commands/cloudflare.d.ts +1 -1
  23. package/dist/commands/cloudflare.js +31 -17
  24. package/dist/commands/helpers.js +3 -3
  25. package/dist/commands/index.d.ts +1 -0
  26. package/dist/commands/index.js +2 -1
  27. package/dist/commands/legacy-validation.d.ts +20 -0
  28. package/dist/commands/legacy-validation.js +77 -3
  29. package/dist/commands/local.js +186 -65
  30. package/dist/commands/one.js +16 -13
  31. package/dist/commands/public-tools.js +66 -35
  32. package/dist/commands/runs.js +5 -5
  33. package/dist/commands/security.d.ts +1 -1
  34. package/dist/commands/security.js +41 -37
  35. package/dist/commands/watchdog.js +5 -5
  36. package/dist/lib/banner.d.ts +5 -11
  37. package/dist/lib/banner.js +11 -31
  38. package/dist/lib/client.d.ts +9 -0
  39. package/dist/lib/client.js +31 -2
  40. package/dist/lib/cloudflare-client.d.ts +2 -2
  41. package/dist/lib/config.d.ts +16 -0
  42. package/dist/lib/config.js +77 -19
  43. package/dist/lib/format.d.ts +5 -1
  44. package/dist/lib/format.js +110 -35
  45. package/dist/lib/help.js +57 -6
  46. package/dist/lib/network.d.ts +12 -3
  47. package/dist/lib/network.js +73 -9
  48. package/dist/lib/one-client.d.ts +2 -0
  49. package/dist/lib/one-client.js +86 -12
  50. package/dist/lib/open-url.js +2 -1
  51. package/dist/lib/platform.d.ts +2 -0
  52. package/dist/lib/platform.js +5 -0
  53. package/dist/lib/progress.d.ts +18 -3
  54. package/dist/lib/progress.js +72 -10
  55. package/dist/lib/system-trust.d.ts +2 -0
  56. package/dist/lib/system-trust.js +6 -0
  57. package/dist/lib/tui.d.ts +1 -1
  58. package/dist/lib/tui.js +5 -7
  59. package/dist/local/cloudflare-checkup/cf/child-env.js +2 -4
  60. package/dist/local/cloudflare-checkup/cf/install.d.ts +4 -2
  61. package/dist/local/cloudflare-checkup/cf/install.js +55 -24
  62. package/dist/local/cloudflare-checkup/cf/locate.d.ts +2 -0
  63. package/dist/local/cloudflare-checkup/cf/locate.js +10 -1
  64. package/dist/local/cloudflare-checkup/cf/run-cf.d.ts +18 -3
  65. package/dist/local/cloudflare-checkup/cf/run-cf.js +75 -17
  66. package/dist/local/cloudflare-checkup/contract.d.ts +16 -9
  67. package/dist/local/cloudflare-checkup/contract.js +80 -14
  68. package/dist/local/cloudflare-checkup/errors.d.ts +34 -1
  69. package/dist/local/cloudflare-checkup/errors.js +36 -5
  70. package/dist/local/cloudflare-checkup/output.d.ts +6 -0
  71. package/dist/local/cloudflare-checkup/output.js +9 -0
  72. package/dist/local/cloudflare-checkup/snapshot-file.d.ts +6 -2
  73. package/dist/local/cloudflare-checkup/snapshot-file.js +25 -11
  74. package/dist/local/cloudflare-checkup/submit-client.js +7 -1
  75. package/dist/types.d.ts +6 -1
  76. package/esm-only.cjs +3 -0
  77. package/package.json +7 -4
package/CLOUDFLARE.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `vigilbase cf` and `vigilbase cloudflare` use the authenticated Vigilbase One API. Run `vigilbase login` first (signing in isn't supported on Windows yet). Your organization, permissions, customer links, and allowed zones determine access. The CLI never requires a Cloudflare API key.
4
4
 
5
- `cf checkup` runs on One's servers. `cloudflare-checkup` (also `local cloudflare-checkup`) runs on your machine with Cloudflare's own `cf` CLI and needs no Vigilbase login: one command, `npx @vigilbase/cli cloudflare-checkup`, verifies your work email with a code, installs cf if needed, signs in read-only, collects and uploads after you confirm. It works while vigilbase.com has local checkups switched on; otherwise it says so before asking for your email and points you to the checkup in your browser at https://vigilbase.com/tools/cloudflare-checkup (see [LOCAL.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/LOCAL.md)).
5
+ `cf checkup` runs on One's servers. `cloudflare-checkup` (also `local cloudflare-checkup`) runs on your machine with Cloudflare's own `cf` CLI and needs no Vigilbase login: one command, `npx @vigilbase/cli cloudflare-checkup`, verifies your work email with a code, installs cf if needed, signs in read-only, collects and uploads after you confirm. It works while vigilbase.com has local checkups switched on; otherwise it says so before asking for your email and points you to the checkup in your browser at https://vigilbase.com/tools/cloudflare-checkup (see [LOCAL.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/LOCAL.md)).
6
6
 
7
7
  Customer provider access requires an `active` or `trialing` Cloudflare service
8
8
  entitlement for the selected account. Historical/inactive rows and legacy account
@@ -45,7 +45,7 @@ In this table, `C` means `[--customer-id <uuid>]`, `C!` means a required `--cust
45
45
  | `cf zero-trust <account-id>` | C | Users, Access applications, tunnels and authentication analytics |
46
46
  | `cf developer-platform <account-id>` | C | Workers, Workers analytics and Pages projects |
47
47
  | `cf magic-transit <account-id>` | C | Prefixes, routes and traffic analytics |
48
- | `cf analytics --customer-id <uuid>` | A or Z, `[--days <1..30>]` | Usage and traffic analytics; default 7 days |
48
+ | `cf analytics --customer-id <uuid>` | A or Z, `[--days <1..30>]` (whole days, digits only; other forms give `--days must be an integer.`) | Usage and traffic analytics; default 7 days |
49
49
  | `cf checkup [status]` | C A | Setup state and latest completed checkup |
50
50
  | `cf checkup start` | C A | Starts a persisted account security checkup |
51
51
  | `cf checkup progress <run-uuid>` | None | Persisted progress events, percentage and status |
package/COMMANDS.md CHANGED
@@ -2,19 +2,21 @@
2
2
 
3
3
  The CLI uses public scanner APIs on `vigilbase.com` and authenticated APIs on
4
4
  `one.vigilbase.com`. Use `vigilbase <command> --help` or
5
- `vigilbase help <command>` for built-in help, and `vigilbase help <tool>` (for
5
+ `vigilbase help <command>` for built-in help (`vigilbase help cf zones` shows
6
+ the same help as `vigilbase cf zones --help`), and `vigilbase help <tool>` (for
6
7
  example `vigilbase help website-security`) for how to run a tool. Examples
7
- below omit `--json`, which every command supports.
8
+ below omit `--json`, which every command supports. Commands are matched in any
9
+ case.
8
10
 
9
11
  ## References
10
12
 
11
13
  | Area | Complete command and API reference |
12
14
  | --- | --- |
13
- | Cloudflare | [CLOUDFLARE.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/CLOUDFLARE.md) |
14
- | Security | [SECURITY.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/SECURITY.md) |
15
- | Customers, organizations, monitoring, support | [ONE.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/ONE.md) |
16
- | Local Cloudflare Checkup (cf on your machine) | [LOCAL.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/LOCAL.md) |
17
- | Sign-in, credentials, configuration, troubleshooting | [README.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/README.md) |
15
+ | Cloudflare | [CLOUDFLARE.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/CLOUDFLARE.md) |
16
+ | Security | [SECURITY.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/SECURITY.md) |
17
+ | Customers, organizations, monitoring, support | [ONE.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/ONE.md) |
18
+ | Local Cloudflare Checkup (cf on your machine) | [LOCAL.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/LOCAL.md) |
19
+ | Sign-in, credentials, configuration, troubleshooting | [README.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/README.md) |
18
20
 
19
21
  The references list the supported operations, filters, response and pagination
20
22
  behaviour, API endpoints and access requirements of the CLI.
@@ -24,16 +26,18 @@ behaviour, API endpoints and access requirements of the CLI.
24
26
  | Flag | Meaning |
25
27
  | --- | --- |
26
28
  | `--json`, `-j` | JSON on stdout; progress and browser instructions on stderr |
27
- | `--help`, `-h` | Help for the named command; makes no API request |
29
+ | `--help`, `-h` | Help for the named command; makes no API request. In a terminal the main help starts with the banner; pipes and files get plain usage |
28
30
  | `--version`, `-V` | The installed version: the banner in a terminal, only the version number when stdout is a pipe or a file, `{"name":"@vigilbase/cli","version":"…"}` with `--json` |
29
31
  | `--one-url <origin>` | One origin; default `https://one.vigilbase.com` |
30
- | `--auth-url <origin>` | The Identity issuer to trust; default `https://auth.vigilbase.com`. Staging (`https://identity-staging.vigilbase.com`) or a loopback issuer is trusted only when set here or in `VIGILBASE_AUTH_URL` |
32
+ | `--auth-url <origin>` | The Identity issuer to trust; default `https://auth.vigilbase.com`. A loopback issuer is trusted only when set here or in `VIGILBASE_AUTH_URL`, with a loopback `--one-url` |
31
33
  | `--base-url <origin>` | Public origin; default `https://vigilbase.com` |
32
34
  | `--timeout <ms>` | Per-request timeout, integer 1–2147483647; default 60000 |
33
35
  | `--client-id <id>` | Device authorization client; default `vigilbase-cli` |
34
36
 
35
37
  Origins must be HTTP(S) URLs without credentials, paths, query strings or
36
- fragments. One requires HTTPS, except HTTP for loopback development.
38
+ fragments, and use HTTPS except on loopback (`localhost`, `127.0.0.0/8`,
39
+ `[::1]`). An empty flag value is an error; an empty environment variable counts
40
+ as unset. A command checks only the origins it uses.
37
41
  `--customer-id` is a command-specific One customer UUID; it does not change the
38
42
  session's permissions. API reads may still return 403 when the signed-in role
39
43
  lacks access. Unknown flags, flags a command doesn't take (including scope
@@ -41,6 +45,17 @@ flags), missing arguments and extra arguments fail before any API request. A
41
45
  missing argument is named with the command's usage, for example
42
46
  `Missing <url>. Usage: vigilbase headers <url>` or
43
47
  `Missing <customer-id>. Usage: vigilbase customers summary <customer-id>`.
48
+ Invalid values fail the same way, with a message that names the flag and the
49
+ allowed values, for example `--severity must be one of: critical, high, medium, low.`,
50
+ `--limit must be between 1 and 200.` or
51
+ `--start must be an ISO 8601 date-time with an offset, for example 2026-10-12T00:00:00Z.`;
52
+ with `--json` these errors have `"code": "INVALID_ARGUMENT"`. An empty or
53
+ whitespace-only argument counts as missing. An unknown subcommand gives
54
+ ``Unknown <group> command "<name>". Run `vigilbase <group> --help` for usage.``
55
+ (also `INVALID_ARGUMENT`). An unknown option gives code `UNKNOWN_OPTION`, with
56
+ `Did you mean --x?` when one is close; a missing or unexpected option value
57
+ gives `INVALID_ARGUMENT` (`--timeout needs a value.`,
58
+ `--json does not take a value.`).
44
59
  `cf dns`, `cf waf` and `cf speed-settings` require `--customer-id` before
45
60
  they send a request, because One refuses these reads without it. `--style`
46
61
  applies only to `badge`.
@@ -56,9 +71,9 @@ issuer's `/.well-known/openid-configuration` (for production,
56
71
  | `login` | Device sign-in; `--no-open` for remote terminals. Signing in again with Identity first revokes and removes the sign-in it replaces (before the new device code), unless that one's last refresh had an uncertain result | One `GET /.well-known/oauth-protected-resource`. Identity: discovery, `POST /api/auth/device/code`, polling the token endpoint, then userinfo; you approve at `https://auth.vigilbase.com/device`. Legacy: One `POST /api/auth/device/code`, `POST /api/auth/device/token`, `GET /api/auth/get-session`; you approve at One's `/device` |
57
72
  | `login --token-stdin` | Check and save a token piped from a secret manager; the input is bounded and never echoed. A saved Identity sign-in is revoked and removed before the token is saved | One `GET /api/auth/get-session`; Identity revocation when a sign-in is saved |
58
73
  | `login --token <bearer>` | Older input, discouraged because arguments can appear in process lists and history. `VIGILBASE_ONE_TOKEN` also works; neither combines with `--token-stdin` | Same as `--token-stdin` |
59
- | `whoami` | Shows the saved session; signed out is a successful answer. Notes a CLI 0.2.0 `credentials.json` that is being ignored | Identity: discovery and userinfo (a refresh first if due). Legacy: One `GET /api/auth/get-session` |
60
- | `logout` | Revokes every saved Identity sign-in, signs a legacy session out, then deletes the credential files. A sign-in Identity has already ended counts as revoked; any other failed Identity revocation keeps every file | Identity: discovery, then `POST /api/auth/oauth2/revoke` per saved sign-in. Legacy: One `POST /api/auth/sign-out` (best effort) |
61
- | `doctor` | Checks the public API, your session and your saved sign-in independently; exits 1 if any check fails | `GET {base-url}/api/v1/agent/tools`. Signed out or legacy: One `GET /api/auth/get-session`. Identity: `GET {issuer}/.well-known/openid-configuration`, then the userinfo endpoint it names (One is not contacted); a refresh at the token endpoint first if the access token expires within 60 seconds |
74
+ | `whoami` | Shows the saved session; signed out is a successful answer. Notes a CLI 0.2.0 `credentials.json` that is being ignored, and names a sign-in saved for another configuration (``A saved sign-in exists for One <origin>, Identity <issuer>, client ID <id>; pass the matching options or run `vigilbase login`.``). When Identity has ended the saved sign-in, it prints `Your saved sign-in was ended by Vigilbase Identity and has been removed.` on stderr and reports you as signed out | Identity: discovery and userinfo (a refresh first if due). Legacy: One `GET /api/auth/get-session` |
75
+ | `logout` | Revokes every saved Identity sign-in, signs a legacy session out, then deletes the credential files. A sign-in Identity has already ended counts as revoked; any other failed Identity revocation keeps every file. JSON: `{success, cleared, warnings}`; `warnings` is `[]` when there are none | Identity: discovery, then `POST /api/auth/oauth2/revoke` per saved sign-in. Legacy: One `POST /api/auth/sign-out` (best effort) |
76
+ | `doctor` | Checks the public API, your session and your saved sign-in independently; exits 1 if any check fails. `signIn` also fails for a sign-in saved for another One origin, Identity issuer or client ID | `GET {base-url}/api/v1/agent/tools`. Signed out or legacy: One `GET /api/auth/get-session`. Identity: `GET {issuer}/.well-known/openid-configuration`, then the userinfo endpoint it names (One is not contacted); a refresh at the token endpoint first if the access token expires within 60 seconds |
62
77
 
63
78
  Credentials are saved atomically with owner-only permissions in
64
79
  `identity-credentials.json` (Identity) or `credentials.json` (legacy One
@@ -74,21 +89,27 @@ logout, directory checks and the config directory.
74
89
  `{ok, url?, error?, status?, code?}`. `checks.one.url` is the endpoint it
75
90
  checked: One's `get-session`, the discovered userinfo endpoint, or the
76
91
  issuer's discovery URL when discovery itself failed. `checks.signIn` has no
77
- `url`.
92
+ `url`. When a check fails, the top level has the first failing check's
93
+ `error`, `status` and `code`.
78
94
 
79
95
  `whoami` JSON has `authenticated`, `oneBaseUrl`, `user`, `issuer`,
80
- `clientId`, `resource`, `organizationId`, `expiresAt`, `scope`, `obtainedAt`,
81
- `authRequiredTools` and `legacyIdentityFileIgnored`. `expiresAt` and `scope`
82
- are those of the access token in use, after any refresh `whoami` just made.
83
- `obtainedAt` is when you signed in; a refresh doesn't change it. Signed out,
84
- `expiresAt`, `scope` and `obtainedAt` are `null`.
96
+ `clientId`, `resource`, `organizationId`, `savedFor`, `signInEnded`,
97
+ `expiresAt`, `scope`, `obtainedAt`, `authRequiredTools` and
98
+ `legacyIdentityFileIgnored`. `expiresAt` and `scope` are those of the access
99
+ token in use, after any refresh `whoami` just made. `obtainedAt` is when you
100
+ signed in; a refresh doesn't change it. Signed out, `issuer`, `clientId`,
101
+ `resource`, `organizationId`, `expiresAt`, `scope` and `obtainedAt` are `null`.
102
+ `savedFor` is `{oneBaseUrl, issuer, clientId}` when a sign-in is saved for
103
+ another One origin, Identity issuer or client ID (`issuer` and `clientId` are
104
+ `null` for a legacy session), otherwise `null`. `signInEnded` is `true` when
105
+ Identity ended the saved sign-in during this command and its file was removed.
85
106
 
86
107
  `authRequiredTools` means something different per command. The names stay as
87
108
  they are so scripts keep working:
88
109
 
89
110
  | Command | `authRequiredTools` in JSON |
90
111
  | --- | --- |
91
- | `list`, `doctor` | Every tool that needs a One sign-in, whether you are signed in or not. In `list`, `oneExecutableTools` is what you can run through One now |
112
+ | `list`, `doctor` | Every tool that needs a One sign-in, whether you are signed in or not. In `list`, `oneExecutableTools` is what you can run through One now, and `[]` when `authenticated` is false |
92
113
  | `whoami` | The tools your sign-in unlocks: the same tools when signed in, `[]` when signed out |
93
114
  | `login` | Every tool that needs a One sign-in; all of them are unlocked once login succeeds |
94
115
 
@@ -97,19 +118,45 @@ they are so scripts keep working:
97
118
  | Command | Options | API |
98
119
  | --- | --- | --- |
99
120
  | `list` (alias `tools`) | Lists the public catalog and the One-only scanners | GET `/api/v1/agent/tools` |
100
- | `run <tool> <target>` | `--via public\|one`; `--public` forces the public API | POST `/api/v1/agent/tools/<tool>/execute` (anonymous) or One POST `/api/tools/<tool>/execute` |
121
+ | `run <tool> <target>` | `--via public\|one`; `--public` (or `--via public`) forces the public API for the public tools | POST `/api/v1/agent/tools/<tool>/execute` (anonymous) or One POST `/api/tools/<tool>/execute` |
101
122
  | `headers <url>` | Shortcut for `run security-headers`; same routing options | Same as `run` |
102
123
  | `email <domain>` | Shortcut for `run email-security`; same routing options | Same as `run` |
103
- | `describe <tool>` | `--no-skill` skips fetching skill Markdown | Catalog plus the tool's published skill URL |
124
+ | `describe <tool>` | Prints the tool's full description and a `Target: <target format>` line; `--no-skill` skips fetching skill Markdown | Catalog plus the tool's published skill URL |
104
125
  | `skill <tool>` | Prints the complete published skill; JSON includes URL and content | Catalog plus the tool's skill URL |
105
126
  | `badge <domain>` | `--style default\|compact\|mini` | None; builds the public badge URL locally |
106
127
 
128
+ `badge <domain>` takes a domain. A http(s) URL is reduced to its hostname;
129
+ case, a trailing dot and a leading `www.` are ignored. Anything else exits 1
130
+ with `Enter a domain such as vigilbase.com. Usage: vigilbase badge <domain>`
131
+ before any output. JSON for `badge` is
132
+ `{success: true, domain: <normalised hostname>, style, url}`; `describe` and
133
+ `skill` JSON also start with `success: true`.
134
+
107
135
  Public tools: `security-headers`, `email-security`. One-only tools:
108
136
  `website-security`, `react2shell`, `fortibleed-check`. Tools aren't commands of
109
137
  their own: run them with `run <tool> <target>` (`vigilbase help <tool>` prints
110
138
  that usage offline). Public scans use the
111
139
  public API unless you add `--via one`; being signed in doesn't change that.
112
- `--public` and `--via one` cannot be combined.
140
+ `--public` and `--via one` cannot be combined. A One-only tool with `--public`
141
+ or `--via public` stops before any request with
142
+ ``website-security runs only through Vigilbase One: drop --public and run `vigilbase login`.``
143
+ (or `drop --via public`). `run` refuses a tool name it doesn't know locally:
144
+ ``Unknown tool "<name>". Run `vigilbase list` for the allowlist.``
145
+ (code `INVALID_ARGUMENT`), as `describe` does. The public API itself answers a One-only tool with 404
146
+ `not_found` and an unknown name with the allowlist URL.
147
+
148
+ `email <domain>` accepts a fully qualified name with a trailing dot and
149
+ internationalised names (converted to punycode). Names under a public domain,
150
+ such as `test.vigilbase.com`, are accepted; reserved suffixes (`.test`,
151
+ `.example`, `.local`, `.internal`, `.invalid`, `.localhost` and similar) and IP
152
+ addresses are refused by vigilbase.com.
153
+
154
+ Public scans share an hourly quota of 20 scans per client IP address and 20 per
155
+ target (1,000 an hour overall); the catalog's
156
+ `rateLimit.scanQuota` describes it. When it is used up, the API answers 429
157
+ `rate_limit_exceeded` with `Retry-After` set to the seconds until the quota
158
+ resets (up to an hour), and the CLI exits 2 without retrying. A 503
159
+ `service_unavailable` means only that scan storage is down.
113
160
 
114
161
  Public paths are relative to `--base-url`. CLI 0.2.1 and earlier call the
115
162
  unversioned `/api/agent/tools` instead, which vigilbase.com plans to retire on
@@ -121,15 +168,19 @@ that go through One (`--via one` and the One-only tools) need a sign-in.
121
168
  Without one they stop with this error:
122
169
 
123
170
  ```
124
- Error: This tool needs a Vigilbase One sign-in: run `vigilbase login`.
171
+ Error: This command needs a Vigilbase One sign-in: run `vigilbase login`.
125
172
  ```
126
173
 
127
- Other sign-in errors keep their own message, with that sentence as the hint
128
- unless the message already says to run `vigilbase login`.
174
+ With `--json` the error has code `NOT_SIGNED_IN`; every One command uses the
175
+ same sentence and code. Other sign-in errors keep their own message, with that
176
+ sentence as the hint unless the message already says to run `vigilbase login`.
177
+ An unsafe or relative config path and Windows get no such hint: `login` would
178
+ fail the same way, so they keep their own fix.
129
179
 
130
180
  `list` reads your saved sign-in from disk only (no refresh, no network, no wait
131
181
  for the lock). In JSON, `authenticated` says whether it looks usable and
132
- `oneExecutableTools` follows it. If it can't be used, `list` still prints the
182
+ `oneExecutableTools` follows it: the tools you can run through One now, `[]`
183
+ when signed out. If it can't be used, `list` still prints the
133
184
  catalog, shows you as signed out and prints one stderr line per run:
134
185
  ``Couldn't use your saved sign-in (<reason>); running anonymously. Run `vigilbase login` to fix.``
135
186
  For an unsafe config path or credentials file, which `login` would refuse too,
@@ -141,7 +192,23 @@ credentials file is there.
141
192
  When a public scan fails and vigilbase.com explains why with a known error
142
193
  code, the CLI prints `Error: <message> (<code>)` (JSON: `error`, `code`,
143
194
  `status`), with the message cleaned to one line of at most 300 characters.
144
- Otherwise it prints `Request failed (HTTP <status>).`
195
+ Otherwise it prints a message of its own, never the server's text.
196
+
197
+ When a scan run through Vigilbase One fails (One answers 422), the CLI prints
198
+ `Error: The scan couldn't be completed. Try again later.` and exits 1. JSON
199
+ has `success: false`, that `error`, `status: 422` and the `toolRunId` One
200
+ recorded, for `vigilbase runs get <toolRunId>`.
201
+
202
+ When the scanner ran but couldn't assess the target, for example because the
203
+ site answered with a bot verification challenge or an error page, the CLI
204
+ prints `✗ <tool> · <target> · n/a` and the scanner's reason on the next line,
205
+ cleaned to one line of at most 300 characters, and exits 1. This looks the
206
+ same on the public API and through One. JSON has `success: false`, that reason
207
+ as `error`, `toolName`, `target`, `grade: null`, `gradeScore: null`, the
208
+ scanner's `result`, `status: 422`, `code: "scan_unassessed"` and the
209
+ `toolRunId` when one was recorded. Other public failures (for example a 400
210
+ for an invalid target, or a 422 without a result) still print
211
+ `Error: <message> (<code>)`.
145
212
 
146
213
  ## Account and billing
147
214
 
@@ -153,12 +220,12 @@ Otherwise it prints `Request failed (HTTP <status>).`
153
220
  | `account endpoints` | `endpoint` | GET `/api/account/endpoints` |
154
221
  | `account sessions` | `session` | GET `/api/account/sessions` |
155
222
  | `account invites` | `invitations`; optional `list` or `ls` | GET `/api/auth/orgs/invitations` |
156
- | `account invites create` | `add` alias; `--email <email>`, `--role <role>` (default member), required `--confirm` | POST `/api/auth/orgs/invite` |
223
+ | `account invites create` | `add` alias; the email as `<email>` or `--email <email>` (not both), `--role <role>` (default member), required `--confirm`. Usage: `vigilbase account invites create <email>\|--email <email> [--role <role>] --confirm` | POST `/api/auth/orgs/invite` |
157
224
  | `account billing` | Same as the billing commands | Same as billing |
158
225
  | `billing` | `summary`, `show`, `status` | GET `/api/account/billing` |
159
226
  | `billing portal` | `open`; `--no-open` prints the portal URL without opening a browser | POST `/api/billing/portal` |
160
227
 
161
- Invitations need a One browser session: Identity's management API doesn't accept CLI sign-ins, so `account invites` and `account invites create` answer 403 (`browser_session_required`) and the CLI points you to https://one.vigilbase.com.
228
+ Invitations need a One browser session: Identity's management API doesn't accept CLI sign-ins, so `account invites` and `account invites create` answer 403 (`browser_session_required`): the CLI prints `You don't have access to this.` and points you to https://one.vigilbase.com.
162
229
 
163
230
  Creating an invitation sends it; `billing portal` starts a Stripe portal
164
231
  session. Both are explicit actions. Billing data comes from One's Stripe
@@ -181,6 +248,11 @@ Stripe's billing host before they are printed, opened or put in JSON.
181
248
  | `watchdog` | `list`, `targets`, `status` | GET `/api/account/watchdog/targets` |
182
249
  | `watchdog scans` | `scan`; `--target-id <UUID>`, `--limit <n>` (1–100, default 20) | GET `/api/account/watchdog/scans` |
183
250
 
251
+ Text output prints full IDs: the first column of `runs list` works with
252
+ `runs get`, `watchdog scans` and `account sessions` show complete IDs, and
253
+ `watchdog list` rows are `<target id> <domain> <uptime status> 24h=<uptime>`,
254
+ whose target ID is what `watchdog scans --target-id` takes.
255
+
184
256
  Customer-specific Watchdog and monitoring views are in ONE.md.
185
257
 
186
258
  ## Local Cloudflare Checkup (no sign-in)
@@ -191,7 +263,7 @@ All vigilbase.com paths below are under
191
263
  | Command | Options | Requests |
192
264
  | --- | --- | --- |
193
265
  | `cloudflare-checkup` (≡ `local cloudflare-checkup [run]`) | `--email`, `--account-id`, `--out`, `--overwrite`, `--yes`, `--confirm`, `--no-open`, `--cf-auth auto\|profile\|env\|default` (default `auto`), `--profile`, `--cf-bin`, `--max-requests-per-5min`, `--base-url` (vigilbase.com or loopback), `--timeout` | In order: GET `…/availability` (before the email is asked for), POST `…/request` and `…/verify` (email verification), GET `…/local-session` (before cf runs), allowlisted read-only cf commands, GET `…/local-session` again and POST `…/local-session/snapshot` after you confirm. npm only to install the pinned cf when none is usable (asks first) |
194
- | `cloudflare-checkup login` | `--profile`, `--no-open`, `--dry-run`, `--cf-bin` | Runs `cf auth create <profile> --scopes …` interactively |
266
+ | `cloudflare-checkup login` | `--profile`, `--no-open`, `--dry-run`, `--cf-bin` | Runs `cf auth create <profile> [--no-browser] --scopes …` interactively (`--no-browser` comes from `--no-open`) |
195
267
  | `cloudflare-checkup doctor` | `--cf-auth`, `--profile`, `--cf-bin` | Offline cf mapping check, one `cf auth whoami` |
196
268
  | `cloudflare-checkup accounts` | `--cf-auth`, `--profile`, `--cf-bin` | `cf accounts list` (all pages) |
197
269
  | `cloudflare-checkup collect` | `--out` (required), `--account-id`, `--overwrite`, `--dry-run`, `--max-requests-per-5min`, cf options | Allowlisted read-only cf commands; writes the snapshot |
@@ -215,25 +287,39 @@ vigilbase.com emails a 6-digit code, and the CLI asks for the code (without a
215
287
  terminal, both are read from stdin, one line each; add `--yes`). In a terminal
216
288
  both show an interactive timeline on stderr (inputs, arrow-key questions,
217
289
  spinners, a collection progress bar); pipes, CI, `TERM=dumb` and `--json` keep
218
- plain lines and prompts. Ctrl-C exits 130. The address, the code and the
219
- session code are never echoed, logged, stored or passed to cf or npm. cf output
220
- and stderr are never echoed; failures carry a stable `code` and a `hint` that
221
- usually says to run the same command again. See LOCAL.md for the email
290
+ plain lines and prompts. Ctrl-C exits 130 (SIGTERM 143, SIGHUP 129), and a
291
+ cancelled run never uploads. The address, the code and the session code are
292
+ never echoed, logged, stored or passed to cf or npm. cf output and stderr are
293
+ never echoed; failures carry a stable `code` (in plain text after the message,
294
+ for example `Error: Local checkups aren't available right now. (LOCAL_MODE_DISABLED)`)
295
+ and a `hint` that usually says to run the same command again. See LOCAL.md for the email
222
296
  verification, the managed cf install, the allowlist, the environment policy,
223
297
  the uploaded data and the error codes.
224
298
 
225
299
  ## Output and effects
226
300
 
227
301
  Exit codes: **0** success, **1** validation, API, network or sign-in failure,
228
- **2** HTTP 429 rate limiting. A completed scan whose result is unsuccessful
229
- also exits 1. A signed-out `whoami` is not a failure, and a healthy `doctor`
230
- does not need a sign-in. API error JSON keeps the status, code and retry delay
231
- when available.
302
+ **2** HTTP 429 rate limiting; `cloudflare-checkup` also exits **130**, **143**
303
+ or **129** when cancelled by SIGINT (Ctrl-C), SIGTERM or SIGHUP (128 + the
304
+ signal number). A graded scan exits 0 whatever the grade. Its first line starts
305
+ with `✓` only when the result's `status` is `"secure"` and the grade isn't F;
306
+ otherwise it starts with `•`. Scripts should gate on `.grade` or
307
+ `.result.status`. When vigilbase.com returns a shareable report link, text
308
+ output ends with ` Report: <url>`. A scan that failed exits 1. So does a scan
309
+ the scanner could not grade (result `status` `"error"`, no grade): it prints
310
+ `✗ <tool> · <target> · n/a` and the scanner's message, cleaned to one line of
311
+ at most 300 characters, and JSON has `success: false` with that message as
312
+ `error`. A signed-out `whoami` is not a failure, and a healthy `doctor` does
313
+ not need a sign-in. API error JSON keeps the status, code and retry delay when
314
+ available.
232
315
 
233
316
  Vigilbase One's error messages are never shown, because they can describe
234
- One's configuration: the CLI prints `Request failed (HTTP <status>).` When it
235
- recognises the failure from the route, the status and One's error code, it adds
236
- a hint of its own (`Hint: …` in text, `hint` in JSON):
317
+ One's configuration. The CLI prints its own message for the status instead:
318
+ ``Authentication required. Run `vigilbase login`.`` (401),
319
+ `You don't have access to this.` (403), `Rate limit exceeded.` (429) and
320
+ `Request failed (HTTP <status>).` otherwise. When it recognises the failure
321
+ from the route, the status and One's error code, it adds a hint of its own
322
+ (`Hint: …` in text, `hint` in JSON):
237
323
 
238
324
  | One answers | Hint |
239
325
  | --- | --- |
package/LOCAL.md CHANGED
@@ -15,7 +15,7 @@ before it asks for your email; when local mode is off it stops with
15
15
  your browser at <https://vigilbase.com/tools/cloudflare-checkup>.
16
16
 
17
17
  `vigilbase cf checkup` runs on Vigilbase One's servers with stored credentials
18
- (see [CLOUDFLARE.md](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/CLOUDFLARE.md));
18
+ (see [CLOUDFLARE.md](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/CLOUDFLARE.md));
19
19
  `vigilbase cloudflare-checkup` runs on your machine and needs no Vigilbase
20
20
  login.
21
21
 
@@ -33,8 +33,9 @@ of the CLI (0.1.x) is running instead: `npx` prefers an installed global
33
33
  `@vigilbase/cli`. Run `npx @vigilbase/cli@latest cloudflare-checkup` once, or
34
34
  update the global install with `npm install -g @vigilbase/cli@latest`. With
35
35
  Yarn 4.15+ or pnpm 11+, `yarn dlx` and `pnpm dlx` run an older release for a
36
- day after each release; use `npx` (see
37
- [Troubleshooting](https://app.unpkg.com/@vigilbase/cli@0.2.2/files/README.md#troubleshooting)).
36
+ day after each release, and pnpm 10.16+ with `minimumReleaseAge` set refuses
37
+ the new version; use `npx` (see
38
+ [Troubleshooting](https://app.unpkg.com/@vigilbase/cli@0.2.4/files/README.md#troubleshooting)).
38
39
 
39
40
  The command does everything, in this order, and stops at the first problem
40
41
  before any slower step:
@@ -158,17 +159,34 @@ and `vigilbase local cloudflare-checkup run` are the same command.
158
159
  Before anything slow, the command checks every flag (no I/O, and `--email`
159
160
  only for its shape), that its questions can be answered (on a terminal, or
160
161
  with `--yes` without one; `--confirm` answers only the upload question, not
161
- installing cf), then Node, then that `--out` is writable, then that
162
- vigilbase.com has local checkups on and accepts this CLI. So no code is emailed
163
- for a run that could not install cf, confirm the upload or be accepted. It
164
- verifies your email before cf runs, and checks that the snapshot location is
165
- writable before collecting, so a long collection is never wasted.
162
+ installing cf), then Node. Then, before it contacts vigilbase.com at all, it
163
+ checks what it can locally:
164
+
165
+ - with `--cf-auth env`, that `CLOUDFLARE_API_TOKEN` is set
166
+ (`CF_AUTH_REQUIRED`);
167
+ - `--out`: a directory gives `OUTPUT_EXISTS` with
168
+ `--out names a directory; it must name a regular file. Nothing was collected.`,
169
+ and any existing entry, a dangling symbolic link included, gives
170
+ `OUTPUT_EXISTS` without `--overwrite`. With `--overwrite` a symbolic link is
171
+ replaced, never followed, unless it points to a directory;
172
+ - without `--out`, that `<config dir>/checkups` can be created (it isn't
173
+ created yet, so a run that stops here writes nothing);
174
+ - a given `--cf-bin` exists and is Cloudflare's cf (`CF_NOT_FOUND`,
175
+ `CF_WRONG_BINARY`; nothing is run).
176
+
177
+ Only then does it ask whether vigilbase.com has local checkups on and accepts
178
+ this CLI. So no code is emailed for a run that could not install cf, confirm
179
+ the upload, write the snapshot or be accepted. It verifies your email before cf
180
+ runs, and checks that the snapshot location is writable before collecting, so a
181
+ long collection is never wasted. `submit` checks the file first, and after the
182
+ availability answer, before it asks for the email, refuses a snapshot over the
183
+ size or zone limit vigilbase.com announced (`SNAPSHOT_TOO_LARGE`).
166
184
 
167
185
  Two problems can show only once cf runs, after the email was verified: without
168
- a terminal, a missing cf login (`CF_AUTH_REQUIRED`) and several accounts
169
- without `--account-id` (`ACCOUNT_SELECTION_REQUIRED`). Running the command
170
- again with the same address then waits for vigilbase.com's 8 minutes per
171
- address (the hint says so). In scripts, sign in first (run
186
+ a terminal, a missing cf login in profile mode (`CF_AUTH_REQUIRED`) and several
187
+ accounts without `--account-id` (`ACCOUNT_SELECTION_REQUIRED`). Running the
188
+ command again with the same address then waits for vigilbase.com's 8 minutes
189
+ per address (the hint says so). In scripts, sign in first (run
172
190
  `npx @vigilbase/cli cloudflare-checkup login` in a terminal, or set
173
191
  `CLOUDFLARE_API_TOKEN`) and pass `--account-id`.
174
192
 
@@ -185,7 +203,9 @@ never answered from stdin: use `--account-id` and `--yes`.
185
203
  In a terminal, the one command and `submit` show their steps as a timeline on
186
204
  stderr (◆ the current step, ◇ a finished one, │ notes, ▲ a warning, ■ the error
187
205
  that stopped the run, └ the result). Spinners run while the CLI checks that
188
- local checkups are available, while vigilbase.com sends or checks the code,
206
+ local checkups are available (`Checking vigilbase.com`, or the host of a
207
+ loopback `--base-url` such as `Checking 127.0.0.1:3001`), while vigilbase.com
208
+ sends or checks the code,
189
209
  while the session is checked, while cf is found, checked and installed, and
190
210
  while the upload is scored; a progress bar runs while
191
211
  collecting (zones done, cf reads done of the estimate, and the time left, from
@@ -223,7 +243,8 @@ the terminal width, also after a resize.
223
243
  stdout as well.
224
244
  - Ctrl-C at any point gives the terminal back (raw mode off, cursor shown),
225
245
  says what happened (for example `Cancelled. Nothing was uploaded.`) and
226
- exits 130. Errors and SIGTERM give the terminal back too.
246
+ exits 130. While cf or npm runs, Ctrl-C, SIGTERM and SIGHUP stop them and
247
+ exit 130, 143 and 129. Errors and SIGTERM give the terminal back too.
227
248
 
228
249
  The plain output (the second transcript in the quick start: the
229
250
  `Work email for your results:`, `Code from the email:` and
@@ -253,7 +274,12 @@ on this path.
253
274
  and the hint
254
275
  `Run the Cloudflare Checkup in your browser instead: https://vigilbase.com/tools/cloudflare-checkup`.
255
276
  Nothing is emailed and cf is not touched. If vigilbase.com needs a newer CLI
256
- or doesn't accept this snapshot format, it stops with `CLI_UPGRADE_REQUIRED`.
277
+ or doesn't accept this snapshot format, it stops with `CLI_UPGRADE_REQUIRED`:
278
+ `vigilbase.com requires @vigilbase/cli <version> or newer for this snapshot.`
279
+ (the hint names `@latest`), or
280
+ `vigilbase.com does not accept snapshots in the <schemaVersion> format.`
281
+ with the hint
282
+ ``Collect a fresh snapshot with the latest CLI: `npx @vigilbase/cli@latest cloudflare-checkup`.``
257
283
  If vigilbase.com doesn't answer the check (for example a network error or a
258
284
  timeout, after 10 seconds or `--timeout`), the command goes on, and the same
259
285
  checks happen when the checkup starts.
@@ -362,8 +388,8 @@ it stops with `CF_NOT_FOUND`).
362
388
  The checkup runs none of those commands, so the install is about 75 MB.
363
389
  - **Failures:** no npm → `CF_INSTALL_FAILED` with the manual
364
390
  `npm install --global cf@1.0.0-beta.13` fallback; then run the command again.
365
- - **Interruptions:** Ctrl-C while npm runs stops npm and deletes the staging
366
- directory. A staging directory left by a crash or a closed terminal is
391
+ - **Interruptions:** Ctrl-C (or SIGTERM or SIGHUP) while npm runs kills npm,
392
+ deletes the staging directory and exits 130 (143, 129). A staging directory left by a crash or a closed terminal is
367
393
  deleted by the next install once it is older than npm's 10-minute timeout,
368
394
  and by `logout`.
369
395
 
@@ -430,14 +456,28 @@ used a loopback `--base-url`, that command ends with the same `--base-url`.
430
456
  All are `vigilbase cloudflare-checkup <command>` or
431
457
  `vigilbase local cloudflare-checkup <command>`. They keep their own defaults
432
458
  (`--cf-auth profile`, no cf install, no sign-in). They find a cf installed by
433
- the one command. `collect --dry-run` prints every cf command with
459
+ the one command. A flag a subcommand doesn't take fails with
460
+ `--<flag> is not supported for cloudflare-checkup <subcommand>.` before
461
+ anything runs. `collect --dry-run` prints every cf command with
434
462
  `<ZONE_ID>`/`<RULESET_ID>` placeholders, the child-environment variable names
435
463
  (never values), the not-collected list and the request formula; it makes no
436
- Cloudflare and no Vigilbase requests. `submit` checks the file, checks that
464
+ Cloudflare and no Vigilbase requests. It warns as a real collect would: in env
465
+ mode without `CLOUDFLARE_API_TOKEN` it warns with code `CF_AUTH_REQUIRED`
466
+ (`… Without it, a real collect would stop here.`, exit 0), and in profile or
467
+ default mode with the variable set it warns `ENV_TOKEN_NOT_USED`.
468
+ `login --dry-run --cf-bin <path>` checks the path (`CF_NOT_FOUND`,
469
+ `CF_WRONG_BINARY`) without running cf. `submit` checks the file, checks that
437
470
  vigilbase.com has local checkups on, verifies your email like the one command,
438
471
  then uploads a snapshot collected earlier (accepted for 24 hours) and prints
439
472
  the results link.
440
473
 
474
+ `inspect` validates a snapshot and shows what it contains. When the snapshot
475
+ can no longer be uploaded it adds `Upload no longer accepted (collected more than 24 hours ago)`
476
+ or `Upload not accepted (dated in the future)`, and above 4 MiB it warns
477
+ `The snapshot is larger than 4 MiB, the default upload limit.` Control
478
+ characters in a file name are shown as escapes (`\n`, `\u001b`) in the
479
+ `Snapshot` line of `inspect` and `submit`.
480
+
441
481
  `logout` runs `cf auth delete <profile>` through the cf it finds (an
442
482
  interactive passthrough, so cf's own message is shown; cf 1.0.0-beta.13 takes
443
483
  only the profile name, refuses `--profile` and a set `CLOUDFLARE_API_TOKEN`,
@@ -513,8 +553,10 @@ passed.
513
553
  | page rules, bot management, page shield | `page-rules list --zone Z`, `bot-management get --zone Z`, `client-side-security settings get --zone Z` | single |
514
554
  | API Shield | `api-security schema-validation settings get --zone Z`, `api-security schema-validation schemas list --zone Z --omit-source --per-page 100 --page N` | single / until an empty page |
515
555
 
516
- The only other cf argv are `--version`, `auth whoami`, `auth create <p> --scopes …`
517
- (sign-in, interactive) and `auth delete <p>` (logout, interactive).
556
+ The only other cf argv are `--version`, `auth whoami`,
557
+ `auth create <p> [--no-browser] --scopes …` (sign-in, interactive;
558
+ `--no-browser` comes from `login --no-open`) and `auth delete <p>` (logout,
559
+ interactive).
518
560
 
519
561
  Before collecting (the one command, `collect`, `collect --dry-run`) and in `doctor`, every template
520
562
  runs once with `--dry-run` and placeholder IDs (no credentials, no network);
@@ -538,7 +580,9 @@ are recorded as `possibly_truncated`.
538
580
  ## Process and environment policy
539
581
 
540
582
  - cf runs from a private, empty `0700` temporary directory that is removed
541
- afterwards (and on Ctrl-C). Your project's `.env`, `.env.local`,
583
+ afterwards (and on Ctrl-C, SIGTERM or SIGHUP: cf children get SIGTERM, then
584
+ SIGKILL after 2 s). A cancelled run never prints a result, and never writes
585
+ or uploads a snapshot. Your project's `.env`, `.env.local`,
542
586
  `cloudflare.config.ts`, directory profile bindings and cf's account cache never
543
587
  apply. `CF_DELEGATION=1` stops cf from handing off to a project-local cf.
544
588
  - cf's environment is built from an empty object. Copied by name if present:
@@ -551,7 +595,8 @@ are recorded as `possibly_truncated`.
551
595
  DO_NOT_TRACK=1 CF_DELEGATION=1` (telemetry off, no prompts, no update checks).
552
596
  - `CLOUDFLARE_API_TOKEN` is passed only with `--cf-auth env`, and only to API
553
597
  reads (absent → `CF_AUTH_REQUIRED`). In profile and default modes it is removed,
554
- because it would override `--profile`; a notice says so.
598
+ because it would override `--profile`; a notice says so (`ENV_TOKEN_NOT_USED`).
599
+ `collect --dry-run` lists it in `childEnv` only when it is set.
555
600
  - Never passed, by construction: `CLOUDFLARE_API_BASE_URL`, `CF_API_BASE_URL`
556
601
  (the primary control against redirecting your token), `CLOUDFLARE_COMPLIANCE_REGION`,
557
602
  `CLOUDFLARE_CLIENT_ID`, `CLOUDFLARE_ZONE_ID`, `CLOUDFLARE_ACCESS_CLIENT_ID/SECRET`,
@@ -616,8 +661,8 @@ Each cf response is projected immediately and the raw text discarded. The file
616
661
  - zone settings' values, DNSSEC status/algorithm, Universal SSL/Total TLS/page
617
662
  shield `enabled`;
618
663
  - DNS A/AAAA records with **pseudonymised IPs** (the first two IPv4 or three IPv6
619
- groups are kept, the host part becomes a per-prefix counter); names only for
620
- non-proxied records;
664
+ groups are kept, the host part becomes a per-prefix counter,
665
+ `per_prefix_sequential/1`); names only for non-proxied records;
621
666
  - ruleset `id, phase`, `name: 'ddos'` markers, and rules reduced to action,
622
667
  `enabled:false`, a `true`/geo-block expression marker, managed-ruleset IDs and
623
668
  name keywords; IDs and descriptions only on disabled managed rules and
@@ -632,6 +677,12 @@ file is validated and checked for credential-shaped values (session codes,
632
677
  verification tokens, API tokens, JWTs, PEM blocks, bearer strings). `inspect` shows counts of every
633
678
  free-text category.
634
679
 
680
+ The pseudonymisation is checked, not just claimed: `inspect` and `submit`
681
+ refuse a file whose DNS record contents are not numbered 1, 2, 3… within each
682
+ prefix without gaps (`SNAPSHOT_INVALID`, issue `ip_not_pseudonymized`), and vigilbase.com
683
+ refuses such an upload too. A real address that looks like the first
684
+ pseudonym of its prefix (for example `10.0.0.1`) can't be told apart.
685
+
635
686
  **Projection predicates (disclosure).** To minimise uploads, the projections
636
687
  encode selection rules that mirror some checks: which rules count as issue
637
688
  rules, the geo-block marker, what makes an access rule broad, the legacy
@@ -656,15 +707,23 @@ collected**. Run the token-based checkup in the browser to include them.
656
707
 
657
708
  Exit codes: **0** success (any grade, replay, file written, dry run, healthy
658
709
  doctor), **1** any other error, **2** `CF_RATE_LIMITED` or a vigilbase.com 429
659
- (`VIGILBASE_RATE_LIMITED`), **130** cancelled with Ctrl-C. Errors print `code` and a `hint`; JSON errors are
660
- `{success:false, error, code, status?, retryAfterSec?, hint?}`. Server messages
661
- are never echoed.
710
+ (`VIGILBASE_RATE_LIMITED`), **130** cancelled with Ctrl-C (SIGINT), **143**
711
+ cancelled by SIGTERM, **129** cancelled by SIGHUP (a closed terminal). Errors
712
+ print `code` and a `hint`. Plain-text errors end with the code in parentheses,
713
+ for example
714
+ `Error: Local checkups aren't available right now. (LOCAL_MODE_DISABLED)`,
715
+ followed by `Hint: …`. JSON errors are
716
+ `{success:false, error, code, status?, retryAfterSec?, hint?}`; a cancelled
717
+ command prints
718
+ `{"success":false,"error":"Cancelled.","code":"CANCELLED","hint":"Nothing was uploaded. Run the same command again when you are ready."}`.
719
+ Server messages are never echoed.
662
720
 
663
721
  | Code | Fix |
664
722
  | --- | --- |
665
723
  | `NODE_UNSUPPORTED` | Install Node.js 22.18 or newer from https://nodejs.org, then run the same command again. |
666
- | `CF_NOT_FOUND` | Run the same command again in a terminal and let it install cf (or add `--yes`), or `npm install --global cf@1.0.0-beta.13`. |
667
- | `CF_WRONG_BINARY` | Another `cf` (Cloud Foundry, or a pnpm/Volta shim) was found; run the command without `--cf-bin` and let it install cf, or pass `--cf-bin`. |
724
+ | `CWD_UNAVAILABLE` | The current directory no longer exists or cannot be read. Change to a directory that exists and that you can read (for example `cd ~`), then run the same command again. |
725
+ | `CF_NOT_FOUND` | From the one command: run it again in a terminal and let it install cf (add `--yes` when no terminal is available), or `npm install --global cf@1.0.0-beta.13`. From `login`, `doctor`, `accounts`, `collect`, `logout`, and from `run` with `--cf-bin`: run `npx @vigilbase/cli cloudflare-checkup` without `--cf-bin` (it can install cf), install cf with `npm install --global cf@1.0.0-beta.13`, or pass `--cf-bin <path>` to a cf package. |
726
+ | `CF_WRONG_BINARY` | Another `cf` (Cloud Foundry, or a pnpm/Volta shim) was found; run the command without `--cf-bin` and let it install cf, or pass `--cf-bin "$(npm root -g)/cf"`. When the cf package was found but `cf --version` fails, the message is `cf --version failed; the package may be damaged.`: reinstall cf with `npm install --global cf@1.0.0-beta.13`, or run `npx @vigilbase/cli cloudflare-checkup` without `--cf-bin` and let it install the tested cf. |
668
727
  | `CF_UNSUPPORTED_VERSION` | Run the same command again without `--cf-bin` and let it install the tested cf. |
669
728
  | `CF_ALLOWLIST_MISMATCH` | This cf release renamed a required command; run the same command again without `--cf-bin` and let it install the tested cf for Vigilbase (your own cf is left alone). |
670
729
  | `CF_INSTALL_FAILED` | npm is missing or failed, or the download did not match the pinned integrity; `npm install --global cf@1.0.0-beta.13`, then run the same command again. |
@@ -672,14 +731,16 @@ are never echoed.
672
731
  | `CF_PERMISSION_DENIED` | Your Cloudflare login cannot read the zones; check its permissions, then run the same command again. With `CLOUDFLARE_API_TOKEN` set (env mode), add the read permissions to the token, or unset it (or use `--cf-auth profile`) to sign in with your browser. |
673
732
  | `CF_RATE_LIMITED` | Wait 5 minutes, then run the same command again; add `--max-requests-per-5min 600` if it repeats. |
674
733
  | `CF_ERROR` | Run the same command again in a few minutes. |
734
+ | `CANCELLED` | Cancelled with Ctrl-C (or SIGTERM or SIGHUP). Nothing was uploaded. Run the same command again when you are ready. |
675
735
  | `ACCOUNT_SELECTION_REQUIRED` | Run the same command again in a terminal to choose, or add `--account-id <ACCOUNT_ID>` (listed in the error). |
676
736
  | `ACCOUNT_NOT_VISIBLE` | Check that your Cloudflare user can read the account and its zones. |
677
- | `ACCOUNT_TOO_LARGE` | Over 100 zones: run the checkup in your browser instead, https://vigilbase.com/tools/cloudflare-checkup. |
737
+ | `ACCOUNT_TOO_LARGE` | Local collection supports up to 100 zones. Run the Cloudflare Checkup in your browser instead: https://vigilbase.com/tools/cloudflare-checkup |
678
738
  | `ACCOUNT_MISMATCH` | The checkup is bound to another account; run the same command again without `--account-id`. |
679
- | `OUTPUT_EXISTS` | Choose another `--out`, or pass `--overwrite`. |
680
- | `SNAPSHOT_INVALID` / `SNAPSHOT_SECRET_LIKE_VALUE` | Run the same command again (remove the credential-like text from the rule or name first). When `inspect` or `submit` finds no file at the path, check the path, or collect one with `npx @vigilbase/cli cloudflare-checkup collect --out <file>`. |
681
- | `SNAPSHOT_TOO_LARGE` | Run the checkup in your browser instead, https://vigilbase.com/tools/cloudflare-checkup. |
682
- | `SNAPSHOT_STALE` | Snapshots are accepted for 24 hours; run the same command again. |
739
+ | `OUTPUT_EXISTS` | Choose another `--out`, or pass `--overwrite`. A directory (or other special file) as `--out` can't be replaced: name a regular file. |
740
+ | `SNAPSHOT_INVALID` | From `run` or `collect`: run the same command again to collect a fresh one. From `inspect`, `submit` (and the re-read before the one command uploads): the file is not a valid snapshot; collect a fresh one with `npx @vigilbase/cli cloudflare-checkup` (or `npx @vigilbase/cli cloudflare-checkup collect --out <file>`). `The snapshot file does not exist.` or `The snapshot path is a symbolic-link loop.`: check the path, or collect one with `collect --out <file>`. `The snapshot file cannot be read (permission denied).`: check the permissions of the file and of its directories, or copy it somewhere you can read it. |
741
+ | `SNAPSHOT_SECRET_LIKE_VALUE` | From `run` or `collect`: remove it from your Cloudflare settings (a name, description or other text field), then run the same command again. From a file: remove the credential-like value from your Cloudflare settings and collect a fresh snapshot. |
742
+ | `SNAPSHOT_TOO_LARGE` | The snapshot is over the upload limit. Run the Cloudflare Checkup in your browser instead: https://vigilbase.com/tools/cloudflare-checkup |
743
+ | `SNAPSHOT_STALE` | Snapshots are accepted for 24 hours. From `run`, run it again; from `submit`, collect a fresh one with `npx @vigilbase/cli cloudflare-checkup`. |
683
744
  | `EMAIL_INVALID` | Use your work email (personal and disposable addresses are refused), then run the same command again. |
684
745
  | `EMAIL_CODE_INVALID` | Five codes were wrong or not 6 digits; run the same command again for a new code. |
685
746
  | `VERIFICATION_INVALID` / `VERIFICATION_EXPIRED` | The code expired, was tried too often, or the checkup closed; run the same command again for a new code. |
@@ -688,7 +749,7 @@ are never echoed.
688
749
  | `SESSION_BUSY` | A snapshot for this checkup is still being processed; wait for the results email, or run the same command again. |
689
750
  | `SUBMIT_ORIGIN_UNTRUSTED` | Upload only to https://vigilbase.com (or loopback for testing). |
690
751
  | `CONFIRMATION_REQUIRED` | Run the command in a terminal, or add `--yes` (and, without `--email`, pipe the address and the code to stdin). |
691
- | `CLI_UPGRADE_REQUIRED` | vigilbase.com needs a newer CLI (checked before your email is asked for). Run `npx @vigilbase/cli@latest cloudflare-checkup`, or `npm install --global @vigilbase/cli@latest`. |
752
+ | `CLI_UPGRADE_REQUIRED` | vigilbase.com needs a newer CLI, or doesn't accept the snapshot's format (checked before your email is asked for). Run `npx @vigilbase/cli@latest cloudflare-checkup`, or `npm install --global @vigilbase/cli@latest`. |
692
753
  | `LOCAL_MODE_DISABLED` | Local checkups aren't available right now. Run the Cloudflare Checkup in your browser instead: https://vigilbase.com/tools/cloudflare-checkup. |
693
754
  | `VIGILBASE_RATE_LIMITED` | Wait as long as the error says (`retryAfterSec` in JSON), then run the same command again. |
694
755
  | `VIGILBASE_CHALLENGED` | vigilbase.com challenged the request; try another network or contact help@vigilbase.com. |
@@ -698,11 +759,11 @@ JSON success payloads (stdout):
698
759
 
699
760
  - `collect`: `{success, snapshot:{path,bytes,sha256,schemaVersion,accountId,zoneCount,entries:{total,ok,httpError,notCollected,collectionFailed}}, cf:{version,authSource}, cfInvocations, durationMs, warnings:[{code,message}]}`
700
761
  - `collect --dry-run`: `{success, dryRun:true, cf:{version,path,tested}, plan:{accountSelection,account,perZone,perRuleset,notCollected}, verified:{commands,mismatched}, childEnv, requestFormula, warnings}`
701
- - `inspect`: `{success, snapshot:{path,bytes,sha256,schemaVersion,accountId,accountName,zoneCount,collectedAt,collector}, entries:{byKind}, dataCategories:{memberEmails,accessRuleValues,dnsHostnames,pseudonymizedIps,ruleDescriptions}}`
762
+ - `inspect`: `{success, snapshot:{path,bytes,sha256,schemaVersion,accountId,accountName,zoneCount,collectedAt,collector,uploadable,notUploadableReason?}, entries:{byKind}, dataCategories:{memberEmails,accessRuleValues,dnsHostnames,pseudonymizedIps,ruleDescriptions}, warnings}`; `notUploadableReason` (`older_than_24_hours` or `dated_in_the_future`) only when `uploadable` is false; `warnings` may hold `SNAPSHOT_OVER_DEFAULT_UPLOAD_LIMIT`
702
763
  - `submit`: `{success, replayed, snapshotSha256, provenance, report, resultsUrl?}`; `resultsUrl` is the results page when vigilbase.com returned one; never the email address, a code, a token or the session code
703
764
  - the one command (`cloudflare-checkup`, `run`): the `submit` fields plus `snapshot` (as in `collect`) and `warnings`
704
765
  - `logout`: `{success, profile:{name,removed,problem?}, managedCf:{path,removed,kept?}, warnings, hint?}`; `success` is false (exit 1) when cf could not run (`problem`)
705
- - `doctor`: `{success, node:{version,supported}, cf:{found,path,version,supported,tested,identityVerified}, auth:{source,profile,authenticated,expiresAt?,scopes,missingRecommendedScopes?,writeScopeCount?}, commands:{verified,mismatched}, warnings, problems}`
766
+ - `doctor`: `{success, node:{version,supported}, cf:{found,path,version,supported,tested,identityVerified}, auth:{source,profile,authenticated,checked,expiresAt?,scopes,missingRecommendedScopes?,writeScopeCount?}, commands:{verified,mismatched}, warnings, problems}`; `auth.checked` is false (and `authenticated` false) when cf was not found or could not run, and the text says `not checked (cf not found)` or `not checked (cf could not run)`
706
767
  - `accounts`: `{success, accounts:[{id,name}]}`
707
768
 
708
769
  ## Windows, pnpm and Volta