@openbuilder/cli 0.50.17 → 0.50.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/chunks/{Banner-D4tqKfzA.js → Banner-ClJs6QcI.js} +3 -4
  2. package/dist/chunks/{Banner-D4tqKfzA.js.map → Banner-ClJs6QcI.js.map} +1 -1
  3. package/dist/chunks/_commonjsHelpers-DcsQGttR.js +32 -0
  4. package/dist/chunks/_commonjsHelpers-DcsQGttR.js.map +1 -0
  5. package/dist/chunks/{init-tui-BNzk_7Yx.js → init-tui-DDxZYe9B.js} +54 -55
  6. package/dist/chunks/{init-tui-BNzk_7Yx.js.map → init-tui-DDxZYe9B.js.map} +1 -1
  7. package/dist/chunks/{init-CZoN6soU.js → init-zX5aX-qn.js} +5 -6
  8. package/dist/chunks/{init-CZoN6soU.js.map → init-zX5aX-qn.js.map} +1 -1
  9. package/dist/chunks/{main-tui-CTgDJWmu.js → main-tui-B5GJ49Bp.js} +43 -44
  10. package/dist/chunks/{main-tui-CTgDJWmu.js.map → main-tui-B5GJ49Bp.js.map} +1 -1
  11. package/dist/chunks/{run-DAEiNzrf.js → run-CaSootos.js} +33 -34
  12. package/dist/chunks/{run-DAEiNzrf.js.map → run-CaSootos.js.map} +1 -1
  13. package/dist/chunks/{start-BygPCbvw.js → start-B4P27nZ7.js} +46 -47
  14. package/dist/chunks/{start-BygPCbvw.js.map → start-B4P27nZ7.js.map} +1 -1
  15. package/dist/chunks/theme-BF4W2Gwm.js +2300 -0
  16. package/dist/chunks/theme-BF4W2Gwm.js.map +1 -0
  17. package/dist/chunks/{useBuildState-CdBSu9y_.js → useBuildState-BZuezCb6.js} +33 -35
  18. package/dist/chunks/{useBuildState-CdBSu9y_.js.map → useBuildState-BZuezCb6.js.map} +1 -1
  19. package/dist/cli/index.js +5 -5
  20. package/dist/instrument.js +1 -29
  21. package/dist/instrument.js.map +1 -1
  22. package/package.json +1 -2
  23. package/scripts/prepare-release.js +9 -0
  24. package/dist/chunks/theme-DhorI2Hb.js +0 -44
  25. package/dist/chunks/theme-DhorI2Hb.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"init-CZoN6soU.js","sources":["../../src/cli/commands/init.ts"],"sourcesContent":["/**\n * Enhanced init command with @clack/prompts and friction-free -y mode\n * Provides beautiful interactive setup or completely automated installation\n * \n * For -y mode: Uses a beautiful centered TUI with animated progress\n */\n\nimport { mkdir, realpath, writeFile } from 'node:fs/promises';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { configManager } from '../utils/config-manager.js';\nimport { isInsideMonorepo } from '../utils/repo-detector.js';\nimport {\n cloneRepository,\n installDependencies,\n isPnpmInstalled,\n buildAgentCore\n} from '../utils/repo-cloner.js';\nimport {\n setupDatabase,\n pushDatabaseSchema,\n connectManualDatabase\n} from '../utils/database-setup.js';\nimport { CLIError, errors } from '../utils/cli-error.js';\nimport { initTUICommand } from './init-tui.js';\n\n/**\n * Generate a secure random secret\n */\nfunction generateSecret(): string {\n return randomBytes(32).toString('hex');\n}\n\n/**\n * Check if a path is or contains the current working directory\n * Prevents accidental deletion of the directory we're running from\n */\nfunction isCurrentWorkingDirectory(targetPath: string): boolean {\n try {\n const cwd = realpathSync(process.cwd());\n const target = realpathSync(resolve(targetPath));\n // Check if target is cwd or if cwd is inside target\n return cwd === target || cwd.startsWith(target + '/');\n } catch {\n // If we can't resolve paths, be safe and assume it might be cwd\n const cwd = process.cwd();\n const target = resolve(targetPath);\n return cwd === target || cwd.startsWith(target + '/');\n }\n}\n\n/**\n * Safely remove a directory, but never the current working directory\n */\nfunction safeRemoveDirectory(targetPath: string, rmSync: typeof import('fs').rmSync): boolean {\n if (isCurrentWorkingDirectory(targetPath)) {\n console.error(`\\n⚠️ Cannot remove ${targetPath} - it is the current working directory`);\n console.error(' Please run this command from a different directory.\\n');\n return false;\n }\n rmSync(targetPath, { recursive: true, force: true });\n return true;\n}\n\n/**\n * Normalize URL by adding protocol if missing\n */\nfunction normalizeUrl(url: string): string {\n if (!url) return url;\n if (url.match(/^https?:\\/\\//i)) return url;\n if (url.match(/^(localhost|127\\.0\\.0\\.1)(:|\\/|$)/i)) {\n return `http://${url}`;\n }\n return `https://${url}`;\n}\n\n/**\n * Get default workspace path\n */\nfunction getDefaultWorkspace(): string {\n return join(process.cwd(), 'openbuilder-workspace');\n}\n\n/**\n * Get default monorepo clone path\n */\nfunction getDefaultMonorepoPath(): string {\n return join(process.cwd(), 'openbuilder');\n}\n\ninterface InitOptions {\n workspace?: string;\n url?: string;\n secret?: string;\n branch?: string;\n database?: string | boolean; // Can be: undefined (neon), or a PostgreSQL connection string\n yes?: boolean;\n nonInteractive?: boolean;\n}\n\nexport async function initCommand(options: InitOptions) {\n const isNonInteractive = options.nonInteractive || options.yes;\n\n // ========================================\n // NON-INTERACTIVE MODE: Use beautiful TUI\n // ========================================\n if (isNonInteractive) {\n return initTUICommand(options);\n }\n\n // ========================================\n // INTERACTIVE MODE (Beautiful @clack/prompts)\n // ========================================\n // Handle Ctrl+C gracefully\n const handleCancel = () => {\n p.cancel('Setup cancelled');\n process.exit(0);\n };\n\n try {\n {\n // Keep banner visible - don't clear screen\n console.log(); // Just add spacing\n\n p.intro(pc.bgCyan(pc.black(' OpenBuilder Setup ')));\n\n // Step 1: Check if already initialized\n if (configManager.isInitialized()) {\n const shouldReset = await p.confirm({\n message: 'Configuration already exists. Reset and reconfigure?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldReset)) {\n handleCancel();\n return;\n }\n\n if (!shouldReset) {\n p.cancel('Setup cancelled');\n return;\n }\n\n configManager.reset();\n p.log.success('Configuration reset');\n }\n\n // Step 2: Check for monorepo\n const s = p.spinner();\n s.start('Checking for OpenBuilder repository');\n\n const repoCheck = await isInsideMonorepo();\n let monorepoPath: string | undefined;\n\n if (repoCheck.inside && repoCheck.root) {\n s.stop(pc.green('✓') + ' Found repository at: ' + pc.cyan(repoCheck.root));\n monorepoPath = repoCheck.root;\n } else {\n s.stop('Repository not found in current directory');\n\n const shouldClone = await p.confirm({\n message: 'Clone OpenBuilder repository?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldClone)) {\n handleCancel();\n return;\n }\n\n if (shouldClone) {\n // Check for pnpm\n const hasPnpm = await isPnpmInstalled();\n if (!hasPnpm) {\n throw new CLIError({\n code: 'DEPENDENCIES_INSTALL_FAILED',\n message: 'pnpm is not installed',\n suggestions: [\n 'Install pnpm: npm install -g pnpm',\n 'Or visit: https://pnpm.io/installation',\n ],\n });\n }\n\n const clonePath = await p.text({\n message: 'Where should the repository be cloned?',\n placeholder: getDefaultMonorepoPath(),\n defaultValue: getDefaultMonorepoPath(),\n validate: (value) => {\n if (!value) return 'Path is required';\n },\n });\n\n if (p.isCancel(clonePath)) {\n handleCancel();\n return;\n }\n\n // Check if path exists\n const defaultWorkspace = getDefaultWorkspace();\n const existingInstallation = existsSync(clonePath as string) || existsSync(defaultWorkspace);\n\n if (existingInstallation) {\n const shouldOverwrite = await p.confirm({\n message: `Existing OpenBuilder installation found. Replace it with fresh install?`,\n initialValue: true,\n });\n\n if (p.isCancel(shouldOverwrite)) {\n handleCancel();\n return;\n }\n\n if (shouldOverwrite) {\n s.start('Removing existing installation');\n const { rmSync } = await import('fs');\n\n // Safety check: never delete the current working directory\n if (existsSync(clonePath as string)) {\n if (!safeRemoveDirectory(clonePath as string, rmSync)) {\n s.stop(pc.red('✗') + ' Cannot remove current working directory');\n p.cancel('Please run openbuilder init from a different directory');\n return;\n }\n }\n\n // Delete workspace directory\n if (existsSync(defaultWorkspace)) {\n if (!safeRemoveDirectory(defaultWorkspace, rmSync)) {\n s.stop(pc.red('✗') + ' Cannot remove current working directory');\n p.cancel('Please run openbuilder init from a different directory');\n return;\n }\n }\n\n s.stop(pc.green('✓') + ' Existing installation removed');\n } else {\n p.cancel('Setup cancelled');\n return;\n }\n }\n\n // Clone, install, build\n try {\n s.start('Cloning repository from GitHub');\n monorepoPath = await cloneRepository({\n targetPath: clonePath as string,\n branch: options.branch || 'main',\n });\n s.stop(pc.green('✓') + ' Repository cloned');\n\n s.start('Installing dependencies (this may take a few minutes)');\n await installDependencies(monorepoPath);\n s.stop(pc.green('✓') + ' Dependencies installed');\n\n s.start('Building @openbuilder/agent-core');\n await buildAgentCore(monorepoPath);\n s.stop(pc.green('✓') + ' Build complete');\n\n // Ask about pre-building services\n const shouldPreBuild = await p.confirm({\n message: 'Pre-build all services for production performance?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldPreBuild)) {\n handleCancel();\n return;\n }\n\n if (shouldPreBuild) {\n s.start('Building all services (this may take a minute)');\n const { spawn } = await import('child_process');\n\n try {\n await new Promise<void>((resolve, reject) => {\n const buildProcess = spawn('pnpm', ['build:all'], {\n cwd: monorepoPath,\n stdio: 'pipe',\n shell: true,\n });\n\n buildProcess.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Build failed with code ${code}`));\n }\n });\n\n buildProcess.on('error', reject);\n });\n\n s.stop(pc.green('✓') + ' All services built for production');\n } catch (error) {\n s.stop(pc.yellow('⚠') + ' Build failed (you can build later with: pnpm build:all)');\n }\n }\n } catch (error) {\n throw new CLIError({\n code: 'MONOREPO_CLONE_FAILED',\n message: 'Failed to setup repository',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check your internet connection',\n 'Verify you have git installed: git --version',\n 'Try cloning manually: git clone https://github.com/codyde/openbuilder.git',\n ],\n });\n }\n } else {\n p.note(\n 'Setup will continue in runner-only mode.\\nYou can add the repository path later with:\\n openbuilder config set monorepoPath <path>',\n 'Repository setup skipped'\n );\n }\n }\n\n // Step 3: Workspace configuration\n p.log.step(pc.cyan('Workspace Configuration'));\n\n const workspace = await p.text({\n message: 'Where should generated projects be stored?',\n placeholder: getDefaultWorkspace(),\n defaultValue: getDefaultWorkspace(),\n validate: (value) => {\n if (!value) return 'Workspace path is required';\n },\n });\n\n if (p.isCancel(workspace)) {\n handleCancel();\n return;\n }\n\n // Create workspace directory\n try {\n if (!existsSync(workspace as string)) {\n await mkdir(workspace as string, { recursive: true });\n }\n } catch (error) {\n throw errors.workspaceNotFound(workspace as string);\n }\n\n // Step 4: Connection configuration\n p.log.step(pc.cyan('Connection Configuration'));\n\n const wsUrl = await p.text({\n message: 'Server WebSocket URL',\n placeholder: 'ws://localhost:3000/ws/runner',\n defaultValue: 'ws://localhost:3000/ws/runner',\n });\n\n if (p.isCancel(wsUrl)) {\n handleCancel();\n return;\n }\n\n const apiUrl = await p.text({\n message: 'API base URL',\n placeholder: 'http://localhost:3000',\n defaultValue: options.url || 'http://localhost:3000',\n });\n\n if (p.isCancel(apiUrl)) {\n handleCancel();\n return;\n }\n\n // Step 5: Security\n const secret = await p.text({\n message: 'Shared secret (press Enter to generate)',\n placeholder: 'Generated automatically',\n defaultValue: options.secret || generateSecret(),\n });\n\n if (p.isCancel(secret)) {\n handleCancel();\n return;\n }\n\n const runnerId = await p.text({\n message: 'Runner ID',\n placeholder: 'local',\n defaultValue: 'local',\n });\n\n if (p.isCancel(runnerId)) {\n handleCancel();\n return;\n }\n\n // Step 6: Database setup (if monorepo available)\n let databaseUrl: string | undefined;\n\n if (monorepoPath) {\n p.log.step(pc.cyan('Database Setup'));\n\n const dbChoice = await p.select({\n message: 'Database configuration',\n options: [\n {\n value: 'neon',\n label: 'Create Neon database (recommended)',\n hint: 'Free tier, persistent storage'\n },\n {\n value: 'existing',\n label: 'Use existing PostgreSQL',\n hint: 'Provide connection string'\n },\n ],\n });\n\n if (p.isCancel(dbChoice)) {\n handleCancel();\n return;\n }\n\n if (dbChoice === 'neon') {\n p.note(\n 'Opening Neon in your browser...\\nCreate a database and paste the connection string below.',\n pc.cyan('Database Setup')\n );\n databaseUrl = await setupDatabase(monorepoPath) || undefined;\n \n // Push schema if we have a database\n if (databaseUrl) {\n s.start('Pushing database schema');\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n if (pushed) {\n s.stop(pc.green('✓') + ' Schema initialized');\n } else {\n s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');\n }\n }\n } else if (dbChoice === 'existing') {\n databaseUrl = await connectManualDatabase() || undefined;\n \n // Push schema if we have a database\n if (databaseUrl) {\n s.start('Pushing database schema');\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n if (pushed) {\n s.stop(pc.green('✓') + ' Schema initialized');\n } else {\n s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');\n }\n }\n }\n }\n\n // Step 7: Save configuration\n try {\n configManager.set('workspace', workspace);\n if (monorepoPath) {\n configManager.set('monorepoPath', monorepoPath);\n }\n if (databaseUrl) {\n configManager.set('databaseUrl', databaseUrl);\n }\n configManager.set('apiUrl', normalizeUrl(apiUrl as string));\n configManager.set('server', {\n wsUrl: wsUrl,\n secret: secret,\n });\n configManager.set('runner', {\n id: runnerId,\n reconnectAttempts: 5,\n heartbeatInterval: 15000,\n });\n configManager.set('tunnel', {\n provider: 'cloudflare',\n autoCreate: true,\n });\n } catch (error) {\n throw new CLIError({\n code: 'CONFIG_INVALID',\n message: 'Failed to save configuration',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check file permissions on config directory',\n 'Try running with sudo (not recommended)',\n ],\n });\n }\n\n // Validate\n const validation = configManager.validate();\n if (!validation.valid) {\n throw new CLIError({\n code: 'CONFIG_INVALID',\n message: 'Configuration validation failed',\n context: { errors: validation.errors },\n suggestions: validation.errors,\n });\n }\n\n // Success!\n p.outro(pc.green('✨ OpenBuilder is ready!'));\n\n p.note(\n `${pc.cyan('openbuilder run')}\\n\\nThen open: ${pc.cyan('http://localhost:3000')}`,\n 'Next Steps'\n );\n\n return;\n }\n } catch (error) {\n // Handle cancellation gracefully\n if (error && typeof error === 'object' && 'name' in error) {\n if ((error as { name: string }).name === 'ExitPromptError' || (error as { code?: string }).code === 'CLACK_CANCEL') {\n handleCancel();\n return;\n }\n }\n\n // Re-throw for global error handler\n throw error;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init-zX5aX-qn.js","sources":["../../src/cli/commands/init.ts"],"sourcesContent":["/**\n * Enhanced init command with @clack/prompts and friction-free -y mode\n * Provides beautiful interactive setup or completely automated installation\n * \n * For -y mode: Uses a beautiful centered TUI with animated progress\n */\n\nimport { mkdir, realpath, writeFile } from 'node:fs/promises';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { configManager } from '../utils/config-manager.js';\nimport { isInsideMonorepo } from '../utils/repo-detector.js';\nimport {\n cloneRepository,\n installDependencies,\n isPnpmInstalled,\n buildAgentCore\n} from '../utils/repo-cloner.js';\nimport {\n setupDatabase,\n pushDatabaseSchema,\n connectManualDatabase\n} from '../utils/database-setup.js';\nimport { CLIError, errors } from '../utils/cli-error.js';\nimport { initTUICommand } from './init-tui.js';\n\n/**\n * Generate a secure random secret\n */\nfunction generateSecret(): string {\n return randomBytes(32).toString('hex');\n}\n\n/**\n * Check if a path is or contains the current working directory\n * Prevents accidental deletion of the directory we're running from\n */\nfunction isCurrentWorkingDirectory(targetPath: string): boolean {\n try {\n const cwd = realpathSync(process.cwd());\n const target = realpathSync(resolve(targetPath));\n // Check if target is cwd or if cwd is inside target\n return cwd === target || cwd.startsWith(target + '/');\n } catch {\n // If we can't resolve paths, be safe and assume it might be cwd\n const cwd = process.cwd();\n const target = resolve(targetPath);\n return cwd === target || cwd.startsWith(target + '/');\n }\n}\n\n/**\n * Safely remove a directory, but never the current working directory\n */\nfunction safeRemoveDirectory(targetPath: string, rmSync: typeof import('fs').rmSync): boolean {\n if (isCurrentWorkingDirectory(targetPath)) {\n console.error(`\\n⚠️ Cannot remove ${targetPath} - it is the current working directory`);\n console.error(' Please run this command from a different directory.\\n');\n return false;\n }\n rmSync(targetPath, { recursive: true, force: true });\n return true;\n}\n\n/**\n * Normalize URL by adding protocol if missing\n */\nfunction normalizeUrl(url: string): string {\n if (!url) return url;\n if (url.match(/^https?:\\/\\//i)) return url;\n if (url.match(/^(localhost|127\\.0\\.0\\.1)(:|\\/|$)/i)) {\n return `http://${url}`;\n }\n return `https://${url}`;\n}\n\n/**\n * Get default workspace path\n */\nfunction getDefaultWorkspace(): string {\n return join(process.cwd(), 'openbuilder-workspace');\n}\n\n/**\n * Get default monorepo clone path\n */\nfunction getDefaultMonorepoPath(): string {\n return join(process.cwd(), 'openbuilder');\n}\n\ninterface InitOptions {\n workspace?: string;\n url?: string;\n secret?: string;\n branch?: string;\n database?: string | boolean; // Can be: undefined (neon), or a PostgreSQL connection string\n yes?: boolean;\n nonInteractive?: boolean;\n}\n\nexport async function initCommand(options: InitOptions) {\n const isNonInteractive = options.nonInteractive || options.yes;\n\n // ========================================\n // NON-INTERACTIVE MODE: Use beautiful TUI\n // ========================================\n if (isNonInteractive) {\n return initTUICommand(options);\n }\n\n // ========================================\n // INTERACTIVE MODE (Beautiful @clack/prompts)\n // ========================================\n // Handle Ctrl+C gracefully\n const handleCancel = () => {\n p.cancel('Setup cancelled');\n process.exit(0);\n };\n\n try {\n {\n // Keep banner visible - don't clear screen\n console.log(); // Just add spacing\n\n p.intro(pc.bgCyan(pc.black(' OpenBuilder Setup ')));\n\n // Step 1: Check if already initialized\n if (configManager.isInitialized()) {\n const shouldReset = await p.confirm({\n message: 'Configuration already exists. Reset and reconfigure?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldReset)) {\n handleCancel();\n return;\n }\n\n if (!shouldReset) {\n p.cancel('Setup cancelled');\n return;\n }\n\n configManager.reset();\n p.log.success('Configuration reset');\n }\n\n // Step 2: Check for monorepo\n const s = p.spinner();\n s.start('Checking for OpenBuilder repository');\n\n const repoCheck = await isInsideMonorepo();\n let monorepoPath: string | undefined;\n\n if (repoCheck.inside && repoCheck.root) {\n s.stop(pc.green('✓') + ' Found repository at: ' + pc.cyan(repoCheck.root));\n monorepoPath = repoCheck.root;\n } else {\n s.stop('Repository not found in current directory');\n\n const shouldClone = await p.confirm({\n message: 'Clone OpenBuilder repository?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldClone)) {\n handleCancel();\n return;\n }\n\n if (shouldClone) {\n // Check for pnpm\n const hasPnpm = await isPnpmInstalled();\n if (!hasPnpm) {\n throw new CLIError({\n code: 'DEPENDENCIES_INSTALL_FAILED',\n message: 'pnpm is not installed',\n suggestions: [\n 'Install pnpm: npm install -g pnpm',\n 'Or visit: https://pnpm.io/installation',\n ],\n });\n }\n\n const clonePath = await p.text({\n message: 'Where should the repository be cloned?',\n placeholder: getDefaultMonorepoPath(),\n defaultValue: getDefaultMonorepoPath(),\n validate: (value) => {\n if (!value) return 'Path is required';\n },\n });\n\n if (p.isCancel(clonePath)) {\n handleCancel();\n return;\n }\n\n // Check if path exists\n const defaultWorkspace = getDefaultWorkspace();\n const existingInstallation = existsSync(clonePath as string) || existsSync(defaultWorkspace);\n\n if (existingInstallation) {\n const shouldOverwrite = await p.confirm({\n message: `Existing OpenBuilder installation found. Replace it with fresh install?`,\n initialValue: true,\n });\n\n if (p.isCancel(shouldOverwrite)) {\n handleCancel();\n return;\n }\n\n if (shouldOverwrite) {\n s.start('Removing existing installation');\n const { rmSync } = await import('fs');\n\n // Safety check: never delete the current working directory\n if (existsSync(clonePath as string)) {\n if (!safeRemoveDirectory(clonePath as string, rmSync)) {\n s.stop(pc.red('✗') + ' Cannot remove current working directory');\n p.cancel('Please run openbuilder init from a different directory');\n return;\n }\n }\n\n // Delete workspace directory\n if (existsSync(defaultWorkspace)) {\n if (!safeRemoveDirectory(defaultWorkspace, rmSync)) {\n s.stop(pc.red('✗') + ' Cannot remove current working directory');\n p.cancel('Please run openbuilder init from a different directory');\n return;\n }\n }\n\n s.stop(pc.green('✓') + ' Existing installation removed');\n } else {\n p.cancel('Setup cancelled');\n return;\n }\n }\n\n // Clone, install, build\n try {\n s.start('Cloning repository from GitHub');\n monorepoPath = await cloneRepository({\n targetPath: clonePath as string,\n branch: options.branch || 'main',\n });\n s.stop(pc.green('✓') + ' Repository cloned');\n\n s.start('Installing dependencies (this may take a few minutes)');\n await installDependencies(monorepoPath);\n s.stop(pc.green('✓') + ' Dependencies installed');\n\n s.start('Building @openbuilder/agent-core');\n await buildAgentCore(monorepoPath);\n s.stop(pc.green('✓') + ' Build complete');\n\n // Ask about pre-building services\n const shouldPreBuild = await p.confirm({\n message: 'Pre-build all services for production performance?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldPreBuild)) {\n handleCancel();\n return;\n }\n\n if (shouldPreBuild) {\n s.start('Building all services (this may take a minute)');\n const { spawn } = await import('child_process');\n\n try {\n await new Promise<void>((resolve, reject) => {\n const buildProcess = spawn('pnpm', ['build:all'], {\n cwd: monorepoPath,\n stdio: 'pipe',\n shell: true,\n });\n\n buildProcess.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Build failed with code ${code}`));\n }\n });\n\n buildProcess.on('error', reject);\n });\n\n s.stop(pc.green('✓') + ' All services built for production');\n } catch (error) {\n s.stop(pc.yellow('⚠') + ' Build failed (you can build later with: pnpm build:all)');\n }\n }\n } catch (error) {\n throw new CLIError({\n code: 'MONOREPO_CLONE_FAILED',\n message: 'Failed to setup repository',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check your internet connection',\n 'Verify you have git installed: git --version',\n 'Try cloning manually: git clone https://github.com/codyde/openbuilder.git',\n ],\n });\n }\n } else {\n p.note(\n 'Setup will continue in runner-only mode.\\nYou can add the repository path later with:\\n openbuilder config set monorepoPath <path>',\n 'Repository setup skipped'\n );\n }\n }\n\n // Step 3: Workspace configuration\n p.log.step(pc.cyan('Workspace Configuration'));\n\n const workspace = await p.text({\n message: 'Where should generated projects be stored?',\n placeholder: getDefaultWorkspace(),\n defaultValue: getDefaultWorkspace(),\n validate: (value) => {\n if (!value) return 'Workspace path is required';\n },\n });\n\n if (p.isCancel(workspace)) {\n handleCancel();\n return;\n }\n\n // Create workspace directory\n try {\n if (!existsSync(workspace as string)) {\n await mkdir(workspace as string, { recursive: true });\n }\n } catch (error) {\n throw errors.workspaceNotFound(workspace as string);\n }\n\n // Step 4: Connection configuration\n p.log.step(pc.cyan('Connection Configuration'));\n\n const wsUrl = await p.text({\n message: 'Server WebSocket URL',\n placeholder: 'ws://localhost:3000/ws/runner',\n defaultValue: 'ws://localhost:3000/ws/runner',\n });\n\n if (p.isCancel(wsUrl)) {\n handleCancel();\n return;\n }\n\n const apiUrl = await p.text({\n message: 'API base URL',\n placeholder: 'http://localhost:3000',\n defaultValue: options.url || 'http://localhost:3000',\n });\n\n if (p.isCancel(apiUrl)) {\n handleCancel();\n return;\n }\n\n // Step 5: Security\n const secret = await p.text({\n message: 'Shared secret (press Enter to generate)',\n placeholder: 'Generated automatically',\n defaultValue: options.secret || generateSecret(),\n });\n\n if (p.isCancel(secret)) {\n handleCancel();\n return;\n }\n\n const runnerId = await p.text({\n message: 'Runner ID',\n placeholder: 'local',\n defaultValue: 'local',\n });\n\n if (p.isCancel(runnerId)) {\n handleCancel();\n return;\n }\n\n // Step 6: Database setup (if monorepo available)\n let databaseUrl: string | undefined;\n\n if (monorepoPath) {\n p.log.step(pc.cyan('Database Setup'));\n\n const dbChoice = await p.select({\n message: 'Database configuration',\n options: [\n {\n value: 'neon',\n label: 'Create Neon database (recommended)',\n hint: 'Free tier, persistent storage'\n },\n {\n value: 'existing',\n label: 'Use existing PostgreSQL',\n hint: 'Provide connection string'\n },\n ],\n });\n\n if (p.isCancel(dbChoice)) {\n handleCancel();\n return;\n }\n\n if (dbChoice === 'neon') {\n p.note(\n 'Opening Neon in your browser...\\nCreate a database and paste the connection string below.',\n pc.cyan('Database Setup')\n );\n databaseUrl = await setupDatabase(monorepoPath) || undefined;\n \n // Push schema if we have a database\n if (databaseUrl) {\n s.start('Pushing database schema');\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n if (pushed) {\n s.stop(pc.green('✓') + ' Schema initialized');\n } else {\n s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');\n }\n }\n } else if (dbChoice === 'existing') {\n databaseUrl = await connectManualDatabase() || undefined;\n \n // Push schema if we have a database\n if (databaseUrl) {\n s.start('Pushing database schema');\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n if (pushed) {\n s.stop(pc.green('✓') + ' Schema initialized');\n } else {\n s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');\n }\n }\n }\n }\n\n // Step 7: Save configuration\n try {\n configManager.set('workspace', workspace);\n if (monorepoPath) {\n configManager.set('monorepoPath', monorepoPath);\n }\n if (databaseUrl) {\n configManager.set('databaseUrl', databaseUrl);\n }\n configManager.set('apiUrl', normalizeUrl(apiUrl as string));\n configManager.set('server', {\n wsUrl: wsUrl,\n secret: secret,\n });\n configManager.set('runner', {\n id: runnerId,\n reconnectAttempts: 5,\n heartbeatInterval: 15000,\n });\n configManager.set('tunnel', {\n provider: 'cloudflare',\n autoCreate: true,\n });\n } catch (error) {\n throw new CLIError({\n code: 'CONFIG_INVALID',\n message: 'Failed to save configuration',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check file permissions on config directory',\n 'Try running with sudo (not recommended)',\n ],\n });\n }\n\n // Validate\n const validation = configManager.validate();\n if (!validation.valid) {\n throw new CLIError({\n code: 'CONFIG_INVALID',\n message: 'Configuration validation failed',\n context: { errors: validation.errors },\n suggestions: validation.errors,\n });\n }\n\n // Success!\n p.outro(pc.green('✨ OpenBuilder is ready!'));\n\n p.note(\n `${pc.cyan('openbuilder run')}\\n\\nThen open: ${pc.cyan('http://localhost:3000')}`,\n 'Next Steps'\n );\n\n return;\n }\n } catch (error) {\n // Handle cancellation gracefully\n if (error && typeof error === 'object' && 'name' in error) {\n if ((error as { name: string }).name === 'ExitPromptError' || (error as { code?: string }).code === 'CLACK_CANCEL') {\n handleCancel();\n return;\n }\n }\n\n // Re-throw for global error handler\n throw error;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;AAKG;AAyBH;;AAEG;AACH,SAAS,cAAc,GAAA;IACrB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxC;AAEA;;;AAGG;AACH,SAAS,yBAAyB,CAAC,UAAkB,EAAA;AACnD,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;;AAEhD,QAAA,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC;IACvD;AAAE,IAAA,MAAM;;AAEN,QAAA,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;AACzB,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;AAClC,QAAA,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC;IACvD;AACF;AAEA;;AAEG;AACH,SAAS,mBAAmB,CAAC,UAAkB,EAAE,MAAkC,EAAA;AACjF,IAAA,IAAI,yBAAyB,CAAC,UAAU,CAAC,EAAE;AACzC,QAAA,OAAO,CAAC,KAAK,CAAC,uBAAuB,UAAU,CAAA,sCAAA,CAAwC,CAAC;AACxF,QAAA,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC;AACzE,QAAA,OAAO,KAAK;IACd;AACA,IAAA,MAAM,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACpD,IAAA,OAAO,IAAI;AACb;AAEA;;AAEG;AACH,SAAS,YAAY,CAAC,GAAW,EAAA;AAC/B,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,GAAG;AACpB,IAAA,IAAI,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC;AAAE,QAAA,OAAO,GAAG;AAC1C,IAAA,IAAI,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,EAAE;QACnD,OAAO,CAAA,OAAA,EAAU,GAAG,CAAA,CAAE;IACxB;IACA,OAAO,CAAA,QAAA,EAAW,GAAG,CAAA,CAAE;AACzB;AAEA;;AAEG;AACH,SAAS,mBAAmB,GAAA;IAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uBAAuB,CAAC;AACrD;AAEA;;AAEG;AACH,SAAS,sBAAsB,GAAA;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC;AAC3C;AAYO,eAAe,WAAW,CAAC,OAAoB,EAAA;IACpD,MAAM,gBAAgB,GAAG,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG;;;;IAK9D,IAAI,gBAAgB,EAAE;AACpB,QAAA,OAAO,cAAc,CAAC,OAAO,CAAC;IAChC;;;;;IAMA,MAAM,YAAY,GAAG,MAAK;AACxB,QAAA,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;AAC3B,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjB,IAAA,CAAC;AAED,IAAA,IAAI;QACF;;AAEE,YAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAEd,YAAA,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;;AAGnD,YAAA,IAAI,aAAa,CAAC,aAAa,EAAE,EAAE;AACjC,gBAAA,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;AAClC,oBAAA,OAAO,EAAE,sDAAsD;AAC/D,oBAAA,YAAY,EAAE,IAAI;AACnB,iBAAA,CAAC;AAEF,gBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;AAC3B,oBAAA,YAAY,EAAE;oBACd;gBACF;gBAEA,IAAI,CAAC,WAAW,EAAE;AAChB,oBAAA,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;oBAC3B;gBACF;gBAEA,aAAa,CAAC,KAAK,EAAE;AACrB,gBAAA,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,qBAAqB,CAAC;YACtC;;AAGA,YAAA,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE;AACrB,YAAA,CAAC,CAAC,KAAK,CAAC,qCAAqC,CAAC;AAE9C,YAAA,MAAM,SAAS,GAAG,MAAM,gBAAgB,EAAE;AAC1C,YAAA,IAAI,YAAgC;YAEpC,IAAI,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,EAAE;gBACtC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,wBAAwB,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC1E,gBAAA,YAAY,GAAG,SAAS,CAAC,IAAI;YAC/B;iBAAO;AACL,gBAAA,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC;AAEnD,gBAAA,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;AAClC,oBAAA,OAAO,EAAE,+BAA+B;AACxC,oBAAA,YAAY,EAAE,IAAI;AACnB,iBAAA,CAAC;AAEF,gBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;AAC3B,oBAAA,YAAY,EAAE;oBACd;gBACF;gBAEA,IAAI,WAAW,EAAE;;AAEf,oBAAA,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE;oBACvC,IAAI,CAAC,OAAO,EAAE;wBACZ,MAAM,IAAI,QAAQ,CAAC;AACjB,4BAAA,IAAI,EAAE,6BAA6B;AACnC,4BAAA,OAAO,EAAE,uBAAuB;AAChC,4BAAA,WAAW,EAAE;gCACX,mCAAmC;gCACnC,wCAAwC;AACzC,6BAAA;AACF,yBAAA,CAAC;oBACJ;AAEA,oBAAA,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7B,wBAAA,OAAO,EAAE,wCAAwC;wBACjD,WAAW,EAAE,sBAAsB,EAAE;wBACrC,YAAY,EAAE,sBAAsB,EAAE;AACtC,wBAAA,QAAQ,EAAE,CAAC,KAAK,KAAI;AAClB,4BAAA,IAAI,CAAC,KAAK;AAAE,gCAAA,OAAO,kBAAkB;wBACvC,CAAC;AACF,qBAAA,CAAC;AAEF,oBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AACzB,wBAAA,YAAY,EAAE;wBACd;oBACF;;AAGA,oBAAA,MAAM,gBAAgB,GAAG,mBAAmB,EAAE;oBAC9C,MAAM,oBAAoB,GAAG,UAAU,CAAC,SAAmB,CAAC,IAAI,UAAU,CAAC,gBAAgB,CAAC;oBAE5F,IAAI,oBAAoB,EAAE;AACxB,wBAAA,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;AACtC,4BAAA,OAAO,EAAE,CAAA,uEAAA,CAAyE;AAClF,4BAAA,YAAY,EAAE,IAAI;AACnB,yBAAA,CAAC;AAEF,wBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;AAC/B,4BAAA,YAAY,EAAE;4BACd;wBACF;wBAEA,IAAI,eAAe,EAAE;AACnB,4BAAA,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC;4BACzC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,IAAI,CAAC;;AAGrC,4BAAA,IAAI,UAAU,CAAC,SAAmB,CAAC,EAAE;gCACnC,IAAI,CAAC,mBAAmB,CAAC,SAAmB,EAAE,MAAM,CAAC,EAAE;AACrD,oCAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,0CAA0C,CAAC;AAChE,oCAAA,CAAC,CAAC,MAAM,CAAC,wDAAwD,CAAC;oCAClE;gCACF;4BACF;;AAGA,4BAAA,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE;gCAChC,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE;AAClD,oCAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,0CAA0C,CAAC;AAChE,oCAAA,CAAC,CAAC,MAAM,CAAC,wDAAwD,CAAC;oCAClE;gCACF;4BACF;AAEA,4BAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,gCAAgC,CAAC;wBAC1D;6BAAO;AACL,4BAAA,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;4BAC3B;wBACF;oBACF;;AAGA,oBAAA,IAAI;AACF,wBAAA,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC;wBACzC,YAAY,GAAG,MAAM,eAAe,CAAC;AACnC,4BAAA,UAAU,EAAE,SAAmB;AAC/B,4BAAA,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;AACjC,yBAAA,CAAC;AACF,wBAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC;AAE5C,wBAAA,CAAC,CAAC,KAAK,CAAC,uDAAuD,CAAC;AAChE,wBAAA,MAAM,mBAAmB,CAAC,YAAY,CAAC;AACvC,wBAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,yBAAyB,CAAC;AAEjD,wBAAA,CAAC,CAAC,KAAK,CAAC,kCAAkC,CAAC;AAC3C,wBAAA,MAAM,cAAc,CAAC,YAAY,CAAC;AAClC,wBAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC;;AAGzC,wBAAA,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;AACrC,4BAAA,OAAO,EAAE,oDAAoD;AAC7D,4BAAA,YAAY,EAAE,IAAI;AACnB,yBAAA,CAAC;AAEF,wBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;AAC9B,4BAAA,YAAY,EAAE;4BACd;wBACF;wBAEA,IAAI,cAAc,EAAE;AAClB,4BAAA,CAAC,CAAC,KAAK,CAAC,gDAAgD,CAAC;4BACzD,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,eAAe,CAAC;AAE/C,4BAAA,IAAI;gCACF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;oCAC1C,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE;AAChD,wCAAA,GAAG,EAAE,YAAY;AACjB,wCAAA,KAAK,EAAE,MAAM;AACb,wCAAA,KAAK,EAAE,IAAI;AACZ,qCAAA,CAAC;oCAEF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,KAAI;AAChC,wCAAA,IAAI,IAAI,KAAK,CAAC,EAAE;AACd,4CAAA,OAAO,EAAE;wCACX;6CAAO;4CACL,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAA,CAAE,CAAC,CAAC;wCACrD;AACF,oCAAA,CAAC,CAAC;AAEF,oCAAA,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;AAClC,gCAAA,CAAC,CAAC;AAEF,gCAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,oCAAoC,CAAC;4BAC9D;4BAAE,OAAO,KAAK,EAAE;AACd,gCAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,0DAA0D,CAAC;4BACrF;wBACF;oBACF;oBAAE,OAAO,KAAK,EAAE;wBACd,MAAM,IAAI,QAAQ,CAAC;AACjB,4BAAA,IAAI,EAAE,uBAAuB;AAC7B,4BAAA,OAAO,EAAE,4BAA4B;AACrC,4BAAA,KAAK,EAAE,KAAK,YAAY,KAAK,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,4BAAA,WAAW,EAAE;gCACX,gCAAgC;gCAChC,8CAA8C;gCAC9C,2EAA2E;AAC5E,6BAAA;AACF,yBAAA,CAAC;oBACJ;gBACF;qBAAO;AACL,oBAAA,CAAC,CAAC,IAAI,CACJ,qIAAqI,EACrI,0BAA0B,CAC3B;gBACH;YACF;;AAGA,YAAA,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AAE9C,YAAA,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7B,gBAAA,OAAO,EAAE,4CAA4C;gBACrD,WAAW,EAAE,mBAAmB,EAAE;gBAClC,YAAY,EAAE,mBAAmB,EAAE;AACnC,gBAAA,QAAQ,EAAE,CAAC,KAAK,KAAI;AAClB,oBAAA,IAAI,CAAC,KAAK;AAAE,wBAAA,OAAO,4BAA4B;gBACjD,CAAC;AACF,aAAA,CAAC;AAEF,YAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AACzB,gBAAA,YAAY,EAAE;gBACd;YACF;;AAGA,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,UAAU,CAAC,SAAmB,CAAC,EAAE;oBACpC,MAAM,KAAK,CAAC,SAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;gBACvD;YACF;YAAE,OAAO,KAAK,EAAE;AACd,gBAAA,MAAM,MAAM,CAAC,iBAAiB,CAAC,SAAmB,CAAC;YACrD;;AAGA,YAAA,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAE/C,YAAA,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AACzB,gBAAA,OAAO,EAAE,sBAAsB;AAC/B,gBAAA,WAAW,EAAE,+BAA+B;AAC5C,gBAAA,YAAY,EAAE,+BAA+B;AAC9C,aAAA,CAAC;AAEF,YAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AACrB,gBAAA,YAAY,EAAE;gBACd;YACF;AAEA,YAAA,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AAC1B,gBAAA,OAAO,EAAE,cAAc;AACvB,gBAAA,WAAW,EAAE,uBAAuB;AACpC,gBAAA,YAAY,EAAE,OAAO,CAAC,GAAG,IAAI,uBAAuB;AACrD,aAAA,CAAC;AAEF,YAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtB,gBAAA,YAAY,EAAE;gBACd;YACF;;AAGA,YAAA,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AAC1B,gBAAA,OAAO,EAAE,yCAAyC;AAClD,gBAAA,WAAW,EAAE,yBAAyB;AACtC,gBAAA,YAAY,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc,EAAE;AACjD,aAAA,CAAC;AAEF,YAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtB,gBAAA,YAAY,EAAE;gBACd;YACF;AAEA,YAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AAC5B,gBAAA,OAAO,EAAE,WAAW;AACpB,gBAAA,WAAW,EAAE,OAAO;AACpB,gBAAA,YAAY,EAAE,OAAO;AACtB,aAAA,CAAC;AAEF,YAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AACxB,gBAAA,YAAY,EAAE;gBACd;YACF;;AAGA,YAAA,IAAI,WAA+B;YAEnC,IAAI,YAAY,EAAE;AAChB,gBAAA,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAErC,gBAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;AAC9B,oBAAA,OAAO,EAAE,wBAAwB;AACjC,oBAAA,OAAO,EAAE;AACP,wBAAA;AACE,4BAAA,KAAK,EAAE,MAAM;AACb,4BAAA,KAAK,EAAE,oCAAoC;AAC3C,4BAAA,IAAI,EAAE;AACP,yBAAA;AACD,wBAAA;AACE,4BAAA,KAAK,EAAE,UAAU;AACjB,4BAAA,KAAK,EAAE,yBAAyB;AAChC,4BAAA,IAAI,EAAE;AACP,yBAAA;AACF,qBAAA;AACF,iBAAA,CAAC;AAEF,gBAAA,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AACxB,oBAAA,YAAY,EAAE;oBACd;gBACF;AAEA,gBAAA,IAAI,QAAQ,KAAK,MAAM,EAAE;AACvB,oBAAA,CAAC,CAAC,IAAI,CACJ,2FAA2F,EAC3F,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAC1B;oBACD,WAAW,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,IAAI,SAAS;;oBAG5D,IAAI,WAAW,EAAE;AACf,wBAAA,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC;wBAClC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC;wBAClE,IAAI,MAAM,EAAE;AACV,4BAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,qBAAqB,CAAC;wBAC/C;6BAAO;AACL,4BAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,2CAA2C,CAAC;wBACtE;oBACF;gBACF;AAAO,qBAAA,IAAI,QAAQ,KAAK,UAAU,EAAE;AAClC,oBAAA,WAAW,GAAG,MAAM,qBAAqB,EAAE,IAAI,SAAS;;oBAGxD,IAAI,WAAW,EAAE;AACf,wBAAA,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC;wBAClC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC;wBAClE,IAAI,MAAM,EAAE;AACV,4BAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,qBAAqB,CAAC;wBAC/C;6BAAO;AACL,4BAAA,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,2CAA2C,CAAC;wBACtE;oBACF;gBACF;YACF;;AAGA,YAAA,IAAI;AACF,gBAAA,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC;gBACzC,IAAI,YAAY,EAAE;AAChB,oBAAA,aAAa,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC;gBACjD;gBACA,IAAI,WAAW,EAAE;AACf,oBAAA,aAAa,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC;gBAC/C;gBACA,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,MAAgB,CAAC,CAAC;AAC3D,gBAAA,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE;AAC1B,oBAAA,KAAK,EAAE,KAAK;AACZ,oBAAA,MAAM,EAAE,MAAM;AACf,iBAAA,CAAC;AACF,gBAAA,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE;AAC1B,oBAAA,EAAE,EAAE,QAAQ;AACZ,oBAAA,iBAAiB,EAAE,CAAC;AACpB,oBAAA,iBAAiB,EAAE,KAAK;AACzB,iBAAA,CAAC;AACF,gBAAA,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE;AAC1B,oBAAA,QAAQ,EAAE,YAAY;AACtB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA,CAAC;YACJ;YAAE,OAAO,KAAK,EAAE;gBACd,MAAM,IAAI,QAAQ,CAAC;AACjB,oBAAA,IAAI,EAAE,gBAAgB;AACtB,oBAAA,OAAO,EAAE,8BAA8B;AACvC,oBAAA,KAAK,EAAE,KAAK,YAAY,KAAK,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,oBAAA,WAAW,EAAE;wBACX,4CAA4C;wBAC5C,yCAAyC;AAC1C,qBAAA;AACF,iBAAA,CAAC;YACJ;;AAGA,YAAA,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,EAAE;AAC3C,YAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;gBACrB,MAAM,IAAI,QAAQ,CAAC;AACjB,oBAAA,IAAI,EAAE,gBAAgB;AACtB,oBAAA,OAAO,EAAE,iCAAiC;AAC1C,oBAAA,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE;oBACtC,WAAW,EAAE,UAAU,CAAC,MAAM;AAC/B,iBAAA,CAAC;YACJ;;YAGA,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YAE5C,CAAC,CAAC,IAAI,CACJ,CAAA,EAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA,CAAE,EACjF,YAAY,CACb;YAED;QACF;IACF;IAAE,OAAO,KAAK,EAAE;;QAEd,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE;AACzD,YAAA,IAAK,KAA0B,CAAC,IAAI,KAAK,iBAAiB,IAAK,KAA2B,CAAC,IAAI,KAAK,cAAc,EAAE;AAClH,gBAAA,YAAY,EAAE;gBACd;YACF;QACF;;AAGA,QAAA,MAAM,KAAK;IACb;AACF;;;;"}
@@ -1,16 +1,15 @@
1
1
  // OpenBuilder CLI - Built with Rollup
2
- import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useState, useRef, useEffect, useCallback } from 'react';
2
+ import { r as reactExports, j as jsxRuntimeExports, c as colors, s as symbols } from './theme-BF4W2Gwm.js';
4
3
  import { useInput, Box, Text, useStdout, render } from 'ink';
