@hatchway/cli 0.50.71 → 0.50.73

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.
@@ -1,473 +0,0 @@
1
- // Hatchway CLI - Built with Rollup
2
- import { mkdir } from 'node:fs/promises';
3
- import { existsSync, realpathSync } from 'node:fs';
4
- import { join, resolve } from 'node:path';
5
- import { randomBytes } from 'node:crypto';
6
- import * as p from '@clack/prompts';
7
- import pc from 'picocolors';
8
- import { c as configManager } from './config-manager-DST6RbP8.js';
9
- import { i as isInsideMonorepo } from './repo-detector-36VydrlB.js';
10
- import { isPnpmInstalled, cloneRepository, installDependencies, buildAgentCore } from './repo-cloner-UY3L2X7h.js';
11
- import { s as setupDatabase, p as pushDatabaseSchema, c as connectManualDatabase } from './database-setup-BdXiI4MV.js';
12
- import { C as CLIError, e as errors } from './cli-error-1drkrXNn.js';
13
- import { initTUICommand } from './init-tui-CcxzfgmC.js';
14
- import 'conf';
15
- import 'node:os';
16
- import 'node:child_process';
17
- import './logger-6V5cBxba.js';
18
- import 'chalk';
19
- import './spinner-DTH0QZQw.js';
20
- import 'ora';
21
- import './prompts-Beijr8dm.js';
22
- import 'inquirer';
23
- import './theme-NAQBkisB.js';
24
- import 'node:stream';
25
- import 'node:process';
26
- import 'assert';
27
- import 'events';
28
- import 'node:events';
29
- import 'module';
30
- import 'node:buffer';
31
- import './use-app-Ct3w2jLI.js';
32
- import './Banner-B4nm86qK.js';
33
- import './version-info-CDtU8Ta2.js';
34
- import 'node:url';
35
- import 'node:http';
36
-
37
- /**
38
- * Enhanced init command with @clack/prompts and friction-free -y mode
39
- * Provides beautiful interactive setup or completely automated installation
40
- *
41
- * For -y mode: Uses a beautiful centered TUI with animated progress
42
- */
43
- /**
44
- * Generate a secure random secret
45
- */
46
- function generateSecret() {
47
- return randomBytes(32).toString('hex');
48
- }
49
- /**
50
- * Check if a path is or contains the current working directory
51
- * Prevents accidental deletion of the directory we're running from
52
- */
53
- function isCurrentWorkingDirectory(targetPath) {
54
- try {
55
- const cwd = realpathSync(process.cwd());
56
- const target = realpathSync(resolve(targetPath));
57
- // Check if target is cwd or if cwd is inside target
58
- return cwd === target || cwd.startsWith(target + '/');
59
- }
60
- catch {
61
- // If we can't resolve paths, be safe and assume it might be cwd
62
- const cwd = process.cwd();
63
- const target = resolve(targetPath);
64
- return cwd === target || cwd.startsWith(target + '/');
65
- }
66
- }
67
- /**
68
- * Safely remove a directory, but never the current working directory
69
- */
70
- function safeRemoveDirectory(targetPath, rmSync) {
71
- if (isCurrentWorkingDirectory(targetPath)) {
72
- console.error(`\n⚠️ Cannot remove ${targetPath} - it is the current working directory`);
73
- console.error(' Please run this command from a different directory.\n');
74
- return false;
75
- }
76
- rmSync(targetPath, { recursive: true, force: true });
77
- return true;
78
- }
79
- /**
80
- * Normalize URL by adding protocol if missing
81
- */
82
- function normalizeUrl(url) {
83
- if (!url)
84
- return url;
85
- if (url.match(/^https?:\/\//i))
86
- return url;
87
- if (url.match(/^(localhost|127\.0\.0\.1)(:|\/|$)/i)) {
88
- return `http://${url}`;
89
- }
90
- return `https://${url}`;
91
- }
92
- /**
93
- * Get default workspace path
94
- */
95
- function getDefaultWorkspace() {
96
- return join(process.cwd(), 'hatchway-workspace');
97
- }
98
- /**
99
- * Get default monorepo clone path
100
- */
101
- function getDefaultMonorepoPath() {
102
- return join(process.cwd(), 'hatchway');
103
- }
104
- async function initCommand(options) {
105
- const isNonInteractive = options.nonInteractive || options.yes;
106
- // ========================================
107
- // NON-INTERACTIVE MODE: Use beautiful TUI
108
- // ========================================
109
- if (isNonInteractive) {
110
- return initTUICommand(options);
111
- }
112
- // ========================================
113
- // INTERACTIVE MODE (Beautiful @clack/prompts)
114
- // ========================================
115
- // Handle Ctrl+C gracefully
116
- const handleCancel = () => {
117
- p.cancel('Setup cancelled');
118
- process.exit(0);
119
- };
120
- try {
121
- {
122
- // Keep banner visible - don't clear screen
123
- console.log(); // Just add spacing
124
- p.intro(pc.bgCyan(pc.black(' Hatchway Setup ')));
125
- // Step 1: Check if already initialized
126
- if (configManager.isInitialized()) {
127
- const shouldReset = await p.confirm({
128
- message: 'Configuration already exists. Reset and reconfigure?',
129
- initialValue: true,
130
- });
131
- if (p.isCancel(shouldReset)) {
132
- handleCancel();
133
- return;
134
- }
135
- if (!shouldReset) {
136
- p.cancel('Setup cancelled');
137
- return;
138
- }
139
- configManager.reset();
140
- p.log.success('Configuration reset');
141
- }
142
- // Step 2: Check for monorepo
143
- const s = p.spinner();
144
- s.start('Checking for Hatchway repository');
145
- const repoCheck = await isInsideMonorepo();
146
- let monorepoPath;
147
- if (repoCheck.inside && repoCheck.root) {
148
- s.stop(pc.green('✓') + ' Found repository at: ' + pc.cyan(repoCheck.root));
149
- monorepoPath = repoCheck.root;
150
- }
151
- else {
152
- s.stop('Repository not found in current directory');
153
- const shouldClone = await p.confirm({
154
- message: 'Clone Hatchway repository?',
155
- initialValue: true,
156
- });
157
- if (p.isCancel(shouldClone)) {
158
- handleCancel();
159
- return;
160
- }
161
- if (shouldClone) {
162
- // Check for pnpm
163
- const hasPnpm = await isPnpmInstalled();
164
- if (!hasPnpm) {
165
- throw new CLIError({
166
- code: 'DEPENDENCIES_INSTALL_FAILED',
167
- message: 'pnpm is not installed',
168
- suggestions: [
169
- 'Install pnpm: npm install -g pnpm',
170
- 'Or visit: https://pnpm.io/installation',
171
- ],
172
- });
173
- }
174
- const clonePath = await p.text({
175
- message: 'Where should the repository be cloned?',
176
- placeholder: getDefaultMonorepoPath(),
177
- defaultValue: getDefaultMonorepoPath(),
178
- validate: (value) => {
179
- if (!value)
180
- return 'Path is required';
181
- },
182
- });
183
- if (p.isCancel(clonePath)) {
184
- handleCancel();
185
- return;
186
- }
187
- // Check if path exists
188
- const defaultWorkspace = getDefaultWorkspace();
189
- const existingInstallation = existsSync(clonePath) || existsSync(defaultWorkspace);
190
- if (existingInstallation) {
191
- const shouldOverwrite = await p.confirm({
192
- message: `Existing Hatchway installation found. Replace it with fresh install?`,
193
- initialValue: true,
194
- });
195
- if (p.isCancel(shouldOverwrite)) {
196
- handleCancel();
197
- return;
198
- }
199
- if (shouldOverwrite) {
200
- s.start('Removing existing installation');
201
- const { rmSync } = await import('fs');
202
- // Safety check: never delete the current working directory
203
- if (existsSync(clonePath)) {
204
- if (!safeRemoveDirectory(clonePath, rmSync)) {
205
- s.stop(pc.red('✗') + ' Cannot remove current working directory');
206
- p.cancel('Please run hatchway init from a different directory');
207
- return;
208
- }
209
- }
210
- // Delete workspace directory
211
- if (existsSync(defaultWorkspace)) {
212
- if (!safeRemoveDirectory(defaultWorkspace, rmSync)) {
213
- s.stop(pc.red('✗') + ' Cannot remove current working directory');
214
- p.cancel('Please run hatchway init from a different directory');
215
- return;
216
- }
217
- }
218
- s.stop(pc.green('✓') + ' Existing installation removed');
219
- }
220
- else {
221
- p.cancel('Setup cancelled');
222
- return;
223
- }
224
- }
225
- // Clone, install, build
226
- try {
227
- s.start('Cloning repository from GitHub');
228
- monorepoPath = await cloneRepository({
229
- targetPath: clonePath,
230
- branch: options.branch || 'main',
231
- });
232
- s.stop(pc.green('✓') + ' Repository cloned');
233
- s.start('Installing dependencies (this may take a few minutes)');
234
- await installDependencies(monorepoPath);
235
- s.stop(pc.green('✓') + ' Dependencies installed');
236
- s.start('Building @hatchway/agent-core');
237
- await buildAgentCore(monorepoPath);
238
- s.stop(pc.green('✓') + ' Build complete');
239
- // Ask about pre-building services
240
- const shouldPreBuild = await p.confirm({
241
- message: 'Pre-build all services for production performance?',
242
- initialValue: true,
243
- });
244
- if (p.isCancel(shouldPreBuild)) {
245
- handleCancel();
246
- return;
247
- }
248
- if (shouldPreBuild) {
249
- s.start('Building all services (this may take a minute)');
250
- const { spawn } = await import('child_process');
251
- try {
252
- await new Promise((resolve, reject) => {
253
- const buildProcess = spawn('pnpm', ['build:all'], {
254
- cwd: monorepoPath,
255
- stdio: 'pipe',
256
- shell: true,
257
- });
258
- buildProcess.on('close', (code) => {
259
- if (code === 0) {
260
- resolve();
261
- }
262
- else {
263
- reject(new Error(`Build failed with code ${code}`));
264
- }
265
- });
266
- buildProcess.on('error', reject);
267
- });
268
- s.stop(pc.green('✓') + ' All services built for production');
269
- }
270
- catch (error) {
271
- s.stop(pc.yellow('⚠') + ' Build failed (you can build later with: pnpm build:all)');
272
- }
273
- }
274
- }
275
- catch (error) {
276
- throw new CLIError({
277
- code: 'MONOREPO_CLONE_FAILED',
278
- message: 'Failed to setup repository',
279
- cause: error instanceof Error ? error : new Error(String(error)),
280
- suggestions: [
281
- 'Check your internet connection',
282
- 'Verify you have git installed: git --version',
283
- 'Try cloning manually: git clone https://github.com/codyde/hatchway.git',
284
- ],
285
- });
286
- }
287
- }
288
- else {
289
- p.note('Setup will continue in runner-only mode.\nYou can add the repository path later with:\n hatchway config set monorepoPath <path>', 'Repository setup skipped');
290
- }
291
- }
292
- // Step 3: Workspace configuration
293
- p.log.step(pc.cyan('Workspace Configuration'));
294
- const workspace = await p.text({
295
- message: 'Where should generated projects be stored?',
296
- placeholder: getDefaultWorkspace(),
297
- defaultValue: getDefaultWorkspace(),
298
- validate: (value) => {
299
- if (!value)
300
- return 'Workspace path is required';
301
- },
302
- });
303
- if (p.isCancel(workspace)) {
304
- handleCancel();
305
- return;
306
- }
307
- // Create workspace directory
308
- try {
309
- if (!existsSync(workspace)) {
310
- await mkdir(workspace, { recursive: true });
311
- }
312
- }
313
- catch (error) {
314
- throw errors.workspaceNotFound(workspace);
315
- }
316
- // Step 4: Connection configuration
317
- p.log.step(pc.cyan('Connection Configuration'));
318
- const wsUrl = await p.text({
319
- message: 'Server WebSocket URL',
320
- placeholder: 'ws://localhost:3000/ws/runner',
321
- defaultValue: 'ws://localhost:3000/ws/runner',
322
- });
323
- if (p.isCancel(wsUrl)) {
324
- handleCancel();
325
- return;
326
- }
327
- const apiUrl = await p.text({
328
- message: 'API base URL',
329
- placeholder: 'http://localhost:3000',
330
- defaultValue: options.url || 'http://localhost:3000',
331
- });
332
- if (p.isCancel(apiUrl)) {
333
- handleCancel();
334
- return;
335
- }
336
- // Step 5: Security
337
- const secret = await p.text({
338
- message: 'Shared secret (press Enter to generate)',
339
- placeholder: 'Generated automatically',
340
- defaultValue: options.secret || generateSecret(),
341
- });
342
- if (p.isCancel(secret)) {
343
- handleCancel();
344
- return;
345
- }
346
- const runnerId = await p.text({
347
- message: 'Runner ID',
348
- placeholder: 'local',
349
- defaultValue: 'local',
350
- });
351
- if (p.isCancel(runnerId)) {
352
- handleCancel();
353
- return;
354
- }
355
- // Step 6: Database setup (if monorepo available)
356
- let databaseUrl;
357
- if (monorepoPath) {
358
- p.log.step(pc.cyan('Database Setup'));
359
- const dbChoice = await p.select({
360
- message: 'Database configuration',
361
- options: [
362
- {
363
- value: 'neon',
364
- label: 'Create Neon database (recommended)',
365
- hint: 'Free tier, persistent storage'
366
- },
367
- {
368
- value: 'existing',
369
- label: 'Use existing PostgreSQL',
370
- hint: 'Provide connection string'
371
- },
372
- ],
373
- });
374
- if (p.isCancel(dbChoice)) {
375
- handleCancel();
376
- return;
377
- }
378
- if (dbChoice === 'neon') {
379
- p.note('Opening Neon in your browser...\nCreate a database and paste the connection string below.', pc.cyan('Database Setup'));
380
- databaseUrl = await setupDatabase(monorepoPath) || undefined;
381
- // Push schema if we have a database
382
- if (databaseUrl) {
383
- s.start('Pushing database schema');
384
- const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);
385
- if (pushed) {
386
- s.stop(pc.green('✓') + ' Schema initialized');
387
- }
388
- else {
389
- s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');
390
- }
391
- }
392
- }
393
- else if (dbChoice === 'existing') {
394
- databaseUrl = await connectManualDatabase() || undefined;
395
- // Push schema if we have a database
396
- if (databaseUrl) {
397
- s.start('Pushing database schema');
398
- const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);
399
- if (pushed) {
400
- s.stop(pc.green('✓') + ' Schema initialized');
401
- }
402
- else {
403
- s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');
404
- }
405
- }
406
- }
407
- }
408
- // Step 7: Save configuration
409
- try {
410
- configManager.set('workspace', workspace);
411
- if (monorepoPath) {
412
- configManager.set('monorepoPath', monorepoPath);
413
- }
414
- if (databaseUrl) {
415
- configManager.set('databaseUrl', databaseUrl);
416
- }
417
- configManager.set('apiUrl', normalizeUrl(apiUrl));
418
- configManager.set('server', {
419
- wsUrl: wsUrl,
420
- secret: secret,
421
- });
422
- configManager.set('runner', {
423
- id: runnerId,
424
- reconnectAttempts: 5,
425
- heartbeatInterval: 15000,
426
- });
427
- configManager.set('tunnel', {
428
- provider: 'cloudflare',
429
- autoCreate: true,
430
- });
431
- }
432
- catch (error) {
433
- throw new CLIError({
434
- code: 'CONFIG_INVALID',
435
- message: 'Failed to save configuration',
436
- cause: error instanceof Error ? error : new Error(String(error)),
437
- suggestions: [
438
- 'Check file permissions on config directory',
439
- 'Try running with sudo (not recommended)',
440
- ],
441
- });
442
- }
443
- // Validate
444
- const validation = configManager.validate();
445
- if (!validation.valid) {
446
- throw new CLIError({
447
- code: 'CONFIG_INVALID',
448
- message: 'Configuration validation failed',
449
- context: { errors: validation.errors },
450
- suggestions: validation.errors,
451
- });
452
- }
453
- // Success!
454
- p.outro(pc.green('✨ Hatchway is ready!'));
455
- p.note(`${pc.cyan('hatchway run')}\n\nThen open: ${pc.cyan('http://localhost:3000')}`, 'Next Steps');
456
- return;
457
- }
458
- }
459
- catch (error) {
460
- // Handle cancellation gracefully
461
- if (error && typeof error === 'object' && 'name' in error) {
462
- if (error.name === 'ExitPromptError' || error.code === 'CLACK_CANCEL') {
463
- handleCancel();
464
- return;
465
- }
466
- }
467
- // Re-throw for global error handler
468
- throw error;
469
- }
470
- }
471
-
472
- export { initCommand };
473
- //# sourceMappingURL=init-CBODHYDw.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init-CBODHYDw.js","sources":["../../src/cli/commands/init.ts"],"sourcesContent":["/**\n * Enhanced init command with @clack/prompts and friction-free -y mode\n * Provides beautiful interactive setup or completely automated installation\n * \n * For -y mode: Uses a beautiful centered TUI with animated progress\n */\n\nimport { mkdir, realpath, writeFile } from 'node:fs/promises';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { randomBytes } from 'node:crypto';\nimport * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { configManager } from '../utils/config-manager.js';\nimport { isInsideMonorepo } from '../utils/repo-detector.js';\nimport {\n cloneRepository,\n installDependencies,\n isPnpmInstalled,\n buildAgentCore\n} from '../utils/repo-cloner.js';\nimport {\n setupDatabase,\n pushDatabaseSchema,\n connectManualDatabase\n} from '../utils/database-setup.js';\nimport { CLIError, errors } from '../utils/cli-error.js';\nimport { initTUICommand } from './init-tui.js';\n\n/**\n * Generate a secure random secret\n */\nfunction generateSecret(): string {\n return randomBytes(32).toString('hex');\n}\n\n/**\n * Check if a path is or contains the current working directory\n * Prevents accidental deletion of the directory we're running from\n */\nfunction isCurrentWorkingDirectory(targetPath: string): boolean {\n try {\n const cwd = realpathSync(process.cwd());\n const target = realpathSync(resolve(targetPath));\n // Check if target is cwd or if cwd is inside target\n return cwd === target || cwd.startsWith(target + '/');\n } catch {\n // If we can't resolve paths, be safe and assume it might be cwd\n const cwd = process.cwd();\n const target = resolve(targetPath);\n return cwd === target || cwd.startsWith(target + '/');\n }\n}\n\n/**\n * Safely remove a directory, but never the current working directory\n */\nfunction safeRemoveDirectory(targetPath: string, rmSync: typeof import('fs').rmSync): boolean {\n if (isCurrentWorkingDirectory(targetPath)) {\n console.error(`\\n⚠️ Cannot remove ${targetPath} - it is the current working directory`);\n console.error(' Please run this command from a different directory.\\n');\n return false;\n }\n rmSync(targetPath, { recursive: true, force: true });\n return true;\n}\n\n/**\n * Normalize URL by adding protocol if missing\n */\nfunction normalizeUrl(url: string): string {\n if (!url) return url;\n if (url.match(/^https?:\\/\\//i)) return url;\n if (url.match(/^(localhost|127\\.0\\.0\\.1)(:|\\/|$)/i)) {\n return `http://${url}`;\n }\n return `https://${url}`;\n}\n\n/**\n * Get default workspace path\n */\nfunction getDefaultWorkspace(): string {\n return join(process.cwd(), 'hatchway-workspace');\n}\n\n/**\n * Get default monorepo clone path\n */\nfunction getDefaultMonorepoPath(): string {\n return join(process.cwd(), 'hatchway');\n}\n\ninterface InitOptions {\n workspace?: string;\n url?: string;\n secret?: string;\n branch?: string;\n database?: string | boolean; // Can be: undefined (neon), or a PostgreSQL connection string\n yes?: boolean;\n nonInteractive?: boolean;\n}\n\nexport async function initCommand(options: InitOptions) {\n const isNonInteractive = options.nonInteractive || options.yes;\n\n // ========================================\n // NON-INTERACTIVE MODE: Use beautiful TUI\n // ========================================\n if (isNonInteractive) {\n return initTUICommand(options);\n }\n\n // ========================================\n // INTERACTIVE MODE (Beautiful @clack/prompts)\n // ========================================\n // Handle Ctrl+C gracefully\n const handleCancel = () => {\n p.cancel('Setup cancelled');\n process.exit(0);\n };\n\n try {\n {\n // Keep banner visible - don't clear screen\n console.log(); // Just add spacing\n\n p.intro(pc.bgCyan(pc.black(' Hatchway Setup ')));\n\n // Step 1: Check if already initialized\n if (configManager.isInitialized()) {\n const shouldReset = await p.confirm({\n message: 'Configuration already exists. Reset and reconfigure?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldReset)) {\n handleCancel();\n return;\n }\n\n if (!shouldReset) {\n p.cancel('Setup cancelled');\n return;\n }\n\n configManager.reset();\n p.log.success('Configuration reset');\n }\n\n // Step 2: Check for monorepo\n const s = p.spinner();\n s.start('Checking for Hatchway repository');\n\n const repoCheck = await isInsideMonorepo();\n let monorepoPath: string | undefined;\n\n if (repoCheck.inside && repoCheck.root) {\n s.stop(pc.green('✓') + ' Found repository at: ' + pc.cyan(repoCheck.root));\n monorepoPath = repoCheck.root;\n } else {\n s.stop('Repository not found in current directory');\n\n const shouldClone = await p.confirm({\n message: 'Clone Hatchway repository?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldClone)) {\n handleCancel();\n return;\n }\n\n if (shouldClone) {\n // Check for pnpm\n const hasPnpm = await isPnpmInstalled();\n if (!hasPnpm) {\n throw new CLIError({\n code: 'DEPENDENCIES_INSTALL_FAILED',\n message: 'pnpm is not installed',\n suggestions: [\n 'Install pnpm: npm install -g pnpm',\n 'Or visit: https://pnpm.io/installation',\n ],\n });\n }\n\n const clonePath = await p.text({\n message: 'Where should the repository be cloned?',\n placeholder: getDefaultMonorepoPath(),\n defaultValue: getDefaultMonorepoPath(),\n validate: (value) => {\n if (!value) return 'Path is required';\n },\n });\n\n if (p.isCancel(clonePath)) {\n handleCancel();\n return;\n }\n\n // Check if path exists\n const defaultWorkspace = getDefaultWorkspace();\n const existingInstallation = existsSync(clonePath as string) || existsSync(defaultWorkspace);\n\n if (existingInstallation) {\n const shouldOverwrite = await p.confirm({\n message: `Existing Hatchway installation found. Replace it with fresh install?`,\n initialValue: true,\n });\n\n if (p.isCancel(shouldOverwrite)) {\n handleCancel();\n return;\n }\n\n if (shouldOverwrite) {\n s.start('Removing existing installation');\n const { rmSync } = await import('fs');\n\n // Safety check: never delete the current working directory\n if (existsSync(clonePath as string)) {\n if (!safeRemoveDirectory(clonePath as string, rmSync)) {\n s.stop(pc.red('✗') + ' Cannot remove current working directory');\n p.cancel('Please run hatchway init from a different directory');\n return;\n }\n }\n\n // Delete workspace directory\n if (existsSync(defaultWorkspace)) {\n if (!safeRemoveDirectory(defaultWorkspace, rmSync)) {\n s.stop(pc.red('✗') + ' Cannot remove current working directory');\n p.cancel('Please run hatchway init from a different directory');\n return;\n }\n }\n\n s.stop(pc.green('✓') + ' Existing installation removed');\n } else {\n p.cancel('Setup cancelled');\n return;\n }\n }\n\n // Clone, install, build\n try {\n s.start('Cloning repository from GitHub');\n monorepoPath = await cloneRepository({\n targetPath: clonePath as string,\n branch: options.branch || 'main',\n });\n s.stop(pc.green('✓') + ' Repository cloned');\n\n s.start('Installing dependencies (this may take a few minutes)');\n await installDependencies(monorepoPath);\n s.stop(pc.green('✓') + ' Dependencies installed');\n\n s.start('Building @hatchway/agent-core');\n await buildAgentCore(monorepoPath);\n s.stop(pc.green('✓') + ' Build complete');\n\n // Ask about pre-building services\n const shouldPreBuild = await p.confirm({\n message: 'Pre-build all services for production performance?',\n initialValue: true,\n });\n\n if (p.isCancel(shouldPreBuild)) {\n handleCancel();\n return;\n }\n\n if (shouldPreBuild) {\n s.start('Building all services (this may take a minute)');\n const { spawn } = await import('child_process');\n\n try {\n await new Promise<void>((resolve, reject) => {\n const buildProcess = spawn('pnpm', ['build:all'], {\n cwd: monorepoPath,\n stdio: 'pipe',\n shell: true,\n });\n\n buildProcess.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Build failed with code ${code}`));\n }\n });\n\n buildProcess.on('error', reject);\n });\n\n s.stop(pc.green('✓') + ' All services built for production');\n } catch (error) {\n s.stop(pc.yellow('⚠') + ' Build failed (you can build later with: pnpm build:all)');\n }\n }\n } catch (error) {\n throw new CLIError({\n code: 'MONOREPO_CLONE_FAILED',\n message: 'Failed to setup repository',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check your internet connection',\n 'Verify you have git installed: git --version',\n 'Try cloning manually: git clone https://github.com/codyde/hatchway.git',\n ],\n });\n }\n } else {\n p.note(\n 'Setup will continue in runner-only mode.\\nYou can add the repository path later with:\\n hatchway config set monorepoPath <path>',\n 'Repository setup skipped'\n );\n }\n }\n\n // Step 3: Workspace configuration\n p.log.step(pc.cyan('Workspace Configuration'));\n\n const workspace = await p.text({\n message: 'Where should generated projects be stored?',\n placeholder: getDefaultWorkspace(),\n defaultValue: getDefaultWorkspace(),\n validate: (value) => {\n if (!value) return 'Workspace path is required';\n },\n });\n\n if (p.isCancel(workspace)) {\n handleCancel();\n return;\n }\n\n // Create workspace directory\n try {\n if (!existsSync(workspace as string)) {\n await mkdir(workspace as string, { recursive: true });\n }\n } catch (error) {\n throw errors.workspaceNotFound(workspace as string);\n }\n\n // Step 4: Connection configuration\n p.log.step(pc.cyan('Connection Configuration'));\n\n const wsUrl = await p.text({\n message: 'Server WebSocket URL',\n placeholder: 'ws://localhost:3000/ws/runner',\n defaultValue: 'ws://localhost:3000/ws/runner',\n });\n\n if (p.isCancel(wsUrl)) {\n handleCancel();\n return;\n }\n\n const apiUrl = await p.text({\n message: 'API base URL',\n placeholder: 'http://localhost:3000',\n defaultValue: options.url || 'http://localhost:3000',\n });\n\n if (p.isCancel(apiUrl)) {\n handleCancel();\n return;\n }\n\n // Step 5: Security\n const secret = await p.text({\n message: 'Shared secret (press Enter to generate)',\n placeholder: 'Generated automatically',\n defaultValue: options.secret || generateSecret(),\n });\n\n if (p.isCancel(secret)) {\n handleCancel();\n return;\n }\n\n const runnerId = await p.text({\n message: 'Runner ID',\n placeholder: 'local',\n defaultValue: 'local',\n });\n\n if (p.isCancel(runnerId)) {\n handleCancel();\n return;\n }\n\n // Step 6: Database setup (if monorepo available)\n let databaseUrl: string | undefined;\n\n if (monorepoPath) {\n p.log.step(pc.cyan('Database Setup'));\n\n const dbChoice = await p.select({\n message: 'Database configuration',\n options: [\n {\n value: 'neon',\n label: 'Create Neon database (recommended)',\n hint: 'Free tier, persistent storage'\n },\n {\n value: 'existing',\n label: 'Use existing PostgreSQL',\n hint: 'Provide connection string'\n },\n ],\n });\n\n if (p.isCancel(dbChoice)) {\n handleCancel();\n return;\n }\n\n if (dbChoice === 'neon') {\n p.note(\n 'Opening Neon in your browser...\\nCreate a database and paste the connection string below.',\n pc.cyan('Database Setup')\n );\n databaseUrl = await setupDatabase(monorepoPath) || undefined;\n \n // Push schema if we have a database\n if (databaseUrl) {\n s.start('Pushing database schema');\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n if (pushed) {\n s.stop(pc.green('✓') + ' Schema initialized');\n } else {\n s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');\n }\n }\n } else if (dbChoice === 'existing') {\n databaseUrl = await connectManualDatabase() || undefined;\n \n // Push schema if we have a database\n if (databaseUrl) {\n s.start('Pushing database schema');\n const pushed = await pushDatabaseSchema(monorepoPath, databaseUrl);\n if (pushed) {\n s.stop(pc.green('✓') + ' Schema initialized');\n } else {\n s.stop(pc.yellow('⚠') + ' Schema push failed (you can retry later)');\n }\n }\n }\n }\n\n // Step 7: Save configuration\n try {\n configManager.set('workspace', workspace);\n if (monorepoPath) {\n configManager.set('monorepoPath', monorepoPath);\n }\n if (databaseUrl) {\n configManager.set('databaseUrl', databaseUrl);\n }\n configManager.set('apiUrl', normalizeUrl(apiUrl as string));\n configManager.set('server', {\n wsUrl: wsUrl,\n secret: secret,\n });\n configManager.set('runner', {\n id: runnerId,\n reconnectAttempts: 5,\n heartbeatInterval: 15000,\n });\n configManager.set('tunnel', {\n provider: 'cloudflare',\n autoCreate: true,\n });\n } catch (error) {\n throw new CLIError({\n code: 'CONFIG_INVALID',\n message: 'Failed to save configuration',\n cause: error instanceof Error ? error : new Error(String(error)),\n suggestions: [\n 'Check file permissions on config directory',\n 'Try running with sudo (not recommended)',\n ],\n });\n }\n\n // Validate\n const validation = configManager.validate();\n if (!validation.valid) {\n throw new CLIError({\n code: 'CONFIG_INVALID',\n message: 'Configuration validation failed',\n context: { errors: validation.errors },\n suggestions: validation.errors,\n });\n }\n\n // Success!\n p.outro(pc.green('✨ Hatchway is ready!'));\n\n p.note(\n `${pc.cyan('hatchway run')}\\n\\nThen open: ${pc.cyan('http://localhost:3000')}`,\n 'Next Steps'\n );\n\n return;\n }\n } catch (error) {\n // Handle cancellation gracefully\n if (error && typeof error === 'object' && 'name' in error) {\n if ((error as { name: string }).name === 'ExitPromptError' || (error as { code?: string }).code === 'CLACK_CANCEL') {\n handleCancel();\n return;\n }\n }\n\n // Re-throw for global error handler\n throw error;\n }\n}\n"],"names":[],"mappings":"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"}