@openbuilder/cli 0.31.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1053 -0
- package/bin/openbuilder.js +31 -0
- package/dist/chunks/Banner-D4tqKfzA.js +113 -0
- package/dist/chunks/Banner-D4tqKfzA.js.map +1 -0
- package/dist/chunks/auto-update-Dj3lWPWO.js +350 -0
- package/dist/chunks/auto-update-Dj3lWPWO.js.map +1 -0
- package/dist/chunks/build-D0qYqIq0.js +116 -0
- package/dist/chunks/build-D0qYqIq0.js.map +1 -0
- package/dist/chunks/cleanup-qVTsA3tk.js +141 -0
- package/dist/chunks/cleanup-qVTsA3tk.js.map +1 -0
- package/dist/chunks/cli-error-BjQwvWtK.js +140 -0
- package/dist/chunks/cli-error-BjQwvWtK.js.map +1 -0
- package/dist/chunks/config-BGP1jZJ4.js +167 -0
- package/dist/chunks/config-BGP1jZJ4.js.map +1 -0
- package/dist/chunks/config-manager-BkbjtN-H.js +133 -0
- package/dist/chunks/config-manager-BkbjtN-H.js.map +1 -0
- package/dist/chunks/database-BvAbD4sP.js +68 -0
- package/dist/chunks/database-BvAbD4sP.js.map +1 -0
- package/dist/chunks/database-setup-BYjIRAmT.js +253 -0
- package/dist/chunks/database-setup-BYjIRAmT.js.map +1 -0
- package/dist/chunks/exports-ij9sv4UM.js +7793 -0
- package/dist/chunks/exports-ij9sv4UM.js.map +1 -0
- package/dist/chunks/init-CZoN6soU.js +468 -0
- package/dist/chunks/init-CZoN6soU.js.map +1 -0
- package/dist/chunks/init-tui-BNzk_7Yx.js +1127 -0
- package/dist/chunks/init-tui-BNzk_7Yx.js.map +1 -0
- package/dist/chunks/logger-ZpJi7chw.js +38 -0
- package/dist/chunks/logger-ZpJi7chw.js.map +1 -0
- package/dist/chunks/main-tui-Cq1hLCx-.js +644 -0
- package/dist/chunks/main-tui-Cq1hLCx-.js.map +1 -0
- package/dist/chunks/manager-CvGX9qqe.js +1161 -0
- package/dist/chunks/manager-CvGX9qqe.js.map +1 -0
- package/dist/chunks/port-allocator-BRFzgH9b.js +749 -0
- package/dist/chunks/port-allocator-BRFzgH9b.js.map +1 -0
- package/dist/chunks/process-killer-CaUL7Kpl.js +87 -0
- package/dist/chunks/process-killer-CaUL7Kpl.js.map +1 -0
- package/dist/chunks/prompts-1QbE_bRr.js +128 -0
- package/dist/chunks/prompts-1QbE_bRr.js.map +1 -0
- package/dist/chunks/repo-cloner-CpOQjFSo.js +219 -0
- package/dist/chunks/repo-cloner-CpOQjFSo.js.map +1 -0
- package/dist/chunks/repo-detector-B_oj696o.js +66 -0
- package/dist/chunks/repo-detector-B_oj696o.js.map +1 -0
- package/dist/chunks/run-D23hg4xy.js +630 -0
- package/dist/chunks/run-D23hg4xy.js.map +1 -0
- package/dist/chunks/runner-logger-instance-nDWv2h2T.js +899 -0
- package/dist/chunks/runner-logger-instance-nDWv2h2T.js.map +1 -0
- package/dist/chunks/spinner-BJL9zWAJ.js +53 -0
- package/dist/chunks/spinner-BJL9zWAJ.js.map +1 -0
- package/dist/chunks/start-BygPCbvw.js +1708 -0
- package/dist/chunks/start-BygPCbvw.js.map +1 -0
- package/dist/chunks/start-traditional-uoLZXdxm.js +255 -0
- package/dist/chunks/start-traditional-uoLZXdxm.js.map +1 -0
- package/dist/chunks/status-cS8YwtUx.js +97 -0
- package/dist/chunks/status-cS8YwtUx.js.map +1 -0
- package/dist/chunks/theme-DhorI2Hb.js +44 -0
- package/dist/chunks/theme-DhorI2Hb.js.map +1 -0
- package/dist/chunks/upgrade-CT6w0lKp.js +323 -0
- package/dist/chunks/upgrade-CT6w0lKp.js.map +1 -0
- package/dist/chunks/useBuildState-CdBSu9y_.js +331 -0
- package/dist/chunks/useBuildState-CdBSu9y_.js.map +1 -0
- package/dist/cli/index.js +694 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.js +14358 -0
- package/dist/index.js.map +1 -0
- package/dist/instrument.js +64226 -0
- package/dist/instrument.js.map +1 -0
- package/dist/templates.json +295 -0
- package/package.json +98 -0
- package/scripts/install-vendor-deps.js +34 -0
- package/scripts/install-vendor.js +167 -0
- package/scripts/prepare-release.js +71 -0
- package/templates/config.template.json +18 -0
- package/templates.json +295 -0
- 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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, resolve } from 'path';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
// Paths relative to this bin script
|
|
11
|
+
const instrumentPath = resolve(__dirname, '../dist/instrument.js');
|
|
12
|
+
const cliPath = resolve(__dirname, '../dist/cli/index.js');
|
|
13
|
+
|
|
14
|
+
// Spawn node with --import flag for proper ESM instrumentation
|
|
15
|
+
const child = spawn(
|
|
16
|
+
process.execPath, // Use the same Node.js binary
|
|
17
|
+
['--import', instrumentPath, cliPath, ...process.argv.slice(2)],
|
|
18
|
+
{
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
env: process.env,
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
child.on('close', (code) => {
|
|
25
|
+
process.exit(code ?? 0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
child.on('error', (err) => {
|
|
29
|
+
console.error('Failed to start CLI:', err);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// OpenBuilder CLI - Built with Rollup
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { join, dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { Box, Text } from 'ink';
|
|
8
|
+
import { c as colors } from './theme-DhorI2Hb.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Version and git commit info utilities
|
|
12
|
+
*/
|
|
13
|
+
const __filename$1 = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname$1 = dirname(__filename$1);
|
|
15
|
+
/**
|
|
16
|
+
* Find the package root directory (apps/runner).
|
|
17
|
+
* Works in both development (src/cli/utils/) and production (dist/cli/utils/) modes.
|
|
18
|
+
*/
|
|
19
|
+
function findPackageRoot() {
|
|
20
|
+
// Try multiple possible locations
|
|
21
|
+
const possiblePaths = [
|
|
22
|
+
// Development: src/cli/utils/ -> apps/runner (3 levels up)
|
|
23
|
+
join(__dirname$1, '..', '..', '..'),
|
|
24
|
+
// Production from dist/cli/utils/: -> apps/runner (3 levels up, same structure)
|
|
25
|
+
join(__dirname$1, '..', '..', '..'),
|
|
26
|
+
];
|
|
27
|
+
for (const path of possiblePaths) {
|
|
28
|
+
const packageJsonPath = join(path, 'package.json');
|
|
29
|
+
if (existsSync(packageJsonPath)) {
|
|
30
|
+
try {
|
|
31
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
32
|
+
// Verify this is the runner package
|
|
33
|
+
if (pkg.name === '@openbuilder/cli') {
|
|
34
|
+
return path;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Continue to next path
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Fallback to the standard path
|
|
43
|
+
return join(__dirname$1, '..', '..', '..');
|
|
44
|
+
}
|
|
45
|
+
// Cache the package root
|
|
46
|
+
const packageRoot = findPackageRoot();
|
|
47
|
+
/**
|
|
48
|
+
* Get the package version from package.json
|
|
49
|
+
*/
|
|
50
|
+
function getPackageVersion() {
|
|
51
|
+
try {
|
|
52
|
+
const packageJsonPath = join(packageRoot, 'package.json');
|
|
53
|
+
if (existsSync(packageJsonPath)) {
|
|
54
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
55
|
+
return packageJson.version || '0.0.0';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Ignore errors
|
|
60
|
+
}
|
|
61
|
+
return '0.0.0';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the short git commit hash
|
|
65
|
+
*/
|
|
66
|
+
function getGitCommit() {
|
|
67
|
+
try {
|
|
68
|
+
// Try to get commit from git command
|
|
69
|
+
const commit = execSync('git rev-parse --short HEAD', {
|
|
70
|
+
cwd: packageRoot,
|
|
71
|
+
encoding: 'utf-8',
|
|
72
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
73
|
+
}).trim();
|
|
74
|
+
return commit || null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Git not available or not a git repo
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get all version info
|
|
83
|
+
*/
|
|
84
|
+
function getVersionInfo() {
|
|
85
|
+
const version = getPackageVersion();
|
|
86
|
+
const commit = getGitCommit();
|
|
87
|
+
return {
|
|
88
|
+
version,
|
|
89
|
+
commit,
|
|
90
|
+
display: commit ? `v${version} (${commit})` : `v${version}`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* ASCII art banner component - centered with cyan/purple gradient
|
|
96
|
+
* Each line is padded to exactly the same width for perfect alignment
|
|
97
|
+
*/
|
|
98
|
+
function Banner() {
|
|
99
|
+
// Full banner lines - OPEN in cyan, BUILDER in purple
|
|
100
|
+
// All lines padded to same total width for consistent centering
|
|
101
|
+
const lines = [
|
|
102
|
+
{ open: ' ██████╗ ██████╗ ███████╗███╗ ██╗', builder: '██████╗ ██╗ ██╗██╗██╗ ██████╗ ███████╗██████╗ ' },
|
|
103
|
+
{ open: '██╔═══██╗██╔══██╗██╔════╝████╗ ██║', builder: '██╔══██╗██║ ██║██║██║ ██╔══██╗██╔════╝██╔══██╗' },
|
|
104
|
+
{ open: '██║ ██║██████╔╝█████╗ ██╔██╗ ██║', builder: '██████╔╝██║ ██║██║██║ ██║ ██║█████╗ ██████╔╝' },
|
|
105
|
+
{ open: '██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║', builder: '██╔══██╗██║ ██║██║██║ ██║ ██║██╔══╝ ██╔══██╗' },
|
|
106
|
+
{ open: '╚██████╔╝██║ ███████╗██║ ╚████║', builder: '██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║' },
|
|
107
|
+
{ open: ' ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝', builder: '╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝' },
|
|
108
|
+
];
|
|
109
|
+
return (jsx(Box, { flexDirection: "column", alignItems: "center", children: lines.map((line, index) => (jsxs(Box, { children: [jsx(Text, { color: colors.cyan, children: line.open }), jsx(Text, { color: colors.brightPurple, children: line.builder })] }, index))) }));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { Banner as B, getVersionInfo as g };
|
|
113
|
+
//# sourceMappingURL=Banner-D4tqKfzA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Banner-D4tqKfzA.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,GAAA,CAAC,GAAG,EAAA,EAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAC,QAAQ,EAAA,QAAA,EAC5C,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MACrBC,IAAA,CAAC,GAAG,EAAA,EAAA,QAAA,EAAA,CACFD,GAAA,CAAC,IAAI,EAAA,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAA,QAAA,EAAG,IAAI,CAAC,IAAI,EAAA,CAAQ,EAC5CA,GAAA,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,350 @@
|
|
|
1
|
+
// OpenBuilder CLI - Built with Rollup
|
|
2
|
+
import { spawnSync, execSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { homedir } from 'node:os';
|
|
6
|
+
import pc from 'picocolors';
|
|
7
|
+
import { c as configManager } from './config-manager-BkbjtN-H.js';
|
|
8
|
+
import 'conf';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Auto-update utility for OpenBuilder CLI
|
|
12
|
+
*
|
|
13
|
+
* Checks GitHub Releases for newer versions and automatically
|
|
14
|
+
* updates both:
|
|
15
|
+
* 1. The CLI itself (globally installed npm package)
|
|
16
|
+
* 2. The app/monorepo (local installation that runs the web app)
|
|
17
|
+
*/
|
|
18
|
+
// GitHub API endpoint for releases
|
|
19
|
+
const GITHUB_RELEASES_URL = 'https://api.github.com/repos/codyde/openbuilder/releases/latest';
|
|
20
|
+
// Install command for CLI
|
|
21
|
+
const INSTALL_COMMAND = 'curl -fsSL https://openbuilder.app/install | bash';
|
|
22
|
+
// Cache settings
|
|
23
|
+
const CACHE_DIR = join(homedir(), '.config', 'openbuilder');
|
|
24
|
+
const CACHE_FILE = join(CACHE_DIR, 'update-cache.json');
|
|
25
|
+
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
26
|
+
/**
|
|
27
|
+
* Read the update cache file
|
|
28
|
+
*/
|
|
29
|
+
function readUpdateCache() {
|
|
30
|
+
try {
|
|
31
|
+
if (existsSync(CACHE_FILE)) {
|
|
32
|
+
const content = readFileSync(CACHE_FILE, 'utf-8');
|
|
33
|
+
return JSON.parse(content);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Cache read failed, that's fine
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Write to the update cache file
|
|
43
|
+
*/
|
|
44
|
+
function saveUpdateCache(cache) {
|
|
45
|
+
try {
|
|
46
|
+
if (!existsSync(CACHE_DIR)) {
|
|
47
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Cache write failed, that's fine
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Fetch the latest release version from GitHub
|
|
57
|
+
* Returns version string (e.g., "0.28.0") or null on failure
|
|
58
|
+
*/
|
|
59
|
+
async function fetchLatestVersion() {
|
|
60
|
+
try {
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeout = setTimeout(() => controller.abort(), 5000); // 5s timeout
|
|
63
|
+
const response = await fetch(GITHUB_RELEASES_URL, {
|
|
64
|
+
headers: {
|
|
65
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
66
|
+
'User-Agent': 'OpenBuilder-CLI-AutoUpdate',
|
|
67
|
+
},
|
|
68
|
+
signal: controller.signal,
|
|
69
|
+
});
|
|
70
|
+
clearTimeout(timeout);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const data = await response.json();
|
|
75
|
+
// Remove 'v' prefix if present (e.g., "v0.28.0" -> "0.28.0")
|
|
76
|
+
return data.tag_name.replace(/^v/, '');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Network error, timeout, or parse error
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compare two semver versions
|
|
85
|
+
* Returns true if version1 < version2 (i.e., version2 is newer)
|
|
86
|
+
*/
|
|
87
|
+
function isNewerVersion(current, latest) {
|
|
88
|
+
const parseVersion = (v) => {
|
|
89
|
+
const parts = v.replace(/^v/, '').split('.').map(n => parseInt(n, 10) || 0);
|
|
90
|
+
return { major: parts[0] || 0, minor: parts[1] || 0, patch: parts[2] || 0 };
|
|
91
|
+
};
|
|
92
|
+
const c = parseVersion(current);
|
|
93
|
+
const l = parseVersion(latest);
|
|
94
|
+
if (l.major > c.major)
|
|
95
|
+
return true;
|
|
96
|
+
if (l.major < c.major)
|
|
97
|
+
return false;
|
|
98
|
+
if (l.minor > c.minor)
|
|
99
|
+
return true;
|
|
100
|
+
if (l.minor < c.minor)
|
|
101
|
+
return false;
|
|
102
|
+
return l.patch > c.patch;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Perform the CLI update by running the install script
|
|
106
|
+
*/
|
|
107
|
+
function performCLIUpdate() {
|
|
108
|
+
try {
|
|
109
|
+
// Run the install command with quiet mode to avoid banner spam
|
|
110
|
+
execSync(INSTALL_COMMAND, {
|
|
111
|
+
stdio: 'inherit',
|
|
112
|
+
shell: '/bin/bash',
|
|
113
|
+
env: {
|
|
114
|
+
...process.env,
|
|
115
|
+
OPENBUILDER_QUIET_INSTALL: '1', // Suppress banner in installer
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if the app/monorepo needs upgrading and perform the upgrade
|
|
126
|
+
* This updates the local OpenBuilder installation that runs the web app
|
|
127
|
+
*/
|
|
128
|
+
function performAppUpgrade() {
|
|
129
|
+
const config = configManager.get();
|
|
130
|
+
const monorepoPath = config.monorepoPath;
|
|
131
|
+
// No monorepo configured, skip app upgrade
|
|
132
|
+
if (!monorepoPath || !existsSync(monorepoPath)) {
|
|
133
|
+
return true; // Not an error, just nothing to upgrade
|
|
134
|
+
}
|
|
135
|
+
console.log();
|
|
136
|
+
console.log(` ${pc.cyan('⬆')} ${pc.bold('Upgrading app installation...')}`);
|
|
137
|
+
console.log(` ${pc.dim(monorepoPath)}`);
|
|
138
|
+
console.log();
|
|
139
|
+
try {
|
|
140
|
+
// Run openbuilder upgrade --force to upgrade the monorepo
|
|
141
|
+
// Use --force to skip prompts since we're in auto-update mode
|
|
142
|
+
const result = spawnSync('openbuilder', ['upgrade', '--force'], {
|
|
143
|
+
stdio: 'inherit',
|
|
144
|
+
env: {
|
|
145
|
+
...process.env,
|
|
146
|
+
OPENBUILDER_SKIP_UPDATE_CHECK: '1', // Don't re-check for CLI updates
|
|
147
|
+
},
|
|
148
|
+
shell: true,
|
|
149
|
+
});
|
|
150
|
+
return result.status === 0;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Re-launch the CLI with original arguments after update
|
|
158
|
+
*/
|
|
159
|
+
function relaunchCLI() {
|
|
160
|
+
const args = process.argv.slice(2);
|
|
161
|
+
try {
|
|
162
|
+
// Get the actual path to openbuilder to avoid shell hash caching issues
|
|
163
|
+
// This ensures we run the newly installed version, not a cached path
|
|
164
|
+
let openbuilderPath = 'openbuilder';
|
|
165
|
+
try {
|
|
166
|
+
// Use 'command -v' to get the actual path, bypassing shell hash
|
|
167
|
+
openbuilderPath = execSync('command -v openbuilder', { encoding: 'utf-8' }).trim();
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Fallback to just 'openbuilder' if command -v fails
|
|
171
|
+
}
|
|
172
|
+
// Use spawnSync with the explicit path to ensure we get the new version
|
|
173
|
+
const result = spawnSync(openbuilderPath, args, {
|
|
174
|
+
stdio: 'inherit',
|
|
175
|
+
env: {
|
|
176
|
+
...process.env,
|
|
177
|
+
OPENBUILDER_SKIP_UPDATE_CHECK: '1', // Prevent update loop
|
|
178
|
+
OPENBUILDER_SKIP_BANNER: '1', // Suppress banner after restart (already shown before update)
|
|
179
|
+
},
|
|
180
|
+
// Don't use shell: true to avoid shell hash caching
|
|
181
|
+
});
|
|
182
|
+
// Exit with the same code as the relaunched process
|
|
183
|
+
process.exit(result.status ?? 0);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// If relaunch fails, just exit - user can run command again
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Main auto-update check function
|
|
192
|
+
* Call this early in CLI startup
|
|
193
|
+
*
|
|
194
|
+
* Updates both:
|
|
195
|
+
* 1. The CLI itself (globally installed)
|
|
196
|
+
* 2. The app/monorepo (if configured)
|
|
197
|
+
*
|
|
198
|
+
* @param currentVersion - Current CLI version from package.json
|
|
199
|
+
* @returns true if update was performed and CLI should exit
|
|
200
|
+
*/
|
|
201
|
+
async function checkAndAutoUpdate(currentVersion) {
|
|
202
|
+
// Skip if update check is disabled via env var
|
|
203
|
+
if (process.env.OPENBUILDER_NO_UPDATE === '1' || process.env.OPENBUILDER_SKIP_UPDATE_CHECK === '1') {
|
|
204
|
+
// But check if we have a pending app upgrade from a previous CLI update
|
|
205
|
+
const cache = readUpdateCache();
|
|
206
|
+
if (cache?.pendingAppUpgrade) {
|
|
207
|
+
console.log();
|
|
208
|
+
console.log(` ${pc.cyan('⬆')} ${pc.bold('Completing app upgrade...')}`);
|
|
209
|
+
const appSuccess = performAppUpgrade();
|
|
210
|
+
if (appSuccess) {
|
|
211
|
+
// Clear the pending flag
|
|
212
|
+
saveUpdateCache({ ...cache, pendingAppUpgrade: false });
|
|
213
|
+
console.log(` ${pc.green('✓')} ${pc.bold('App upgrade complete!')}`);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
console.log(` ${pc.yellow('⚠')} ${pc.dim('App upgrade failed. Run manually:')} ${pc.cyan('openbuilder upgrade')}`);
|
|
217
|
+
}
|
|
218
|
+
console.log();
|
|
219
|
+
}
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
// Skip if disabled in config
|
|
223
|
+
const config = configManager.get();
|
|
224
|
+
if (config.autoUpdate === false) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
let latestVersion = null;
|
|
228
|
+
// Check cache first to avoid hitting GitHub API too often
|
|
229
|
+
const cache = readUpdateCache();
|
|
230
|
+
const now = Date.now();
|
|
231
|
+
if (cache && (now - cache.lastCheck) < CACHE_TTL_MS) {
|
|
232
|
+
// Use cached version
|
|
233
|
+
latestVersion = cache.latestVersion;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// Fetch from GitHub (with timeout)
|
|
237
|
+
latestVersion = await fetchLatestVersion();
|
|
238
|
+
if (latestVersion) {
|
|
239
|
+
// Update cache
|
|
240
|
+
saveUpdateCache({
|
|
241
|
+
lastCheck: now,
|
|
242
|
+
latestVersion,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
else if (cache) {
|
|
246
|
+
// Fetch failed, use stale cache
|
|
247
|
+
latestVersion = cache.latestVersion;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// If we couldn't determine latest version, skip update
|
|
251
|
+
if (!latestVersion) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
// Check if update is needed
|
|
255
|
+
if (!isNewerVersion(currentVersion, latestVersion)) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
// Update available! Show message and perform update
|
|
259
|
+
console.log();
|
|
260
|
+
console.log(` ${pc.cyan('⬆')} ${pc.bold('Update available:')} ${pc.dim(currentVersion)} → ${pc.green(latestVersion)}`);
|
|
261
|
+
console.log();
|
|
262
|
+
// Step 1: Update the CLI
|
|
263
|
+
console.log(` ${pc.dim('Step 1/2:')} Updating CLI...`);
|
|
264
|
+
const cliSuccess = performCLIUpdate();
|
|
265
|
+
if (!cliSuccess) {
|
|
266
|
+
// CLI update failed, continue with current version
|
|
267
|
+
console.log();
|
|
268
|
+
console.log(` ${pc.yellow('⚠')} ${pc.dim('CLI update failed. Continuing with current version.')}`);
|
|
269
|
+
console.log(` ${pc.dim('You can manually update with:')} ${pc.cyan('curl -fsSL https://openbuilder.app/install | bash')}`);
|
|
270
|
+
console.log();
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
console.log(` ${pc.green('✓')} CLI updated to ${pc.green(latestVersion)}`);
|
|
274
|
+
// Step 2: Check if we need to upgrade the app
|
|
275
|
+
const monorepoPath = config.monorepoPath;
|
|
276
|
+
const hasMonorepo = monorepoPath && existsSync(monorepoPath);
|
|
277
|
+
if (hasMonorepo) {
|
|
278
|
+
// Mark that we need to upgrade the app after CLI restart
|
|
279
|
+
// The new CLI version will handle the app upgrade
|
|
280
|
+
saveUpdateCache({
|
|
281
|
+
lastCheck: now,
|
|
282
|
+
latestVersion,
|
|
283
|
+
pendingAppUpgrade: true,
|
|
284
|
+
});
|
|
285
|
+
console.log();
|
|
286
|
+
console.log(` ${pc.dim('Step 2/2:')} App upgrade will continue after restart...`);
|
|
287
|
+
}
|
|
288
|
+
console.log();
|
|
289
|
+
console.log(` ${pc.green('✓')} ${pc.bold('CLI update complete!')} Restarting...`);
|
|
290
|
+
console.log();
|
|
291
|
+
// Relaunch CLI with original args
|
|
292
|
+
// The new CLI will pick up the pendingAppUpgrade flag and complete step 2
|
|
293
|
+
relaunchCLI();
|
|
294
|
+
return true; // CLI will exit via relaunchCLI
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Check for updates without auto-updating (for TUI modes)
|
|
298
|
+
* Returns version info that can be displayed in the TUI
|
|
299
|
+
*
|
|
300
|
+
* @param currentVersion - Current CLI version from package.json
|
|
301
|
+
* @returns Update info or null if no update available
|
|
302
|
+
*/
|
|
303
|
+
async function checkForUpdate(currentVersion) {
|
|
304
|
+
// Skip if update check is disabled via env var
|
|
305
|
+
if (process.env.OPENBUILDER_NO_UPDATE === '1' || process.env.OPENBUILDER_SKIP_UPDATE_CHECK === '1') {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
// Skip if disabled in config
|
|
309
|
+
const config = configManager.get();
|
|
310
|
+
if (config.autoUpdate === false) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
let latestVersion = null;
|
|
314
|
+
// Check cache first to avoid hitting GitHub API too often
|
|
315
|
+
const cache = readUpdateCache();
|
|
316
|
+
const now = Date.now();
|
|
317
|
+
if (cache && (now - cache.lastCheck) < CACHE_TTL_MS) {
|
|
318
|
+
// Use cached version
|
|
319
|
+
latestVersion = cache.latestVersion;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Fetch from GitHub (with timeout)
|
|
323
|
+
latestVersion = await fetchLatestVersion();
|
|
324
|
+
if (latestVersion) {
|
|
325
|
+
// Update cache
|
|
326
|
+
saveUpdateCache({
|
|
327
|
+
lastCheck: now,
|
|
328
|
+
latestVersion,
|
|
329
|
+
pendingAppUpgrade: cache?.pendingAppUpgrade,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
else if (cache) {
|
|
333
|
+
// Fetch failed, use stale cache
|
|
334
|
+
latestVersion = cache.latestVersion;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// If we couldn't determine latest version, return null
|
|
338
|
+
if (!latestVersion) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
const updateAvailable = isNewerVersion(currentVersion, latestVersion);
|
|
342
|
+
return {
|
|
343
|
+
currentVersion,
|
|
344
|
+
latestVersion,
|
|
345
|
+
updateAvailable,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export { checkAndAutoUpdate, checkForUpdate };
|
|
350
|
+
//# sourceMappingURL=auto-update-Dj3lWPWO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update-Dj3lWPWO.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.app/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 // Step 1: Update the CLI\n console.log(` ${pc.dim('Step 1/2:')} 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.app/install | bash')}`);\n console.log();\n return false;\n }\n\n console.log(` ${pc.green('✓')} CLI updated to ${pc.green(latestVersion)}`);\n \n // Step 2: 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 // The new CLI version will handle the app upgrade\n saveUpdateCache({\n lastCheck: now,\n latestVersion,\n pendingAppUpgrade: true,\n });\n \n console.log();\n console.log(` ${pc.dim('Step 2/2:')} App upgrade will continue after restart...`);\n }\n\n console.log();\n console.log(` ${pc.green('✓')} ${pc.bold('CLI update complete!')} Restarting...`);\n console.log();\n \n // Relaunch CLI with original args\n // The new CLI will pick up the pendingAppUpgrade flag and complete step 2\n relaunchCLI();\n \n return true; // CLI will exit via relaunchCLI\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":";;;;;;;;;AAAA;;;;;;;AAOG;AASH;AACA,MAAM,mBAAmB,GAAG,iEAAiE;AAE7F;AACA,MAAM,eAAe,GAAG,mDAAmD;AAE3E;AACA,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC;AAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC;AACvD,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AASpC;;AAEG;AACH,SAAS,eAAe,GAAA;AACtB,IAAA,IAAI;AACF,QAAA,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE;YAC1B,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;AACjD,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5B;IACF;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,OAAO,IAAI;AACb;AAEA;;AAEG;AACH,SAAS,eAAe,CAAC,KAAkB,EAAA;AACzC,IAAA,IAAI;AACF,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;YAC1B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC3C;AACA,QAAA,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D;AAAE,IAAA,MAAM;;IAER;AACF;AAEA;;;AAGG;AACH,eAAe,kBAAkB,GAAA;AAC/B,IAAA,IAAI;AACF,QAAA,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE;AACxC,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;AAE3D,QAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,mBAAmB,EAAE;AAChD,YAAA,OAAO,EAAE;AACP,gBAAA,QAAQ,EAAE,gCAAgC;AAC1C,gBAAA,YAAY,EAAE,4BAA4B;AAC3C,aAAA;YACD,MAAM,EAAE,UAAU,CAAC,MAAM;AAC1B,SAAA,CAAC;QAEF,YAAY,CAAC,OAAO,CAAC;AAErB,QAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;AAChB,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA0B;;QAE1D,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IACxC;AAAE,IAAA,MAAM;;AAEN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;;AAGG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,MAAc,EAAA;AACrD,IAAA,MAAM,YAAY,GAAG,CAAC,CAAS,KAAI;AACjC,QAAA,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC3E,QAAA,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7E,IAAA,CAAC;AAED,IAAA,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC;AAC/B,IAAA,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;AAE9B,IAAA,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AAClC,IAAA,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;AAAE,QAAA,OAAO,KAAK;AACnC,IAAA,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;AAAE,QAAA,OAAO,IAAI;AAClC,IAAA,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;AAAE,QAAA,OAAO,KAAK;AACnC,IAAA,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;AAC1B;AAEA;;AAEG;AACH,SAAS,gBAAgB,GAAA;AACvB,IAAA,IAAI;;QAEF,QAAQ,CAAC,eAAe,EAAE;AACxB,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,KAAK,EAAE,WAAW;AAClB,YAAA,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,yBAAyB,EAAE,GAAG;AAC/B,aAAA;AACF,SAAA,CAAC;AACF,QAAA,OAAO,IAAI;IACb;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACF;AAEA;;;AAGG;AACH,SAAS,iBAAiB,GAAA;AACxB,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE;AAClC,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY;;IAGxC,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE;QAC9C,OAAO,IAAI,CAAC;IACd;IAEA,OAAO,CAAC,GAAG,EAAE;AACb,IAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA,CAAE,CAAC;AAC5E,IAAA,OAAO,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA,CAAE,CAAC;IACxC,OAAO,CAAC,GAAG,EAAE;AAEb,IAAA,IAAI;;;QAGF,MAAM,MAAM,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE;AAC9D,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,6BAA6B,EAAE,GAAG;AACnC,aAAA;AACD,YAAA,KAAK,EAAE,IAAI;AACZ,SAAA,CAAC;AAEF,QAAA,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC;IAC5B;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;IACd;AACF;AAEA;;AAEG;AACH,SAAS,WAAW,GAAA;IAClB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAElC,IAAA,IAAI;;;QAGF,IAAI,eAAe,GAAG,aAAa;AACnC,QAAA,IAAI;;AAEF,YAAA,eAAe,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE;QACpF;AAAE,QAAA,MAAM;;QAER;;AAGA,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE;AAC9C,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,6BAA6B,EAAE,GAAG;gBAClC,uBAAuB,EAAE,GAAG;AAC7B,aAAA;;AAEF,SAAA,CAAC;;QAGF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC;AAAE,IAAA,MAAM;;AAEN,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB;AACF;AAEA;;;;;;;;;;AAUG;AACI,eAAe,kBAAkB,CAAC,cAAsB,EAAA;;AAE7D,IAAA,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,GAAG,EAAE;;AAElG,QAAA,MAAM,KAAK,GAAG,eAAe,EAAE;AAC/B,QAAA,IAAI,KAAK,EAAE,iBAAiB,EAAE;YAC5B,OAAO,CAAC,GAAG,EAAE;AACb,YAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA,CAAE,CAAC;AAExE,YAAA,MAAM,UAAU,GAAG,iBAAiB,EAAE;YAEtC,IAAI,UAAU,EAAE;;gBAEd,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;AACvD,gBAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA,CAAE,CAAC;YACvE;iBAAO;gBACL,OAAO,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA,CAAE,CAAC;YACrH;YACA,OAAO,CAAC,GAAG,EAAE;QACf;AACA,QAAA,OAAO,KAAK;IACd;;AAGA,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE;AAClC,IAAA,IAAI,MAAM,CAAC,UAAU,KAAK,KAAK,EAAE;AAC/B,QAAA,OAAO,KAAK;IACd;IAEA,IAAI,aAAa,GAAkB,IAAI;;AAGvC,IAAA,MAAM,KAAK,GAAG,eAAe,EAAE;AAC/B,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AAEtB,IAAA,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;;AAEnD,QAAA,aAAa,GAAG,KAAK,CAAC,aAAa;IACrC;SAAO;;AAEL,QAAA,aAAa,GAAG,MAAM,kBAAkB,EAAE;QAE1C,IAAI,aAAa,EAAE;;AAEjB,YAAA,eAAe,CAAC;AACd,gBAAA,SAAS,EAAE,GAAG;gBACd,aAAa;AACd,aAAA,CAAC;QACJ;aAAO,IAAI,KAAK,EAAE;;AAEhB,YAAA,aAAa,GAAG,KAAK,CAAC,aAAa;QACrC;IACF;;IAGA,IAAI,CAAC,aAAa,EAAE;AAClB,QAAA,OAAO,KAAK;IACd;;IAGA,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,aAAa,CAAC,EAAE;AAClD,QAAA,OAAO,KAAK;IACd;;IAGA,OAAO,CAAC,GAAG,EAAE;AACb,IAAA,OAAO,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA,GAAA,EAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA,CAAE,CAAC;IACvH,OAAO,CAAC,GAAG,EAAE;;AAGb,IAAA,OAAO,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA,gBAAA,CAAkB,CAAC;AACvD,IAAA,MAAM,UAAU,GAAG,gBAAgB,EAAE;IAErC,IAAI,CAAC,UAAU,EAAE;;QAEf,OAAO,CAAC,GAAG,EAAE;AACb,QAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAA,CAAE,CAAC;AACnG,QAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAA,CAAE,CAAC;QAC3H,OAAO,CAAC,GAAG,EAAE;AACb,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA,gBAAA,EAAmB,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA,CAAE,CAAC;;AAG3E,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY;IACxC,MAAM,WAAW,GAAG,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC;IAE5D,IAAI,WAAW,EAAE;;;AAGf,QAAA,eAAe,CAAC;AACd,YAAA,SAAS,EAAE,GAAG;YACd,aAAa;AACb,YAAA,iBAAiB,EAAE,IAAI;AACxB,SAAA,CAAC;QAEF,OAAO,CAAC,GAAG,EAAE;AACb,QAAA,OAAO,CAAC,GAAG,CAAC,CAAA,EAAA,EAAK,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA,2CAAA,CAA6C,CAAC;IACpF;IAEA,OAAO,CAAC,GAAG,EAAE;AACb,IAAA,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA,cAAA,CAAgB,CAAC;IAClF,OAAO,CAAC,GAAG,EAAE;;;AAIb,IAAA,WAAW,EAAE;IAEb,OAAO,IAAI,CAAC;AACd;AAEA;;;;;;AAMG;AACI,eAAe,cAAc,CAAC,cAAsB,EAAA;;AAMzD,IAAA,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,GAAG,EAAE;AAClG,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE;AAClC,IAAA,IAAI,MAAM,CAAC,UAAU,KAAK,KAAK,EAAE;AAC/B,QAAA,OAAO,IAAI;IACb;IAEA,IAAI,aAAa,GAAkB,IAAI;;AAGvC,IAAA,MAAM,KAAK,GAAG,eAAe,EAAE;AAC/B,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AAEtB,IAAA,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;;AAEnD,QAAA,aAAa,GAAG,KAAK,CAAC,aAAa;IACrC;SAAO;;AAEL,QAAA,aAAa,GAAG,MAAM,kBAAkB,EAAE;QAE1C,IAAI,aAAa,EAAE;;AAEjB,YAAA,eAAe,CAAC;AACd,gBAAA,SAAS,EAAE,GAAG;gBACd,aAAa;gBACb,iBAAiB,EAAE,KAAK,EAAE,iBAAiB;AAC5C,aAAA,CAAC;QACJ;aAAO,IAAI,KAAK,EAAE;;AAEhB,YAAA,aAAa,GAAG,KAAK,CAAC,aAAa;QACrC;IACF;;IAGA,IAAI,CAAC,aAAa,EAAE;AAClB,QAAA,OAAO,IAAI;IACb;IAEA,MAAM,eAAe,GAAG,cAAc,CAAC,cAAc,EAAE,aAAa,CAAC;IAErE,OAAO;QACL,cAAc;QACd,aAAa;QACb,eAAe;KAChB;AACH;;;;"}
|