@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
@@ -3,4 +3,3 @@ import { type CommandContext, type CommandHandler } from './helpers.js';
3
3
  export declare function buildOneOperation(ctx: CommandContext): OneOperation;
4
4
  export declare const handleOne: CommandHandler;
5
5
  export declare const ONE_HELP: Record<string, string>;
6
- //# sourceMappingURL=one.d.ts.map
@@ -153,7 +153,7 @@ export const handleOne = async (ctx) => {
153
153
  };
154
154
  export const ONE_HELP = {
155
155
  customers: `Usage: vigilbase customers <command> [--json]
156
- list List visible customers (also the default)
156
+ list List visible customers (also the default)
157
157
  show <customer-id> Full customer details
158
158
  summary <customer-id> Lightweight service/integration summary
159
159
  services <customer-id> Service records
@@ -163,7 +163,7 @@ export const ONE_HELP = {
163
163
  watchdog-targets <customer-id> Security/uptime targets
164
164
  watchdog-scans <customer-id> --limit 1..100 --offset 0..1000000 --target-id UUID
165
165
  reports <customer-id> Recon reports; --limit 1..100
166
- report <customer-id> <report-id> Recon report detail
166
+ report <customer-id> <report-id> Recon report detail
167
167
  investigations <customer-id> --limit 1..100 --cursor TEXT or --before ISO; --issue-id TEXT
168
168
  investigation <customer-id> <id> --revision 1..2147483647
169
169
  contracts <customer-id> --status draft|pending|active|expired|terminated
@@ -186,10 +186,10 @@ These commands read organization context; they do not switch the active organiza
186
186
  health Metrics backend and alerting readiness (also the default)
187
187
  probes Registered probe heartbeats (internal operators)
188
188
  probe-health Live probe health, with database fallback
189
- metrics <target-id>... Metrics for 1..50 target UUIDs
190
- targets <customer-id> Customer's monitoring targets
191
- status <customer-id> Current status; --light skips latency/SSL provider reads
192
- history <customer-id> --range 24h|7d|30d --region CODE --target-id UUID
189
+ metrics <target-id>... Metrics for 1..50 target UUIDs
190
+ targets <customer-id> Customer's monitoring targets
191
+ status <customer-id> Current status; --light skips latency/SSL provider reads
192
+ history <customer-id> --range 24h|7d|30d --region CODE --target-id UUID
193
193
  All operations require read:monitoring and the API's tenant access checks.
194
194
  History defaults to 7d. Health metadata preserves unknown, partial, and unavailable states.`,
195
195
  support: `Usage: vigilbase support tickets [--all] [--limit 1..100] [--json]
@@ -197,4 +197,3 @@ Lists current organization's open tickets; --all includes closed tickets.
197
197
  The API defaults to 50 results. Requires support:access and a linked Pylon account.
198
198
  The response retains hasMore; the API does not expose cursor pagination.`,
199
199
  };
200
- //# sourceMappingURL=one.js.map
@@ -6,4 +6,3 @@ export declare const handleDescribe: CommandHandler;
6
6
  export declare const handleSkill: CommandHandler;
7
7
  export declare const handleBadge: CommandHandler;
8
8
  export declare const handleDoctor: CommandHandler;
9
- //# sourceMappingURL=public-tools.d.ts.map
@@ -2,16 +2,38 @@ import { z } from 'zod';
2
2
  import { toolNameSchema, validateArguments } from './legacy-validation.js';
3
3
  import { NetworkError } from '../lib/network.js';
4
4
  import { VigilbaseApiError } from '../lib/client.js';
5
- import { getOneAccessToken } from '../auth/index.js';
5
+ import { getOneAccessToken, getOptionalOneAccessToken, hasUsableSignIn, readCredentials } from '../auth/index.js';
6
+ import { SignInUnsupportedError } from '../auth/store.js';
6
7
  import { formatExecuteResult, formatToolDescription, formatToolsList, } from '../lib/format.js';
7
8
  import { isOneAuthRequiredTool, isOneExecutableTool, ONE_AUTH_REQUIRED_TOOLS, resolveToolDefinition, VigilbaseOneClient, } from '../lib/one-client.js';
8
9
  import { EXIT, ok, outputJson, withSpinner, } from './helpers.js';
10
+ const ONE_SIGN_IN_REQUIRED = 'This tool needs a Vigilbase One sign-in: run `vigilbase login`.';
11
+ /**
12
+ * For --via one and auth-required tools only: any sign-in problem fails. Specific errors keep their
13
+ * message; those that don't already point to `vigilbase login` get it as their hint.
14
+ */
15
+ async function requireOneSignIn(config) {
16
+ let accessToken;
17
+ try {
18
+ accessToken = await getOneAccessToken(config);
19
+ }
20
+ catch (error) {
21
+ // Windows cannot sign in at all, so pointing to login would mislead.
22
+ if (error instanceof Error && !(error instanceof SignInUnsupportedError) && !error.message.includes('`vigilbase login`')) {
23
+ Object.assign(error, { hint: ONE_SIGN_IN_REQUIRED });
24
+ }
25
+ throw error;
26
+ }
27
+ if (!accessToken)
28
+ throw new Error(ONE_SIGN_IN_REQUIRED);
29
+ return accessToken;
30
+ }
9
31
  /** Public tools work without login. Auth-required tools need Vigilbase One. */