5
4
  import { userInfo, homedir } from 'node:os';
6
5
  import { join } from 'node:path';
7
- import { B as Banner } from './Banner-D4tqKfzA.js';
6
+ import { B as Banner } from './Banner-ClJs6QcI.js';
8
7
  import TextInput from 'ink-text-input';
9
8
  import 'node:fs';
10
9
  import 'node:events';
11
10
  import 'chalk';
12
- import { c as colors, s as symbols } from './theme-DhorI2Hb.js';
13
11
  import { c as configManager } from './config-manager-BkbjtN-H.js';
12
+ import './_commonjsHelpers-DcsQGttR.js';
14
13
  import 'node:child_process';
15
14
  import 'node:url';
16
15
  import 'conf';
@@ -23,7 +22,7 @@ import 'conf';
23
22
  * Exit
24
23
  */
25
24
  function Menu({ items, onSelect }) {
26
- const [selectedIndex, setSelectedIndex] = useState(0);
25
+ const [selectedIndex, setSelectedIndex] = reactExports.useState(0);
27
26
  useInput((input, key) => {
28
27
  if (key.upArrow) {
29
28
  setSelectedIndex(prev => (prev > 0 ? prev - 1 : items.length - 1));
@@ -35,9 +34,9 @@ function Menu({ items, onSelect }) {
35
34
  onSelect(items[selectedIndex]);
36
35
  }
37
36
  });
38
- return (jsx(Box, { flexDirection: "column", alignItems: "flex-start", children: items.map((item, index) => {
37
+ return (jsxRuntimeExports.jsx(Box, { flexDirection: "column", alignItems: "flex-start", children: items.map((item, index) => {
39
38
  const isSelected = index === selectedIndex;
40
- return (jsxs(Box, { marginY: 0, children: [jsx(Text, { color: isSelected ? colors.cyan : colors.gray, children: isSelected ? '› ' : ' ' }), jsx(Text, { color: isSelected ? colors.white : colors.gray, bold: isSelected, children: item.label }), item.description && (jsxs(Text, { color: colors.dimGray, children: [' ', item.description] }))] }, item.id));
39
+ return (jsxRuntimeExports.jsxs(Box, { marginY: 0, children: [jsxRuntimeExports.jsx(Text, { color: isSelected ? colors.cyan : colors.gray, children: isSelected ? '› ' : ' ' }), jsxRuntimeExports.jsx(Text, { color: isSelected ? colors.white : colors.gray, bold: isSelected, children: item.label }), item.description && (jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: [' ', item.description] }))] }, item.id));
41
40
  }) }));
42
41
  }
43
42
 
@@ -53,7 +52,7 @@ function Menu({ items, onSelect }) {
53
52
  * [SELECTED]
54
53
  */
55
54
  function HorizontalSelector({ options, onSelect, onEscape }) {
56
- const [selectedIndex, setSelectedIndex] = useState(0);
55
+ const [selectedIndex, setSelectedIndex] = reactExports.useState(0);
57
56
  useInput((input, key) => {
58
57
  if (key.leftArrow) {
59
58
  setSelectedIndex(prev => (prev > 0 ? prev - 1 : options.length - 1));
@@ -68,10 +67,10 @@ function HorizontalSelector({ options, onSelect, onEscape }) {
68
67
  onEscape();
69
68
  }
70
69
  });
71
- return (jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsx(Box, { flexDirection: "row", gap: 2, children: options.map((option, index) => {
70
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { flexDirection: "row", gap: 2, children: options.map((option, index) => {
72
71
  const isSelected = index === selectedIndex;
73
- return (jsxs(Box, { flexDirection: "column", alignItems: "center", borderStyle: "round", borderColor: isSelected ? colors.cyan : colors.darkGray, paddingX: 3, paddingY: 1, width: 25, children: [jsx(Text, { color: isSelected ? colors.white : colors.gray, bold: isSelected, children: option.title }), jsx(Box, { marginTop: 1, children: jsx(Text, { color: isSelected ? colors.gray : colors.dimGray, wrap: "wrap", children: option.description }) })] }, option.id));
74
- }) }), jsx(Box, { marginTop: 1, children: options.map((option, index) => (jsx(Box, { width: 25, justifyContent: "center", marginX: 1, children: index === selectedIndex && (jsx(Text, { color: colors.cyan, children: '▲' })) }, option.id))) })] }));
72
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", borderStyle: "round", borderColor: isSelected ? colors.cyan : colors.darkGray, paddingX: 3, paddingY: 1, width: 25, children: [jsxRuntimeExports.jsx(Text, { color: isSelected ? colors.white : colors.gray, bold: isSelected, children: option.title }), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsx(Text, { color: isSelected ? colors.gray : colors.dimGray, wrap: "wrap", children: option.description }) })] }, option.id));
73
+ }) }), jsxRuntimeExports.jsx(Box, { marginTop: 1, children: options.map((option, index) => (jsxRuntimeExports.jsx(Box, { width: 25, justifyContent: "center", marginX: 1, children: index === selectedIndex && (jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: '▲' })) }, option.id))) })] }));
75
74
  }
