1+ // EARLY LOGGING SETUP - Initialize before anything else
2+ import * as path from 'node:path' ;
3+ import { setAppLogFile , appDebug } from '../shared/logging/logger.js' ;
4+
5+ const earlyCwd = process . env . CODEMACHINE_CWD || process . cwd ( ) ;
6+ const earlyLogLevel = ( process . env . LOG_LEVEL || '' ) . trim ( ) . toLowerCase ( ) ;
7+ const earlyDebugFlag = ( process . env . DEBUG || '' ) . trim ( ) . toLowerCase ( ) ;
8+ const earlyDebugEnabled = earlyLogLevel === 'debug' || ( earlyDebugFlag !== '' && earlyDebugFlag !== '0' && earlyDebugFlag !== 'false' ) ;
9+ if ( earlyDebugEnabled ) {
10+ const appDebugLogPath = path . join ( earlyCwd , '.codemachine' , 'logs' , 'app-debug.log' ) ;
11+ setAppLogFile ( appDebugLogPath ) ;
12+ }
13+ appDebug ( '[Boot] CLI module loading started' ) ;
14+
115// ENSURE EMBEDDED RESOURCES EARLY (BEFORE IMPORTS)
216// This must run before any modules that might resolve the package root
17+ appDebug ( '[Boot] Importing embed module' ) ;
318import { ensure as ensureResources } from '../shared/runtime/embed.js' ;
419
20+ appDebug ( '[Boot] Ensuring embedded resources' ) ;
521const embeddedRoot = await ensureResources ( ) ;
22+ appDebug ( '[Boot] embeddedRoot=%s' , embeddedRoot ) ;
623
724if ( ! embeddedRoot && ! process . env . CODEMACHINE_INSTALL_DIR ) {
825 // Fallback to normal resolution if not embedded
26+ appDebug ( '[Boot] Resolving package root (fallback)' ) ;
927 const { resolvePackageRoot } = await import ( '../shared/runtime/root.js' ) ;
1028 try {
1129 const packageRoot = resolvePackageRoot ( import . meta. url , 'cli-setup' ) ;
1230 process . env . CODEMACHINE_INSTALL_DIR = packageRoot ;
13- } catch {
31+ appDebug ( '[Boot] CODEMACHINE_INSTALL_DIR=%s' , packageRoot ) ;
32+ } catch ( err ) {
33+ appDebug ( '[Boot] Failed to resolve package root: %s' , err ) ;
1434 // Continue without setting
1535 }
1636}
1737
1838// IMMEDIATE SPLASH - Only show for main TUI session
1939// Skip splash for: subcommands, help flags, or version flags
40+ appDebug ( '[Boot] Checking splash screen conditions' ) ;
2041const args = process . argv . slice ( 2 ) ;
42+ appDebug ( '[Boot] args=%o' , args ) ;
2143const hasSubcommand = args . length > 0 && ! args [ 0 ] . startsWith ( '-' ) ;
2244const hasHelpOrVersion = args . some ( arg =>
2345 arg === '--help' || arg === '-h' || arg === '--version' || arg === '-V'
2446) ;
2547const shouldSkipSplash = hasSubcommand || hasHelpOrVersion ;
48+ appDebug ( '[Boot] hasSubcommand=%s, hasHelpOrVersion=%s, shouldSkipSplash=%s' , hasSubcommand , hasHelpOrVersion , shouldSkipSplash ) ;
2649
2750if ( process . stdout . isTTY && ! shouldSkipSplash ) {
51+ appDebug ( '[Boot] Showing splash screen' ) ;
2852 const { rows = 24 , columns = 80 } = process . stdout ;
2953 const centerY = Math . floor ( rows / 2 ) ;
3054 const centerX = Math . floor ( columns / 2 ) ;
@@ -33,12 +57,14 @@ if (process.stdout.isTTY && !shouldSkipSplash) {
3357 process . stdout . write ( '\x1b[38;2;224;230;240mCode\x1b[1mMachine\x1b[0m' ) ;
3458 process . stdout . write ( `\x1b[${ centerY + 1 } ;${ centerX - 6 } H` ) ;
3559 process . stdout . write ( '\x1b[38;2;0;217;255m━━━━━━━━━━━━\x1b[0m' ) ;
60+ appDebug ( '[Boot] Splash screen displayed' ) ;
3661}
3762
63+ appDebug ( '[Boot] Importing remaining modules' ) ;
3864import { Command } from 'commander' ;
3965import { existsSync , realpathSync } from 'node:fs' ;
4066import { fileURLToPath } from 'node:url' ;
41- import * as path from 'node:path' ;
67+ appDebug ( '[Boot] Imports complete' ) ;
4268
4369const DEFAULT_SPEC_PATH = '.codemachine/inputs/specifications.md' ;
4470
@@ -51,6 +77,7 @@ async function initializeInBackground(cwd: string): Promise<void> {
5177
5278 // Only bootstrap if .codemachine doesn't exist
5379 if ( ! existsSync ( cmRoot ) ) {
80+ appDebug ( '[Init] Bootstrapping workspace (first run)' ) ;
5481 // Lazy load bootstrap utilities (only on first run)
5582 const { bootstrapWorkspace } = await import ( './services/workspace/index.js' ) ;
5683 const { resolvePackageRoot } = await import ( '../shared/runtime/root.js' ) ;
@@ -60,23 +87,31 @@ async function initializeInBackground(cwd: string): Promise<void> {
6087 const defaultTemplate = path . join ( templatesDir , 'codemachine.workflow.js' ) ;
6188
6289 await bootstrapWorkspace ( { cwd, templatePath : defaultTemplate } ) ;
90+ appDebug ( '[Init] Workspace bootstrapped' ) ;
6391 }
6492
6593 // Lazy load and initialize engine registry
94+ appDebug ( '[Init] Loading engine registry' ) ;
6695 const { registry } = await import ( '../infra/engines/index.js' ) ;
6796 const engines = registry . getAll ( ) ;
6897
6998 // Sync engine configs in background
99+ appDebug ( '[Init] Syncing %d engine configs' , engines . length ) ;
70100 for ( const engine of engines ) {
71101 if ( engine . syncConfig ) {
72102 await engine . syncConfig ( ) ;
73103 }
74104 }
105+ appDebug ( '[Init] Background initialization complete' ) ;
75106}
76107
77108export async function runCodemachineCli ( argv : string [ ] = process . argv ) : Promise < void > {
109+ appDebug ( '[CLI] runCodemachineCli started' ) ;
110+
78111 // Import version from auto-generated version file (works in compiled binaries)
112+ appDebug ( '[CLI] Importing version' ) ;
79113 const { VERSION } = await import ( './version.js' ) ;
114+ appDebug ( '[CLI] VERSION=%s' , VERSION ) ;
80115
81116 const program = new Command ( )
82117 . name ( 'codemachine' )
@@ -91,53 +126,84 @@ export async function runCodemachineCli(argv: string[] = process.argv): Promise<
91126
92127 // Start background initialization (non-blocking, fire-and-forget)
93128 // This runs while TUI is visible and user is reading/thinking
129+ appDebug ( '[CLI] Starting background initialization' ) ;
94130 initializeInBackground ( cwd ) . catch ( err => {
131+ appDebug ( '[CLI] Background init error: %s' , err ) ;
95132 console . error ( '[Background Init Error]' , err ) ;
96133 } ) ;
97134
98135 // Launch TUI immediately - don't wait for background init
99136 // Import via launcher to scope SolidJS transform to TUI only
137+ appDebug ( '[CLI] Launching TUI' ) ;
100138 const { startTUI } = await import ( '../cli/tui/launcher.js' ) ;
101139 await startTUI ( ) ;
140+ appDebug ( '[CLI] TUI exited' ) ;
102141 } ) ;
103142
104143 // Lazy load CLI commands only if user uses subcommands
105144 if ( argv . length > 2 && ! argv [ 2 ] . startsWith ( '-' ) ) {
145+ appDebug ( '[CLI] Loading subcommands' ) ;
106146 const { registerCli } = await import ( '../cli/index.js' ) ;
107147 await registerCli ( program ) ;
148+ appDebug ( '[CLI] Subcommands registered' ) ;
108149 }
109150
151+ appDebug ( '[CLI] Parsing command line' ) ;
110152 await program . parseAsync ( argv ) ;
153+ appDebug ( '[CLI] Command line parsed' ) ;
111154}
112155
156+ appDebug ( '[Boot] Checking shouldRunCli' ) ;
113157const shouldRunCli = ( ( ) => {
114158 const entry = process . argv [ 1 ] ;
115- if ( ! entry ) return false ;
159+ appDebug ( '[Boot] entry=%s' , entry ) ;
160+ if ( ! entry ) {
161+ appDebug ( '[Boot] No entry, returning false' ) ;
162+ return false ;
163+ }
116164
117165 // For compiled binaries, Bun.main will be the binary itself
118166 if ( typeof Bun !== 'undefined' && Bun . main ) {
167+ appDebug ( '[Boot] Checking Bun.main' ) ;
119168 try {
120169 const mainPath = fileURLToPath ( Bun . main ) ;
121170 const modulePath = fileURLToPath ( import . meta. url ) ;
122- if ( mainPath === modulePath ) return true ;
123- } catch {
171+ appDebug ( '[Boot] mainPath=%s, modulePath=%s' , mainPath , modulePath ) ;
172+ if ( mainPath === modulePath ) {
173+ appDebug ( '[Boot] Bun.main matches, returning true' ) ;
174+ return true ;
175+ }
176+ } catch ( err ) {
177+ appDebug ( '[Boot] Bun.main check failed: %s' , err ) ;
124178 // Continue to other checks
125179 }
126180 }
127181
128182 try {
129183 const resolvedEntry = realpathSync ( entry ) ;
130184 const modulePath = realpathSync ( fileURLToPath ( import . meta. url ) ) ;
131- return resolvedEntry === modulePath ;
132- } catch {
185+ appDebug ( '[Boot] resolvedEntry=%s, modulePath=%s' , resolvedEntry , modulePath ) ;
186+ const matches = resolvedEntry === modulePath ;
187+ appDebug ( '[Boot] realpathSync matches=%s' , matches ) ;
188+ return matches ;
189+ } catch ( err ) {
190+ appDebug ( '[Boot] realpathSync failed: %s, using fallback' , err ) ;
133191 // Fallback: if entry contains 'index' or 'codemachine', run CLI
134- return entry . includes ( 'index' ) || entry . includes ( 'codemachine' ) ;
192+ const fallback = entry . includes ( 'index' ) || entry . includes ( 'codemachine' ) ;
193+ appDebug ( '[Boot] fallback result=%s' , fallback ) ;
194+ return fallback ;
135195 }
136196} ) ( ) ;
137197
198+ appDebug ( '[Boot] shouldRunCli=%s' , shouldRunCli ) ;
199+
138200if ( shouldRunCli ) {
201+ appDebug ( '[Boot] Calling runCodemachineCli()' ) ;
139202 runCodemachineCli ( ) . catch ( ( error ) => {
203+ appDebug ( '[Boot] runCodemachineCli error: %s' , error ) ;
140204 console . error ( error ) ;
141205 process . exitCode = 1 ;
142206 } ) ;
207+ } else {
208+ appDebug ( '[Boot] CLI not run (shouldRunCli=false)' ) ;
143209}
0 commit comments