10
32
  export const handleList = async (ctx) => {
11
33
  validateArguments(ctx, 0);
12
34
  const catalog = await withSpinner(ctx, 'Loading tool catalog', () => ctx.publicClient.listTools());
13
- const accessToken = await getOneAccessToken(ctx.config);
14
- const authenticated = Boolean(accessToken);
35
+ // Offline: list never refreshes, so it cannot leave a refresh half-done.
36
+ const authenticated = await hasUsableSignIn(ctx.config, ctx.writer.stderr);
15
37
  if (ctx.mode === 'json') {
16
38
  outputJson(ctx, {
17
39
  ...catalog,
@@ -65,19 +87,17 @@ export const handleRun = async (ctx) => {
65
87
  if (via && via !== 'one' && via !== 'public') {
66
88
  throw new Error('--via must be one of: public, one');
67
89
  }
68
- const accessToken = await getOneAccessToken(ctx.config);
69
90
  const forcePublic = Boolean(ctx.values.isPublic) || via === 'public';
70
91
  const forceOne = via === 'one';
71
92
  // Public tools stay free unless forced onto One. Auth-required tools need login.
93
+ // The public route is anonymous and never reads the credential store.
72
94
  const useOne = !forcePublic && (forceOne || isOneAuthRequiredTool(toolName));
73
95
  if (useOne) {
74
- if (!accessToken) {
75
- throw new Error(`Tool "${toolName}" requires Vigilbase One auth. Run \`vigilbase login\` first.`);
76
- }
96
+ const accessToken = await requireOneSignIn(ctx.config);
77
97
  if (!isOneExecutableTool(toolName)) {
78
98
  throw new Error(`Tool "${toolName}" is not executable via Vigilbase One CLI yet.`);
79
99
  }
80
- const oneClient = new VigilbaseOneClient(ctx.config, accessToken);
100
+ const oneClient = new VigilbaseOneClient(ctx.config, accessToken, true);
81
101
  const oneResult = await withSpinner(ctx, `Running ${toolName} against ${target}`, () => oneClient.executeTool(toolName, target));
82
102
  formatExecuteResult({
83
103
  success: Boolean(oneResult.success),
@@ -162,12 +182,22 @@ export const handleBadge = async (ctx) => {
162
182
  };
163
183
  export const handleDoctor = async (ctx) => {
164
184
  validateArguments(ctx, 0);
165
- const [publicResult, oneResult] = await withSpinner(ctx, 'Checking public API and Vigilbase One', () => Promise.allSettled([
185
+ let oneCheckUrl = `${ctx.config.oneBaseUrl}/api/auth/get-session`;
186
+ // A sign-in problem fails its own check, and One connectivity is then checked anonymously.
187
+ // The saved sign-in may refresh, with the configured timeout like any One command.
188
+ const signIn = getOptionalOneAccessToken(ctx.config);
189
+ const [publicResult, oneResult, signInResult] = await withSpinner(ctx, 'Checking public API and Vigilbase One', () => Promise.allSettled([
166
190
  ctx.publicClient.listTools(),
167
191
  (async () => {
168
- const accessToken = await getOneAccessToken(ctx.config);
192
+ const { accessToken } = await signIn;
193
+ const saved = accessToken ? await readCredentials(ctx.config) : null;
194
+ // An Identity session is checked at the userinfo endpoint its issuer's discovery names.
195
+ if (saved?.version === 2)
196
+ oneCheckUrl = `${saved.one.issuer}/.well-known/openid-configuration`;
197
+ // Signed out, the check stays anonymous and never reads the credential store.
198
+ const client = new VigilbaseOneClient(ctx.config, accessToken ?? '', Boolean(accessToken));
169
199
  try {
170
- const session = await new VigilbaseOneClient(ctx.config, accessToken ?? '').getSession();
200
+ const session = await client.getSession();
171
201
  return { authenticated: Boolean(session.user?.id) };
172
202
  }
173
203
  catch (error) {
@@ -177,15 +207,23 @@ export const handleDoctor = async (ctx) => {
177
207
  }
178
208
  throw error;
179
209
  }
210
+ finally {
211
+ if (client.userinfoEndpoint)
212
+ oneCheckUrl = client.userinfoEndpoint;
213
+ }
180
214
  })(),
215
+ signIn.then(({ problem }) => {
216
+ if (problem)
217
+ throw new Error(problem);
218
+ }),
181
219
  ]));
182
220
  const checkResult = (result, url) => {
183
221
  if (result.status === 'fulfilled')
184
- return { ok: true, url };
222
+ return { ok: true, ...(url ? { url } : {}) };
185
223
  const error = result.reason;
186
224
  return {
187
225
  ok: false,
188
- url,
226
+ ...(url ? { url } : {}),
189
227
  error: error instanceof Error ? error.message : 'Connectivity check failed.',
190
228
  ...(error instanceof VigilbaseApiError || error instanceof NetworkError ? { status: error.status } : {}),
191
229
  ...(error instanceof NetworkError ? { code: error.code } : {}),
@@ -193,9 +231,10 @@ export const handleDoctor = async (ctx) => {
193
231
  };
194
232
  const checks = {
195
233
  publicApi: checkResult(publicResult, `${ctx.config.publicBaseUrl}/api/agent/tools`),
196
- one: checkResult(oneResult, `${ctx.config.oneBaseUrl}/api/auth/get-session`),
234
+ one: checkResult(oneResult, oneCheckUrl),
235
+ signIn: checkResult(signInResult),
197
236
  };
198
- const isOk = checks.publicApi.ok && checks.one.ok;
237
+ const isOk = checks.publicApi.ok && checks.one.ok && checks.signIn.ok;
199
238
  const firstFailure = Object.values(checks).find((check) => !check.ok);
200
239
  const catalog = publicResult.status === 'fulfilled' ? publicResult.value : null;
201
240
  const payload = {
@@ -219,10 +258,9 @@ export const handleDoctor = async (ctx) => {
219
258
  }
220
259
  else {
221
260
  for (const [label, check] of Object.entries(checks)) {
222
- ctx.writer.stdout(`${check.ok ? 'ok' : 'fail'} ${label} ${check.url}${check.error ? ` — ${check.error}` : ''}`);
261
+ ctx.writer.stdout(`${check.ok ? 'ok' : 'fail'} ${label}${check.url ? ` ${check.url}` : ''}${check.error ? ` — ${check.error}` : ''}`);
223
262
  }
224
263
  ctx.writer.stdout(`auth=${payload.authenticated ? 'in' : 'out'} tools=${payload.tools.join(',') || 'unavailable'}`);
225
264
  }
226
265
  return isOk ? ok() : EXIT.ERROR;
227
266
  };
228
- //# sourceMappingURL=public-tools.js.map
@@ -1,3 +1,2 @@
1
1
  import { type CommandHandler } from './helpers.js';
2
2
  export declare const handleRuns: CommandHandler;
3
- //# sourceMappingURL=runs.d.ts.map
@@ -73,4 +73,3 @@ export const handleRuns = async (ctx) => {
73
73
  }
74
74
  throw new Error('Usage: vigilbase runs [list|get <id>] [--tool …] [--limit …] [--json]');
75
75
  };
76
- //# sourceMappingURL=runs.js.map
@@ -2,5 +2,4 @@ import { type SecurityRequest } from '../lib/security-client.js';
2
2
  import { type CommandContext, type CommandHandler } from './helpers.js';
3
3
  export declare function buildSecurityRequest(ctx: CommandContext): SecurityRequest;
4
4
  export declare const handleSecurity: CommandHandler;
5
- export declare const SECURITY_HELP = "vigilbase security \u2014 managed security in Vigilbase One\n\n [overview]\n incidents [list] --status --severity --attack-category\n --order-by --order-direction --limit --offset\n incidents show <id>\n incidents timeline <id> --limit --before\n incidents fabric <id> --dataset --min-weight --limit\n incidents share-links <id>\n incidents update <id> <status> --confirm [--note]\n alerts [list] --limit --asset-id --start\n alerts show <id>\n logs --limit --asset-id --provider --dataset --search\n --start --end --sort --frs-min --cursor\n audit --limit --cursor --action-prefix --outcome\n assets\n assets <allowlist|blocklist|remediation|autonomy|datasets> <asset-id>\n assets graph <asset-id> --dataset --hours --min-weight --limit\n fabric default-asset\n detections --asset-id\n providers\n connections [list]\n connections show <id>\n connections <available-assets|remediation> <id>\n connections <logpush-status|worker-stats> <connection-id> <job-id>\n analytics [overview] --metrics + time-window flags\n analytics <security-analysis|bot-activity|top-attacker-ips|bot-asns|dns-security|page-shield>\n analytics provider-events --provider --dataset --start --end\n [--asset-id --search --limit]\n zero-trust <device-health|app-tests|access|sessions|device-posture>\n zero-trust gateway <dns|http|network>\n cloudflare-account [inventory]\n cloudflare-account <audit|ingestion|posture>\n notifications [list] --limit\n notifications <settings|preferences|slack-channels>\n reports [list] --limit --offset\n reports show <id>\n reports settings\n intel quota\n intel <ip|asn|cidr|ja3|ja4> <query>\n settings <lifecycle-emails|broadcast-emails|applications>\n\nTime-window flags: --hours (1\u2013720, default 24) or --start/--end ISO timestamps;\noptional --asset-id. Apply to analytics (except provider-events), zero-trust,\nand cloudflare-account audit/ingestion/posture. Inventory has no window flags.\nLimits: list incidents/reports/audit 1\u2013100 (default 50); alerts/notifications\n1\u2013100 (default 100); timeline 1\u2013200 (default 100); logs 1\u20131000 (default 100);\nprovider-events 1\u2013500 (default 200); graph 1\u20131000 (default 200).\nOffsets: 0\u20131000000. Graph min-weight: 1\u20131000000 (default 1).\nAll: --json, --timeout <ms>, --customer-id <One customer UUID> (internal View-as).\nAll operations read data except confirmed incident status updates.\nUpdate status: acknowledged, mitigating, resolved, false_positive.\nSee SECURITY.md for every endpoint, supported value, alias, and pagination contract.\n";
6
- //# sourceMappingURL=security.d.ts.map
5
+ export declare const SECURITY_HELP = "vigilbase security \u2014 managed security in Vigilbase One\n\n [overview]\n incidents [list] --status --severity --attack-category\n --order-by --order-direction --limit --offset\n incidents show <id>\n incidents timeline <id> --limit --before\n incidents fabric <id> --dataset --min-weight --limit\n incidents share-links <id>\n incidents update <id> <status> --confirm [--note]\n alerts [list] --limit --asset-id --start\n alerts show <id>\n logs --limit --asset-id --provider --dataset --search\n --start --end --sort --frs-min --cursor\n audit --limit --cursor --action-prefix --outcome\n assets\n assets <allowlist|blocklist|remediation|autonomy|datasets> <asset-id>\n assets graph <asset-id> --dataset --hours --min-weight --limit\n fabric default-asset\n detections --asset-id\n providers\n connections [list]\n connections show <id>\n connections <available-assets|remediation> <id>\n connections <logpush-status|worker-stats> <connection-id> <job-id>\n analytics [overview] --metrics + time-window flags\n analytics <security-analysis|bot-activity|top-attacker-ips|bot-asns|dns-security|page-shield>\n analytics provider-events --provider --dataset --start --end\n [--asset-id --search --limit]\n zero-trust <device-health|app-tests|access|sessions|device-posture>\n zero-trust gateway <dns|http|network>\n cloudflare-account [inventory]\n cloudflare-account <audit|ingestion|posture>\n notifications [list] --limit\n notifications <settings|preferences|slack-channels>\n reports [list] --limit --offset\n reports show <id>\n reports settings\n intel quota\n intel <ip|asn|cidr|ja3|ja4> <query>\n settings <lifecycle-emails|broadcast-emails|applications>\n\nTime-window flags: --hours (1\u2013720, default 24) or --start/--end ISO timestamps;\noptional --asset-id. Apply to analytics (except provider-events), zero-trust,\nand cloudflare-account audit/ingestion/posture. Inventory has no window flags.\nLimits: list incidents/reports/audit 1\u2013100 (default 50); alerts/notifications\n1\u2013100 (default 100); timeline 1\u2013200 (default 100); logs 1\u20131000 (default 100);\nprovider-events 1\u2013500 (default 200); graph 1\u20131000 (default 200).\nOffsets: 0\u20131000000. Graph min-weight: 1\u20131000000 (default 1).\nAll: --json, --timeout <ms>, --customer-id <One customer UUID> (internal View-as).\nAll operations read data except confirmed incident status updates.\nUpdate status: acknowledged, mitigating, resolved, false_positive.\nSee SECURITY.md for every endpoint, supported value, alias, and pagination contract.\n";
@@ -387,5 +387,4 @@ export const handleSecurity = async (ctx) => {
387
387
  display(ctx, request, payload);
388
388
  return ok();
389
389
  };
390
- export const SECURITY_HELP = "vigilbase security \u2014 managed security in Vigilbase One\n\n [overview]\n incidents [list] --status --severity --attack-category\n --order-by --order-direction --limit --offset\n incidents show <id>\n incidents timeline <id> --limit --before\n incidents fabric <id> --dataset --min-weight --limit\n incidents share-links <id>\n incidents update <id> <status> --confirm [--note]\n alerts [list] --limit --asset-id --start\n alerts show <id>\n logs --limit --asset-id --provider --dataset --search\n --start --end --sort --frs-min --cursor\n audit --limit --cursor --action-prefix --outcome\n assets\n assets <allowlist|blocklist|remediation|autonomy|datasets> <asset-id>\n assets graph <asset-id> --dataset --hours --min-weight --limit\n fabric default-asset\n detections --asset-id\n providers\n connections [list]\n connections show <id>\n connections <available-assets|remediation> <id>\n connections <logpush-status|worker-stats> <connection-id> <job-id>\n analytics [overview] --metrics + time-window flags\n analytics <security-analysis|bot-activity|top-attacker-ips|bot-asns|dns-security|page-shield>\n analytics provider-events --provider --dataset --start --end\n [--asset-id --search --limit]\n zero-trust <device-health|app-tests|access|sessions|device-posture>\n zero-trust gateway <dns|http|network>\n cloudflare-account [inventory]\n cloudflare-account <audit|ingestion|posture>\n notifications [list] --limit\n notifications <settings|preferences|slack-channels>\n reports [list] --limit --offset\n reports show <id>\n reports settings\n intel quota\n intel <ip|asn|cidr|ja3|ja4> <query>\n settings <lifecycle-emails|broadcast-emails|applications>\n\nTime-window flags: --hours (1\u2013720, default 24) or --start/--end ISO timestamps;\noptional --asset-id. Apply to analytics (except provider-events), zero-trust,\nand cloudflare-account audit/ingestion/posture. Inventory has no window flags.\nLimits: list incidents/reports/audit 1\u2013100 (default 50); alerts/notifications\n1\u2013100 (default 100); timeline 1\u2013200 (default 100); logs 1\u20131000 (default 100);\nprovider-events 1\u2013500 (default 200); graph 1\u20131000 (default 200).\nOffsets: 0\u20131000000. Graph min-weight: 1\u20131000000 (default 1).\nAll: --json, --timeout <ms>, --customer-id <One customer UUID> (internal View-as).\nAll operations read data except confirmed incident status updates.\nUpdate status: acknowledged, mitigating, resolved, false_positive.\nSee SECURITY.md for every endpoint, supported value, alias, and pagination contract.\n";
391
- //# sourceMappingURL=security.js.map
390
+ export const SECURITY_HELP = "vigilbase security \u2014 managed security in Vigilbase One\n\n [overview]\n incidents [list] --status --severity --attack-category\n --order-by --order-direction --limit --offset\n incidents show <id>\n incidents timeline <id> --limit --before\n incidents fabric <id> --dataset --min-weight --limit\n incidents share-links <id>\n incidents update <id> <status> --confirm [--note]\n alerts [list] --limit --asset-id --start\n alerts show <id>\n logs --limit --asset-id --provider --dataset --search\n --start --end --sort --frs-min --cursor\n audit --limit --cursor --action-prefix --outcome\n assets\n assets <allowlist|blocklist|remediation|autonomy|datasets> <asset-id>\n assets graph <asset-id> --dataset --hours --min-weight --limit\n fabric default-asset\n detections --asset-id\n providers\n connections [list]\n connections show <id>\n connections <available-assets|remediation> <id>\n connections <logpush-status|worker-stats> <connection-id> <job-id>\n analytics [overview] --metrics + time-window flags\n analytics <security-analysis|bot-activity|top-attacker-ips|bot-asns|dns-security|page-shield>\n analytics provider-events --provider --dataset --start --end\n [--asset-id --search --limit]\n zero-trust <device-health|app-tests|access|sessions|device-posture>\n zero-trust gateway <dns|http|network>\n cloudflare-account [inventory]\n cloudflare-account <audit|ingestion|posture>\n notifications [list] --limit\n notifications <settings|preferences|slack-channels>\n reports [list] --limit --offset\n reports show <id>\n reports settings\n intel quota\n intel <ip|asn|cidr|ja3|ja4> <query>\n settings <lifecycle-emails|broadcast-emails|applications>\n\nTime-window flags: --hours (1\u2013720, default 24) or --start/--end ISO timestamps;\noptional --asset-id. Apply to analytics (except provider-events), zero-trust,\nand cloudflare-account audit/ingestion/posture. Inventory has no window flags.\nLimits: list incidents/reports/audit 1\u2013100 (default 50); alerts/notifications\n1\u2013100 (default 100); timeline 1\u2013200 (default 100); logs 1\u20131000 (default 100);\nprovider-events 1\u2013500 (default 200); graph 1\u20131000 (default 200).\nOffsets: 0\u20131000000. Graph min-weight: 1\u20131000000 (default 1).\nAll: --json, --timeout <ms>, --customer-id <One customer UUID> (internal View-as).\nAll operations read data except confirmed incident status updates.\nUpdate status: acknowledged, mitigating, resolved, false_positive.\nSee SECURITY.md for every endpoint, supported value, alias, and pagination contract.\n";
@@ -1,3 +1,2 @@
1
1
  import { type CommandHandler } from './helpers.js';
2
2
  export declare const handleWatchdog: CommandHandler;
3
- //# sourceMappingURL=watchdog.d.ts.map
@@ -59,4 +59,3 @@ export const handleWatchdog = async (ctx) => {
59
59
  }
60
60
  throw new Error('Usage: vigilbase watchdog [list|scans] [--target-id …] [--limit …] [--json]');
61
61
  };
62
- //# sourceMappingURL=watchdog.js.map
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  export { runCli, CLI_VERSION } from './cli.js';
2
2
  export { VigilbaseClient, VigilbaseApiError } from './lib/client.js';
3
3
  export { createConfig, resolveBaseUrl, resolvePublicBaseUrl, resolveOneBaseUrl, } from './lib/config.js';
4
- export { clearOneCredentials, credentialsPath, DeviceAuthError, getOneAccessToken, readCredentials, requestDeviceCode, waitForDeviceAuthorization, writeOneCredentials, } from './auth/index.js';
4
+ export { discoverAuthProvider, identityProvider, managedAccessToken, revokeSavedCredentials, clearOneCredentials, credentialsPath, DeviceAuthError, getOneAccessToken, identityCredentialsPath, readCredentials, requestDeviceCode, waitForDeviceAuthorization, writeOneCredentials, } from './auth/index.js';
5
5
  export { isOneAuthRequiredTool, isOneExecutableTool, ONE_AUTH_REQUIRED_TOOLS, ONE_AUTH_REQUIRED_TOOL_DEFINITIONS, ONE_EXECUTABLE_TOOLS, VigilbaseOneClient, } from './lib/one-client.js';
6
6
  export { EXIT } from './types.js';
7
- export type { AgentToolDefinition, AgentToolExecuteResponse, AgentToolsCatalogResponse, CliOutputMode, ExitCode, } from './types.js';
7
+ export type { AgentApiError, AgentApiErrorCode, AgentApiErrorResponse, AgentToolDefinition, AgentToolExecuteResponse, AgentToolsCatalogResponse, CliOutputMode, ExitCode, } from './types.js';
8
+ export type { AuthProvider } from './auth/provider.js';
8
9
  export type { CredentialsFile, OneCredentials } from './auth/types.js';
9
10
  export { CloudflareClient } from './lib/cloudflare-client.js';
10
11
  export type { CloudflareScope, WorkspaceSection } from './lib/cloudflare-client.js';
11
12
  export { SecurityClient } from './lib/security-client.js';
12
13
  export type { SecurityPayload, SecurityQuery, SecurityRequest } from './lib/security-client.js';
13
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  export { runCli, CLI_VERSION } from './cli.js';
2
2
  export { VigilbaseClient, VigilbaseApiError } from './lib/client.js';
3
3
  export { createConfig, resolveBaseUrl, resolvePublicBaseUrl, resolveOneBaseUrl, } from './lib/config.js';
4
- export { clearOneCredentials, credentialsPath, DeviceAuthError, getOneAccessToken, readCredentials, requestDeviceCode, waitForDeviceAuthorization, writeOneCredentials, } from './auth/index.js';
4
+ export { discoverAuthProvider, identityProvider, managedAccessToken, revokeSavedCredentials, clearOneCredentials, credentialsPath, DeviceAuthError, getOneAccessToken, identityCredentialsPath, readCredentials, requestDeviceCode, waitForDeviceAuthorization, writeOneCredentials, } from './auth/index.js';
5
5
  export { isOneAuthRequiredTool, isOneExecutableTool, ONE_AUTH_REQUIRED_TOOLS, ONE_AUTH_REQUIRED_TOOL_DEFINITIONS, ONE_EXECUTABLE_TOOLS, VigilbaseOneClient, } from './lib/one-client.js';
6
6
  export { EXIT } from './types.js';
7
7
  export { CloudflareClient } from './lib/cloudflare-client.js';
8
8
  export { SecurityClient } from './lib/security-client.js';
9
- //# sourceMappingURL=index.js.map
@@ -26,4 +26,3 @@ export declare function shouldShowBanner(mode?: 'text' | 'json', env?: NodeJS.Pr
26
26
  export declare function renderBanner(options?: BannerOptions, stream?: {
27
27
  isTTY?: boolean;
28
28
  } | undefined, env?: NodeJS.ProcessEnv): string;
29
- //# sourceMappingURL=banner.d.ts.map
@@ -65,4 +65,3 @@ export function renderBanner(options = {}, stream = process.stdout, env = proces
65
65
  });
66
66
  return lines.join('\n');
67
67
  }
68
- //# sourceMappingURL=banner.js.map
@@ -1,15 +1,18 @@
1
- import type { AgentToolExecuteResponse, AgentToolsCatalogResponse } from '../types.js';
1
+ import { type AgentToolExecuteResponse, type AgentToolsCatalogResponse } from '../types.js';
2
2
  import type { CliConfig } from './config.js';
3
3
  export declare class VigilbaseApiError extends Error {
4
4
  readonly status: number;
5
5
  readonly body: unknown;
6
6
  readonly retryAfterSec?: number;
7
7
  readonly code?: string;
8
+ /** The server's sanitised explanation, set only for known vigilbase.com problem errors. */
9
+ readonly reason?: string;
8
10
  constructor(message: string, options: {
9
11
  status: number;
10
12
  body?: unknown;
11
13
  retryAfterSec?: number;
12
14
  code?: string;
15
+ reason?: string;
13
16
  });
14
17
  }
15
18
  export declare function retryAfterSeconds(response: Response, body: unknown): number | undefined;
@@ -27,4 +30,3 @@ export declare class VigilbaseClient {
27
30
  fetchSkillMarkdown(skillUrl: string): Promise<string>;
28
31
  badgeUrl(domain: string, style?: 'default' | 'compact' | 'mini'): string;
29
32
  }
30
- //# sourceMappingURL=client.d.ts.map
@@ -1,11 +1,15 @@
1
1
  import { z } from 'zod';
2
+ import { singleLine } from './format.js';
2
3
  import { parseJsonResponse, requestText } from './network.js';
3
4
  import { fetchSkillText } from './skill-fetch.js';
5
+ import { AGENT_API_ERROR_CODES, } from '../types.js';
4
6
  export class VigilbaseApiError extends Error {
5
7
  status;
6
8
  body;
7
9
  retryAfterSec;
8
10
  code;
11
+ /** The server's sanitised explanation, set only for known vigilbase.com problem errors. */
12
+ reason;
9
13
  constructor(message, options) {
10
14
  super(message);
11
15
  this.name = 'VigilbaseApiError';
@@ -13,6 +17,7 @@ export class VigilbaseApiError extends Error {
13
17
  this.body = options.body;
14
18
  this.retryAfterSec = options.retryAfterSec;
15
19
  this.code = options.code;
20
+ this.reason = options.reason;
16
21
  }
17
22
  }
18
23
  export function retryAfterSeconds(response, body) {
@@ -30,6 +35,39 @@ export function retryAfterSeconds(response, body) {
30
35
  }
31
36
  return undefined;
32
37
  }
38
+ /** Longer messages are withheld rather than cut. */
39
+ const MAX_REASON_SOURCE_LENGTH = 1000;
40
+ const problemSchema = z.object({
41
+ error: z.object({ code: z.unknown(), message: z.string().max(MAX_REASON_SOURCE_LENGTH) }),
42
+ code: z.unknown(),
43
+ });
44
+ /**
45
+ * The reason a vigilbase.com problem+json error gives, when its code is one com sends.
46
+ * Anything else stays redacted: other media types, unknown codes, odd messages.
47
+ */
48
+ function problemReason(response, body) {
49
+ const mediaType = response.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase();
50
+ if (mediaType !== 'application/problem+json')
51
+ return undefined;
52
+ const problem = problemSchema.safeParse(body);
53
+ if (!problem.success)
54
+ return undefined;
55
+ const code = z.enum(AGENT_API_ERROR_CODES).safeParse(problem.data.error.code ?? problem.data.code);
56
+ if (!code.success)
57
+ return undefined;
58
+ const message = singleLine(problem.data.error.message);
59
+ return message ? { code: code.data, message } : undefined;
60
+ }
61
+ function publicApiError(fallback, response, body) {
62
+ const reason = problemReason(response, body);
63
+ return new VigilbaseApiError(reason?.message ?? fallback, {
64
+ status: response.status,
65
+ body,
66
+ retryAfterSec: retryAfterSeconds(response, body),
67
+ code: reason?.code,
68
+ reason: reason?.message,
69
+ });
70
+ }
33
71
  /**
34
72
  * Public (unauthenticated) vigilbase.com tools client.
35
73
  * Vigilbase One authenticated calls will use a separate client + device-auth tokens.
@@ -57,12 +95,7 @@ export class VigilbaseClient {
57
95
  async listTools() {
58
96
  const { response, body } = await this.request('/api/agent/tools');
59
97
  if (!response.ok) {
60
- const message = `Failed to list tools (HTTP ${response.status})`;
61
- throw new VigilbaseApiError(message, {
62
- status: response.status,
63
- body,
64
- retryAfterSec: retryAfterSeconds(response, body),
65
- });
98
+ throw publicApiError(`Failed to list tools (HTTP ${response.status})`, response, body);
66
99
  }
67
100
  const schema = z.object({
68
101
  success: z.literal(true),
@@ -84,24 +117,16 @@ export class VigilbaseClient {
84
117
  });
85
118
  const parsed = (body ?? {});
86
119
  if (response.status === 429) {
87
- throw new VigilbaseApiError('Rate limit exceeded. Retry after the indicated delay.', {
88
- status: 429,
89
- body: parsed,
90
- retryAfterSec: retryAfterSeconds(response, body),
91
- });
120
+ throw publicApiError('Rate limit exceeded. Retry after the indicated delay.', response, parsed);
92
121
  }
93
122
  if (!response.ok && response.status !== 422) {
94
- throw new VigilbaseApiError(`Tool execution failed (HTTP ${response.status})`, {
95
- status: response.status,
96
- body: parsed,
97
- retryAfterSec: retryAfterSeconds(response, body),
98
- });
123
+ throw publicApiError(`Tool execution failed (HTTP ${response.status})`, response, parsed);
99
124
  }
100
125
  if (!z.object({ success: z.boolean() }).passthrough().safeParse(body).success) {
101
126
  throw new VigilbaseApiError('Invalid tool execution response. Check the API URL or retry later.', { status: response.status });
102
127
  }
103
128
  if (!parsed.success) {
104
- throw new VigilbaseApiError('Tool execution was unsuccessful.', { status: response.status, body, retryAfterSec: retryAfterSeconds(response, body) });
129
+ throw publicApiError('Tool execution was unsuccessful.', response, body);
105
130
  }
106
131
  return parsed;
107
132
  }
@@ -116,4 +141,3 @@ export class VigilbaseClient {
116
141
  return `${this.origin}/api/badge/${encodeURIComponent(domain)}${query ? `?${query}` : ''}`;
117
142
  }
118
143
  }
119
- //# sourceMappingURL=client.js.map
@@ -37,4 +37,3 @@ export declare class CloudflareClient {
37
37
  checkupProgress(toolRunId: string): Promise<Record<string, unknown>>;
38
38
  private path;
39
39
  }
40
- //# sourceMappingURL=cloudflare-client.d.ts.map
@@ -78,4 +78,3 @@ export class CloudflareClient {
78
78
  return `${path}${query ? `?${query}` : ''}`;
79
79
  }
80
80
  }
81
- //# sourceMappingURL=cloudflare-client.js.map
@@ -5,7 +5,13 @@ export type CliConfig = {
5
5
  oneBaseUrl: string;
6
6
  /** OAuth client_id for Better Auth device authorization. */
7
7
  clientId: string;
8
- /** Directory for credentials and local config (~/.config/vigilbase). */
8
+ /** Explicit Identity issuer (--auth-url / VIGILBASE_AUTH_URL). One's discovery must name it; unset, only production Identity is trusted. */
9
+ identityBaseUrl?: string;
10
+ authProvider?: import('../auth/provider.js').AuthProvider;
11
+ /**
12
+ * Directory for credentials and local config (~/.config/vigilbase). Not validated when the config is built:
13
+ * the credential store rejects a relative path itself, so commands that never use it work whatever it holds.
14
+ */
9
15
  configDir: string;
10
16
  userAgent: string;
11
17
  timeoutMs: number;
@@ -14,20 +20,42 @@ export type CliConfig = {
14
20
  export type CliConfigLegacy = CliConfig & {
15
21
  baseUrl: string;
16
22
  };
23
+ export declare function parseOrigin(raw: string, option: string): string;
24
+ /** Default request timeout; also used when library callers omit `timeoutMs`. */
25
+ export declare const DEFAULT_TIMEOUT_MS = 60000;
17
26
  export declare function resolvePublicBaseUrl(explicit?: string | null): string;
18
27
  export declare function resolveOneBaseUrl(explicit?: string | null): string;
19
28
  /** Validate at transport boundaries too: library callers may construct config objects. */
20
29
  export declare function validateOneOrigin(raw: string): string;
30
+ /** Production Identity: the only issuer trusted unless --auth-url / VIGILBASE_AUTH_URL names another. */
31
+ export declare const DEFAULT_IDENTITY_ISSUER = "https://auth.vigilbase.com";
32
+ export declare const STAGING_IDENTITY_ISSUER = "https://identity-staging.vigilbase.com";
33
+ export declare function resolveIdentityBaseUrl(raw: string): string;
34
+ /**
35
+ * The one Identity issuer this configuration trusts: --auth-url / VIGILBASE_AUTH_URL
36
+ * when set, otherwise production. Staging is trusted only when configured explicitly.
37
+ * Validated here too because library callers may construct config objects.
38
+ */
39
+ export declare function trustedIdentityIssuer(config: Pick<CliConfig, 'oneBaseUrl' | 'identityBaseUrl'>): string;
21
40
  export declare function resolveClientId(explicit?: string | null): string;
22
- export declare function resolveConfigDir(explicit?: string | null): string;
41
+ /** The config directory, which must be absolute. */
42
+ export declare function resolveConfigDir(explicit?: string | null, env?: NodeJS.ProcessEnv): string;
23
43
  export declare function createConfig(options?: {
24
44
  baseUrl?: string | null;
25
45
  publicBaseUrl?: string | null;
26
46
  oneBaseUrl?: string | null;
27
47
  clientId?: string | null;
48
+ identityBaseUrl?: string | null;
28
49
  configDir?: string | null;
29
50
  timeoutMs?: number;
30
51
  }): CliConfigLegacy;
52
+ /**
53
+ * Config for `vigilbase local …` and `vigilbase cloudflare-checkup`. Local
54
+ * checkups resolve their own submit origin (resolveSubmitOrigin) and never
55
+ * read VIGILBASE_* URLs. They resolve the config directory themselves, and
56
+ * only when they need it (the managed cf install, the default snapshot path),
57
+ * so malformed values cannot block offline commands such as `inspect`.
58
+ */
59
+ export declare function createLocalCommandConfig(timeoutMs?: number): CliConfigLegacy;
31
60
  /** Back-compat helper used by older call sites / tests. */
32
61
  export declare function resolveBaseUrl(explicit?: string | null): string;
33
- //# sourceMappingURL=config.d.ts.map
@@ -9,7 +9,7 @@ const DEFAULT_CLIENT_ID = 'vigilbase-cli';
9
9
  const originSchema = z.string().url().transform((raw) => new URL(raw)).refine((url) => (url.protocol === 'https:' || url.protocol === 'http:') &&
10
10
  !url.username && !url.password &&
11
11
  /^\/+$/.test(url.pathname) && !url.search && !url.hash, 'Expected an HTTP(S) origin without credentials, a path, query, or fragment.').transform((url) => url.origin);
12
- function parseOrigin(raw, option) {
12
+ export function parseOrigin(raw, option) {
13
13
  const result = originSchema.safeParse(raw);
14
14
  if (!result.success) {
15
15
  // Do not echo the input: malformed URLs can contain credentials.
@@ -18,6 +18,8 @@ function parseOrigin(raw, option) {
18
18
  return result.data;
19
19
  }
20
20
  const timeoutSchema = z.number().int().min(1).max(2_147_483_647);
21
+ /** Default request timeout; also used when library callers omit `timeoutMs`. */
22
+ export const DEFAULT_TIMEOUT_MS = 60_000;
21
23
  export function resolvePublicBaseUrl(explicit) {
22
24
  const raw = explicit?.trim() ||
23
25
  process.env.VIGILBASE_BASE_URL?.trim() ||
@@ -42,26 +44,60 @@ export function validateOneOrigin(raw) {
42
44
  }
43
45
  return origin;
44
46
  }
47
+ /** Production Identity: the only issuer trusted unless --auth-url / VIGILBASE_AUTH_URL names another. */
48
+ export const DEFAULT_IDENTITY_ISSUER = 'https://auth.vigilbase.com';
49
+ export const STAGING_IDENTITY_ISSUER = 'https://identity-staging.vigilbase.com';
50
+ const IDENTITY_OPTION = '--auth-url / VIGILBASE_AUTH_URL';
51
+ function isIdentityLoopback(origin) {
52
+ return ['localhost', '127.0.0.1', '[::1]'].includes(new URL(origin).hostname);
53
+ }
54
+ export function resolveIdentityBaseUrl(raw) {
55
+ const origin = parseOrigin(raw, IDENTITY_OPTION);
56
+ if (origin !== DEFAULT_IDENTITY_ISSUER && origin !== STAGING_IDENTITY_ISSUER && !isIdentityLoopback(origin)) {
57
+ throw new Error(`${IDENTITY_OPTION} must be ${DEFAULT_IDENTITY_ISSUER}, ${STAGING_IDENTITY_ISSUER} or a loopback development origin.`);
58
+ }
59
+ return origin;
60
+ }
61
+ /**
62
+ * The one Identity issuer this configuration trusts: --auth-url / VIGILBASE_AUTH_URL
63
+ * when set, otherwise production. Staging is trusted only when configured explicitly.
64
+ * Validated here too because library callers may construct config objects.
65
+ */
66
+ export function trustedIdentityIssuer(config) {
67
+ if (!config.identityBaseUrl)
68
+ return DEFAULT_IDENTITY_ISSUER;
69
+ const origin = resolveIdentityBaseUrl(config.identityBaseUrl);
70
+ if (isIdentityLoopback(origin) && !isIdentityLoopback(validateOneOrigin(config.oneBaseUrl))) {
71
+ throw new Error(`${IDENTITY_OPTION} can be a loopback origin only when --one-url / VIGILBASE_ONE_URL is loopback too.`);
72
+ }
73
+ return origin;
74
+ }
45
75
  export function resolveClientId(explicit) {
46
76
  return (explicit?.trim() ||
47
77
  process.env.VIGILBASE_CLIENT_ID?.trim() ||
48
78
  DEFAULT_CLIENT_ID);
49
79
  }
50
- export function resolveConfigDir(explicit) {
51
- const custom = explicit?.trim() || process.env.VIGILBASE_CONFIG_DIR?.trim();
52
- const xdg = process.env.XDG_CONFIG_HOME?.trim();
53
- if ((custom && !isAbsolute(custom)) || (xdg && !isAbsolute(xdg))) {
54
- throw new Error('Custom config directories and XDG_CONFIG_HOME must be absolute paths.');
55
- }
80
+ /**
81
+ * VIGILBASE_CONFIG_DIR (or `explicit`), else $XDG_CONFIG_HOME/vigilbase, else ~/.config/vigilbase. A relative
82
+ * XDG_CONFIG_HOME is ignored, as the XDG Base Directory spec says; a relative custom directory is returned as is.
83
+ */
84
+ function configDirFromEnvironment(explicit, env) {
85
+ const custom = explicit?.trim() || env.VIGILBASE_CONFIG_DIR?.trim();
56
86
  if (custom)
57
87
  return custom;
58
- if (xdg)
59
- return join(xdg, 'vigilbase');
60
- return join(homedir(), '.config', 'vigilbase');
88
+ const xdg = env.XDG_CONFIG_HOME?.trim();
89
+ return xdg && isAbsolute(xdg) ? join(xdg, 'vigilbase') : join(homedir(), '.config', 'vigilbase');
90
+ }
91
+ /** The config directory, which must be absolute. */
92
+ export function resolveConfigDir(explicit, env = process.env) {
93
+ const configDir = configDirFromEnvironment(explicit, env);
94
+ if (!isAbsolute(configDir))
95
+ throw new Error('VIGILBASE_CONFIG_DIR must be an absolute path.');
96
+ return configDir;
61
97
  }
62
98
  export function createConfig(options) {
63
99
  const publicBaseUrl = resolvePublicBaseUrl(options?.publicBaseUrl ?? options?.baseUrl);
64
- const timeoutMs = options?.timeoutMs ?? 60_000;
100
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
65
101
  if (!timeoutSchema.safeParse(timeoutMs).success) {
66
102
  throw new Error('Request timeout must be an integer between 1 and 2147483647 milliseconds.');
67
103
  }
@@ -70,14 +106,37 @@ export function createConfig(options) {
70
106
  /** Alias used by the current public tools client. */
71
107
  baseUrl: publicBaseUrl,
72
108
  oneBaseUrl: resolveOneBaseUrl(options?.oneBaseUrl),
109
+ ...(options?.identityBaseUrl || process.env.VIGILBASE_AUTH_URL ? { identityBaseUrl: resolveIdentityBaseUrl(options?.identityBaseUrl || process.env.VIGILBASE_AUTH_URL) } : {}),
73
110
  clientId: resolveClientId(options?.clientId),
74
- configDir: resolveConfigDir(options?.configDir),
111
+ configDir: configDirFromEnvironment(options?.configDir, process.env),
75
112
  userAgent: `@vigilbase/cli/${CLI_VERSION} (+https://vigilbase.com; node/${process.version})`,
76
113
  timeoutMs,
77
114
  };
78
115
  }
116
+ /**
117
+ * Config for `vigilbase local …` and `vigilbase cloudflare-checkup`. Local
118
+ * checkups resolve their own submit origin (resolveSubmitOrigin) and never
119
+ * read VIGILBASE_* URLs. They resolve the config directory themselves, and
120
+ * only when they need it (the managed cf install, the default snapshot path),
121
+ * so malformed values cannot block offline commands such as `inspect`.
122
+ */
123
+ export function createLocalCommandConfig(timeoutMs) {
124
+ const timeout = timeoutMs ?? DEFAULT_TIMEOUT_MS;
125
+ if (!timeoutSchema.safeParse(timeout).success) {
126
+ throw new Error('Request timeout must be an integer between 1 and 2147483647 milliseconds.');
127
+ }
128
+ return {
129
+ publicBaseUrl: DEFAULT_PUBLIC_BASE_URL,
130
+ baseUrl: DEFAULT_PUBLIC_BASE_URL,
131
+ oneBaseUrl: DEFAULT_ONE_BASE_URL,
132
+ clientId: DEFAULT_CLIENT_ID,
133
+ // Unused by local commands; never read from the environment.
134
+ configDir: join(homedir(), '.config', 'vigilbase'),
135
+ userAgent: `@vigilbase/cli/${CLI_VERSION} (+https://vigilbase.com; node/${process.version})`,
136
+ timeoutMs: timeout,
137
+ };
138
+ }
79
139
  /** Back-compat helper used by older call sites / tests. */
80
140
  export function resolveBaseUrl(explicit) {
81
141
  return resolvePublicBaseUrl(explicit);
82
142
  }
83
- //# sourceMappingURL=config.js.map