@forcefield/mcp-server 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,14 +9,14 @@ Current channel is **public beta**.
9
9
  ## Setup
10
10
 
11
11
  ```bash
12
- npm i -g forcefield
12
+ npm i -g @forcefield/forcefield
13
13
  forcefield setup
14
14
  ```
15
15
 
16
16
  One-off (no global install):
17
17
 
18
18
  ```bash
19
- npx -y forcefield setup
19
+ npx -y @forcefield/forcefield setup
20
20
  ```
21
21
 
22
22
  Direct runtime package path (equivalent):
@@ -622,7 +622,7 @@ var WORKFLOW_DIR_CANDIDATES = [
622
622
  join7(__dirname2, "..", "..", "workflows")
623
623
  ];
624
624
  var CONFIG_FILE = ".forcefield.json";
625
- var VERSION = "0.1.2";
625
+ var VERSION = "0.1.4";
626
626
  var BANNER_TEXT = "Forcefield";
627
627
  var BANNER_FONT = "Rowan Cap";
628
628
  var BANNER_MIN_COLUMNS = 80;
@@ -1226,4 +1226,4 @@ export {
1226
1226
  parseArgs,
1227
1227
  runSetupCli
1228
1228
  };
1229
- //# sourceMappingURL=chunk-4L46G65Q.js.map
1229
+ //# sourceMappingURL=chunk-5A2F5L4X.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../setup/wizard.ts","../setup/ide-detect.ts","../setup/ide-adapters/claude-code.ts","../setup/ide-adapters/mcp-runtime.ts","../setup/ide-adapters/cursor.ts","../setup/ide-adapters/codex.ts","../setup/ide-adapters/windsurf.ts","../setup/ide-adapters/index.ts","../setup/auth.ts","../setup/index.ts"],"sourcesContent":["/**\n * setup/wizard.ts — Interactive setup wizard using @clack/prompts.\n *\n * Orchestrates the full setup flow:\n * 1. Welcome banner\n * 2. Existing setup check\n * 3. IDE detection + selection\n * 4. Mode selection (Core vs Full)\n * 5. Authentication\n * 6. Configure + install\n * 7. Verify + success\n */\n\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport figlet from 'figlet';\nimport gradient from 'gradient-string';\nimport { readFile, writeFile, access } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Ide, SetupMode, SetupConfig, CliArgs } from './types.js';\nimport { detectIde } from './ide-detect.js';\nimport { getAdapter, IDE_CHOICES } from './ide-adapters/index.js';\nimport {\n authenticateAccountAndCreateApiKey,\n authenticateLocalAndCreateApiKey,\n authenticateWithRetry,\n verifyApiKey,\n} from './auth.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst WORKFLOW_DIR_CANDIDATES = [\n join(__dirname, '..', 'workflows'),\n join(__dirname, '..', '..', 'workflows'),\n];\nconst CONFIG_FILE = '.forcefield.json';\nconst VERSION = '0.1.2';\nconst BANNER_TEXT = 'Forcefield';\nconst BANNER_FONT = 'Rowan Cap';\nconst BANNER_MIN_COLUMNS = 80;\nconst BANNER_FALLBACK_TEXT = ' Forcefield';\nconst BANNER_SUBTITLE = ' Corporate compliance copilot\\n';\n// rainbow2-like palette cycling red -> violet for the terminal banner\nconst BANNER_GRADIENT_STOPS = ['#ff3b3b', '#ff9f1a', '#ffe74c', '#2ed573', '#1e90ff', '#7d5fff', '#e056fd'];\nconst bannerGradient = gradient(BANNER_GRADIENT_STOPS);\n\nasync function resolveWorkflowsDir(): Promise<string> {\n for (const dir of WORKFLOW_DIR_CANDIDATES) {\n try {\n await access(dir);\n return dir;\n } catch {\n // try next candidate\n }\n }\n throw new Error(\n `Unable to locate workflow templates. Checked: ${WORKFLOW_DIR_CANDIDATES.join(', ')}`,\n );\n}\n\n/**\n * Run the interactive setup wizard.\n */\nexport async function runWizard(projectDir: string, args: CliArgs): Promise<void> {\n // --status: read-only check\n if (args.status) {\n await showStatus(projectDir);\n return;\n }\n\n // --doctor: setup diagnostics\n if (args.doctor) {\n await runDoctor(projectDir, args);\n return;\n }\n\n // Non-interactive mode\n if (args.ide && args.mode && (args.token || args.localAuth || (args.email && args.password))) {\n await runNonInteractive(projectDir, args);\n return;\n }\n\n // Interactive mode\n await runInteractive(projectDir, args);\n}\n\n// === Welcome Banner ===\n\nfunction showBanner(): void {\n const cols = process.stdout.columns || 80;\n\n if (cols >= BANNER_MIN_COLUMNS) {\n try {\n const banner = figlet.textSync(BANNER_TEXT, { font: BANNER_FONT });\n const colored = applyBannerGradient(banner);\n console.log(colored);\n } catch {\n // figlet font not available — use fallback\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n } else {\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n console.log(pc.dim(BANNER_SUBTITLE));\n}\n\nfunction applyBannerGradient(text: string): string {\n return bannerGradient.multiline(text);\n}\n\n// === Status Check ===\n\nasync function showStatus(projectDir: string): Promise<void> {\n const config = await readConfig(projectDir);\n\n if (!config) {\n console.log(pc.yellow('No Forcefield setup found in this directory.'));\n console.log(`Run ${pc.cyan('forcefield setup')} to get started.`);\n process.exit(1);\n }\n\n console.log(pc.bold('Forcefield Setup Status'));\n console.log(` IDE: ${pc.cyan(config.ide)}`);\n console.log(` Mode: ${pc.cyan(config.mode)}`);\n console.log(` Version: ${pc.cyan(config.version)}`);\n console.log(` Installed: ${pc.dim(config.installed_at)}`);\n}\n\ninterface DoctorCheckResult {\n ok: boolean;\n label: string;\n detail: string;\n}\n\ninterface McpCheckResult {\n ok: boolean;\n filePath: string;\n key?: string;\n detail: string;\n}\n\nasync function runDoctor(projectDir: string, args: CliArgs): Promise<void> {\n console.log(pc.bold('Forcefield Setup Doctor'));\n console.log(pc.dim(`Project: ${projectDir}`));\n\n const checks: DoctorCheckResult[] = [];\n const config = await readConfig(projectDir);\n\n if (!config) {\n checks.push({\n ok: false,\n label: 'Setup config',\n detail: `Missing ${CONFIG_FILE}. Run forcefield setup first.`,\n });\n } else {\n checks.push({\n ok: true,\n label: 'Setup config',\n detail: `${config.ide} / ${config.mode} / v${config.version}`,\n });\n\n const mcp = await inspectMcpConfig(projectDir, config.ide);\n checks.push({\n ok: mcp.ok,\n label: 'MCP config',\n detail: `${mcp.filePath} — ${mcp.detail}`,\n });\n\n if (mcp.key) {\n const verified = await verifyApiKey(mcp.key, { localDev: isLocalSetupMode(args) });\n checks.push({\n ok: verified.valid,\n label: 'API key exchange',\n detail: verified.valid\n ? 'Key exchange succeeded.'\n : (verified.error ?? 'Key exchange failed.'),\n });\n } else {\n checks.push({\n ok: false,\n label: 'API key exchange',\n detail: 'FORCEFIELD_API_KEY not found in MCP config env.',\n });\n }\n }\n\n for (const check of checks) {\n const symbol = check.ok ? pc.green('✓') : pc.red('✗');\n console.log(`${symbol} ${pc.bold(check.label)}: ${check.detail}`);\n }\n\n const failures = checks.filter((check) => !check.ok);\n if (failures.length > 0) {\n console.log('');\n console.log(pc.yellow('Suggested fixes:'));\n console.log(` 1. Re-run ${pc.cyan('forcefield setup')} in this project.`);\n console.log(` 2. Confirm your coding agent shows Forcefield connected (${pc.cyan('/mcp')}).`);\n console.log(` 3. Re-run ${pc.cyan('forcefield doctor')} after setup.`);\n process.exit(1);\n }\n\n console.log('');\n console.log(pc.green('Doctor checks passed. Forcefield should be ready.'));\n}\n\nasync function inspectMcpConfig(projectDir: string, ide: Ide): Promise<McpCheckResult> {\n if (ide === 'claude-code') {\n return inspectJsonMcpConfig(join(projectDir, '.mcp.json'), 'mcpServers');\n }\n\n if (ide === 'cursor') {\n return inspectJsonMcpConfig(join(projectDir, '.cursor', 'mcp.json'), 'mcpServers');\n }\n\n if (ide === 'windsurf') {\n return inspectJsonMcpConfig(join(projectDir, '.windsurf', 'mcp_config.json'), 'mcpServers');\n }\n\n return inspectCodexMcpConfig(join(projectDir, '.codex', 'config.toml'));\n}\n\nasync function inspectJsonMcpConfig(\n filePath: string,\n rootKey: string,\n): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'Invalid JSON.',\n };\n }\n\n const servers =\n typeof parsed[rootKey] === 'object' && parsed[rootKey] != null\n ? (parsed[rootKey] as Record<string, unknown>)\n : null;\n\n if (!servers || typeof servers.forcefield !== 'object' || servers.forcefield == null) {\n return {\n ok: false,\n filePath,\n detail: 'Missing forcefield MCP server entry.',\n };\n }\n\n const ffServer = servers.forcefield as Record<string, unknown>;\n const command = typeof ffServer.command === 'string' ? ffServer.command : '';\n const env = typeof ffServer.env === 'object' && ffServer.env != null\n ? (ffServer.env as Record<string, unknown>)\n : {};\n const key = typeof env.FORCEFIELD_API_KEY === 'string'\n ? env.FORCEFIELD_API_KEY\n : undefined;\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n detail: 'forcefield entry missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n detail: `Found forcefield entry (command: ${command}).`,\n };\n}\n\nasync function inspectCodexMcpConfig(filePath: string): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n const command = extractTomlValue(raw, /^\\s*command\\s*=\\s*\"([^\"]+)\"/m);\n const key = extractTomlValue(raw, /^\\s*FORCEFIELD_API_KEY\\s*=\\s*\"([^\"]+)\"/m);\n const hasServerSection = raw.includes('[mcp_servers.forcefield]');\n\n if (!hasServerSection) {\n return {\n ok: false,\n filePath,\n key,\n detail: 'Missing [mcp_servers.forcefield] section.',\n };\n }\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n detail: 'forcefield section missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n detail: `Found forcefield section (command: ${command}).`,\n };\n}\n\nfunction extractTomlValue(content: string, pattern: RegExp): string | undefined {\n const match = content.match(pattern);\n return match?.[1];\n}\n\n// === Non-Interactive Mode ===\n\nasync function runNonInteractive(projectDir: string, args: CliArgs): Promise<void> {\n const ide = args.ide!;\n const mode = args.mode!;\n let apiKey = args.token;\n\n if (args.localAuth) {\n if (!args.email || !args.password) {\n console.error(pc.red('Non-interactive local auth requires --email and --password.'));\n process.exit(1);\n }\n\n const auth = await authenticateLocalAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard (Local)',\n });\n apiKey = auth.apiKey;\n console.log(`Created local API key for ${auth.email}.`);\n } else if (!apiKey && args.email && args.password) {\n const auth = await authenticateAccountAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard Key',\n localDev: isLocalSetupMode(args),\n });\n apiKey = auth.apiKey;\n console.log(`Created API key for ${auth.email}.`);\n } else if (apiKey) {\n const verified = await authenticateWithRetry(async () => apiKey ?? null, {\n localDev: isLocalSetupMode(args),\n });\n if (!verified.valid) {\n console.error(pc.red(verified.error ?? 'API key validation failed.'));\n process.exit(1);\n }\n apiKey = verified.apiKey;\n }\n\n if (!apiKey) {\n console.error(pc.red('Missing auth input. Pass --token, --local-auth, or --email/--password.'));\n process.exit(1);\n }\n\n console.log(`Setting up Forcefield for ${ide} in ${mode} mode...`);\n\n await configure(projectDir, ide, mode, apiKey);\n\n console.log(pc.green('Setup complete!'));\n for (const line of getPostSetupInstructions(ide, mode, projectDir)) {\n console.log(line);\n }\n}\n\n// === Interactive Mode ===\n\nasync function runInteractive(projectDir: string, preArgs: CliArgs): Promise<void> {\n showBanner();\n\n p.intro(pc.bgCyan(pc.black(' Forcefield Setup ')));\n\n // Step 1: Check existing setup\n const existingConfig = await readConfig(projectDir);\n if (existingConfig) {\n const updateChoice = await p.select({\n message: `Forcefield is already set up (${existingConfig.ide}, ${existingConfig.mode} mode).`,\n options: [\n { value: 'update', label: 'Update existing setup', hint: 'Refresh workflows + auth' },\n { value: 'fresh', label: 'Start fresh', hint: 'Remove existing config and reconfigure' },\n ],\n });\n\n if (p.isCancel(updateChoice)) {\n p.cancel('Setup cancelled.');\n process.exit(0);\n }\n\n if (updateChoice === 'update') {\n // Re-run configure with existing settings\n const apiKey = await promptApiKey();\n if (!apiKey) return;\n await configure(projectDir, existingConfig.ide, existingConfig.mode, apiKey);\n showSuccess(existingConfig.ide, existingConfig.mode, projectDir);\n return;\n }\n // fresh → continue with full wizard\n }\n\n // Step 2: IDE detection + selection\n const ide = preArgs.ide ?? await promptIde(projectDir);\n if (!ide) return;\n\n // Step 3: Mode selection\n const mode = preArgs.mode ?? await promptMode();\n if (!mode) return;\n\n // Step 4: Authentication\n const apiKey = preArgs.token ?? await promptApiKey(preArgs);\n if (!apiKey) return;\n\n // Step 5: Configure + install\n const s = p.spinner();\n s.start('Configuring Forcefield...');\n\n try {\n await configure(projectDir, ide, mode, apiKey);\n s.stop('Configuration complete.');\n } catch (err) {\n s.stop('Configuration failed.');\n p.cancel(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n // Step 6: Success\n showSuccess(ide, mode, projectDir);\n}\n\n// === Prompts ===\n\nasync function promptIde(projectDir: string): Promise<Ide | null> {\n const detection = await detectIde(projectDir);\n\n if (detection.detected) {\n const adapter = getAdapter(detection.detected);\n const confirm = await p.confirm({\n message: `Detected ${adapter.name} (${detection.markers[0]!.marker} found). Use ${adapter.name}?`,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (confirm) return detection.detected;\n }\n\n const choice = await p.select({\n message: 'Which IDE do you use?',\n options: IDE_CHOICES,\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as Ide;\n}\n\nasync function promptMode(): Promise<SetupMode | null> {\n const choice = await p.select({\n message: 'Installation type:',\n options: [\n { value: 'full' as const, label: 'Full — MCP server + guided workflows', hint: 'Recommended' },\n { value: 'core' as const, label: 'Core — MCP server only', hint: 'Minimal' },\n ],\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as SetupMode;\n}\n\nasync function promptApiKey(preArgs?: CliArgs): Promise<string | null> {\n if (preArgs?.localAuth) {\n const preEmail = preArgs.email ?? await promptTextValue('Local test email:', 'alice@test.local');\n const prePassword = preArgs.password ?? await promptTextValue('Local test password:', 'password123', true);\n if (!preEmail || !prePassword) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(preEmail, prePassword, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const localMode = isLocalSetupMode(preArgs);\n const methodOptions = [\n { value: 'account', label: 'Sign in / create account + API key', hint: 'Recommended' },\n { value: 'paste', label: 'Paste existing API key', hint: 'Use an existing ff_live_... key' },\n ];\n\n if (localMode) {\n methodOptions.push({\n value: 'local',\n label: 'Create local account + API key',\n hint: 'For local Supabase testing',\n });\n }\n\n const method = await p.select({\n message: 'How do you want to authenticate?',\n options: methodOptions,\n });\n\n if (p.isCancel(method)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (method === 'account') {\n const email = await promptTextValue('Account email:', preArgs?.email ?? 'you@company.com');\n const password = await promptTextValue('Account password:', '••••••••', true);\n if (!email || !password) return null;\n\n try {\n const result = await authenticateAccountAndCreateApiKey(email, password, {\n label: 'Setup Wizard Key',\n localDev: localMode,\n });\n p.log.success(`Created API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Account authentication failed');\n return null;\n }\n }\n\n if (method === 'local') {\n const email = await promptTextValue('Local test email:', 'alice@test.local');\n const password = await promptTextValue('Local test password:', 'password123', true);\n if (!email || !password) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(email, password, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const auth = await authenticateWithRetry(\n async () => {\n const key = await p.text({\n message: 'Enter your Forcefield API key:',\n placeholder: 'ff_live_...',\n validate: (value) => {\n if (!value) return 'API key is required.';\n if (!value.startsWith('ff_live_')) return 'Key must start with \"ff_live_\".';\n if (value.length < 20) return 'Key seems too short.';\n return undefined;\n },\n });\n\n if (p.isCancel(key)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return key;\n },\n {\n localDev: localMode,\n },\n );\n\n if (!auth.valid) {\n p.log.error(auth.error ?? 'Authentication failed. Check your credentials and retry.');\n return null;\n }\n\n return auth.apiKey;\n}\n\nfunction isLocalSetupMode(preArgs?: CliArgs): boolean {\n if (preArgs?.localAuth) return true;\n const localValue = process.env.FORCEFIELD_LOCAL_DEV;\n if (localValue) {\n const normalized = localValue.trim().toLowerCase();\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true;\n }\n }\n\n const supabaseUrl = process.env.SUPABASE_URL;\n if (!supabaseUrl) return false;\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nasync function promptTextValue(\n message: string,\n placeholder: string,\n secret = false,\n): Promise<string | null> {\n const value = await p.text({\n message,\n placeholder,\n ...(secret ? { placeholder: '••••••••' } : {}),\n validate: (input) => {\n if (!input) return 'This field is required.';\n return undefined;\n },\n });\n\n if (p.isCancel(value)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n return value;\n}\n\n// === Configure ===\n\nasync function configure(\n projectDir: string,\n ide: Ide,\n mode: SetupMode,\n apiKey: string,\n): Promise<void> {\n const adapter = getAdapter(ide);\n\n // Configure MCP\n await adapter.configureMcp(projectDir, apiKey);\n\n // Install workflows (full mode only)\n let workflowCount = 0;\n if (mode === 'full') {\n const workflowsDir = await resolveWorkflowsDir();\n workflowCount = await adapter.installWorkflows(projectDir, workflowsDir);\n }\n\n // Write config\n const config: SetupConfig = {\n ide,\n mode,\n installed_at: new Date().toISOString(),\n version: VERSION,\n };\n await writeConfig(projectDir, config);\n\n void workflowCount; // Used in logging below\n}\n\nfunction getPostSetupInstructions(ide: Ide, mode: SetupMode, projectDir: string): string[] {\n const repo = pc.cyan(projectDir);\n const dashboardHint =\n `Optional beta companion: run local dashboard in the Forcefield repo via ${pc.cyan('pnpm run dev:dashboard')} and sign in at ${pc.cyan('http://localhost:3000')}.`;\n\n if (mode === 'core') {\n return [\n `Next: open your coding agent in ${repo} and use Forcefield MCP tools directly (e.g. ${pc.cyan('ff_system(action: \"health\")')}).`,\n dashboardHint,\n ];\n }\n\n const common = [\n `Next: start your coding agent in ${repo}.`,\n `Then in IDE chat (not terminal), run ${pc.cyan('/ff-onboard')} to set up your company profile and deadlines.`,\n `Optional: run ${pc.cyan('/ff-start')} only if you want a command primer or connection troubleshooting.`,\n `If connection fails, run ${pc.cyan('forcefield doctor')} in terminal for diagnostics.`,\n dashboardHint,\n ];\n\n if (ide === 'claude-code') {\n return [\n ...common,\n `If tools are missing, run ${pc.cyan('/mcp')} and confirm ${pc.cyan('forcefield')} is connected.`,\n ];\n }\n\n return common;\n}\n\nfunction showSuccess(ide: Ide, mode: SetupMode, projectDir: string): void {\n const adapter = getAdapter(ide);\n const workflowStatus =\n mode === 'full'\n ? `${pc.green('✓')} Project workflow commands installed`\n : `${pc.yellow('•')} Core mode selected (no slash-command workflows installed)`;\n\n p.note(\n [\n `${pc.green('✓')} MCP server configured`,\n workflowStatus,\n `${pc.green('✓')} IDE: ${adapter.name}`,\n ].join('\\n'),\n 'Setup Complete',\n );\n\n p.outro(getPostSetupInstructions(ide, mode, projectDir).join('\\n'));\n}\n\n// === Config File ===\n\nasync function readConfig(projectDir: string): Promise<SetupConfig | null> {\n const configPath = join(projectDir, CONFIG_FILE);\n try {\n await access(configPath);\n const raw = await readFile(configPath, 'utf-8');\n return JSON.parse(raw) as SetupConfig;\n } catch {\n return null;\n }\n}\n\nasync function writeConfig(projectDir: string, config: SetupConfig): Promise<void> {\n const configPath = join(projectDir, CONFIG_FILE);\n await writeFile(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport {\n readConfig,\n writeConfig,\n CONFIG_FILE,\n VERSION,\n BANNER_FONT,\n BANNER_MIN_COLUMNS,\n BANNER_GRADIENT_STOPS,\n showBanner,\n applyBannerGradient,\n getPostSetupInstructions,\n inspectMcpConfig,\n inspectJsonMcpConfig,\n inspectCodexMcpConfig,\n extractTomlValue,\n};\n","/**\n * setup/ide-detect.ts — Auto-detect IDE from project directory markers.\n */\n\nimport { access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Ide } from './types.js';\n\ninterface DetectionResult {\n detected: Ide | null;\n markers: Array<{ ide: Ide; marker: string }>;\n}\n\nconst IDE_MARKERS: Array<{ ide: Ide; marker: string; isDir: boolean }> = [\n { ide: 'claude-code', marker: '.claude', isDir: true },\n { ide: 'cursor', marker: '.cursor', isDir: true },\n { ide: 'codex', marker: 'AGENTS.md', isDir: false },\n { ide: 'windsurf', marker: '.windsurfrules', isDir: false },\n];\n\nexport async function detectIde(projectDir: string): Promise<DetectionResult> {\n const found: Array<{ ide: Ide; marker: string }> = [];\n\n for (const { ide, marker } of IDE_MARKERS) {\n const markerPath = join(projectDir, marker);\n try {\n await access(markerPath);\n found.push({ ide, marker });\n } catch {\n // Marker not found — skip\n }\n }\n\n return {\n detected: found.length === 1 ? found[0]!.ide : null,\n markers: found,\n };\n}\n\nexport { IDE_MARKERS };\n","/**\n * IDE adapter for Claude Code.\n * Workflows → .claude/commands/ff-*.md\n * MCP → project-scoped .mcp.json entry\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nexport const claudeCodeAdapter: IdeAdapter = {\n name: 'Claude Code',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n // Ensure Claude config folder exists for slash-command workflows.\n const claudeDir = join(projectDir, '.claude');\n await mkdir(claudeDir, { recursive: true });\n\n // Configure project-scoped MCP entry used by Claude Code.\n const launch = await getMcpLaunchConfig();\n const mcpPath = join(projectDir, '.mcp.json');\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(mcpPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const nextConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(mcpPath, JSON.stringify(nextConfig, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n await mkdir(commandsDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(commandsDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n try {\n const files = await readdir(commandsDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(commandsDir, file));\n }\n }\n } catch {\n // Directory doesn't exist — nothing to remove\n }\n },\n};\n","import { access } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst LOCAL_ENTRY_CANDIDATES = [\n join(__dirname, '..', '..', 'build', 'index.js'),\n join(__dirname, '..', '..', 'index.js'),\n];\nconst RUNNING_FROM_NODE_MODULES = __dirname.includes('node_modules');\n\nconst FORWARDED_ENV_KEYS = [\n 'SUPABASE_URL',\n 'SUPABASE_ANON_KEY',\n 'FORCEFIELD_LOCAL_DEV',\n 'FORCEFIELD_DISABLE_GATING',\n 'FORCEFIELD_LOCAL_DATA_FALLBACK',\n] as const;\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nasync function resolveLocalEntry(): Promise<string | null> {\n for (const candidate of LOCAL_ENTRY_CANDIDATES) {\n try {\n await access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n}\n\nexport async function getMcpLaunchConfig(): Promise<{ command: string; args: string[] }> {\n if (\n RUNNING_FROM_NODE_MODULES\n || isTruthy(process.env.FORCEFIELD_LOCAL_DEV)\n || isTruthy(process.env.FORCEFIELD_SETUP_USE_LOCAL_BUILD)\n ) {\n const localEntry = await resolveLocalEntry();\n if (localEntry) {\n return {\n command: process.execPath,\n args: [localEntry],\n };\n }\n }\n\n return {\n command: 'npx',\n args: ['-y', '-p', '@forcefield/mcp-server', 'forcefield-mcp'],\n };\n}\n\nexport function buildMcpEnv(apiKey: string): Record<string, string> {\n const env: Record<string, string> = {\n FORCEFIELD_API_KEY: apiKey,\n };\n\n for (const key of FORWARDED_ENV_KEYS) {\n const value = process.env[key];\n if (value && value.trim().length > 0) {\n env[key] = value;\n }\n }\n\n return env;\n}\n","/**\n * IDE adapter for Cursor.\n * Workflows → .cursor/rules/ff-*.md\n * MCP → .cursor/mcp.json\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\ntype CursorMcpConfig = {\n mcpServers?: Record<string, { command: string; args: string[]; env?: Record<string, string> }>;\n};\n\nexport const cursorAdapter: IdeAdapter = {\n name: 'Cursor',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const cursorDir = join(projectDir, '.cursor');\n await mkdir(cursorDir, { recursive: true });\n\n const configPath = join(cursorDir, 'mcp.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: CursorMcpConfig = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as CursorMcpConfig;\n } catch {\n // file missing/invalid: overwrite with fresh config\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? existing.mcpServers\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged: CursorMcpConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n await mkdir(rulesDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(rulesDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n try {\n const files = await readdir(rulesDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(rulesDir, file));\n }\n }\n } catch {\n // Directory doesn't exist\n }\n },\n};\n","/**\n * IDE adapter for Codex (OpenAI).\n * Workflows → appended to AGENTS.md with markers\n * MCP → .codex/config.toml or project-level config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\nconst MCP_START_MARKER = '# forcefield:mcp:start';\nconst MCP_END_MARKER = '# forcefield:mcp:end';\n\nexport const codexAdapter: IdeAdapter = {\n name: 'Codex',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const codexDir = join(projectDir, '.codex');\n await mkdir(codexDir, { recursive: true });\n\n const configPath = join(codexDir, 'config.toml');\n const launch = await getMcpLaunchConfig();\n const env = buildMcpEnv(apiKey);\n\n const forcefieldBlock = buildForcefieldTomlBlock(launch.command, launch.args, env);\n\n let existing = '';\n try {\n existing = await readFile(configPath, 'utf-8');\n } catch {\n // file missing — create new\n }\n\n const cleaned = removeTomlForcefieldSection(existing).trim();\n const final = cleaned ? `${cleaned}\\n\\n${forcefieldBlock}\\n` : `${forcefieldBlock}\\n`;\n await writeFile(configPath, final, 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n const { readdir } = await import('node:fs/promises');\n\n // Read all workflow files\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n 'The following workflows are available for compliance management:',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n // Read existing AGENTS.md or create new\n let existing = '';\n try {\n existing = await readFile(agentsPath, 'utf-8');\n } catch {\n // File doesn't exist — will create\n }\n\n // Remove existing Forcefield section if present\n const cleaned = removeSection(existing);\n\n // Append new section\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(agentsPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n try {\n const content = await readFile(agentsPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(agentsPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist — nothing to remove\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n\nfunction removeTomlForcefieldSection(content: string): string {\n const markerStart = content.indexOf(MCP_START_MARKER);\n const markerEnd = content.indexOf(MCP_END_MARKER);\n\n if (markerStart !== -1 && markerEnd !== -1) {\n const before = content.slice(0, markerStart).trimEnd();\n const after = content.slice(markerEnd + MCP_END_MARKER.length).trimStart();\n return before + (after ? '\\n\\n' + after : '');\n }\n\n // Backward-compatible cleanup if a previous config wrote unmanaged sections.\n return content\n .replace(/^\\[mcp_servers\\.forcefield\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .replace(/^\\[mcp_servers\\.forcefield\\.env\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .trim();\n}\n\nfunction buildForcefieldTomlBlock(\n command: string,\n args: string[],\n env: Record<string, string>,\n): string {\n const envLines = Object.entries(env)\n .map(([key, value]) => `${key} = \"${escapeTomlString(value)}\"`);\n\n return [\n MCP_START_MARKER,\n '[mcp_servers.forcefield]',\n `command = \"${escapeTomlString(command)}\"`,\n `args = [${args.map((arg) => `\"${escapeTomlString(arg)}\"`).join(', ')}]`,\n '[mcp_servers.forcefield.env]',\n ...envLines,\n MCP_END_MARKER,\n ].join('\\n');\n}\n\nfunction escapeTomlString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","/**\n * IDE adapter for Windsurf.\n * Workflows → appended to .windsurfrules with markers\n * MCP → Windsurf MCP config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\n\nexport const windsurfAdapter: IdeAdapter = {\n name: 'Windsurf',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const configDir = join(projectDir, '.windsurf');\n await mkdir(configDir, { recursive: true });\n\n const configPath = join(configDir, 'mcp_config.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesPath = join(projectDir, '.windsurfrules');\n const { readdir } = await import('node:fs/promises');\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n let existing = '';\n try {\n existing = await readFile(rulesPath, 'utf-8');\n } catch {\n // File doesn't exist\n }\n\n const cleaned = removeSection(existing);\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(rulesPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesPath = join(projectDir, '.windsurfrules');\n try {\n const content = await readFile(rulesPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(rulesPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n","/**\n * IDE adapter registry.\n */\n\nimport type { Ide, IdeAdapter } from '../types.js';\nimport { claudeCodeAdapter } from './claude-code.js';\nimport { cursorAdapter } from './cursor.js';\nimport { codexAdapter } from './codex.js';\nimport { windsurfAdapter } from './windsurf.js';\n\nconst adapters: Record<Ide, IdeAdapter> = {\n 'claude-code': claudeCodeAdapter,\n 'cursor': cursorAdapter,\n 'codex': codexAdapter,\n 'windsurf': windsurfAdapter,\n};\n\nexport function getAdapter(ide: Ide): IdeAdapter {\n return adapters[ide];\n}\n\nexport const IDE_CHOICES: Array<{ value: Ide; label: string; hint: string }> = [\n { value: 'claude-code', label: 'Claude Code', hint: '.claude/commands/' },\n { value: 'cursor', label: 'Cursor', hint: '.cursor/rules/' },\n { value: 'codex', label: 'Codex (OpenAI)', hint: 'AGENTS.md' },\n { value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },\n];\n","/**\n * setup/auth.ts — Authentication and API key issuance for setup wizard.\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport { createClient } from '@supabase/supabase-js';\nimport {\n LOCAL_SUPABASE_ANON_KEY,\n LOCAL_SUPABASE_SERVICE_ROLE_KEY,\n PRODUCTION_SUPABASE_PUBLISHABLE_KEY,\n PRODUCTION_SUPABASE_URL,\n} from '../src/supabase-defaults.js';\n\nconst API_KEY_PREFIX = 'ff_live_';\nconst MAX_RETRIES = 3;\n\nexport interface AuthResult {\n valid: boolean;\n apiKey: string;\n error?: string;\n}\n\nexport interface LocalAuthResult {\n apiKey: string;\n userId: string;\n email: string;\n}\n\ninterface SetupAuthOptions {\n supabaseUrl?: string;\n anonKey?: string;\n localDev?: boolean;\n}\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nfunction getSupabaseUrl(options?: SetupAuthOptions): string {\n return options?.supabaseUrl ?? process.env.SUPABASE_URL ?? PRODUCTION_SUPABASE_URL;\n}\n\nfunction isLocalSupabaseUrl(supabaseUrl: string): boolean {\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nfunction isLocalMode(options?: SetupAuthOptions): boolean {\n if (options?.localDev !== undefined) return options.localDev;\n if (isTruthy(process.env.FORCEFIELD_LOCAL_DEV)) return true;\n return isLocalSupabaseUrl(getSupabaseUrl(options));\n}\n\nfunction getAnonKey(supabaseUrl: string, options?: SetupAuthOptions): string {\n const explicit = options?.anonKey ?? process.env.SUPABASE_ANON_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_ANON_KEY;\n }\n\n return PRODUCTION_SUPABASE_PUBLISHABLE_KEY;\n}\n\nfunction getServiceRoleKey(supabaseUrl: string): string | null {\n const explicit = process.env.SUPABASE_SERVICE_ROLE_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_SERVICE_ROLE_KEY;\n }\n\n return null;\n}\n\n/**\n * Validate API key format.\n */\nexport function validateApiKeyFormat(key: string): boolean {\n return key.startsWith(API_KEY_PREFIX) && key.length > API_KEY_PREFIX.length + 8;\n}\n\n/**\n * Verify an API key through key-exchange endpoint.\n */\nexport async function verifyApiKey(apiKey: string, options?: SetupAuthOptions): Promise<AuthResult> {\n if (!validateApiKeyFormat(apiKey)) {\n return {\n valid: false,\n apiKey: '',\n error: 'Invalid API key format. Keys must start with \"ff_live_\".',\n };\n }\n\n const supabaseUrl = getSupabaseUrl(options);\n const endpoint = `${supabaseUrl}/functions/v1/key-exchange`;\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const payload = await response.json().catch(() => ({})) as { error?: string };\n const detail = payload.error ?? 'API key invalid or revoked.';\n return {\n valid: false,\n apiKey: '',\n error: `Authentication failed (${response.status}): ${detail}`,\n };\n }\n\n return { valid: true, apiKey };\n } catch {\n return {\n valid: false,\n apiKey: '',\n error: `Could not reach Forcefield backend at ${supabaseUrl}. Check SUPABASE_URL/network and retry.`,\n };\n }\n}\n\n/**\n * Authenticate with retries.\n */\nexport async function authenticateWithRetry(\n getKey: () => Promise<string | null>,\n options?: SetupAuthOptions,\n): Promise<AuthResult> {\n let lastError: string | undefined;\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n const key = await getKey();\n\n if (!key) {\n return { valid: false, apiKey: '', error: 'No API key provided.' };\n }\n\n const verified = await verifyApiKey(key, options);\n if (verified.valid) {\n return verified;\n }\n\n lastError = verified.error;\n\n if (attempt < MAX_RETRIES) {\n continue;\n }\n }\n\n return {\n valid: false,\n apiKey: '',\n error: lastError ?? `Authentication failed after ${MAX_RETRIES} attempts.`,\n };\n}\n\nfunction generateApiKey(): { plaintext: string; hash: string; prefix: string } {\n const raw = randomBytes(32).toString('hex');\n const plaintext = `${API_KEY_PREFIX}${raw}`;\n const hash = createHash('sha256').update(plaintext).digest('hex');\n const prefix = plaintext.slice(0, 12);\n return { plaintext, hash, prefix };\n}\n\n/**\n * Hosted/local account flow:\n * 1. Sign in (or sign up + sign in)\n * 2. Insert API key under authenticated user\n */\nexport async function authenticateAccountAndCreateApiKey(\n email: string,\n password: string,\n options?: {\n supabaseUrl?: string;\n anonKey?: string;\n label?: string;\n localDev?: boolean;\n },\n): Promise<LocalAuthResult> {\n const supabaseUrl = getSupabaseUrl(options);\n const anonKey = getAnonKey(supabaseUrl, options);\n\n const supabase = createClient(supabaseUrl, anonKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let signIn = await supabase.auth.signInWithPassword({ email, password });\n\n if (signIn.error || !signIn.data.user) {\n await supabase.auth.signUp({ email, password });\n signIn = await supabase.auth.signInWithPassword({ email, password });\n }\n\n if (signIn.error || !signIn.data.user) {\n const message = signIn.error?.message ?? 'Invalid login credentials';\n throw new Error(`Authentication failed: ${message}`);\n }\n\n const userId = signIn.data.user.id;\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await supabase\n .from('api_keys')\n .insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: options?.label ?? 'Setup Wizard Key',\n tier: 'free',\n });\n\n if (insertError) {\n if (isLocalMode(options)) {\n const serviceRoleKey = getServiceRoleKey(supabaseUrl);\n if (serviceRoleKey) {\n return createApiKeyViaServiceRole({\n supabaseUrl,\n serviceRoleKey,\n email,\n password,\n label: options?.label ?? 'Setup Wizard Key',\n });\n }\n }\n\n throw new Error(`Failed to create API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email,\n };\n}\n\n/**\n * Local auth flow preserved for scripted local development.\n */\nexport async function authenticateLocalAndCreateApiKey(\n email: string,\n password: string,\n options?: { supabaseUrl?: string; anonKey?: string; label?: string },\n): Promise<LocalAuthResult> {\n return authenticateAccountAndCreateApiKey(email, password, {\n ...options,\n localDev: true,\n label: options?.label ?? 'Local Setup Key',\n });\n}\n\nasync function createApiKeyViaServiceRole(params: {\n supabaseUrl: string;\n serviceRoleKey: string;\n email: string;\n password: string;\n label: string;\n}): Promise<LocalAuthResult> {\n const admin = createClient(params.supabaseUrl, params.serviceRoleKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let userId: string | undefined;\n const createUser = await admin.auth.admin.createUser({\n email: params.email,\n password: params.password,\n email_confirm: true,\n });\n\n if (createUser.data.user?.id) {\n userId = createUser.data.user.id;\n } else if (createUser.error) {\n const authDb = createClient(params.supabaseUrl, params.serviceRoleKey, {\n db: { schema: 'auth' },\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n const existingUser = await authDb\n .from('users')\n .select('id,email')\n .eq('email', params.email)\n .limit(1)\n .maybeSingle();\n\n if (existingUser.error) {\n throw new Error(`Local login failed: ${createUser.error.message}`);\n }\n userId = existingUser.data?.id;\n }\n\n if (!userId) {\n throw new Error('Local login failed: could not resolve user account');\n }\n\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await admin.from('api_keys').insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: params.label,\n tier: 'free',\n });\n\n if (insertError) {\n throw new Error(`Failed to create local API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email: params.email,\n };\n}\n\nexport { API_KEY_PREFIX, MAX_RETRIES };\n","/**\n * Forcefield Setup Wizard — entry point.\n *\n * This is the setup wizard binary (forcefield-setup), invoked via\n * `npx -y -p @forcefield/mcp-server forcefield setup`.\n * Parses CLI arguments and launches the interactive wizard.\n */\n\nimport type { CliArgs, Ide, SetupMode } from './types.js';\nimport { runWizard } from './wizard.js';\nimport { pathToFileURL } from 'node:url';\n\nfunction parseArgs(argv: string[]): CliArgs {\n const args: CliArgs = {};\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i]!;\n\n if (arg === '--status') {\n args.status = true;\n } else if (arg === '--doctor') {\n args.doctor = true;\n } else if (arg === '--ide' && argv[i + 1]) {\n const ide = argv[++i]!;\n if (['claude-code', 'cursor', 'codex', 'windsurf'].includes(ide)) {\n args.ide = ide as Ide;\n }\n } else if (arg === '--mode' && argv[i + 1]) {\n const mode = argv[++i]!;\n if (['full', 'core'].includes(mode)) {\n args.mode = mode as SetupMode;\n }\n } else if (arg === '--token' && argv[i + 1]) {\n args.token = argv[++i]!;\n } else if (arg === '--email' && argv[i + 1]) {\n args.email = argv[++i]!;\n } else if (arg === '--password' && argv[i + 1]) {\n args.password = argv[++i]!;\n } else if (arg === '--local-auth') {\n args.localAuth = true;\n }\n }\n\n return args;\n}\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv);\n const projectDir = process.cwd();\n\n try {\n await runWizard(projectDir, args);\n } catch (err) {\n console.error('Setup failed:', err instanceof Error ? err.message : err);\n process.exit(1);\n }\n}\n\nexport async function runSetupCli(argv: string[] = process.argv): Promise<void> {\n const originalArgv = process.argv;\n process.argv = argv;\n try {\n await main();\n } finally {\n process.argv = originalArgv;\n }\n}\n\nfunction isExecutedDirectly(metaUrl: string): boolean {\n const entryPath = process.argv[1];\n if (!entryPath) return false;\n return metaUrl === pathToFileURL(entryPath).href;\n}\n\nif (isExecutedDirectly(import.meta.url)) {\n void runSetupCli();\n}\n\nexport { parseArgs };\n"],"mappings":";;;;;;;;;AAaA,YAAY,OAAO;AACnB,OAAO,QAAQ;AACf,OAAO,YAAY;AACnB,OAAO,cAAc;AACrB,SAAS,YAAAA,WAAU,aAAAC,YAAW,UAAAC,eAAc;AAC5C,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAC9B,SAAS,iBAAAC,sBAAqB;;;ACf9B,SAAS,cAAc;AACvB,SAAS,YAAY;AAQrB,IAAM,cAAmE;AAAA,EACvE,EAAE,KAAK,eAAe,QAAQ,WAAW,OAAO,KAAK;AAAA,EACrD,EAAE,KAAK,UAAU,QAAQ,WAAW,OAAO,KAAK;AAAA,EAChD,EAAE,KAAK,SAAS,QAAQ,aAAa,OAAO,MAAM;AAAA,EAClD,EAAE,KAAK,YAAY,QAAQ,kBAAkB,OAAO,MAAM;AAC5D;AAEA,eAAsB,UAAU,YAA8C;AAC5E,QAAM,QAA6C,CAAC;AAEpD,aAAW,EAAE,KAAK,OAAO,KAAK,aAAa;AACzC,UAAM,aAAa,KAAK,YAAY,MAAM;AAC1C,QAAI;AACF,YAAM,OAAO,UAAU;AACvB,YAAM,KAAK,EAAE,KAAK,OAAO,CAAC;AAAA,IAC5B,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,MAAM,WAAW,IAAI,MAAM,CAAC,EAAG,MAAM;AAAA,IAC/C,SAAS;AAAA,EACX;AACF;;;AC/BA,SAAS,OAAO,SAAS,UAAU,IAAI,UAAU,iBAAiB;AAClE,SAAS,QAAAC,aAAY;;;ACPrB,SAAS,UAAAC,eAAc;AACvB,SAAS,SAAS,QAAAC,aAAY;AAC9B,SAAS,qBAAqB;AAE9B,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,yBAAyB;AAAA,EAC7BA,MAAK,WAAW,MAAM,MAAM,SAAS,UAAU;AAAA,EAC/CA,MAAK,WAAW,MAAM,MAAM,UAAU;AACxC;AACA,IAAM,4BAA4B,UAAU,SAAS,cAAc;AAEnE,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,SAAS,OAAoC;AACpD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAC5C,SAAO,eAAe,OAAO,eAAe,UAAU,eAAe,SAAS,eAAe;AAC/F;AAEA,eAAe,oBAA4C;AACzD,aAAW,aAAa,wBAAwB;AAC9C,QAAI;AACF,YAAMD,QAAO,SAAS;AACtB,aAAO;AAAA,IACT,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,qBAAmE;AACvF,MACE,6BACG,SAAS,QAAQ,IAAI,oBAAoB,KACzC,SAAS,QAAQ,IAAI,gCAAgC,GACxD;AACA,UAAM,aAAa,MAAM,kBAAkB;AAC3C,QAAI,YAAY;AACd,aAAO;AAAA,QACL,SAAS,QAAQ;AAAA,QACjB,MAAM,CAAC,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,MAAM,MAAM,0BAA0B,gBAAgB;AAAA,EAC/D;AACF;AAEO,SAAS,YAAY,QAAwC;AAClE,QAAM,MAA8B;AAAA,IAClC,oBAAoB;AAAA,EACtB;AAEA,aAAW,OAAO,oBAAoB;AACpC,UAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,QAAI,SAAS,MAAM,KAAK,EAAE,SAAS,GAAG;AACpC,UAAI,GAAG,IAAI;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AACT;;;AD5DO,IAAM,oBAAgC;AAAA,EAC3C,MAAM;AAAA,EAEN,MAAM,aAAa,YAAoB,QAA+B;AAEpE,UAAM,YAAYE,MAAK,YAAY,SAAS;AAC5C,UAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAG1C,UAAM,SAAS,MAAM,mBAAmB;AACxC,UAAM,UAAUA,MAAK,YAAY,WAAW;AAE5C,QAAI,WAAoC,CAAC;AACzC,QAAI;AACF,iBAAW,KAAK,MAAM,MAAM,SAAS,SAAS,OAAO,CAAC;AAAA,IACxD,QAAQ;AAAA,IAER;AAEA,UAAM,kBACJ,OAAO,SAAS,eAAe,YAAY,SAAS,cAAc,OAC7D,SAAS,aACV,CAAC;AAEP,oBAAgB,aAAa;AAAA,MAC3B,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,KAAK,YAAY,MAAM;AAAA,IACzB;AAEA,UAAM,aAAa;AAAA,MACjB,GAAG;AAAA,MACH,YAAY;AAAA,IACd;AAEA,UAAM,UAAU,SAAS,KAAK,UAAU,YAAY,MAAM,CAAC,IAAI,MAAM,OAAO;AAAA,EAC9E;AAAA,EAEA,MAAM,iBAAiB,YAAoB,cAAuC;AAChF,UAAM,cAAcA,MAAK,YAAY,WAAW,UAAU;AAC1D,UAAM,MAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAE5C,UAAM,QAAQ,MAAM,QAAQ,YAAY;AACxC,UAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK,EAAE,SAAS,KAAK,CAAC;AAE5E,eAAW,QAAQ,SAAS;AAC1B,YAAM,SAASA,MAAK,cAAc,IAAI,GAAGA,MAAK,aAAa,IAAI,CAAC;AAAA,IAClE;AAEA,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,gBAAgB,YAAmC;AACvD,UAAM,cAAcA,MAAK,YAAY,WAAW,UAAU;AAC1D,QAAI;AACF,YAAM,QAAQ,MAAM,QAAQ,WAAW;AACvC,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,WAAW,KAAK,KAAK,KAAK,SAAS,KAAK,GAAG;AAClD,gBAAM,GAAGA,MAAK,aAAa,IAAI,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;AEtEA,SAAS,SAAAC,QAAO,WAAAC,UAAS,YAAAC,WAAU,MAAAC,KAAI,YAAAC,WAAU,aAAAC,kBAAiB;AAClE,SAAS,QAAAC,aAAY;AAQd,IAAM,gBAA4B;AAAA,EACvC,MAAM;AAAA,EAEN,MAAM,aAAa,YAAoB,QAA+B;AACpE,UAAM,YAAYC,MAAK,YAAY,SAAS;AAC5C,UAAMC,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAE1C,UAAM,aAAaD,MAAK,WAAW,UAAU;AAC7C,UAAM,SAAS,MAAM,mBAAmB;AAExC,QAAI,WAA4B,CAAC;AACjC,QAAI;AACF,iBAAW,KAAK,MAAM,MAAME,UAAS,YAAY,OAAO,CAAC;AAAA,IAC3D,QAAQ;AAAA,IAER;AAEA,UAAM,kBACJ,OAAO,SAAS,eAAe,YAAY,SAAS,cAAc,OAC9D,SAAS,aACT,CAAC;AAEP,oBAAgB,aAAa;AAAA,MAC3B,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,KAAK,YAAY,MAAM;AAAA,IACzB;AAEA,UAAM,SAA0B;AAAA,MAC9B,GAAG;AAAA,MACH,YAAY;AAAA,IACd;AAEA,UAAMC,WAAU,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AAAA,EAC7E;AAAA,EAEA,MAAM,iBAAiB,YAAoB,cAAuC;AAChF,UAAM,WAAWH,MAAK,YAAY,WAAW,OAAO;AACpD,UAAMC,OAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAEzC,UAAM,QAAQ,MAAMG,SAAQ,YAAY;AACxC,UAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK,EAAE,SAAS,KAAK,CAAC;AAE5E,eAAW,QAAQ,SAAS;AAC1B,YAAMC,UAASL,MAAK,cAAc,IAAI,GAAGA,MAAK,UAAU,IAAI,CAAC;AAAA,IAC/D;AAEA,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,gBAAgB,YAAmC;AACvD,UAAM,WAAWA,MAAK,YAAY,WAAW,OAAO;AACpD,QAAI;AACF,YAAM,QAAQ,MAAMI,SAAQ,QAAQ;AACpC,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,WAAW,KAAK,KAAK,KAAK,SAAS,KAAK,GAAG;AAClD,gBAAME,IAAGN,MAAK,UAAU,IAAI,CAAC;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;ACxEA,SAAS,SAAAO,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAC3C,SAAS,QAAAC,aAAY;AAIrB,IAAM,eAAe;AACrB,IAAM,aAAa;AACnB,IAAM,mBAAmB;AACzB,IAAM,iBAAiB;AAEhB,IAAM,eAA2B;AAAA,EACtC,MAAM;AAAA,EAEN,MAAM,aAAa,YAAoB,QAA+B;AACpE,UAAM,WAAWC,MAAK,YAAY,QAAQ;AAC1C,UAAMC,OAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAEzC,UAAM,aAAaD,MAAK,UAAU,aAAa;AAC/C,UAAM,SAAS,MAAM,mBAAmB;AACxC,UAAM,MAAM,YAAY,MAAM;AAE9B,UAAM,kBAAkB,yBAAyB,OAAO,SAAS,OAAO,MAAM,GAAG;AAEjF,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAME,UAAS,YAAY,OAAO;AAAA,IAC/C,QAAQ;AAAA,IAER;AAEA,UAAM,UAAU,4BAA4B,QAAQ,EAAE,KAAK;AAC3D,UAAM,QAAQ,UAAU,GAAG,OAAO;AAAA;AAAA,EAAO,eAAe;AAAA,IAAO,GAAG,eAAe;AAAA;AACjF,UAAMC,WAAU,YAAY,OAAO,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAM,iBAAiB,YAAoB,cAAuC;AAChF,UAAM,aAAaH,MAAK,YAAY,WAAW;AAC/C,UAAM,EAAE,SAAAI,SAAQ,IAAI,MAAM,OAAO,aAAkB;AAGnD,UAAM,QAAQ,MAAMA,SAAQ,YAAY;AACxC,UAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK,EAAE,SAAS,KAAK,CAAC;AAE5E,UAAM,mBAA6B,CAAC;AACpC,eAAW,QAAQ,SAAS;AAC1B,YAAM,UAAU,MAAMF,UAASF,MAAK,cAAc,IAAI,GAAG,OAAO;AAChE,uBAAiB,KAAK,OAAO;AAAA,IAC/B;AAEA,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,iBAAiB,IAAI,CAAC,MAAM,IAAI,WAAW;AAAA,MAC9C;AAAA,IACF,EAAE,KAAK,IAAI;AAGX,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAME,UAAS,YAAY,OAAO;AAAA,IAC/C,QAAQ;AAAA,IAER;AAGA,UAAM,UAAU,cAAc,QAAQ;AAGtC,UAAM,QAAQ,QAAQ,KAAK,IACvB,QAAQ,KAAK,IAAI,SAAS,oBAC1B;AAEJ,UAAMC,WAAU,YAAY,OAAO,OAAO;AAC1C,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,gBAAgB,YAAmC;AACvD,UAAM,aAAaH,MAAK,YAAY,WAAW;AAC/C,QAAI;AACF,YAAM,UAAU,MAAME,UAAS,YAAY,OAAO;AAClD,YAAM,UAAU,cAAc,OAAO;AACrC,YAAMC,WAAU,YAAY,SAAS,OAAO;AAAA,IAC9C,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAAS,cAAc,SAAyB;AAC9C,QAAM,WAAW,QAAQ,QAAQ,YAAY;AAC7C,QAAM,SAAS,QAAQ,QAAQ,UAAU;AAEzC,MAAI,aAAa,MAAM,WAAW,GAAI,QAAO;AAE7C,QAAM,SAAS,QAAQ,MAAM,GAAG,QAAQ,EAAE,QAAQ;AAClD,QAAM,QAAQ,QAAQ,MAAM,SAAS,WAAW,MAAM,EAAE,UAAU;AAElE,SAAO,UAAU,QAAQ,SAAS,QAAQ;AAC5C;AAEA,SAAS,4BAA4B,SAAyB;AAC5D,QAAM,cAAc,QAAQ,QAAQ,gBAAgB;AACpD,QAAM,YAAY,QAAQ,QAAQ,cAAc;AAEhD,MAAI,gBAAgB,MAAM,cAAc,IAAI;AAC1C,UAAM,SAAS,QAAQ,MAAM,GAAG,WAAW,EAAE,QAAQ;AACrD,UAAM,QAAQ,QAAQ,MAAM,YAAY,eAAe,MAAM,EAAE,UAAU;AACzE,WAAO,UAAU,QAAQ,SAAS,QAAQ;AAAA,EAC5C;AAGA,SAAO,QACJ,QAAQ,qDAAqD,EAAE,EAC/D,QAAQ,0DAA0D,EAAE,EACpE,KAAK;AACV;AAEA,SAAS,yBACP,SACA,MACA,KACQ;AACR,QAAM,WAAW,OAAO,QAAQ,GAAG,EAChC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,OAAO,iBAAiB,KAAK,CAAC,GAAG;AAEhE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc,iBAAiB,OAAO,CAAC;AAAA,IACvC,WAAW,KAAK,IAAI,CAAC,QAAQ,IAAI,iBAAiB,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IACrE;AAAA,IACA,GAAG;AAAA,IACH;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,SAAO,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACzD;;;AC9IA,SAAS,SAAAE,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAC3C,SAAS,QAAAC,aAAY;AAIrB,IAAMC,gBAAe;AACrB,IAAMC,cAAa;AAEZ,IAAM,kBAA8B;AAAA,EACzC,MAAM;AAAA,EAEN,MAAM,aAAa,YAAoB,QAA+B;AACpE,UAAM,YAAYC,MAAK,YAAY,WAAW;AAC9C,UAAMC,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAE1C,UAAM,aAAaD,MAAK,WAAW,iBAAiB;AACpD,UAAM,SAAS,MAAM,mBAAmB;AAExC,QAAI,WAAoC,CAAC;AACzC,QAAI;AACF,iBAAW,KAAK,MAAM,MAAME,UAAS,YAAY,OAAO,CAAC;AAAA,IAC3D,QAAQ;AAAA,IAER;AAEA,UAAM,kBACJ,OAAO,SAAS,eAAe,YAAY,SAAS,cAAc,OAC7D,SAAS,aACV,CAAC;AAEP,oBAAgB,aAAa;AAAA,MAC3B,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,MACb,KAAK,YAAY,MAAM;AAAA,IACzB;AAEA,UAAM,SAAS;AAAA,MACb,GAAG;AAAA,MACH,YAAY;AAAA,IACd;AAEA,UAAMC,WAAU,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AAAA,EAC7E;AAAA,EAEA,MAAM,iBAAiB,YAAoB,cAAuC;AAChF,UAAM,YAAYH,MAAK,YAAY,gBAAgB;AACnD,UAAM,EAAE,SAAAI,SAAQ,IAAI,MAAM,OAAO,aAAkB;AAEnD,UAAM,QAAQ,MAAMA,SAAQ,YAAY;AACxC,UAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK,EAAE,SAAS,KAAK,CAAC;AAE5E,UAAM,mBAA6B,CAAC;AACpC,eAAW,QAAQ,SAAS;AAC1B,YAAM,UAAU,MAAMF,UAASF,MAAK,cAAc,IAAI,GAAG,OAAO;AAChE,uBAAiB,KAAK,OAAO;AAAA,IAC/B;AAEA,UAAM,oBAAoB;AAAA,MACxBF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,iBAAiB,IAAI,CAAC,MAAM,IAAI,WAAW;AAAA,MAC9CC;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAMG,UAAS,WAAW,OAAO;AAAA,IAC9C,QAAQ;AAAA,IAER;AAEA,UAAM,UAAUG,eAAc,QAAQ;AACtC,UAAM,QAAQ,QAAQ,KAAK,IACvB,QAAQ,KAAK,IAAI,SAAS,oBAC1B;AAEJ,UAAMF,WAAU,WAAW,OAAO,OAAO;AACzC,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,gBAAgB,YAAmC;AACvD,UAAM,YAAYH,MAAK,YAAY,gBAAgB;AACnD,QAAI;AACF,YAAM,UAAU,MAAME,UAAS,WAAW,OAAO;AACjD,YAAM,UAAUG,eAAc,OAAO;AACrC,YAAMF,WAAU,WAAW,SAAS,OAAO;AAAA,IAC7C,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAASE,eAAc,SAAyB;AAC9C,QAAM,WAAW,QAAQ,QAAQP,aAAY;AAC7C,QAAM,SAAS,QAAQ,QAAQC,WAAU;AAEzC,MAAI,aAAa,MAAM,WAAW,GAAI,QAAO;AAE7C,QAAM,SAAS,QAAQ,MAAM,GAAG,QAAQ,EAAE,QAAQ;AAClD,QAAM,QAAQ,QAAQ,MAAM,SAASA,YAAW,MAAM,EAAE,UAAU;AAElE,SAAO,UAAU,QAAQ,SAAS,QAAQ;AAC5C;;;ACpGA,IAAM,WAAoC;AAAA,EACxC,eAAe;AAAA,EACf,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AACd;AAEO,SAAS,WAAW,KAAsB;AAC/C,SAAO,SAAS,GAAG;AACrB;AAEO,IAAM,cAAkE;AAAA,EAC7E,EAAE,OAAO,eAAe,OAAO,eAAe,MAAM,oBAAoB;AAAA,EACxE,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,iBAAiB;AAAA,EAC3D,EAAE,OAAO,SAAS,OAAO,kBAAkB,MAAM,YAAY;AAAA,EAC7D,EAAE,OAAO,YAAY,OAAO,YAAY,MAAM,iBAAiB;AACjE;;;ACtBA,SAAS,YAAY,mBAAmB;AACxC,SAAS,oBAAoB;AAQ7B,IAAM,iBAAiB;AACvB,IAAM,cAAc;AAoBpB,SAASO,UAAS,OAAoC;AACpD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAC5C,SAAO,eAAe,OAAO,eAAe,UAAU,eAAe,SAAS,eAAe;AAC/F;AAEA,SAAS,eAAe,SAAoC;AAC1D,SAAO,SAAS,eAAe,QAAQ,IAAI,gBAAgB;AAC7D;AAEA,SAAS,mBAAmB,aAA8B;AACxD,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,WAAW;AAClC,WAAO,OAAO,aAAa,eAAe,OAAO,aAAa;AAAA,EAChE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,SAAqC;AACxD,MAAI,SAAS,aAAa,OAAW,QAAO,QAAQ;AACpD,MAAIA,UAAS,QAAQ,IAAI,oBAAoB,EAAG,QAAO;AACvD,SAAO,mBAAmB,eAAe,OAAO,CAAC;AACnD;AAEA,SAAS,WAAW,aAAqB,SAAoC;AAC3E,QAAM,WAAW,SAAS,WAAW,QAAQ,IAAI;AACjD,MAAI,YAAY,SAAS,KAAK,EAAE,SAAS,EAAG,QAAO;AAEnD,MAAI,mBAAmB,WAAW,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,aAAoC;AAC7D,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,YAAY,SAAS,KAAK,EAAE,SAAS,EAAG,QAAO;AAEnD,MAAI,mBAAmB,WAAW,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,SAAS,qBAAqB,KAAsB;AACzD,SAAO,IAAI,WAAW,cAAc,KAAK,IAAI,SAAS,eAAe,SAAS;AAChF;AAKA,eAAsB,aAAa,QAAgB,SAAiD;AAClG,MAAI,CAAC,qBAAqB,MAAM,GAAG;AACjC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,WAAW,GAAG,WAAW;AAE/B,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,UAAU;AAAA,MACrC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,MAAM;AAAA,QAC/B,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACtD,YAAM,SAAS,QAAQ,SAAS;AAChC,aAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,OAAO,0BAA0B,SAAS,MAAM,MAAM,MAAM;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO,EAAE,OAAO,MAAM,OAAO;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,yCAAyC,WAAW;AAAA,IAC7D;AAAA,EACF;AACF;AAKA,eAAsB,sBACpB,QACA,SACqB;AACrB,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,UAAM,MAAM,MAAM,OAAO;AAEzB,QAAI,CAAC,KAAK;AACR,aAAO,EAAE,OAAO,OAAO,QAAQ,IAAI,OAAO,uBAAuB;AAAA,IACnE;AAEA,UAAM,WAAW,MAAM,aAAa,KAAK,OAAO;AAChD,QAAI,SAAS,OAAO;AAClB,aAAO;AAAA,IACT;AAEA,gBAAY,SAAS;AAErB,QAAI,UAAU,aAAa;AACzB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO,aAAa,+BAA+B,WAAW;AAAA,EAChE;AACF;AAEA,SAAS,iBAAsE;AAC7E,QAAM,MAAM,YAAY,EAAE,EAAE,SAAS,KAAK;AAC1C,QAAM,YAAY,GAAG,cAAc,GAAG,GAAG;AACzC,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,SAAS,EAAE,OAAO,KAAK;AAChE,QAAM,SAAS,UAAU,MAAM,GAAG,EAAE;AACpC,SAAO,EAAE,WAAW,MAAM,OAAO;AACnC;AAOA,eAAsB,mCACpB,OACA,UACA,SAM0B;AAC1B,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,UAAU,WAAW,aAAa,OAAO;AAE/C,QAAM,WAAW,aAAa,aAAa,SAAS;AAAA,IAClD,MAAM;AAAA,MACJ,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,IACpB;AAAA,EACF,CAAC;AAED,MAAI,SAAS,MAAM,SAAS,KAAK,mBAAmB,EAAE,OAAO,SAAS,CAAC;AAEvE,MAAI,OAAO,SAAS,CAAC,OAAO,KAAK,MAAM;AACrC,UAAM,SAAS,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC;AAC9C,aAAS,MAAM,SAAS,KAAK,mBAAmB,EAAE,OAAO,SAAS,CAAC;AAAA,EACrE;AAEA,MAAI,OAAO,SAAS,CAAC,OAAO,KAAK,MAAM;AACrC,UAAM,UAAU,OAAO,OAAO,WAAW;AACzC,UAAM,IAAI,MAAM,0BAA0B,OAAO,EAAE;AAAA,EACrD;AAEA,QAAM,SAAS,OAAO,KAAK,KAAK;AAChC,QAAM,EAAE,WAAW,MAAM,OAAO,IAAI,eAAe;AACnD,QAAM,EAAE,OAAO,YAAY,IAAI,MAAM,SAClC,KAAK,UAAU,EACf,OAAO;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO,SAAS,SAAS;AAAA,IACzB,MAAM;AAAA,EACR,CAAC;AAEH,MAAI,aAAa;AACf,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,iBAAiB,kBAAkB,WAAW;AACpD,UAAI,gBAAgB;AAClB,eAAO,2BAA2B;AAAA,UAChC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO,SAAS,SAAS;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,6BAA6B,YAAY,OAAO,EAAE;AAAA,EACpE;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF;AACF;AAKA,eAAsB,iCACpB,OACA,UACA,SAC0B;AAC1B,SAAO,mCAAmC,OAAO,UAAU;AAAA,IACzD,GAAG;AAAA,IACH,UAAU;AAAA,IACV,OAAO,SAAS,SAAS;AAAA,EAC3B,CAAC;AACH;AAEA,eAAe,2BAA2B,QAMb;AAC3B,QAAM,QAAQ,aAAa,OAAO,aAAa,OAAO,gBAAgB;AAAA,IACpE,MAAM;AAAA,MACJ,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,IACpB;AAAA,EACF,CAAC;AAED,MAAI;AACJ,QAAM,aAAa,MAAM,MAAM,KAAK,MAAM,WAAW;AAAA,IACnD,OAAO,OAAO;AAAA,IACd,UAAU,OAAO;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AAED,MAAI,WAAW,KAAK,MAAM,IAAI;AAC5B,aAAS,WAAW,KAAK,KAAK;AAAA,EAChC,WAAW,WAAW,OAAO;AAC3B,UAAM,SAAS,aAAa,OAAO,aAAa,OAAO,gBAAgB;AAAA,MACrE,IAAI,EAAE,QAAQ,OAAO;AAAA,MACrB,MAAM;AAAA,QACJ,gBAAgB;AAAA,QAChB,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAED,UAAM,eAAe,MAAM,OACxB,KAAK,OAAO,EACZ,OAAO,UAAU,EACjB,GAAG,SAAS,OAAO,KAAK,EACxB,MAAM,CAAC,EACP,YAAY;AAEf,QAAI,aAAa,OAAO;AACtB,YAAM,IAAI,MAAM,uBAAuB,WAAW,MAAM,OAAO,EAAE;AAAA,IACnE;AACA,aAAS,aAAa,MAAM;AAAA,EAC9B;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,QAAM,EAAE,WAAW,MAAM,OAAO,IAAI,eAAe;AACnD,QAAM,EAAE,OAAO,YAAY,IAAI,MAAM,MAAM,KAAK,UAAU,EAAE,OAAO;AAAA,IACjE,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO,OAAO;AAAA,IACd,MAAM;AAAA,EACR,CAAC;AAED,MAAI,aAAa;AACf,UAAM,IAAI,MAAM,mCAAmC,YAAY,OAAO,EAAE;AAAA,EAC1E;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,OAAO,OAAO;AAAA,EAChB;AACF;;;AR5SA,IAAMC,aAAYC,SAAQC,eAAc,YAAY,GAAG,CAAC;AACxD,IAAM,0BAA0B;AAAA,EAC9BC,MAAKH,YAAW,MAAM,WAAW;AAAA,EACjCG,MAAKH,YAAW,MAAM,MAAM,WAAW;AACzC;AACA,IAAM,cAAc;AACpB,IAAM,UAAU;AAChB,IAAM,cAAc;AACpB,IAAM,cAAc;AACpB,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB;AAExB,IAAM,wBAAwB,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAC1G,IAAM,iBAAiB,SAAS,qBAAqB;AAErD,eAAe,sBAAuC;AACpD,aAAW,OAAO,yBAAyB;AACzC,QAAI;AACF,YAAMI,QAAO,GAAG;AAChB,aAAO;AAAA,IACT,QAAQ;AAAA,IAER;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR,iDAAiD,wBAAwB,KAAK,IAAI,CAAC;AAAA,EACrF;AACF;AAKA,eAAsB,UAAU,YAAoB,MAA8B;AAEhF,MAAI,KAAK,QAAQ;AACf,UAAM,WAAW,UAAU;AAC3B;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,UAAM,UAAU,YAAY,IAAI;AAChC;AAAA,EACF;AAGA,MAAI,KAAK,OAAO,KAAK,SAAS,KAAK,SAAS,KAAK,aAAc,KAAK,SAAS,KAAK,WAAY;AAC5F,UAAM,kBAAkB,YAAY,IAAI;AACxC;AAAA,EACF;AAGA,QAAM,eAAe,YAAY,IAAI;AACvC;AAIA,SAAS,aAAmB;AAC1B,QAAM,OAAO,QAAQ,OAAO,WAAW;AAEvC,MAAI,QAAQ,oBAAoB;AAC9B,QAAI;AACF,YAAM,SAAS,OAAO,SAAS,aAAa,EAAE,MAAM,YAAY,CAAC;AACjE,YAAM,UAAU,oBAAoB,MAAM;AAC1C,cAAQ,IAAI,OAAO;AAAA,IACrB,QAAQ;AAEN,cAAQ,IAAI,GAAG,KAAK,oBAAoB,oBAAoB,CAAC,CAAC;AAAA,IAChE;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,GAAG,KAAK,oBAAoB,oBAAoB,CAAC,CAAC;AAAA,EAChE;AACA,UAAQ,IAAI,GAAG,IAAI,eAAe,CAAC;AACrC;AAEA,SAAS,oBAAoBC,OAAsB;AACjD,SAAO,eAAe,UAAUA,KAAI;AACtC;AAIA,eAAe,WAAW,YAAmC;AAC3D,QAAM,SAAS,MAAM,WAAW,UAAU;AAE1C,MAAI,CAAC,QAAQ;AACX,YAAQ,IAAI,GAAG,OAAO,8CAA8C,CAAC;AACrE,YAAQ,IAAI,OAAO,GAAG,KAAK,kBAAkB,CAAC,kBAAkB;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,GAAG,KAAK,yBAAyB,CAAC;AAC9C,UAAQ,IAAI,UAAU,GAAG,KAAK,OAAO,GAAG,CAAC,EAAE;AAC3C,UAAQ,IAAI,WAAW,GAAG,KAAK,OAAO,IAAI,CAAC,EAAE;AAC7C,UAAQ,IAAI,cAAc,GAAG,KAAK,OAAO,OAAO,CAAC,EAAE;AACnD,UAAQ,IAAI,gBAAgB,GAAG,IAAI,OAAO,YAAY,CAAC,EAAE;AAC3D;AAeA,eAAe,UAAU,YAAoB,MAA8B;AACzE,UAAQ,IAAI,GAAG,KAAK,yBAAyB,CAAC;AAC9C,UAAQ,IAAI,GAAG,IAAI,YAAY,UAAU,EAAE,CAAC;AAE5C,QAAM,SAA8B,CAAC;AACrC,QAAM,SAAS,MAAM,WAAW,UAAU;AAE1C,MAAI,CAAC,QAAQ;AACX,WAAO,KAAK;AAAA,MACV,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ,WAAW,WAAW;AAAA,IAChC,CAAC;AAAA,EACH,OAAO;AACL,WAAO,KAAK;AAAA,MACV,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ,GAAG,OAAO,GAAG,MAAM,OAAO,IAAI,OAAO,OAAO,OAAO;AAAA,IAC7D,CAAC;AAED,UAAM,MAAM,MAAM,iBAAiB,YAAY,OAAO,GAAG;AACzD,WAAO,KAAK;AAAA,MACV,IAAI,IAAI;AAAA,MACR,OAAO;AAAA,MACP,QAAQ,GAAG,IAAI,QAAQ,WAAM,IAAI,MAAM;AAAA,IACzC,CAAC;AAED,QAAI,IAAI,KAAK;AACX,YAAM,WAAW,MAAM,aAAa,IAAI,KAAK,EAAE,UAAU,iBAAiB,IAAI,EAAE,CAAC;AACjF,aAAO,KAAK;AAAA,QACV,IAAI,SAAS;AAAA,QACb,OAAO;AAAA,QACP,QAAQ,SAAS,QACb,4BACC,SAAS,SAAS;AAAA,MACzB,CAAC;AAAA,IACH,OAAO;AACL,aAAO,KAAK;AAAA,QACV,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ;AAC1B,UAAM,SAAS,MAAM,KAAK,GAAG,MAAM,QAAG,IAAI,GAAG,IAAI,QAAG;AACpD,YAAQ,IAAI,GAAG,MAAM,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,KAAK,MAAM,MAAM,EAAE;AAAA,EAClE;AAEA,QAAM,WAAW,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE;AACnD,MAAI,SAAS,SAAS,GAAG;AACvB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,GAAG,OAAO,kBAAkB,CAAC;AACzC,YAAQ,IAAI,eAAe,GAAG,KAAK,kBAAkB,CAAC,mBAAmB;AACzE,YAAQ,IAAI,8DAA8D,GAAG,KAAK,MAAM,CAAC,IAAI;AAC7F,YAAQ,IAAI,eAAe,GAAG,KAAK,mBAAmB,CAAC,eAAe;AACtE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,MAAM,mDAAmD,CAAC;AAC3E;AAEA,eAAe,iBAAiB,YAAoB,KAAmC;AACrF,MAAI,QAAQ,eAAe;AACzB,WAAO,qBAAqBF,MAAK,YAAY,WAAW,GAAG,YAAY;AAAA,EACzE;AAEA,MAAI,QAAQ,UAAU;AACpB,WAAO,qBAAqBA,MAAK,YAAY,WAAW,UAAU,GAAG,YAAY;AAAA,EACnF;AAEA,MAAI,QAAQ,YAAY;AACtB,WAAO,qBAAqBA,MAAK,YAAY,aAAa,iBAAiB,GAAG,YAAY;AAAA,EAC5F;AAEA,SAAO,sBAAsBA,MAAK,YAAY,UAAU,aAAa,CAAC;AACxE;AAEA,eAAe,qBACb,UACA,SACyB;AACzB,MAAI,MAAM;AACV,MAAI;AACF,UAAM,MAAMG,UAAS,UAAU,OAAO;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,UACJ,OAAO,OAAO,OAAO,MAAM,YAAY,OAAO,OAAO,KAAK,OACrD,OAAO,OAAO,IACf;AAEN,MAAI,CAAC,WAAW,OAAO,QAAQ,eAAe,YAAY,QAAQ,cAAc,MAAM;AACpF,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,WAAW,QAAQ;AACzB,QAAM,UAAU,OAAO,SAAS,YAAY,WAAW,SAAS,UAAU;AAC1E,QAAM,MAAM,OAAO,SAAS,QAAQ,YAAY,SAAS,OAAO,OAC3D,SAAS,MACV,CAAC;AACL,QAAM,MAAM,OAAO,IAAI,uBAAuB,WAC1C,IAAI,qBACJ;AAEJ,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ,oCAAoC,OAAO;AAAA,EACrD;AACF;AAEA,eAAe,sBAAsB,UAA2C;AAC9E,MAAI,MAAM;AACV,MAAI;AACF,UAAM,MAAMA,UAAS,UAAU,OAAO;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,UAAU,iBAAiB,KAAK,8BAA8B;AACpE,QAAM,MAAM,iBAAiB,KAAK,yCAAyC;AAC3E,QAAM,mBAAmB,IAAI,SAAS,0BAA0B;AAEhE,MAAI,CAAC,kBAAkB;AACrB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ,sCAAsC,OAAO;AAAA,EACvD;AACF;AAEA,SAAS,iBAAiB,SAAiB,SAAqC;AAC9E,QAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,SAAO,QAAQ,CAAC;AAClB;AAIA,eAAe,kBAAkB,YAAoB,MAA8B;AACjF,QAAM,MAAM,KAAK;AACjB,QAAM,OAAO,KAAK;AAClB,MAAI,SAAS,KAAK;AAElB,MAAI,KAAK,WAAW;AAClB,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,UAAU;AACjC,cAAQ,MAAM,GAAG,IAAI,6DAA6D,CAAC;AACnF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAO,MAAM,iCAAiC,KAAK,OAAO,KAAK,UAAU;AAAA,MAC7E,OAAO;AAAA,IACT,CAAC;AACD,aAAS,KAAK;AACd,YAAQ,IAAI,6BAA6B,KAAK,KAAK,GAAG;AAAA,EACxD,WAAW,CAAC,UAAU,KAAK,SAAS,KAAK,UAAU;AACjD,UAAM,OAAO,MAAM,mCAAmC,KAAK,OAAO,KAAK,UAAU;AAAA,MAC/E,OAAO;AAAA,MACP,UAAU,iBAAiB,IAAI;AAAA,IACjC,CAAC;AACD,aAAS,KAAK;AACd,YAAQ,IAAI,uBAAuB,KAAK,KAAK,GAAG;AAAA,EAClD,WAAW,QAAQ;AACjB,UAAM,WAAW,MAAM,sBAAsB,YAAY,UAAU,MAAM;AAAA,MACvE,UAAU,iBAAiB,IAAI;AAAA,IACjC,CAAC;AACD,QAAI,CAAC,SAAS,OAAO;AACnB,cAAQ,MAAM,GAAG,IAAI,SAAS,SAAS,4BAA4B,CAAC;AACpE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,aAAS,SAAS;AAAA,EACpB;AAEA,MAAI,CAAC,QAAQ;AACX,YAAQ,MAAM,GAAG,IAAI,wEAAwE,CAAC;AAC9F,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,6BAA6B,GAAG,OAAO,IAAI,UAAU;AAEjE,QAAM,UAAU,YAAY,KAAK,MAAM,MAAM;AAE7C,UAAQ,IAAI,GAAG,MAAM,iBAAiB,CAAC;AACvC,aAAW,QAAQ,yBAAyB,KAAK,MAAM,UAAU,GAAG;AAClE,YAAQ,IAAI,IAAI;AAAA,EAClB;AACF;AAIA,eAAe,eAAe,YAAoB,SAAiC;AACjF,aAAW;AAEX,EAAE,QAAM,GAAG,OAAO,GAAG,MAAM,oBAAoB,CAAC,CAAC;AAGjD,QAAM,iBAAiB,MAAM,WAAW,UAAU;AAClD,MAAI,gBAAgB;AAClB,UAAM,eAAe,MAAQ,SAAO;AAAA,MAClC,SAAS,iCAAiC,eAAe,GAAG,KAAK,eAAe,IAAI;AAAA,MACpF,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,OAAO,yBAAyB,MAAM,2BAA2B;AAAA,QACpF,EAAE,OAAO,SAAS,OAAO,eAAe,MAAM,yCAAyC;AAAA,MACzF;AAAA,IACF,CAAC;AAED,QAAM,WAAS,YAAY,GAAG;AAC5B,MAAE,SAAO,kBAAkB;AAC3B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,iBAAiB,UAAU;AAE7B,YAAMC,UAAS,MAAM,aAAa;AAClC,UAAI,CAACA,QAAQ;AACb,YAAM,UAAU,YAAY,eAAe,KAAK,eAAe,MAAMA,OAAM;AAC3E,kBAAY,eAAe,KAAK,eAAe,MAAM,UAAU;AAC/D;AAAA,IACF;AAAA,EAEF;AAGA,QAAM,MAAM,QAAQ,OAAO,MAAM,UAAU,UAAU;AACrD,MAAI,CAAC,IAAK;AAGV,QAAM,OAAO,QAAQ,QAAQ,MAAM,WAAW;AAC9C,MAAI,CAAC,KAAM;AAGX,QAAM,SAAS,QAAQ,SAAS,MAAM,aAAa,OAAO;AAC1D,MAAI,CAAC,OAAQ;AAGb,QAAM,IAAM,UAAQ;AACpB,IAAE,MAAM,2BAA2B;AAEnC,MAAI;AACF,UAAM,UAAU,YAAY,KAAK,MAAM,MAAM;AAC7C,MAAE,KAAK,yBAAyB;AAAA,EAClC,SAAS,KAAK;AACZ,MAAE,KAAK,uBAAuB;AAC9B,IAAE,SAAO,eAAe,QAAQ,IAAI,UAAU,eAAe;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,cAAY,KAAK,MAAM,UAAU;AACnC;AAIA,eAAe,UAAU,YAAyC;AAChE,QAAM,YAAY,MAAM,UAAU,UAAU;AAE5C,MAAI,UAAU,UAAU;AACtB,UAAM,UAAU,WAAW,UAAU,QAAQ;AAC7C,UAAMC,WAAU,MAAQ,UAAQ;AAAA,MAC9B,SAAS,YAAY,QAAQ,IAAI,KAAK,UAAU,QAAQ,CAAC,EAAG,MAAM,gBAAgB,QAAQ,IAAI;AAAA,IAChG,CAAC;AAED,QAAM,WAASA,QAAO,GAAG;AACvB,MAAE,SAAO,kBAAkB;AAC3B,aAAO;AAAA,IACT;AAEA,QAAIA,SAAS,QAAO,UAAU;AAAA,EAChC;AAEA,QAAM,SAAS,MAAQ,SAAO;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,MAAM,WAAS,MAAM,GAAG;AACtB,IAAE,SAAO,kBAAkB;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,aAAwC;AACrD,QAAM,SAAS,MAAQ,SAAO;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,QAAiB,OAAO,6CAAwC,MAAM,cAAc;AAAA,MAC7F,EAAE,OAAO,QAAiB,OAAO,+BAA0B,MAAM,UAAU;AAAA,IAC7E;AAAA,EACF,CAAC;AAED,MAAM,WAAS,MAAM,GAAG;AACtB,IAAE,SAAO,kBAAkB;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,aAAa,SAA2C;AACrE,MAAI,SAAS,WAAW;AACtB,UAAM,WAAW,QAAQ,SAAS,MAAM,gBAAgB,qBAAqB,kBAAkB;AAC/F,UAAM,cAAc,QAAQ,YAAY,MAAM,gBAAgB,wBAAwB,eAAe,IAAI;AACzG,QAAI,CAAC,YAAY,CAAC,YAAa,QAAO;AAEtC,QAAI;AACF,YAAM,SAAS,MAAM,iCAAiC,UAAU,aAAa;AAAA,QAC3E,OAAO;AAAA,MACT,CAAC;AACD,MAAE,MAAI,QAAQ,6BAA6B,OAAO,KAAK,GAAG;AAC1D,aAAO,OAAO;AAAA,IAChB,SAAS,KAAK;AACZ,MAAE,MAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,mBAAmB;AACpE,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,YAAY,iBAAiB,OAAO;AAC1C,QAAM,gBAAgB;AAAA,IACpB,EAAE,OAAO,WAAW,OAAO,sCAAsC,MAAM,cAAc;AAAA,IACrF,EAAE,OAAO,SAAS,OAAO,0BAA0B,MAAM,kCAAkC;AAAA,EAC7F;AAEA,MAAI,WAAW;AACb,kBAAc,KAAK;AAAA,MACjB,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAQ,SAAO;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,MAAM,WAAS,MAAM,GAAG;AACtB,IAAE,SAAO,kBAAkB;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,WAAW;AACxB,UAAM,QAAQ,MAAM,gBAAgB,kBAAkB,SAAS,SAAS,iBAAiB;AACzF,UAAM,WAAW,MAAM,gBAAgB,qBAAqB,oDAAY,IAAI;AAC5E,QAAI,CAAC,SAAS,CAAC,SAAU,QAAO;AAEhC,QAAI;AACF,YAAM,SAAS,MAAM,mCAAmC,OAAO,UAAU;AAAA,QACvE,OAAO;AAAA,QACP,UAAU;AAAA,MACZ,CAAC;AACD,MAAE,MAAI,QAAQ,uBAAuB,OAAO,KAAK,GAAG;AACpD,aAAO,OAAO;AAAA,IAChB,SAAS,KAAK;AACZ,MAAE,MAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,+BAA+B;AAChF,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,WAAW,SAAS;AACtB,UAAM,QAAQ,MAAM,gBAAgB,qBAAqB,kBAAkB;AAC3E,UAAM,WAAW,MAAM,gBAAgB,wBAAwB,eAAe,IAAI;AAClF,QAAI,CAAC,SAAS,CAAC,SAAU,QAAO;AAEhC,QAAI;AACF,YAAM,SAAS,MAAM,iCAAiC,OAAO,UAAU;AAAA,QACrE,OAAO;AAAA,MACT,CAAC;AACD,MAAE,MAAI,QAAQ,6BAA6B,OAAO,KAAK,GAAG;AAC1D,aAAO,OAAO;AAAA,IAChB,SAAS,KAAK;AACZ,MAAE,MAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,mBAAmB;AACpE,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,OAAO,MAAM;AAAA,IACjB,YAAY;AACV,YAAM,MAAM,MAAQ,OAAK;AAAA,QACvB,SAAS;AAAA,QACT,aAAa;AAAA,QACb,UAAU,CAAC,UAAU;AACnB,cAAI,CAAC,MAAO,QAAO;AACnB,cAAI,CAAC,MAAM,WAAW,UAAU,EAAG,QAAO;AAC1C,cAAI,MAAM,SAAS,GAAI,QAAO;AAC9B,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAED,UAAM,WAAS,GAAG,GAAG;AACnB,QAAE,SAAO,kBAAkB;AAC3B,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,CAAC,KAAK,OAAO;AACf,IAAE,MAAI,MAAM,KAAK,SAAS,0DAA0D;AACpF,WAAO;AAAA,EACT;AAEA,SAAO,KAAK;AACd;AAEA,SAAS,iBAAiB,SAA4B;AACpD,MAAI,SAAS,UAAW,QAAO;AAC/B,QAAM,aAAa,QAAQ,IAAI;AAC/B,MAAI,YAAY;AACd,UAAM,aAAa,WAAW,KAAK,EAAE,YAAY;AACjD,QAAI,CAAC,KAAK,QAAQ,OAAO,IAAI,EAAE,SAAS,UAAU,GAAG;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,CAAC,YAAa,QAAO;AACzB,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,WAAW;AAClC,WAAO,OAAO,aAAa,eAAe,OAAO,aAAa;AAAA,EAChE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,gBACb,SACA,aACA,SAAS,OACe;AACxB,QAAM,QAAQ,MAAQ,OAAK;AAAA,IACzB;AAAA,IACA;AAAA,IACA,GAAI,SAAS,EAAE,aAAa,mDAAW,IAAI,CAAC;AAAA,IAC5C,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAM,WAAS,KAAK,GAAG;AACrB,IAAE,SAAO,kBAAkB;AAC3B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAIA,eAAe,UACb,YACA,KACA,MACA,QACe;AACf,QAAM,UAAU,WAAW,GAAG;AAG9B,QAAM,QAAQ,aAAa,YAAY,MAAM;AAG7C,MAAI,gBAAgB;AACpB,MAAI,SAAS,QAAQ;AACnB,UAAM,eAAe,MAAM,oBAAoB;AAC/C,oBAAgB,MAAM,QAAQ,iBAAiB,YAAY,YAAY;AAAA,EACzE;AAGA,QAAM,SAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,SAAS;AAAA,EACX;AACA,QAAM,YAAY,YAAY,MAAM;AAEpC,OAAK;AACP;AAEA,SAAS,yBAAyB,KAAU,MAAiB,YAA8B;AACzF,QAAM,OAAO,GAAG,KAAK,UAAU;AAC/B,QAAM,gBACJ,2EAA2E,GAAG,KAAK,wBAAwB,CAAC,mBAAmB,GAAG,KAAK,uBAAuB,CAAC;AAEjK,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,MACL,mCAAmC,IAAI,gDAAgD,GAAG,KAAK,6BAA6B,CAAC;AAAA,MAC7H;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS;AAAA,IACb,oCAAoC,IAAI;AAAA,IACxC,wCAAwC,GAAG,KAAK,aAAa,CAAC;AAAA,IAC9D,iBAAiB,GAAG,KAAK,WAAW,CAAC;AAAA,IACrC,4BAA4B,GAAG,KAAK,mBAAmB,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,QAAQ,eAAe;AACzB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,6BAA6B,GAAG,KAAK,MAAM,CAAC,gBAAgB,GAAG,KAAK,YAAY,CAAC;AAAA,IACnF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,KAAU,MAAiB,YAA0B;AACxE,QAAM,UAAU,WAAW,GAAG;AAC9B,QAAM,iBACJ,SAAS,SACL,GAAG,GAAG,MAAM,QAAG,CAAC,yCAChB,GAAG,GAAG,OAAO,QAAG,CAAC;AAEvB,EAAE;AAAA,IACA;AAAA,MACE,GAAG,GAAG,MAAM,QAAG,CAAC;AAAA,MAChB;AAAA,MACA,GAAG,GAAG,MAAM,QAAG,CAAC,SAAS,QAAQ,IAAI;AAAA,IACvC,EAAE,KAAK,IAAI;AAAA,IACX;AAAA,EACF;AAEA,EAAE,QAAM,yBAAyB,KAAK,MAAM,UAAU,EAAE,KAAK,IAAI,CAAC;AACpE;AAIA,eAAe,WAAW,YAAiD;AACzE,QAAM,aAAaL,MAAK,YAAY,WAAW;AAC/C,MAAI;AACF,UAAMC,QAAO,UAAU;AACvB,UAAM,MAAM,MAAME,UAAS,YAAY,OAAO;AAC9C,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,YAAY,YAAoB,QAAoC;AACjF,QAAM,aAAaH,MAAK,YAAY,WAAW;AAC/C,QAAMM,WAAU,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AAC7E;;;AS/tBA,SAAS,qBAAqB;AAE9B,SAAS,UAAU,MAAyB;AAC1C,QAAM,OAAgB,CAAC;AAEvB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAElB,QAAI,QAAQ,YAAY;AACtB,WAAK,SAAS;AAAA,IAChB,WAAW,QAAQ,YAAY;AAC7B,WAAK,SAAS;AAAA,IAChB,WAAW,QAAQ,WAAW,KAAK,IAAI,CAAC,GAAG;AACzC,YAAM,MAAM,KAAK,EAAE,CAAC;AACpB,UAAI,CAAC,eAAe,UAAU,SAAS,UAAU,EAAE,SAAS,GAAG,GAAG;AAChE,aAAK,MAAM;AAAA,MACb;AAAA,IACF,WAAW,QAAQ,YAAY,KAAK,IAAI,CAAC,GAAG;AAC1C,YAAM,OAAO,KAAK,EAAE,CAAC;AACrB,UAAI,CAAC,QAAQ,MAAM,EAAE,SAAS,IAAI,GAAG;AACnC,aAAK,OAAO;AAAA,MACd;AAAA,IACF,WAAW,QAAQ,aAAa,KAAK,IAAI,CAAC,GAAG;AAC3C,WAAK,QAAQ,KAAK,EAAE,CAAC;AAAA,IACvB,WAAW,QAAQ,aAAa,KAAK,IAAI,CAAC,GAAG;AAC3C,WAAK,QAAQ,KAAK,EAAE,CAAC;AAAA,IACvB,WAAW,QAAQ,gBAAgB,KAAK,IAAI,CAAC,GAAG;AAC9C,WAAK,WAAW,KAAK,EAAE,CAAC;AAAA,IAC1B,WAAW,QAAQ,gBAAgB;AACjC,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,UAAU,QAAQ,IAAI;AACnC,QAAM,aAAa,QAAQ,IAAI;AAE/B,MAAI;AACF,UAAM,UAAU,YAAY,IAAI;AAAA,EAClC,SAAS,KAAK;AACZ,YAAQ,MAAM,iBAAiB,eAAe,QAAQ,IAAI,UAAU,GAAG;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,eAAsB,YAAY,OAAiB,QAAQ,MAAqB;AAC9E,QAAM,eAAe,QAAQ;AAC7B,UAAQ,OAAO;AACf,MAAI;AACF,UAAM,KAAK;AAAA,EACb,UAAE;AACA,YAAQ,OAAO;AAAA,EACjB;AACF;AAEA,SAAS,mBAAmB,SAA0B;AACpD,QAAM,YAAY,QAAQ,KAAK,CAAC;AAChC,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,YAAY,cAAc,SAAS,EAAE;AAC9C;AAEA,IAAI,mBAAmB,YAAY,GAAG,GAAG;AACvC,OAAK,YAAY;AACnB;","names":["readFile","writeFile","access","join","dirname","fileURLToPath","join","access","join","join","mkdir","readdir","copyFile","rm","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","copyFile","rm","mkdir","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","mkdir","readFile","writeFile","join","START_MARKER","END_MARKER","join","mkdir","readFile","writeFile","readdir","removeSection","isTruthy","__dirname","dirname","fileURLToPath","join","access","text","readFile","apiKey","confirm","writeFile"]}
1
+ {"version":3,"sources":["../setup/wizard.ts","../setup/ide-detect.ts","../setup/ide-adapters/claude-code.ts","../setup/ide-adapters/mcp-runtime.ts","../setup/ide-adapters/cursor.ts","../setup/ide-adapters/codex.ts","../setup/ide-adapters/windsurf.ts","../setup/ide-adapters/index.ts","../setup/auth.ts","../setup/index.ts"],"sourcesContent":["/**\n * setup/wizard.ts — Interactive setup wizard using @clack/prompts.\n *\n * Orchestrates the full setup flow:\n * 1. Welcome banner\n * 2. Existing setup check\n * 3. IDE detection + selection\n * 4. Mode selection (Core vs Full)\n * 5. Authentication\n * 6. Configure + install\n * 7. Verify + success\n */\n\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport figlet from 'figlet';\nimport gradient from 'gradient-string';\nimport { readFile, writeFile, access } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Ide, SetupMode, SetupConfig, CliArgs } from './types.js';\nimport { detectIde } from './ide-detect.js';\nimport { getAdapter, IDE_CHOICES } from './ide-adapters/index.js';\nimport {\n authenticateAccountAndCreateApiKey,\n authenticateLocalAndCreateApiKey,\n authenticateWithRetry,\n verifyApiKey,\n} from './auth.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst WORKFLOW_DIR_CANDIDATES = [\n join(__dirname, '..', 'workflows'),\n join(__dirname, '..', '..', 'workflows'),\n];\nconst CONFIG_FILE = '.forcefield.json';\nconst VERSION = '0.1.4';\nconst BANNER_TEXT = 'Forcefield';\nconst BANNER_FONT = 'Rowan Cap';\nconst BANNER_MIN_COLUMNS = 80;\nconst BANNER_FALLBACK_TEXT = ' Forcefield';\nconst BANNER_SUBTITLE = ' Corporate compliance copilot\\n';\n// rainbow2-like palette cycling red -> violet for the terminal banner\nconst BANNER_GRADIENT_STOPS = ['#ff3b3b', '#ff9f1a', '#ffe74c', '#2ed573', '#1e90ff', '#7d5fff', '#e056fd'];\nconst bannerGradient = gradient(BANNER_GRADIENT_STOPS);\n\nasync function resolveWorkflowsDir(): Promise<string> {\n for (const dir of WORKFLOW_DIR_CANDIDATES) {\n try {\n await access(dir);\n return dir;\n } catch {\n // try next candidate\n }\n }\n throw new Error(\n `Unable to locate workflow templates. Checked: ${WORKFLOW_DIR_CANDIDATES.join(', ')}`,\n );\n}\n\n/**\n * Run the interactive setup wizard.\n */\nexport async function runWizard(projectDir: string, args: CliArgs): Promise<void> {\n // --status: read-only check\n if (args.status) {\n await showStatus(projectDir);\n return;\n }\n\n // --doctor: setup diagnostics\n if (args.doctor) {\n await runDoctor(projectDir, args);\n return;\n }\n\n // Non-interactive mode\n if (args.ide && args.mode && (args.token || args.localAuth || (args.email && args.password))) {\n await runNonInteractive(projectDir, args);\n return;\n }\n\n // Interactive mode\n await runInteractive(projectDir, args);\n}\n\n// === Welcome Banner ===\n\nfunction showBanner(): void {\n const cols = process.stdout.columns || 80;\n\n if (cols >= BANNER_MIN_COLUMNS) {\n try {\n const banner = figlet.textSync(BANNER_TEXT, { font: BANNER_FONT });\n const colored = applyBannerGradient(banner);\n console.log(colored);\n } catch {\n // figlet font not available — use fallback\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n } else {\n console.log(pc.bold(applyBannerGradient(BANNER_FALLBACK_TEXT)));\n }\n console.log(pc.dim(BANNER_SUBTITLE));\n}\n\nfunction applyBannerGradient(text: string): string {\n return bannerGradient.multiline(text);\n}\n\n// === Status Check ===\n\nasync function showStatus(projectDir: string): Promise<void> {\n const config = await readConfig(projectDir);\n\n if (!config) {\n console.log(pc.yellow('No Forcefield setup found in this directory.'));\n console.log(`Run ${pc.cyan('forcefield setup')} to get started.`);\n process.exit(1);\n }\n\n console.log(pc.bold('Forcefield Setup Status'));\n console.log(` IDE: ${pc.cyan(config.ide)}`);\n console.log(` Mode: ${pc.cyan(config.mode)}`);\n console.log(` Version: ${pc.cyan(config.version)}`);\n console.log(` Installed: ${pc.dim(config.installed_at)}`);\n}\n\ninterface DoctorCheckResult {\n ok: boolean;\n label: string;\n detail: string;\n}\n\ninterface McpCheckResult {\n ok: boolean;\n filePath: string;\n key?: string;\n detail: string;\n}\n\nasync function runDoctor(projectDir: string, args: CliArgs): Promise<void> {\n console.log(pc.bold('Forcefield Setup Doctor'));\n console.log(pc.dim(`Project: ${projectDir}`));\n\n const checks: DoctorCheckResult[] = [];\n const config = await readConfig(projectDir);\n\n if (!config) {\n checks.push({\n ok: false,\n label: 'Setup config',\n detail: `Missing ${CONFIG_FILE}. Run forcefield setup first.`,\n });\n } else {\n checks.push({\n ok: true,\n label: 'Setup config',\n detail: `${config.ide} / ${config.mode} / v${config.version}`,\n });\n\n const mcp = await inspectMcpConfig(projectDir, config.ide);\n checks.push({\n ok: mcp.ok,\n label: 'MCP config',\n detail: `${mcp.filePath} — ${mcp.detail}`,\n });\n\n if (mcp.key) {\n const verified = await verifyApiKey(mcp.key, { localDev: isLocalSetupMode(args) });\n checks.push({\n ok: verified.valid,\n label: 'API key exchange',\n detail: verified.valid\n ? 'Key exchange succeeded.'\n : (verified.error ?? 'Key exchange failed.'),\n });\n } else {\n checks.push({\n ok: false,\n label: 'API key exchange',\n detail: 'FORCEFIELD_API_KEY not found in MCP config env.',\n });\n }\n }\n\n for (const check of checks) {\n const symbol = check.ok ? pc.green('✓') : pc.red('✗');\n console.log(`${symbol} ${pc.bold(check.label)}: ${check.detail}`);\n }\n\n const failures = checks.filter((check) => !check.ok);\n if (failures.length > 0) {\n console.log('');\n console.log(pc.yellow('Suggested fixes:'));\n console.log(` 1. Re-run ${pc.cyan('forcefield setup')} in this project.`);\n console.log(` 2. Confirm your coding agent shows Forcefield connected (${pc.cyan('/mcp')}).`);\n console.log(` 3. Re-run ${pc.cyan('forcefield doctor')} after setup.`);\n process.exit(1);\n }\n\n console.log('');\n console.log(pc.green('Doctor checks passed. Forcefield should be ready.'));\n}\n\nasync function inspectMcpConfig(projectDir: string, ide: Ide): Promise<McpCheckResult> {\n if (ide === 'claude-code') {\n return inspectJsonMcpConfig(join(projectDir, '.mcp.json'), 'mcpServers');\n }\n\n if (ide === 'cursor') {\n return inspectJsonMcpConfig(join(projectDir, '.cursor', 'mcp.json'), 'mcpServers');\n }\n\n if (ide === 'windsurf') {\n return inspectJsonMcpConfig(join(projectDir, '.windsurf', 'mcp_config.json'), 'mcpServers');\n }\n\n return inspectCodexMcpConfig(join(projectDir, '.codex', 'config.toml'));\n}\n\nasync function inspectJsonMcpConfig(\n filePath: string,\n rootKey: string,\n): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'Invalid JSON.',\n };\n }\n\n const servers =\n typeof parsed[rootKey] === 'object' && parsed[rootKey] != null\n ? (parsed[rootKey] as Record<string, unknown>)\n : null;\n\n if (!servers || typeof servers.forcefield !== 'object' || servers.forcefield == null) {\n return {\n ok: false,\n filePath,\n detail: 'Missing forcefield MCP server entry.',\n };\n }\n\n const ffServer = servers.forcefield as Record<string, unknown>;\n const command = typeof ffServer.command === 'string' ? ffServer.command : '';\n const env = typeof ffServer.env === 'object' && ffServer.env != null\n ? (ffServer.env as Record<string, unknown>)\n : {};\n const key = typeof env.FORCEFIELD_API_KEY === 'string'\n ? env.FORCEFIELD_API_KEY\n : undefined;\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n detail: 'forcefield entry missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n detail: `Found forcefield entry (command: ${command}).`,\n };\n}\n\nasync function inspectCodexMcpConfig(filePath: string): Promise<McpCheckResult> {\n let raw = '';\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch {\n return {\n ok: false,\n filePath,\n detail: 'File not found.',\n };\n }\n\n const command = extractTomlValue(raw, /^\\s*command\\s*=\\s*\"([^\"]+)\"/m);\n const key = extractTomlValue(raw, /^\\s*FORCEFIELD_API_KEY\\s*=\\s*\"([^\"]+)\"/m);\n const hasServerSection = raw.includes('[mcp_servers.forcefield]');\n\n if (!hasServerSection) {\n return {\n ok: false,\n filePath,\n key,\n detail: 'Missing [mcp_servers.forcefield] section.',\n };\n }\n\n if (!command) {\n return {\n ok: false,\n filePath,\n key,\n detail: 'forcefield section missing command.',\n };\n }\n\n return {\n ok: true,\n filePath,\n key,\n detail: `Found forcefield section (command: ${command}).`,\n };\n}\n\nfunction extractTomlValue(content: string, pattern: RegExp): string | undefined {\n const match = content.match(pattern);\n return match?.[1];\n}\n\n// === Non-Interactive Mode ===\n\nasync function runNonInteractive(projectDir: string, args: CliArgs): Promise<void> {\n const ide = args.ide!;\n const mode = args.mode!;\n let apiKey = args.token;\n\n if (args.localAuth) {\n if (!args.email || !args.password) {\n console.error(pc.red('Non-interactive local auth requires --email and --password.'));\n process.exit(1);\n }\n\n const auth = await authenticateLocalAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard (Local)',\n });\n apiKey = auth.apiKey;\n console.log(`Created local API key for ${auth.email}.`);\n } else if (!apiKey && args.email && args.password) {\n const auth = await authenticateAccountAndCreateApiKey(args.email, args.password, {\n label: 'Setup Wizard Key',\n localDev: isLocalSetupMode(args),\n });\n apiKey = auth.apiKey;\n console.log(`Created API key for ${auth.email}.`);\n } else if (apiKey) {\n const verified = await authenticateWithRetry(async () => apiKey ?? null, {\n localDev: isLocalSetupMode(args),\n });\n if (!verified.valid) {\n console.error(pc.red(verified.error ?? 'API key validation failed.'));\n process.exit(1);\n }\n apiKey = verified.apiKey;\n }\n\n if (!apiKey) {\n console.error(pc.red('Missing auth input. Pass --token, --local-auth, or --email/--password.'));\n process.exit(1);\n }\n\n console.log(`Setting up Forcefield for ${ide} in ${mode} mode...`);\n\n await configure(projectDir, ide, mode, apiKey);\n\n console.log(pc.green('Setup complete!'));\n for (const line of getPostSetupInstructions(ide, mode, projectDir)) {\n console.log(line);\n }\n}\n\n// === Interactive Mode ===\n\nasync function runInteractive(projectDir: string, preArgs: CliArgs): Promise<void> {\n showBanner();\n\n p.intro(pc.bgCyan(pc.black(' Forcefield Setup ')));\n\n // Step 1: Check existing setup\n const existingConfig = await readConfig(projectDir);\n if (existingConfig) {\n const updateChoice = await p.select({\n message: `Forcefield is already set up (${existingConfig.ide}, ${existingConfig.mode} mode).`,\n options: [\n { value: 'update', label: 'Update existing setup', hint: 'Refresh workflows + auth' },\n { value: 'fresh', label: 'Start fresh', hint: 'Remove existing config and reconfigure' },\n ],\n });\n\n if (p.isCancel(updateChoice)) {\n p.cancel('Setup cancelled.');\n process.exit(0);\n }\n\n if (updateChoice === 'update') {\n // Re-run configure with existing settings\n const apiKey = await promptApiKey();\n if (!apiKey) return;\n await configure(projectDir, existingConfig.ide, existingConfig.mode, apiKey);\n showSuccess(existingConfig.ide, existingConfig.mode, projectDir);\n return;\n }\n // fresh → continue with full wizard\n }\n\n // Step 2: IDE detection + selection\n const ide = preArgs.ide ?? await promptIde(projectDir);\n if (!ide) return;\n\n // Step 3: Mode selection\n const mode = preArgs.mode ?? await promptMode();\n if (!mode) return;\n\n // Step 4: Authentication\n const apiKey = preArgs.token ?? await promptApiKey(preArgs);\n if (!apiKey) return;\n\n // Step 5: Configure + install\n const s = p.spinner();\n s.start('Configuring Forcefield...');\n\n try {\n await configure(projectDir, ide, mode, apiKey);\n s.stop('Configuration complete.');\n } catch (err) {\n s.stop('Configuration failed.');\n p.cancel(err instanceof Error ? err.message : 'Unknown error');\n process.exit(1);\n }\n\n // Step 6: Success\n showSuccess(ide, mode, projectDir);\n}\n\n// === Prompts ===\n\nasync function promptIde(projectDir: string): Promise<Ide | null> {\n const detection = await detectIde(projectDir);\n\n if (detection.detected) {\n const adapter = getAdapter(detection.detected);\n const confirm = await p.confirm({\n message: `Detected ${adapter.name} (${detection.markers[0]!.marker} found). Use ${adapter.name}?`,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (confirm) return detection.detected;\n }\n\n const choice = await p.select({\n message: 'Which IDE do you use?',\n options: IDE_CHOICES,\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as Ide;\n}\n\nasync function promptMode(): Promise<SetupMode | null> {\n const choice = await p.select({\n message: 'Installation type:',\n options: [\n { value: 'full' as const, label: 'Full — MCP server + guided workflows', hint: 'Recommended' },\n { value: 'core' as const, label: 'Core — MCP server only', hint: 'Minimal' },\n ],\n });\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return choice as SetupMode;\n}\n\nasync function promptApiKey(preArgs?: CliArgs): Promise<string | null> {\n if (preArgs?.localAuth) {\n const preEmail = preArgs.email ?? await promptTextValue('Local test email:', 'alice@test.local');\n const prePassword = preArgs.password ?? await promptTextValue('Local test password:', 'password123', true);\n if (!preEmail || !prePassword) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(preEmail, prePassword, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const localMode = isLocalSetupMode(preArgs);\n const methodOptions = [\n { value: 'account', label: 'Sign in / create account + API key', hint: 'Recommended' },\n { value: 'paste', label: 'Paste existing API key', hint: 'Use an existing ff_live_... key' },\n ];\n\n if (localMode) {\n methodOptions.push({\n value: 'local',\n label: 'Create local account + API key',\n hint: 'For local Supabase testing',\n });\n }\n\n const method = await p.select({\n message: 'How do you want to authenticate?',\n options: methodOptions,\n });\n\n if (p.isCancel(method)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n if (method === 'account') {\n const email = await promptTextValue('Account email:', preArgs?.email ?? 'you@company.com');\n const password = await promptTextValue('Account password:', '••••••••', true);\n if (!email || !password) return null;\n\n try {\n const result = await authenticateAccountAndCreateApiKey(email, password, {\n label: 'Setup Wizard Key',\n localDev: localMode,\n });\n p.log.success(`Created API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Account authentication failed');\n return null;\n }\n }\n\n if (method === 'local') {\n const email = await promptTextValue('Local test email:', 'alice@test.local');\n const password = await promptTextValue('Local test password:', 'password123', true);\n if (!email || !password) return null;\n\n try {\n const result = await authenticateLocalAndCreateApiKey(email, password, {\n label: 'Setup Wizard (Local)',\n });\n p.log.success(`Created local API key for ${result.email}.`);\n return result.apiKey;\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'Failed local auth');\n return null;\n }\n }\n\n const auth = await authenticateWithRetry(\n async () => {\n const key = await p.text({\n message: 'Enter your Forcefield API key:',\n placeholder: 'ff_live_...',\n validate: (value) => {\n if (!value) return 'API key is required.';\n if (!value.startsWith('ff_live_')) return 'Key must start with \"ff_live_\".';\n if (value.length < 20) return 'Key seems too short.';\n return undefined;\n },\n });\n\n if (p.isCancel(key)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n\n return key;\n },\n {\n localDev: localMode,\n },\n );\n\n if (!auth.valid) {\n p.log.error(auth.error ?? 'Authentication failed. Check your credentials and retry.');\n return null;\n }\n\n return auth.apiKey;\n}\n\nfunction isLocalSetupMode(preArgs?: CliArgs): boolean {\n if (preArgs?.localAuth) return true;\n const localValue = process.env.FORCEFIELD_LOCAL_DEV;\n if (localValue) {\n const normalized = localValue.trim().toLowerCase();\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true;\n }\n }\n\n const supabaseUrl = process.env.SUPABASE_URL;\n if (!supabaseUrl) return false;\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nasync function promptTextValue(\n message: string,\n placeholder: string,\n secret = false,\n): Promise<string | null> {\n const value = await p.text({\n message,\n placeholder,\n ...(secret ? { placeholder: '••••••••' } : {}),\n validate: (input) => {\n if (!input) return 'This field is required.';\n return undefined;\n },\n });\n\n if (p.isCancel(value)) {\n p.cancel('Setup cancelled.');\n return null;\n }\n return value;\n}\n\n// === Configure ===\n\nasync function configure(\n projectDir: string,\n ide: Ide,\n mode: SetupMode,\n apiKey: string,\n): Promise<void> {\n const adapter = getAdapter(ide);\n\n // Configure MCP\n await adapter.configureMcp(projectDir, apiKey);\n\n // Install workflows (full mode only)\n let workflowCount = 0;\n if (mode === 'full') {\n const workflowsDir = await resolveWorkflowsDir();\n workflowCount = await adapter.installWorkflows(projectDir, workflowsDir);\n }\n\n // Write config\n const config: SetupConfig = {\n ide,\n mode,\n installed_at: new Date().toISOString(),\n version: VERSION,\n };\n await writeConfig(projectDir, config);\n\n void workflowCount; // Used in logging below\n}\n\nfunction getPostSetupInstructions(ide: Ide, mode: SetupMode, projectDir: string): string[] {\n const repo = pc.cyan(projectDir);\n const dashboardHint =\n `Optional beta companion: run local dashboard in the Forcefield repo via ${pc.cyan('pnpm run dev:dashboard')} and sign in at ${pc.cyan('http://localhost:3000')}.`;\n\n if (mode === 'core') {\n return [\n `Next: open your coding agent in ${repo} and use Forcefield MCP tools directly (e.g. ${pc.cyan('ff_system(action: \"health\")')}).`,\n dashboardHint,\n ];\n }\n\n const common = [\n `Next: start your coding agent in ${repo}.`,\n `Then in IDE chat (not terminal), run ${pc.cyan('/ff-onboard')} to set up your company profile and deadlines.`,\n `Optional: run ${pc.cyan('/ff-start')} only if you want a command primer or connection troubleshooting.`,\n `If connection fails, run ${pc.cyan('forcefield doctor')} in terminal for diagnostics.`,\n dashboardHint,\n ];\n\n if (ide === 'claude-code') {\n return [\n ...common,\n `If tools are missing, run ${pc.cyan('/mcp')} and confirm ${pc.cyan('forcefield')} is connected.`,\n ];\n }\n\n return common;\n}\n\nfunction showSuccess(ide: Ide, mode: SetupMode, projectDir: string): void {\n const adapter = getAdapter(ide);\n const workflowStatus =\n mode === 'full'\n ? `${pc.green('✓')} Project workflow commands installed`\n : `${pc.yellow('•')} Core mode selected (no slash-command workflows installed)`;\n\n p.note(\n [\n `${pc.green('✓')} MCP server configured`,\n workflowStatus,\n `${pc.green('✓')} IDE: ${adapter.name}`,\n ].join('\\n'),\n 'Setup Complete',\n );\n\n p.outro(getPostSetupInstructions(ide, mode, projectDir).join('\\n'));\n}\n\n// === Config File ===\n\nasync function readConfig(projectDir: string): Promise<SetupConfig | null> {\n const configPath = join(projectDir, CONFIG_FILE);\n try {\n await access(configPath);\n const raw = await readFile(configPath, 'utf-8');\n return JSON.parse(raw) as SetupConfig;\n } catch {\n return null;\n }\n}\n\nasync function writeConfig(projectDir: string, config: SetupConfig): Promise<void> {\n const configPath = join(projectDir, CONFIG_FILE);\n await writeFile(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport {\n readConfig,\n writeConfig,\n CONFIG_FILE,\n VERSION,\n BANNER_FONT,\n BANNER_MIN_COLUMNS,\n BANNER_GRADIENT_STOPS,\n showBanner,\n applyBannerGradient,\n getPostSetupInstructions,\n inspectMcpConfig,\n inspectJsonMcpConfig,\n inspectCodexMcpConfig,\n extractTomlValue,\n};\n","/**\n * setup/ide-detect.ts — Auto-detect IDE from project directory markers.\n */\n\nimport { access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { Ide } from './types.js';\n\ninterface DetectionResult {\n detected: Ide | null;\n markers: Array<{ ide: Ide; marker: string }>;\n}\n\nconst IDE_MARKERS: Array<{ ide: Ide; marker: string; isDir: boolean }> = [\n { ide: 'claude-code', marker: '.claude', isDir: true },\n { ide: 'cursor', marker: '.cursor', isDir: true },\n { ide: 'codex', marker: 'AGENTS.md', isDir: false },\n { ide: 'windsurf', marker: '.windsurfrules', isDir: false },\n];\n\nexport async function detectIde(projectDir: string): Promise<DetectionResult> {\n const found: Array<{ ide: Ide; marker: string }> = [];\n\n for (const { ide, marker } of IDE_MARKERS) {\n const markerPath = join(projectDir, marker);\n try {\n await access(markerPath);\n found.push({ ide, marker });\n } catch {\n // Marker not found — skip\n }\n }\n\n return {\n detected: found.length === 1 ? found[0]!.ide : null,\n markers: found,\n };\n}\n\nexport { IDE_MARKERS };\n","/**\n * IDE adapter for Claude Code.\n * Workflows → .claude/commands/ff-*.md\n * MCP → project-scoped .mcp.json entry\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nexport const claudeCodeAdapter: IdeAdapter = {\n name: 'Claude Code',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n // Ensure Claude config folder exists for slash-command workflows.\n const claudeDir = join(projectDir, '.claude');\n await mkdir(claudeDir, { recursive: true });\n\n // Configure project-scoped MCP entry used by Claude Code.\n const launch = await getMcpLaunchConfig();\n const mcpPath = join(projectDir, '.mcp.json');\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(mcpPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const nextConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(mcpPath, JSON.stringify(nextConfig, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n await mkdir(commandsDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(commandsDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const commandsDir = join(projectDir, '.claude', 'commands');\n try {\n const files = await readdir(commandsDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(commandsDir, file));\n }\n }\n } catch {\n // Directory doesn't exist — nothing to remove\n }\n },\n};\n","import { access } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst LOCAL_ENTRY_CANDIDATES = [\n join(__dirname, '..', '..', 'build', 'index.js'),\n join(__dirname, '..', '..', 'index.js'),\n];\nconst RUNNING_FROM_NODE_MODULES = __dirname.includes('node_modules');\n\nconst FORWARDED_ENV_KEYS = [\n 'SUPABASE_URL',\n 'SUPABASE_ANON_KEY',\n 'FORCEFIELD_LOCAL_DEV',\n 'FORCEFIELD_DISABLE_GATING',\n 'FORCEFIELD_LOCAL_DATA_FALLBACK',\n] as const;\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nasync function resolveLocalEntry(): Promise<string | null> {\n for (const candidate of LOCAL_ENTRY_CANDIDATES) {\n try {\n await access(candidate);\n return candidate;\n } catch {\n // try next candidate\n }\n }\n return null;\n}\n\nexport async function getMcpLaunchConfig(): Promise<{ command: string; args: string[] }> {\n if (\n RUNNING_FROM_NODE_MODULES\n || isTruthy(process.env.FORCEFIELD_LOCAL_DEV)\n || isTruthy(process.env.FORCEFIELD_SETUP_USE_LOCAL_BUILD)\n ) {\n const localEntry = await resolveLocalEntry();\n if (localEntry) {\n return {\n command: process.execPath,\n args: [localEntry],\n };\n }\n }\n\n return {\n command: 'npx',\n args: ['-y', '-p', '@forcefield/mcp-server', 'forcefield-mcp'],\n };\n}\n\nexport function buildMcpEnv(apiKey: string): Record<string, string> {\n const env: Record<string, string> = {\n FORCEFIELD_API_KEY: apiKey,\n };\n\n for (const key of FORWARDED_ENV_KEYS) {\n const value = process.env[key];\n if (value && value.trim().length > 0) {\n env[key] = value;\n }\n }\n\n return env;\n}\n","/**\n * IDE adapter for Cursor.\n * Workflows → .cursor/rules/ff-*.md\n * MCP → .cursor/mcp.json\n */\n\nimport { mkdir, readdir, copyFile, rm, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\ntype CursorMcpConfig = {\n mcpServers?: Record<string, { command: string; args: string[]; env?: Record<string, string> }>;\n};\n\nexport const cursorAdapter: IdeAdapter = {\n name: 'Cursor',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const cursorDir = join(projectDir, '.cursor');\n await mkdir(cursorDir, { recursive: true });\n\n const configPath = join(cursorDir, 'mcp.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: CursorMcpConfig = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as CursorMcpConfig;\n } catch {\n // file missing/invalid: overwrite with fresh config\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? existing.mcpServers\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged: CursorMcpConfig = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n await mkdir(rulesDir, { recursive: true });\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n for (const file of mdFiles) {\n await copyFile(join(workflowsDir, file), join(rulesDir, file));\n }\n\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesDir = join(projectDir, '.cursor', 'rules');\n try {\n const files = await readdir(rulesDir);\n for (const file of files) {\n if (file.startsWith('ff-') && file.endsWith('.md')) {\n await rm(join(rulesDir, file));\n }\n }\n } catch {\n // Directory doesn't exist\n }\n },\n};\n","/**\n * IDE adapter for Codex (OpenAI).\n * Workflows → appended to AGENTS.md with markers\n * MCP → .codex/config.toml or project-level config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\nconst MCP_START_MARKER = '# forcefield:mcp:start';\nconst MCP_END_MARKER = '# forcefield:mcp:end';\n\nexport const codexAdapter: IdeAdapter = {\n name: 'Codex',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const codexDir = join(projectDir, '.codex');\n await mkdir(codexDir, { recursive: true });\n\n const configPath = join(codexDir, 'config.toml');\n const launch = await getMcpLaunchConfig();\n const env = buildMcpEnv(apiKey);\n\n const forcefieldBlock = buildForcefieldTomlBlock(launch.command, launch.args, env);\n\n let existing = '';\n try {\n existing = await readFile(configPath, 'utf-8');\n } catch {\n // file missing — create new\n }\n\n const cleaned = removeTomlForcefieldSection(existing).trim();\n const final = cleaned ? `${cleaned}\\n\\n${forcefieldBlock}\\n` : `${forcefieldBlock}\\n`;\n await writeFile(configPath, final, 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n const { readdir } = await import('node:fs/promises');\n\n // Read all workflow files\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n 'The following workflows are available for compliance management:',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n // Read existing AGENTS.md or create new\n let existing = '';\n try {\n existing = await readFile(agentsPath, 'utf-8');\n } catch {\n // File doesn't exist — will create\n }\n\n // Remove existing Forcefield section if present\n const cleaned = removeSection(existing);\n\n // Append new section\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(agentsPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const agentsPath = join(projectDir, 'AGENTS.md');\n try {\n const content = await readFile(agentsPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(agentsPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist — nothing to remove\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n\nfunction removeTomlForcefieldSection(content: string): string {\n const markerStart = content.indexOf(MCP_START_MARKER);\n const markerEnd = content.indexOf(MCP_END_MARKER);\n\n if (markerStart !== -1 && markerEnd !== -1) {\n const before = content.slice(0, markerStart).trimEnd();\n const after = content.slice(markerEnd + MCP_END_MARKER.length).trimStart();\n return before + (after ? '\\n\\n' + after : '');\n }\n\n // Backward-compatible cleanup if a previous config wrote unmanaged sections.\n return content\n .replace(/^\\[mcp_servers\\.forcefield\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .replace(/^\\[mcp_servers\\.forcefield\\.env\\]\\n[\\s\\S]*?(?=^\\[|$)/gm, '')\n .trim();\n}\n\nfunction buildForcefieldTomlBlock(\n command: string,\n args: string[],\n env: Record<string, string>,\n): string {\n const envLines = Object.entries(env)\n .map(([key, value]) => `${key} = \"${escapeTomlString(value)}\"`);\n\n return [\n MCP_START_MARKER,\n '[mcp_servers.forcefield]',\n `command = \"${escapeTomlString(command)}\"`,\n `args = [${args.map((arg) => `\"${escapeTomlString(arg)}\"`).join(', ')}]`,\n '[mcp_servers.forcefield.env]',\n ...envLines,\n MCP_END_MARKER,\n ].join('\\n');\n}\n\nfunction escapeTomlString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n","/**\n * IDE adapter for Windsurf.\n * Workflows → appended to .windsurfrules with markers\n * MCP → Windsurf MCP config\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { IdeAdapter } from '../types.js';\nimport { buildMcpEnv, getMcpLaunchConfig } from './mcp-runtime.js';\n\nconst START_MARKER = '<!-- forcefield:start -->';\nconst END_MARKER = '<!-- forcefield:end -->';\n\nexport const windsurfAdapter: IdeAdapter = {\n name: 'Windsurf',\n\n async configureMcp(projectDir: string, apiKey: string): Promise<void> {\n const configDir = join(projectDir, '.windsurf');\n await mkdir(configDir, { recursive: true });\n\n const configPath = join(configDir, 'mcp_config.json');\n const launch = await getMcpLaunchConfig();\n\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(await readFile(configPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n // file missing/invalid: start fresh\n }\n\n const existingServers =\n typeof existing.mcpServers === 'object' && existing.mcpServers != null\n ? (existing.mcpServers as Record<string, unknown>)\n : {};\n\n existingServers.forcefield = {\n command: launch.command,\n args: launch.args,\n env: buildMcpEnv(apiKey),\n };\n\n const merged = {\n ...existing,\n mcpServers: existingServers,\n };\n\n await writeFile(configPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n },\n\n async installWorkflows(projectDir: string, workflowsDir: string): Promise<number> {\n const rulesPath = join(projectDir, '.windsurfrules');\n const { readdir } = await import('node:fs/promises');\n\n const files = await readdir(workflowsDir);\n const mdFiles = files.filter((f) => f.startsWith('ff-') && f.endsWith('.md'));\n\n const workflowContents: string[] = [];\n for (const file of mdFiles) {\n const content = await readFile(join(workflowsDir, file), 'utf-8');\n workflowContents.push(content);\n }\n\n const forcefieldSection = [\n START_MARKER,\n '',\n '# Forcefield Workflows',\n '',\n ...workflowContents.map((c) => c + '\\n\\n---\\n'),\n END_MARKER,\n ].join('\\n');\n\n let existing = '';\n try {\n existing = await readFile(rulesPath, 'utf-8');\n } catch {\n // File doesn't exist\n }\n\n const cleaned = removeSection(existing);\n const final = cleaned.trim()\n ? cleaned.trim() + '\\n\\n' + forcefieldSection\n : forcefieldSection;\n\n await writeFile(rulesPath, final, 'utf-8');\n return mdFiles.length;\n },\n\n async removeWorkflows(projectDir: string): Promise<void> {\n const rulesPath = join(projectDir, '.windsurfrules');\n try {\n const content = await readFile(rulesPath, 'utf-8');\n const cleaned = removeSection(content);\n await writeFile(rulesPath, cleaned, 'utf-8');\n } catch {\n // File doesn't exist\n }\n },\n};\n\nfunction removeSection(content: string): string {\n const startIdx = content.indexOf(START_MARKER);\n const endIdx = content.indexOf(END_MARKER);\n\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + END_MARKER.length).trimStart();\n\n return before + (after ? '\\n\\n' + after : '');\n}\n","/**\n * IDE adapter registry.\n */\n\nimport type { Ide, IdeAdapter } from '../types.js';\nimport { claudeCodeAdapter } from './claude-code.js';\nimport { cursorAdapter } from './cursor.js';\nimport { codexAdapter } from './codex.js';\nimport { windsurfAdapter } from './windsurf.js';\n\nconst adapters: Record<Ide, IdeAdapter> = {\n 'claude-code': claudeCodeAdapter,\n 'cursor': cursorAdapter,\n 'codex': codexAdapter,\n 'windsurf': windsurfAdapter,\n};\n\nexport function getAdapter(ide: Ide): IdeAdapter {\n return adapters[ide];\n}\n\nexport const IDE_CHOICES: Array<{ value: Ide; label: string; hint: string }> = [\n { value: 'claude-code', label: 'Claude Code', hint: '.claude/commands/' },\n { value: 'cursor', label: 'Cursor', hint: '.cursor/rules/' },\n { value: 'codex', label: 'Codex (OpenAI)', hint: 'AGENTS.md' },\n { value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },\n];\n","/**\n * setup/auth.ts — Authentication and API key issuance for setup wizard.\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport { createClient } from '@supabase/supabase-js';\nimport {\n LOCAL_SUPABASE_ANON_KEY,\n LOCAL_SUPABASE_SERVICE_ROLE_KEY,\n PRODUCTION_SUPABASE_PUBLISHABLE_KEY,\n PRODUCTION_SUPABASE_URL,\n} from '../src/supabase-defaults.js';\n\nconst API_KEY_PREFIX = 'ff_live_';\nconst MAX_RETRIES = 3;\n\nexport interface AuthResult {\n valid: boolean;\n apiKey: string;\n error?: string;\n}\n\nexport interface LocalAuthResult {\n apiKey: string;\n userId: string;\n email: string;\n}\n\ninterface SetupAuthOptions {\n supabaseUrl?: string;\n anonKey?: string;\n localDev?: boolean;\n}\n\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n const normalized = value.trim().toLowerCase();\n return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';\n}\n\nfunction getSupabaseUrl(options?: SetupAuthOptions): string {\n return options?.supabaseUrl ?? process.env.SUPABASE_URL ?? PRODUCTION_SUPABASE_URL;\n}\n\nfunction isLocalSupabaseUrl(supabaseUrl: string): boolean {\n try {\n const parsed = new URL(supabaseUrl);\n return parsed.hostname === '127.0.0.1' || parsed.hostname === 'localhost';\n } catch {\n return false;\n }\n}\n\nfunction isLocalMode(options?: SetupAuthOptions): boolean {\n if (options?.localDev !== undefined) return options.localDev;\n if (isTruthy(process.env.FORCEFIELD_LOCAL_DEV)) return true;\n return isLocalSupabaseUrl(getSupabaseUrl(options));\n}\n\nfunction getAnonKey(supabaseUrl: string, options?: SetupAuthOptions): string {\n const explicit = options?.anonKey ?? process.env.SUPABASE_ANON_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_ANON_KEY;\n }\n\n return PRODUCTION_SUPABASE_PUBLISHABLE_KEY;\n}\n\nfunction getServiceRoleKey(supabaseUrl: string): string | null {\n const explicit = process.env.SUPABASE_SERVICE_ROLE_KEY;\n if (explicit && explicit.trim().length > 0) return explicit;\n\n if (isLocalSupabaseUrl(supabaseUrl)) {\n return LOCAL_SUPABASE_SERVICE_ROLE_KEY;\n }\n\n return null;\n}\n\n/**\n * Validate API key format.\n */\nexport function validateApiKeyFormat(key: string): boolean {\n return key.startsWith(API_KEY_PREFIX) && key.length > API_KEY_PREFIX.length + 8;\n}\n\n/**\n * Verify an API key through key-exchange endpoint.\n */\nexport async function verifyApiKey(apiKey: string, options?: SetupAuthOptions): Promise<AuthResult> {\n if (!validateApiKeyFormat(apiKey)) {\n return {\n valid: false,\n apiKey: '',\n error: 'Invalid API key format. Keys must start with \"ff_live_\".',\n };\n }\n\n const supabaseUrl = getSupabaseUrl(options);\n const endpoint = `${supabaseUrl}/functions/v1/key-exchange`;\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n const payload = await response.json().catch(() => ({})) as { error?: string };\n const detail = payload.error ?? 'API key invalid or revoked.';\n return {\n valid: false,\n apiKey: '',\n error: `Authentication failed (${response.status}): ${detail}`,\n };\n }\n\n return { valid: true, apiKey };\n } catch {\n return {\n valid: false,\n apiKey: '',\n error: `Could not reach Forcefield backend at ${supabaseUrl}. Check SUPABASE_URL/network and retry.`,\n };\n }\n}\n\n/**\n * Authenticate with retries.\n */\nexport async function authenticateWithRetry(\n getKey: () => Promise<string | null>,\n options?: SetupAuthOptions,\n): Promise<AuthResult> {\n let lastError: string | undefined;\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n const key = await getKey();\n\n if (!key) {\n return { valid: false, apiKey: '', error: 'No API key provided.' };\n }\n\n const verified = await verifyApiKey(key, options);\n if (verified.valid) {\n return verified;\n }\n\n lastError = verified.error;\n\n if (attempt < MAX_RETRIES) {\n continue;\n }\n }\n\n return {\n valid: false,\n apiKey: '',\n error: lastError ?? `Authentication failed after ${MAX_RETRIES} attempts.`,\n };\n}\n\nfunction generateApiKey(): { plaintext: string; hash: string; prefix: string } {\n const raw = randomBytes(32).toString('hex');\n const plaintext = `${API_KEY_PREFIX}${raw}`;\n const hash = createHash('sha256').update(plaintext).digest('hex');\n const prefix = plaintext.slice(0, 12);\n return { plaintext, hash, prefix };\n}\n\n/**\n * Hosted/local account flow:\n * 1. Sign in (or sign up + sign in)\n * 2. Insert API key under authenticated user\n */\nexport async function authenticateAccountAndCreateApiKey(\n email: string,\n password: string,\n options?: {\n supabaseUrl?: string;\n anonKey?: string;\n label?: string;\n localDev?: boolean;\n },\n): Promise<LocalAuthResult> {\n const supabaseUrl = getSupabaseUrl(options);\n const anonKey = getAnonKey(supabaseUrl, options);\n\n const supabase = createClient(supabaseUrl, anonKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let signIn = await supabase.auth.signInWithPassword({ email, password });\n\n if (signIn.error || !signIn.data.user) {\n await supabase.auth.signUp({ email, password });\n signIn = await supabase.auth.signInWithPassword({ email, password });\n }\n\n if (signIn.error || !signIn.data.user) {\n const message = signIn.error?.message ?? 'Invalid login credentials';\n throw new Error(`Authentication failed: ${message}`);\n }\n\n const userId = signIn.data.user.id;\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await supabase\n .from('api_keys')\n .insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: options?.label ?? 'Setup Wizard Key',\n tier: 'free',\n });\n\n if (insertError) {\n if (isLocalMode(options)) {\n const serviceRoleKey = getServiceRoleKey(supabaseUrl);\n if (serviceRoleKey) {\n return createApiKeyViaServiceRole({\n supabaseUrl,\n serviceRoleKey,\n email,\n password,\n label: options?.label ?? 'Setup Wizard Key',\n });\n }\n }\n\n throw new Error(`Failed to create API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email,\n };\n}\n\n/**\n * Local auth flow preserved for scripted local development.\n */\nexport async function authenticateLocalAndCreateApiKey(\n email: string,\n password: string,\n options?: { supabaseUrl?: string; anonKey?: string; label?: string },\n): Promise<LocalAuthResult> {\n return authenticateAccountAndCreateApiKey(email, password, {\n ...options,\n localDev: true,\n label: options?.label ?? 'Local Setup Key',\n });\n}\n\nasync function createApiKeyViaServiceRole(params: {\n supabaseUrl: string;\n serviceRoleKey: string;\n email: string;\n password: string;\n label: string;\n}): Promise<LocalAuthResult> {\n const admin = createClient(params.supabaseUrl, params.serviceRoleKey, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n let userId: string | undefined;\n const createUser = await admin.auth.admin.createUser({\n email: params.email,\n password: params.password,\n email_confirm: true,\n });\n\n if (createUser.data.user?.id) {\n userId = createUser.data.user.id;\n } else if (createUser.error) {\n const authDb = createClient(params.supabaseUrl, params.serviceRoleKey, {\n db: { schema: 'auth' },\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n });\n\n const existingUser = await authDb\n .from('users')\n .select('id,email')\n .eq('email', params.email)\n .limit(1)\n .maybeSingle();\n\n if (existingUser.error) {\n throw new Error(`Local login failed: ${createUser.error.message}`);\n }\n userId = existingUser.data?.id;\n }\n\n if (!userId) {\n throw new Error('Local login failed: could not resolve user account');\n }\n\n const { plaintext, hash, prefix } = generateApiKey();\n const { error: insertError } = await admin.from('api_keys').insert({\n user_id: userId,\n key_hash: hash,\n key_prefix: prefix,\n label: params.label,\n tier: 'free',\n });\n\n if (insertError) {\n throw new Error(`Failed to create local API key: ${insertError.message}`);\n }\n\n return {\n apiKey: plaintext,\n userId,\n email: params.email,\n };\n}\n\nexport { API_KEY_PREFIX, MAX_RETRIES };\n","/**\n * Forcefield Setup Wizard — entry point.\n *\n * This is the setup wizard binary (forcefield-setup), invoked via\n * `npx -y -p @forcefield/mcp-server forcefield setup`.\n * Parses CLI arguments and launches the interactive wizard.\n */\n\nimport type { CliArgs, Ide, SetupMode } from './types.js';\nimport { runWizard } from './wizard.js';\nimport { pathToFileURL } from 'node:url';\n\nfunction parseArgs(argv: string[]): CliArgs {\n const args: CliArgs = {};\n\n for (let i = 2; i < argv.length; i++) {\n const arg = argv[i]!;\n\n if (arg === '--status') {\n args.status = true;\n } else if (arg === '--doctor') {\n args.doctor = true;\n } else if (arg === '--ide' && argv[i + 1]) {\n const ide = argv[++i]!;\n if (['claude-code', 'cursor', 'codex', 'windsurf'].includes(ide)) {\n args.ide = ide as Ide;\n }\n } else if (arg === '--mode' && argv[i + 1]) {\n const mode = argv[++i]!;\n if (['full', 'core'].includes(mode)) {\n args.mode = mode as SetupMode;\n }\n } else if (arg === '--token' && argv[i + 1]) {\n args.token = argv[++i]!;\n } else if (arg === '--email' && argv[i + 1]) {\n args.email = argv[++i]!;\n } else if (arg === '--password' && argv[i + 1]) {\n args.password = argv[++i]!;\n } else if (arg === '--local-auth') {\n args.localAuth = true;\n }\n }\n\n return args;\n}\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv);\n const projectDir = process.cwd();\n\n try {\n await runWizard(projectDir, args);\n } catch (err) {\n console.error('Setup failed:', err instanceof Error ? err.message : err);\n process.exit(1);\n }\n}\n\nexport async function runSetupCli(argv: string[] = process.argv): Promise<void> {\n const originalArgv = process.argv;\n process.argv = argv;\n try {\n await main();\n } finally {\n process.argv = originalArgv;\n }\n}\n\nfunction isExecutedDirectly(metaUrl: string): boolean {\n const entryPath = process.argv[1];\n if (!entryPath) return false;\n return metaUrl === pathToFileURL(entryPath).href;\n}\n\nif (isExecutedDirectly(import.meta.url)) {\n void runSetupCli();\n}\n\nexport { parseArgs };\n"],"mappings":"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","names":["readFile","writeFile","access","join","dirname","fileURLToPath","join","access","join","join","mkdir","readdir","copyFile","rm","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","copyFile","rm","mkdir","readFile","writeFile","join","join","mkdir","readFile","writeFile","readdir","mkdir","readFile","writeFile","join","START_MARKER","END_MARKER","join","mkdir","readFile","writeFile","readdir","removeSection","isTruthy","__dirname","dirname","fileURLToPath","join","access","text","readFile","apiKey","confirm","writeFile"]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-7XLGRGP6.js";
5
5
  import {
6
6
  runSetupCli
7
- } from "../chunk-4L46G65Q.js";
7
+ } from "../chunk-5A2F5L4X.js";
8
8
  import "../chunk-6YANB5QT.js";
9
9
 
10
10
  // cli/index.ts
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  parseArgs,
4
4
  runSetupCli
5
- } from "../chunk-4L46G65Q.js";
5
+ } from "../chunk-5A2F5L4X.js";
6
6
  import "../chunk-6YANB5QT.js";
7
7
  export {
8
8
  parseArgs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forcefield/mcp-server",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "AI-powered corporate compliance MCP server",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -9,9 +9,9 @@
9
9
  "tag": "beta"
10
10
  },
11
11
  "bin": {
12
- "forcefield": "./build/cli/index.js",
13
- "forcefield-mcp": "./build/index.js",
14
- "forcefield-setup": "./build/setup/index.js"
12
+ "forcefield": "build/cli/index.js",
13
+ "forcefield-mcp": "build/index.js",
14
+ "forcefield-setup": "build/cli/index.js"
15
15
  },
16
16
  "files": [
17
17
  "build/",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "https://github.com/forcefield-ai/forcefield"
25
+ "url": "git+https://github.com/forcefield-ai/forcefield.git"
26
26
  },
27
27
  "keywords": [
28
28
  "mcp",