@vigilbase/cli 0.1.4 → 0.2.1

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 (191) hide show
  1. package/CLOUDFLARE.md +3 -4
  2. package/COMMANDS.md +158 -83
  3. package/LOCAL.md +721 -0
  4. package/ONE.md +2 -4
  5. package/README.md +341 -123
  6. package/SECURITY.md +2 -2
  7. package/dist/auth/device-auth.d.ts +0 -1
  8. package/dist/auth/device-auth.js +13 -8
  9. package/dist/auth/index.d.ts +4 -2
  10. package/dist/auth/index.js +3 -2
  11. package/dist/auth/provider.d.ts +18 -0
  12. package/dist/auth/provider.js +71 -0
  13. package/dist/auth/refresh.d.ts +29 -0
  14. package/dist/auth/refresh.js +199 -0
  15. package/dist/auth/store.d.ts +103 -4
  16. package/dist/auth/store.js +400 -74
  17. package/dist/auth/token-metadata.d.ts +9 -0
  18. package/dist/auth/token-metadata.js +21 -0
  19. package/dist/auth/types.d.ts +8 -2
  20. package/dist/auth/types.js +0 -1
  21. package/dist/bin.d.ts +0 -1
  22. package/dist/bin.js +0 -1
  23. package/dist/cli.d.ts +4 -2
  24. package/dist/cli.js +45 -15
  25. package/dist/commands/account.d.ts +0 -1
  26. package/dist/commands/account.js +0 -1
  27. package/dist/commands/auth.d.ts +0 -1
  28. package/dist/commands/auth.js +82 -22
  29. package/dist/commands/billing.d.ts +0 -1
  30. package/dist/commands/billing.js +0 -1
  31. package/dist/commands/cloudflare.d.ts +1 -2
  32. package/dist/commands/cloudflare.js +6 -6
  33. package/dist/commands/helpers.d.ts +15 -1
  34. package/dist/commands/helpers.js +2 -3
  35. package/dist/commands/index.d.ts +3 -2
  36. package/dist/commands/index.js +6 -2
  37. package/dist/commands/legacy-validation.d.ts +0 -1
  38. package/dist/commands/legacy-validation.js +0 -1
  39. package/dist/commands/local.d.ts +35 -0
  40. package/dist/commands/local.js +1543 -0
  41. package/dist/commands/one.d.ts +0 -1
  42. package/dist/commands/one.js +6 -7
  43. package/dist/commands/public-tools.d.ts +0 -1
  44. package/dist/commands/public-tools.js +55 -17
  45. package/dist/commands/runs.d.ts +0 -1
  46. package/dist/commands/runs.js +0 -1
  47. package/dist/commands/security.d.ts +1 -2
  48. package/dist/commands/security.js +1 -2
  49. package/dist/commands/watchdog.d.ts +0 -1
  50. package/dist/commands/watchdog.js +0 -1
  51. package/dist/index.d.ts +3 -3
  52. package/dist/index.js +1 -2
  53. package/dist/lib/banner.d.ts +0 -1
  54. package/dist/lib/banner.js +0 -1
  55. package/dist/lib/client.d.ts +4 -2
  56. package/dist/lib/client.js +42 -18
  57. package/dist/lib/cloudflare-client.d.ts +0 -1
  58. package/dist/lib/cloudflare-client.js +0 -1
  59. package/dist/lib/config.d.ts +31 -3
  60. package/dist/lib/config.js +72 -13
  61. package/dist/lib/format.d.ts +2 -1
  62. package/dist/lib/format.js +27 -7
  63. package/dist/lib/help.d.ts +1 -2
  64. package/dist/lib/help.js +37 -17
  65. package/dist/lib/network.d.ts +10 -1
  66. package/dist/lib/network.js +33 -5
  67. package/dist/lib/one-client.d.ts +5 -3
  68. package/dist/lib/one-client.js +49 -3
  69. package/dist/lib/one-operations.d.ts +0 -1
  70. package/dist/lib/one-operations.js +0 -1
  71. package/dist/lib/open-url.d.ts +0 -1
  72. package/dist/lib/open-url.js +0 -1
  73. package/dist/lib/platform.d.ts +2 -0
  74. package/dist/lib/platform.js +4 -0
  75. package/dist/lib/progress.d.ts +0 -1
  76. package/dist/lib/progress.js +0 -1
  77. package/dist/lib/security-client.d.ts +1 -2
  78. package/dist/lib/security-client.js +0 -1
  79. package/dist/lib/skill-fetch.d.ts +0 -1
  80. package/dist/lib/skill-fetch.js +0 -1
  81. package/dist/lib/system-trust.d.ts +0 -1
  82. package/dist/lib/system-trust.js +0 -1
  83. package/dist/lib/tui.d.ts +308 -0
  84. package/dist/lib/tui.js +846 -0
  85. package/dist/local/cloudflare-checkup/cf/allowlist.d.ts +94 -0
  86. package/dist/local/cloudflare-checkup/cf/allowlist.js +183 -0
  87. package/dist/local/cloudflare-checkup/cf/auth-lifecycle.d.ts +112 -0
  88. package/dist/local/cloudflare-checkup/cf/auth-lifecycle.js +312 -0
  89. package/dist/local/cloudflare-checkup/cf/child-env.d.ts +31 -0
  90. package/dist/local/cloudflare-checkup/cf/child-env.js +80 -0
  91. package/dist/local/cloudflare-checkup/cf/install.d.ts +105 -0
  92. package/dist/local/cloudflare-checkup/cf/install.js +308 -0
  93. package/dist/local/cloudflare-checkup/cf/locate.d.ts +43 -0
  94. package/dist/local/cloudflare-checkup/cf/locate.js +227 -0
  95. package/dist/local/cloudflare-checkup/cf/run-cf.d.ts +88 -0
  96. package/dist/local/cloudflare-checkup/cf/run-cf.js +274 -0
  97. package/dist/local/cloudflare-checkup/collector.d.ts +47 -0
  98. package/dist/local/cloudflare-checkup/collector.js +295 -0
  99. package/dist/local/cloudflare-checkup/contract.d.ts +2804 -0
  100. package/dist/local/cloudflare-checkup/contract.js +1620 -0
  101. package/dist/local/cloudflare-checkup/email-verification.d.ts +124 -0
  102. package/dist/local/cloudflare-checkup/email-verification.js +211 -0
  103. package/dist/local/cloudflare-checkup/errors.d.ts +29 -0
  104. package/dist/local/cloudflare-checkup/errors.js +103 -0
  105. package/dist/local/cloudflare-checkup/output.d.ts +23 -0
  106. package/dist/local/cloudflare-checkup/output.js +88 -0
  107. package/dist/local/cloudflare-checkup/prompts.d.ts +40 -0
  108. package/dist/local/cloudflare-checkup/prompts.js +139 -0
  109. package/dist/local/cloudflare-checkup/rate-budget.d.ts +41 -0
  110. package/dist/local/cloudflare-checkup/rate-budget.js +79 -0
  111. package/dist/local/cloudflare-checkup/snapshot-file.d.ts +52 -0
  112. package/dist/local/cloudflare-checkup/snapshot-file.js +185 -0
  113. package/dist/local/cloudflare-checkup/submit-client.d.ts +112 -0
  114. package/dist/local/cloudflare-checkup/submit-client.js +395 -0
  115. package/dist/local/cloudflare-checkup/terminal-ui.d.ts +170 -0
  116. package/dist/local/cloudflare-checkup/terminal-ui.js +403 -0
  117. package/dist/types.d.ts +25 -3
  118. package/dist/types.js +16 -1
  119. package/dist/version.d.ts +0 -1
  120. package/dist/version.js +0 -1
  121. package/package.json +12 -12
  122. package/dist/auth/device-auth.d.ts.map +0 -1
  123. package/dist/auth/device-auth.js.map +0 -1
  124. package/dist/auth/index.d.ts.map +0 -1
  125. package/dist/auth/index.js.map +0 -1
  126. package/dist/auth/store.d.ts.map +0 -1
  127. package/dist/auth/store.js.map +0 -1
  128. package/dist/auth/types.d.ts.map +0 -1
  129. package/dist/auth/types.js.map +0 -1
  130. package/dist/bin.d.ts.map +0 -1
  131. package/dist/bin.js.map +0 -1
  132. package/dist/cli.d.ts.map +0 -1
  133. package/dist/cli.js.map +0 -1
  134. package/dist/commands/account.d.ts.map +0 -1
  135. package/dist/commands/account.js.map +0 -1
  136. package/dist/commands/auth.d.ts.map +0 -1
  137. package/dist/commands/auth.js.map +0 -1
  138. package/dist/commands/billing.d.ts.map +0 -1
  139. package/dist/commands/billing.js.map +0 -1
  140. package/dist/commands/cloudflare.d.ts.map +0 -1
  141. package/dist/commands/cloudflare.js.map +0 -1
  142. package/dist/commands/helpers.d.ts.map +0 -1
  143. package/dist/commands/helpers.js.map +0 -1
  144. package/dist/commands/index.d.ts.map +0 -1
  145. package/dist/commands/index.js.map +0 -1
  146. package/dist/commands/legacy-validation.d.ts.map +0 -1
  147. package/dist/commands/legacy-validation.js.map +0 -1
  148. package/dist/commands/one.d.ts.map +0 -1
  149. package/dist/commands/one.js.map +0 -1
  150. package/dist/commands/public-tools.d.ts.map +0 -1
  151. package/dist/commands/public-tools.js.map +0 -1
  152. package/dist/commands/runs.d.ts.map +0 -1
  153. package/dist/commands/runs.js.map +0 -1
  154. package/dist/commands/security.d.ts.map +0 -1
  155. package/dist/commands/security.js.map +0 -1
  156. package/dist/commands/watchdog.d.ts.map +0 -1
  157. package/dist/commands/watchdog.js.map +0 -1
  158. package/dist/index.d.ts.map +0 -1
  159. package/dist/index.js.map +0 -1
  160. package/dist/lib/banner.d.ts.map +0 -1
  161. package/dist/lib/banner.js.map +0 -1
  162. package/dist/lib/client.d.ts.map +0 -1
  163. package/dist/lib/client.js.map +0 -1
  164. package/dist/lib/cloudflare-client.d.ts.map +0 -1
  165. package/dist/lib/cloudflare-client.js.map +0 -1
  166. package/dist/lib/config.d.ts.map +0 -1
  167. package/dist/lib/config.js.map +0 -1
  168. package/dist/lib/format.d.ts.map +0 -1
  169. package/dist/lib/format.js.map +0 -1
  170. package/dist/lib/help.d.ts.map +0 -1
  171. package/dist/lib/help.js.map +0 -1
  172. package/dist/lib/network.d.ts.map +0 -1
  173. package/dist/lib/network.js.map +0 -1
  174. package/dist/lib/one-client.d.ts.map +0 -1
  175. package/dist/lib/one-client.js.map +0 -1
  176. package/dist/lib/one-operations.d.ts.map +0 -1
  177. package/dist/lib/one-operations.js.map +0 -1
  178. package/dist/lib/open-url.d.ts.map +0 -1
  179. package/dist/lib/open-url.js.map +0 -1
  180. package/dist/lib/progress.d.ts.map +0 -1
  181. package/dist/lib/progress.js.map +0 -1
  182. package/dist/lib/security-client.d.ts.map +0 -1
  183. package/dist/lib/security-client.js.map +0 -1
  184. package/dist/lib/skill-fetch.d.ts.map +0 -1
  185. package/dist/lib/skill-fetch.js.map +0 -1
  186. package/dist/lib/system-trust.d.ts.map +0 -1
  187. package/dist/lib/system-trust.js.map +0 -1
  188. package/dist/types.d.ts.map +0 -1
  189. package/dist/types.js.map +0 -1
  190. package/dist/version.d.ts.map +0 -1
  191. package/dist/version.js.map +0 -1