76
75
 
77
76
  /**
@@ -80,15 +79,15 @@ function HorizontalSelector({ options, onSelect, onEscape }) {
80
79
  * Supports paste (multi-character input) with buffering to prevent visual glitches
81
80
  */
82
81
  function MaskedInput({ value, onChange, placeholder = '', maskChar = '*', focused = false, visiblePrefixLength = 5, }) {
83
- const [cursorVisible, setCursorVisible] = useState(true);
82
+ const [cursorVisible, setCursorVisible] = reactExports.useState(true);
84
83
  // Buffer to accumulate rapid input (for paste detection)
85
- const inputBufferRef = useRef('');
86
- const flushTimeoutRef = useRef(null);
84
+ const inputBufferRef = reactExports.useRef('');
85
+ const flushTimeoutRef = reactExports.useRef(null);
87
86
  // Keep current value in ref for use in timeout callbacks
88
- const valueRef = useRef(value);
87
+ const valueRef = reactExports.useRef(value);
89
88
  valueRef.current = value;
90
89
  // Blink cursor when focused
91
- useEffect(() => {
90
+ reactExports.useEffect(() => {
92
91
  if (!focused) {
93
92
  setCursorVisible(false);
94
93
  return;
@@ -100,7 +99,7 @@ function MaskedInput({ value, onChange, placeholder = '', maskChar = '*', focuse
100
99
  return () => clearInterval(interval);
101
100
  }, [focused]);
102
101
  // Flush buffered input - called after a brief delay to batch paste operations
103
- const flushBuffer = useCallback(() => {
102
+ const flushBuffer = reactExports.useCallback(() => {
104
103
  if (inputBufferRef.current) {
105
104
  onChange(valueRef.current + inputBufferRef.current);
106
105
  inputBufferRef.current = '';
@@ -148,7 +147,7 @@ function MaskedInput({ value, onChange, placeholder = '', maskChar = '*', focuse
148
147
  }
149
148
  }, { isActive: focused });
150
149
  // Cleanup timeout on unmount
151
- useEffect(() => {
150
+ reactExports.useEffect(() => {
152
151
  return () => {
153
152
  if (flushTimeoutRef.current) {
154
153
  clearTimeout(flushTimeoutRef.current);
@@ -169,9 +168,9 @@ function MaskedInput({ value, onChange, placeholder = '', maskChar = '*', focuse
169
168
  const displayValue = getDisplayValue();
170
169
  const cursor = focused && cursorVisible ? '│' : ' ';
171
170
  if (!value && !focused) {
172
- return (jsx(Text, { color: colors.dimGray, children: placeholder }));
171
+ return (jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: placeholder }));
173
172
  }
174
- return (jsxs(Text, { color: colors.white, children: [displayValue, focused && jsx(Text, { color: colors.cyan, children: cursor })] }));
173
+ return (jsxRuntimeExports.jsxs(Text, { color: colors.white, children: [displayValue, focused && jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: cursor })] }));
175
174
  }
176
175
 
177
176
  /**
@@ -195,10 +194,10 @@ function RadioGroup({ options, selected, onChange, focused = false }) {
195
194
  }
196
195
  else ;
197
196
  }, { isActive: focused });
198
- return (jsx(Box, { flexDirection: "column", children: options.map((option) => {
197
+ return (jsxRuntimeExports.jsx(Box, { flexDirection: "column", children: options.map((option) => {
199
198
  const isSelected = option.id === selected;
200
199
  const isFocusedOption = focused && isSelected;
201
- return (jsxs(Box, { marginY: 0, children: [jsx(Text, { color: isSelected ? colors.cyan : colors.gray, children: isSelected ? symbols.filledDot : symbols.hollowDot }), jsx(Text, { children: " " }), jsx(Text, { color: isFocusedOption ? colors.white : (isSelected ? colors.gray : colors.dimGray), bold: isFocusedOption, children: option.label })] }, option.id));
200
+ return (jsxRuntimeExports.jsxs(Box, { marginY: 0, children: [jsxRuntimeExports.jsx(Text, { color: isSelected ? colors.cyan : colors.gray, children: isSelected ? symbols.filledDot : symbols.hollowDot }), jsxRuntimeExports.jsx(Text, { children: " " }), jsxRuntimeExports.jsx(Text, { color: isFocusedOption ? colors.white : (isSelected ? colors.gray : colors.dimGray), bold: isFocusedOption, children: option.label })] }, option.id));
202
201
  }) }));
203
202
  }
204
203
 
@@ -229,7 +228,7 @@ function ModeSelectScreen({ onSelect, onEscape }) {
229
228
  const handleSelect = (option) => {
230
229
  onSelect(option.id);
231
230
  };
232
- return (jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsx(Banner, {}), updateAvailable && (jsxs(Box, { marginTop: 1, children: [jsx(Text, { color: colors.cyan, children: "\u2B06 Update available: " }), jsx(Text, { color: colors.success, children: updateAvailable }), jsx(Text, { color: colors.dimGray, children: " \u2014 Run " }), jsx(Text, { color: colors.cyan, children: "openbuilder upgrade" }), jsx(Text, { color: colors.dimGray, children: " to update" })] })), jsx(Box, { marginTop: 2 }), jsx(HorizontalSelector, { options: modeOptions, onSelect: handleSelect, onEscape: onEscape }), jsx(Box, { marginTop: 2 }), jsxs(Text, { color: colors.dimGray, children: ["Use ", '<-', " ", '->', " arrows to navigate, Enter to select, Esc to exit"] })] }));
231
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsxRuntimeExports.jsx(Banner, {}), updateAvailable && (jsxRuntimeExports.jsxs(Box, { marginTop: 1, children: [jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: "\u2B06 Update available: " }), jsxRuntimeExports.jsx(Text, { color: colors.success, children: updateAvailable }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: " \u2014 Run " }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, children: "openbuilder upgrade" }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: " to update" })] })), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsx(HorizontalSelector, { options: modeOptions, onSelect: handleSelect, onEscape: onEscape }), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["Use ", '<-', " ", '->', " arrows to navigate, Enter to select, Esc to exit"] })] }));
233
232
  }
234
233
 
235
234
  /**
@@ -272,7 +271,7 @@ function LocalModeScreen({ isInitialized, onSelect, onEscape }) {
272
271
  const handleSelect = (item) => {
273
272
  onSelect(item.id);
274
273
  };
275
- return (jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsx(Banner, {}), jsx(Box, { marginTop: 1 }), jsx(Text, { color: colors.cyan, bold: true, children: "Local Mode" }), jsx(Box, { marginTop: 1 }), isInitialized ? (jsx(Text, { color: colors.success, children: "\u25CF Configured" })) : (jsx(Text, { color: colors.warning, children: "\u25CB Not configured" })), jsx(Box, { marginTop: 2 }), jsx(Menu, { items: menuItems, onSelect: handleSelect }), jsx(Box, { marginTop: 2 }), jsx(Text, { color: colors.dimGray, children: "Use up/down arrows to navigate, Enter to select, Esc to go back" })] }));
274
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsx(Box, { marginTop: 1 }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: "Local Mode" }), jsxRuntimeExports.jsx(Box, { marginTop: 1 }), isInitialized ? (jsxRuntimeExports.jsx(Text, { color: colors.success, children: "\u25CF Configured" })) : (jsxRuntimeExports.jsx(Text, { color: colors.warning, children: "\u25CB Not configured" })), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsx(Menu, { items: menuItems, onSelect: handleSelect }), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsx(Text, { color: colors.dimGray, children: "Use up/down arrows to navigate, Enter to select, Esc to go back" })] }));
276
275
  }
277
276
 
278
277
  // Fixed label width for alignment
@@ -282,10 +281,10 @@ const LABEL_WIDTH$1 = 14;
282
281
  */
283
282
  function RunnerModeScreen({ initialKey = '', initialRunnerId = '', onStart, onEscape, }) {
284
283
  const { stdout } = useStdout();
285
- const [runnerId, setRunnerId] = useState(initialRunnerId);
286
- const [focusedField, setFocusedField] = useState('key');
284
+ const [runnerId, setRunnerId] = reactExports.useState(initialRunnerId);
285
+ const [focusedField, setFocusedField] = reactExports.useState('key');
287
286
  // We need a separate state for the actual key value since MaskedInput doesn't use ink-text-input
288
- const [runnerKey, setRunnerKey] = useState(initialKey);
287
+ const [runnerKey, setRunnerKey] = reactExports.useState(initialKey);
289
288
  // Calculate vertical centering
290
289
  const terminalHeight = stdout?.rows || 24;
291
290
  const contentHeight = 18;
@@ -328,7 +327,7 @@ function RunnerModeScreen({ initialKey = '', initialRunnerId = '', onStart, onEs
328
327
  const handleKeyChange = (value) => {
329
328
  setRunnerKey(value);
330
329
  };
331
- return (jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsx(Banner, {}), jsx(Box, { marginTop: 1 }), jsx(Text, { color: colors.purple, bold: true, children: "Runner Mode" }), jsx(Box, { marginTop: 2 }), jsxs(Box, { flexDirection: "column", gap: 1, children: [jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsx(Box, { width: LABEL_WIDTH$1, justifyContent: "flex-end", marginRight: 1, children: jsx(Text, { color: focusedField === 'key' ? colors.cyan : colors.gray, children: "Runner Key" }) }), jsx(Box, { borderStyle: "round", borderColor: focusedField === 'key' ? colors.cyan : colors.darkGray, paddingX: 1, width: 40, children: jsx(MaskedInput, { value: runnerKey, onChange: handleKeyChange, placeholder: "Paste your runner key", focused: focusedField === 'key' }) })] }), initialKey && focusedField === 'key' && (jsx(Box, { marginLeft: LABEL_WIDTH$1 + 2, children: jsx(Text, { color: colors.dimGray, italic: true, children: "(auto-filled from previous config)" }) })), jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsx(Box, { width: LABEL_WIDTH$1, justifyContent: "flex-end", marginRight: 1, children: jsx(Text, { color: focusedField === 'runnerId' ? colors.cyan : colors.gray, children: "Runner ID" }) }), jsx(Box, { borderStyle: "round", borderColor: focusedField === 'runnerId' ? colors.cyan : colors.darkGray, paddingX: 1, width: 40, children: focusedField === 'runnerId' ? (jsx(TextInput, { value: runnerId, onChange: setRunnerId, placeholder: initialRunnerId || 'Enter runner ID' })) : (jsx(Text, { color: runnerId ? colors.white : colors.dimGray, children: runnerId || initialRunnerId || 'Enter runner ID' })) })] })] }), jsx(Box, { marginTop: 3 }), jsxs(Text, { color: colors.dimGray, children: ["Enter: ", isLastField ? 'Start runner' : 'Next field', " | Shift+Enter: Start now | Esc: Back"] }), !runnerKey.trim() && (jsx(Box, { marginTop: 1, children: jsx(Text, { color: colors.warning, children: "Runner key is required" }) }))] }));
330
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsx(Box, { marginTop: 1 }), jsxRuntimeExports.jsx(Text, { color: colors.purple, bold: true, children: "Runner Mode" }), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", gap: 1, children: [jsxRuntimeExports.jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { width: LABEL_WIDTH$1, justifyContent: "flex-end", marginRight: 1, children: jsxRuntimeExports.jsx(Text, { color: focusedField === 'key' ? colors.cyan : colors.gray, children: "Runner Key" }) }), jsxRuntimeExports.jsx(Box, { borderStyle: "round", borderColor: focusedField === 'key' ? colors.cyan : colors.darkGray, paddingX: 1, width: 40, children: jsxRuntimeExports.jsx(MaskedInput, { value: runnerKey, onChange: handleKeyChange, placeholder: "Paste your runner key", focused: focusedField === 'key' }) })] }), initialKey && focusedField === 'key' && (jsxRuntimeExports.jsx(Box, { marginLeft: LABEL_WIDTH$1 + 2, children: jsxRuntimeExports.jsx(Text, { color: colors.dimGray, italic: true, children: "(auto-filled from previous config)" }) })), jsxRuntimeExports.jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { width: LABEL_WIDTH$1, justifyContent: "flex-end", marginRight: 1, children: jsxRuntimeExports.jsx(Text, { color: focusedField === 'runnerId' ? colors.cyan : colors.gray, children: "Runner ID" }) }), jsxRuntimeExports.jsx(Box, { borderStyle: "round", borderColor: focusedField === 'runnerId' ? colors.cyan : colors.darkGray, paddingX: 1, width: 40, children: focusedField === 'runnerId' ? (jsxRuntimeExports.jsx(TextInput, { value: runnerId, onChange: setRunnerId, placeholder: initialRunnerId || 'Enter runner ID' })) : (jsxRuntimeExports.jsx(Text, { color: runnerId ? colors.white : colors.dimGray, children: runnerId || initialRunnerId || 'Enter runner ID' })) })] })] }), jsxRuntimeExports.jsx(Box, { marginTop: 3 }), jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["Enter: ", isLastField ? 'Start runner' : 'Next field', " | Shift+Enter: Start now | Esc: Back"] }), !runnerKey.trim() && (jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsx(Text, { color: colors.warning, children: "Runner key is required" }) }))] }));
332
331
  }
333
332
 
334
333
  const databaseOptions = [
@@ -343,15 +342,15 @@ const LABEL_WIDTH = 14;
343
342
  function ConfigFormScreen({ initialConfig, onSubmit, onEscape, error, }) {
344
343
  const { stdout } = useStdout();
345
344
  // Form state
346
- const [branch, setBranch] = useState(initialConfig?.branch || 'main');
345
+ const [branch, setBranch] = reactExports.useState(initialConfig?.branch || 'main');
347
346
  // Clear error when user starts typing in branch field
348
347
  const handleBranchChange = (value) => {
349
348
  setBranch(value);
350
349
  };
351
- const [workspace, setWorkspace] = useState(initialConfig?.workspace || '~/openbuilder-workspace');
352
- const [databaseType, setDatabaseType] = useState(initialConfig?.useNeon === false ? 'custom' : 'neon');
353
- const [databaseUrl, setDatabaseUrl] = useState(initialConfig?.databaseUrl || '');
354
- const [focusedField, setFocusedField] = useState('branch');
350
+ const [workspace, setWorkspace] = reactExports.useState(initialConfig?.workspace || '~/openbuilder-workspace');
351
+ const [databaseType, setDatabaseType] = reactExports.useState(initialConfig?.useNeon === false ? 'custom' : 'neon');
352
+ const [databaseUrl, setDatabaseUrl] = reactExports.useState(initialConfig?.databaseUrl || '');
353
+ const [focusedField, setFocusedField] = reactExports.useState('branch');
355
354
  // Calculate vertical centering
356
355
  const terminalHeight = stdout?.rows || 24;
357
356
  const contentHeight = 22;
@@ -415,14 +414,14 @@ function ConfigFormScreen({ initialConfig, onSubmit, onEscape, error, }) {
415
414
  setFocusedField('databaseUrl');
416
415
  }
417
416
  };
418
- return (jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsx(Banner, {}), jsx(Box, { marginTop: 1 }), jsx(Text, { color: colors.cyan, bold: true, children: "Configure OpenBuilder" }), jsx(Box, { marginTop: 2 }), jsxs(Box, { flexDirection: "column", gap: 1, children: [jsxs(Box, { flexDirection: "column", children: [jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsx(Text, { color: error ? colors.error : (focusedField === 'branch' ? colors.cyan : colors.gray), children: "Branch" }) }), jsx(Box, { borderStyle: "round", borderColor: error ? colors.error : (focusedField === 'branch' ? colors.cyan : colors.darkGray), paddingX: 1, children: focusedField === 'branch' ? (jsx(TextInput, { value: branch, onChange: handleBranchChange, placeholder: "main" })) : (jsx(Text, { color: branch ? colors.white : colors.dimGray, children: branch || 'main' })) })] }), error && (jsx(Box, { marginLeft: LABEL_WIDTH + 2, children: jsxs(Text, { color: colors.error, children: [symbols.cross, " ", error] }) }))] }), jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsx(Text, { color: focusedField === 'workspace' ? colors.cyan : colors.gray, children: "Workspace" }) }), jsx(Box, { borderStyle: "round", borderColor: focusedField === 'workspace' ? colors.cyan : colors.darkGray, paddingX: 1, width: 40, children: focusedField === 'workspace' ? (jsx(TextInput, { value: workspace, onChange: setWorkspace, placeholder: "~/openbuilder-workspace" })) : (jsx(Text, { color: workspace ? colors.white : colors.dimGray, children: workspace || '~/openbuilder-workspace' })) })] }), jsxs(Box, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsx(Text, { color: focusedField === 'database' ? colors.cyan : colors.gray, children: "Database" }) }), jsx(RadioGroup, { options: databaseOptions, selected: databaseType, onChange: handleDatabaseTypeChange, focused: focusedField === 'database' })] }), databaseType === 'custom' && (jsxs(Box, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsx(Text, { color: focusedField === 'databaseUrl' ? colors.cyan : colors.gray, children: "URL" }) }), jsx(Box, { borderStyle: "round", borderColor: focusedField === 'databaseUrl' ? colors.cyan : colors.darkGray, paddingX: 1, width: 50, children: focusedField === 'databaseUrl' ? (jsx(TextInput, { value: databaseUrl, onChange: setDatabaseUrl, placeholder: "postgres://user:pass@host:5432/db" })) : (jsx(Text, { color: databaseUrl ? colors.white : colors.dimGray, children: databaseUrl || 'postgres://user:pass@host:5432/db' })) })] }))] }), jsx(Box, { marginTop: 3 }), jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxs(Text, { color: colors.dimGray, children: ["Enter: ", isLastField ? 'Start' : 'Next field', " | Shift+Enter: Start now | Esc: Back"] }), databaseType === 'custom' && !databaseUrl.trim() && (jsx(Box, { marginTop: 1, children: jsxs(Text, { color: colors.warning, children: [symbols.hollowDot, " Database URL required for custom PostgreSQL"] }) }))] })] }));
417
+ return (jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", paddingTop: topPadding, children: [jsxRuntimeExports.jsx(Banner, {}), jsxRuntimeExports.jsx(Box, { marginTop: 1 }), jsxRuntimeExports.jsx(Text, { color: colors.cyan, bold: true, children: "Configure OpenBuilder" }), jsxRuntimeExports.jsx(Box, { marginTop: 2 }), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", gap: 1, children: [jsxRuntimeExports.jsxs(Box, { flexDirection: "column", children: [jsxRuntimeExports.jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsxRuntimeExports.jsx(Text, { color: error ? colors.error : (focusedField === 'branch' ? colors.cyan : colors.gray), children: "Branch" }) }), jsxRuntimeExports.jsx(Box, { borderStyle: "round", borderColor: error ? colors.error : (focusedField === 'branch' ? colors.cyan : colors.darkGray), paddingX: 1, children: focusedField === 'branch' ? (jsxRuntimeExports.jsx(TextInput, { value: branch, onChange: handleBranchChange, placeholder: "main" })) : (jsxRuntimeExports.jsx(Text, { color: branch ? colors.white : colors.dimGray, children: branch || 'main' })) })] }), error && (jsxRuntimeExports.jsx(Box, { marginLeft: LABEL_WIDTH + 2, children: jsxRuntimeExports.jsxs(Text, { color: colors.error, children: [symbols.cross, " ", error] }) }))] }), jsxRuntimeExports.jsxs(Box, { flexDirection: "row", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsxRuntimeExports.jsx(Text, { color: focusedField === 'workspace' ? colors.cyan : colors.gray, children: "Workspace" }) }), jsxRuntimeExports.jsx(Box, { borderStyle: "round", borderColor: focusedField === 'workspace' ? colors.cyan : colors.darkGray, paddingX: 1, width: 40, children: focusedField === 'workspace' ? (jsxRuntimeExports.jsx(TextInput, { value: workspace, onChange: setWorkspace, placeholder: "~/openbuilder-workspace" })) : (jsxRuntimeExports.jsx(Text, { color: workspace ? colors.white : colors.dimGray, children: workspace || '~/openbuilder-workspace' })) })] }), jsxRuntimeExports.jsxs(Box, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsxRuntimeExports.jsx(Text, { color: focusedField === 'database' ? colors.cyan : colors.gray, children: "Database" }) }), jsxRuntimeExports.jsx(RadioGroup, { options: databaseOptions, selected: databaseType, onChange: handleDatabaseTypeChange, focused: focusedField === 'database' })] }), databaseType === 'custom' && (jsxRuntimeExports.jsxs(Box, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [jsxRuntimeExports.jsx(Box, { width: LABEL_WIDTH, justifyContent: "flex-end", marginRight: 1, children: jsxRuntimeExports.jsx(Text, { color: focusedField === 'databaseUrl' ? colors.cyan : colors.gray, children: "URL" }) }), jsxRuntimeExports.jsx(Box, { borderStyle: "round", borderColor: focusedField === 'databaseUrl' ? colors.cyan : colors.darkGray, paddingX: 1, width: 50, children: focusedField === 'databaseUrl' ? (jsxRuntimeExports.jsx(TextInput, { value: databaseUrl, onChange: setDatabaseUrl, placeholder: "postgres://user:pass@host:5432/db" })) : (jsxRuntimeExports.jsx(Text, { color: databaseUrl ? colors.white : colors.dimGray, children: databaseUrl || 'postgres://user:pass@host:5432/db' })) })] }))] }), jsxRuntimeExports.jsx(Box, { marginTop: 3 }), jsxRuntimeExports.jsxs(Box, { flexDirection: "column", alignItems: "center", children: [jsxRuntimeExports.jsxs(Text, { color: colors.dimGray, children: ["Enter: ", isLastField ? 'Start' : 'Next field', " | Shift+Enter: Start now | Esc: Back"] }), databaseType === 'custom' && !databaseUrl.trim() && (jsxRuntimeExports.jsx(Box, { marginTop: 1, children: jsxRuntimeExports.jsxs(Text, { color: colors.warning, children: [symbols.hollowDot, " Database URL required for custom PostgreSQL"] }) }))] })] }));
419
418
  }
