@openbuilder/cli 0.50.43 → 0.50.46
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/dist/chunks/{Banner-C-FTiOIR.js → Banner-BKC6yG6z.js} +2 -2
- package/dist/chunks/Banner-BKC6yG6z.js.map +1 -0
- package/dist/chunks/auto-update-Dq2PFvjt.js +1 -0
- package/dist/chunks/auto-update-Dq2PFvjt.js.map +1 -0
- package/dist/chunks/build-D0qYqIq0.js +1 -0
- package/dist/chunks/build-D0qYqIq0.js.map +1 -0
- package/dist/chunks/cleanup-qVTsA3tk.js +1 -0
- package/dist/chunks/cleanup-qVTsA3tk.js.map +1 -0
- package/dist/chunks/{cli-auth-ChCnxlFl.js → cli-auth-BgiGSBOt.js} +4 -3
- package/dist/chunks/cli-auth-BgiGSBOt.js.map +1 -0
- package/dist/chunks/cli-error-BjQwvWtK.js +1 -0
- package/dist/chunks/cli-error-BjQwvWtK.js.map +1 -0
- package/dist/chunks/config-BGP1jZJ4.js +1 -0
- package/dist/chunks/config-BGP1jZJ4.js.map +1 -0
- package/dist/chunks/config-manager-BkbjtN-H.js +1 -0
- package/dist/chunks/config-manager-BkbjtN-H.js.map +1 -0
- package/dist/chunks/database-BvAbD4sP.js +1 -0
- package/dist/chunks/database-BvAbD4sP.js.map +1 -0
- package/dist/chunks/database-setup-BYjIRAmT.js +1 -0
- package/dist/chunks/database-setup-BYjIRAmT.js.map +1 -0
- package/dist/chunks/devtools-7A3EXJhY.js +75 -0
- package/dist/chunks/devtools-7A3EXJhY.js.map +1 -0
- package/dist/chunks/index-ZNRLfdj5.js +119 -0
- package/dist/chunks/index-ZNRLfdj5.js.map +1 -0
- package/dist/chunks/{init-DNyPS_SR.js → init-IQRjA1g3.js} +8 -9
- package/dist/chunks/init-IQRjA1g3.js.map +1 -0
- package/dist/chunks/{init-tui-EFMXj-MG.js → init-tui-B4jfmo3U.js} +7 -8
- package/dist/chunks/init-tui-B4jfmo3U.js.map +1 -0
- package/dist/chunks/logger-ZpJi7chw.js +1 -0
- package/dist/chunks/logger-ZpJi7chw.js.map +1 -0
- package/dist/chunks/{login-BhtodVsj.js → login-CrIcDJpS.js} +2 -1
- package/dist/chunks/login-CrIcDJpS.js.map +1 -0
- package/dist/chunks/{logout-CDDASeuQ.js → logout-BxgiczmY.js} +2 -1
- package/dist/chunks/logout-BxgiczmY.js.map +1 -0
- package/dist/chunks/{main-tui-D-SG-Ba5.js → main-tui-NPDVPKol.js} +9 -10
- package/dist/chunks/main-tui-NPDVPKol.js.map +1 -0
- package/dist/chunks/manager-CvGX9qqe.js +1 -0
- package/dist/chunks/manager-CvGX9qqe.js.map +1 -0
- package/dist/chunks/{port-allocator-B0q7xkLs.js → port-allocator-DuAZe2_S.js} +3 -36
- package/dist/chunks/port-allocator-DuAZe2_S.js.map +1 -0
- package/dist/chunks/process-killer-CaUL7Kpl.js +1 -0
- package/dist/chunks/process-killer-CaUL7Kpl.js.map +1 -0
- package/dist/chunks/prompts-1QbE_bRr.js +1 -0
- package/dist/chunks/prompts-1QbE_bRr.js.map +1 -0
- package/dist/chunks/repo-cloner-CpOQjFSo.js +1 -0
- package/dist/chunks/repo-cloner-CpOQjFSo.js.map +1 -0
- package/dist/chunks/repo-detector-B_oj696o.js +1 -0
- package/dist/chunks/repo-detector-B_oj696o.js.map +1 -0
- package/dist/chunks/{run-Cor14S0I.js → run-Yh3YjeLl.js} +17 -36
- package/dist/chunks/run-Yh3YjeLl.js.map +1 -0
- package/dist/chunks/runner-logger-instance-nDWv2h2T.js +1 -0
- package/dist/chunks/runner-logger-instance-nDWv2h2T.js.map +1 -0
- package/dist/chunks/spinner-BJL9zWAJ.js +1 -0
- package/dist/chunks/spinner-BJL9zWAJ.js.map +1 -0
- package/dist/chunks/{start-k9iGDVWo.js → start-B-brfyVy.js} +7 -7
- package/dist/chunks/start-B-brfyVy.js.map +1 -0
- package/dist/chunks/start-traditional-uoLZXdxm.js +1 -0
- package/dist/chunks/start-traditional-uoLZXdxm.js.map +1 -0
- package/dist/chunks/status-cS8YwtUx.js +1 -0
- package/dist/chunks/status-cS8YwtUx.js.map +1 -0
- package/dist/chunks/{vendor-react-CXgiD1Dl.js → theme-DOjeB8BU.js} +50 -225
- package/dist/chunks/theme-DOjeB8BU.js.map +1 -0
- package/dist/chunks/upgrade-CKjl4HlB.js +1 -0
- package/dist/chunks/upgrade-CKjl4HlB.js.map +1 -0
- package/dist/chunks/use-app-DozfqdJj.js +10 -0
- package/dist/chunks/use-app-DozfqdJj.js.map +1 -0
- package/dist/chunks/{useBuildState-DscLOZLl.js → useBuildState-DV6wurQ2.js} +2 -2
- package/dist/chunks/useBuildState-DV6wurQ2.js.map +1 -0
- package/dist/cli/index.js +8 -7
- package/dist/cli/index.js.map +1 -0
- package/dist/index.js +109 -700
- package/dist/index.js.map +1 -0
- package/dist/instrument.js +8 -81
- package/dist/instrument.js.map +1 -0
- package/package.json +2 -11
- package/dist/chunks/theme-DhorI2Hb.js +0 -43
- package/dist/chunks/vendor-ai-sdk-CSJ0bw9X.js +0 -1970
- package/dist/chunks/vendor-sentry-CqA9P3UG.js +0 -71910
- package/scripts/install-vendor-deps.js +0 -34
- package/scripts/install-vendor.js +0 -167
- package/scripts/prepare-release.js +0 -83
- package/vendor/ai-sdk-provider-claude-code-LOCAL.tgz +0 -0
- package/vendor/sentry-core-LOCAL.tgz +0 -0
- package/vendor/sentry-nextjs-LOCAL.tgz +0 -0
- package/vendor/sentry-node-LOCAL.tgz +0 -0
- package/vendor/sentry-node-core-LOCAL.tgz +0 -0
|
@@ -3,12 +3,11 @@ import { execSync } from 'node:child_process';
|
|
|
3
3
|
import { existsSync, readFileSync } from 'node:fs';
|
|
4
4
|
import { join, dirname } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { j as jsxRuntimeExports, B as Box, T as Text } from './
|
|
6
|
+
import { j as jsxRuntimeExports, B as Box, T as Text, c as colors } from './theme-DOjeB8BU.js';
|
|
7
7
|
import 'node:stream';
|
|
8
8
|
import 'node:process';
|
|
9
9
|
import 'chalk';
|
|
10
10
|
import 'node:events';
|
|
11
|
-
import { c as colors } from './theme-DhorI2Hb.js';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Version and git commit info utilities
|
|
@@ -113,3 +112,4 @@ function Banner() {
|
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
export { Banner as B, getVersionInfo as g };
|
|
115
|
+
//# sourceMappingURL=Banner-BKC6yG6z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Banner-BKC6yG6z.js","sources":["../../src/cli/utils/version-info.ts","../../src/cli/tui/components/Banner.tsx"],"sourcesContent":["/**\n * Version and git commit info utilities\n */\n\nimport { execSync } from 'node:child_process';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Find the package root directory (apps/runner).\n * Works in both development (src/cli/utils/) and production (dist/cli/utils/) modes.\n */\nfunction findPackageRoot(): string {\n // Try multiple possible locations\n const possiblePaths = [\n // Development: src/cli/utils/ -> apps/runner (3 levels up)\n join(__dirname, '..', '..', '..'),\n // Production from dist/cli/utils/: -> apps/runner (3 levels up, same structure)\n join(__dirname, '..', '..', '..'),\n ];\n \n for (const path of possiblePaths) {\n const packageJsonPath = join(path, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n // Verify this is the runner package\n if (pkg.name === '@openbuilder/cli') {\n return path;\n }\n } catch {\n // Continue to next path\n }\n }\n }\n \n // Fallback to the standard path\n return join(__dirname, '..', '..', '..');\n}\n\n// Cache the package root\nconst packageRoot = findPackageRoot();\n\n/**\n * Get the package version from package.json\n */\nexport function getPackageVersion(): string {\n try {\n const packageJsonPath = join(packageRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version || '0.0.0';\n }\n } catch {\n // Ignore errors\n }\n return '0.0.0';\n}\n\n/**\n * Get the short git commit hash\n */\nexport function getGitCommit(): string | null {\n try {\n // Try to get commit from git command\n const commit = execSync('git rev-parse --short HEAD', {\n cwd: packageRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n return commit || null;\n } catch {\n // Git not available or not a git repo\n return null;\n }\n}\n\n/**\n * Get combined version string with commit\n * Returns \"v0.19.1 (abc1234)\" or just \"v0.19.1\" if no commit\n */\nexport function getVersionString(): string {\n const version = getPackageVersion();\n const commit = getGitCommit();\n \n if (commit) {\n return `v${version} (${commit})`;\n }\n return `v${version}`;\n}\n\n/**\n * Version info object\n */\nexport interface VersionInfo {\n version: string;\n commit: string | null;\n display: string;\n}\n\n/**\n * Get all version info\n */\nexport function getVersionInfo(): VersionInfo {\n const version = getPackageVersion();\n const commit = getGitCommit();\n \n return {\n version,\n commit,\n display: commit ? `v${version} (${commit})` : `v${version}`,\n };\n}\n","import { Box, Text } from 'ink';\nimport { colors } from '../theme.js';\n\n/**\n * ASCII art banner component - centered with cyan/purple gradient\n * Each line is padded to exactly the same width for perfect alignment\n */\nexport function Banner() {\n // Full banner lines - OPEN in cyan, BUILDER in purple\n // All lines padded to same total width for consistent centering\n const lines = [\n { open: ' ██████╗ ██████╗ ███████╗███╗ ██╗', builder: '██████╗ ██╗ ██╗██╗██╗ ██████╗ ███████╗██████╗ ' },\n { open: '██╔═══██╗██╔══██╗██╔════╝████╗ ██║', builder: '██╔══██╗██║ ██║██║██║ ██╔══██╗██╔════╝██╔══██╗' },\n { open: '██║ ██║██████╔╝█████╗ ██╔██╗ ██║', builder: '██████╔╝██║ ██║██║██║ ██║ ██║█████╗ ██████╔╝' },\n { open: '██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║', builder: '██╔══██╗██║ ██║██║██║ ██║ ██║██╔══╝ ██╔══██╗' },\n { open: '╚██████╔╝██║ ███████╗██║ ╚████║', builder: '██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║' },\n { open: ' ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝', builder: '╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝' },\n ];\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\">\n {lines.map((line, index) => (\n <Box key={index}>\n <Text color={colors.cyan}>{line.open}</Text>\n <Text color={colors.brightPurple}>{line.builder}</Text>\n </Box>\n ))}\n </Box>\n );\n}\n"],"names":["__filename","__dirname","_jsx","_jsxs"],"mappings":";;;;;;;;;;;AAAA;;AAEG;AAOH,MAAMA,YAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;AACjD,MAAMC,WAAS,GAAG,OAAO,CAACD,YAAU,CAAC;AAErC;;;AAGG;AACH,SAAS,eAAe,GAAA;;AAEtB,IAAA,MAAM,aAAa,GAAG;;QAEpB,IAAI,CAACC,WAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;;QAEjC,IAAI,CAACA,WAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;KAClC;AAED,IAAA,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE;QAChC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;AAClD,QAAA,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE;AAC/B,YAAA,IAAI;AACF,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;;AAE9D,gBAAA,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;AACnC,oBAAA,OAAO,IAAI;gBACb;YACF;AAAE,YAAA,MAAM;;YAER;QACF;IACF;;IAGA,OAAO,IAAI,CAACA,WAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAC1C;AAEA;AACA,MAAM,WAAW,GAAG,eAAe,EAAE;AAErC;;AAEG;SACa,iBAAiB,GAAA;AAC/B,IAAA,IAAI;QACF,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC;AACzD,QAAA,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE;AAC/B,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AACtE,YAAA,OAAO,WAAW,CAAC,OAAO,IAAI,OAAO;QACvC;IACF;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,OAAO,OAAO;AAChB;AAEA;;AAEG;SACa,YAAY,GAAA;AAC1B,IAAA,IAAI;;AAEF,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,4BAA4B,EAAE;AACpD,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,QAAQ,EAAE,OAAO;AACjB,YAAA,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE;QACT,OAAO,MAAM,IAAI,IAAI;IACvB;AAAE,IAAA,MAAM;;AAEN,QAAA,OAAO,IAAI;IACb;AACF;AAyBA;;AAEG;SACa,cAAc,GAAA;AAC5B,IAAA,MAAM,OAAO,GAAG,iBAAiB,EAAE;AACnC,IAAA,MAAM,MAAM,GAAG,YAAY,EAAE;IAE7B,OAAO;QACL,OAAO;QACP,MAAM;AACN,QAAA,OAAO,EAAE,MAAM,GAAG,CAAA,CAAA,EAAI,OAAO,CAAA,EAAA,EAAK,MAAM,GAAG,GAAG,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE;KAC5D;AACH;;ACjHA;;;AAGG;SACa,MAAM,GAAA;;;AAGpB,IAAA,MAAM,KAAK,GAAG;AACZ,QAAA,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,sDAAsD,EAAE;AAChH,QAAA,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,sDAAsD,EAAE;AAChH,QAAA,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,sDAAsD,EAAE;AAChH,QAAA,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,sDAAsD,EAAE;AAChH,QAAA,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,sDAAsD,EAAE;AAChH,QAAA,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,sDAAsD,EAAE;KACjH;AAED,IAAA,QACEC,qBAAA,CAAC,GAAG,EAAA,EAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAC,QAAQ,EAAA,QAAA,EAC5C,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MACrBC,sBAAA,CAAC,GAAG,EAAA,EAAA,QAAA,EAAA,CACFD,qBAAA,CAAC,IAAI,EAAA,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAA,QAAA,EAAG,IAAI,CAAC,IAAI,EAAA,CAAQ,EAC5CA,qBAAA,CAAC,IAAI,EAAA,EAAC,KAAK,EAAE,MAAM,CAAC,YAAY,EAAA,QAAA,EAAG,IAAI,CAAC,OAAO,EAAA,CAAQ,CAAA,EAAA,EAF/C,KAAK,CAGT,CACP,CAAC,EAAA,CACE;AAEV;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update-Dq2PFvjt.js","sources":["../../src/cli/utils/auto-update.ts"],"sourcesContent":["/**\n * Auto-update utility for OpenBuilder CLI\n * \n * Checks GitHub Releases for newer versions and automatically\n * updates both:\n * 1. The CLI itself (globally installed npm package)\n * 2. The app/monorepo (local installation that runs the web app)\n */\n\nimport { execSync, spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport pc from 'picocolors';\nimport { configManager } from './config-manager.js';\n\n// GitHub API endpoint for releases\nconst GITHUB_RELEASES_URL = 'https://api.github.com/repos/codyde/openbuilder/releases/latest';\n\n// Install command for CLI\nconst INSTALL_COMMAND = 'curl -fsSL https://openbuilder.sh/install | bash';\n\n// Cache settings\nconst CACHE_DIR = join(homedir(), '.config', 'openbuilder');\nconst CACHE_FILE = join(CACHE_DIR, 'update-cache.json');\nconst CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour\n\ninterface UpdateCache {\n lastCheck: number;\n latestVersion: string;\n // Track if we need to upgrade the app after CLI update\n pendingAppUpgrade?: boolean;\n}\n\n/**\n * Read the update cache file\n */\nfunction readUpdateCache(): UpdateCache | null {\n try {\n if (existsSync(CACHE_FILE)) {\n const content = readFileSync(CACHE_FILE, 'utf-8');\n return JSON.parse(content);\n }\n } catch {\n // Cache read failed, that's fine\n }\n return null;\n}\n\n/**\n * Write to the update cache file\n */\nfunction saveUpdateCache(cache: UpdateCache): void {\n try {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true });\n }\n writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));\n } catch {\n // Cache write failed, that's fine\n }\n}\n\n/**\n * Fetch the latest release version from GitHub\n * Returns version string (e.g., \"0.28.0\") or null on failure\n */\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000); // 5s timeout\n\n const response = await fetch(GITHUB_RELEASES_URL, {\n headers: {\n 'Accept': 'application/vnd.github.v3+json',\n 'User-Agent': 'OpenBuilder-CLI-AutoUpdate',\n },\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n return null;\n }\n\n const data = await response.json() as { tag_name: string };\n // Remove 'v' prefix if present (e.g., \"v0.28.0\" -> \"0.28.0\")\n return data.tag_name.replace(/^v/, '');\n } catch {\n // Network error, timeout, or parse error\n return null;\n }\n}\n\n/**\n * Compare two semver versions\n * Returns true if version1 < version2 (i.e., version2 is newer)\n */\nfunction isNewerVersion(current: string, latest: string): boolean {\n const parseVersion = (v: string) => {\n const parts = v.replace(/^v/, '').split('.').map(n => parseInt(n, 10) || 0);\n return { major: parts[0] || 0, minor: parts[1] || 0, patch: parts[2] || 0 };\n };\n\n const c = parseVersion(current);\n const l = parseVersion(latest);\n\n if (l.major > c.major) return true;\n if (l.major < c.major) return false;\n if (l.minor > c.minor) return true;\n if (l.minor < c.minor) return false;\n return l.patch > c.patch;\n}\n\n/**\n * Perform the CLI update by running the install script\n */\nfunction performCLIUpdate(): boolean {\n try {\n // Run the install command with quiet mode to avoid banner spam\n execSync(INSTALL_COMMAND, {\n stdio: 'inherit',\n shell: '/bin/bash',\n env: {\n ...process.env,\n OPENBUILDER_QUIET_INSTALL: '1', // Suppress banner in installer\n },\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if the app/monorepo needs upgrading and perform the upgrade\n * This updates the local OpenBuilder installation that runs the web app\n */\nfunction performAppUpgrade(): boolean {\n const config = configManager.get();\n const monorepoPath = config.monorepoPath;\n\n // No monorepo configured, skip app upgrade\n if (!monorepoPath || !existsSync(monorepoPath)) {\n return true; // Not an error, just nothing to upgrade\n }\n\n console.log();\n console.log(` ${pc.cyan('⬆')} ${pc.bold('Upgrading app installation...')}`);\n console.log(` ${pc.dim(monorepoPath)}`);\n console.log();\n\n try {\n // Run openbuilder upgrade --force to upgrade the monorepo\n // Use --force to skip prompts since we're in auto-update mode\n const result = spawnSync('openbuilder', ['upgrade', '--force'], {\n stdio: 'inherit',\n env: {\n ...process.env,\n OPENBUILDER_SKIP_UPDATE_CHECK: '1', // Don't re-check for CLI updates\n },\n shell: true,\n });\n\n return result.status === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Re-launch the CLI with original arguments after update\n */\nfunction relaunchCLI(): void {\n const args = process.argv.slice(2);\n \n try {\n // Get the actual path to openbuilder to avoid shell hash caching issues\n // This ensures we run the newly installed version, not a cached path\n let openbuilderPath = 'openbuilder';\n try {\n // Use 'command -v' to get the actual path, bypassing shell hash\n openbuilderPath = execSync('command -v openbuilder', { encoding: 'utf-8' }).trim();\n } catch {\n // Fallback to just 'openbuilder' if command -v fails\n }\n \n // Use spawnSync with the explicit path to ensure we get the new version\n const result = spawnSync(openbuilderPath, args, {\n stdio: 'inherit',\n env: { \n ...process.env, \n OPENBUILDER_SKIP_UPDATE_CHECK: '1', // Prevent update loop\n OPENBUILDER_SKIP_BANNER: '1', // Suppress banner after restart (already shown before update)\n },\n // Don't use shell: true to avoid shell hash caching\n });\n \n // Exit with the same code as the relaunched process\n process.exit(result.status ?? 0);\n } catch {\n // If relaunch fails, just exit - user can run command again\n process.exit(0);\n }\n}\n\n/**\n * Main auto-update check function\n * Call this early in CLI startup\n * \n * Updates both:\n * 1. The CLI itself (globally installed)\n * 2. The app/monorepo (if configured)\n * \n * @param currentVersion - Current CLI version from package.json\n * @returns true if update was performed and CLI should exit\n */\nexport async function checkAndAutoUpdate(currentVersion: string): Promise<boolean> {\n // Skip if update check is disabled via env var\n if (process.env.OPENBUILDER_NO_UPDATE === '1' || process.env.OPENBUILDER_SKIP_UPDATE_CHECK === '1') {\n // But check if we have a pending app upgrade from a previous CLI update\n const cache = readUpdateCache();\n if (cache?.pendingAppUpgrade) {\n console.log();\n console.log(` ${pc.cyan('⬆')} ${pc.bold('Completing app upgrade...')}`);\n \n const appSuccess = performAppUpgrade();\n \n if (appSuccess) {\n // Clear the pending flag\n saveUpdateCache({ ...cache, pendingAppUpgrade: false });\n console.log(` ${pc.green('✓')} ${pc.bold('App upgrade complete!')}`);\n } else {\n console.log(` ${pc.yellow('⚠')} ${pc.dim('App upgrade failed. Run manually:')} ${pc.cyan('openbuilder upgrade')}`);\n }\n console.log();\n }\n return false;\n }\n\n // Skip if disabled in config\n const config = configManager.get();\n if (config.autoUpdate === false) {\n return false;\n }\n\n let latestVersion: string | null = null;\n\n // Check cache first to avoid hitting GitHub API too often\n const cache = readUpdateCache();\n const now = Date.now();\n\n if (cache && (now - cache.lastCheck) < CACHE_TTL_MS) {\n // Use cached version\n latestVersion = cache.latestVersion;\n } else {\n // Fetch from GitHub (with timeout)\n latestVersion = await fetchLatestVersion();\n \n if (latestVersion) {\n // Update cache\n saveUpdateCache({\n lastCheck: now,\n latestVersion,\n });\n } else if (cache) {\n // Fetch failed, use stale cache\n latestVersion = cache.latestVersion;\n }\n }\n\n // If we couldn't determine latest version, skip update\n if (!latestVersion) {\n return false;\n }\n\n // Check if update is needed\n if (!isNewerVersion(currentVersion, latestVersion)) {\n return false;\n }\n\n // Update available! Show message and perform update\n console.log();\n console.log(` ${pc.cyan('⬆')} ${pc.bold('Update available:')} ${pc.dim(currentVersion)} → ${pc.green(latestVersion)}`);\n console.log();\n\n // Perform the CLI update\n console.log(` ${pc.dim('Updating CLI...')}`);\n const cliSuccess = performCLIUpdate();\n\n if (!cliSuccess) {\n // CLI update failed, continue with current version\n console.log();\n console.log(` ${pc.yellow('⚠')} ${pc.dim('CLI update failed. Continuing with current version.')}`);\n console.log(` ${pc.dim('You can manually update with:')} ${pc.cyan('curl -fsSL https://openbuilder.sh/install | bash')}`);\n console.log();\n return false;\n }\n\n console.log(` ${pc.green('✓')} CLI updated to ${pc.green(latestVersion)}`);\n \n // Check if we need to upgrade the app\n const monorepoPath = config.monorepoPath;\n const hasMonorepo = monorepoPath && existsSync(monorepoPath);\n\n if (hasMonorepo) {\n // Mark that we need to upgrade the app after CLI restart\n saveUpdateCache({\n lastCheck: now,\n latestVersion,\n pendingAppUpgrade: true,\n });\n }\n\n console.log();\n console.log(` ${pc.green('✓')} ${pc.bold('Update complete!')}`);\n console.log();\n console.log(` ${pc.yellow('⚠')} ${pc.bold('Please restart your terminal')} or run:`);\n console.log(` ${pc.cyan('hash -r')} ${pc.dim('(bash/zsh)')}`);\n console.log();\n console.log(` ${pc.dim('Then run')} ${pc.cyan('openbuilder')} ${pc.dim('again.')}`);\n console.log();\n \n // Exit - user needs to restart terminal to pick up new version\n process.exit(0);\n}\n\n/**\n * Check for updates without auto-updating (for TUI modes)\n * Returns version info that can be displayed in the TUI\n * \n * @param currentVersion - Current CLI version from package.json\n * @returns Update info or null if no update available\n */\nexport async function checkForUpdate(currentVersion: string): Promise<{\n currentVersion: string;\n latestVersion: string;\n updateAvailable: boolean;\n} | null> {\n // Skip if update check is disabled via env var\n if (process.env.OPENBUILDER_NO_UPDATE === '1' || process.env.OPENBUILDER_SKIP_UPDATE_CHECK === '1') {\n return null;\n }\n\n // Skip if disabled in config\n const config = configManager.get();\n if (config.autoUpdate === false) {\n return null;\n }\n\n let latestVersion: string | null = null;\n\n // Check cache first to avoid hitting GitHub API too often\n const cache = readUpdateCache();\n const now = Date.now();\n\n if (cache && (now - cache.lastCheck) < CACHE_TTL_MS) {\n // Use cached version\n latestVersion = cache.latestVersion;\n } else {\n // Fetch from GitHub (with timeout)\n latestVersion = await fetchLatestVersion();\n \n if (latestVersion) {\n // Update cache\n saveUpdateCache({\n lastCheck: now,\n latestVersion,\n pendingAppUpgrade: cache?.pendingAppUpgrade,\n });\n } else if (cache) {\n // Fetch failed, use stale cache\n latestVersion = cache.latestVersion;\n }\n }\n\n // If we couldn't determine latest version, return null\n if (!latestVersion) {\n return null;\n }\n\n const updateAvailable = isNewerVersion(currentVersion, latestVersion);\n \n return {\n currentVersion,\n latestVersion,\n updateAvailable,\n };\n}\n\n/**\n * Clear the update cache (useful for testing or forcing a fresh check)\n */\nexport function clearUpdateCache(): void {\n try {\n if (existsSync(CACHE_FILE)) {\n unlinkSync(CACHE_FILE);\n }\n } catch {\n // Ignore errors\n }\n}\n\n/**\n * Get the current update status (for debugging/status commands)\n */\nexport function getUpdateStatus(): { \n cacheFile: string;\n cache: UpdateCache | null;\n monorepoPath: string | undefined;\n hasMonorepo: boolean;\n} {\n const config = configManager.get();\n const monorepoPath = config.monorepoPath;\n \n return {\n cacheFile: CACHE_FILE,\n cache: readUpdateCache(),\n monorepoPath,\n hasMonorepo: !!(monorepoPath && existsSync(monorepoPath)),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-D0qYqIq0.js","sources":["../../src/cli/commands/build.ts"],"sourcesContent":["/**\n * Build command - rebuild all services without starting them\n * Useful for rebuilding while services are already running\n */\n\nimport { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\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 { CLIError, errors } from '../utils/cli-error.js';\n\ninterface BuildOptions {\n watch?: boolean; // Watch mode for continuous rebuilds\n}\n\nexport async function buildCommand(options: BuildOptions) {\n const s = p.spinner();\n\n // Step 1: Find monorepo\n s.start('Locating OpenBuilder repository');\n\n let monorepoRoot: string | undefined;\n const config = configManager.get();\n\n if (config.monorepoPath && existsSync(config.monorepoPath)) {\n monorepoRoot = config.monorepoPath;\n }\n\n if (!monorepoRoot) {\n const repoCheck = await isInsideMonorepo();\n if (repoCheck.inside && repoCheck.root) {\n monorepoRoot = repoCheck.root;\n }\n }\n\n if (!monorepoRoot) {\n s.stop(pc.red('✗') + ' Repository not found');\n throw errors.monorepoNotFound([\n config.monorepoPath || 'none',\n process.cwd(),\n ]);\n }\n\n s.stop(pc.green('✓') + ' Repository found');\n\n // Step 2: Build services\n if (options.watch) {\n console.log();\n console.log(pc.cyan('Building services in watch mode...'));\n console.log(pc.dim('Press Ctrl+C to stop'));\n console.log();\n\n // Use turbo watch mode\n const watchProcess = spawn('pnpm', ['build:all', '--watch'], {\n cwd: monorepoRoot,\n stdio: 'inherit',\n shell: true,\n });\n\n // Handle Ctrl+C gracefully\n process.on('SIGINT', () => {\n console.log();\n console.log(pc.yellow('⚠'), 'Stopping watch mode...');\n watchProcess.kill('SIGTERM');\n process.exit(0);\n });\n\n watchProcess.on('error', (error) => {\n throw new CLIError({\n code: 'BUILD_FAILED',\n message: 'Watch mode failed',\n cause: error,\n suggestions: [\n 'Check that all dependencies are installed',\n 'Try running: pnpm install',\n ],\n });\n });\n\n // Wait for process to exit\n await new Promise<void>((resolve) => {\n watchProcess.on('close', () => resolve());\n });\n } else {\n s.start('Building all services');\n\n try {\n await new Promise<void>((resolve, reject) => {\n const buildProcess = spawn('pnpm', ['build:all'], {\n cwd: monorepoRoot,\n stdio: 'inherit', // Show build output\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('✓') + ' Build complete');\n\n console.log();\n console.log(pc.dim('Tip: Restart services to use the new build'));\n } catch (error) {\n s.stop(pc.red('✗') + ' Build failed');\n throw new CLIError({\n code: 'BUILD_FAILED',\n message: 'Failed to build services',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check that all dependencies are installed',\n 'Try running: pnpm install',\n 'Check for TypeScript errors in your code',\n ],\n });\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-qVTsA3tk.js","sources":["../../src/cli/commands/cleanup.ts"],"sourcesContent":["import { rm, readdir, stat } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport { logger } from '../utils/logger.js';\nimport { prompts } from '../utils/prompts.js';\nimport { configManager } from '../utils/config-manager.js';\nimport { spinner } from '../utils/spinner.js';\n\ninterface CleanupOptions {\n project?: string;\n all?: boolean;\n tunnels?: boolean;\n processes?: boolean;\n}\n\nexport async function cleanupCommand(options: CleanupOptions) {\n const config = configManager.get();\n const workspace = config.workspace;\n\n if (!workspace || !existsSync(workspace)) {\n logger.error('Workspace not found');\n logger.info(`Expected: ${workspace}`);\n return;\n }\n\n // Handle specific cleanup actions\n if (options.project) {\n await cleanupProject(workspace, options.project);\n return;\n }\n\n if (options.all) {\n await cleanupAllProjects(workspace);\n return;\n }\n\n if (options.tunnels) {\n logger.warn('Tunnel cleanup requires the runner to be running');\n logger.info('Tunnels are managed by the active runner process');\n return;\n }\n\n if (options.processes) {\n logger.warn('Process cleanup requires the runner to be running');\n logger.info('Dev servers are managed by the active runner process');\n return;\n }\n\n // No specific action - show help\n logger.info('Cleanup options:');\n logger.log(` ${chalk.cyan('--project <slug>')} Delete specific project`);\n logger.log(` ${chalk.cyan('--all')} Delete all projects`);\n logger.log(` ${chalk.cyan('--tunnels')} Close all tunnels (requires running runner)`);\n logger.log(` ${chalk.cyan('--processes')} Kill all dev servers (requires running runner)`);\n logger.log('');\n logger.info('Examples:');\n logger.log(` openbuilder cleanup --project my-project`);\n logger.log(` openbuilder cleanup --all`);\n}\n\nasync function cleanupProject(workspace: string, slug: string) {\n const projectPath = join(workspace, slug);\n\n if (!existsSync(projectPath)) {\n logger.error(`Project not found: ${slug}`);\n return;\n }\n\n // Get project size\n let size = 'unknown';\n try {\n const stats = await stat(projectPath);\n if (stats.isDirectory()) {\n // Estimate size (this is approximate)\n size = `${Math.round(stats.size / 1024)}KB+`;\n }\n } catch {\n // Ignore size calculation errors\n }\n\n logger.warn(`This will permanently delete project: ${chalk.cyan(slug)}`);\n logger.log(`Path: ${projectPath}`);\n logger.log(`Size: ${size}`);\n logger.log('');\n\n const confirmed = await prompts.confirm('Are you sure?', false);\n\n if (!confirmed) {\n logger.info('Cleanup cancelled');\n return;\n }\n\n spinner.start(`Deleting project: ${slug}`);\n\n try {\n await rm(projectPath, { recursive: true, force: true, maxRetries: 3 });\n spinner.succeed(`Deleted project: ${chalk.cyan(slug)}`);\n } catch (error) {\n spinner.fail('Failed to delete project');\n logger.error(error instanceof Error ? error.message : 'Unknown error');\n process.exit(1);\n }\n}\n\nasync function cleanupAllProjects(workspace: string) {\n logger.warn(`This will permanently delete ALL projects in workspace`);\n logger.log(`Workspace: ${workspace}`);\n logger.log('');\n\n // List projects\n const entries = await readdir(workspace);\n const projects = [];\n\n for (const entry of entries) {\n const entryPath = join(workspace, entry);\n const stats = await stat(entryPath);\n if (stats.isDirectory()) {\n projects.push(entry);\n }\n }\n\n if (projects.length === 0) {\n logger.info('No projects found to delete');\n return;\n }\n\n logger.log(`Found ${projects.length} project(s):`);\n projects.forEach(p => logger.log(` - ${p}`));\n logger.log('');\n\n const confirmed = await prompts.confirm(\n `Delete all ${projects.length} projects?`,\n false\n );\n\n if (!confirmed) {\n logger.info('Cleanup cancelled');\n return;\n }\n\n spinner.start(`Deleting ${projects.length} projects...`);\n\n let deleted = 0;\n const errors: string[] = [];\n\n for (const project of projects) {\n try {\n await rm(join(workspace, project), { recursive: true, force: true, maxRetries: 3 });\n deleted++;\n } catch (error) {\n errors.push(`${project}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n if (errors.length === 0) {\n spinner.succeed(`Deleted ${deleted} projects`);\n } else {\n spinner.warn(`Deleted ${deleted}/${projects.length} projects`);\n logger.log('');\n logger.error('Errors:');\n errors.forEach(err => logger.error(` ${err}`));\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// OpenBuilder CLI - Built with Rollup
|
|
2
|
-
import
|
|
2
|
+
import http from 'node:http';
|
|
3
3
|
import { URL } from 'node:url';
|
|
4
4
|
import { hostname, platform } from 'node:os';
|
|
5
5
|
import { exec } from 'node:child_process';
|
|
@@ -39,7 +39,7 @@ async function openBrowser(url) {
|
|
|
39
39
|
async function findAvailablePort(startPort = 9876, endPort = 9999) {
|
|
40
40
|
for (let port = startPort; port <= endPort; port++) {
|
|
41
41
|
const isAvailable = await new Promise((resolve) => {
|
|
42
|
-
const server =
|
|
42
|
+
const server = http.createServer();
|
|
43
43
|
server.once('error', () => resolve(false));
|
|
44
44
|
server.once('listening', () => {
|
|
45
45
|
server.close();
|
|
@@ -68,7 +68,7 @@ function startCallbackServer(port) {
|
|
|
68
68
|
return new Promise((resolve) => {
|
|
69
69
|
// Track active connections so we can forcefully close them
|
|
70
70
|
const connections = new Set();
|
|
71
|
-
const server =
|
|
71
|
+
const server = http.createServer((req, res) => {
|
|
72
72
|
const url = new URL(req.url || '/', `http://localhost:${port}`);
|
|
73
73
|
if (url.pathname === '/callback') {
|
|
74
74
|
const token = url.searchParams.get('token');
|
|
@@ -337,3 +337,4 @@ function clearToken() {
|
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
export { clearToken as c, getStoredToken as g, hasStoredToken as h, openBrowser as o, performOAuthLogin as p, storeToken as s };
|
|
340
|
+
//# sourceMappingURL=cli-auth-BgiGSBOt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-auth-BgiGSBOt.js","sources":["../../src/cli/utils/cli-auth.ts"],"sourcesContent":["import http from 'node:http';\nimport { URL } from 'node:url';\nimport { hostname, platform } from 'node:os';\nimport { exec } from 'node:child_process';\nimport chalk from 'chalk';\nimport { configManager } from './config-manager.js';\n\n/**\n * Open a URL in the default browser (cross-platform)\n */\nexport async function openBrowser(url: string): Promise<void> {\n const os = platform();\n \n return new Promise((resolve, reject) => {\n let command: string;\n \n switch (os) {\n case 'darwin':\n command = `open \"${url}\"`;\n break;\n case 'win32':\n command = `start \"\" \"${url}\"`;\n break;\n default: // Linux and others\n command = `xdg-open \"${url}\"`;\n }\n \n exec(command, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\ninterface AuthResult {\n success: boolean;\n token?: string;\n error?: string;\n}\n\ninterface CLIAuthOptions {\n apiUrl?: string;\n deviceName?: string;\n silent?: boolean;\n}\n\n/**\n * Find an available port for the callback server\n */\nasync function findAvailablePort(startPort: number = 9876, endPort: number = 9999): Promise<number> {\n for (let port = startPort; port <= endPort; port++) {\n const isAvailable = await new Promise<boolean>((resolve) => {\n const server = http.createServer();\n server.once('error', () => resolve(false));\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n server.listen(port, '127.0.0.1');\n });\n \n if (isAvailable) {\n return port;\n }\n }\n \n throw new Error('No available ports found for OAuth callback server');\n}\n\n/**\n * Get a device name for the runner key\n */\nfunction getDeviceName(): string {\n const host = hostname();\n const date = new Date().toLocaleDateString();\n return `CLI - ${host} - ${date}`;\n}\n\n/**\n * Start a local HTTP server to receive the OAuth callback\n */\nfunction startCallbackServer(port: number): Promise<AuthResult> {\n return new Promise((resolve) => {\n // Track active connections so we can forcefully close them\n const connections = new Set<import('net').Socket>();\n \n const server = http.createServer((req, res) => {\n const url = new URL(req.url || '/', `http://localhost:${port}`);\n \n if (url.pathname === '/callback') {\n const token = url.searchParams.get('token');\n const status = url.searchParams.get('status');\n const error = url.searchParams.get('error');\n \n // Send response to browser\n res.writeHead(200, { 'Content-Type': 'text/html' });\n \n if (status === 'success' && token) {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>Authentication Successful</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n background: #09090b;\n color: white;\n }\n .container {\n text-align: center;\n padding: 40px;\n }\n .success {\n color: #22c55e;\n font-size: 48px;\n margin-bottom: 20px;\n }\n h1 { margin: 0 0 10px; }\n p { color: #a1a1aa; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <div class=\"success\">✓</div>\n <h1>Authentication Successful!</h1>\n <p>You can close this window and return to your terminal.</p>\n </div>\n </body>\n </html>\n `);\n \n // Close server and resolve - destroy all connections to ensure clean exit\n server.close();\n connections.forEach(conn => conn.destroy());\n resolve({ success: true, token });\n } else {\n res.end(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>Authentication Failed</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n background: #09090b;\n color: white;\n }\n .container {\n text-align: center;\n padding: 40px;\n }\n .error {\n color: #ef4444;\n font-size: 48px;\n margin-bottom: 20px;\n }\n h1 { margin: 0 0 10px; }\n p { color: #a1a1aa; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <div class=\"error\">✗</div>\n <h1>Authentication Failed</h1>\n <p>${error || 'An error occurred during authentication.'}</p>\n <p>Please close this window and try again.</p>\n </div>\n </body>\n </html>\n `);\n \n server.close();\n connections.forEach(conn => conn.destroy());\n resolve({ success: false, error: error || 'Authentication failed' });\n }\n } else {\n // Handle other paths\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n }\n });\n \n // Timeout after 5 minutes\n const timeout = setTimeout(() => {\n server.close();\n connections.forEach(conn => conn.destroy());\n resolve({ success: false, error: 'Authentication timed out' });\n }, 5 * 60 * 1000);\n \n server.on('close', () => {\n clearTimeout(timeout);\n });\n \n // Handle server errors (e.g., port became unavailable due to race condition)\n server.on('error', (err: NodeJS.ErrnoException) => {\n clearTimeout(timeout);\n if (err.code === 'EADDRINUSE') {\n resolve({ success: false, error: `Port ${port} is no longer available. Please try again.` });\n } else {\n resolve({ success: false, error: `Server error: ${err.message}` });\n }\n });\n \n // Track connections for cleanup\n server.on('connection', (conn) => {\n connections.add(conn);\n conn.on('close', () => connections.delete(conn));\n });\n \n server.listen(port, '127.0.0.1');\n });\n}\n\n/**\n * Perform CLI OAuth authentication flow\n * \n * 1. Find an available port\n * 2. Start local callback server\n * 3. Request auth session from API\n * 4. Open browser to auth page\n * 5. Wait for callback\n * 6. Return token\n */\nexport async function performOAuthLogin(options: CLIAuthOptions = {}): Promise<AuthResult> {\n const apiUrl = options.apiUrl || 'https://openbuilder.sh';\n const deviceName = options.deviceName || getDeviceName();\n const silent = options.silent || false;\n \n try {\n // Find available port\n if (!silent) {\n console.log(chalk.dim('Finding available port for callback...'));\n }\n const port = await findAvailablePort();\n \n // Start callback server before requesting auth (so it's ready when browser redirects)\n const callbackPromise = startCallbackServer(port);\n \n // Request auth session from API\n if (!silent) {\n console.log(chalk.dim('Initiating authentication...'));\n }\n \n const response = await fetch(`${apiUrl}/api/auth/cli/start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n callbackPort: port,\n callbackHost: 'localhost',\n deviceName,\n }),\n });\n \n if (!response.ok) {\n const data = await response.json();\n return { success: false, error: data.error || 'Failed to start authentication' };\n }\n \n const { authUrl } = await response.json();\n \n // Open browser\n if (!silent) {\n console.log('');\n console.log(chalk.cyan('Opening browser for authentication...'));\n console.log(chalk.dim(`If the browser doesn't open, visit:`));\n console.log(chalk.underline(authUrl));\n console.log('');\n }\n \n try {\n await openBrowser(authUrl);\n } catch {\n // Browser failed to open - user will need to copy/paste URL\n if (!silent) {\n console.log(chalk.yellow('Could not open browser automatically.'));\n }\n }\n \n if (!silent) {\n console.log(chalk.yellow('Waiting for authentication...'));\n console.log(chalk.dim('(Press Ctrl+C to cancel)'));\n }\n \n // Wait for callback\n const result = await callbackPromise;\n \n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Authentication failed',\n };\n }\n}\n\n/**\n * Check if we have a valid stored token\n */\nexport function hasStoredToken(): boolean {\n const token = getStoredToken();\n return token !== null && token.startsWith('sv_');\n}\n\n/**\n * Get the stored runner token\n */\nexport function getStoredToken(): string | null {\n const config = configManager.get();\n \n // Check for runner token in config\n if (config.server?.secret && config.server.secret.startsWith('sv_')) {\n return config.server.secret;\n }\n \n // Legacy: check broker config\n if (config.broker?.secret && config.broker.secret.startsWith('sv_')) {\n return config.broker.secret;\n }\n \n return null;\n}\n\n/**\n * Store the runner token in config\n */\nexport function storeToken(token: string, apiUrl?: string): void {\n // Determine the WebSocket URL from the API URL\n let wsUrl = 'wss://openbuilder.sh/ws/runner';\n if (apiUrl) {\n const url = new URL(apiUrl);\n const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n wsUrl = `${protocol}//${url.host}/ws/runner`;\n }\n \n // Store in the server config\n configManager.set('server', {\n wsUrl,\n secret: token,\n });\n \n // Also set the apiUrl if provided\n if (apiUrl) {\n configManager.set('apiUrl', apiUrl);\n }\n}\n\n/**\n * Clear the stored token\n */\nexport function clearToken(): void {\n const config = configManager.get();\n \n // Clear server secret\n if (config.server) {\n configManager.set('server', {\n ...config.server,\n secret: '',\n });\n }\n \n // Clear legacy broker secret\n if (config.broker) {\n configManager.set('broker', {\n ...config.broker,\n secret: '',\n });\n }\n}\n\n/**\n * Validate the stored token against the server\n */\nexport async function validateToken(token: string, apiUrl: string): Promise<boolean> {\n try {\n // Try to fetch user's runner keys - this will fail if token is invalid\n const response = await fetch(`${apiUrl}/api/runner-keys`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n \n return response.ok;\n } catch {\n return false;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-error-BjQwvWtK.js","sources":["../../src/cli/utils/cli-error.ts"],"sourcesContent":["/**\n * CLI Error handling with context and actionable suggestions\n * Replaces scattered process.exit() calls throughout the codebase\n */\n\nexport type ErrorCode =\n // Initialization errors\n | 'INIT_FAILED'\n | 'MONOREPO_NOT_FOUND'\n | 'MONOREPO_CLONE_FAILED'\n | 'DEPENDENCIES_INSTALL_FAILED'\n | 'BUILD_FAILED'\n\n // Configuration errors\n | 'CONFIG_INVALID'\n | 'CONFIG_NOT_FOUND'\n | 'WORKSPACE_NOT_FOUND'\n | 'WORKSPACE_CREATE_FAILED'\n\n // Database errors\n | 'DB_CONNECTION_FAILED'\n | 'DB_MIGRATION_FAILED'\n | 'DB_URL_INVALID'\n\n // Network/Port errors\n | 'PORT_IN_USE'\n | 'BROKER_CONNECTION_FAILED'\n | 'TUNNEL_CREATION_FAILED'\n\n // Runtime errors\n | 'SERVICE_START_FAILED'\n | 'SERVICE_CRASHED'\n | 'PROCESS_KILL_FAILED'\n\n // User errors\n | 'INVALID_ARGUMENT'\n | 'MISSING_REQUIRED_CONFIG'\n | 'PERMISSION_DENIED'\n\n // Upgrade errors\n | 'UPGRADE_NOT_IN_REPO'\n | 'UPGRADE_CLONE_FAILED'\n | 'UPGRADE_INSTALL_FAILED'\n | 'UPGRADE_BUILD_FAILED'\n\n // Unknown\n | 'UNKNOWN_ERROR';\n\nexport interface CLIErrorOptions {\n code: ErrorCode;\n message: string;\n context?: Record<string, unknown>;\n suggestions?: string[];\n fatal?: boolean;\n cause?: Error;\n docs?: string; // Link to documentation\n}\n\n/**\n * Custom error class for CLI operations\n * Provides context, suggestions, and proper exit codes\n */\nexport class CLIError extends Error {\n public readonly code: ErrorCode;\n public readonly context?: Record<string, unknown>;\n public readonly suggestions: string[];\n public readonly fatal: boolean;\n public readonly cause?: Error;\n public readonly docs?: string;\n\n constructor(options: CLIErrorOptions) {\n super(options.message);\n this.name = 'CLIError';\n this.code = options.code;\n this.context = options.context;\n this.suggestions = options.suggestions || [];\n this.fatal = options.fatal !== false; // Default true\n this.cause = options.cause;\n this.docs = options.docs;\n\n // Maintains proper stack trace for where error was thrown\n Error.captureStackTrace(this, this.constructor);\n }\n\n /**\n * Get exit code based on error type\n */\n getExitCode(): number {\n // Map error codes to exit codes\n const exitCodes: Partial<Record<ErrorCode, number>> = {\n 'CONFIG_INVALID': 78, // EX_CONFIG\n 'CONFIG_NOT_FOUND': 78,\n 'PERMISSION_DENIED': 77, // EX_NOPERM\n 'INVALID_ARGUMENT': 64, // EX_USAGE\n 'DB_CONNECTION_FAILED': 69, // EX_UNAVAILABLE\n 'BROKER_CONNECTION_FAILED': 69,\n 'PORT_IN_USE': 69,\n };\n\n return exitCodes[this.code] || 1; // Default generic error\n }\n}\n\n/**\n * Common error factory functions\n * Use these instead of throwing raw CLIError\n */\nexport const errors = {\n portInUse: (port: number, process?: string): CLIError => {\n return new CLIError({\n code: 'PORT_IN_USE',\n message: `Port ${port} is already in use`,\n context: { port, process },\n suggestions: [\n `Stop the existing process: lsof -ti:${port} | xargs kill`,\n `Or let OpenBuilder kill it: openbuilder run --force`,\n process ? `The port is being used by: ${process}` : 'Check what process is using the port: lsof -i:' + port,\n ],\n });\n },\n\n databaseConnectionFailed: (url: string, cause: Error): CLIError => {\n // Parse URL to get host (safely)\n let host = 'database server';\n try {\n const parsed = new URL(url);\n host = parsed.host;\n } catch {\n // URL might be invalid\n }\n\n return new CLIError({\n code: 'DB_CONNECTION_FAILED',\n message: 'Could not connect to database',\n context: { host, error: cause.message },\n cause,\n suggestions: [\n 'Verify your connection string: openbuilder config get databaseUrl',\n 'Test the connection manually: psql <connection-string>',\n 'Reset database setup: openbuilder db setup --force',\n ],\n docs: 'https://github.com/codyde/openbuilder#database-setup',\n });\n },\n\n monorepoNotFound: (searchedPaths: string[]): CLIError => {\n return new CLIError({\n code: 'MONOREPO_NOT_FOUND',\n message: 'OpenBuilder monorepo not found',\n context: { searchedPaths },\n suggestions: [\n 'Run initialization: openbuilder init',\n 'Or specify path: openbuilder run --monorepo ~/openbuilder',\n ],\n });\n },\n\n configNotFound: (): CLIError => {\n return new CLIError({\n code: 'CONFIG_NOT_FOUND',\n message: 'Configuration not found',\n suggestions: [\n 'Initialize OpenBuilder: openbuilder init',\n 'This will create your configuration file',\n ],\n docs: 'https://github.com/codyde/openbuilder#getting-started',\n });\n },\n\n workspaceNotFound: (path: string): CLIError => {\n return new CLIError({\n code: 'WORKSPACE_NOT_FOUND',\n message: `Workspace directory does not exist: ${path}`,\n context: { path },\n suggestions: [\n 'Create the directory: mkdir -p ' + path,\n 'Or reconfigure workspace: openbuilder config set workspace <path>',\n 'Or re-run init: openbuilder init',\n ],\n });\n },\n\n serviceStartFailed: (service: string, cause: Error): CLIError => {\n return new CLIError({\n code: 'SERVICE_START_FAILED',\n message: `Failed to start ${service}`,\n context: { service },\n cause,\n suggestions: [\n 'Check if dependencies are installed: cd ~/.openbuilder-monorepo && pnpm install',\n 'Check if ports are available: lsof -i:3000 -i:4000',\n 'Try restarting: openbuilder run --force',\n ],\n });\n },\n\n invalidArgument: (arg: string, reason: string): CLIError => {\n return new CLIError({\n code: 'INVALID_ARGUMENT',\n message: `Invalid argument: ${arg}`,\n context: { argument: arg, reason },\n suggestions: [\n 'Check the command usage: openbuilder --help',\n ],\n });\n },\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-BGP1jZJ4.js","sources":["../../src/cli/commands/config.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { logger } from '../utils/logger.js';\nimport { configManager } from '../utils/config-manager.js';\nimport { prompts } from '../utils/prompts.js';\n\nexport async function configCommand(action: string, key?: string, value?: string) {\n switch (action) {\n case 'get':\n if (!key) {\n logger.error('Key is required for get action');\n logger.info('Usage: openbuilder config get <key>');\n process.exit(1);\n }\n handleGet(key);\n break;\n\n case 'set':\n if (!key || !value) {\n logger.error('Key and value are required for set action');\n logger.info('Usage: openbuilder config set <key> <value>');\n process.exit(1);\n }\n handleSet(key, value);\n break;\n\n case 'list':\n handleList();\n break;\n\n case 'path':\n handlePath();\n break;\n\n case 'validate':\n handleValidate();\n break;\n\n case 'reset':\n await handleReset();\n break;\n\n default:\n logger.error(`Unknown action: ${action}`);\n logger.info('Available actions: get, set, list, path, validate, reset');\n process.exit(1);\n }\n}\n\nfunction handleGet(key: string) {\n try {\n const value = configManager.get(key as any);\n if (value === undefined) {\n logger.warn(`Key not found: ${key}`);\n process.exit(1);\n }\n\n if (typeof value === 'object') {\n logger.log(JSON.stringify(value, null, 2));\n } else {\n logger.log(String(value));\n }\n } catch (error) {\n logger.error('Failed to get config value');\n logger.error(error instanceof Error ? error.message : 'Unknown error');\n process.exit(1);\n }\n}\n\nfunction handleSet(key: string, value: string) {\n try {\n // Try to parse as JSON for objects/arrays\n let parsedValue: any = value;\n if (value.startsWith('{') || value.startsWith('[')) {\n try {\n parsedValue = JSON.parse(value);\n } catch {\n // Keep as string if not valid JSON\n }\n }\n\n configManager.set(key as any, parsedValue);\n logger.success(`Set ${chalk.cyan(key)} = ${chalk.green(value)}`);\n } catch (error) {\n logger.error('Failed to set config value');\n logger.error(error instanceof Error ? error.message : 'Unknown error');\n process.exit(1);\n }\n}\n\nfunction handleList() {\n const config = configManager.get();\n\n logger.section('Current Configuration');\n logger.log('');\n\n // Workspace\n logger.info(`${chalk.bold('Workspace:')}`);\n logger.log(` ${config.workspace}`);\n logger.log('');\n\n // API\n logger.info(`${chalk.bold('API:')}`);\n logger.log(` URL: ${config.apiUrl || 'not set'}`);\n logger.log('');\n\n // Broker\n logger.info(`${chalk.bold('Broker:')}`);\n logger.log(` WebSocket URL: ${config.broker?.url || 'not set'}`);\n logger.log(` HTTP URL: ${config.broker?.httpUrl || 'not set'}`);\n logger.log(` Secret: ${config.broker?.secret ? '***' : 'not set'}`);\n logger.log('');\n\n // Runner\n logger.info(`${chalk.bold('Runner:')}`);\n logger.log(` ID: ${config.runner?.id || 'not set'}`);\n logger.log(` Reconnect Attempts: ${config.runner?.reconnectAttempts || 5}`);\n logger.log(` Heartbeat Interval: ${config.runner?.heartbeatInterval || 15000}ms`);\n logger.log('');\n\n // Database\n if (config.databaseUrl) {\n logger.info(`${chalk.bold('Database:')}`);\n logger.log(` URL: ${config.databaseUrl.replace(/:[^:@]+@/, ':***@')}`); // Mask password\n logger.log('');\n }\n\n // Monorepo\n if (config.monorepoPath) {\n logger.info(`${chalk.bold('Monorepo:')}`);\n logger.log(` Path: ${config.monorepoPath}`);\n logger.log('');\n }\n\n // Tunnel\n if (config.tunnel) {\n logger.info(`${chalk.bold('Tunnel:')}`);\n logger.log(` Provider: ${config.tunnel.provider}`);\n logger.log(` Auto Create: ${config.tunnel.autoCreate}`);\n logger.log('');\n }\n}\n\nfunction handlePath() {\n logger.info(`Config file: ${chalk.cyan(configManager.path)}`);\n}\n\nfunction handleValidate() {\n const validation = configManager.validate();\n\n if (validation.valid) {\n logger.success('Configuration is valid');\n } else {\n logger.error('Configuration validation failed:');\n validation.errors.forEach((err) => logger.error(` - ${err}`));\n process.exit(1);\n }\n}\n\nasync function handleReset() {\n logger.warn('This will delete all configuration and reset to defaults');\n const confirmed = await prompts.confirm('Are you sure?', false);\n\n if (!confirmed) {\n logger.info('Reset cancelled');\n return;\n }\n\n try {\n configManager.reset();\n logger.success('Configuration reset to defaults');\n logger.info('Run \"openbuilder init\" to reconfigure');\n } catch (error) {\n logger.error('Failed to reset configuration');\n logger.error(error instanceof Error ? error.message : 'Unknown error');\n process.exit(1);\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAKO,eAAe,aAAa,CAAC,MAAc,EAAE,GAAY,EAAE,KAAc,EAAA;IAC9E,QAAQ,MAAM;AACZ,QAAA,KAAK,KAAK;YACR,IAAI,CAAC,GAAG,EAAE;AACR,gBAAA,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC;AAC9C,gBAAA,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC;AAClD,gBAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACjB;YACA,SAAS,CAAC,GAAG,CAAC;YACd;AAEF,QAAA,KAAK,KAAK;AACR,YAAA,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE;AAClB,gBAAA,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC;AACzD,gBAAA,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC;AAC1D,gBAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACjB;AACA,YAAA,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC;YACrB;AAEF,QAAA,KAAK,MAAM;AACT,YAAA,UAAU,EAAE;YACZ;AAEF,QAAA,KAAK,MAAM;AACT,YAAA,UAAU,EAAE;YACZ;AAEF,QAAA,KAAK,UAAU;AACb,YAAA,cAAc,EAAE;YAChB;AAEF,QAAA,KAAK,OAAO;YACV,MAAM,WAAW,EAAE;YACnB;AAEF,QAAA;AACE,YAAA,MAAM,CAAC,KAAK,CAAC,mBAAmB,MAAM,CAAA,CAAE,CAAC;AACzC,YAAA,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC;AACvE,YAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAErB;AAEA,SAAS,SAAS,CAAC,GAAW,EAAA;AAC5B,IAAA,IAAI;QACF,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,GAAU,CAAC;AAC3C,QAAA,IAAI,KAAK,KAAK,SAAS,EAAE;AACvB,YAAA,MAAM,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAA,CAAE,CAAC;AACpC,YAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACjB;AAEA,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,YAAA,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC5C;aAAO;YACL,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B;IACF;IAAE,OAAO,KAAK,EAAE;AACd,QAAA,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC;AAC1C,QAAA,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,eAAe,CAAC;AACtE,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;AACF;AAEA,SAAS,SAAS,CAAC,GAAW,EAAE,KAAa,EAAA;AAC3C,IAAA,IAAI;;QAEF,IAAI,WAAW,GAAQ,KAAK;AAC5B,QAAA,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAClD,YAAA,IAAI;AACF,gBAAA,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YACjC;AAAE,YAAA,MAAM;;YAER;QACF;AAEA,QAAA,aAAa,CAAC,GAAG,CAAC,GAAU,EAAE,WAAW,CAAC;AAC1C,QAAA,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,GAAA,EAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA,CAAE,CAAC;IAClE;IAAE,OAAO,KAAK,EAAE;AACd,QAAA,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC;AAC1C,QAAA,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,eAAe,CAAC;AACtE,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;AACF;AAEA,SAAS,UAAU,GAAA;AACjB,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE;AAElC,IAAA,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC;AACvC,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA,CAAE,CAAC;IAC1C,MAAM,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,MAAM,CAAC,SAAS,CAAA,CAAE,CAAC;AACnC,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA,CAAE,CAAC;IACpC,MAAM,CAAC,GAAG,CAAC,CAAA,OAAA,EAAU,MAAM,CAAC,MAAM,IAAI,SAAS,CAAA,CAAE,CAAC;AAClD,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA,CAAE,CAAC;AACvC,IAAA,MAAM,CAAC,GAAG,CAAC,CAAA,iBAAA,EAAoB,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAA,CAAE,CAAC;AACjE,IAAA,MAAM,CAAC,GAAG,CAAC,CAAA,YAAA,EAAe,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,SAAS,CAAA,CAAE,CAAC;AAChE,IAAA,MAAM,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA,CAAE,CAAC;AACpE,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA,CAAE,CAAC;AACvC,IAAA,MAAM,CAAC,GAAG,CAAC,CAAA,MAAA,EAAS,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,SAAS,CAAA,CAAE,CAAC;AACrD,IAAA,MAAM,CAAC,GAAG,CAAC,CAAA,sBAAA,EAAyB,MAAM,CAAC,MAAM,EAAE,iBAAiB,IAAI,CAAC,CAAA,CAAE,CAAC;AAC5E,IAAA,MAAM,CAAC,GAAG,CAAC,CAAA,sBAAA,EAAyB,MAAM,CAAC,MAAM,EAAE,iBAAiB,IAAI,KAAK,CAAA,EAAA,CAAI,CAAC;AAClF,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,IAAI,MAAM,CAAC,WAAW,EAAE;AACtB,QAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA,CAAE,CAAC;AACzC,QAAA,MAAM,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AACxE,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAChB;;AAGA,IAAA,IAAI,MAAM,CAAC,YAAY,EAAE;AACvB,QAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA,CAAE,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,CAAA,QAAA,EAAW,MAAM,CAAC,YAAY,CAAA,CAAE,CAAC;AAC5C,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAChB;;AAGA,IAAA,IAAI,MAAM,CAAC,MAAM,EAAE;AACjB,QAAA,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA,CAAE,CAAC;QACvC,MAAM,CAAC,GAAG,CAAC,CAAA,YAAA,EAAe,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAA,CAAE,CAAC;QACnD,MAAM,CAAC,GAAG,CAAC,CAAA,eAAA,EAAkB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAA,CAAE,CAAC;AACxD,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAChB;AACF;AAEA,SAAS,UAAU,GAAA;AACjB,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,aAAA,EAAgB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA,CAAE,CAAC;AAC/D;AAEA,SAAS,cAAc,GAAA;AACrB,IAAA,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,EAAE;AAE3C,IAAA,IAAI,UAAU,CAAC,KAAK,EAAE;AACpB,QAAA,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC;IAC1C;SAAO;AACL,QAAA,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC;AAChD,QAAA,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,CAAA,IAAA,EAAO,GAAG,CAAA,CAAE,CAAC,CAAC;AAC9D,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;AACF;AAEA,eAAe,WAAW,GAAA;AACxB,IAAA,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC;IACvE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC;IAE/D,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAC9B;IACF;AAEA,IAAA,IAAI;QACF,aAAa,CAAC,KAAK,EAAE;AACrB,QAAA,MAAM,CAAC,OAAO,CAAC,iCAAiC,CAAC;AACjD,QAAA,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC;IACtD;IAAE,OAAO,KAAK,EAAE;AACd,QAAA,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC;AAC7C,QAAA,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,eAAe,CAAC;AACtE,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;AACF;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-manager-BkbjtN-H.js","sources":["../../src/cli/utils/config-manager.ts"],"sourcesContent":["import Conf from 'conf';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync } from 'node:fs';\n\n// Theme names for the TUI\nexport type ThemeName = 'sentry' | 'ocean' | 'ember' | 'forest' | 'noir';\n\nexport interface RunnerConfig {\n version: string;\n workspace: string;\n monorepoPath?: string; // Path to cloned openbuilder repository\n databaseUrl?: string; // PostgreSQL connection string\n apiUrl?: string; // API base URL (e.g., http://localhost:3000)\n autoUpdate?: boolean; // Enable automatic CLI updates (default: true)\n // Server connection config (formerly \"broker\" - now connects directly to Next.js)\n server: {\n wsUrl: string; // WebSocket URL (e.g., ws://localhost:3000/ws/runner)\n secret: string;\n };\n // Legacy broker config for backward compatibility\n broker?: {\n url: string;\n httpUrl?: string;\n secret: string;\n };\n runner: {\n id: string; // This runner's ID and default ID for web app in local mode\n lastRunnerId?: string; // Last used runner ID (for runner mode)\n reconnectAttempts?: number;\n heartbeatInterval?: number;\n };\n tunnel?: {\n provider: 'cloudflare';\n autoCreate: boolean;\n };\n // TUI preferences\n ui?: {\n theme: ThemeName;\n };\n}\n\n/**\n * Config manager using conf library\n * Handles platform-specific config locations\n */\nexport class ConfigManager {\n private conf: Conf<RunnerConfig>;\n\n constructor() {\n this.conf = new Conf<RunnerConfig>({\n projectName: 'openbuilder',\n projectSuffix: '', // No suffix, just 'openbuilder'\n defaults: this.getDefaults(),\n });\n }\n\n private getDefaults(): RunnerConfig {\n return {\n version: '0.1.0',\n workspace: join(homedir(), 'openbuilder-workspace'),\n apiUrl: 'http://localhost:3000', // Default API URL\n server: {\n wsUrl: 'ws://localhost:3000/ws/runner', // Direct WebSocket connection to Next.js\n secret: 'dev-secret', // Default local secret\n },\n runner: {\n id: 'local',\n reconnectAttempts: 5,\n heartbeatInterval: 15000,\n },\n tunnel: {\n provider: 'cloudflare',\n autoCreate: true,\n },\n };\n }\n\n get(key?: keyof RunnerConfig): any {\n if (!key) {\n return this.conf.store;\n }\n return this.conf.get(key);\n }\n\n set(key: keyof RunnerConfig | string, value: any): void {\n this.conf.set(key as any, value);\n }\n\n delete(key: keyof RunnerConfig): void {\n this.conf.delete(key);\n }\n\n reset(): void {\n this.conf.clear();\n this.conf.store = this.getDefaults();\n }\n\n has(key: keyof RunnerConfig): boolean {\n return this.conf.has(key);\n }\n\n get path(): string {\n return this.conf.path;\n }\n\n validate(): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n const config = this.conf.store;\n\n if (!config.workspace) {\n errors.push('Workspace path is required');\n }\n\n // Check for server config (new) or legacy broker config\n const hasServerConfig = config.server?.secret && config.server?.wsUrl;\n const hasLegacyBrokerConfig = config.broker?.secret && config.broker?.url;\n \n if (!hasServerConfig && !hasLegacyBrokerConfig) {\n errors.push('Server shared secret is required');\n errors.push('Server WebSocket URL is required');\n }\n\n if (!config.runner?.id) {\n errors.push('Runner ID is required');\n }\n\n // Check if workspace exists\n if (config.workspace && !existsSync(config.workspace)) {\n errors.push(`Workspace directory does not exist: ${config.workspace}`);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Check if config has been initialized properly\n * Requires monorepo to be cloned and databaseUrl to be configured\n */\n isInitialized(): boolean {\n const monorepoPath = this.get('monorepoPath');\n const databaseUrl = this.get('databaseUrl');\n \n // Must have monorepo path set and the directory must exist\n if (!monorepoPath || !existsSync(monorepoPath)) {\n return false;\n }\n \n // Must have database URL configured\n if (!databaseUrl) {\n return false;\n }\n \n return true;\n }\n \n /**\n * Get the WebSocket URL (supports both new and legacy config)\n */\n getWsUrl(): string {\n const server = this.get('server');\n const broker = this.get('broker');\n \n // Prefer new server config\n if (server?.wsUrl) {\n return server.wsUrl;\n }\n \n // Fall back to legacy broker URL\n return broker?.url ?? 'ws://localhost:3000/ws/runner';\n }\n \n /**\n * Get the shared secret (supports both new and legacy config)\n */\n getSecret(): string {\n const server = this.get('server');\n const broker = this.get('broker');\n \n // Prefer new server config\n if (server?.secret) {\n return server.secret;\n }\n \n // Fall back to legacy broker secret\n return broker?.secret ?? '';\n }\n}\n\nexport const configManager = new ConfigManager();\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-BvAbD4sP.js","sources":["../../src/cli/commands/database.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { logger } from '../utils/logger.js';\nimport { configManager } from '../utils/config-manager.js';\nimport { setupDatabase, pushDatabaseSchema } from '../utils/database-setup.js';\nimport { prompts } from '../utils/prompts.js';\n\nexport async function databaseCommand() {\n logger.section('Database Setup');\n logger.log('');\n\n // Check if monorepo is configured\n const config = configManager.get();\n const monorepoPath = config.monorepoPath;\n\n if (!monorepoPath) {\n logger.error('Monorepo path not found in config');\n logger.info('Run \"openbuilder init\" first to set up the repository');\n process.exit(1);\n }\n\n // Step 1: Setup new database\n logger.info('Setting up new Neon PostgreSQL database...');\n logger.log('');\n\n const databaseUrl = await setupDatabase(monorepoPath);\n\n if (!databaseUrl) {\n logger.error('Failed to create database');\n logger.log('');\n logger.info('You can manually set a database URL with:');\n logger.log(` ${chalk.cyan('openbuilder config set databaseUrl <url>')}`);\n process.exit(1);\n }\n\n logger.log('');\n logger.success('Database created!');\n logger.info(`Connection string saved to config`);\n logger.log('');\n\n // Save to config\n configManager.set('databaseUrl', databaseUrl);\n\n // Step 2: Push schema\n logger.info('Initializing database schema...');\n logger.log('');\n\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n\n if (!pushed) {\n logger.warn('Failed to push database schema');\n logger.log('');\n logger.info('You can try manually:');\n logger.log(` ${chalk.cyan('cd apps/openbuilder')}`);\n logger.log(` ${chalk.cyan('npx drizzle-kit push --config=drizzle.config.ts')}`);\n logger.log('');\n process.exit(1);\n }\n\n // Success!\n logger.log('');\n logger.success('Database setup complete! 🎉');\n logger.log('');\n logger.info('Database is ready for use');\n logger.info(`You can now run: ${chalk.cyan('openbuilder run')}`);\n logger.log('');\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAMO,eAAe,eAAe,GAAA;AACnC,IAAA,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;AAChC,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE;AAClC,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY;IAExC,IAAI,CAAC,YAAY,EAAE;AACjB,QAAA,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC;AACjD,QAAA,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC;AACpE,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;;AAGA,IAAA,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC;AACzD,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAEd,IAAA,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC;IAErD,IAAI,CAAC,WAAW,EAAE;AAChB,QAAA,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC;AACzC,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACd,QAAA,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC;AACxD,QAAA,MAAM,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA,CAAE,CAAC;AACzE,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;AAEA,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACd,IAAA,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC;AACnC,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,iCAAA,CAAmC,CAAC;AAChD,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;;AAGd,IAAA,aAAa,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC;;AAG7C,IAAA,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC;AAC9C,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAEd,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC;IAElE,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC;AAC7C,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACd,QAAA,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC;AACpC,QAAA,MAAM,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA,CAAE,CAAC;AACpD,QAAA,MAAM,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAA,CAAE,CAAC;AAChF,QAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACd,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;;AAGA,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACd,IAAA,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC;AAC7C,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACd,IAAA,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC;AACxC,IAAA,MAAM,CAAC,IAAI,CAAC,CAAA,iBAAA,EAAoB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA,CAAE,CAAC;AAChE,IAAA,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAChB;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-setup-BYjIRAmT.js","sources":["../../src/cli/utils/database-setup.ts"],"sourcesContent":["import { spawn, execFileSync } from 'node:child_process';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { logger } from './logger.js';\nimport { spinner } from './spinner.js';\nimport { prompts } from './prompts.js';\n\n/**\n * Read DATABASE_URL from .env file in monorepo root\n */\nexport async function readDatabaseUrlFromEnv(monorepoPath: string): Promise<string | null> {\n const envPath = join(monorepoPath, '.env');\n\n if (!existsSync(envPath)) {\n return null;\n }\n\n try {\n const content = await readFile(envPath, 'utf-8');\n const match = content.match(/^DATABASE_URL\\s*=\\s*['\"]?([^'\"\\n]+)['\"]?/m);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Clear DATABASE_URL from .env file (removes stale value)\n */\nexport async function clearDatabaseUrlFromEnv(monorepoPath: string): Promise<void> {\n const envPath = join(monorepoPath, '.env');\n\n if (!existsSync(envPath)) {\n return;\n }\n\n try {\n const content = await readFile(envPath, 'utf-8');\n const updated = content\n .split('\\n')\n .filter(line => !line.trim().startsWith('DATABASE_URL'))\n .join('\\n');\n await writeFile(envPath, updated, 'utf-8');\n } catch (error) {\n logger.warn('Could not clear DATABASE_URL from .env');\n }\n}\n\n/**\n * Run neondb setup to create a database and get the connection string\n * Returns the DATABASE_URL if successful\n */\nexport async function setupDatabase(monorepoPath: string, silent: boolean = false): Promise<string | null> {\n // Clear any stale DATABASE_URL first\n await clearDatabaseUrlFromEnv(monorepoPath);\n\n if (!silent) {\n spinner.start('Setting up Neon PostgreSQL database...');\n }\n\n return new Promise((resolve) => {\n const proc = spawn('npx', ['neondb', '-y'], {\n cwd: monorepoPath, // Run in monorepo root so .env is created there\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n let databaseUrl: string | null = null;\n let output = '';\n\n proc.stdout?.on('data', (data) => {\n const text = data.toString();\n output += text;\n\n // Look for DATABASE_URL in the output\n const match = text.match(/DATABASE_URL[=:]?\\s*['\"]?([^'\"\\s]+)['\"]?/);\n if (match && match[1]) {\n databaseUrl = match[1];\n }\n\n // Also check for postgres:// connection strings\n const connMatch = text.match(/(postgres(?:ql)?:\\/\\/[^\\s'\"]+)/);\n if (connMatch && connMatch[1]) {\n databaseUrl = connMatch[1];\n }\n });\n\n proc.stderr?.on('data', (data) => {\n const text = data.toString();\n // Only log actual errors (and only if not silent)\n if (!silent && (text.includes('error') || text.includes('Error'))) {\n logger.debug(text.trim());\n }\n });\n\n proc.on('exit', async (code) => {\n if (code === 0) {\n // Try to read DATABASE_URL from .env file (neondb writes it there)\n const urlFromEnv = await readDatabaseUrlFromEnv(monorepoPath);\n\n if (urlFromEnv) {\n databaseUrl = urlFromEnv;\n if (!silent) {\n spinner.succeed('Database created successfully');\n }\n resolve(databaseUrl);\n } else if (databaseUrl) {\n // Fallback to what we parsed from output\n if (!silent) {\n spinner.succeed('Database created successfully');\n }\n resolve(databaseUrl);\n } else {\n if (!silent) {\n spinner.warn('Database command completed but DATABASE_URL not found');\n logger.info('Check .env file in monorepo root for DATABASE_URL');\n }\n resolve(null);\n }\n } else {\n if (!silent) {\n spinner.fail('Failed to create database');\n }\n resolve(null);\n }\n });\n\n proc.on('error', (error) => {\n if (!silent) {\n spinner.fail('Failed to run neondb');\n logger.error(`Error: ${error.message}`);\n }\n resolve(null);\n });\n });\n}\n\n/**\n * Check if neondb is available\n */\nexport async function isNeondbAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn('npx', ['neondb', '--version'], {\n stdio: 'ignore',\n shell: true,\n });\n\n proc.on('exit', (code) => {\n resolve(code === 0);\n });\n\n proc.on('error', () => {\n resolve(false);\n });\n });\n}\n\n/**\n * Push database schema using drizzle-kit\n */\nexport async function pushDatabaseSchema(monorepoPath: string, databaseUrl: string, silent: boolean = false): Promise<boolean> {\n const { join } = await import('path');\n const { existsSync } = await import('fs');\n\n const openbuilderAppPath = join(monorepoPath, 'apps/openbuilder');\n const configPath = join(openbuilderAppPath, 'drizzle.config.ts');\n\n // Verify paths exist\n if (!existsSync(openbuilderAppPath)) {\n if (!silent) {\n logger.error(`Directory not found: ${openbuilderAppPath}`);\n }\n return false;\n }\n\n if (!existsSync(configPath)) {\n if (!silent) {\n logger.error(`Drizzle config not found: ${configPath}`);\n }\n return false;\n }\n\n if (!silent) {\n spinner.start('Ensuring openbuilder dependencies are installed...');\n }\n\n try {\n execFileSync('pnpm', ['install'], {\n cwd: openbuilderAppPath,\n stdio: 'pipe',\n });\n execFileSync('pnpm', ['--filter', '@openbuilder/agent-core', 'build'], {\n cwd: monorepoPath,\n stdio: 'pipe',\n });\n if (!silent) {\n spinner.succeed('Dependencies ready');\n }\n } catch (error) {\n if (!silent) {\n spinner.warn('Dependency installation failed, trying schema push anyway');\n }\n }\n\n if (!silent) {\n spinner.start('Initializing database schema (this may take a moment)...');\n }\n\n return new Promise((resolve) => {\n const proc = spawn('npx', ['drizzle-kit', 'push', '--config=drizzle.config.ts'], {\n cwd: openbuilderAppPath,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n env: {\n ...process.env,\n DATABASE_URL: databaseUrl, // Ensure drizzle-kit has access\n },\n });\n\n let allOutput = '';\n\n // Capture all output for debugging\n proc.stdout?.on('data', (data) => {\n allOutput += data.toString();\n });\n\n proc.stderr?.on('data', (data) => {\n allOutput += data.toString();\n });\n\n proc.on('exit', (code) => {\n if (code === 0) {\n if (!silent) {\n spinner.succeed('Database schema initialized successfully');\n }\n resolve(true);\n } else {\n if (!silent) {\n spinner.fail('Failed to push database schema');\n // Show all output when it fails so user can see what went wrong\n if (allOutput.trim()) {\n logger.log(''); // Blank line\n logger.log('Output from drizzle-kit push:');\n logger.log(allOutput.trim());\n logger.log(''); // Blank line\n }\n }\n resolve(false);\n }\n });\n\n proc.on('error', (error) => {\n if (!silent) {\n spinner.fail('Failed to run drizzle-kit');\n logger.error(`Error: ${error.message}`);\n }\n resolve(false);\n });\n });\n}\n\n/**\n * Connect to an existing database manually by prompting for connection string\n */\nexport async function connectManualDatabase(): Promise<string | null> {\n logger.log('');\n\n // Ask user what type of connection they want\n const connectionType = await prompts.select(\n 'How would you like to connect your database?',\n [\n 'Connect an existing OpenBuilder database',\n 'Provide a connection string directly',\n ]\n );\n\n logger.log('');\n\n // Prompt for the connection string\n let message: string;\n if (connectionType === 'Connect an existing OpenBuilder database') {\n message = 'Enter your OpenBuilder database connection string:';\n } else {\n message = 'Enter your PostgreSQL connection string:';\n }\n\n const connectionString = await prompts.input(message);\n\n // Basic validation\n if (!connectionString || connectionString.trim() === '') {\n logger.error('Connection string cannot be empty');\n return null;\n }\n\n // Validate it looks like a PostgreSQL connection string\n if (!connectionString.match(/^postgres(?:ql)?:\\/\\//)) {\n logger.error('Connection string must start with postgres:// or postgresql://');\n return null;\n }\n\n return connectionString.trim();\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// OpenBuilder CLI - Built with Rollup
|
|
2
|
+
import WebSocket from 'ws';
|
|
3
|
+
import devtools from 'react-devtools-core';
|
|
4
|
+
|
|
5
|
+
// Ignoring missing types error to avoid adding another dependency for this hack to work
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
7
|
+
const customGlobal = global;
|
|
8
|
+
// These things must exist before importing `react-devtools-core`
|
|
9
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
10
|
+
customGlobal.WebSocket ||= WebSocket;
|
|
11
|
+
customGlobal.window ||= global;
|
|
12
|
+
customGlobal.self ||= global;
|
|
13
|
+
// Filter out Ink's internal components from devtools for a cleaner view.
|
|
14
|
+
// Also, ince `react-devtools-shared` package isn't published on npm, we can't
|
|
15
|
+
// use its types, that's why there are hard-coded values in `type` fields below.
|
|
16
|
+
// See https://github.com/facebook/react/blob/edf6eac8a181860fd8a2d076a43806f1237495a1/packages/react-devtools-shared/src/types.js#L24
|
|
17
|
+
customGlobal.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = [
|
|
18
|
+
{
|
|
19
|
+
// ComponentFilterElementType
|
|
20
|
+
type: 1,
|
|
21
|
+
// ElementTypeHostComponent
|
|
22
|
+
value: 7,
|
|
23
|
+
isEnabled: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
// ComponentFilterDisplayName
|
|
27
|
+
type: 2,
|
|
28
|
+
value: 'InternalApp',
|
|
29
|
+
isEnabled: true,
|
|
30
|
+
isValid: true,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
// ComponentFilterDisplayName
|
|
34
|
+
type: 2,
|
|
35
|
+
value: 'InternalAppContext',
|
|
36
|
+
isEnabled: true,
|
|
37
|
+
isValid: true,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
// ComponentFilterDisplayName
|
|
41
|
+
type: 2,
|
|
42
|
+
value: 'InternalStdoutContext',
|
|
43
|
+
isEnabled: true,
|
|
44
|
+
isValid: true,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
// ComponentFilterDisplayName
|
|
48
|
+
type: 2,
|
|
49
|
+
value: 'InternalStderrContext',
|
|
50
|
+
isEnabled: true,
|
|
51
|
+
isValid: true,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
// ComponentFilterDisplayName
|
|
55
|
+
type: 2,
|
|
56
|
+
value: 'InternalStdinContext',
|
|
57
|
+
isEnabled: true,
|
|
58
|
+
isValid: true,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
// ComponentFilterDisplayName
|
|
62
|
+
type: 2,
|
|
63
|
+
value: 'InternalFocusContext',
|
|
64
|
+
isEnabled: true,
|
|
65
|
+
isValid: true,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
/* eslint-disable import/order */
|
|
70
|
+
// eslint-disable-next-line import/no-unassigned-import
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
72
|
+
devtools.initialize();
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
74
|
+
devtools.connectToDevTools();
|
|
75
|
+
//# sourceMappingURL=devtools-7A3EXJhY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devtools-7A3EXJhY.js","sources":["../../../../node_modules/.pnpm/ink@6.5.1_@types+react@19.2.7_react@19.1.0/node_modules/ink/build/devtools-window-polyfill.js","../../../../node_modules/.pnpm/ink@6.5.1_@types+react@19.2.7_react@19.1.0/node_modules/ink/build/devtools.js"],"sourcesContent":["// Ignoring missing types error to avoid adding another dependency for this hack to work\nimport ws from 'ws';\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nconst customGlobal = global;\n// These things must exist before importing `react-devtools-core`\n// eslint-disable-next-line n/no-unsupported-features/node-builtins\ncustomGlobal.WebSocket ||= ws;\ncustomGlobal.window ||= global;\ncustomGlobal.self ||= global;\n// Filter out Ink's internal components from devtools for a cleaner view.\n// Also, ince `react-devtools-shared` package isn't published on npm, we can't\n// use its types, that's why there are hard-coded values in `type` fields below.\n// See https://github.com/facebook/react/blob/edf6eac8a181860fd8a2d076a43806f1237495a1/packages/react-devtools-shared/src/types.js#L24\ncustomGlobal.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = [\n {\n // ComponentFilterElementType\n type: 1,\n // ElementTypeHostComponent\n value: 7,\n isEnabled: true,\n },\n {\n // ComponentFilterDisplayName\n type: 2,\n value: 'InternalApp',\n isEnabled: true,\n isValid: true,\n },\n {\n // ComponentFilterDisplayName\n type: 2,\n value: 'InternalAppContext',\n isEnabled: true,\n isValid: true,\n },\n {\n // ComponentFilterDisplayName\n type: 2,\n value: 'InternalStdoutContext',\n isEnabled: true,\n isValid: true,\n },\n {\n // ComponentFilterDisplayName\n type: 2,\n value: 'InternalStderrContext',\n isEnabled: true,\n isValid: true,\n },\n {\n // ComponentFilterDisplayName\n type: 2,\n value: 'InternalStdinContext',\n isEnabled: true,\n isValid: true,\n },\n {\n // ComponentFilterDisplayName\n type: 2,\n value: 'InternalFocusContext',\n isEnabled: true,\n isValid: true,\n },\n];\n//# sourceMappingURL=devtools-window-polyfill.js.map","/* eslint-disable import/order */\n// eslint-disable-next-line import/no-unassigned-import\nimport './devtools-window-polyfill.js';\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport devtools from 'react-devtools-core';\n// eslint-disable-next-line @typescript-eslint/no-unsafe-call\ndevtools.initialize();\n// eslint-disable-next-line @typescript-eslint/no-unsafe-call\ndevtools.connectToDevTools();\n//# sourceMappingURL=devtools.js.map"],"names":["ws"],"mappings":";;;;AAAA;AAEA;AACA,MAAM,YAAY,GAAG,MAAM;AAC3B;AACA;AACA,YAAY,CAAC,SAAS,KAAKA,SAAE;AAC7B,YAAY,CAAC,MAAM,KAAK,MAAM;AAC9B,YAAY,CAAC,IAAI,KAAK,MAAM;AAC5B;AACA;AACA;AACA;AACA,YAAY,CAAC,MAAM,CAAC,oCAAoC,GAAG;AAC3D,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf;AACA,QAAQ,KAAK,EAAE,CAAC;AAChB,QAAQ,SAAS,EAAE,IAAI;AACvB,KAAK;AACL,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,KAAK,EAAE,aAAa;AAC5B,QAAQ,SAAS,EAAE,IAAI;AACvB,QAAQ,OAAO,EAAE,IAAI;AACrB,KAAK;AACL,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,KAAK,EAAE,oBAAoB;AACnC,QAAQ,SAAS,EAAE,IAAI;AACvB,QAAQ,OAAO,EAAE,IAAI;AACrB,KAAK;AACL,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,KAAK,EAAE,uBAAuB;AACtC,QAAQ,SAAS,EAAE,IAAI;AACvB,QAAQ,OAAO,EAAE,IAAI;AACrB,KAAK;AACL,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,KAAK,EAAE,uBAAuB;AACtC,QAAQ,SAAS,EAAE,IAAI;AACvB,QAAQ,OAAO,EAAE,IAAI;AACrB,KAAK;AACL,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,KAAK,EAAE,sBAAsB;AACrC,QAAQ,SAAS,EAAE,IAAI;AACvB,QAAQ,OAAO,EAAE,IAAI;AACrB,KAAK;AACL,IAAI;AACJ;AACA,QAAQ,IAAI,EAAE,CAAC;AACf,QAAQ,KAAK,EAAE,sBAAsB;AACrC,QAAQ,SAAS,EAAE,IAAI;AACvB,QAAQ,OAAO,EAAE,IAAI;AACrB,KAAK;AACL,CAAC;;AC/DD;AACA;AAKA;AACA,QAAQ,CAAC,UAAU,EAAE;AACrB;AACA,QAAQ,CAAC,iBAAiB,EAAE","x_google_ignoreList":[0,1]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// OpenBuilder CLI - Built with Rollup
|
|
2
|
+
import { r as reactExports, u as useInput, R as React, T as Text } from './theme-DOjeB8BU.js';
|
|
3
|
+
import 'node:stream';
|
|
4
|
+
import 'node:process';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import 'node:events';
|
|
7
|
+
|
|
8
|
+
function TextInput({ value: originalValue, placeholder = '', focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit, }) {
|
|
9
|
+
const [state, setState] = reactExports.useState({
|
|
10
|
+
cursorOffset: (originalValue || '').length,
|
|
11
|
+
cursorWidth: 0,
|
|
12
|
+
});
|
|
13
|
+
const { cursorOffset, cursorWidth } = state;
|
|
14
|
+
reactExports.useEffect(() => {
|
|
15
|
+
setState(previousState => {
|
|
16
|
+
if (!focus || !showCursor) {
|
|
17
|
+
return previousState;
|
|
18
|
+
}
|
|
19
|
+
const newValue = originalValue || '';
|
|
20
|
+
if (previousState.cursorOffset > newValue.length - 1) {
|
|
21
|
+
return {
|
|
22
|
+
cursorOffset: newValue.length,
|
|
23
|
+
cursorWidth: 0,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return previousState;
|
|
27
|
+
});
|
|
28
|
+
}, [originalValue, focus, showCursor]);
|
|
29
|
+
const cursorActualWidth = highlightPastedText ? cursorWidth : 0;
|
|
30
|
+
const value = mask ? mask.repeat(originalValue.length) : originalValue;
|
|
31
|
+
let renderedValue = value;
|
|
32
|
+
let renderedPlaceholder = placeholder ? chalk.grey(placeholder) : undefined;
|
|
33
|
+
// Fake mouse cursor, because it's too inconvenient to deal with actual cursor and ansi escapes
|
|
34
|
+
if (showCursor && focus) {
|
|
35
|
+
renderedPlaceholder =
|
|
36
|
+
placeholder.length > 0
|
|
37
|
+
? chalk.inverse(placeholder[0]) + chalk.grey(placeholder.slice(1))
|
|
38
|
+
: chalk.inverse(' ');
|
|
39
|
+
renderedValue = value.length > 0 ? '' : chalk.inverse(' ');
|
|
40
|
+
let i = 0;
|
|
41
|
+
for (const char of value) {
|
|
42
|
+
renderedValue +=
|
|
43
|
+
i >= cursorOffset - cursorActualWidth && i <= cursorOffset
|
|
44
|
+
? chalk.inverse(char)
|
|
45
|
+
: char;
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
if (value.length > 0 && cursorOffset === value.length) {
|
|
49
|
+
renderedValue += chalk.inverse(' ');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
useInput((input, key) => {
|
|
53
|
+
if (key.upArrow ||
|
|
54
|
+
key.downArrow ||
|
|
55
|
+
(key.ctrl && input === 'c') ||
|
|
56
|
+
key.tab ||
|
|
57
|
+
(key.shift && key.tab)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (key.return) {
|
|
61
|
+
if (onSubmit) {
|
|
62
|
+
onSubmit(originalValue);
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
let nextCursorOffset = cursorOffset;
|
|
67
|
+
let nextValue = originalValue;
|
|
68
|
+
let nextCursorWidth = 0;
|
|
69
|
+
if (key.leftArrow) {
|
|
70
|
+
if (showCursor) {
|
|
71
|
+
nextCursorOffset--;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (key.rightArrow) {
|
|
75
|
+
if (showCursor) {
|
|
76
|
+
nextCursorOffset++;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (key.backspace || key.delete) {
|
|
80
|
+
if (cursorOffset > 0) {
|
|
81
|
+
nextValue =
|
|
82
|
+
originalValue.slice(0, cursorOffset - 1) +
|
|
83
|
+
originalValue.slice(cursorOffset, originalValue.length);
|
|
84
|
+
nextCursorOffset--;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
nextValue =
|
|
89
|
+
originalValue.slice(0, cursorOffset) +
|
|
90
|
+
input +
|
|
91
|
+
originalValue.slice(cursorOffset, originalValue.length);
|
|
92
|
+
nextCursorOffset += input.length;
|
|
93
|
+
if (input.length > 1) {
|
|
94
|
+
nextCursorWidth = input.length;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (cursorOffset < 0) {
|
|
98
|
+
nextCursorOffset = 0;
|
|
99
|
+
}
|
|
100
|
+
if (cursorOffset > originalValue.length) {
|
|
101
|
+
nextCursorOffset = originalValue.length;
|
|
102
|
+
}
|
|
103
|
+
setState({
|
|
104
|
+
cursorOffset: nextCursorOffset,
|
|
105
|
+
cursorWidth: nextCursorWidth,
|
|
106
|
+
});
|
|
107
|
+
if (nextValue !== originalValue) {
|
|
108
|
+
onChange(nextValue);
|
|
109
|
+
}
|
|
110
|
+
}, { isActive: focus });
|
|
111
|
+
return (React.createElement(Text, null, placeholder
|
|
112
|
+
? value.length > 0
|
|
113
|
+
? renderedValue
|
|
114
|
+
: renderedPlaceholder
|
|
115
|
+
: renderedValue));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { TextInput as T };
|
|
119
|
+
//# sourceMappingURL=index-ZNRLfdj5.js.map
|