@hatchway/cli 0.50.53
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 +274 -0
- package/bin/hatchway.js +31 -0
- package/dist/chunks/Banner-DL1Fpz_g.js +115 -0
- package/dist/chunks/Banner-DL1Fpz_g.js.map +1 -0
- package/dist/chunks/auto-update-Ddo5Ntt7.js +264 -0
- package/dist/chunks/auto-update-Ddo5Ntt7.js.map +1 -0
- package/dist/chunks/build-V8_D-JHF.js +116 -0
- package/dist/chunks/build-V8_D-JHF.js.map +1 -0
- package/dist/chunks/cleanup-BNuJNSve.js +141 -0
- package/dist/chunks/cleanup-BNuJNSve.js.map +1 -0
- package/dist/chunks/cli-auth-B4Do-N8Y.js +340 -0
- package/dist/chunks/cli-auth-B4Do-N8Y.js.map +1 -0
- package/dist/chunks/cli-error-1drkrXNn.js +140 -0
- package/dist/chunks/cli-error-1drkrXNn.js.map +1 -0
- package/dist/chunks/config-hFJA7z5y.js +167 -0
- package/dist/chunks/config-hFJA7z5y.js.map +1 -0
- package/dist/chunks/config-manager-DST6RbP8.js +133 -0
- package/dist/chunks/config-manager-DST6RbP8.js.map +1 -0
- package/dist/chunks/database-YGb1Lzim.js +68 -0
- package/dist/chunks/database-YGb1Lzim.js.map +1 -0
- package/dist/chunks/database-setup-U31oEs90.js +253 -0
- package/dist/chunks/database-setup-U31oEs90.js.map +1 -0
- package/dist/chunks/devtools-CPruVlOo.js +75 -0
- package/dist/chunks/devtools-CPruVlOo.js.map +1 -0
- package/dist/chunks/index-DCC6HGdr.js +119 -0
- package/dist/chunks/index-DCC6HGdr.js.map +1 -0
- package/dist/chunks/init-DkXJVFFx.js +472 -0
- package/dist/chunks/init-DkXJVFFx.js.map +1 -0
- package/dist/chunks/init-tui-D2VOVdeK.js +1131 -0
- package/dist/chunks/init-tui-D2VOVdeK.js.map +1 -0
- package/dist/chunks/logger-6V5cBxba.js +38 -0
- package/dist/chunks/logger-6V5cBxba.js.map +1 -0
- package/dist/chunks/login-CA1XWUEM.js +63 -0
- package/dist/chunks/login-CA1XWUEM.js.map +1 -0
- package/dist/chunks/logout-BC4VFt8f.js +40 -0
- package/dist/chunks/logout-BC4VFt8f.js.map +1 -0
- package/dist/chunks/main-tui-D8KkJRd_.js +648 -0
- package/dist/chunks/main-tui-D8KkJRd_.js.map +1 -0
- package/dist/chunks/manager-DjVI7erc.js +1161 -0
- package/dist/chunks/manager-DjVI7erc.js.map +1 -0
- package/dist/chunks/port-allocator-BENntRMG.js +864 -0
- package/dist/chunks/port-allocator-BENntRMG.js.map +1 -0
- package/dist/chunks/process-killer-ChXAqhfm.js +87 -0
- package/dist/chunks/process-killer-ChXAqhfm.js.map +1 -0
- package/dist/chunks/prompts-Beijr8dm.js +128 -0
- package/dist/chunks/prompts-Beijr8dm.js.map +1 -0
- package/dist/chunks/repo-cloner-UY3L2X7h.js +219 -0
- package/dist/chunks/repo-cloner-UY3L2X7h.js.map +1 -0
- package/dist/chunks/repo-detector-36VydrlB.js +66 -0
- package/dist/chunks/repo-detector-36VydrlB.js.map +1 -0
- package/dist/chunks/run-Du6dvTJL.js +697 -0
- package/dist/chunks/run-Du6dvTJL.js.map +1 -0
- package/dist/chunks/runner-logger-instance-Dj_JMznn.js +899 -0
- package/dist/chunks/runner-logger-instance-Dj_JMznn.js.map +1 -0
- package/dist/chunks/spinner-DTH0QZQw.js +53 -0
- package/dist/chunks/spinner-DTH0QZQw.js.map +1 -0
- package/dist/chunks/start-Dkuro1jp.js +1713 -0
- package/dist/chunks/start-Dkuro1jp.js.map +1 -0
- package/dist/chunks/start-traditional-7wlD2f2H.js +255 -0
- package/dist/chunks/start-traditional-7wlD2f2H.js.map +1 -0
- package/dist/chunks/status-BU3cFJm1.js +97 -0
- package/dist/chunks/status-BU3cFJm1.js.map +1 -0
- package/dist/chunks/theme-NAQBkisB.js +40222 -0
- package/dist/chunks/theme-NAQBkisB.js.map +1 -0
- package/dist/chunks/upgrade-BBpJirEu.js +455 -0
- package/dist/chunks/upgrade-BBpJirEu.js.map +1 -0
- package/dist/chunks/use-app-Ct3w2jLI.js +10 -0
- package/dist/chunks/use-app-Ct3w2jLI.js.map +1 -0
- package/dist/chunks/useBuildState-Dy7pRR8Z.js +330 -0
- package/dist/chunks/useBuildState-Dy7pRR8Z.js.map +1 -0
- package/dist/cli/index.js +712 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.js +13625 -0
- package/dist/index.js.map +1 -0
- package/dist/instrument.js +45 -0
- package/dist/instrument.js.map +1 -0
- package/dist/templates.json +295 -0
- package/package.json +87 -0
- package/templates/config.template.json +18 -0
- package/templates.json +295 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update-Ddo5Ntt7.js","sources":["../../src/cli/utils/auto-update.ts"],"sourcesContent":["/**\n * Auto-update utility for Hatchway 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/hatchway/releases/latest';\n\n// Install command for CLI\nconst INSTALL_COMMAND = 'curl -fsSL https://hatchway.sh/install | bash';\n\n// Cache settings\nconst CACHE_DIR = join(homedir(), '.config', 'hatchway');\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': 'Hatchway-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 HATCHWAY_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 Hatchway 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 hatchway upgrade --force to upgrade the monorepo\n // Use --force to skip prompts since we're in auto-update mode\n const result = spawnSync('hatchway', ['upgrade', '--force'], {\n stdio: 'inherit',\n env: {\n ...process.env,\n HATCHWAY_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 hatchway to avoid shell hash caching issues\n // This ensures we run the newly installed version, not a cached path\n let hatchwayPath = 'hatchway';\n try {\n // Use 'command -v' to get the actual path, bypassing shell hash\n hatchwayPath = execSync('command -v hatchway', { encoding: 'utf-8' }).trim();\n } catch {\n // Fallback to just 'hatchway' if command -v fails\n }\n\n // Use spawnSync with the explicit path to ensure we get the new version\n const result = spawnSync(hatchwayPath, args, {\n stdio: 'inherit',\n env: {\n ...process.env,\n HATCHWAY_SKIP_UPDATE_CHECK: '1', // Prevent update loop\n HATCHWAY_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.HATCHWAY_NO_UPDATE === '1' || process.env.HATCHWAY_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('hatchway 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://hatchway.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('hatchway')} ${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.HATCHWAY_NO_UPDATE === '1' || process.env.HATCHWAY_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,116 @@
|
|
|
1
|
+
// Hatchway CLI - Built with Rollup
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import * as p from '@clack/prompts';
|
|
5
|
+
import pc from 'picocolors';
|
|
6
|
+
import { c as configManager } from './config-manager-DST6RbP8.js';
|
|
7
|
+
import { i as isInsideMonorepo } from './repo-detector-36VydrlB.js';
|
|
8
|
+
import { e as errors, C as CLIError } from './cli-error-1drkrXNn.js';
|
|
9
|
+
import 'conf';
|
|
10
|
+
import 'node:os';
|
|
11
|
+
import 'node:path';
|
|
12
|
+
import 'node:fs/promises';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Build command - rebuild all services without starting them
|
|
16
|
+
* Useful for rebuilding while services are already running
|
|
17
|
+
*/
|
|
18
|
+
async function buildCommand(options) {
|
|
19
|
+
const s = p.spinner();
|
|
20
|
+
// Step 1: Find monorepo
|
|
21
|
+
s.start('Locating Hatchway repository');
|
|
22
|
+
let monorepoRoot;
|
|
23
|
+
const config = configManager.get();
|
|
24
|
+
if (config.monorepoPath && existsSync(config.monorepoPath)) {
|
|
25
|
+
monorepoRoot = config.monorepoPath;
|
|
26
|
+
}
|
|
27
|
+
if (!monorepoRoot) {
|
|
28
|
+
const repoCheck = await isInsideMonorepo();
|
|
29
|
+
if (repoCheck.inside && repoCheck.root) {
|
|
30
|
+
monorepoRoot = repoCheck.root;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!monorepoRoot) {
|
|
34
|
+
s.stop(pc.red('✗') + ' Repository not found');
|
|
35
|
+
throw errors.monorepoNotFound([
|
|
36
|
+
config.monorepoPath || 'none',
|
|
37
|
+
process.cwd(),
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
s.stop(pc.green('✓') + ' Repository found');
|
|
41
|
+
// Step 2: Build services
|
|
42
|
+
if (options.watch) {
|
|
43
|
+
console.log();
|
|
44
|
+
console.log(pc.cyan('Building services in watch mode...'));
|
|
45
|
+
console.log(pc.dim('Press Ctrl+C to stop'));
|
|
46
|
+
console.log();
|
|
47
|
+
// Use turbo watch mode
|
|
48
|
+
const watchProcess = spawn('pnpm', ['build:all', '--watch'], {
|
|
49
|
+
cwd: monorepoRoot,
|
|
50
|
+
stdio: 'inherit',
|
|
51
|
+
shell: true,
|
|
52
|
+
});
|
|
53
|
+
// Handle Ctrl+C gracefully
|
|
54
|
+
process.on('SIGINT', () => {
|
|
55
|
+
console.log();
|
|
56
|
+
console.log(pc.yellow('⚠'), 'Stopping watch mode...');
|
|
57
|
+
watchProcess.kill('SIGTERM');
|
|
58
|
+
process.exit(0);
|
|
59
|
+
});
|
|
60
|
+
watchProcess.on('error', (error) => {
|
|
61
|
+
throw new CLIError({
|
|
62
|
+
code: 'BUILD_FAILED',
|
|
63
|
+
message: 'Watch mode failed',
|
|
64
|
+
cause: error,
|
|
65
|
+
suggestions: [
|
|
66
|
+
'Check that all dependencies are installed',
|
|
67
|
+
'Try running: pnpm install',
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// Wait for process to exit
|
|
72
|
+
await new Promise((resolve) => {
|
|
73
|
+
watchProcess.on('close', () => resolve());
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
s.start('Building all services');
|
|
78
|
+
try {
|
|
79
|
+
await new Promise((resolve, reject) => {
|
|
80
|
+
const buildProcess = spawn('pnpm', ['build:all'], {
|
|
81
|
+
cwd: monorepoRoot,
|
|
82
|
+
stdio: 'inherit', // Show build output
|
|
83
|
+
shell: true,
|
|
84
|
+
});
|
|
85
|
+
buildProcess.on('close', (code) => {
|
|
86
|
+
if (code === 0) {
|
|
87
|
+
resolve();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
reject(new Error(`Build failed with code ${code}`));
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
buildProcess.on('error', reject);
|
|
94
|
+
});
|
|
95
|
+
s.stop(pc.green('✓') + ' Build complete');
|
|
96
|
+
console.log();
|
|
97
|
+
console.log(pc.dim('Tip: Restart services to use the new build'));
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
s.stop(pc.red('✗') + ' Build failed');
|
|
101
|
+
throw new CLIError({
|
|
102
|
+
code: 'BUILD_FAILED',
|
|
103
|
+
message: 'Failed to build services',
|
|
104
|
+
cause: error instanceof Error ? error : new Error(String(error)),
|
|
105
|
+
suggestions: [
|
|
106
|
+
'Check that all dependencies are installed',
|
|
107
|
+
'Try running: pnpm install',
|
|
108
|
+
'Check for TypeScript errors in your code',
|
|
109
|
+
],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { buildCommand };
|
|
116
|
+
//# sourceMappingURL=build-V8_D-JHF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-V8_D-JHF.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 Hatchway 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,141 @@
|
|
|
1
|
+
// Hatchway CLI - Built with Rollup
|
|
2
|
+
import { stat, rm, readdir } from 'node:fs/promises';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { l as logger } from './logger-6V5cBxba.js';
|
|
7
|
+
import { p as prompts } from './prompts-Beijr8dm.js';
|
|
8
|
+
import { c as configManager } from './config-manager-DST6RbP8.js';
|
|
9
|
+
import { s as spinner } from './spinner-DTH0QZQw.js';
|
|
10
|
+
import 'inquirer';
|
|
11
|
+
import 'node:os';
|
|
12
|
+
import 'conf';
|
|
13
|
+
import 'ora';
|
|
14
|
+
|
|
15
|
+
async function cleanupCommand(options) {
|
|
16
|
+
const config = configManager.get();
|
|
17
|
+
const workspace = config.workspace;
|
|
18
|
+
if (!workspace || !existsSync(workspace)) {
|
|
19
|
+
logger.error('Workspace not found');
|
|
20
|
+
logger.info(`Expected: ${workspace}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Handle specific cleanup actions
|
|
24
|
+
if (options.project) {
|
|
25
|
+
await cleanupProject(workspace, options.project);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (options.all) {
|
|
29
|
+
await cleanupAllProjects(workspace);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (options.tunnels) {
|
|
33
|
+
logger.warn('Tunnel cleanup requires the runner to be running');
|
|
34
|
+
logger.info('Tunnels are managed by the active runner process');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (options.processes) {
|
|
38
|
+
logger.warn('Process cleanup requires the runner to be running');
|
|
39
|
+
logger.info('Dev servers are managed by the active runner process');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// No specific action - show help
|
|
43
|
+
logger.info('Cleanup options:');
|
|
44
|
+
logger.log(` ${chalk.cyan('--project <slug>')} Delete specific project`);
|
|
45
|
+
logger.log(` ${chalk.cyan('--all')} Delete all projects`);
|
|
46
|
+
logger.log(` ${chalk.cyan('--tunnels')} Close all tunnels (requires running runner)`);
|
|
47
|
+
logger.log(` ${chalk.cyan('--processes')} Kill all dev servers (requires running runner)`);
|
|
48
|
+
logger.log('');
|
|
49
|
+
logger.info('Examples:');
|
|
50
|
+
logger.log(` hatchway cleanup --project my-project`);
|
|
51
|
+
logger.log(` hatchway cleanup --all`);
|
|
52
|
+
}
|
|
53
|
+
async function cleanupProject(workspace, slug) {
|
|
54
|
+
const projectPath = join(workspace, slug);
|
|
55
|
+
if (!existsSync(projectPath)) {
|
|
56
|
+
logger.error(`Project not found: ${slug}`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Get project size
|
|
60
|
+
let size = 'unknown';
|
|
61
|
+
try {
|
|
62
|
+
const stats = await stat(projectPath);
|
|
63
|
+
if (stats.isDirectory()) {
|
|
64
|
+
// Estimate size (this is approximate)
|
|
65
|
+
size = `${Math.round(stats.size / 1024)}KB+`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Ignore size calculation errors
|
|
70
|
+
}
|
|
71
|
+
logger.warn(`This will permanently delete project: ${chalk.cyan(slug)}`);
|
|
72
|
+
logger.log(`Path: ${projectPath}`);
|
|
73
|
+
logger.log(`Size: ${size}`);
|
|
74
|
+
logger.log('');
|
|
75
|
+
const confirmed = await prompts.confirm('Are you sure?', false);
|
|
76
|
+
if (!confirmed) {
|
|
77
|
+
logger.info('Cleanup cancelled');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
spinner.start(`Deleting project: ${slug}`);
|
|
81
|
+
try {
|
|
82
|
+
await rm(projectPath, { recursive: true, force: true, maxRetries: 3 });
|
|
83
|
+
spinner.succeed(`Deleted project: ${chalk.cyan(slug)}`);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
spinner.fail('Failed to delete project');
|
|
87
|
+
logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function cleanupAllProjects(workspace) {
|
|
92
|
+
logger.warn(`This will permanently delete ALL projects in workspace`);
|
|
93
|
+
logger.log(`Workspace: ${workspace}`);
|
|
94
|
+
logger.log('');
|
|
95
|
+
// List projects
|
|
96
|
+
const entries = await readdir(workspace);
|
|
97
|
+
const projects = [];
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
const entryPath = join(workspace, entry);
|
|
100
|
+
const stats = await stat(entryPath);
|
|
101
|
+
if (stats.isDirectory()) {
|
|
102
|
+
projects.push(entry);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (projects.length === 0) {
|
|
106
|
+
logger.info('No projects found to delete');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
logger.log(`Found ${projects.length} project(s):`);
|
|
110
|
+
projects.forEach(p => logger.log(` - ${p}`));
|
|
111
|
+
logger.log('');
|
|
112
|
+
const confirmed = await prompts.confirm(`Delete all ${projects.length} projects?`, false);
|
|
113
|
+
if (!confirmed) {
|
|
114
|
+
logger.info('Cleanup cancelled');
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
spinner.start(`Deleting ${projects.length} projects...`);
|
|
118
|
+
let deleted = 0;
|
|
119
|
+
const errors = [];
|
|
120
|
+
for (const project of projects) {
|
|
121
|
+
try {
|
|
122
|
+
await rm(join(workspace, project), { recursive: true, force: true, maxRetries: 3 });
|
|
123
|
+
deleted++;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
errors.push(`${project}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (errors.length === 0) {
|
|
130
|
+
spinner.succeed(`Deleted ${deleted} projects`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
spinner.warn(`Deleted ${deleted}/${projects.length} projects`);
|
|
134
|
+
logger.log('');
|
|
135
|
+
logger.error('Errors:');
|
|
136
|
+
errors.forEach(err => logger.error(` ${err}`));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { cleanupCommand };
|
|
141
|
+
//# sourceMappingURL=cleanup-BNuJNSve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-BNuJNSve.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(` hatchway cleanup --project my-project`);\n logger.log(` hatchway 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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"}
|