420
419
 
421
420
  /**
422
421
  * Main TUI App component with screen navigation
423
422
  */
424
423
  function App({ initialState, onExit, onRunnerStart, onLocalStart, onInitStart, }) {
425
- const [state, setState] = useState(initialState);
424
+ const [state, setState] = reactExports.useState(initialState);
426
425
  // Screen navigation handlers
427
426
  const navigateTo = (screen) => {
428
427
  setState(prev => ({ ...prev, screen }));
@@ -478,13 +477,13 @@ function App({ initialState, onExit, onRunnerStart, onLocalStart, onInitStart, }
478
477
  // Render current screen
479
478
  switch (state.screen.type) {
480
479
  case 'mode-select':
481
- return (jsx(ModeSelectScreen, { onSelect: handleModeSelect, onEscape: onExit }));
480
+ return (jsxRuntimeExports.jsx(ModeSelectScreen, { onSelect: handleModeSelect, onEscape: onExit }));
482
481
  case 'local-mode':
483
- return (jsx(LocalModeScreen, { isInitialized: state.isInitialized, onSelect: handleLocalAction, onEscape: () => navigateTo({ type: 'mode-select' }) }));
482
+ return (jsxRuntimeExports.jsx(LocalModeScreen, { isInitialized: state.isInitialized, onSelect: handleLocalAction, onEscape: () => navigateTo({ type: 'mode-select' }) }));
484
483
  case 'runner-mode':
485
- return (jsx(RunnerModeScreen, { initialKey: state.existingKey, initialRunnerId: state.existingRunnerId, onStart: handleRunnerStart, onEscape: () => navigateTo({ type: 'mode-select' }) }));
484
+ return (jsxRuntimeExports.jsx(RunnerModeScreen, { initialKey: state.existingKey, initialRunnerId: state.existingRunnerId, onStart: handleRunnerStart, onEscape: () => navigateTo({ type: 'mode-select' }) }));
486
485
  case 'config-form':
487
- return (jsx(ConfigFormScreen, { initialConfig: {
486
+ return (jsxRuntimeExports.jsx(ConfigFormScreen, { initialConfig: {
488
487
  branch: state.screen.lastBranch || 'main',
489
488
  workspace: state.existingWorkspace || join(homedir(), 'openbuilder-workspace'),
490
489
  useNeon: true,
@@ -527,7 +526,7 @@ async function mainTUICommand() {
527
526
  let exitReason = null;
528
527
  let runnerConfig = null;
529
528
  let initConfig = null;
530
- const { unmount, waitUntilExit } = render(jsx(App, { initialState: initialState, onExit: () => {
529
+ const { unmount, waitUntilExit } = render(jsxRuntimeExports.jsx(App, { initialState: initialState, onExit: () => {
531
530
  exitReason = 'exit';
532
531
  unmount();
533
532
  }, onRunnerStart: (config) => {
@@ -601,7 +600,7 @@ async function startRunner(config) {
601
600
  console.log('\n Starting OpenBuilder Runner...\n');
602
601
  console.log(` Runner ID: ${config.runnerId}`);
603
602
  console.log(' Connecting to remote server...\n');
604
- const { runCommand } = await import('./run-DAEiNzrf.js');
603
+ const { runCommand } = await import('./run-CaSootos.js');
605
604
  await runCommand({
606
605
  secret: config.key,
607
606
  runnerId: config.runnerId,
@@ -612,7 +611,7 @@ async function startRunner(config) {
612
611
  */
613
612
  async function startLocalMode() {
614
613
  console.log('\n Starting OpenBuilder in Local Mode...\n');
615
- const { startCommand } = await import('./start-BygPCbvw.js');
614
+ const { startCommand } = await import('./start-B4P27nZ7.js');
616
615
  await startCommand({});
617
616
  }
618
617
  /**
@@ -623,7 +622,7 @@ async function runInitialization(config) {
623
622
  const workspace = config.workspace.startsWith('~')
624
623
  ? config.workspace.replace('~', homedir())
625
624
  : config.workspace;
626
- const { initTUICommand } = await import('./init-tui-BNzk_7Yx.js');
625
+ const { initTUICommand } = await import('./init-tui-DDxZYe9B.js');
627
626
  // Build options based on form input
628
627
  const options = {
629
628
  workspace,
@@ -641,4 +640,4 @@ async function runInitialization(config) {
641
640
  }
642
641
 
643
642
  export { mainTUICommand };
644
- //# sourceMappingURL=main-tui-CTgDJWmu.js.map
643
+ //# sourceMappingURL=main-tui-B5GJ49Bp.js.map