fuzzi-cli 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Run Fuzzi security scans from your terminal. Interactive shell for daily use, scriptable commands for CI.
4
4
 
5
+ **Web app:** [fuzzi-ten.vercel.app](https://fuzzi-ten.vercel.app)
6
+
5
7
  ```bash
6
8
  npm install -g fuzzi-cli
7
9
  fuzzi
@@ -14,7 +16,7 @@ fuzzi
14
16
  1. **Install** the CLI (above)
15
17
  2. **Run** `fuzzi`
16
18
  3. You'll see **Sign in to continue** — press **Enter**
17
- 4. Your **browser opens** to app.fuzzi.dev — log in or sign up
19
+ 4. Your **browser opens** to [fuzzi-ten.vercel.app](https://fuzzi-ten.vercel.app) — log in or sign up
18
20
  5. After authorizing, return to the terminal — you're in
19
21
 
20
22
  ```
@@ -24,7 +26,7 @@ fuzzi
24
26
  › /palette # search commands
25
27
  ```
26
28
 
27
- No browser? Use **`/auth-key`** to paste an API key from [Settings → API Keys](https://app.fuzzi.dev/settings/api-keys).
29
+ No browser? Use **`/auth-key`** to paste an API key from [Settings → API Keys](https://fuzzi-ten.vercel.app/settings/api-keys).
28
30
 
29
31
  ---
30
32
 
@@ -74,10 +76,7 @@ fuzzi scan https://staging.example.com --fail-on high
74
76
  # JSON for pipelines
75
77
  fuzzi scan https://example.com --format json
76
78
 
77
- # Machine-readable exit codes
78
- # 0 = success, risk below threshold
79
- # 1 = scan done, risk at/above --fail-on
80
- # 2 = error (network, auth, bad URL)
79
+ # Exit codes: 0 = pass, 1 = risk threshold met, 2 = error
81
80
  ```
82
81
 
83
82
  ### All commands
@@ -91,15 +90,12 @@ fuzzi auth logout
91
90
  fuzzi scan <url> [--wait] [--no-wait] [--format table|json|markdown]
92
91
  [--env production|staging|development]
93
92
  [--fail-on low|medium|high|critical]
94
- [--fail-threshold 0.0-1.0]
95
93
 
96
- fuzzi scans list [--status] [--risk-level] [--limit 20]
97
- fuzzi scans get <scan-id> [--format table|json|markdown]
98
- fuzzi report <scan-id> --format pdf|csv|json [-o file]
94
+ fuzzi scans list | get <scan-id>
95
+ fuzzi report <scan-id> --format pdf|csv|json
99
96
  fuzzi whatif <scan-id> --set dimension=0.5
100
97
  fuzzi compare <scan-a> <scan-b>
101
-
102
- fuzzi config list | get [key] | set <key> <value>
98
+ fuzzi config list | get | set
103
99
  fuzzi status
104
100
  fuzzi --help
105
101
  ```
@@ -111,84 +107,48 @@ fuzzi --help
111
107
  | File | Purpose |
112
108
  |------|---------|
113
109
  | `~/.fuzzi/credentials` | API key (mode 600) |
114
- | `~/.fuzzi/config` | CLI defaults (`default_env`, `default_format`) |
115
- | `~/.fuzzi/history` | Shell command history |
116
- | `.fuzzirc` or `fuzzi.toml` | Project defaults in repo root |
117
-
118
- **Example `.fuzzirc`:**
119
-
120
- ```json
121
- {
122
- "scan": {
123
- "url": "https://staging.example.com",
124
- "environment": "staging",
125
- "fail_on": "high"
126
- },
127
- "output": { "format": "markdown" }
128
- }
129
- ```
110
+ | `~/.fuzzi/config` | CLI defaults |
111
+ | `.fuzzirc` / `fuzzi.toml` | Project defaults |
130
112
 
131
- Flags on the command line override file values.
113
+ **Default API:** `https://fuzzi-ten.vercel.app/api`
132
114
 
133
115
  ```bash
134
116
  fuzzi config set default_env staging
135
- fuzzi config set default_format markdown
136
- export FUZZI_API_URL=https://app.fuzzi.dev/api # override API
137
- export FUZZI_DEBUG=1 # debug logging
117
+ export FUZZI_API_URL=https://fuzzi-ten.vercel.app/api # override if needed
118
+ export FUZZI_DEBUG=1
138
119
  ```
139
120
 
140
121
  ---
141
122
 
142
- ## CI example (GitHub Actions)
123
+ ## CI example
143
124
 
144
125
  ```yaml
145
126
  - name: Fuzzi security gate
146
127
  run: |
147
128
  npm install -g fuzzi-cli
148
129
  fuzzi auth login --api-key "${{ secrets.FUZZI_API_KEY }}"
149
- fuzzi scan https://staging.example.com --fail-on critical --format markdown
130
+ fuzzi scan https://staging.example.com --fail-on critical
150
131
  ```
151
132
 
152
133
  ---
153
134
 
154
- ## For web / frontend developers
135
+ ## For web developers
155
136
 
156
- The CLI browser login flow requires pages and API routes on **app.fuzzi.dev**.
137
+ Browser login and API contracts for [fuzzi-ten.vercel.app](https://fuzzi-ten.vercel.app):
157
138
 
158
- See **[docs/frontend-integration.md](./docs/frontend-integration.md)** for:
159
-
160
- - `/cli-auth` page spec
161
- - `POST /api/cli/handoff` contract
162
- - API keys settings UI
163
- - Full feature parity checklist
139
+ See **[docs/frontend-integration.md](./docs/frontend-integration.md)**
164
140
 
165
141
  ---
166
142
 
167
143
  ## Development
168
144
 
169
145
  ```bash
170
- git clone <repo>
171
- cd fuzzi-cli
172
- npm install
173
- npm test
174
- npm run build
175
- npm link # optional: global `fuzzi` command
146
+ npm install && npm test && npm run build
147
+ npm link # optional global `fuzzi` command
176
148
  ```
177
149
 
178
- ---
179
-
180
- ## Publish to npm
150
+ ## Publish
181
151
 
182
152
  ```bash
183
- npm login
184
153
  npm publish --access public
185
154
  ```
186
-
187
- Or tag `v0.1.0` and let GitHub Actions publish (requires `NPM_TOKEN` secret).
188
-
189
- ---
190
-
191
- ## Brand
192
-
193
- - Accent: `#4FC3A1` (teal)
194
- - Risk: LOW green · MEDIUM amber · HIGH red · CRITICAL purple
@@ -1,4 +1,14 @@
1
1
  [
2
+ {
3
+ "version": "0.1.3",
4
+ "date": "2026-06-19",
5
+ "highlights": [
6
+ "Production app URL: fuzzi-ten.vercel.app",
7
+ "API default: fuzzi-ten.vercel.app/api",
8
+ "Claude Code-style two-column home screen",
9
+ "Browser sign-in on startup"
10
+ ]
11
+ },
2
12
  {
3
13
  "version": "0.1.2",
4
14
  "date": "2026-06-19",
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var __export = (target, all) => {
9
9
  };
10
10
 
11
11
  // src/types/brand.ts
12
- var BRAND, RISK_COLORS, VERSION, APP_ORIGIN, DEFAULT_API_URL;
12
+ var BRAND, RISK_COLORS, VERSION, APP_ORIGIN, DEFAULT_API_URL, SETTINGS_API_KEYS_URL, CLI_AUTH_URL, APP_HOST;
13
13
  var init_brand = __esm({
14
14
  "src/types/brand.ts"() {
15
15
  "use strict";
@@ -27,9 +27,12 @@ var init_brand = __esm({
27
27
  HIGH: "#EF4444",
28
28
  CRITICAL: "#A855F7"
29
29
  };
30
- VERSION = "0.1.2";
31
- APP_ORIGIN = "https://app.fuzzi.dev";
30
+ VERSION = "0.1.3";
31
+ APP_ORIGIN = "https://fuzzi-ten.vercel.app";
32
32
  DEFAULT_API_URL = `${APP_ORIGIN}/api`;
33
+ SETTINGS_API_KEYS_URL = `${APP_ORIGIN}/settings/api-keys`;
34
+ CLI_AUTH_URL = `${APP_ORIGIN}/cli-auth`;
35
+ APP_HOST = "fuzzi-ten.vercel.app";
33
36
  }
34
37
  });
35
38
 
@@ -220,9 +223,9 @@ function mapErrorMessage(status, body) {
220
223
  return "API key has been revoked. Please log in again.";
221
224
  }
222
225
  if (code === "key_expired" || msg.toLowerCase().includes("expired")) {
223
- return "API key has expired. Generate a new one at https://app.fuzzi.dev/settings/api-keys";
226
+ return `API key has expired. Generate a new one at ${SETTINGS_API_KEYS_URL}`;
224
227
  }
225
- return "Invalid API key. Generate a new one at https://app.fuzzi.dev/settings/api-keys";
228
+ return `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`;
226
229
  }
227
230
  if (status === 403 && (code === "ssrf" || msg.toLowerCase().includes("private ip"))) {
228
231
  return "This URL is not allowed (private IP address detected). Please scan a public-facing URL.";
@@ -253,6 +256,7 @@ var init_api_client = __esm({
253
256
  init_config();
254
257
  init_credentials();
255
258
  init_logger();
259
+ init_brand();
256
260
  ApiError = class extends Error {
257
261
  constructor(message, status, code, body, exitCode) {
258
262
  super(message);
@@ -302,7 +306,7 @@ var init_api_client = __esm({
302
306
  });
303
307
  } catch {
304
308
  throw new ApiError(
305
- "Could not connect to app.fuzzi.dev. Check your internet connection or try again later.",
309
+ `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,
306
310
  0,
307
311
  "network_error",
308
312
  void 0,
@@ -358,7 +362,7 @@ var init_api_client = __esm({
358
362
  res = await fetch(url, { headers: this.headers() });
359
363
  } catch {
360
364
  throw new ApiError(
361
- "Could not connect to app.fuzzi.dev. Check your internet connection or try again later.",
365
+ `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,
362
366
  0,
363
367
  "network_error",
364
368
  void 0,
@@ -802,6 +806,7 @@ async function runBrowserLogin() {
802
806
  }
803
807
 
804
808
  // src/commands/auth.ts
809
+ init_brand();
805
810
  async function runAuthLogin(opts = {}) {
806
811
  if (opts.browser || opts.interactive !== false && !opts.apiKey && !opts.apiKeyOnly) {
807
812
  try {
@@ -841,7 +846,7 @@ async function runApiKeyLogin(opts = {}) {
841
846
  apiKey = apiKey.trim();
842
847
  if (!isValidApiKeyFormat(apiKey)) {
843
848
  throw new ApiError(
844
- "Invalid API key format. Generate a new one at https://app.fuzzi.dev/settings/api-keys",
849
+ `Invalid API key format. Generate a new one at ${SETTINGS_API_KEYS_URL}`,
845
850
  401,
846
851
  "invalid_key_format",
847
852
  void 0,
@@ -852,7 +857,7 @@ async function runApiKeyLogin(opts = {}) {
852
857
  const valid = await client.validateToken();
853
858
  if (!valid) {
854
859
  throw new ApiError(
855
- "Invalid API key. Generate a new one at https://app.fuzzi.dev/settings/api-keys",
860
+ `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`,
856
861
  401,
857
862
  "invalid_token",
858
863
  void 0,
@@ -993,13 +998,14 @@ init_theme();
993
998
 
994
999
  // src/lib/errors.ts
995
1000
  init_api_client();
1001
+ init_brand();
996
1002
  function formatApiError(err) {
997
1003
  if (err instanceof ApiError) {
998
1004
  return err.message;
999
1005
  }
1000
1006
  if (err instanceof Error) {
1001
1007
  if (err.message.includes("fetch failed") || err.message.includes("ECONNREFUSED")) {
1002
- return "Could not connect to app.fuzzi.dev. Check your internet connection or try again later.";
1008
+ return `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`;
1003
1009
  }
1004
1010
  return `An error occurred: ${err.message}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;
1005
1011
  }
@@ -1668,6 +1674,9 @@ function emptyState(title, hint, action) {
1668
1674
  return lines.join("\n");
1669
1675
  }
1670
1676
 
1677
+ // src/commands/keys.ts
1678
+ init_brand();
1679
+
1671
1680
  // src/terminal/interactive.ts
1672
1681
  init_theme();
1673
1682
  import { select, search } from "@inquirer/prompts";
@@ -1702,7 +1711,7 @@ async function runKeysListCommand(client) {
1702
1711
  const data = await client.get("/keys");
1703
1712
  const keys = data.results || [];
1704
1713
  if (!keys.length) {
1705
- return emptyState("No API keys", "Create one at app.fuzzi.dev/settings/api-keys", "[n] new key in this view");
1714
+ return emptyState("No API keys", `Create one at ${SETTINGS_API_KEYS_URL}`, "[n] new key in this view");
1706
1715
  }
1707
1716
  const rows = keys.map((k) => [
1708
1717
  k.name,
@@ -2187,7 +2196,7 @@ function renderAuthGate() {
2187
2196
  muted("and authorize the CLI."),
2188
2197
  "",
2189
2198
  muted("A local server receives the callback"),
2190
- muted("from app.fuzzi.dev automatically.")
2199
+ muted(`from ${APP_HOST} automatically.`)
2191
2200
  ].join("\n");
2192
2201
  const rightBottom = [
2193
2202
  accentBold("Other options"),
@@ -2195,7 +2204,7 @@ function renderAuthGate() {
2195
2204
  muted("Paste an API key with /auth-key"),
2196
2205
  muted("from Settings \u2192 API Keys on the web."),
2197
2206
  "",
2198
- italic(muted("docs: app.fuzzi.dev/settings/api-keys"))
2207
+ italic(muted(SETTINGS_API_KEYS_URL))
2199
2208
  ].join("\n");
2200
2209
  return splitHomePanel({
2201
2210
  title: `Fuzzi CLI v${VERSION}`,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/brand.ts","../src/lib/credentials.ts","../src/lib/config.ts","../src/lib/logger.ts","../src/lib/api-client.ts","../src/terminal/capabilities.ts","../src/terminal/theme.ts","../src/terminal/table.ts","../src/terminal/strings.ts","../src/terminal/width.ts","../src/terminal/layout.ts","../src/lib/theme.ts","../src/commands/report.ts","../src/commands/whatif.ts","../src/commands/compare.ts","../src/cli/program.ts","../src/commands/auth.ts","../src/lib/browser-auth.ts","../src/lib/output.ts","../src/commands/scan.ts","../src/lib/errors.ts","../src/lib/risk.ts","../src/lib/project-config.ts","../src/terminal/progress.ts","../src/lib/retry.ts","../src/commands/scans.ts","../src/commands/status.ts","../src/commands/config.ts","../src/cli/exit.ts","../src/shell/prompt-loop.ts","../src/shell/home-screen.ts","../src/shell/ascii-mark.ts","../src/lib/assets.ts","../src/shell/slash-commands.ts","../src/commands/keys.ts","../src/terminal/empty-state.ts","../src/terminal/interactive.ts","../src/shell/help-screen.ts","../src/shell/registry.ts","../src/shell/command-palette.ts","../src/shell/session.ts","../src/terminal/banner.ts","../src/shell/completer.ts","../src/shell/auth-gate.ts","../src/cli/profile.ts","../src/cli/bootstrap.ts","../src/index.ts"],"sourcesContent":["export const BRAND = {\n accent: \"#4FC3A1\",\n accentDim: \"#3A9A7E\",\n text: \"#FAFAFA\",\n textSecondary: \"#8C8C8C\",\n bg: \"#0A0A0A\",\n border: \"#2A2A2A\",\n} as const;\n\nexport const RISK_COLORS: Record<string, string> = {\n LOW: \"#22C55E\",\n MEDIUM: \"#F59E0B\",\n HIGH: \"#EF4444\",\n CRITICAL: \"#A855F7\",\n};\n\nexport const VERSION = \"0.1.2\";\n\nexport const APP_ORIGIN = \"https://app.fuzzi.dev\";\nexport const DEFAULT_API_URL = `${APP_ORIGIN}/api`;\n","import { mkdir, readFile, writeFile, chmod, unlink } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Credentials } from \"../types/api.js\";\n\nconst FUZZI_DIR = join(homedir(), \".fuzzi\");\nconst CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials\");\nconst LEGACY_CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials.json\");\n\nexport function fuzziDir(): string {\n return FUZZI_DIR;\n}\n\nexport function credentialsPath(): string {\n return CREDENTIALS_PATH;\n}\n\nasync function ensureDir(): Promise<void> {\n await mkdir(FUZZI_DIR, { recursive: true, mode: 0o700 });\n}\n\nfunction normalizeCredentials(raw: Record<string, unknown>): Credentials {\n if (raw.api_key && typeof raw.api_key === \"string\") {\n return {\n api_key: raw.api_key,\n auth_method: \"api_key\",\n key_prefix: (raw.key_prefix as string) || raw.api_key.slice(0, 12) + \"...\",\n key_expires_at: raw.key_expires_at as string | undefined,\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n if (raw.access_token && typeof raw.access_token === \"string\") {\n return {\n api_key: raw.access_token,\n auth_method: \"api_key\",\n key_prefix: raw.access_token.slice(0, 12) + \"...\",\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n throw new Error(\"Invalid credentials file\");\n}\n\nexport async function loadCredentials(): Promise<Credentials | null> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || Object.keys(parsed).length === 0) return null;\n return normalizeCredentials(parsed);\n } catch {\n /* try next path */\n }\n }\n return null;\n}\n\nexport async function saveCredentials(creds: Credentials): Promise<void> {\n await ensureDir();\n await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), { mode: 0o600 });\n try {\n await chmod(CREDENTIALS_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function clearCredentials(): Promise<void> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n await unlink(path);\n } catch {\n /* ok */\n }\n }\n}\n\nexport function maskApiKey(key: string): string {\n if (key.length <= 16) return key.slice(0, 8) + \"...\";\n return key.slice(0, 12) + \"...\";\n}\n\nexport function isValidApiKeyFormat(key: string): boolean {\n return /^fz_live_[A-Za-z0-9_-]{20,}$/.test(key.trim());\n}\n","import { mkdir, readFile, writeFile, chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CliConfig } from \"../types/api.js\";\nimport { DEFAULT_API_URL } from \"../types/brand.js\";\nimport { fuzziDir } from \"./credentials.js\";\n\nconst CONFIG_PATH = join(homedir(), \".fuzzi\", \"config\");\nconst LEGACY_CONFIG_PATH = join(homedir(), \".fuzzi\", \"config.json\");\n\nexport { fuzziDir };\n\nasync function ensureDir(): Promise<void> {\n await mkdir(fuzziDir(), { recursive: true, mode: 0o700 });\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n for (const path of [CONFIG_PATH, LEGACY_CONFIG_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<CliConfig>;\n return {\n api_url: process.env.FUZZI_API_URL || parsed.api_url || DEFAULT_API_URL,\n default_env: parsed.default_env,\n default_format: parsed.default_format,\n ...parsed,\n };\n } catch {\n /* try next */\n }\n }\n return { api_url: process.env.FUZZI_API_URL || DEFAULT_API_URL };\n}\n\nexport async function saveConfig(config: CliConfig): Promise<void> {\n await ensureDir();\n await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });\n try {\n await chmod(CONFIG_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function setConfigValue(key: string, value: string): Promise<void> {\n const config = await loadConfig();\n if (key === \"api_url\") config.api_url = value;\n else if (key === \"default_env\") config.default_env = value as CliConfig[\"default_env\"];\n else if (key === \"default_format\") config.default_format = value as CliConfig[\"default_format\"];\n else (config as unknown as Record<string, string>)[key] = value;\n await saveConfig(config);\n}\n\nexport async function getConfigValue(key: string): Promise<string | undefined> {\n const config = await loadConfig();\n return (config as unknown as Record<string, string | undefined>)[key];\n}\n\nexport async function listConfigEntries(): Promise<Record<string, string>> {\n const config = await loadConfig();\n const entries: Record<string, string> = {};\n for (const [k, v] of Object.entries(config)) {\n if (v !== undefined) entries[k] = String(v);\n }\n return entries;\n}\n","type Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<Level, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\nfunction currentLevel(): Level {\n if (process.env.FUZZI_DEBUG === \"1\" || process.env.FUZZI_DEBUG === \"true\") return \"debug\";\n if (process.env.FUZZI_LOG_LEVEL) return process.env.FUZZI_LOG_LEVEL as Level;\n return \"warn\";\n}\n\nfunction shouldLog(level: Level): boolean {\n return LEVELS[level] >= LEVELS[currentLevel()];\n}\n\nfunction stamp(): string {\n return new Date().toISOString();\n}\n\nexport const log = {\n debug(...args: unknown[]) {\n if (shouldLog(\"debug\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n info(...args: unknown[]) {\n if (shouldLog(\"info\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n warn(...args: unknown[]) {\n if (shouldLog(\"warn\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n error(...args: unknown[]) {\n if (shouldLog(\"error\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n};\n\nexport function isDebugMode(): boolean {\n return currentLevel() === \"debug\";\n}\n","import type { Credentials, CliConfig } from \"../types/api.js\";\nimport { loadConfig } from \"./config.js\";\nimport { loadCredentials } from \"./credentials.js\";\nimport { log } from \"./logger.js\";\n\nexport class ApiError extends Error {\n exitCode?: number;\n\n constructor(\n message: string,\n public status: number,\n public code?: string,\n public body?: unknown,\n exitCode?: number,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.exitCode = exitCode;\n }\n}\n\nfunction mapErrorMessage(status: number, body: { error?: string; code?: string; message?: string }): string {\n const code = body.code?.toLowerCase();\n const msg = body.error || body.message || \"\";\n\n if (status === 401) {\n if (code === \"key_revoked\" || msg.toLowerCase().includes(\"revoked\")) {\n return \"API key has been revoked. Please log in again.\";\n }\n if (code === \"key_expired\" || msg.toLowerCase().includes(\"expired\")) {\n return \"API key has expired. Generate a new one at https://app.fuzzi.dev/settings/api-keys\";\n }\n return \"Invalid API key. Generate a new one at https://app.fuzzi.dev/settings/api-keys\";\n }\n if (status === 403 && (code === \"ssrf\" || msg.toLowerCase().includes(\"private ip\"))) {\n return \"This URL is not allowed (private IP address detected). Please scan a public-facing URL.\";\n }\n if (status === 400 && msg.toLowerCase().includes(\"url\")) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n if (status === 429) {\n return msg || \"Rate limit exceeded.\";\n }\n if (msg.toLowerCase().startsWith(\"scan failed\")) {\n return msg;\n }\n if (msg) return msg;\n return `Request failed with status ${status}`;\n}\n\nexport class FuzziApiClient {\n constructor(\n private baseUrl: string,\n private token?: string,\n ) {}\n\n static async create(): Promise<FuzziApiClient> {\n const config = await loadConfig();\n const creds = await loadCredentials();\n return new FuzziApiClient(config.api_url.replace(/\\/$/, \"\"), creds?.api_key);\n }\n\n get base(): string {\n return this.baseUrl;\n }\n\n setToken(token: string): void {\n this.token = token;\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\", Accept: \"application/json\" };\n if (this.token) h.Authorization = `Bearer ${this.token}`;\n return h;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n log.debug(`${method} ${url}`);\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(\n \"Could not connect to app.fuzzi.dev. Check your internet connection or try again later.\",\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n\n let data: unknown;\n const text = await res.text();\n try {\n data = text ? JSON.parse(text) : {};\n } catch {\n data = { error: text };\n }\n\n if (!res.ok) {\n const errBody = data as { error?: string; code?: string; message?: string };\n let message = mapErrorMessage(res.status, errBody);\n\n if (res.status === 429) {\n const retryAfter = res.headers.get(\"Retry-After\");\n const seconds = retryAfter ? parseInt(retryAfter, 10) : 60;\n message = `Rate limit exceeded. Retry after ${seconds} seconds.`;\n }\n\n if (res.status >= 500) {\n message = `Scan failed: ${errBody.error || errBody.message || res.statusText}`;\n }\n\n throw new ApiError(message, res.status, errBody.code, data, 2);\n }\n return data as T;\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async validateToken(): Promise<boolean> {\n try {\n await this.get(\"/me\");\n return true;\n } catch {\n return false;\n }\n }\n\n async download(path: string): Promise<{ data: Buffer; contentType: string }> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n let res: Response;\n try {\n res = await fetch(url, { headers: this.headers() });\n } catch {\n throw new ApiError(\n \"Could not connect to app.fuzzi.dev. Check your internet connection or try again later.\",\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n if (!res.ok) {\n const text = await res.text();\n let errBody: { error?: string; code?: string } = {};\n try {\n errBody = JSON.parse(text);\n } catch {\n errBody = { error: text };\n }\n throw new ApiError(mapErrorMessage(res.status, errBody), res.status, errBody.code, errBody, 2);\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return { data: buf, contentType: res.headers.get(\"content-type\") || \"application/octet-stream\" };\n }\n}\n\nexport async function getAuthenticatedClient(): Promise<FuzziApiClient> {\n const client = await FuzziApiClient.create();\n if (!client[\"token\"]) {\n throw new ApiError(\"Not authenticated. Run: fuzzi auth login\", 401, \"not_authenticated\", undefined, 2);\n }\n return client;\n}\n\nexport async function getConfig(): Promise<CliConfig> {\n return loadConfig();\n}\n\nexport async function getCredentials(): Promise<Credentials | null> {\n return loadCredentials();\n}\n","import { stdout } from \"node:process\";\n\nexport interface TerminalCapabilities {\n width: number;\n trueColor: boolean;\n interactive: boolean;\n}\n\nlet cached: TerminalCapabilities | null = null;\n\nexport function getCapabilities(): TerminalCapabilities {\n if (cached) return cached;\n const cols = stdout.columns ?? 80;\n const term = process.env.TERM ?? \"\";\n const colorterm = process.env.COLORTERM ?? \"\";\n const trueColor =\n colorterm.includes(\"truecolor\") ||\n colorterm.includes(\"24bit\") ||\n term.includes(\"truecolor\") ||\n (!!process.env.FORCE_COLOR && process.env.FORCE_COLOR !== \"0\");\n\n cached = {\n width: Math.max(60, Math.min(cols, 120)),\n trueColor,\n interactive: stdout.isTTY === true,\n };\n return cached;\n}\n\nexport function resetCapabilities(): void {\n cached = null;\n}\n","import chalk, { type ChalkInstance } from \"chalk\";\nimport { BRAND, RISK_COLORS } from \"../types/brand.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nfunction color(hex: string, fallback: ChalkInstance): ChalkInstance {\n return getCapabilities().trueColor ? chalk.hex(hex) : fallback;\n}\n\nexport const accent = color(BRAND.accent, chalk.cyan);\nexport const accentBold = accent.bold;\nexport const muted = color(BRAND.textSecondary, chalk.gray);\nexport const bold = chalk.bold;\nexport const dim = chalk.dim;\n\nexport function riskColor(level: string | null | undefined): (s: string) => string {\n if (!level) return muted;\n const key = level.toUpperCase();\n const hex = RISK_COLORS[key] || BRAND.textSecondary;\n const fallbacks: Record<string, ChalkInstance> = {\n LOW: chalk.green,\n MEDIUM: chalk.yellow,\n HIGH: chalk.red,\n CRITICAL: chalk.magenta,\n };\n return color(hex, fallbacks[key] ?? chalk.gray).bold;\n}\n\nexport function scoreBold(n: number | null | undefined): string {\n if (n == null) return muted(\"—\");\n return chalk.bold(String(n));\n}\n\nexport function header(text: string): string {\n return accentBold(text);\n}\n\nexport function error(text: string): string {\n return color(\"#EF4444\", chalk.red)(text);\n}\n\nexport function success(text: string): string {\n return color(\"#22C55E\", chalk.green)(text);\n}\n\nexport function warn(text: string): string {\n return color(\"#F59E0B\", chalk.yellow)(text);\n}\n\nexport function info(text: string): string {\n return color(BRAND.accent, chalk.cyan)(text);\n}\n\nexport const italic = chalk.italic;\n\nexport function riskBadge(level: string): string {\n const tag = level.toUpperCase().padEnd(8);\n return riskColor(level)(tag);\n}\n","import Table from \"cli-table3\";\nimport { muted } from \"./theme.js\";\n\nconst BOX_CHARS: Record<string, string> = {\n mid: \"─\",\n \"left-mid\": \"├\",\n \"mid-mid\": \"┼\",\n \"right-mid\": \"┤\",\n};\n\nexport function createTable(headers: string[], rows: string[][]): string {\n const table = new Table({\n head: headers.map((h) => muted(h)),\n style: { head: [], border: [] },\n chars: BOX_CHARS,\n });\n for (const row of rows) table.push(row);\n return table.toString();\n}\n","export function truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max - 1) + \"…\";\n}\n\nexport function padEndVisible(s: string, width: number): string {\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, width - plain.length);\n return s + \" \".repeat(pad);\n}\n\nexport function formatTimestamp(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;\n}\n\nexport function hostnameFromUrl(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n","import { stdout } from \"node:process\";\nimport { getCapabilities, resetCapabilities } from \"./capabilities.js\";\n\nexport function terminalWidth(): number {\n resetCapabilities();\n return Math.max(64, (stdout.columns ?? 80) - 2);\n}\n\nexport function contentWidth(): number {\n return terminalWidth() - 4;\n}\n","import boxen from \"boxen\";\nimport { BRAND } from \"../types/brand.js\";\nimport { accentBold, dim, muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\nimport { padEndVisible } from \"./strings.js\";\nimport { terminalWidth, contentWidth } from \"./width.js\";\n\nexport interface PanelOptions {\n title?: string;\n padding?: number;\n marginBottom?: number;\n fullWidth?: boolean;\n borderStyle?: \"round\" | \"single\" | \"classic\" | \"bold\";\n}\n\nexport function panel(content: string, opts: PanelOptions = {}): string {\n const width = opts.fullWidth !== false ? terminalWidth() : undefined;\n return boxen(content, {\n title: opts.title ? accentBold(opts.title) : undefined,\n padding: opts.padding ?? 1,\n margin: { top: 0, bottom: opts.marginBottom ?? 1, left: 0, right: 0 },\n borderStyle: opts.borderStyle ?? \"classic\",\n borderColor: getCapabilities().trueColor ? BRAND.accent : undefined,\n titleAlignment: \"left\",\n width,\n });\n}\n\nexport function centerInColumn(text: string, colWidth: number): string {\n return text\n .split(\"\\n\")\n .map((line) => {\n const plain = line.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, Math.floor((colWidth - plain.length) / 2));\n return \" \".repeat(pad) + line;\n })\n .join(\"\\n\");\n}\n\nexport interface SplitHomeOptions {\n title: string;\n left: string;\n rightTop: string;\n rightBottom: string;\n leftRatio?: number;\n}\n\n/** Claude Code-style two-column home with horizontal split on the right. */\nexport function splitHomePanel(opts: SplitHomeOptions): string {\n const total = contentWidth();\n const leftW = Math.max(28, Math.floor(total * (opts.leftRatio ?? 0.34)));\n const rightW = total - leftW - 3;\n\n const leftLines = opts.left.split(\"\\n\");\n const rightTop = opts.rightTop.split(\"\\n\");\n const rightDiv = dim(\"─\".repeat(Math.max(10, rightW)));\n const rightBottom = opts.rightBottom.split(\"\\n\");\n const rightLines = [...rightTop, \"\", rightDiv, \"\", ...rightBottom];\n\n const rows = Math.max(leftLines.length, rightLines.length);\n const sep = dim(\"│\");\n const body: string[] = [\"\"];\n\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", leftW);\n const r = rightLines[i] ?? \"\";\n body.push(`${l} ${sep} ${r}`);\n }\n body.push(\"\");\n\n return panel(body.join(\"\\n\"), { title: opts.title, marginBottom: 0, borderStyle: \"classic\" });\n}\n\nexport function columns(left: string, right: string, leftWidth?: number): string {\n const total = contentWidth();\n const split = leftWidth ?? Math.floor(total * 0.48);\n const leftLines = left.split(\"\\n\");\n const rightLines = right.split(\"\\n\");\n const rows = Math.max(leftLines.length, rightLines.length);\n const out: string[] = [];\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", split);\n const r = rightLines[i] ?? \"\";\n out.push(`${l} ${r}`);\n }\n return out.join(\"\\n\");\n}\n\nexport function divider(char = \"─\", width?: number): string {\n const w = width ?? contentWidth();\n return dim(char.repeat(Math.max(20, w)));\n}\n\nexport function statusBar(parts: string[]): string {\n return dim(parts.filter(Boolean).join(\" · \"));\n}\n\nexport function keyValue(rows: Array<[string, string]>, indent = 2): string {\n const pad = \" \".repeat(indent);\n const maxKey = Math.max(...rows.map(([k]) => k.length), 4);\n return rows.map(([k, v]) => `${pad}${muted(k.padEnd(maxKey))} ${v}`).join(\"\\n\");\n}\n\nexport function centerBlock(text: string, width = contentWidth()): string {\n return centerInColumn(text, width);\n}\n","export * from \"../terminal/theme.js\";\n","import { writeFile } from \"node:fs/promises\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\n\nexport async function runReportCommand(\n client: FuzziApiClient,\n scanId: string,\n format: \"pdf\" | \"csv\" | \"json\",\n outputPath?: string,\n): Promise<string> {\n const { data, contentType } = await client.download(`/scan/${scanId}/report?format=${format}`);\n\n const ext = format === \"pdf\" ? \"pdf\" : format === \"csv\" ? \"csv\" : \"json\";\n const path = outputPath || `fuzzi-report-${scanId.slice(0, 8)}.${ext}`;\n\n await writeFile(path, data);\n return `Report saved to ${path} (${contentType})`;\n}\n","import { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { riskColor, scoreBold } from \"../lib/theme.js\";\n\nexport async function runWhatIfCommand(\n scanId: string,\n overrides: Record<string, number>,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<{\n original: { risk_level: string; overall_score: number };\n simulated: { risk_level: string; overall_score: number };\n summary: string;\n overall_score_delta: number;\n }>(\"/whatif\", { scan_id: scanId, overrides });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n return [\n `Original: ${riskColor(data.original.risk_level)(data.original.risk_level)} (${scoreBold(data.original.overall_score)})`,\n `Simulated: ${riskColor(data.simulated.risk_level)(data.simulated.risk_level)} (${scoreBold(data.simulated.overall_score)})`,\n `Delta: ${data.overall_score_delta > 0 ? \"+\" : \"\"}${data.overall_score_delta}`,\n data.summary,\n ].join(\"\\n\");\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { riskColor, scoreBold } from \"../terminal/theme.js\";\nimport { panel } from \"../terminal/layout.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { CompareResponse } from \"../types/api.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\n\nexport async function runCompareCommand(\n scanA: string,\n scanB: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<CompareResponse>(\"/compare\", {\n scan_a_id: scanA,\n scan_b_id: scanB,\n });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n\n const summary = [\n `Scan A ${data.scan_a.target_url}`,\n ` ${riskColor(data.scan_a.risk_level || \"\")(data.scan_a.risk_level || \"—\")} ${scoreBold(data.scan_a.overall_score)}`,\n `Scan B ${data.scan_b.target_url}`,\n ` ${riskColor(data.scan_b.risk_level || \"\")(data.scan_b.risk_level || \"—\")} ${scoreBold(data.scan_b.overall_score)}`,\n `Delta ${data.score_delta > 0 ? \"+\" : \"\"}${data.score_delta}`,\n data.summary,\n ].join(\"\\n\");\n\n let body = panel(summary, { title: \"Compare\" });\n\n if (data.factor_changes?.length) {\n const rows = data.factor_changes.map((f) => [f.name.replace(/_/g, \" \"), String(f.delta)]);\n body += \"\\n\\n\" + createTable([\"Factor\", \"Delta\"], rows);\n }\n\n return body;\n}\n","import { Command } from \"commander\";\nimport { cwd } from \"node:process\";\nimport { VERSION } from \"../types/brand.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runAuthLogin, runAuthLogout } from \"../commands/auth.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand, runScanGetCommand } from \"../commands/scans.js\";\nimport { runStatusCommand } from \"../commands/status.js\";\nimport { runConfigGet, runConfigSet, runConfigList } from \"../commands/config.js\";\nimport { handleCommandError, exitWith } from \"./exit.js\";\nimport type { RiskLevel } from \"../lib/risk.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\n\nexport function buildProgram(): Command {\n const program = new Command(\"fuzzi\")\n .name(\"fuzzi\")\n .description(\"Fuzzi security scanner CLI — interactive shell and scriptable commands\")\n .version(VERSION);\n\n const auth = program.command(\"auth\").description(\"Authentication\");\n\n auth\n .command(\"login\")\n .description(\"Sign in via browser (default) or API key\")\n .option(\"--browser\", \"Sign in via browser (default when interactive)\")\n .option(\"--api-key <key>\", \"Paste an API key (fz_live_...)\")\n .action(async (opts) => {\n try {\n const useApiKey = !!opts.apiKey;\n console.log(\n await runAuthLogin({\n apiKey: opts.apiKey,\n interactive: !opts.apiKey,\n browser: !useApiKey,\n apiKeyOnly: useApiKey,\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n auth.command(\"logout\").description(\"Clear stored credentials\").action(async () => {\n console.log(await runAuthLogout());\n });\n\n auth.command(\"status\").description(\"Show auth status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"scan [url]\")\n .description(\"Scan a URL (waits for completion by default)\")\n .option(\"-t, --title <title>\", \"Scan title\")\n .option(\"-e, --env <env>\", \"production|staging|development\")\n .option(\"-w, --wait\", \"Poll until scan completes (default)\")\n .option(\"--no-wait\", \"Return immediately with scan ID\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .option(\"--fail-on <level>\", \"Exit 1 if risk >= level (low|medium|high|critical)\")\n .option(\"--fail-threshold <n>\", \"Exit 1 if risk_score >= threshold (0.0-1.0)\", parseFloat)\n .action(async (urlArg, opts) => {\n try {\n const project = await loadProjectConfig(cwd());\n const url = urlArg || project?.scan?.url;\n if (!url) {\n console.error(\"Usage: fuzzi scan <url>\");\n exitWith(2);\n }\n const client = await getAuthenticatedClient();\n const result = await runScanCommand(client, {\n url,\n wait: opts.wait,\n noWait: opts.noWait,\n format: opts.format as OutputFormat,\n environment: opts.env,\n title: opts.title,\n failOn: opts.failOn as RiskLevel | undefined,\n failThreshold: opts.failThreshold,\n });\n console.log(result.output);\n exitWith(result.exitCode);\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const scans = program.command(\"scans\").description(\"Browse scans\");\n\n scans\n .command(\"list\")\n .description(\"List recent scans\")\n .option(\"--status <status>\", \"pending|running|completed|failed\")\n .option(\"--risk-level <level>\", \"low|medium|high|critical\")\n .option(\"--limit <n>\", \"Max results\", \"20\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(\n await runScansListCommand(client, opts.format as OutputFormat, {\n status: opts.status,\n riskLevel: opts.riskLevel,\n limit: parseInt(opts.limit, 10),\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n scans\n .command(\"get <scan-id>\")\n .description(\"Get scan details\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runScanGetCommand(client, scanId, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"report <scan-id>\")\n .description(\"Download a scan report\")\n .requiredOption(\"--format <format>\", \"pdf|csv|json\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .action(async (scanId, opts) => {\n try {\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n console.log(await runReportCommand(client, scanId, opts.format, opts.output));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"whatif <scan-id>\")\n .description(\"Simulate factor overrides\")\n .option(\"--set <pair>\", \"dimension=value (repeatable)\", (v, prev: string[]) => [...prev, v], [])\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n const overrides: Record<string, number> = {};\n for (const pair of opts.set as string[]) {\n const [k, val] = pair.split(\"=\");\n if (k && val) overrides[k] = parseFloat(val);\n }\n console.log(await runWhatIfCommand(scanId, overrides, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"compare <scan-a> <scan-b>\")\n .description(\"Compare two scans\")\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanA, scanB, opts) => {\n try {\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n console.log(await runCompareCommand(scanA, scanB, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const config = program.command(\"config\").description(\"CLI configuration (~/.fuzzi/config)\");\n\n config.command(\"list\").action(async () => console.log(await runConfigList()));\n config.command(\"get [key]\").action(async (key) => console.log(await runConfigGet(key)));\n config\n .command(\"set <key> <value>\")\n .action(async (key, value) => console.log(await runConfigSet(key, value)));\n\n program.command(\"status\").description(\"Show account status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n return program;\n}\n","import { password, input, confirm } from \"@inquirer/prompts\";\nimport { saveCredentials, clearCredentials } from \"../lib/credentials.js\";\nimport { ApiError, FuzziApiClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { isValidApiKeyFormat, maskApiKey } from \"../lib/credentials.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted } from \"../terminal/theme.js\";\nimport { runBrowserLogin } from \"../lib/browser-auth.js\";\n\nexport interface AuthLoginOptions {\n apiKey?: string;\n interactive?: boolean;\n browser?: boolean;\n apiKeyOnly?: boolean;\n}\n\nexport async function runAuthLogin(opts: AuthLoginOptions = {}): Promise<string> {\n if (opts.browser || (opts.interactive !== false && !opts.apiKey && !opts.apiKeyOnly)) {\n try {\n const result = await runBrowserLogin();\n return success(result.message);\n } catch (e) {\n if (opts.browser) throw e;\n if (opts.apiKeyOnly) throw e;\n // fall through to API key on optional browser failure when explicitly api-key path\n }\n }\n\n return runApiKeyLogin(opts);\n}\n\nexport async function runApiKeyLogin(opts: AuthLoginOptions = {}): Promise<string> {\n const config = await loadConfig();\n const client = new FuzziApiClient(config.api_url);\n\n let apiKey = opts.apiKey?.trim();\n\n if (!apiKey) {\n if (opts.interactive === false) {\n throw new ApiError(\n \"No API key provided. Run fuzzi auth login or sign in via browser.\",\n 401,\n \"missing_key\",\n undefined,\n 2,\n );\n }\n apiKey = await password({\n message: \"Paste your API key (fz_live_...):\",\n mask: \"•\",\n validate: (v) => {\n if (!v.trim()) return \"API key is required\";\n if (!isValidApiKeyFormat(v)) return \"Key must start with fz_live_\";\n return true;\n },\n });\n }\n\n apiKey = apiKey.trim();\n if (!isValidApiKeyFormat(apiKey)) {\n throw new ApiError(\n \"Invalid API key format. Generate a new one at https://app.fuzzi.dev/settings/api-keys\",\n 401,\n \"invalid_key_format\",\n undefined,\n 2,\n );\n }\n\n client.setToken(apiKey);\n const valid = await client.validateToken();\n if (!valid) {\n throw new ApiError(\n \"Invalid API key. Generate a new one at https://app.fuzzi.dev/settings/api-keys\",\n 401,\n \"invalid_token\",\n undefined,\n 2,\n );\n }\n\n const profile = await client.get<UserProfile>(\"/me\");\n await saveCredentials({\n api_key: apiKey,\n auth_method: \"api_key\",\n key_prefix: profile.key_prefix || maskApiKey(apiKey),\n key_expires_at: profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return success(`Authenticated as ${name}`);\n}\n\nexport async function runAuthLogout(): Promise<string> {\n await clearCredentials();\n return muted(\"You are now logged out.\");\n}\n\nexport async function promptNewKeyName(): Promise<string> {\n return input({\n message: \"Key name:\",\n validate: (v) => (v.trim().length > 0 ? true : \"Name is required\"),\n });\n}\n\nexport async function confirmBrowserLogin(): Promise<boolean> {\n return confirm({\n message: \"Open browser to sign in?\",\n default: true,\n });\n}\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { exec } from \"node:child_process\";\nimport { loadConfig } from \"./config.js\";\nimport { saveCredentials, maskApiKey } from \"./credentials.js\";\nimport { FuzziApiClient, ApiError } from \"./api-client.js\";\nimport { APP_ORIGIN } from \"../types/brand.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"./logger.js\";\n\nconst TIMEOUT_MS = 5 * 60 * 1000;\n\nexport interface BrowserLoginResult {\n message: string;\n profile: UserProfile;\n}\n\ninterface HandoffResponse {\n api_key: string;\n prefix?: string;\n expires_at?: string | null;\n}\n\nfunction generateState(): string {\n return randomBytes(24).toString(\"base64url\");\n}\n\nfunction openBrowser(url: string): void {\n const platform = process.platform;\n const cmd =\n platform === \"darwin\" ? `open ${JSON.stringify(url)}`\n : platform === \"win32\" ? `start \"\" ${JSON.stringify(url)}`\n : `xdg-open ${JSON.stringify(url)}`;\n exec(cmd, (err) => {\n if (err) log.warn(\"could not open browser automatically\", err.message);\n });\n}\n\nfunction apiOrigin(apiUrl: string): string {\n return apiUrl.replace(/\\/api\\/?$/, \"\") || APP_ORIGIN;\n}\n\nexport async function runBrowserLogin(): Promise<BrowserLoginResult> {\n const config = await loadConfig();\n const state = generateState();\n\n const handoffToken = await new Promise<string>((resolve, reject) => {\n const server = createServer((req, res) => {\n try {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const url = new URL(req.url ?? \"/\", `http://127.0.0.1:${port}`);\n\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end();\n return;\n }\n\n const token = url.searchParams.get(\"token\");\n const returnedState = url.searchParams.get(\"state\");\n if (!token || returnedState !== state) {\n res.writeHead(400);\n res.end(\"Invalid callback\");\n reject(new ApiError(\"Invalid sign-in callback.\", 400, \"invalid_callback\", undefined, 2));\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(`<!DOCTYPE html><html><body style=\"font-family:system-ui;text-align:center;padding:48px\">\n <h1>Signed in to Fuzzi CLI</h1><p>Return to your terminal.</p>\n <script>setTimeout(()=>window.close(),1200)</script></body></html>`);\n server.close();\n resolve(token);\n } catch (e) {\n server.close();\n reject(e);\n }\n });\n\n const timer = setTimeout(() => {\n server.close();\n reject(new ApiError(\"Sign-in timed out after 5 minutes.\", 408, \"auth_timeout\", undefined, 2));\n }, TIMEOUT_MS);\n\n server.listen(0, \"127.0.0.1\", () => {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const loginUrl = `${apiOrigin(config.api_url)}/cli-auth?state=${encodeURIComponent(state)}&callback_port=${port}`;\n openBrowser(loginUrl);\n log.debug(\"browser auth\", loginUrl);\n });\n\n server.on(\"error\", (e) => {\n clearTimeout(timer);\n reject(e);\n });\n });\n\n const client = new FuzziApiClient(config.api_url);\n const handoff = await client.post<HandoffResponse>(\"/cli/handoff\", {\n handoff_token: handoffToken,\n state,\n });\n\n if (!handoff.api_key) {\n throw new ApiError(\"Sign-in failed: no API key returned.\", 500, \"handoff_failed\", undefined, 2);\n }\n\n client.setToken(handoff.api_key);\n const profile = await client.get<UserProfile>(\"/me\");\n\n await saveCredentials({\n api_key: handoff.api_key,\n auth_method: \"api_key\",\n key_prefix: handoff.prefix || profile.key_prefix || maskApiKey(handoff.api_key),\n key_expires_at: handoff.expires_at || profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return { message: `Signed in as ${name}`, profile };\n}\n","import { riskColor, accent, muted, bold, scoreBold, warn } from \"../terminal/theme.js\";\nimport { createTable } from \"../terminal/table.js\";\nimport { formatTimestamp, hostnameFromUrl, truncate } from \"../terminal/strings.js\";\nimport { panel, divider } from \"../terminal/layout.js\";\nimport type { ScanDetail, ScanSummary } from \"../types/api.js\";\n\nexport type OutputFormat = \"table\" | \"json\" | \"markdown\";\n\nexport function formatScanDate(scan: ScanDetail | ScanSummary): string {\n return formatTimestamp(\"created_at\" in scan ? scan.created_at : undefined);\n}\n\nexport function renderScanResult(scan: ScanDetail, format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(buildScanJson(scan), null, 2);\n if (format === \"markdown\") return renderScanMarkdown(scan);\n return renderScanTable(scan);\n}\n\nfunction buildScanJson(scan: ScanDetail) {\n const fr = scan.fuzzy_result;\n return {\n scan: {\n id: scan.id,\n target_url: scan.target_url,\n status: scan.status,\n risk_level: fr?.risk_level ?? null,\n risk_score: fr?.risk_score ?? null,\n overall_score: fr?.overall_score ?? null,\n },\n factors: scan.factors ?? [],\n recommendations: scan.recommendations ?? [],\n };\n}\n\nfunction levelIndicator(level: string): string {\n if (level === \"LOW\") return muted(\"ok\");\n return warn(\"!\");\n}\n\nexport function renderScanTable(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const rc = riskColor(fr?.risk_level);\n const lines: string[] = [];\n\n lines.push(panel([\n bold(scan.target_url),\n fr ? `${rc(\"Risk\")} ${rc(fr.risk_level)} ${muted(\"Score\")} ${scoreBold(fr.overall_score)}/100` : \"\",\n `${muted(\"Date\")} ${formatScanDate(scan)}`,\n scan.status === \"completed_inconclusive\" ? warn(\"Inconclusive — indicative only\") : \"\",\n ].filter(Boolean).join(\"\\n\"), { title: \"Scan result\" }));\n\n if (scan.factors?.length) {\n const rows = [...scan.factors]\n .sort((a, b) => a.score_100 - b.score_100)\n .map((f) => {\n const inc = f.details?.inconclusive;\n return [\n f.name.replace(/_/g, \" \"),\n inc ? muted(\"—\") : `${f.score_100}/100`,\n inc ? muted(\"n/a\") : `${riskColor(f.linguistic_value)(f.linguistic_value)} ${levelIndicator(f.linguistic_value)}`,\n ];\n });\n lines.push(\"\", createTable([\"Dimension\", \"Score\", \"Level\"], rows));\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"\", accent(\"Findings\"));\n scan.recommendations.forEach((r, i) => {\n lines.push(` ${muted(String(i + 1).padStart(2))} ${riskColor(r.severity.toUpperCase())(`[${r.severity.toUpperCase()}]`)} ${r.title}`);\n });\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nexport function renderScanMarkdown(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const host = hostnameFromUrl(scan.target_url);\n const lines: string[] = [`## Fuzzi Security Scan: ${host}`, \"\"];\n\n if (fr) lines.push(`**Risk Level:** ${fr.risk_level} (${fr.overall_score}/100)`, \"\");\n\n if (scan.factors?.length) {\n lines.push(\"| Dimension | Score | Level |\", \"|-----------|-------|-------|\");\n for (const f of scan.factors) {\n lines.push(`| ${f.name.replace(/_/g, \" \")} | ${f.score_100}/100 | ${f.linguistic_value} |`);\n }\n lines.push(\"\");\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"### Findings\");\n scan.recommendations.forEach((r, i) => {\n lines.push(`${i + 1}. [${r.severity.toUpperCase()}] ${r.title}`);\n });\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderScansList(scans: ScanSummary[], format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(scans, null, 2);\n if (format === \"markdown\") {\n if (!scans.length) return \"No scans found.\";\n const lines = [\"| URL | Status | Risk | Score | Date |\", \"|-----|--------|------|-------|------|\"];\n for (const s of scans) {\n lines.push(`| ${s.target_url} | ${s.status} | ${s.risk_level || \"—\"} | ${s.overall_score ?? \"—\"} | ${formatScanDate(s)} |`);\n }\n return lines.join(\"\\n\");\n }\n if (!scans.length) return muted(\"No scans found.\");\n\n const rows = scans.map((s) => [\n truncate(s.target_url, 40),\n s.status === \"completed_inconclusive\" ? warn(\"inconcl.\") : s.status,\n s.risk_level ? riskColor(s.risk_level)(s.risk_level) : muted(\"—\"),\n s.overall_score != null ? scoreBold(s.overall_score) : muted(\"—\"),\n muted(formatScanDate(s)),\n ]);\n return createTable([\"URL\", \"Status\", \"Risk\", \"Score\", \"Date\"], rows);\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScanResult } from \"../lib/output.js\";\nimport { ApiError, FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanCreateResponse, ScanDetail } from \"../types/api.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted } from \"../terminal/theme.js\";\nimport { validateUrl } from \"../lib/errors.js\";\nimport { riskMeetsThreshold, type RiskLevel } from \"../lib/risk.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\nimport { createProgress } from \"../terminal/progress.js\";\nimport { hostnameFromUrl } from \"../terminal/strings.js\";\nimport { withRetry } from \"../lib/retry.js\";\nimport { log } from \"../lib/logger.js\";\nimport { cwd } from \"node:process\";\n\nexport interface ScanCommandOptions {\n url: string;\n format?: OutputFormat;\n wait?: boolean;\n noWait?: boolean;\n environment?: string;\n title?: string;\n failOn?: RiskLevel;\n failThreshold?: number;\n onProgress?: (message: string) => void;\n streamProgress?: boolean;\n}\n\nexport interface ScanCommandResult {\n output: string;\n exitCode: 0 | 1 | 2;\n scan?: ScanDetail;\n}\n\nconst TERMINAL_STATUSES = new Set([\"completed\", \"completed_inconclusive\", \"failed\"]);\nconst POLL_INTERVAL_MS = 3000;\n\nexport async function pollScan(\n client: FuzziApiClient,\n scanId: string,\n onTick?: (elapsed: number, status: string) => void,\n maxWaitMs = 300_000,\n): Promise<ScanDetail> {\n const start = Date.now();\n let last = \"pending\";\n while (Date.now() - start < maxWaitMs) {\n const detail = await withRetry(() => client.get<ScanDetail>(`/scan/${scanId}`));\n last = detail.status;\n onTick?.(Math.floor((Date.now() - start) / 1000), last);\n if (TERMINAL_STATUSES.has(detail.status)) {\n if (detail.status === \"failed\") {\n throw new ApiError(\n `Scan failed: ${detail.inconclusive_message || detail.inconclusive_reason || \"unknown error\"}`,\n 500,\n \"scan_failed\",\n detail,\n 2,\n );\n }\n return detail;\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n throw new ApiError(`Scan timed out after ${maxWaitMs / 1000}s (last status: ${last})`, 408, \"scan_timeout\", undefined, 2);\n}\n\nfunction resolveFormat(format?: OutputFormat, projectFormat?: OutputFormat): OutputFormat {\n return format || projectFormat || \"table\";\n}\n\nfunction computeExitCode(scan: ScanDetail, opts: ScanCommandOptions): 0 | 1 | 2 {\n const fr = scan.fuzzy_result;\n if (!fr) return 0;\n if (opts.failThreshold != null && fr.risk_score >= opts.failThreshold) return 1;\n if (opts.failOn && riskMeetsThreshold(fr.risk_level, opts.failOn)) return 1;\n return 0;\n}\n\nexport async function runScanCommand(\n client: FuzziApiClient,\n opts: ScanCommandOptions,\n): Promise<ScanCommandResult> {\n const urlError = validateUrl(opts.url);\n if (urlError) throw new ApiError(urlError, 400, \"invalid_url\", undefined, 2);\n\n const projectConfig = await loadProjectConfig(cwd());\n const config = await loadConfig();\n const format = resolveFormat(opts.format, projectConfig?.output?.format || config.default_format);\n const env = opts.environment || projectConfig?.scan?.environment || config.default_env || \"production\";\n const failOn = opts.failOn || (projectConfig?.scan?.fail_on as RiskLevel | undefined);\n const shouldWait = opts.noWait ? false : opts.wait !== false;\n\n const body: Record<string, string> = { url: opts.url, environment: env };\n if (opts.title || projectConfig?.scan?.title) {\n body.title = opts.title || projectConfig?.scan?.title || \"\";\n }\n\n log.debug(\"creating scan\", { url: opts.url, env });\n const created = await withRetry(() => client.post<ScanCreateResponse>(\"/scan\", body));\n\n if (!shouldWait) {\n const output =\n format === \"json\"\n ? JSON.stringify(created, null, 2)\n : [success(\"Scan started\"), muted(`ID: ${created.scan_id}`), muted(created.message)].join(\"\\n\");\n return { output, exitCode: 0 };\n }\n\n const host = hostnameFromUrl(opts.url);\n const progress = opts.onProgress\n ? { update: opts.onProgress, stop: () => {}, succeed: () => {}, fail: () => {} }\n : createProgress(`Scanning ${host}...`, opts.streamProgress);\n\n const detail = await pollScan(client, created.scan_id, (sec, status) => {\n progress.update(`Scanning ${host}... (${sec}s) ${muted(status)}`);\n });\n\n progress.succeed(`Scan complete — ${host}`);\n\n const exitCode = computeExitCode(detail, { ...opts, failOn });\n return { output: renderScanResult(detail, format), exitCode, scan: detail };\n}\n","import { ApiError } from \"./api-client.js\";\n\nexport type ExitCode = 0 | 1 | 2;\n\nexport function formatApiError(err: unknown): string {\n if (err instanceof ApiError) {\n return err.message;\n }\n if (err instanceof Error) {\n if (err.message.includes(\"fetch failed\") || err.message.includes(\"ECONNREFUSED\")) {\n return \"Could not connect to app.fuzzi.dev. Check your internet connection or try again later.\";\n }\n return `An error occurred: ${err.message}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n }\n return `An error occurred: ${String(err)}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n}\n\nexport function getExitCode(err: unknown): ExitCode {\n if (err instanceof ApiError && err.exitCode !== undefined) {\n return err.exitCode as ExitCode;\n }\n return 2;\n}\n\nexport function validateUrl(url: string): string | null {\n try {\n const parsed = new URL(url);\n if (![\"http:\", \"https:\"].includes(parsed.protocol)) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n return null;\n } catch {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n}\n","export type RiskLevel = \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\";\n\nconst RISK_ORDER: Record<RiskLevel, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function normalizeRiskLevel(level: string | null | undefined): RiskLevel | null {\n if (!level) return null;\n const upper = level.toUpperCase() as RiskLevel;\n return upper in RISK_ORDER ? upper : null;\n}\n\nexport function riskMeetsThreshold(\n actual: string | null | undefined,\n threshold: RiskLevel,\n): boolean {\n const a = normalizeRiskLevel(actual);\n const t = normalizeRiskLevel(threshold);\n if (!a || !t) return false;\n return RISK_ORDER[a] >= RISK_ORDER[t];\n}\n\nexport function parseRiskLevel(value: string): RiskLevel | null {\n return normalizeRiskLevel(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport interface ProjectConfig {\n scan?: {\n url?: string;\n environment?: \"production\" | \"staging\" | \"development\";\n fail_on?: string;\n title?: string;\n };\n output?: {\n format?: \"table\" | \"json\" | \"markdown\";\n };\n}\n\nfunction parseTomlSimple(raw: string): ProjectConfig {\n const config: ProjectConfig = { scan: {}, output: {} };\n let section = \"\";\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const sectionMatch = trimmed.match(/^\\[([^\\]]+)\\]$/);\n if (sectionMatch) {\n section = sectionMatch[1];\n continue;\n }\n const kv = trimmed.match(/^(\\w+)\\s*=\\s*\"?([^\"]+)\"?$/);\n if (!kv) continue;\n const [, key, value] = kv;\n if (section === \"scan\" || section === \"scan.scan\") {\n config.scan ??= {};\n if (key === \"url\") config.scan.url = value;\n else if (key === \"environment\") config.scan.environment = value as \"production\" | \"staging\" | \"development\";\n else if (key === \"fail_on\") config.scan.fail_on = value;\n else if (key === \"title\") config.scan.title = value;\n } else if (section === \"output\") {\n config.output ??= {};\n if (key === \"format\") config.output.format = value as \"table\" | \"json\" | \"markdown\";\n }\n }\n return config;\n}\n\nexport async function loadProjectConfig(cwd: string): Promise<ProjectConfig | null> {\n const fuzzirc = join(cwd, \".fuzzirc\");\n const fuzzitoml = join(cwd, \"fuzzi.toml\");\n\n if (existsSync(fuzzirc)) {\n try {\n const raw = await readFile(fuzzirc, \"utf8\");\n return JSON.parse(raw) as ProjectConfig;\n } catch {\n return null;\n }\n }\n\n if (existsSync(fuzzitoml)) {\n try {\n const raw = await readFile(fuzzitoml, \"utf8\");\n return parseTomlSimple(raw);\n } catch {\n return null;\n }\n }\n\n return null;\n}\n","import ora, { type Ora } from \"ora\";\nimport { muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nexport interface ProgressHandle {\n update(message: string): void;\n succeed(message?: string): void;\n fail(message?: string): void;\n stop(): void;\n}\n\nexport function createProgress(label: string, stream = false): ProgressHandle {\n if (!getCapabilities().interactive) {\n return {\n update: () => {},\n succeed: () => {},\n fail: () => {},\n stop: () => {},\n };\n }\n\n if (stream) {\n let last = \"\";\n return {\n update(message: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = message;\n process.stdout.write(muted(message));\n },\n succeed(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n fail(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n stop() {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = \"\";\n },\n };\n }\n\n let spinner: Ora | null = ora({ text: label, color: \"cyan\", discardStdin: false }).start();\n return {\n update(message: string) {\n if (spinner) spinner.text = message;\n },\n succeed(message?: string) {\n if (spinner) {\n spinner.succeed(message);\n spinner = null;\n }\n },\n fail(message?: string) {\n if (spinner) {\n spinner.fail(message);\n spinner = null;\n }\n },\n stop() {\n if (spinner) {\n spinner.stop();\n spinner = null;\n }\n },\n };\n}\n\nexport async function withSteps<T>(\n steps: Array<{ title: string; run: () => Promise<T> }>,\n): Promise<T> {\n let last: T | undefined;\n for (const step of steps) {\n const p = createProgress(step.title);\n try {\n last = await step.run();\n p.succeed(step.title);\n } catch (e) {\n p.fail(step.title);\n throw e;\n }\n }\n return last as T;\n}\n","import { log } from \"./logger.js\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n baseDelayMs?: number;\n retryOn?: (error: unknown) => boolean;\n}\n\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions = {}): Promise<T> {\n const max = opts.maxAttempts ?? 3;\n const base = opts.baseDelayMs ?? 500;\n const retryOn = opts.retryOn ?? ((e: unknown) => {\n const err = e as { status?: number };\n return err.status === 429 || err.status === 502 || err.status === 503;\n });\n\n let last: unknown;\n for (let attempt = 1; attempt <= max; attempt++) {\n try {\n return await fn();\n } catch (e) {\n last = e;\n if (attempt >= max || !retryOn(e)) throw e;\n const delay = base * Math.pow(2, attempt - 1);\n log.debug(`retry ${attempt}/${max} in ${delay}ms`);\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n throw last;\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScansList } from \"../lib/output.js\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanDetail } from \"../types/api.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface ScansListFilters {\n status?: string;\n riskLevel?: string;\n limit?: number;\n}\n\nexport async function runScansListCommand(\n client: FuzziApiClient,\n format: OutputFormat = \"table\",\n filters?: ScansListFilters,\n): Promise<string> {\n const params = new URLSearchParams({ page: \"1\", page_size: String(filters?.limit || 20) });\n if (filters?.status) params.set(\"status\", filters.status);\n if (filters?.riskLevel) params.set(\"risk_level\", filters.riskLevel);\n\n const data = await client.get<{ results: import(\"../types/api.js\").ScanSummary[] }>(\n `/scans?${params.toString()}`,\n );\n return renderScansList(data.results || [], format);\n}\n\nexport async function runScanGetCommand(\n client: FuzziApiClient,\n scanId: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n return renderScanResult(detail, format);\n}\n","import { FuzziApiClient } from \"../lib/api-client.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { loadCredentials, maskApiKey } from \"../lib/credentials.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { panel, keyValue, divider } from \"../terminal/layout.js\";\nimport { muted } from \"../terminal/theme.js\";\n\nfunction daysUntil(dateStr: string): number {\n const diff = new Date(dateStr).getTime() - Date.now();\n return Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)));\n}\n\nexport async function runRateLimitStatus(client: FuzziApiClient): Promise<string | null> {\n try {\n const data = await client.get<{ limit?: number; remaining?: number; reset?: string }>(\"/rate-limit\");\n if (data.limit != null) {\n return `${data.remaining ?? \"?\"}/${data.limit} remaining`;\n }\n } catch {\n /* optional endpoint */\n }\n return null;\n}\n\nexport async function runStatusCommand(client: FuzziApiClient): Promise<string> {\n const creds = await loadCredentials();\n const profile = await client.get<UserProfile>(\"/me\");\n const keyExpiry = creds?.key_expires_at || profile.key_expires_at;\n const config = await loadConfig();\n const rate = await runRateLimitStatus(client);\n\n const rows: Array<[string, string]> = [\n [\"Name\", profile.full_name || profile.email.split(\"@\")[0]],\n [\"Email\", profile.email],\n [\"Organization\", profile.organization || muted(\"—\")],\n [\"Role\", profile.role],\n [\"Auth\", `API Key (${creds ? maskApiKey(creds.api_key) : \"—\"})`],\n ];\n\n if (keyExpiry) {\n const days = daysUntil(keyExpiry);\n rows.push([\"Key expires\", `${keyExpiry.slice(0, 10)} (${days}d remaining)`]);\n } else {\n rows.push([\"Key expires\", muted(\"No expiry\")]);\n }\n\n rows.push([\"API\", config.api_url]);\n if (rate) rows.push([\"Rate limit\", rate]);\n\n return [panel(keyValue(rows), { title: \"Account\" }), \"\", divider(), muted(\"Use /keys to manage API keys\")].join(\"\\n\");\n}\n\nexport { formatApiError } from \"../lib/errors.js\";\n","import { loadConfig, setConfigValue, getConfigValue, listConfigEntries } from \"../lib/config.js\";\nimport { accent, muted } from \"../lib/theme.js\";\n\nexport async function runConfigList(): Promise<string> {\n const entries = await listConfigEntries();\n const lines = Object.entries(entries).map(([k, v]) => ` ${k} = ${v}`);\n return lines.length ? [accent(\"Config (~/.fuzzi/config)\"), ...lines].join(\"\\n\") : muted(\"No config set.\");\n}\n\nexport async function runConfigGet(key?: string): Promise<string> {\n if (!key) return runConfigList();\n const value = await getConfigValue(key);\n if (value === undefined) return muted(`Config key not set: ${key}`);\n return value;\n}\n\nexport async function runConfigSet(key: string, value: string): Promise<string> {\n const allowed = [\"api_url\", \"default_env\", \"default_format\"];\n if (!allowed.includes(key)) {\n return muted(`Unknown config key: ${key}. Supported: ${allowed.join(\", \")}`);\n }\n await setConfigValue(key, value);\n return accent(\"Config updated.\");\n}\n\nexport async function runConfigShowApiUrl(): Promise<string> {\n const config = await loadConfig();\n return config.api_url;\n}\n","import { formatApiError, getExitCode } from \"../lib/errors.js\";\n\nexport function handleCommandError(e: unknown): never {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n}\n\nexport function exitWith(code: 0 | 1 | 2): never {\n process.exit(code);\n}\n","import * as readline from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { fetchHomeData, renderHomeScreen } from \"./home-screen.js\";\nimport { dispatchSlashCommand, normalizeInput } from \"./slash-commands.js\";\nimport { accent, muted, dim } from \"../terminal/theme.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { cwd } from \"node:process\";\nimport { appendHistory, loadHistory } from \"./session.js\";\nimport { buildCompleter } from \"./completer.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\nimport { getCapabilities } from \"../terminal/capabilities.js\";\nimport { statusBar } from \"../terminal/layout.js\";\nimport { isDebugMode } from \"../lib/logger.js\";\n\nexport async function runPromptLoop(initialProfile: UserProfile | null): Promise<void> {\n let profile = initialProfile;\n const workDir = cwd();\n const history = await loadHistory();\n\n const refresh = async () => {\n if (getCapabilities().interactive) {\n process.stdout.write(\"\\x1b[2J\\x1b[H\");\n }\n const data = await fetchHomeData(profile, workDir);\n console.log(renderHomeScreen(data));\n console.log(statusBar([\n profile ? muted(profile.email) : muted(\"guest\"),\n dim(workDir),\n isDebugMode() ? muted(\"debug\") : null,\n ].filter(Boolean) as string[]));\n console.log(\"\");\n };\n\n await refresh();\n\n const rl = readline.createInterface({\n input,\n output,\n terminal: true,\n completer: buildCompleter(SLASH_COMMANDS, history),\n historySize: 300,\n });\n\n rl.on(\"SIGINT\", () => {\n console.log(muted(\"\\nGoodbye!\"));\n rl.close();\n process.exit(0);\n });\n\n const prompt = () => process.stdout.write(accent(\"› \"));\n\n prompt();\n\n for await (const line of rl) {\n await appendHistory(line);\n history.push(line.trim());\n\n const sink = {\n write: (text: string) => console.log(text),\n error: (text: string) => console.error(text),\n clearLine: () => process.stdout.write(\"\\r\\x1b[K\"),\n };\n\n const normalized = normalizeInput(line);\n const result = await dispatchSlashCommand(normalized, {\n cwd: workDir,\n profile,\n sink,\n refresh,\n });\n\n if (result.profile) profile = result.profile;\n if (result.exit) {\n console.log(muted(\"Goodbye!\"));\n rl.close();\n break;\n }\n if (result.redraw) await refresh();\n\n prompt();\n }\n}\n","import { homedir } from \"node:os\";\nimport { renderFuzziMark } from \"./ascii-mark.js\";\nimport { VERSION } from \"../types/brand.js\";\nimport { accent, accentBold, muted, italic, info } from \"../terminal/theme.js\";\nimport { splitHomePanel, centerInColumn } from \"../terminal/layout.js\";\nimport { contentWidth } from \"../terminal/width.js\";\nimport { readAsset } from \"../lib/assets.js\";\nimport type { ChangelogEntry, UserProfile } from \"../types/api.js\";\n\nexport interface HomeScreenData {\n profile: UserProfile | null;\n cwd: string;\n changelog: ChangelogEntry[];\n}\n\nexport async function fetchHomeData(profile: UserProfile | null, cwd: string): Promise<HomeScreenData> {\n let changelog: ChangelogEntry[] = [];\n try {\n changelog = JSON.parse(await readAsset(\"changelog.json\")) as ChangelogEntry[];\n } catch {\n changelog = [];\n }\n return { profile, cwd, changelog };\n}\n\nfunction isHomeDir(dir: string): boolean {\n return dir === homedir() || dir === homedir().replace(/\\/$/, \"\");\n}\n\nfunction renderLeftColumn(data: HomeScreenData): string {\n const colW = Math.max(28, Math.floor(contentWidth() * 0.34));\n const name = data.profile?.full_name || data.profile?.email?.split(\"@\")[0] || \"there\";\n const org = data.profile?.organization?.trim();\n const mark = centerInColumn(accent(renderFuzziMark()), colW);\n\n const lines: string[] = [];\n\n if (data.profile) {\n lines.push(\n accentBold(`Welcome back ${name}!`),\n \"\",\n mark,\n \"\",\n [accent(\"● Connected\"), muted(\"·\"), info(\"API Key auth\"), org ? muted(\"· \" + org) : \"\"]\n .filter(Boolean)\n .join(\" \"),\n muted(data.profile.email),\n data.profile.role ? muted(`Role: ${data.profile.role}`) : \"\",\n \"\",\n muted(data.cwd),\n \"\",\n accent(\"/scan\") + muted(\" <url> scan a target\"),\n accent(\"/scans\") + muted(\" browse history\"),\n accent(\"/status\") + muted(\" account info\"),\n accent(\"/keys\") + muted(\" manage keys\"),\n accent(\"/palette\") + muted(\" find commands\"),\n );\n } else {\n lines.push(\n accentBold(\"Welcome to Fuzzi!\"),\n \"\",\n mark,\n \"\",\n muted(\"Not connected\"),\n info(\"Press Enter to sign in\"),\n \"\",\n muted(data.cwd),\n \"\",\n accent(\"/auth\") + muted(\" browser sign-in\"),\n accent(\"/auth-key\") + muted(\" paste API key\"),\n accent(\"/scan\") + muted(\" <url> after login\"),\n accent(\"/help\") + muted(\" all commands\"),\n );\n }\n\n return lines.filter((l) => l !== \"\").join(\"\\n\");\n}\n\nfunction renderTipsColumn(data: HomeScreenData): string {\n const lines = [\n accentBold(\"Tips for getting started\"),\n \"\",\n `Run ${accent(\"/scan\")}${muted(\" <url>\")} to scan a site for security risks`,\n `Run ${accent(\"/palette\")} to search every available command`,\n `Run ${accent(\"/help\")} for the full command reference`,\n \"\",\n ];\n\n if (!data.profile) {\n lines.push(\n muted(\"Note: You launched without credentials.\"),\n muted(\"Press Enter at the prompt to open your browser,\"),\n muted(\"or use /auth-key to paste an API key.\"),\n \"\",\n );\n } else if (isHomeDir(data.cwd)) {\n lines.push(\n muted(\"Note: You launched fuzzi in your home directory.\"),\n muted(\"cd into a project folder first for better context,\"),\n muted(\"or pass URLs directly: /scan https://example.com\"),\n \"\",\n );\n } else {\n lines.push(\n muted(\"Note: Add a .fuzzirc in this directory to set default\"),\n muted(\"scan URL, environment, and output format for the team.\"),\n \"\",\n );\n }\n\n lines.push(\n muted(\"CI usage: \"),\n muted(\"fuzzi scan <url> --fail-on critical --format json\"),\n );\n\n return lines.join(\"\\n\");\n}\n\nfunction renderWhatsNewColumn(data: HomeScreenData): string {\n const latest = data.changelog[0];\n const lines = [accentBold(\"What's new\"), \"\"];\n\n if (latest) {\n for (const h of latest.highlights.slice(0, 4)) {\n lines.push(muted(h));\n }\n lines.push(\"\");\n lines.push(italic(muted(\"/changelog for more\")));\n } else {\n lines.push(muted(\"Stay tuned for updates.\"));\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function renderHomeScreen(data: HomeScreenData): string {\n return splitHomePanel({\n title: `Fuzzi CLI v${VERSION}`,\n left: renderLeftColumn(data),\n rightTop: renderTipsColumn(data),\n rightBottom: renderWhatsNewColumn(data),\n leftRatio: 0.36,\n });\n}\n\nexport function renderChangelog(entries: ChangelogEntry[]): string {\n if (!entries.length) return muted(\"No changelog entries.\");\n return entries\n .map((e) => {\n const lines = [\n accentBold(`v${e.version}`) + muted(` — ${e.date}`),\n ...e.highlights.map((h) => muted(` · ${h}`)),\n ];\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n","export function renderFuzziMark(): string {\n // Thick pixel shield mascot (teal when wrapped with accent())\n return [\n \" ██████████\",\n \" ██████████████\",\n \" ██ ██\",\n \" ██ ██████ ██\",\n \" ██ ██████ ██\",\n \" ██ ████ ██\",\n \" ██████████████\",\n \" ██ ██\",\n \" ██████████\",\n \" ██ ██\",\n \" ██ ██\",\n ].join(\"\\n\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { existsSync } from \"node:fs\";\n\n/** Resolve assets dir for both dev (src/) and production (dist/) layouts. */\nexport function assetsDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, \"..\", \"assets\"), // dist/lib → dist/../assets = package/assets\n join(here, \"..\", \"..\", \"assets\"), // src/lib → package/assets\n join(here, \"assets\"), // bundled flat fallback\n ];\n for (const p of candidates) {\n if (existsSync(join(p, \"changelog.json\"))) return p;\n }\n return candidates[0];\n}\n\nexport async function readAsset(name: string): Promise<string> {\n return readFile(join(assetsDir(), name), \"utf8\");\n}\n","import { confirm, input } from \"@inquirer/prompts\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand } from \"../commands/scans.js\";\nimport { runStatusCommand, runRateLimitStatus } from \"../commands/status.js\";\nimport { runAuthLogin, runApiKeyLogin, promptNewKeyName } from \"../commands/auth.js\";\nimport { runKeysListCommand, runKeyRevoke, pickKeyForRevoke } from \"../commands/keys.js\";\nimport { runConfigSet } from \"../commands/config.js\";\nimport { formatApiError } from \"../lib/errors.js\";\nimport { readAsset } from \"../lib/assets.js\";\nimport { renderChangelog } from \"./home-screen.js\";\nimport { renderHelpScreen, renderHistoryScreen } from \"./help-screen.js\";\nimport { openCommandPalette, pickFromList } from \"./command-palette.js\";\nimport { findCommand } from \"./registry.js\";\nimport { loadHistory } from \"./session.js\";\nimport { accent, muted, success, error as errStyle } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { errorBox, successBox } from \"../terminal/banner.js\";\nimport { truncate, formatTimestamp } from \"../terminal/strings.js\";\nimport type { UserProfile, ScanSummary, ScanDetail } from \"../types/api.js\";\nimport type { OutputSink } from \"../terminal/sink.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface SlashContext {\n cwd: string;\n profile: UserProfile | null;\n sink: OutputSink;\n refresh: () => Promise<void>;\n}\n\nexport interface SlashResult {\n exit?: boolean;\n redraw?: boolean;\n profile?: UserProfile | null;\n}\n\n/** Map bare CLI-style input to slash commands. */\nexport function normalizeInput(line: string): string {\n let t = line.trim();\n if (!t || t.startsWith(\"/\")) return t;\n\n if (t.toLowerCase().startsWith(\"fuzzi \")) t = t.slice(6).trim();\n\n const lower = t.toLowerCase();\n const aliases: Record<string, string> = {\n \"auth login\": \"/auth\",\n auth: \"/auth\",\n login: \"/auth\",\n \"auth-key\": \"/auth-key\",\n logout: \"/exit\",\n help: \"/help\",\n exit: \"/exit\",\n quit: \"/exit\",\n clear: \"/clear\",\n changelog: \"/changelog\",\n status: \"/status\",\n scans: \"/scans\",\n keys: \"/keys\",\n palette: \"/palette\",\n };\n if (aliases[lower]) return aliases[lower];\n\n if (lower.startsWith(\"scan \")) return `/scan ${t.slice(5).trim()}`;\n if (lower.startsWith(\"config set \")) {\n const parts = t.slice(11).trim().split(/\\s+/);\n if (parts.length >= 2) return `/config ${parts[0]}=${parts.slice(1).join(\" \")}`;\n }\n if (lower.startsWith(\"config \")) return `/config ${t.slice(7).trim().replace(/\\s+/, \"=\")}`;\n\n // Bare hostname → scan\n if (!t.includes(\" \") && t.includes(\".\")) return `/scan ${t}`;\n\n return t;\n}\n\nfunction normalizeScanUrl(url: string): string {\n const u = url.trim();\n if (!/^https?:\\/\\//i.test(u)) return `https://${u}`;\n return u;\n}\n\nexport async function dispatchSlashCommand(line: string, ctx: SlashContext): Promise<SlashResult> {\n const trimmed = line.trim();\n if (!trimmed) return {};\n if (trimmed === \"/exit\" || trimmed === \"/quit\") return { exit: true };\n\n const [cmd, ...rest] = trimmed.split(/\\s+/);\n const arg = rest.join(\" \").trim();\n\n if (!cmd.startsWith(\"/\")) {\n ctx.sink.write(\n errorBox(\n `Not a shell command: ${trimmed}`,\n `Use slash commands here — e.g. ${accent(\"/auth\")} not \"fuzzi auth login\"\\n${accent(\"/help\")} lists everything`,\n ),\n );\n return {};\n }\n\n if (!findCommand(cmd) && cmd.startsWith(\"/\")) {\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help or /palette\"));\n return {};\n }\n\n try {\n switch (cmd.toLowerCase()) {\n case \"/help\":\n ctx.sink.write(renderHelpScreen());\n break;\n\n case \"/palette\":\n case \"/commands\": {\n const picked = await openCommandPalette();\n if (picked) return dispatchSlashCommand(picked, ctx);\n break;\n }\n\n case \"/clear\":\n return { redraw: true };\n\n case \"/history\": {\n const hist = await loadHistory();\n ctx.sink.write(renderHistoryScreen(hist));\n break;\n }\n\n case \"/scan\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /scan <url>\"));\n break;\n }\n const client = await getAuthenticatedClient();\n const progress = createStreamProgress(ctx.sink);\n const result = await runScanCommand(client, {\n url: normalizeScanUrl(arg),\n wait: true,\n onProgress: progress.update,\n streamProgress: true,\n });\n progress.stop();\n ctx.sink.write(result.output);\n break;\n }\n\n case \"/status\": {\n const client = await getAuthenticatedClient();\n const status = await runStatusCommand(client);\n const rate = await runRateLimitStatus(client);\n ctx.sink.write(rate ? `${status}\\n\\n${muted(\"Rate limit\")} ${rate}` : status);\n break;\n }\n\n case \"/scans\":\n await runScansInteractive(ctx);\n break;\n\n case \"/keys\":\n await runKeysInteractive(ctx);\n break;\n\n case \"/config\": {\n if (!arg.includes(\"=\")) {\n ctx.sink.write(errStyle(\"Usage: /config key=value\"));\n break;\n }\n const [k, ...vParts] = arg.split(\"=\");\n ctx.sink.write(await runConfigSet(k.trim(), vParts.join(\"=\").trim()));\n break;\n }\n\n case \"/changelog\": {\n const raw = await readAsset(\"changelog.json\");\n ctx.sink.write(renderChangelog(JSON.parse(raw)));\n break;\n }\n\n case \"/compare\": {\n const [a, b] = arg.split(/\\s+/);\n if (!a || !b) {\n ctx.sink.write(errStyle(\"Usage: /compare <scan-a> <scan-b>\"));\n break;\n }\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n ctx.sink.write(await runCompareCommand(a, b, \"table\"));\n break;\n }\n\n case \"/whatif\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /whatif <scan-id>\"));\n break;\n }\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n ctx.sink.write(await runWhatIfCommand(arg, {}, \"table\"));\n break;\n }\n\n case \"/report\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /report <scan-id>\"));\n break;\n }\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runReportCommand(client, arg, \"json\"));\n break;\n }\n\n case \"/login\":\n case \"/auth\": {\n ctx.sink.write(await runAuthLogin({ interactive: true, browser: true }));\n const client = await getAuthenticatedClient();\n return { profile: await client.get<UserProfile>(\"/me\"), redraw: true };\n }\n\n case \"/auth-key\": {\n ctx.sink.write(await runApiKeyLogin({ interactive: true }));\n const client = await getAuthenticatedClient();\n return { profile: await client.get<UserProfile>(\"/me\"), redraw: true };\n }\n\n default:\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help\"));\n }\n } catch (e) {\n ctx.sink.error(formatApiError(e));\n }\n return {};\n}\n\nfunction createStreamProgress(sink: OutputSink) {\n let last = \"\";\n return {\n update(msg: string) {\n if (last) sink.clearLine?.();\n last = msg;\n process.stdout.write(muted(msg));\n },\n stop() {\n if (last) sink.clearLine?.();\n last = \"\";\n },\n };\n}\n\nasync function runScansInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n\n while (true) {\n const list = await runScansListCommand(client, \"table\", { limit: 20 });\n const data = await client.get<{ results: ScanSummary[] }>(\"/scans?page=1&page_size=20\");\n const scans = data.results || [];\n\n if (!scans.length) {\n ctx.sink.write(emptyState(\"No scans yet\", \"Run /scan <url> to create your first scan\", \"/scan https://example.com\"));\n return;\n }\n\n ctx.sink.write(list);\n ctx.sink.write(\"\");\n\n const scanId = await pickFromList(\n \"Select a scan (Esc to go back)\",\n scans.map((s) => ({\n name: `${truncate(s.target_url, 32)} ${s.risk_level ?? s.status} ${s.overall_score ?? \"—\"} ${formatTimestamp(s.created_at)}`,\n value: s.id,\n })),\n );\n if (!scanId) return;\n\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n ctx.sink.write(renderScanResult(detail, \"table\"));\n\n const cont = await input({\n message: muted(\"Enter = back to list · q = exit\"),\n default: \"\",\n }).catch(() => \"q\");\n if (cont.toLowerCase() === \"q\") return;\n }\n}\n\nasync function runKeysInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runKeysListCommand(client));\n ctx.sink.write(muted(\"\\nActions: [r] revoke [n] new key [Enter] back\"));\n\n const action = await input({ message: \"Action\", default: \"\" }).catch(() => \"\");\n\n if (action.toLowerCase() === \"r\") {\n const keyId = await pickKeyForRevoke(client);\n if (!keyId) return;\n const ok = await confirm({ message: \"Revoke this API key?\", default: false }).catch(() => false);\n if (ok) ctx.sink.write(successBox(await runKeyRevoke(client, keyId)));\n } else if (action.toLowerCase() === \"n\") {\n const name = await promptNewKeyName();\n const created = await client.post<{ key: string; name: string; prefix: string }>(\"/keys\", { name });\n ctx.sink.write(success(`Created: ${created.name} (${created.prefix})`));\n ctx.sink.write(accent(\"Save this key — it won't be shown again:\"));\n ctx.sink.write(created.key);\n }\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { muted, success } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport type { ApiKey } from \"../types/api.js\";\nimport type { FuzziApiClient } from \"../lib/api-client.js\";\nimport { pickFromList } from \"../terminal/interactive.js\";\n\nexport async function runKeysListCommand(client: FuzziApiClient): Promise<string> {\n const data = await client.get<{ results: ApiKey[] }>(\"/keys\");\n const keys = data.results || [];\n if (!keys.length) {\n return emptyState(\"No API keys\", \"Create one at app.fuzzi.dev/settings/api-keys\", \"[n] new key in this view\");\n }\n\n const rows = keys.map((k) => [\n k.name,\n k.prefix,\n k.scopes?.join(\", \") || muted(\"—\"),\n k.revoked ? muted(\"Revoked\") : k.active ? success(\"Active\") : muted(\"Inactive\"),\n k.last_used_at ? new Date(k.last_used_at).toLocaleDateString() : muted(\"Never\"),\n ]);\n\n return createTable([\"Name\", \"Prefix\", \"Scopes\", \"Status\", \"Last Used\"], rows);\n}\n\nexport async function runKeyRevoke(client: FuzziApiClient, keyId: string): Promise<string> {\n await client.delete(`/keys/${keyId}`);\n return \"API key revoked.\";\n}\n\nexport async function pickKeyForRevoke(client: FuzziApiClient): Promise<string | null> {\n const data = await client.get<{ results: ApiKey[] }>(\"/keys\");\n const active = (data.results || []).filter((k) => !k.revoked && k.active);\n return pickFromList(\n \"Select a key to revoke\",\n active.map((k) => ({ name: `${k.name} (${k.prefix})`, value: k.id })),\n );\n}\n","import { muted, accent } from \"./theme.js\";\n\nexport function emptyState(title: string, hint: string, action?: string): string {\n const lines = [\"\", muted(title), muted(hint)];\n if (action) lines.push(\"\", accent(action));\n return lines.join(\"\\n\");\n}\n","import { select, search } from \"@inquirer/prompts\";\nimport { accent, muted } from \"./theme.js\";\n\nexport async function pickFromList<T extends { name: string; value: string }>(\n message: string,\n items: T[],\n): Promise<string | null> {\n if (!items.length) return null;\n try {\n return await select({ message, choices: items });\n } catch {\n return null;\n }\n}\n\nexport async function searchPalette(\n message: string,\n choices: Array<{ name: string; value: string; description?: string }>,\n): Promise<string | null> {\n try {\n return await search({\n message,\n source: async (input) => {\n if (!input) return choices;\n const q = input.toLowerCase();\n return choices.filter((c) => c.value.includes(q) || c.description?.includes(q));\n },\n });\n } catch {\n return null;\n }\n}\n\nexport function formatChoice(name: string, description: string): string {\n return `${accent(name)}${muted(\" — \" + description)}`;\n}\n","import { panel, columns, divider, keyValue } from \"../terminal/layout.js\";\nimport { accent, accentBold, muted, dim } from \"../terminal/theme.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport function renderHelpScreen(): string {\n const visible = SLASH_COMMANDS.filter((c) => !c.hidden);\n const left = visible\n .slice(0, Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n const right = visible\n .slice(Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n\n const script = [\n muted(\"Scriptable commands\"),\n ` fuzzi scan <url> [--format json|markdown] [--fail-on critical]`,\n ` fuzzi scans list | get <id> · fuzzi auth login | status`,\n ` fuzzi config set default_env staging`,\n ].join(\"\\n\");\n\n return [\n panel(columns(left, right), { title: \"Commands\" }),\n \"\",\n script,\n \"\",\n divider(),\n dim(\"Tips: Tab to complete · /palette to search · Ctrl+C to exit\"),\n ].join(\"\\n\");\n}\n\nexport function renderHistoryScreen(entries: string[]): string {\n if (!entries.length) return muted(\"No command history yet.\");\n const body = entries\n .slice(-15)\n .reverse()\n .map((e, i) => `${dim(String(i + 1).padStart(2))} ${e}`)\n .join(\"\\n\");\n return panel(body, { title: \"Recent commands\" });\n}\n","export interface SlashCommandDef {\n name: string;\n description: string;\n usage?: string;\n aliases?: string[];\n requiresAuth?: boolean;\n hidden?: boolean;\n}\n\nexport const SLASH_COMMANDS: SlashCommandDef[] = [\n { name: \"/scan\", description: \"Run a security scan on a URL\", usage: \"/scan <url>\", requiresAuth: true },\n { name: \"/scans\", description: \"Browse recent scans\", requiresAuth: true },\n { name: \"/status\", description: \"Show auth status and rate limits\", requiresAuth: true },\n { name: \"/keys\", description: \"Manage API keys\", requiresAuth: true },\n { name: \"/config\", description: \"Set CLI configuration\", usage: \"/config key=value\" },\n { name: \"/compare\", description: \"Compare two scans\", usage: \"/compare <id-a> <id-b>\", requiresAuth: true },\n { name: \"/whatif\", description: \"Simulate factor overrides\", usage: \"/whatif <id>\", requiresAuth: true },\n { name: \"/report\", description: \"Download scan report\", usage: \"/report <id>\", requiresAuth: true },\n { name: \"/palette\", description: \"Open command palette\", aliases: [\"/commands\"] },\n { name: \"/changelog\", description: \"View release notes\" },\n { name: \"/help\", description: \"Show all commands\" },\n { name: \"/auth\", description: \"Sign in via browser\", aliases: [\"/login\"] },\n { name: \"/auth-key\", description: \"Paste an API key instead\", usage: \"/auth-key\" },\n { name: \"/clear\", description: \"Clear screen and refresh home\" },\n { name: \"/history\", description: \"Show recent commands\" },\n { name: \"/exit\", description: \"Exit the shell\", aliases: [\"/quit\"] },\n];\n\nexport function findCommand(input: string): SlashCommandDef | undefined {\n const cmd = input.trim().split(/\\s/)[0].toLowerCase();\n return SLASH_COMMANDS.find(\n (c) => c.name === cmd || c.aliases?.some((a) => a === cmd),\n );\n}\n\nexport function suggestCommands(partial: string): SlashCommandDef[] {\n const p = partial.toLowerCase();\n if (!p.startsWith(\"/\")) return SLASH_COMMANDS.filter((c) => !c.hidden);\n return SLASH_COMMANDS.filter((c) => c.name.startsWith(p) || c.aliases?.some((a) => a.startsWith(p)));\n}\n","import { searchPalette, formatChoice } from \"../terminal/interactive.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport async function openCommandPalette(): Promise<string | null> {\n const choices = SLASH_COMMANDS.filter((c) => !c.hidden).map((c) => ({\n name: formatChoice(c.name, c.description),\n value: c.name,\n description: c.usage,\n }));\n return searchPalette(\"Command palette\", choices);\n}\n\nexport { pickFromList } from \"../terminal/interactive.js\";\n","import { mkdir, readFile, writeFile, appendFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fuzziDir } from \"../lib/credentials.js\";\n\nconst HISTORY_PATH = join(fuzziDir(), \"history\");\nconst MAX_ENTRIES = 200;\n\nexport async function loadHistory(): Promise<string[]> {\n try {\n const raw = await readFile(HISTORY_PATH, \"utf8\");\n return raw.split(\"\\n\").filter(Boolean).slice(-MAX_ENTRIES);\n } catch {\n return [];\n }\n}\n\nexport async function appendHistory(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) return;\n await mkdir(fuzziDir(), { recursive: true, mode: 0o700 });\n await appendFile(HISTORY_PATH, trimmed + \"\\n\", \"utf8\");\n}\n\nexport async function clearHistory(): Promise<void> {\n await writeFile(HISTORY_PATH, \"\", \"utf8\");\n}\n","import { panel } from \"./layout.js\";\nimport { error, warn, success, accentBold } from \"./theme.js\";\n\nexport function errorBox(message: string, hint?: string): string {\n const body = hint ? `${message}\\n\\n${hint}` : message;\n return panel(body, { title: \"Error\" });\n}\n\nexport function successBox(message: string): string {\n return panel(success(message), { title: \"Done\" });\n}\n\nexport function section(title: string, body: string): string {\n return [accentBold(title), body].join(\"\\n\");\n}\n\nexport function warningBox(message: string): string {\n return panel(warn(message), { title: \"Warning\" });\n}\n","import type { SlashCommandDef } from \"./registry.js\";\n\nexport function buildCompleter(commands: SlashCommandDef[], history: string[]): (line: string) => [string[], string] {\n const names = commands.map((c) => c.name);\n return (line: string): [string[], string] => {\n const trimmed = line.trimStart();\n if (!trimmed.startsWith(\"/\")) {\n if (trimmed === \"\") return [[...names, ...history.slice(-20).reverse()], line];\n return [[], line];\n }\n const hits = names.filter((n) => n.startsWith(trimmed.split(/\\s/)[0]));\n return [hits.length ? hits : names, line];\n };\n}\n","import * as readline from \"node:readline\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { splitHomePanel, centerInColumn } from \"../terminal/layout.js\";\nimport { accent, accentBold, info, muted, italic } from \"../terminal/theme.js\";\nimport { contentWidth } from \"../terminal/width.js\";\nimport { renderFuzziMark } from \"./ascii-mark.js\";\nimport { runBrowserLogin } from \"../lib/browser-auth.js\";\nimport { tryGetProfile } from \"../cli/profile.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { formatApiError } from \"../lib/errors.js\";\nimport { createProgress } from \"../terminal/progress.js\";\nimport { VERSION } from \"../types/brand.js\";\n\nexport function renderAuthGate(): string {\n const colW = Math.max(28, Math.floor(contentWidth() * 0.36));\n const mark = centerInColumn(accent(renderFuzziMark()), colW);\n\n const left = [\n accentBold(\"Welcome to Fuzzi!\"),\n \"\",\n mark,\n \"\",\n muted(\"Not connected\"),\n info(\"Sign in to run scans\"),\n \"\",\n accent(\"/auth-key\") + muted(\" paste API key\"),\n accent(\"/help\") + muted(\" commands\"),\n ].join(\"\\n\");\n\n const rightTop = [\n accentBold(\"Sign in to continue\"),\n \"\",\n info(\"Press Enter to open your browser\"),\n muted(\"and authorize the CLI.\"),\n \"\",\n muted(\"A local server receives the callback\"),\n muted(\"from app.fuzzi.dev automatically.\"),\n ].join(\"\\n\");\n\n const rightBottom = [\n accentBold(\"Other options\"),\n \"\",\n muted(\"Paste an API key with /auth-key\"),\n muted(\"from Settings → API Keys on the web.\"),\n \"\",\n italic(muted(\"docs: app.fuzzi.dev/settings/api-keys\")),\n ].join(\"\\n\");\n\n return splitHomePanel({\n title: `Fuzzi CLI v${VERSION}`,\n left,\n rightTop,\n rightBottom,\n leftRatio: 0.36,\n });\n}\n\nfunction waitForEnter(): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input, output, terminal: true });\n output.write(accent(\"\\n › Press Enter to open browser... \"));\n rl.once(\"line\", () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport async function runAuthGate(): Promise<UserProfile | null> {\n const existing = await tryGetProfile();\n if (existing) return existing;\n\n if (!output.isTTY) return null;\n\n console.log(renderAuthGate());\n await waitForEnter();\n\n const progress = createProgress(\"Opening browser...\");\n try {\n const result = await runBrowserLogin();\n progress.succeed(\"Signed in\");\n console.log(accent(result.message));\n return result.profile;\n } catch (e) {\n progress.fail(\"Sign-in failed\");\n console.log(muted(formatApiError(e)));\n console.log(muted(\"Use /auth-key to paste an API key, or /auth to retry.\"));\n return null;\n }\n}\n","import { cwd } from \"node:process\";\nimport { loadCredentials } from \"../lib/credentials.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"../lib/logger.js\";\n\nexport async function tryGetProfile(): Promise<UserProfile | null> {\n try {\n const creds = await loadCredentials();\n if (!creds?.api_key) return null;\n const client = await getAuthenticatedClient();\n return await client.get<UserProfile>(\"/me\");\n } catch (e) {\n log.debug(\"profile bootstrap failed\", e);\n return null;\n }\n}\n","import type { UserProfile } from \"../types/api.js\";\nimport { runPromptLoop } from \"../shell/prompt-loop.js\";\nimport { runAuthGate } from \"../shell/auth-gate.js\";\nimport { tryGetProfile } from \"./profile.js\";\n\nexport async function runInteractiveMode(): Promise<void> {\n let profile = await tryGetProfile();\n if (!profile) {\n profile = await runAuthGate();\n }\n await runPromptLoop(profile);\n}\n","import { buildProgram } from \"./cli/program.js\";\nimport { runInteractiveMode } from \"./cli/bootstrap.js\";\nimport { formatApiError, getExitCode } from \"./lib/errors.js\";\n\nasync function main(argv: string[]): Promise<void> {\n if (argv.length <= 2) {\n await runInteractiveMode();\n return;\n }\n await buildProgram().parseAsync(argv);\n}\n\nmain(process.argv).catch((e) => {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n});\n"],"mappings":"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","names":["mkdir","readFile","writeFile","chmod","homedir","join","ensureDir","stdout","init_theme","writeFile","init_theme","cwd","readFile","join","cwd","output","init_theme","cwd","runReportCommand","runWhatIfCommand","runCompareCommand","input","homedir","readFile","join","existsSync","cwd","homedir","confirm","input","input","input","mkdir","readFile","writeFile","join","runCompareCommand","runWhatIfCommand","runReportCommand","input","confirm","cwd","cwd","input","readline","input","output","input","output"]}
1
+ {"version":3,"sources":["../src/types/brand.ts","../src/lib/credentials.ts","../src/lib/config.ts","../src/lib/logger.ts","../src/lib/api-client.ts","../src/terminal/capabilities.ts","../src/terminal/theme.ts","../src/terminal/table.ts","../src/terminal/strings.ts","../src/terminal/width.ts","../src/terminal/layout.ts","../src/lib/theme.ts","../src/commands/report.ts","../src/commands/whatif.ts","../src/commands/compare.ts","../src/cli/program.ts","../src/commands/auth.ts","../src/lib/browser-auth.ts","../src/lib/output.ts","../src/commands/scan.ts","../src/lib/errors.ts","../src/lib/risk.ts","../src/lib/project-config.ts","../src/terminal/progress.ts","../src/lib/retry.ts","../src/commands/scans.ts","../src/commands/status.ts","../src/commands/config.ts","../src/cli/exit.ts","../src/shell/prompt-loop.ts","../src/shell/home-screen.ts","../src/shell/ascii-mark.ts","../src/lib/assets.ts","../src/shell/slash-commands.ts","../src/commands/keys.ts","../src/terminal/empty-state.ts","../src/terminal/interactive.ts","../src/shell/help-screen.ts","../src/shell/registry.ts","../src/shell/command-palette.ts","../src/shell/session.ts","../src/terminal/banner.ts","../src/shell/completer.ts","../src/shell/auth-gate.ts","../src/cli/profile.ts","../src/cli/bootstrap.ts","../src/index.ts"],"sourcesContent":["export const BRAND = {\n accent: \"#4FC3A1\",\n accentDim: \"#3A9A7E\",\n text: \"#FAFAFA\",\n textSecondary: \"#8C8C8C\",\n bg: \"#0A0A0A\",\n border: \"#2A2A2A\",\n} as const;\n\nexport const RISK_COLORS: Record<string, string> = {\n LOW: \"#22C55E\",\n MEDIUM: \"#F59E0B\",\n HIGH: \"#EF4444\",\n CRITICAL: \"#A855F7\",\n};\n\nexport const VERSION = \"0.1.3\";\n\n/** Production web app (Vercel) */\nexport const APP_ORIGIN = \"https://fuzzi-ten.vercel.app\";\n\n/** Default API base — override with FUZZI_API_URL */\nexport const DEFAULT_API_URL = `${APP_ORIGIN}/api`;\n\nexport const SETTINGS_API_KEYS_URL = `${APP_ORIGIN}/settings/api-keys`;\nexport const CLI_AUTH_URL = `${APP_ORIGIN}/cli-auth`;\nexport const APP_HOST = \"fuzzi-ten.vercel.app\";\n","import { mkdir, readFile, writeFile, chmod, unlink } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Credentials } from \"../types/api.js\";\n\nconst FUZZI_DIR = join(homedir(), \".fuzzi\");\nconst CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials\");\nconst LEGACY_CREDENTIALS_PATH = join(FUZZI_DIR, \"credentials.json\");\n\nexport function fuzziDir(): string {\n return FUZZI_DIR;\n}\n\nexport function credentialsPath(): string {\n return CREDENTIALS_PATH;\n}\n\nasync function ensureDir(): Promise<void> {\n await mkdir(FUZZI_DIR, { recursive: true, mode: 0o700 });\n}\n\nfunction normalizeCredentials(raw: Record<string, unknown>): Credentials {\n if (raw.api_key && typeof raw.api_key === \"string\") {\n return {\n api_key: raw.api_key,\n auth_method: \"api_key\",\n key_prefix: (raw.key_prefix as string) || raw.api_key.slice(0, 12) + \"...\",\n key_expires_at: raw.key_expires_at as string | undefined,\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n if (raw.access_token && typeof raw.access_token === \"string\") {\n return {\n api_key: raw.access_token,\n auth_method: \"api_key\",\n key_prefix: raw.access_token.slice(0, 12) + \"...\",\n email: raw.email as string | undefined,\n full_name: raw.full_name as string | undefined,\n saved_at: (raw.saved_at as string) || new Date().toISOString(),\n };\n }\n throw new Error(\"Invalid credentials file\");\n}\n\nexport async function loadCredentials(): Promise<Credentials | null> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (!parsed || Object.keys(parsed).length === 0) return null;\n return normalizeCredentials(parsed);\n } catch {\n /* try next path */\n }\n }\n return null;\n}\n\nexport async function saveCredentials(creds: Credentials): Promise<void> {\n await ensureDir();\n await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), { mode: 0o600 });\n try {\n await chmod(CREDENTIALS_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function clearCredentials(): Promise<void> {\n for (const path of [CREDENTIALS_PATH, LEGACY_CREDENTIALS_PATH]) {\n try {\n await unlink(path);\n } catch {\n /* ok */\n }\n }\n}\n\nexport function maskApiKey(key: string): string {\n if (key.length <= 16) return key.slice(0, 8) + \"...\";\n return key.slice(0, 12) + \"...\";\n}\n\nexport function isValidApiKeyFormat(key: string): boolean {\n return /^fz_live_[A-Za-z0-9_-]{20,}$/.test(key.trim());\n}\n","import { mkdir, readFile, writeFile, chmod } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CliConfig } from \"../types/api.js\";\nimport { DEFAULT_API_URL } from \"../types/brand.js\";\nimport { fuzziDir } from \"./credentials.js\";\n\nconst CONFIG_PATH = join(homedir(), \".fuzzi\", \"config\");\nconst LEGACY_CONFIG_PATH = join(homedir(), \".fuzzi\", \"config.json\");\n\nexport { fuzziDir };\n\nasync function ensureDir(): Promise<void> {\n await mkdir(fuzziDir(), { recursive: true, mode: 0o700 });\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n for (const path of [CONFIG_PATH, LEGACY_CONFIG_PATH]) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<CliConfig>;\n return {\n api_url: process.env.FUZZI_API_URL || parsed.api_url || DEFAULT_API_URL,\n default_env: parsed.default_env,\n default_format: parsed.default_format,\n ...parsed,\n };\n } catch {\n /* try next */\n }\n }\n return { api_url: process.env.FUZZI_API_URL || DEFAULT_API_URL };\n}\n\nexport async function saveConfig(config: CliConfig): Promise<void> {\n await ensureDir();\n await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });\n try {\n await chmod(CONFIG_PATH, 0o600);\n } catch {\n /* windows */\n }\n}\n\nexport async function setConfigValue(key: string, value: string): Promise<void> {\n const config = await loadConfig();\n if (key === \"api_url\") config.api_url = value;\n else if (key === \"default_env\") config.default_env = value as CliConfig[\"default_env\"];\n else if (key === \"default_format\") config.default_format = value as CliConfig[\"default_format\"];\n else (config as unknown as Record<string, string>)[key] = value;\n await saveConfig(config);\n}\n\nexport async function getConfigValue(key: string): Promise<string | undefined> {\n const config = await loadConfig();\n return (config as unknown as Record<string, string | undefined>)[key];\n}\n\nexport async function listConfigEntries(): Promise<Record<string, string>> {\n const config = await loadConfig();\n const entries: Record<string, string> = {};\n for (const [k, v] of Object.entries(config)) {\n if (v !== undefined) entries[k] = String(v);\n }\n return entries;\n}\n","type Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<Level, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\nfunction currentLevel(): Level {\n if (process.env.FUZZI_DEBUG === \"1\" || process.env.FUZZI_DEBUG === \"true\") return \"debug\";\n if (process.env.FUZZI_LOG_LEVEL) return process.env.FUZZI_LOG_LEVEL as Level;\n return \"warn\";\n}\n\nfunction shouldLog(level: Level): boolean {\n return LEVELS[level] >= LEVELS[currentLevel()];\n}\n\nfunction stamp(): string {\n return new Date().toISOString();\n}\n\nexport const log = {\n debug(...args: unknown[]) {\n if (shouldLog(\"debug\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n info(...args: unknown[]) {\n if (shouldLog(\"info\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n warn(...args: unknown[]) {\n if (shouldLog(\"warn\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n error(...args: unknown[]) {\n if (shouldLog(\"error\")) console.error(`[fuzzi ${stamp()}]`, ...args);\n },\n};\n\nexport function isDebugMode(): boolean {\n return currentLevel() === \"debug\";\n}\n","import type { Credentials, CliConfig } from \"../types/api.js\";\nimport { loadConfig } from \"./config.js\";\nimport { loadCredentials } from \"./credentials.js\";\nimport { log } from \"./logger.js\";\nimport { APP_HOST, SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\n\nexport class ApiError extends Error {\n exitCode?: number;\n\n constructor(\n message: string,\n public status: number,\n public code?: string,\n public body?: unknown,\n exitCode?: number,\n ) {\n super(message);\n this.name = \"ApiError\";\n this.exitCode = exitCode;\n }\n}\n\nfunction mapErrorMessage(status: number, body: { error?: string; code?: string; message?: string }): string {\n const code = body.code?.toLowerCase();\n const msg = body.error || body.message || \"\";\n\n if (status === 401) {\n if (code === \"key_revoked\" || msg.toLowerCase().includes(\"revoked\")) {\n return \"API key has been revoked. Please log in again.\";\n }\n if (code === \"key_expired\" || msg.toLowerCase().includes(\"expired\")) {\n return `API key has expired. Generate a new one at ${SETTINGS_API_KEYS_URL}`;\n }\n return `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`;\n }\n if (status === 403 && (code === \"ssrf\" || msg.toLowerCase().includes(\"private ip\"))) {\n return \"This URL is not allowed (private IP address detected). Please scan a public-facing URL.\";\n }\n if (status === 400 && msg.toLowerCase().includes(\"url\")) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n if (status === 429) {\n return msg || \"Rate limit exceeded.\";\n }\n if (msg.toLowerCase().startsWith(\"scan failed\")) {\n return msg;\n }\n if (msg) return msg;\n return `Request failed with status ${status}`;\n}\n\nexport class FuzziApiClient {\n constructor(\n private baseUrl: string,\n private token?: string,\n ) {}\n\n static async create(): Promise<FuzziApiClient> {\n const config = await loadConfig();\n const creds = await loadCredentials();\n return new FuzziApiClient(config.api_url.replace(/\\/$/, \"\"), creds?.api_key);\n }\n\n get base(): string {\n return this.baseUrl;\n }\n\n setToken(token: string): void {\n this.token = token;\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\", Accept: \"application/json\" };\n if (this.token) h.Authorization = `Bearer ${this.token}`;\n return h;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n log.debug(`${method} ${url}`);\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: this.headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(\n `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n\n let data: unknown;\n const text = await res.text();\n try {\n data = text ? JSON.parse(text) : {};\n } catch {\n data = { error: text };\n }\n\n if (!res.ok) {\n const errBody = data as { error?: string; code?: string; message?: string };\n let message = mapErrorMessage(res.status, errBody);\n\n if (res.status === 429) {\n const retryAfter = res.headers.get(\"Retry-After\");\n const seconds = retryAfter ? parseInt(retryAfter, 10) : 60;\n message = `Rate limit exceeded. Retry after ${seconds} seconds.`;\n }\n\n if (res.status >= 500) {\n message = `Scan failed: ${errBody.error || errBody.message || res.statusText}`;\n }\n\n throw new ApiError(message, res.status, errBody.code, data, 2);\n }\n return data as T;\n }\n\n get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async validateToken(): Promise<boolean> {\n try {\n await this.get(\"/me\");\n return true;\n } catch {\n return false;\n }\n }\n\n async download(path: string): Promise<{ data: Buffer; contentType: string }> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n let res: Response;\n try {\n res = await fetch(url, { headers: this.headers() });\n } catch {\n throw new ApiError(\n `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`,\n 0,\n \"network_error\",\n undefined,\n 2,\n );\n }\n if (!res.ok) {\n const text = await res.text();\n let errBody: { error?: string; code?: string } = {};\n try {\n errBody = JSON.parse(text);\n } catch {\n errBody = { error: text };\n }\n throw new ApiError(mapErrorMessage(res.status, errBody), res.status, errBody.code, errBody, 2);\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return { data: buf, contentType: res.headers.get(\"content-type\") || \"application/octet-stream\" };\n }\n}\n\nexport async function getAuthenticatedClient(): Promise<FuzziApiClient> {\n const client = await FuzziApiClient.create();\n if (!client[\"token\"]) {\n throw new ApiError(\"Not authenticated. Run: fuzzi auth login\", 401, \"not_authenticated\", undefined, 2);\n }\n return client;\n}\n\nexport async function getConfig(): Promise<CliConfig> {\n return loadConfig();\n}\n\nexport async function getCredentials(): Promise<Credentials | null> {\n return loadCredentials();\n}\n","import { stdout } from \"node:process\";\n\nexport interface TerminalCapabilities {\n width: number;\n trueColor: boolean;\n interactive: boolean;\n}\n\nlet cached: TerminalCapabilities | null = null;\n\nexport function getCapabilities(): TerminalCapabilities {\n if (cached) return cached;\n const cols = stdout.columns ?? 80;\n const term = process.env.TERM ?? \"\";\n const colorterm = process.env.COLORTERM ?? \"\";\n const trueColor =\n colorterm.includes(\"truecolor\") ||\n colorterm.includes(\"24bit\") ||\n term.includes(\"truecolor\") ||\n (!!process.env.FORCE_COLOR && process.env.FORCE_COLOR !== \"0\");\n\n cached = {\n width: Math.max(60, Math.min(cols, 120)),\n trueColor,\n interactive: stdout.isTTY === true,\n };\n return cached;\n}\n\nexport function resetCapabilities(): void {\n cached = null;\n}\n","import chalk, { type ChalkInstance } from \"chalk\";\nimport { BRAND, RISK_COLORS } from \"../types/brand.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nfunction color(hex: string, fallback: ChalkInstance): ChalkInstance {\n return getCapabilities().trueColor ? chalk.hex(hex) : fallback;\n}\n\nexport const accent = color(BRAND.accent, chalk.cyan);\nexport const accentBold = accent.bold;\nexport const muted = color(BRAND.textSecondary, chalk.gray);\nexport const bold = chalk.bold;\nexport const dim = chalk.dim;\n\nexport function riskColor(level: string | null | undefined): (s: string) => string {\n if (!level) return muted;\n const key = level.toUpperCase();\n const hex = RISK_COLORS[key] || BRAND.textSecondary;\n const fallbacks: Record<string, ChalkInstance> = {\n LOW: chalk.green,\n MEDIUM: chalk.yellow,\n HIGH: chalk.red,\n CRITICAL: chalk.magenta,\n };\n return color(hex, fallbacks[key] ?? chalk.gray).bold;\n}\n\nexport function scoreBold(n: number | null | undefined): string {\n if (n == null) return muted(\"—\");\n return chalk.bold(String(n));\n}\n\nexport function header(text: string): string {\n return accentBold(text);\n}\n\nexport function error(text: string): string {\n return color(\"#EF4444\", chalk.red)(text);\n}\n\nexport function success(text: string): string {\n return color(\"#22C55E\", chalk.green)(text);\n}\n\nexport function warn(text: string): string {\n return color(\"#F59E0B\", chalk.yellow)(text);\n}\n\nexport function info(text: string): string {\n return color(BRAND.accent, chalk.cyan)(text);\n}\n\nexport const italic = chalk.italic;\n\nexport function riskBadge(level: string): string {\n const tag = level.toUpperCase().padEnd(8);\n return riskColor(level)(tag);\n}\n","import Table from \"cli-table3\";\nimport { muted } from \"./theme.js\";\n\nconst BOX_CHARS: Record<string, string> = {\n mid: \"─\",\n \"left-mid\": \"├\",\n \"mid-mid\": \"┼\",\n \"right-mid\": \"┤\",\n};\n\nexport function createTable(headers: string[], rows: string[][]): string {\n const table = new Table({\n head: headers.map((h) => muted(h)),\n style: { head: [], border: [] },\n chars: BOX_CHARS,\n });\n for (const row of rows) table.push(row);\n return table.toString();\n}\n","export function truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, max - 1) + \"…\";\n}\n\nexport function padEndVisible(s: string, width: number): string {\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, width - plain.length);\n return s + \" \".repeat(pad);\n}\n\nexport function formatTimestamp(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;\n}\n\nexport function hostnameFromUrl(url: string): string {\n try {\n return new URL(url).hostname;\n } catch {\n return url;\n }\n}\n","import { stdout } from \"node:process\";\nimport { getCapabilities, resetCapabilities } from \"./capabilities.js\";\n\nexport function terminalWidth(): number {\n resetCapabilities();\n return Math.max(64, (stdout.columns ?? 80) - 2);\n}\n\nexport function contentWidth(): number {\n return terminalWidth() - 4;\n}\n","import boxen from \"boxen\";\nimport { BRAND } from \"../types/brand.js\";\nimport { accentBold, dim, muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\nimport { padEndVisible } from \"./strings.js\";\nimport { terminalWidth, contentWidth } from \"./width.js\";\n\nexport interface PanelOptions {\n title?: string;\n padding?: number;\n marginBottom?: number;\n fullWidth?: boolean;\n borderStyle?: \"round\" | \"single\" | \"classic\" | \"bold\";\n}\n\nexport function panel(content: string, opts: PanelOptions = {}): string {\n const width = opts.fullWidth !== false ? terminalWidth() : undefined;\n return boxen(content, {\n title: opts.title ? accentBold(opts.title) : undefined,\n padding: opts.padding ?? 1,\n margin: { top: 0, bottom: opts.marginBottom ?? 1, left: 0, right: 0 },\n borderStyle: opts.borderStyle ?? \"classic\",\n borderColor: getCapabilities().trueColor ? BRAND.accent : undefined,\n titleAlignment: \"left\",\n width,\n });\n}\n\nexport function centerInColumn(text: string, colWidth: number): string {\n return text\n .split(\"\\n\")\n .map((line) => {\n const plain = line.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const pad = Math.max(0, Math.floor((colWidth - plain.length) / 2));\n return \" \".repeat(pad) + line;\n })\n .join(\"\\n\");\n}\n\nexport interface SplitHomeOptions {\n title: string;\n left: string;\n rightTop: string;\n rightBottom: string;\n leftRatio?: number;\n}\n\n/** Claude Code-style two-column home with horizontal split on the right. */\nexport function splitHomePanel(opts: SplitHomeOptions): string {\n const total = contentWidth();\n const leftW = Math.max(28, Math.floor(total * (opts.leftRatio ?? 0.34)));\n const rightW = total - leftW - 3;\n\n const leftLines = opts.left.split(\"\\n\");\n const rightTop = opts.rightTop.split(\"\\n\");\n const rightDiv = dim(\"─\".repeat(Math.max(10, rightW)));\n const rightBottom = opts.rightBottom.split(\"\\n\");\n const rightLines = [...rightTop, \"\", rightDiv, \"\", ...rightBottom];\n\n const rows = Math.max(leftLines.length, rightLines.length);\n const sep = dim(\"│\");\n const body: string[] = [\"\"];\n\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", leftW);\n const r = rightLines[i] ?? \"\";\n body.push(`${l} ${sep} ${r}`);\n }\n body.push(\"\");\n\n return panel(body.join(\"\\n\"), { title: opts.title, marginBottom: 0, borderStyle: \"classic\" });\n}\n\nexport function columns(left: string, right: string, leftWidth?: number): string {\n const total = contentWidth();\n const split = leftWidth ?? Math.floor(total * 0.48);\n const leftLines = left.split(\"\\n\");\n const rightLines = right.split(\"\\n\");\n const rows = Math.max(leftLines.length, rightLines.length);\n const out: string[] = [];\n for (let i = 0; i < rows; i++) {\n const l = padEndVisible(leftLines[i] ?? \"\", split);\n const r = rightLines[i] ?? \"\";\n out.push(`${l} ${r}`);\n }\n return out.join(\"\\n\");\n}\n\nexport function divider(char = \"─\", width?: number): string {\n const w = width ?? contentWidth();\n return dim(char.repeat(Math.max(20, w)));\n}\n\nexport function statusBar(parts: string[]): string {\n return dim(parts.filter(Boolean).join(\" · \"));\n}\n\nexport function keyValue(rows: Array<[string, string]>, indent = 2): string {\n const pad = \" \".repeat(indent);\n const maxKey = Math.max(...rows.map(([k]) => k.length), 4);\n return rows.map(([k, v]) => `${pad}${muted(k.padEnd(maxKey))} ${v}`).join(\"\\n\");\n}\n\nexport function centerBlock(text: string, width = contentWidth()): string {\n return centerInColumn(text, width);\n}\n","export * from \"../terminal/theme.js\";\n","import { writeFile } from \"node:fs/promises\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\n\nexport async function runReportCommand(\n client: FuzziApiClient,\n scanId: string,\n format: \"pdf\" | \"csv\" | \"json\",\n outputPath?: string,\n): Promise<string> {\n const { data, contentType } = await client.download(`/scan/${scanId}/report?format=${format}`);\n\n const ext = format === \"pdf\" ? \"pdf\" : format === \"csv\" ? \"csv\" : \"json\";\n const path = outputPath || `fuzzi-report-${scanId.slice(0, 8)}.${ext}`;\n\n await writeFile(path, data);\n return `Report saved to ${path} (${contentType})`;\n}\n","import { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { riskColor, scoreBold } from \"../lib/theme.js\";\n\nexport async function runWhatIfCommand(\n scanId: string,\n overrides: Record<string, number>,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<{\n original: { risk_level: string; overall_score: number };\n simulated: { risk_level: string; overall_score: number };\n summary: string;\n overall_score_delta: number;\n }>(\"/whatif\", { scan_id: scanId, overrides });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n return [\n `Original: ${riskColor(data.original.risk_level)(data.original.risk_level)} (${scoreBold(data.original.overall_score)})`,\n `Simulated: ${riskColor(data.simulated.risk_level)(data.simulated.risk_level)} (${scoreBold(data.simulated.overall_score)})`,\n `Delta: ${data.overall_score_delta > 0 ? \"+\" : \"\"}${data.overall_score_delta}`,\n data.summary,\n ].join(\"\\n\");\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { riskColor, scoreBold } from \"../terminal/theme.js\";\nimport { panel } from \"../terminal/layout.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { CompareResponse } from \"../types/api.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\n\nexport async function runCompareCommand(\n scanA: string,\n scanB: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const client = await getAuthenticatedClient();\n const data = await client.post<CompareResponse>(\"/compare\", {\n scan_a_id: scanA,\n scan_b_id: scanB,\n });\n\n if (format === \"json\") return JSON.stringify(data, null, 2);\n\n const summary = [\n `Scan A ${data.scan_a.target_url}`,\n ` ${riskColor(data.scan_a.risk_level || \"\")(data.scan_a.risk_level || \"—\")} ${scoreBold(data.scan_a.overall_score)}`,\n `Scan B ${data.scan_b.target_url}`,\n ` ${riskColor(data.scan_b.risk_level || \"\")(data.scan_b.risk_level || \"—\")} ${scoreBold(data.scan_b.overall_score)}`,\n `Delta ${data.score_delta > 0 ? \"+\" : \"\"}${data.score_delta}`,\n data.summary,\n ].join(\"\\n\");\n\n let body = panel(summary, { title: \"Compare\" });\n\n if (data.factor_changes?.length) {\n const rows = data.factor_changes.map((f) => [f.name.replace(/_/g, \" \"), String(f.delta)]);\n body += \"\\n\\n\" + createTable([\"Factor\", \"Delta\"], rows);\n }\n\n return body;\n}\n","import { Command } from \"commander\";\nimport { cwd } from \"node:process\";\nimport { VERSION } from \"../types/brand.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runAuthLogin, runAuthLogout } from \"../commands/auth.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand, runScanGetCommand } from \"../commands/scans.js\";\nimport { runStatusCommand } from \"../commands/status.js\";\nimport { runConfigGet, runConfigSet, runConfigList } from \"../commands/config.js\";\nimport { handleCommandError, exitWith } from \"./exit.js\";\nimport type { RiskLevel } from \"../lib/risk.js\";\nimport type { OutputFormat } from \"../lib/output.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\n\nexport function buildProgram(): Command {\n const program = new Command(\"fuzzi\")\n .name(\"fuzzi\")\n .description(\"Fuzzi security scanner CLI — interactive shell and scriptable commands\")\n .version(VERSION);\n\n const auth = program.command(\"auth\").description(\"Authentication\");\n\n auth\n .command(\"login\")\n .description(\"Sign in via browser (default) or API key\")\n .option(\"--browser\", \"Sign in via browser (default when interactive)\")\n .option(\"--api-key <key>\", \"Paste an API key (fz_live_...)\")\n .action(async (opts) => {\n try {\n const useApiKey = !!opts.apiKey;\n console.log(\n await runAuthLogin({\n apiKey: opts.apiKey,\n interactive: !opts.apiKey,\n browser: !useApiKey,\n apiKeyOnly: useApiKey,\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n auth.command(\"logout\").description(\"Clear stored credentials\").action(async () => {\n console.log(await runAuthLogout());\n });\n\n auth.command(\"status\").description(\"Show auth status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"scan [url]\")\n .description(\"Scan a URL (waits for completion by default)\")\n .option(\"-t, --title <title>\", \"Scan title\")\n .option(\"-e, --env <env>\", \"production|staging|development\")\n .option(\"-w, --wait\", \"Poll until scan completes (default)\")\n .option(\"--no-wait\", \"Return immediately with scan ID\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .option(\"--fail-on <level>\", \"Exit 1 if risk >= level (low|medium|high|critical)\")\n .option(\"--fail-threshold <n>\", \"Exit 1 if risk_score >= threshold (0.0-1.0)\", parseFloat)\n .action(async (urlArg, opts) => {\n try {\n const project = await loadProjectConfig(cwd());\n const url = urlArg || project?.scan?.url;\n if (!url) {\n console.error(\"Usage: fuzzi scan <url>\");\n exitWith(2);\n }\n const client = await getAuthenticatedClient();\n const result = await runScanCommand(client, {\n url,\n wait: opts.wait,\n noWait: opts.noWait,\n format: opts.format as OutputFormat,\n environment: opts.env,\n title: opts.title,\n failOn: opts.failOn as RiskLevel | undefined,\n failThreshold: opts.failThreshold,\n });\n console.log(result.output);\n exitWith(result.exitCode);\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const scans = program.command(\"scans\").description(\"Browse scans\");\n\n scans\n .command(\"list\")\n .description(\"List recent scans\")\n .option(\"--status <status>\", \"pending|running|completed|failed\")\n .option(\"--risk-level <level>\", \"low|medium|high|critical\")\n .option(\"--limit <n>\", \"Max results\", \"20\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(\n await runScansListCommand(client, opts.format as OutputFormat, {\n status: opts.status,\n riskLevel: opts.riskLevel,\n limit: parseInt(opts.limit, 10),\n }),\n );\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n scans\n .command(\"get <scan-id>\")\n .description(\"Get scan details\")\n .option(\"-f, --format <format>\", \"table|json|markdown\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runScanGetCommand(client, scanId, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"report <scan-id>\")\n .description(\"Download a scan report\")\n .requiredOption(\"--format <format>\", \"pdf|csv|json\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .action(async (scanId, opts) => {\n try {\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n console.log(await runReportCommand(client, scanId, opts.format, opts.output));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"whatif <scan-id>\")\n .description(\"Simulate factor overrides\")\n .option(\"--set <pair>\", \"dimension=value (repeatable)\", (v, prev: string[]) => [...prev, v], [])\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanId, opts) => {\n try {\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n const overrides: Record<string, number> = {};\n for (const pair of opts.set as string[]) {\n const [k, val] = pair.split(\"=\");\n if (k && val) overrides[k] = parseFloat(val);\n }\n console.log(await runWhatIfCommand(scanId, overrides, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n program\n .command(\"compare <scan-a> <scan-b>\")\n .description(\"Compare two scans\")\n .option(\"-f, --format <format>\", \"table|json\", \"table\")\n .action(async (scanA, scanB, opts) => {\n try {\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n console.log(await runCompareCommand(scanA, scanB, opts.format as OutputFormat));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n const config = program.command(\"config\").description(\"CLI configuration (~/.fuzzi/config)\");\n\n config.command(\"list\").action(async () => console.log(await runConfigList()));\n config.command(\"get [key]\").action(async (key) => console.log(await runConfigGet(key)));\n config\n .command(\"set <key> <value>\")\n .action(async (key, value) => console.log(await runConfigSet(key, value)));\n\n program.command(\"status\").description(\"Show account status\").action(async () => {\n try {\n const client = await getAuthenticatedClient();\n console.log(await runStatusCommand(client));\n } catch (e) {\n handleCommandError(e);\n }\n });\n\n return program;\n}\n","import { password, input, confirm } from \"@inquirer/prompts\";\nimport { saveCredentials, clearCredentials } from \"../lib/credentials.js\";\nimport { ApiError, FuzziApiClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { isValidApiKeyFormat, maskApiKey } from \"../lib/credentials.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted } from \"../terminal/theme.js\";\nimport { runBrowserLogin } from \"../lib/browser-auth.js\";\nimport { SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\n\nexport interface AuthLoginOptions {\n apiKey?: string;\n interactive?: boolean;\n browser?: boolean;\n apiKeyOnly?: boolean;\n}\n\nexport async function runAuthLogin(opts: AuthLoginOptions = {}): Promise<string> {\n if (opts.browser || (opts.interactive !== false && !opts.apiKey && !opts.apiKeyOnly)) {\n try {\n const result = await runBrowserLogin();\n return success(result.message);\n } catch (e) {\n if (opts.browser) throw e;\n if (opts.apiKeyOnly) throw e;\n // fall through to API key on optional browser failure when explicitly api-key path\n }\n }\n\n return runApiKeyLogin(opts);\n}\n\nexport async function runApiKeyLogin(opts: AuthLoginOptions = {}): Promise<string> {\n const config = await loadConfig();\n const client = new FuzziApiClient(config.api_url);\n\n let apiKey = opts.apiKey?.trim();\n\n if (!apiKey) {\n if (opts.interactive === false) {\n throw new ApiError(\n \"No API key provided. Run fuzzi auth login or sign in via browser.\",\n 401,\n \"missing_key\",\n undefined,\n 2,\n );\n }\n apiKey = await password({\n message: \"Paste your API key (fz_live_...):\",\n mask: \"•\",\n validate: (v) => {\n if (!v.trim()) return \"API key is required\";\n if (!isValidApiKeyFormat(v)) return \"Key must start with fz_live_\";\n return true;\n },\n });\n }\n\n apiKey = apiKey.trim();\n if (!isValidApiKeyFormat(apiKey)) {\n throw new ApiError(\n `Invalid API key format. Generate a new one at ${SETTINGS_API_KEYS_URL}`,\n 401,\n \"invalid_key_format\",\n undefined,\n 2,\n );\n }\n\n client.setToken(apiKey);\n const valid = await client.validateToken();\n if (!valid) {\n throw new ApiError(\n `Invalid API key. Generate a new one at ${SETTINGS_API_KEYS_URL}`,\n 401,\n \"invalid_token\",\n undefined,\n 2,\n );\n }\n\n const profile = await client.get<UserProfile>(\"/me\");\n await saveCredentials({\n api_key: apiKey,\n auth_method: \"api_key\",\n key_prefix: profile.key_prefix || maskApiKey(apiKey),\n key_expires_at: profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return success(`Authenticated as ${name}`);\n}\n\nexport async function runAuthLogout(): Promise<string> {\n await clearCredentials();\n return muted(\"You are now logged out.\");\n}\n\nexport async function promptNewKeyName(): Promise<string> {\n return input({\n message: \"Key name:\",\n validate: (v) => (v.trim().length > 0 ? true : \"Name is required\"),\n });\n}\n\nexport async function confirmBrowserLogin(): Promise<boolean> {\n return confirm({\n message: \"Open browser to sign in?\",\n default: true,\n });\n}\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { exec } from \"node:child_process\";\nimport { loadConfig } from \"./config.js\";\nimport { saveCredentials, maskApiKey } from \"./credentials.js\";\nimport { FuzziApiClient, ApiError } from \"./api-client.js\";\nimport { APP_ORIGIN } from \"../types/brand.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"./logger.js\";\n\nconst TIMEOUT_MS = 5 * 60 * 1000;\n\nexport interface BrowserLoginResult {\n message: string;\n profile: UserProfile;\n}\n\ninterface HandoffResponse {\n api_key: string;\n prefix?: string;\n expires_at?: string | null;\n}\n\nfunction generateState(): string {\n return randomBytes(24).toString(\"base64url\");\n}\n\nfunction openBrowser(url: string): void {\n const platform = process.platform;\n const cmd =\n platform === \"darwin\" ? `open ${JSON.stringify(url)}`\n : platform === \"win32\" ? `start \"\" ${JSON.stringify(url)}`\n : `xdg-open ${JSON.stringify(url)}`;\n exec(cmd, (err) => {\n if (err) log.warn(\"could not open browser automatically\", err.message);\n });\n}\n\nfunction apiOrigin(apiUrl: string): string {\n return apiUrl.replace(/\\/api\\/?$/, \"\") || APP_ORIGIN;\n}\n\nexport async function runBrowserLogin(): Promise<BrowserLoginResult> {\n const config = await loadConfig();\n const state = generateState();\n\n const handoffToken = await new Promise<string>((resolve, reject) => {\n const server = createServer((req, res) => {\n try {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const url = new URL(req.url ?? \"/\", `http://127.0.0.1:${port}`);\n\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end();\n return;\n }\n\n const token = url.searchParams.get(\"token\");\n const returnedState = url.searchParams.get(\"state\");\n if (!token || returnedState !== state) {\n res.writeHead(400);\n res.end(\"Invalid callback\");\n reject(new ApiError(\"Invalid sign-in callback.\", 400, \"invalid_callback\", undefined, 2));\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(`<!DOCTYPE html><html><body style=\"font-family:system-ui;text-align:center;padding:48px\">\n <h1>Signed in to Fuzzi CLI</h1><p>Return to your terminal.</p>\n <script>setTimeout(()=>window.close(),1200)</script></body></html>`);\n server.close();\n resolve(token);\n } catch (e) {\n server.close();\n reject(e);\n }\n });\n\n const timer = setTimeout(() => {\n server.close();\n reject(new ApiError(\"Sign-in timed out after 5 minutes.\", 408, \"auth_timeout\", undefined, 2));\n }, TIMEOUT_MS);\n\n server.listen(0, \"127.0.0.1\", () => {\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n const loginUrl = `${apiOrigin(config.api_url)}/cli-auth?state=${encodeURIComponent(state)}&callback_port=${port}`;\n openBrowser(loginUrl);\n log.debug(\"browser auth\", loginUrl);\n });\n\n server.on(\"error\", (e) => {\n clearTimeout(timer);\n reject(e);\n });\n });\n\n const client = new FuzziApiClient(config.api_url);\n const handoff = await client.post<HandoffResponse>(\"/cli/handoff\", {\n handoff_token: handoffToken,\n state,\n });\n\n if (!handoff.api_key) {\n throw new ApiError(\"Sign-in failed: no API key returned.\", 500, \"handoff_failed\", undefined, 2);\n }\n\n client.setToken(handoff.api_key);\n const profile = await client.get<UserProfile>(\"/me\");\n\n await saveCredentials({\n api_key: handoff.api_key,\n auth_method: \"api_key\",\n key_prefix: handoff.prefix || profile.key_prefix || maskApiKey(handoff.api_key),\n key_expires_at: handoff.expires_at || profile.key_expires_at || undefined,\n email: profile.email,\n full_name: profile.full_name || undefined,\n saved_at: new Date().toISOString(),\n });\n\n const name = profile.full_name || profile.email;\n return { message: `Signed in as ${name}`, profile };\n}\n","import { riskColor, accent, muted, bold, scoreBold, warn } from \"../terminal/theme.js\";\nimport { createTable } from \"../terminal/table.js\";\nimport { formatTimestamp, hostnameFromUrl, truncate } from \"../terminal/strings.js\";\nimport { panel, divider } from \"../terminal/layout.js\";\nimport type { ScanDetail, ScanSummary } from \"../types/api.js\";\n\nexport type OutputFormat = \"table\" | \"json\" | \"markdown\";\n\nexport function formatScanDate(scan: ScanDetail | ScanSummary): string {\n return formatTimestamp(\"created_at\" in scan ? scan.created_at : undefined);\n}\n\nexport function renderScanResult(scan: ScanDetail, format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(buildScanJson(scan), null, 2);\n if (format === \"markdown\") return renderScanMarkdown(scan);\n return renderScanTable(scan);\n}\n\nfunction buildScanJson(scan: ScanDetail) {\n const fr = scan.fuzzy_result;\n return {\n scan: {\n id: scan.id,\n target_url: scan.target_url,\n status: scan.status,\n risk_level: fr?.risk_level ?? null,\n risk_score: fr?.risk_score ?? null,\n overall_score: fr?.overall_score ?? null,\n },\n factors: scan.factors ?? [],\n recommendations: scan.recommendations ?? [],\n };\n}\n\nfunction levelIndicator(level: string): string {\n if (level === \"LOW\") return muted(\"ok\");\n return warn(\"!\");\n}\n\nexport function renderScanTable(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const rc = riskColor(fr?.risk_level);\n const lines: string[] = [];\n\n lines.push(panel([\n bold(scan.target_url),\n fr ? `${rc(\"Risk\")} ${rc(fr.risk_level)} ${muted(\"Score\")} ${scoreBold(fr.overall_score)}/100` : \"\",\n `${muted(\"Date\")} ${formatScanDate(scan)}`,\n scan.status === \"completed_inconclusive\" ? warn(\"Inconclusive — indicative only\") : \"\",\n ].filter(Boolean).join(\"\\n\"), { title: \"Scan result\" }));\n\n if (scan.factors?.length) {\n const rows = [...scan.factors]\n .sort((a, b) => a.score_100 - b.score_100)\n .map((f) => {\n const inc = f.details?.inconclusive;\n return [\n f.name.replace(/_/g, \" \"),\n inc ? muted(\"—\") : `${f.score_100}/100`,\n inc ? muted(\"n/a\") : `${riskColor(f.linguistic_value)(f.linguistic_value)} ${levelIndicator(f.linguistic_value)}`,\n ];\n });\n lines.push(\"\", createTable([\"Dimension\", \"Score\", \"Level\"], rows));\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"\", accent(\"Findings\"));\n scan.recommendations.forEach((r, i) => {\n lines.push(` ${muted(String(i + 1).padStart(2))} ${riskColor(r.severity.toUpperCase())(`[${r.severity.toUpperCase()}]`)} ${r.title}`);\n });\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nexport function renderScanMarkdown(scan: ScanDetail): string {\n const fr = scan.fuzzy_result;\n const host = hostnameFromUrl(scan.target_url);\n const lines: string[] = [`## Fuzzi Security Scan: ${host}`, \"\"];\n\n if (fr) lines.push(`**Risk Level:** ${fr.risk_level} (${fr.overall_score}/100)`, \"\");\n\n if (scan.factors?.length) {\n lines.push(\"| Dimension | Score | Level |\", \"|-----------|-------|-------|\");\n for (const f of scan.factors) {\n lines.push(`| ${f.name.replace(/_/g, \" \")} | ${f.score_100}/100 | ${f.linguistic_value} |`);\n }\n lines.push(\"\");\n }\n\n if (scan.recommendations?.length) {\n lines.push(\"### Findings\");\n scan.recommendations.forEach((r, i) => {\n lines.push(`${i + 1}. [${r.severity.toUpperCase()}] ${r.title}`);\n });\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderScansList(scans: ScanSummary[], format: OutputFormat): string {\n if (format === \"json\") return JSON.stringify(scans, null, 2);\n if (format === \"markdown\") {\n if (!scans.length) return \"No scans found.\";\n const lines = [\"| URL | Status | Risk | Score | Date |\", \"|-----|--------|------|-------|------|\"];\n for (const s of scans) {\n lines.push(`| ${s.target_url} | ${s.status} | ${s.risk_level || \"—\"} | ${s.overall_score ?? \"—\"} | ${formatScanDate(s)} |`);\n }\n return lines.join(\"\\n\");\n }\n if (!scans.length) return muted(\"No scans found.\");\n\n const rows = scans.map((s) => [\n truncate(s.target_url, 40),\n s.status === \"completed_inconclusive\" ? warn(\"inconcl.\") : s.status,\n s.risk_level ? riskColor(s.risk_level)(s.risk_level) : muted(\"—\"),\n s.overall_score != null ? scoreBold(s.overall_score) : muted(\"—\"),\n muted(formatScanDate(s)),\n ]);\n return createTable([\"URL\", \"Status\", \"Risk\", \"Score\", \"Date\"], rows);\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScanResult } from \"../lib/output.js\";\nimport { ApiError, FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanCreateResponse, ScanDetail } from \"../types/api.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { success, muted } from \"../terminal/theme.js\";\nimport { validateUrl } from \"../lib/errors.js\";\nimport { riskMeetsThreshold, type RiskLevel } from \"../lib/risk.js\";\nimport { loadProjectConfig } from \"../lib/project-config.js\";\nimport { createProgress } from \"../terminal/progress.js\";\nimport { hostnameFromUrl } from \"../terminal/strings.js\";\nimport { withRetry } from \"../lib/retry.js\";\nimport { log } from \"../lib/logger.js\";\nimport { cwd } from \"node:process\";\n\nexport interface ScanCommandOptions {\n url: string;\n format?: OutputFormat;\n wait?: boolean;\n noWait?: boolean;\n environment?: string;\n title?: string;\n failOn?: RiskLevel;\n failThreshold?: number;\n onProgress?: (message: string) => void;\n streamProgress?: boolean;\n}\n\nexport interface ScanCommandResult {\n output: string;\n exitCode: 0 | 1 | 2;\n scan?: ScanDetail;\n}\n\nconst TERMINAL_STATUSES = new Set([\"completed\", \"completed_inconclusive\", \"failed\"]);\nconst POLL_INTERVAL_MS = 3000;\n\nexport async function pollScan(\n client: FuzziApiClient,\n scanId: string,\n onTick?: (elapsed: number, status: string) => void,\n maxWaitMs = 300_000,\n): Promise<ScanDetail> {\n const start = Date.now();\n let last = \"pending\";\n while (Date.now() - start < maxWaitMs) {\n const detail = await withRetry(() => client.get<ScanDetail>(`/scan/${scanId}`));\n last = detail.status;\n onTick?.(Math.floor((Date.now() - start) / 1000), last);\n if (TERMINAL_STATUSES.has(detail.status)) {\n if (detail.status === \"failed\") {\n throw new ApiError(\n `Scan failed: ${detail.inconclusive_message || detail.inconclusive_reason || \"unknown error\"}`,\n 500,\n \"scan_failed\",\n detail,\n 2,\n );\n }\n return detail;\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n throw new ApiError(`Scan timed out after ${maxWaitMs / 1000}s (last status: ${last})`, 408, \"scan_timeout\", undefined, 2);\n}\n\nfunction resolveFormat(format?: OutputFormat, projectFormat?: OutputFormat): OutputFormat {\n return format || projectFormat || \"table\";\n}\n\nfunction computeExitCode(scan: ScanDetail, opts: ScanCommandOptions): 0 | 1 | 2 {\n const fr = scan.fuzzy_result;\n if (!fr) return 0;\n if (opts.failThreshold != null && fr.risk_score >= opts.failThreshold) return 1;\n if (opts.failOn && riskMeetsThreshold(fr.risk_level, opts.failOn)) return 1;\n return 0;\n}\n\nexport async function runScanCommand(\n client: FuzziApiClient,\n opts: ScanCommandOptions,\n): Promise<ScanCommandResult> {\n const urlError = validateUrl(opts.url);\n if (urlError) throw new ApiError(urlError, 400, \"invalid_url\", undefined, 2);\n\n const projectConfig = await loadProjectConfig(cwd());\n const config = await loadConfig();\n const format = resolveFormat(opts.format, projectConfig?.output?.format || config.default_format);\n const env = opts.environment || projectConfig?.scan?.environment || config.default_env || \"production\";\n const failOn = opts.failOn || (projectConfig?.scan?.fail_on as RiskLevel | undefined);\n const shouldWait = opts.noWait ? false : opts.wait !== false;\n\n const body: Record<string, string> = { url: opts.url, environment: env };\n if (opts.title || projectConfig?.scan?.title) {\n body.title = opts.title || projectConfig?.scan?.title || \"\";\n }\n\n log.debug(\"creating scan\", { url: opts.url, env });\n const created = await withRetry(() => client.post<ScanCreateResponse>(\"/scan\", body));\n\n if (!shouldWait) {\n const output =\n format === \"json\"\n ? JSON.stringify(created, null, 2)\n : [success(\"Scan started\"), muted(`ID: ${created.scan_id}`), muted(created.message)].join(\"\\n\");\n return { output, exitCode: 0 };\n }\n\n const host = hostnameFromUrl(opts.url);\n const progress = opts.onProgress\n ? { update: opts.onProgress, stop: () => {}, succeed: () => {}, fail: () => {} }\n : createProgress(`Scanning ${host}...`, opts.streamProgress);\n\n const detail = await pollScan(client, created.scan_id, (sec, status) => {\n progress.update(`Scanning ${host}... (${sec}s) ${muted(status)}`);\n });\n\n progress.succeed(`Scan complete — ${host}`);\n\n const exitCode = computeExitCode(detail, { ...opts, failOn });\n return { output: renderScanResult(detail, format), exitCode, scan: detail };\n}\n","import { ApiError } from \"./api-client.js\";\nimport { APP_HOST } from \"../types/brand.js\";\n\nexport type ExitCode = 0 | 1 | 2;\n\nexport function formatApiError(err: unknown): string {\n if (err instanceof ApiError) {\n return err.message;\n }\n if (err instanceof Error) {\n if (err.message.includes(\"fetch failed\") || err.message.includes(\"ECONNREFUSED\")) {\n return `Could not connect to ${APP_HOST}. Check your internet connection or try again later.`;\n }\n return `An error occurred: ${err.message}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n }\n return `An error occurred: ${String(err)}. Please report this at https://github.com/fuzzi-cli/fuzzi-cli/issues`;\n}\n\nexport function getExitCode(err: unknown): ExitCode {\n if (err instanceof ApiError && err.exitCode !== undefined) {\n return err.exitCode as ExitCode;\n }\n return 2;\n}\n\nexport function validateUrl(url: string): string | null {\n try {\n const parsed = new URL(url);\n if (![\"http:\", \"https:\"].includes(parsed.protocol)) {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n return null;\n } catch {\n return \"Invalid URL. Please provide a valid URL starting with http:// or https://\";\n }\n}\n","export type RiskLevel = \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\";\n\nconst RISK_ORDER: Record<RiskLevel, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function normalizeRiskLevel(level: string | null | undefined): RiskLevel | null {\n if (!level) return null;\n const upper = level.toUpperCase() as RiskLevel;\n return upper in RISK_ORDER ? upper : null;\n}\n\nexport function riskMeetsThreshold(\n actual: string | null | undefined,\n threshold: RiskLevel,\n): boolean {\n const a = normalizeRiskLevel(actual);\n const t = normalizeRiskLevel(threshold);\n if (!a || !t) return false;\n return RISK_ORDER[a] >= RISK_ORDER[t];\n}\n\nexport function parseRiskLevel(value: string): RiskLevel | null {\n return normalizeRiskLevel(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport interface ProjectConfig {\n scan?: {\n url?: string;\n environment?: \"production\" | \"staging\" | \"development\";\n fail_on?: string;\n title?: string;\n };\n output?: {\n format?: \"table\" | \"json\" | \"markdown\";\n };\n}\n\nfunction parseTomlSimple(raw: string): ProjectConfig {\n const config: ProjectConfig = { scan: {}, output: {} };\n let section = \"\";\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const sectionMatch = trimmed.match(/^\\[([^\\]]+)\\]$/);\n if (sectionMatch) {\n section = sectionMatch[1];\n continue;\n }\n const kv = trimmed.match(/^(\\w+)\\s*=\\s*\"?([^\"]+)\"?$/);\n if (!kv) continue;\n const [, key, value] = kv;\n if (section === \"scan\" || section === \"scan.scan\") {\n config.scan ??= {};\n if (key === \"url\") config.scan.url = value;\n else if (key === \"environment\") config.scan.environment = value as \"production\" | \"staging\" | \"development\";\n else if (key === \"fail_on\") config.scan.fail_on = value;\n else if (key === \"title\") config.scan.title = value;\n } else if (section === \"output\") {\n config.output ??= {};\n if (key === \"format\") config.output.format = value as \"table\" | \"json\" | \"markdown\";\n }\n }\n return config;\n}\n\nexport async function loadProjectConfig(cwd: string): Promise<ProjectConfig | null> {\n const fuzzirc = join(cwd, \".fuzzirc\");\n const fuzzitoml = join(cwd, \"fuzzi.toml\");\n\n if (existsSync(fuzzirc)) {\n try {\n const raw = await readFile(fuzzirc, \"utf8\");\n return JSON.parse(raw) as ProjectConfig;\n } catch {\n return null;\n }\n }\n\n if (existsSync(fuzzitoml)) {\n try {\n const raw = await readFile(fuzzitoml, \"utf8\");\n return parseTomlSimple(raw);\n } catch {\n return null;\n }\n }\n\n return null;\n}\n","import ora, { type Ora } from \"ora\";\nimport { muted } from \"./theme.js\";\nimport { getCapabilities } from \"./capabilities.js\";\n\nexport interface ProgressHandle {\n update(message: string): void;\n succeed(message?: string): void;\n fail(message?: string): void;\n stop(): void;\n}\n\nexport function createProgress(label: string, stream = false): ProgressHandle {\n if (!getCapabilities().interactive) {\n return {\n update: () => {},\n succeed: () => {},\n fail: () => {},\n stop: () => {},\n };\n }\n\n if (stream) {\n let last = \"\";\n return {\n update(message: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = message;\n process.stdout.write(muted(message));\n },\n succeed(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n fail(message?: string) {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n if (message) process.stdout.write(muted(message) + \"\\n\");\n last = \"\";\n },\n stop() {\n if (last) process.stdout.write(\"\\r\\x1b[K\");\n last = \"\";\n },\n };\n }\n\n let spinner: Ora | null = ora({ text: label, color: \"cyan\", discardStdin: false }).start();\n return {\n update(message: string) {\n if (spinner) spinner.text = message;\n },\n succeed(message?: string) {\n if (spinner) {\n spinner.succeed(message);\n spinner = null;\n }\n },\n fail(message?: string) {\n if (spinner) {\n spinner.fail(message);\n spinner = null;\n }\n },\n stop() {\n if (spinner) {\n spinner.stop();\n spinner = null;\n }\n },\n };\n}\n\nexport async function withSteps<T>(\n steps: Array<{ title: string; run: () => Promise<T> }>,\n): Promise<T> {\n let last: T | undefined;\n for (const step of steps) {\n const p = createProgress(step.title);\n try {\n last = await step.run();\n p.succeed(step.title);\n } catch (e) {\n p.fail(step.title);\n throw e;\n }\n }\n return last as T;\n}\n","import { log } from \"./logger.js\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n baseDelayMs?: number;\n retryOn?: (error: unknown) => boolean;\n}\n\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions = {}): Promise<T> {\n const max = opts.maxAttempts ?? 3;\n const base = opts.baseDelayMs ?? 500;\n const retryOn = opts.retryOn ?? ((e: unknown) => {\n const err = e as { status?: number };\n return err.status === 429 || err.status === 502 || err.status === 503;\n });\n\n let last: unknown;\n for (let attempt = 1; attempt <= max; attempt++) {\n try {\n return await fn();\n } catch (e) {\n last = e;\n if (attempt >= max || !retryOn(e)) throw e;\n const delay = base * Math.pow(2, attempt - 1);\n log.debug(`retry ${attempt}/${max} in ${delay}ms`);\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n throw last;\n}\n","import type { OutputFormat } from \"../lib/output.js\";\nimport { renderScansList } from \"../lib/output.js\";\nimport { FuzziApiClient } from \"../lib/api-client.js\";\nimport type { ScanDetail } from \"../types/api.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface ScansListFilters {\n status?: string;\n riskLevel?: string;\n limit?: number;\n}\n\nexport async function runScansListCommand(\n client: FuzziApiClient,\n format: OutputFormat = \"table\",\n filters?: ScansListFilters,\n): Promise<string> {\n const params = new URLSearchParams({ page: \"1\", page_size: String(filters?.limit || 20) });\n if (filters?.status) params.set(\"status\", filters.status);\n if (filters?.riskLevel) params.set(\"risk_level\", filters.riskLevel);\n\n const data = await client.get<{ results: import(\"../types/api.js\").ScanSummary[] }>(\n `/scans?${params.toString()}`,\n );\n return renderScansList(data.results || [], format);\n}\n\nexport async function runScanGetCommand(\n client: FuzziApiClient,\n scanId: string,\n format: OutputFormat = \"table\",\n): Promise<string> {\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n return renderScanResult(detail, format);\n}\n","import { FuzziApiClient } from \"../lib/api-client.js\";\nimport { loadConfig } from \"../lib/config.js\";\nimport { loadCredentials, maskApiKey } from \"../lib/credentials.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { panel, keyValue, divider } from \"../terminal/layout.js\";\nimport { muted } from \"../terminal/theme.js\";\n\nfunction daysUntil(dateStr: string): number {\n const diff = new Date(dateStr).getTime() - Date.now();\n return Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)));\n}\n\nexport async function runRateLimitStatus(client: FuzziApiClient): Promise<string | null> {\n try {\n const data = await client.get<{ limit?: number; remaining?: number; reset?: string }>(\"/rate-limit\");\n if (data.limit != null) {\n return `${data.remaining ?? \"?\"}/${data.limit} remaining`;\n }\n } catch {\n /* optional endpoint */\n }\n return null;\n}\n\nexport async function runStatusCommand(client: FuzziApiClient): Promise<string> {\n const creds = await loadCredentials();\n const profile = await client.get<UserProfile>(\"/me\");\n const keyExpiry = creds?.key_expires_at || profile.key_expires_at;\n const config = await loadConfig();\n const rate = await runRateLimitStatus(client);\n\n const rows: Array<[string, string]> = [\n [\"Name\", profile.full_name || profile.email.split(\"@\")[0]],\n [\"Email\", profile.email],\n [\"Organization\", profile.organization || muted(\"—\")],\n [\"Role\", profile.role],\n [\"Auth\", `API Key (${creds ? maskApiKey(creds.api_key) : \"—\"})`],\n ];\n\n if (keyExpiry) {\n const days = daysUntil(keyExpiry);\n rows.push([\"Key expires\", `${keyExpiry.slice(0, 10)} (${days}d remaining)`]);\n } else {\n rows.push([\"Key expires\", muted(\"No expiry\")]);\n }\n\n rows.push([\"API\", config.api_url]);\n if (rate) rows.push([\"Rate limit\", rate]);\n\n return [panel(keyValue(rows), { title: \"Account\" }), \"\", divider(), muted(\"Use /keys to manage API keys\")].join(\"\\n\");\n}\n\nexport { formatApiError } from \"../lib/errors.js\";\n","import { loadConfig, setConfigValue, getConfigValue, listConfigEntries } from \"../lib/config.js\";\nimport { accent, muted } from \"../lib/theme.js\";\n\nexport async function runConfigList(): Promise<string> {\n const entries = await listConfigEntries();\n const lines = Object.entries(entries).map(([k, v]) => ` ${k} = ${v}`);\n return lines.length ? [accent(\"Config (~/.fuzzi/config)\"), ...lines].join(\"\\n\") : muted(\"No config set.\");\n}\n\nexport async function runConfigGet(key?: string): Promise<string> {\n if (!key) return runConfigList();\n const value = await getConfigValue(key);\n if (value === undefined) return muted(`Config key not set: ${key}`);\n return value;\n}\n\nexport async function runConfigSet(key: string, value: string): Promise<string> {\n const allowed = [\"api_url\", \"default_env\", \"default_format\"];\n if (!allowed.includes(key)) {\n return muted(`Unknown config key: ${key}. Supported: ${allowed.join(\", \")}`);\n }\n await setConfigValue(key, value);\n return accent(\"Config updated.\");\n}\n\nexport async function runConfigShowApiUrl(): Promise<string> {\n const config = await loadConfig();\n return config.api_url;\n}\n","import { formatApiError, getExitCode } from \"../lib/errors.js\";\n\nexport function handleCommandError(e: unknown): never {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n}\n\nexport function exitWith(code: 0 | 1 | 2): never {\n process.exit(code);\n}\n","import * as readline from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { fetchHomeData, renderHomeScreen } from \"./home-screen.js\";\nimport { dispatchSlashCommand, normalizeInput } from \"./slash-commands.js\";\nimport { accent, muted, dim } from \"../terminal/theme.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { cwd } from \"node:process\";\nimport { appendHistory, loadHistory } from \"./session.js\";\nimport { buildCompleter } from \"./completer.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\nimport { getCapabilities } from \"../terminal/capabilities.js\";\nimport { statusBar } from \"../terminal/layout.js\";\nimport { isDebugMode } from \"../lib/logger.js\";\n\nexport async function runPromptLoop(initialProfile: UserProfile | null): Promise<void> {\n let profile = initialProfile;\n const workDir = cwd();\n const history = await loadHistory();\n\n const refresh = async () => {\n if (getCapabilities().interactive) {\n process.stdout.write(\"\\x1b[2J\\x1b[H\");\n }\n const data = await fetchHomeData(profile, workDir);\n console.log(renderHomeScreen(data));\n console.log(statusBar([\n profile ? muted(profile.email) : muted(\"guest\"),\n dim(workDir),\n isDebugMode() ? muted(\"debug\") : null,\n ].filter(Boolean) as string[]));\n console.log(\"\");\n };\n\n await refresh();\n\n const rl = readline.createInterface({\n input,\n output,\n terminal: true,\n completer: buildCompleter(SLASH_COMMANDS, history),\n historySize: 300,\n });\n\n rl.on(\"SIGINT\", () => {\n console.log(muted(\"\\nGoodbye!\"));\n rl.close();\n process.exit(0);\n });\n\n const prompt = () => process.stdout.write(accent(\"› \"));\n\n prompt();\n\n for await (const line of rl) {\n await appendHistory(line);\n history.push(line.trim());\n\n const sink = {\n write: (text: string) => console.log(text),\n error: (text: string) => console.error(text),\n clearLine: () => process.stdout.write(\"\\r\\x1b[K\"),\n };\n\n const normalized = normalizeInput(line);\n const result = await dispatchSlashCommand(normalized, {\n cwd: workDir,\n profile,\n sink,\n refresh,\n });\n\n if (result.profile) profile = result.profile;\n if (result.exit) {\n console.log(muted(\"Goodbye!\"));\n rl.close();\n break;\n }\n if (result.redraw) await refresh();\n\n prompt();\n }\n}\n","import { homedir } from \"node:os\";\nimport { renderFuzziMark } from \"./ascii-mark.js\";\nimport { VERSION } from \"../types/brand.js\";\nimport { accent, accentBold, muted, italic, info } from \"../terminal/theme.js\";\nimport { splitHomePanel, centerInColumn } from \"../terminal/layout.js\";\nimport { contentWidth } from \"../terminal/width.js\";\nimport { readAsset } from \"../lib/assets.js\";\nimport type { ChangelogEntry, UserProfile } from \"../types/api.js\";\n\nexport interface HomeScreenData {\n profile: UserProfile | null;\n cwd: string;\n changelog: ChangelogEntry[];\n}\n\nexport async function fetchHomeData(profile: UserProfile | null, cwd: string): Promise<HomeScreenData> {\n let changelog: ChangelogEntry[] = [];\n try {\n changelog = JSON.parse(await readAsset(\"changelog.json\")) as ChangelogEntry[];\n } catch {\n changelog = [];\n }\n return { profile, cwd, changelog };\n}\n\nfunction isHomeDir(dir: string): boolean {\n return dir === homedir() || dir === homedir().replace(/\\/$/, \"\");\n}\n\nfunction renderLeftColumn(data: HomeScreenData): string {\n const colW = Math.max(28, Math.floor(contentWidth() * 0.34));\n const name = data.profile?.full_name || data.profile?.email?.split(\"@\")[0] || \"there\";\n const org = data.profile?.organization?.trim();\n const mark = centerInColumn(accent(renderFuzziMark()), colW);\n\n const lines: string[] = [];\n\n if (data.profile) {\n lines.push(\n accentBold(`Welcome back ${name}!`),\n \"\",\n mark,\n \"\",\n [accent(\"● Connected\"), muted(\"·\"), info(\"API Key auth\"), org ? muted(\"· \" + org) : \"\"]\n .filter(Boolean)\n .join(\" \"),\n muted(data.profile.email),\n data.profile.role ? muted(`Role: ${data.profile.role}`) : \"\",\n \"\",\n muted(data.cwd),\n \"\",\n accent(\"/scan\") + muted(\" <url> scan a target\"),\n accent(\"/scans\") + muted(\" browse history\"),\n accent(\"/status\") + muted(\" account info\"),\n accent(\"/keys\") + muted(\" manage keys\"),\n accent(\"/palette\") + muted(\" find commands\"),\n );\n } else {\n lines.push(\n accentBold(\"Welcome to Fuzzi!\"),\n \"\",\n mark,\n \"\",\n muted(\"Not connected\"),\n info(\"Press Enter to sign in\"),\n \"\",\n muted(data.cwd),\n \"\",\n accent(\"/auth\") + muted(\" browser sign-in\"),\n accent(\"/auth-key\") + muted(\" paste API key\"),\n accent(\"/scan\") + muted(\" <url> after login\"),\n accent(\"/help\") + muted(\" all commands\"),\n );\n }\n\n return lines.filter((l) => l !== \"\").join(\"\\n\");\n}\n\nfunction renderTipsColumn(data: HomeScreenData): string {\n const lines = [\n accentBold(\"Tips for getting started\"),\n \"\",\n `Run ${accent(\"/scan\")}${muted(\" <url>\")} to scan a site for security risks`,\n `Run ${accent(\"/palette\")} to search every available command`,\n `Run ${accent(\"/help\")} for the full command reference`,\n \"\",\n ];\n\n if (!data.profile) {\n lines.push(\n muted(\"Note: You launched without credentials.\"),\n muted(\"Press Enter at the prompt to open your browser,\"),\n muted(\"or use /auth-key to paste an API key.\"),\n \"\",\n );\n } else if (isHomeDir(data.cwd)) {\n lines.push(\n muted(\"Note: You launched fuzzi in your home directory.\"),\n muted(\"cd into a project folder first for better context,\"),\n muted(\"or pass URLs directly: /scan https://example.com\"),\n \"\",\n );\n } else {\n lines.push(\n muted(\"Note: Add a .fuzzirc in this directory to set default\"),\n muted(\"scan URL, environment, and output format for the team.\"),\n \"\",\n );\n }\n\n lines.push(\n muted(\"CI usage: \"),\n muted(\"fuzzi scan <url> --fail-on critical --format json\"),\n );\n\n return lines.join(\"\\n\");\n}\n\nfunction renderWhatsNewColumn(data: HomeScreenData): string {\n const latest = data.changelog[0];\n const lines = [accentBold(\"What's new\"), \"\"];\n\n if (latest) {\n for (const h of latest.highlights.slice(0, 4)) {\n lines.push(muted(h));\n }\n lines.push(\"\");\n lines.push(italic(muted(\"/changelog for more\")));\n } else {\n lines.push(muted(\"Stay tuned for updates.\"));\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function renderHomeScreen(data: HomeScreenData): string {\n return splitHomePanel({\n title: `Fuzzi CLI v${VERSION}`,\n left: renderLeftColumn(data),\n rightTop: renderTipsColumn(data),\n rightBottom: renderWhatsNewColumn(data),\n leftRatio: 0.36,\n });\n}\n\nexport function renderChangelog(entries: ChangelogEntry[]): string {\n if (!entries.length) return muted(\"No changelog entries.\");\n return entries\n .map((e) => {\n const lines = [\n accentBold(`v${e.version}`) + muted(` — ${e.date}`),\n ...e.highlights.map((h) => muted(` · ${h}`)),\n ];\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n","export function renderFuzziMark(): string {\n // Thick pixel shield mascot (teal when wrapped with accent())\n return [\n \" ██████████\",\n \" ██████████████\",\n \" ██ ██\",\n \" ██ ██████ ██\",\n \" ██ ██████ ██\",\n \" ██ ████ ██\",\n \" ██████████████\",\n \" ██ ██\",\n \" ██████████\",\n \" ██ ██\",\n \" ██ ██\",\n ].join(\"\\n\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { existsSync } from \"node:fs\";\n\n/** Resolve assets dir for both dev (src/) and production (dist/) layouts. */\nexport function assetsDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, \"..\", \"assets\"), // dist/lib → dist/../assets = package/assets\n join(here, \"..\", \"..\", \"assets\"), // src/lib → package/assets\n join(here, \"assets\"), // bundled flat fallback\n ];\n for (const p of candidates) {\n if (existsSync(join(p, \"changelog.json\"))) return p;\n }\n return candidates[0];\n}\n\nexport async function readAsset(name: string): Promise<string> {\n return readFile(join(assetsDir(), name), \"utf8\");\n}\n","import { confirm, input } from \"@inquirer/prompts\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport { runScanCommand } from \"../commands/scan.js\";\nimport { runScansListCommand } from \"../commands/scans.js\";\nimport { runStatusCommand, runRateLimitStatus } from \"../commands/status.js\";\nimport { runAuthLogin, runApiKeyLogin, promptNewKeyName } from \"../commands/auth.js\";\nimport { runKeysListCommand, runKeyRevoke, pickKeyForRevoke } from \"../commands/keys.js\";\nimport { runConfigSet } from \"../commands/config.js\";\nimport { formatApiError } from \"../lib/errors.js\";\nimport { readAsset } from \"../lib/assets.js\";\nimport { renderChangelog } from \"./home-screen.js\";\nimport { renderHelpScreen, renderHistoryScreen } from \"./help-screen.js\";\nimport { openCommandPalette, pickFromList } from \"./command-palette.js\";\nimport { findCommand } from \"./registry.js\";\nimport { loadHistory } from \"./session.js\";\nimport { accent, muted, success, error as errStyle } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { errorBox, successBox } from \"../terminal/banner.js\";\nimport { truncate, formatTimestamp } from \"../terminal/strings.js\";\nimport type { UserProfile, ScanSummary, ScanDetail } from \"../types/api.js\";\nimport type { OutputSink } from \"../terminal/sink.js\";\nimport { renderScanResult } from \"../lib/output.js\";\n\nexport interface SlashContext {\n cwd: string;\n profile: UserProfile | null;\n sink: OutputSink;\n refresh: () => Promise<void>;\n}\n\nexport interface SlashResult {\n exit?: boolean;\n redraw?: boolean;\n profile?: UserProfile | null;\n}\n\n/** Map bare CLI-style input to slash commands. */\nexport function normalizeInput(line: string): string {\n let t = line.trim();\n if (!t || t.startsWith(\"/\")) return t;\n\n if (t.toLowerCase().startsWith(\"fuzzi \")) t = t.slice(6).trim();\n\n const lower = t.toLowerCase();\n const aliases: Record<string, string> = {\n \"auth login\": \"/auth\",\n auth: \"/auth\",\n login: \"/auth\",\n \"auth-key\": \"/auth-key\",\n logout: \"/exit\",\n help: \"/help\",\n exit: \"/exit\",\n quit: \"/exit\",\n clear: \"/clear\",\n changelog: \"/changelog\",\n status: \"/status\",\n scans: \"/scans\",\n keys: \"/keys\",\n palette: \"/palette\",\n };\n if (aliases[lower]) return aliases[lower];\n\n if (lower.startsWith(\"scan \")) return `/scan ${t.slice(5).trim()}`;\n if (lower.startsWith(\"config set \")) {\n const parts = t.slice(11).trim().split(/\\s+/);\n if (parts.length >= 2) return `/config ${parts[0]}=${parts.slice(1).join(\" \")}`;\n }\n if (lower.startsWith(\"config \")) return `/config ${t.slice(7).trim().replace(/\\s+/, \"=\")}`;\n\n // Bare hostname → scan\n if (!t.includes(\" \") && t.includes(\".\")) return `/scan ${t}`;\n\n return t;\n}\n\nfunction normalizeScanUrl(url: string): string {\n const u = url.trim();\n if (!/^https?:\\/\\//i.test(u)) return `https://${u}`;\n return u;\n}\n\nexport async function dispatchSlashCommand(line: string, ctx: SlashContext): Promise<SlashResult> {\n const trimmed = line.trim();\n if (!trimmed) return {};\n if (trimmed === \"/exit\" || trimmed === \"/quit\") return { exit: true };\n\n const [cmd, ...rest] = trimmed.split(/\\s+/);\n const arg = rest.join(\" \").trim();\n\n if (!cmd.startsWith(\"/\")) {\n ctx.sink.write(\n errorBox(\n `Not a shell command: ${trimmed}`,\n `Use slash commands here — e.g. ${accent(\"/auth\")} not \"fuzzi auth login\"\\n${accent(\"/help\")} lists everything`,\n ),\n );\n return {};\n }\n\n if (!findCommand(cmd) && cmd.startsWith(\"/\")) {\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help or /palette\"));\n return {};\n }\n\n try {\n switch (cmd.toLowerCase()) {\n case \"/help\":\n ctx.sink.write(renderHelpScreen());\n break;\n\n case \"/palette\":\n case \"/commands\": {\n const picked = await openCommandPalette();\n if (picked) return dispatchSlashCommand(picked, ctx);\n break;\n }\n\n case \"/clear\":\n return { redraw: true };\n\n case \"/history\": {\n const hist = await loadHistory();\n ctx.sink.write(renderHistoryScreen(hist));\n break;\n }\n\n case \"/scan\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /scan <url>\"));\n break;\n }\n const client = await getAuthenticatedClient();\n const progress = createStreamProgress(ctx.sink);\n const result = await runScanCommand(client, {\n url: normalizeScanUrl(arg),\n wait: true,\n onProgress: progress.update,\n streamProgress: true,\n });\n progress.stop();\n ctx.sink.write(result.output);\n break;\n }\n\n case \"/status\": {\n const client = await getAuthenticatedClient();\n const status = await runStatusCommand(client);\n const rate = await runRateLimitStatus(client);\n ctx.sink.write(rate ? `${status}\\n\\n${muted(\"Rate limit\")} ${rate}` : status);\n break;\n }\n\n case \"/scans\":\n await runScansInteractive(ctx);\n break;\n\n case \"/keys\":\n await runKeysInteractive(ctx);\n break;\n\n case \"/config\": {\n if (!arg.includes(\"=\")) {\n ctx.sink.write(errStyle(\"Usage: /config key=value\"));\n break;\n }\n const [k, ...vParts] = arg.split(\"=\");\n ctx.sink.write(await runConfigSet(k.trim(), vParts.join(\"=\").trim()));\n break;\n }\n\n case \"/changelog\": {\n const raw = await readAsset(\"changelog.json\");\n ctx.sink.write(renderChangelog(JSON.parse(raw)));\n break;\n }\n\n case \"/compare\": {\n const [a, b] = arg.split(/\\s+/);\n if (!a || !b) {\n ctx.sink.write(errStyle(\"Usage: /compare <scan-a> <scan-b>\"));\n break;\n }\n const { runCompareCommand } = await import(\"../commands/compare.js\");\n ctx.sink.write(await runCompareCommand(a, b, \"table\"));\n break;\n }\n\n case \"/whatif\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /whatif <scan-id>\"));\n break;\n }\n const { runWhatIfCommand } = await import(\"../commands/whatif.js\");\n ctx.sink.write(await runWhatIfCommand(arg, {}, \"table\"));\n break;\n }\n\n case \"/report\": {\n if (!arg) {\n ctx.sink.write(errStyle(\"Usage: /report <scan-id>\"));\n break;\n }\n const { runReportCommand } = await import(\"../commands/report.js\");\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runReportCommand(client, arg, \"json\"));\n break;\n }\n\n case \"/login\":\n case \"/auth\": {\n ctx.sink.write(await runAuthLogin({ interactive: true, browser: true }));\n const client = await getAuthenticatedClient();\n return { profile: await client.get<UserProfile>(\"/me\"), redraw: true };\n }\n\n case \"/auth-key\": {\n ctx.sink.write(await runApiKeyLogin({ interactive: true }));\n const client = await getAuthenticatedClient();\n return { profile: await client.get<UserProfile>(\"/me\"), redraw: true };\n }\n\n default:\n ctx.sink.write(errorBox(`Unknown command: ${cmd}`, \"Type /help\"));\n }\n } catch (e) {\n ctx.sink.error(formatApiError(e));\n }\n return {};\n}\n\nfunction createStreamProgress(sink: OutputSink) {\n let last = \"\";\n return {\n update(msg: string) {\n if (last) sink.clearLine?.();\n last = msg;\n process.stdout.write(muted(msg));\n },\n stop() {\n if (last) sink.clearLine?.();\n last = \"\";\n },\n };\n}\n\nasync function runScansInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n\n while (true) {\n const list = await runScansListCommand(client, \"table\", { limit: 20 });\n const data = await client.get<{ results: ScanSummary[] }>(\"/scans?page=1&page_size=20\");\n const scans = data.results || [];\n\n if (!scans.length) {\n ctx.sink.write(emptyState(\"No scans yet\", \"Run /scan <url> to create your first scan\", \"/scan https://example.com\"));\n return;\n }\n\n ctx.sink.write(list);\n ctx.sink.write(\"\");\n\n const scanId = await pickFromList(\n \"Select a scan (Esc to go back)\",\n scans.map((s) => ({\n name: `${truncate(s.target_url, 32)} ${s.risk_level ?? s.status} ${s.overall_score ?? \"—\"} ${formatTimestamp(s.created_at)}`,\n value: s.id,\n })),\n );\n if (!scanId) return;\n\n const detail = await client.get<ScanDetail>(`/scan/${scanId}`);\n ctx.sink.write(renderScanResult(detail, \"table\"));\n\n const cont = await input({\n message: muted(\"Enter = back to list · q = exit\"),\n default: \"\",\n }).catch(() => \"q\");\n if (cont.toLowerCase() === \"q\") return;\n }\n}\n\nasync function runKeysInteractive(ctx: SlashContext): Promise<void> {\n const client = await getAuthenticatedClient();\n ctx.sink.write(await runKeysListCommand(client));\n ctx.sink.write(muted(\"\\nActions: [r] revoke [n] new key [Enter] back\"));\n\n const action = await input({ message: \"Action\", default: \"\" }).catch(() => \"\");\n\n if (action.toLowerCase() === \"r\") {\n const keyId = await pickKeyForRevoke(client);\n if (!keyId) return;\n const ok = await confirm({ message: \"Revoke this API key?\", default: false }).catch(() => false);\n if (ok) ctx.sink.write(successBox(await runKeyRevoke(client, keyId)));\n } else if (action.toLowerCase() === \"n\") {\n const name = await promptNewKeyName();\n const created = await client.post<{ key: string; name: string; prefix: string }>(\"/keys\", { name });\n ctx.sink.write(success(`Created: ${created.name} (${created.prefix})`));\n ctx.sink.write(accent(\"Save this key — it won't be shown again:\"));\n ctx.sink.write(created.key);\n }\n}\n","import { createTable } from \"../terminal/table.js\";\nimport { muted, success } from \"../terminal/theme.js\";\nimport { emptyState } from \"../terminal/empty-state.js\";\nimport { SETTINGS_API_KEYS_URL } from \"../types/brand.js\";\nimport type { ApiKey } from \"../types/api.js\";\nimport type { FuzziApiClient } from \"../lib/api-client.js\";\nimport { pickFromList } from \"../terminal/interactive.js\";\n\nexport async function runKeysListCommand(client: FuzziApiClient): Promise<string> {\n const data = await client.get<{ results: ApiKey[] }>(\"/keys\");\n const keys = data.results || [];\n if (!keys.length) {\n return emptyState(\"No API keys\", `Create one at ${SETTINGS_API_KEYS_URL}`, \"[n] new key in this view\");\n }\n\n const rows = keys.map((k) => [\n k.name,\n k.prefix,\n k.scopes?.join(\", \") || muted(\"—\"),\n k.revoked ? muted(\"Revoked\") : k.active ? success(\"Active\") : muted(\"Inactive\"),\n k.last_used_at ? new Date(k.last_used_at).toLocaleDateString() : muted(\"Never\"),\n ]);\n\n return createTable([\"Name\", \"Prefix\", \"Scopes\", \"Status\", \"Last Used\"], rows);\n}\n\nexport async function runKeyRevoke(client: FuzziApiClient, keyId: string): Promise<string> {\n await client.delete(`/keys/${keyId}`);\n return \"API key revoked.\";\n}\n\nexport async function pickKeyForRevoke(client: FuzziApiClient): Promise<string | null> {\n const data = await client.get<{ results: ApiKey[] }>(\"/keys\");\n const active = (data.results || []).filter((k) => !k.revoked && k.active);\n return pickFromList(\n \"Select a key to revoke\",\n active.map((k) => ({ name: `${k.name} (${k.prefix})`, value: k.id })),\n );\n}\n","import { muted, accent } from \"./theme.js\";\n\nexport function emptyState(title: string, hint: string, action?: string): string {\n const lines = [\"\", muted(title), muted(hint)];\n if (action) lines.push(\"\", accent(action));\n return lines.join(\"\\n\");\n}\n","import { select, search } from \"@inquirer/prompts\";\nimport { accent, muted } from \"./theme.js\";\n\nexport async function pickFromList<T extends { name: string; value: string }>(\n message: string,\n items: T[],\n): Promise<string | null> {\n if (!items.length) return null;\n try {\n return await select({ message, choices: items });\n } catch {\n return null;\n }\n}\n\nexport async function searchPalette(\n message: string,\n choices: Array<{ name: string; value: string; description?: string }>,\n): Promise<string | null> {\n try {\n return await search({\n message,\n source: async (input) => {\n if (!input) return choices;\n const q = input.toLowerCase();\n return choices.filter((c) => c.value.includes(q) || c.description?.includes(q));\n },\n });\n } catch {\n return null;\n }\n}\n\nexport function formatChoice(name: string, description: string): string {\n return `${accent(name)}${muted(\" — \" + description)}`;\n}\n","import { panel, columns, divider, keyValue } from \"../terminal/layout.js\";\nimport { accent, accentBold, muted, dim } from \"../terminal/theme.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport function renderHelpScreen(): string {\n const visible = SLASH_COMMANDS.filter((c) => !c.hidden);\n const left = visible\n .slice(0, Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n const right = visible\n .slice(Math.ceil(visible.length / 2))\n .map((c) => `${accent(c.name.padEnd(12))} ${muted(c.description)}`)\n .join(\"\\n\");\n\n const script = [\n muted(\"Scriptable commands\"),\n ` fuzzi scan <url> [--format json|markdown] [--fail-on critical]`,\n ` fuzzi scans list | get <id> · fuzzi auth login | status`,\n ` fuzzi config set default_env staging`,\n ].join(\"\\n\");\n\n return [\n panel(columns(left, right), { title: \"Commands\" }),\n \"\",\n script,\n \"\",\n divider(),\n dim(\"Tips: Tab to complete · /palette to search · Ctrl+C to exit\"),\n ].join(\"\\n\");\n}\n\nexport function renderHistoryScreen(entries: string[]): string {\n if (!entries.length) return muted(\"No command history yet.\");\n const body = entries\n .slice(-15)\n .reverse()\n .map((e, i) => `${dim(String(i + 1).padStart(2))} ${e}`)\n .join(\"\\n\");\n return panel(body, { title: \"Recent commands\" });\n}\n","export interface SlashCommandDef {\n name: string;\n description: string;\n usage?: string;\n aliases?: string[];\n requiresAuth?: boolean;\n hidden?: boolean;\n}\n\nexport const SLASH_COMMANDS: SlashCommandDef[] = [\n { name: \"/scan\", description: \"Run a security scan on a URL\", usage: \"/scan <url>\", requiresAuth: true },\n { name: \"/scans\", description: \"Browse recent scans\", requiresAuth: true },\n { name: \"/status\", description: \"Show auth status and rate limits\", requiresAuth: true },\n { name: \"/keys\", description: \"Manage API keys\", requiresAuth: true },\n { name: \"/config\", description: \"Set CLI configuration\", usage: \"/config key=value\" },\n { name: \"/compare\", description: \"Compare two scans\", usage: \"/compare <id-a> <id-b>\", requiresAuth: true },\n { name: \"/whatif\", description: \"Simulate factor overrides\", usage: \"/whatif <id>\", requiresAuth: true },\n { name: \"/report\", description: \"Download scan report\", usage: \"/report <id>\", requiresAuth: true },\n { name: \"/palette\", description: \"Open command palette\", aliases: [\"/commands\"] },\n { name: \"/changelog\", description: \"View release notes\" },\n { name: \"/help\", description: \"Show all commands\" },\n { name: \"/auth\", description: \"Sign in via browser\", aliases: [\"/login\"] },\n { name: \"/auth-key\", description: \"Paste an API key instead\", usage: \"/auth-key\" },\n { name: \"/clear\", description: \"Clear screen and refresh home\" },\n { name: \"/history\", description: \"Show recent commands\" },\n { name: \"/exit\", description: \"Exit the shell\", aliases: [\"/quit\"] },\n];\n\nexport function findCommand(input: string): SlashCommandDef | undefined {\n const cmd = input.trim().split(/\\s/)[0].toLowerCase();\n return SLASH_COMMANDS.find(\n (c) => c.name === cmd || c.aliases?.some((a) => a === cmd),\n );\n}\n\nexport function suggestCommands(partial: string): SlashCommandDef[] {\n const p = partial.toLowerCase();\n if (!p.startsWith(\"/\")) return SLASH_COMMANDS.filter((c) => !c.hidden);\n return SLASH_COMMANDS.filter((c) => c.name.startsWith(p) || c.aliases?.some((a) => a.startsWith(p)));\n}\n","import { searchPalette, formatChoice } from \"../terminal/interactive.js\";\nimport { SLASH_COMMANDS } from \"./registry.js\";\n\nexport async function openCommandPalette(): Promise<string | null> {\n const choices = SLASH_COMMANDS.filter((c) => !c.hidden).map((c) => ({\n name: formatChoice(c.name, c.description),\n value: c.name,\n description: c.usage,\n }));\n return searchPalette(\"Command palette\", choices);\n}\n\nexport { pickFromList } from \"../terminal/interactive.js\";\n","import { mkdir, readFile, writeFile, appendFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fuzziDir } from \"../lib/credentials.js\";\n\nconst HISTORY_PATH = join(fuzziDir(), \"history\");\nconst MAX_ENTRIES = 200;\n\nexport async function loadHistory(): Promise<string[]> {\n try {\n const raw = await readFile(HISTORY_PATH, \"utf8\");\n return raw.split(\"\\n\").filter(Boolean).slice(-MAX_ENTRIES);\n } catch {\n return [];\n }\n}\n\nexport async function appendHistory(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) return;\n await mkdir(fuzziDir(), { recursive: true, mode: 0o700 });\n await appendFile(HISTORY_PATH, trimmed + \"\\n\", \"utf8\");\n}\n\nexport async function clearHistory(): Promise<void> {\n await writeFile(HISTORY_PATH, \"\", \"utf8\");\n}\n","import { panel } from \"./layout.js\";\nimport { error, warn, success, accentBold } from \"./theme.js\";\n\nexport function errorBox(message: string, hint?: string): string {\n const body = hint ? `${message}\\n\\n${hint}` : message;\n return panel(body, { title: \"Error\" });\n}\n\nexport function successBox(message: string): string {\n return panel(success(message), { title: \"Done\" });\n}\n\nexport function section(title: string, body: string): string {\n return [accentBold(title), body].join(\"\\n\");\n}\n\nexport function warningBox(message: string): string {\n return panel(warn(message), { title: \"Warning\" });\n}\n","import type { SlashCommandDef } from \"./registry.js\";\n\nexport function buildCompleter(commands: SlashCommandDef[], history: string[]): (line: string) => [string[], string] {\n const names = commands.map((c) => c.name);\n return (line: string): [string[], string] => {\n const trimmed = line.trimStart();\n if (!trimmed.startsWith(\"/\")) {\n if (trimmed === \"\") return [[...names, ...history.slice(-20).reverse()], line];\n return [[], line];\n }\n const hits = names.filter((n) => n.startsWith(trimmed.split(/\\s/)[0]));\n return [hits.length ? hits : names, line];\n };\n}\n","import * as readline from \"node:readline\";\nimport { stdin as input, stdout as output } from \"node:process\";\nimport { splitHomePanel, centerInColumn } from \"../terminal/layout.js\";\nimport { accent, accentBold, info, muted, italic } from \"../terminal/theme.js\";\nimport { contentWidth } from \"../terminal/width.js\";\nimport { renderFuzziMark } from \"./ascii-mark.js\";\nimport { runBrowserLogin } from \"../lib/browser-auth.js\";\nimport { tryGetProfile } from \"../cli/profile.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { formatApiError } from \"../lib/errors.js\";\nimport { createProgress } from \"../terminal/progress.js\";\nimport { VERSION, SETTINGS_API_KEYS_URL, APP_HOST } from \"../types/brand.js\";\n\nexport function renderAuthGate(): string {\n const colW = Math.max(28, Math.floor(contentWidth() * 0.36));\n const mark = centerInColumn(accent(renderFuzziMark()), colW);\n\n const left = [\n accentBold(\"Welcome to Fuzzi!\"),\n \"\",\n mark,\n \"\",\n muted(\"Not connected\"),\n info(\"Sign in to run scans\"),\n \"\",\n accent(\"/auth-key\") + muted(\" paste API key\"),\n accent(\"/help\") + muted(\" commands\"),\n ].join(\"\\n\");\n\n const rightTop = [\n accentBold(\"Sign in to continue\"),\n \"\",\n info(\"Press Enter to open your browser\"),\n muted(\"and authorize the CLI.\"),\n \"\",\n muted(\"A local server receives the callback\"),\n muted(`from ${APP_HOST} automatically.`),\n ].join(\"\\n\");\n\n const rightBottom = [\n accentBold(\"Other options\"),\n \"\",\n muted(\"Paste an API key with /auth-key\"),\n muted(\"from Settings → API Keys on the web.\"),\n \"\",\n italic(muted(SETTINGS_API_KEYS_URL)),\n ].join(\"\\n\");\n\n return splitHomePanel({\n title: `Fuzzi CLI v${VERSION}`,\n left,\n rightTop,\n rightBottom,\n leftRatio: 0.36,\n });\n}\n\nfunction waitForEnter(): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input, output, terminal: true });\n output.write(accent(\"\\n › Press Enter to open browser... \"));\n rl.once(\"line\", () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport async function runAuthGate(): Promise<UserProfile | null> {\n const existing = await tryGetProfile();\n if (existing) return existing;\n\n if (!output.isTTY) return null;\n\n console.log(renderAuthGate());\n await waitForEnter();\n\n const progress = createProgress(\"Opening browser...\");\n try {\n const result = await runBrowserLogin();\n progress.succeed(\"Signed in\");\n console.log(accent(result.message));\n return result.profile;\n } catch (e) {\n progress.fail(\"Sign-in failed\");\n console.log(muted(formatApiError(e)));\n console.log(muted(\"Use /auth-key to paste an API key, or /auth to retry.\"));\n return null;\n }\n}\n","import { cwd } from \"node:process\";\nimport { loadCredentials } from \"../lib/credentials.js\";\nimport { getAuthenticatedClient } from \"../lib/api-client.js\";\nimport type { UserProfile } from \"../types/api.js\";\nimport { log } from \"../lib/logger.js\";\n\nexport async function tryGetProfile(): Promise<UserProfile | null> {\n try {\n const creds = await loadCredentials();\n if (!creds?.api_key) return null;\n const client = await getAuthenticatedClient();\n return await client.get<UserProfile>(\"/me\");\n } catch (e) {\n log.debug(\"profile bootstrap failed\", e);\n return null;\n }\n}\n","import type { UserProfile } from \"../types/api.js\";\nimport { runPromptLoop } from \"../shell/prompt-loop.js\";\nimport { runAuthGate } from \"../shell/auth-gate.js\";\nimport { tryGetProfile } from \"./profile.js\";\n\nexport async function runInteractiveMode(): Promise<void> {\n let profile = await tryGetProfile();\n if (!profile) {\n profile = await runAuthGate();\n }\n await runPromptLoop(profile);\n}\n","import { buildProgram } from \"./cli/program.js\";\nimport { runInteractiveMode } from \"./cli/bootstrap.js\";\nimport { formatApiError, getExitCode } from \"./lib/errors.js\";\n\nasync function main(argv: string[]): Promise<void> {\n if (argv.length <= 2) {\n await runInteractiveMode();\n return;\n }\n await buildProgram().parseAsync(argv);\n}\n\nmain(process.argv).catch((e) => {\n console.error(formatApiError(e));\n process.exit(getExitCode(e));\n});\n"],"mappings":"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","names":["mkdir","readFile","writeFile","chmod","homedir","join","ensureDir","stdout","init_theme","writeFile","init_theme","cwd","readFile","join","cwd","output","init_theme","cwd","runReportCommand","runWhatIfCommand","runCompareCommand","input","homedir","readFile","join","existsSync","cwd","homedir","confirm","input","input","input","mkdir","readFile","writeFile","join","runCompareCommand","runWhatIfCommand","runReportCommand","input","confirm","cwd","cwd","input","readline","input","output","input","output"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fuzzi-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Fuzzi security scanner CLI — interactive shell and scriptable commands",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "keywords": ["fuzzi", "security", "scanner", "cli", "devsecops", "ci"],
28
28
  "license": "UNLICENSED",
29
- "homepage": "https://github.com/fuzzi-cli/fuzzi-cli#readme",
29
+ "homepage": "https://fuzzi-ten.vercel.app",
30
30
  "bugs": {
31
31
  "url": "https://github.com/fuzzi-cli/fuzzi-cli/issues"
32
32
  },