@@ -5,6 +5,8 @@ export type Writer = {
5
5
  };
6
6
  /** Untrusted API data must never become terminal control sequences or bidi overrides. */
7
7
  export declare function sanitizeTerminal(value: string): string;
8
+ /** One sanitised line, cut to `maxLength` characters with an ellipsis. */
9
+ export declare function singleLine(value: string, maxLength?: number): string;
8
10
  export declare function createWriter(stdout?: NodeJS.WritableStream, stderr?: NodeJS.WritableStream): Writer;
9
11
  export declare function printJson(writer: Writer, value: unknown): void;
10
12
  export declare function formatToolsList(catalog: AgentToolsCatalogResponse, mode: CliOutputMode, writer: Writer, options?: {
@@ -16,4 +18,3 @@ export declare function formatToolsList(catalog: AgentToolsCatalogResponse, mode
16
18
  export declare function formatToolDescription(tool: AgentToolDefinition, mode: CliOutputMode, writer: Writer, skillMarkdown?: string): void;
17
19
  export declare function formatExecuteResult(result: AgentToolExecuteResponse, mode: CliOutputMode, writer: Writer): void;
18
20
  export declare function formatError(error: unknown, mode: CliOutputMode, writer: Writer): void;
19
- //# sourceMappingURL=format.d.ts.map
@@ -3,6 +3,11 @@ import { stripVTControlCharacters } from 'node:util';
3
3
  export function sanitizeTerminal(value) {
4
4
  return stripVTControlCharacters(value).replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g, '');
5
5
  }
6
+ /** One sanitised line, cut to `maxLength` characters with an ellipsis. */
7
+ export function singleLine(value, maxLength = 300) {
8
+ const line = sanitizeTerminal(value).replace(/\s+/g, ' ').trim();
9
+ return line.length > maxLength ? `${line.slice(0, maxLength - 1).trimEnd()}…` : line;
10
+ }
6
11
  export function createWriter(stdout = process.stdout, stderr = process.stderr) {
7
12
  return {
8
13
  stdout: (line = '') => {
@@ -257,8 +262,9 @@ export function formatExecuteResult(result, mode, writer) {
257
262
  writer.stdout(head);
258
263
  else
259
264
  writer.stderr(head);
260
- if (result.error) {
261
- writer.stderr(` ${result.error}`);
265
+ const error = typeof result.error === 'string' ? result.error : result.error?.message;
266
+ if (error) {
267
+ writer.stderr(` ${error}`);
262
268
  }
263
269
  for (const line of summarizeResultCompact(result.result)) {
264
270
  writer.stdout(` ${line}`);
@@ -266,11 +272,17 @@ export function formatExecuteResult(result, mode, writer) {
266
272
  }
267
273
  export function formatError(error, mode, writer) {
268
274
  let message = error instanceof Error ? error.message : String(error);
275
+ let reason = '';
269
276
  // Server bodies can contain credentials, customer data, or arbitrary error text.
270
277
  if (error && typeof error === 'object' && 'body' in error && error.body != null && 'status' in error && typeof error.status === 'number') {
271
- message = 'code' in error && error.code === 'FLAREHAWK_VIEW_AS_REQUIRED'
272
- ? 'Select a customer with --customer-id <customer UUID> for security commands.'
273
- : `Request failed (HTTP ${error.status}).`;
278
+ if ('code' in error && error.code === 'FLAREHAWK_VIEW_AS_REQUIRED') {
279
+ message = 'Select a customer with --customer-id <customer UUID> for security commands.';
280
+ }
281
+ else {
282
+ // Only the reason the public client accepted from a known problem+json error is shown.
283
+ reason = 'reason' in error && typeof error.reason === 'string' ? singleLine(error.reason) : '';
284
+ message = reason || `Request failed (HTTP ${error.status}).`;
285
+ }
274
286
  }
275
287
  const payload = {
276
288
  success: false,
@@ -292,14 +304,22 @@ export function formatError(error, mode, writer) {
292
304
  error.retryAfterSec >= 0) {
293
305
  payload.retryAfterSec = error.retryAfterSec;
294
306
  }
307
+ // CLI-authored remediation (never server text); bounded and sanitised like any output.
308
+ if ('hint' in error && typeof error.hint === 'string') {
309
+ const hint = singleLine(error.hint);
310
+ if (hint)
311
+ payload.hint = hint;
312
+ }
295
313
  }
296
314
  if (mode === 'json') {
297
315
  printJson(writer, payload);
298
316
  return;
299
317
  }
300
- writer.stderr(`Error: ${message}`);
318
+ writer.stderr(`Error: ${message}${reason && typeof payload.code === 'string' ? ` (${payload.code})` : ''}`);
301
319
  if (typeof payload.retryAfterSec === 'number') {
302
320
  writer.stderr(`Retry after ${payload.retryAfterSec}s`);
303
321
  }
322
+ if (typeof payload.hint === 'string') {
323
+ writer.stderr(`Hint: ${payload.hint}`);
324
+ }
304
325
  }
305
- //# sourceMappingURL=format.js.map
@@ -1,4 +1,3 @@
1
1
  export declare const HELP_TAGLINE = "one \u00B7 security \u00B7 tools";
2
- export declare const HELP_TEXT = "Usage: vigilbase <command>\n\nPublic tools (no login)\n list List available tools\n run <tool> <target> Run a scan\n headers <url> Check security headers\n email <domain> Check email security\n describe <tool> \u00B7 skill Tool details / skill markdown\n badge <domain> \u00B7 doctor Badge URL \u00B7 connectivity\n\nAuth-required tools (after login)\n website-security \u00B7 react2shell \u00B7 fortibleed-check\n\nAccount (login required)\n login \u00B7 logout \u00B7 whoami Session\n account [services|org|\u2026] Account overview\n account endpoints Endpoint inventory\n account sessions Active sessions\n account invites [list|create]\n billing [summary|portal] Billing summary / Stripe portal\n runs [list|get <id>] Tool run history\n cf <command> Cloudflare accounts, zones, DNS, WAF, analytics\n security <command> Incidents, logs, assets, detections, intel, reports\n watchdog [list|scans] Watchdog targets / scans\n customers <command> Customer records, billing, reports, investigations\n orgs <command> Organizations, members, permission roles\n monitoring <command> Health, probes, metrics, customer targets\n support tickets Support ticket history\n\nOptions\n -j, --json JSON output\n -h, --help Help for the current command\n -V, --version Installed version\n --timeout <milliseconds> Request timeout (default: 60000)\n --base-url <origin> Public API origin\n --one-url <origin> Vigilbase One origin\n --client-id <id> Device authorization client ID\n\nUse vigilbase <command> --help for command options.\n\nExamples\n vigilbase headers https://vigilbase.com\n vigilbase email vigilbase.com --json\n vigilbase login\n vigilbase account --json\n vigilbase runs list --json\n vigilbase cf zones\n vigilbase security incidents --severity high\n";
2
+ export declare const HELP_TEXT: string;
3
3
  export declare function helpForCommand(command: string): string | null;
4
- //# sourceMappingURL=help.d.ts.map
package/dist/lib/help.js CHANGED
@@ -1,7 +1,26 @@
1
1
  import { CLOUDFLARE_HELP } from '../commands/cloudflare.js';
2
+ import { LOCAL_HELP } from '../commands/local.js';
2
3
  import { ONE_HELP } from '../commands/one.js';
3
4
  import { SECURITY_HELP } from '../commands/security.js';
4
5
  export const HELP_TAGLINE = 'one · security · tools';
6
+ /** Column where descriptions start in the main help: two-space indent, term, at least two spaces. */
7
+ const DESCRIPTION_COLUMN = 31;
8
+ /** Two-column help rows whose descriptions all start at DESCRIPTION_COLUMN. */
9
+ function helpRows(rows) {
10
+ return rows
11
+ .map(([term, description]) => ` ${term.padEnd(DESCRIPTION_COLUMN - 4)} ${description}`)
12
+ .join('\n');
13
+ }
14
+ const GLOBAL_OPTIONS = helpRows([
15
+ ['-j, --json', 'JSON output'],
16
+ ['-h, --help', 'Help for the current command'],
17
+ ['-V, --version', 'Installed version'],
18
+ ['--timeout <milliseconds>', 'Request timeout (default: 60000)'],
19
+ ['--base-url <origin>', 'Public API origin'],
20
+ ['--one-url <origin>', 'Vigilbase One origin'],
21
+ ['--auth-url <origin>', 'Identity issuer (default: auth.vigilbase.com)'],
22
+ ['--client-id <id>', 'Device authorization client ID'],
23
+ ]);
5
24
  export const HELP_TEXT = `Usage: vigilbase <command>
6
25
 
7
26
  Public tools (no login)
@@ -15,6 +34,10 @@ Public tools (no login)
15
34
  Auth-required tools (after login)
16
35
  website-security · react2shell · fortibleed-check
17
36
 
37
+ On this machine (no login)
38
+ cloudflare-checkup Run the Cloudflare Checkup on this machine in one
39
+ command (alias: local cloudflare-checkup)
40
+
18
41
  Account (login required)
19
42
  login · logout · whoami Session
20
43
  account [services|org|…] Account overview
@@ -23,22 +46,16 @@ Account (login required)
23
46
  account invites [list|create]
24
47
  billing [summary|portal] Billing summary / Stripe portal
25
48
  runs [list|get <id>] Tool run history
26
- cf <command> Cloudflare accounts, zones, DNS, WAF, analytics
27
- security <command> Incidents, logs, assets, detections, intel, reports
49
+ cf <command> Cloudflare accounts, zones, DNS, WAF, analytics
50
+ security <command> Incidents, logs, assets, detections, intel, reports
28
51
  watchdog [list|scans] Watchdog targets / scans
29
- customers <command> Customer records, billing, reports, investigations
30
- orgs <command> Organizations, members, permission roles
31
- monitoring <command> Health, probes, metrics, customer targets
32
- support tickets Support ticket history
52
+ customers <command> Customer records, billing, reports, investigations
53
+ orgs <command> Organizations, members, permission roles
54
+ monitoring <command> Health, probes, metrics, customer targets
55
+ support tickets Support ticket history
33
56
 
34
57
  Options
35
- -j, --json JSON output
36
- -h, --help Help for the current command
37
- -V, --version Installed version
38
- --timeout <milliseconds> Request timeout (default: 60000)
39
- --base-url <origin> Public API origin
40
- --one-url <origin> Vigilbase One origin
41
- --client-id <id> Device authorization client ID
58
+ ${GLOBAL_OPTIONS}
42
59
 
43
60
  Use vigilbase <command> --help for command options.
44
61
 
@@ -70,9 +87,10 @@ Login: website-security, react2shell, fortibleed-check`;
70
87
  case 'doctor':
71
88
  return `Usage: vigilbase doctor [--json]
72
89
 
73
- Checks the public tools API and Vigilbase One session endpoint independently.
74
- Login is optional. Exits with status 1 if either check fails.
75
- Use --base-url, --one-url, and --timeout to check alternate environments.`;
90
+ Checks the public tools API, your session (Identity's userinfo endpoint when
91
+ signed in through Identity, otherwise One's session endpoint) and any saved
92
+ sign-in independently. Login is optional. Exits with status 1 if any check fails.
93
+ Use --base-url, --one-url, --auth-url and --timeout to check other environments.`;
76
94
  case 'account':
77
95
  return `Usage: vigilbase account [services|org|endpoints|sessions|invites|billing] [--json]
78
96
 
@@ -95,6 +113,9 @@ List only: --tool <name>, --limit <1..200> (default 50).`;
95
113
  case 'watchdog':
96
114
  return `Usage: vigilbase watchdog [list|scans] [--json]
97
115
  Scans only: --target-id <UUID>, --limit <1..100> (default 20).`;
116
+ case 'local':
117
+ case 'cloudflare-checkup':
118
+ return LOCAL_HELP;
98
119
  case 'billing':
99
120
  return `Usage: vigilbase billing [summary|portal] [--json]
100
121
  Portal only: --no-open. URLs must use HTTPS on billing.stripe.com.`;
@@ -113,4 +134,3 @@ Prefer --token-stdin with piped input to keep tokens out of command arguments.`;
113
134
  return null;
114
135
  }
115
136
  }
116
- //# sourceMappingURL=help.js.map
@@ -8,10 +8,19 @@ export declare function networkError(error: unknown, url: string, timeoutMs: num
8
8
  export declare const MAX_RESPONSE_BYTES: number;
9
9
  /** Bound decoded bytes even when Content-Length is absent, compressed, or dishonest. */
10
10
  export declare function readBoundedBody(response: Response, signal: AbortSignal, maxBytes?: number): Promise<string>;
11
+ /**
12
+ * A signal that aborts with the reason of the first of `signals` to abort.
13
+ * Uses `AbortSignal.any` (Node 20.3+) and combines them by hand on older
14
+ * Node 20; `dispose` then removes the listeners so a long-lived signal does
15
+ * not collect one per request.
16
+ */
17
+ export declare function anySignal(signals: AbortSignal[]): {
18
+ signal: AbortSignal;
19
+ dispose: () => void;
20
+ };
11
21
  /** Keep the timeout active until the complete response body has been read. */
12
22
  export declare function requestText(config: CliConfig, url: string, init?: RequestInit): Promise<{
13
23
  response: Response;
14
24
  text: string;
15
25
  }>;
16
26
  export declare function parseJsonResponse(response: Response, text: string): unknown;
17
- //# sourceMappingURL=network.d.ts.map
@@ -70,16 +70,44 @@ export async function readBoundedBody(response, signal, maxBytes = MAX_RESPONSE_
70
70
  reader.releaseLock();
71
71
  }
72
72
  }
73
+ /**
74
+ * A signal that aborts with the reason of the first of `signals` to abort.
75
+ * Uses `AbortSignal.any` (Node 20.3+) and combines them by hand on older
76
+ * Node 20; `dispose` then removes the listeners so a long-lived signal does
77
+ * not collect one per request.
78
+ */
79
+ export function anySignal(signals) {
80
+ if (typeof AbortSignal.any === 'function')
81
+ return { signal: AbortSignal.any(signals), dispose: () => undefined };
82
+ const controller = new AbortController();
83
+ const dispose = () => {
84
+ for (const signal of signals)
85
+ signal.removeEventListener('abort', onAbort);
86
+ };
87
+ function onAbort(event) {
88
+ dispose();
89
+ controller.abort(event.target.reason);
90
+ }
91
+ const aborted = signals.find((signal) => signal.aborted);
92
+ if (aborted) {
93
+ controller.abort(aborted.reason);
94
+ return { signal: controller.signal, dispose: () => undefined };
95
+ }
96
+ for (const signal of signals)
97
+ signal.addEventListener('abort', onAbort, { once: true });
98
+ return { signal: controller.signal, dispose };
99
+ }
73
100
  /** Keep the timeout active until the complete response body has been read. */
74
101
  export async function requestText(config, url, init = {}) {
75
102
  const controller = new AbortController();
76
103
  const timer = setTimeout(() => controller.abort(), config.timeoutMs);
77
- const signal = init.signal
78
- ? AbortSignal.any([init.signal, controller.signal])
79
- : controller.signal;
104
+ const { signal, dispose } = init.signal
105
+ ? anySignal([init.signal, controller.signal])
106
+ : { signal: controller.signal, dispose: () => undefined };
80
107
  try {
81
108
  // Never forward token-bearing POST bodies (or credentials) through redirects.
82
- const response = await fetch(url, { ...init, signal, redirect: 'error' });
109
+ // 'manual' is honoured because it surfaces the 3xx without following it.
110
+ const response = await fetch(url, { ...init, signal, redirect: init.redirect === 'manual' ? 'manual' : 'error' });
83
111
  return { response, text: await readBoundedBody(response, signal) };
84
112
  }
85
113
  catch (error) {
@@ -92,6 +120,7 @@ export async function requestText(config, url, init = {}) {
92
120
  }
93
121
  finally {
94
122
  clearTimeout(timer);
123
+ dispose();
95
124
  }
96
125
  }
97
126
  export function parseJsonResponse(response, text) {
@@ -105,4 +134,3 @@ export function parseJsonResponse(response, text) {
105
134
  throw new NetworkError(`Expected JSON but received a non-JSON response (HTTP ${response.status}). Check the configured API URL and any proxy or sign-in page.`, 'INVALID_RESPONSE');
106
135
  }
107
136
  }
108
- //# sourceMappingURL=network.js.map
@@ -45,8 +45,11 @@ export declare const ONE_EXECUTABLE_TOOLS: readonly ["security-headers", "email-
45
45
  export declare function isOneExecutableTool(toolName: string): boolean;
46
46
  export declare class VigilbaseOneClient {
47
47
  private readonly config;
48
- private readonly accessToken;
49
- constructor(config: CliConfig, accessToken: string);
48
+ private accessToken;
49
+ private readonly managed;
50
+ /** The userinfo endpoint Identity discovery named for the last getSession, if it used Identity. */
51
+ userinfoEndpoint?: string;
52
+ constructor(config: CliConfig, accessToken: string, managed?: boolean);
50
53
  private request;
51
54
  /** Authenticated JSON transport shared by the One command clients. */
52
55
  requestJson<T extends ApiErrorBody = Record<string, unknown>>(path: string, init?: RequestInit, options?: {
@@ -88,4 +91,3 @@ export declare class VigilbaseOneClient {
88
91
  executeTool(toolName: string, target: string): Promise<OneToolExecuteResponse>;
89
92
  }
90
93
  export {};
91
- //# sourceMappingURL=one-client.d.ts.map
@@ -1,3 +1,6 @@
1
+ import { managedAccessToken } from '../auth/refresh.js';
2
+ import { readCredentials } from '../auth/store.js';
3
+ import { identityProvider } from '../auth/provider.js';
1
4
  import { randomUUID } from 'node:crypto';
2
5
  import { z } from 'zod';
3
6
  import { validateOneOrigin } from './config.js';
@@ -80,13 +83,22 @@ export function isOneExecutableTool(toolName) {
80
83
  export class VigilbaseOneClient {
81
84
  config;
82
85
  accessToken;
83
- constructor(config, accessToken) {
86
+ managed;
87
+ /** The userinfo endpoint Identity discovery named for the last getSession, if it used Identity. */
88
+ userinfoEndpoint;
89
+ constructor(config, accessToken, managed = false) {
84
90
  this.config = config;
85
91
  this.accessToken = accessToken;
92
+ this.managed = managed;
86
93
  }
87
94
  async request(path, init) {
88
95
  const url = `${validateOneOrigin(this.config.oneBaseUrl)}${path.startsWith('/') ? path : `/${path}`}`;
89
- const { response, text } = await requestText(this.config, url, {
96
+ if (this.managed) {
97
+ const token = await managedAccessToken(this.config);
98
+ if (token)
99
+ this.accessToken = token;
100
+ }
101
+ const send = () => requestText(this.config, url, {
90
102
  ...init,
91
103
  headers: {
92
104
  Accept: 'application/json',
@@ -95,6 +107,14 @@ export class VigilbaseOneClient {
95
107
  ...(init?.headers ?? {}),
96
108
  },
97
109
  });
110
+ let { response, text } = await send();
111
+ if (response.status === 401 && this.managed) {
112
+ const token = await managedAccessToken(this.config, this.accessToken);
113
+ if (token) {
114
+ this.accessToken = token;
115
+ ({ response, text } = await send());
116
+ }
117
+ }
98
118
  return { response, body: parseJsonResponse(response, text) };
99
119
  }
100
120
  /** Authenticated JSON transport shared by the One command clients. */
@@ -135,6 +155,33 @@ export class VigilbaseOneClient {
135
155
  return parsed;
136
156
  }
137
157
  async getSession() {
158
+ const saved = this.managed ? await readCredentials(this.config) : null;
159
+ const issuer = this.config.authProvider?.issuer ?? (saved?.version === 2 ? saved.one?.issuer : undefined);
160
+ if (issuer) {
161
+ const provider = await identityProvider(this.config, issuer);
162
+ this.userinfoEndpoint = provider.userinfoEndpoint;
163
+ if (this.managed) {
164
+ const token = await managedAccessToken(this.config);
165
+ if (!token)
166
+ throw new VigilbaseApiError('Authentication required.', { status: 401 });
167
+ this.accessToken = token;
168
+ }
169
+ const load = () => requestText(this.config, provider.userinfoEndpoint, { headers: { Authorization: `Bearer ${this.accessToken}`, Accept: 'application/json', 'User-Agent': this.config.userAgent } });
170
+ let { response, text } = await load();
171
+ if (response.status === 401 && this.managed) {
172
+ const token = await managedAccessToken(this.config, this.accessToken);
173
+ if (token) {
174
+ this.accessToken = token;
175
+ ({ response, text } = await load());
176
+ }
177
+ }
178
+ if (!response.ok)
179
+ throw new VigilbaseApiError('Failed to load Identity profile.', { status: response.status });
180
+ const user = z.object({ sub: z.string(), email: z.string().optional(), name: z.string().optional() }).safeParse(parseJsonResponse(response, text));
181
+ if (!user.success)
182
+ throw new VigilbaseApiError('Invalid Identity profile.', { status: response.status });
183
+ return { user: { id: user.data.sub, email: user.data.email, name: user.data.name } };
184
+ }
138
185
  const { response, body } = await this.request('/api/auth/get-session');
139
186
  if (!response.ok) {
140
187
  throw new VigilbaseApiError(`Failed to load One session (HTTP ${response.status})`, { status: response.status, body });
@@ -239,4 +286,3 @@ export class VigilbaseOneClient {
239
286
  }, { allowStatuses: [422] });
240
287
  }
241
288
  }
242
- //# sourceMappingURL=one-client.js.map
@@ -8,4 +8,3 @@ export interface OneOperation {
8
8
  export declare function executeOneOperation(client: VigilbaseOneClient, operation: OneOperation): Promise<Record<string, unknown>>;
9
9
  /** Render all fields, including pagination and degraded-health metadata. */
10
10
  export declare function formatOnePayload(value: unknown, indent?: string): string[];
11
- //# sourceMappingURL=one-operations.d.ts.map
@@ -64,4 +64,3 @@ export function formatOnePayload(value, indent = '') {
64
64
  return [`${indent}${safeText(key)}: ${safeText(item)}`];
65
65
  });
66
66
  }
67
- //# sourceMappingURL=one-operations.js.map
@@ -24,4 +24,3 @@ export declare function resolveDeviceVerificationUrl(oneBaseUrl: string, device:
24
24
  verification_uri?: string;
25
25
  verification_uri_complete?: string;
26
26
  }): string;
27
- //# sourceMappingURL=open-url.d.ts.map
@@ -110,4 +110,3 @@ export function resolveDeviceVerificationUrl(oneBaseUrl, device) {
110
110
  // redirect parameters, fragments, or paths, even when they share One's origin.
111
111
  return fallback;
112
112
  }
113
- //# sourceMappingURL=open-url.js.map
@@ -0,0 +1,2 @@
1
+ /** The host platform. A function rather than a constant so tests can simulate Windows. */
2
+ export declare function platform(): NodeJS.Platform;
@@ -0,0 +1,4 @@
1
+ /** The host platform. A function rather than a constant so tests can simulate Windows. */
2
+ export function platform() {
3
+ return process.platform;
4
+ }
@@ -17,4 +17,3 @@ export declare function shouldShowProgress(mode: 'text' | 'json', env?: NodeJS.P
17
17
  }): boolean;
18
18
  /** Tiny helper so call sites stay readable. */
19
19
  export declare function withProgress<T>(label: string, mode: 'text' | 'json', work: () => Promise<T>, writer?: Writer): Promise<T>;
20
- //# sourceMappingURL=progress.d.ts.map
@@ -77,4 +77,3 @@ export async function withProgress(label, mode, work, writer) {
77
77
  throw error;
78
78
  }
79
79
  }
80
- //# sourceMappingURL=progress.js.map
@@ -237,8 +237,8 @@ export declare const securityResponses: {
237
237
  intel: z.ZodObject<{
238
238
  query: z.ZodString;
239
239
  query_type: z.ZodEnum<{
240
- ip: "ip";
241
240
  asn: "asn";
241
+ ip: "ip";
242
242
  cidr: "cidr";
243
243
  ja3: "ja3";
244
244
  ja4: "ja4";
@@ -276,4 +276,3 @@ export declare class SecurityClient {
276
276
  constructor(one: VigilbaseOneClient);
277
277
  request(input: SecurityRequest): Promise<SecurityPayload>;
278
278
  }
279
- //# sourceMappingURL=security-client.d.ts.map
@@ -108,4 +108,3 @@ export class SecurityClient {
108
108
  return payload;
109
109
  }
110
110
  }
111
- //# sourceMappingURL=security-client.js.map
@@ -4,4 +4,3 @@ export declare function isPublicSkillAddress(address: string): boolean;
4
4
  export declare function validateSkillUrl(raw: string): URL;
5
5
  /** Resolve once, reject mixed private/public DNS, and pin the validated address to TLS. */
6
6
  export declare function fetchSkillText(config: CliConfig, raw: string): Promise<string>;
7
- //# sourceMappingURL=skill-fetch.d.ts.map
@@ -99,4 +99,3 @@ export async function fetchSkillText(config, raw) {
99
99
  clearTimeout(timer);
100
100
  }
101
101
  }
102
- //# sourceMappingURL=skill-fetch.js.map
@@ -5,4 +5,3 @@ type SystemTrustApi = {
5
5
  /** CLI startup only: preserve bundled/extra CAs and add OS-managed trust. */
6
6
  export declare function configureSystemTrust(api?: SystemTrustApi): boolean;
7
7
  export {};
8
- //# sourceMappingURL=system-trust.d.ts.map
@@ -8,4 +8,3 @@ export function configureSystemTrust(api = tls) {
8
8
  ]);
9
9
  return true;
10
10
  }
11
- //# sourceMappingURL=system-trust.js.map