11import argparse
2+ import logging
23
34from pathlib import Path
45from shutil import which
910
1011import questionary
1112
13+ logger = logging .getLogger (__name__ )
14+
1215from xaibo import Xaibo , __version__
1316try :
1417 from xaibo .server .web import XaiboWebServer
@@ -44,8 +47,8 @@ def check_uv_version():
4447 try :
4548 # Check if uv is available
4649 if not which ('uv' ):
47- print ( "Error: uv is not installed or not found in PATH." )
48- print ("Please install uv from https://docs.astral.sh/uv/getting-started/installation/" )
50+ logger . error ( " uv is not installed or not found in PATH." )
51+ logger . error ("Please install uv from https://docs.astral.sh/uv/getting-started/installation/" )
4952 sys .exit (1 )
5053
5154 # Get uv version
@@ -55,7 +58,7 @@ def check_uv_version():
5558 # Extract version number using regex (format: "uv 0.6.0" or similar)
5659 version_match = re .search (r'uv\s+(\d+\.\d+\.\d+)' , version_output )
5760 if not version_match :
58- print (f"Error: Could not parse uv version from output: { version_output } " )
61+ logger . error (f"Could not parse uv version from output: { version_output } " )
5962 sys .exit (1 )
6063
6164 version_str = version_match .group (1 )
@@ -64,16 +67,16 @@ def check_uv_version():
6467 # Check if version is at least 0.6.0
6568 min_version = [0 , 6 , 0 ]
6669 if version_parts < min_version :
67- print (f"Error: uv version { version_str } is too old." )
68- print ("Please upgrade to uv 0.6.0 or later." )
69- print ("Run: pip install --upgrade uv" )
70+ logger . error (f"uv version { version_str } is too old." )
71+ logger . error ("Please upgrade to uv 0.6.0 or later." )
72+ logger . error ("Run: pip install --upgrade uv" )
7073 sys .exit (1 )
71-
74+
7275 except subprocess .CalledProcessError as e :
73- print (f"Error: Failed to check uv version: { e } " )
76+ logger . error (f"Failed to check uv version: { e } " )
7477 sys .exit (1 )
7578 except Exception as e :
76- print (f"Error: Unexpected error while checking uv version: { e } " )
79+ logger . error (f"Unexpected error while checking uv version: { e } " )
7780 sys .exit (1 )
7881
7982def get_default_model_for_provider (provider ):
@@ -271,7 +274,7 @@ def eject_items(items_with_packages, dest_root: Path):
271274 dst_path = pkg_dir / src_path .name
272275
273276 if dst_path .exists ():
274- print (f"⚠️ Skipping { pkg_name } .{ src_path .name } ; already exists." )
277+ logger . warning (f"Skipping { pkg_name } .{ src_path .name } ; already exists." )
275278 continue
276279
277280 # Copy the file or directory
@@ -280,7 +283,7 @@ def eject_items(items_with_packages, dest_root: Path):
280283 else :
281284 shutil .copy2 (src_path , dst_path )
282285
283- print (f"✅ Ejected { pkg_name } .{ src_path .name } → { dst_path .relative_to (dest_root )} " )
286+ logger . info (f"Ejected { pkg_name } .{ src_path .name } → { dst_path .relative_to (dest_root )} " )
284287
285288def interactive_eject_mode (dest : Path ):
286289 """Interactive mode for ejecting modules."""
@@ -434,19 +437,19 @@ async def test_example_agent():
434437 )
435438
436439
437- print (f"{ project_name } initialized." )
440+ logger . info (f"{ project_name } initialized." )
438441
439442def eject (args , extra_args = []):
440443 """
441444 Eject primitive modules into the current project, with fuzzy suggestions on typos.
442445 """
443446 # If user ran `eject list`, list everything and exit
444447 if args .action == 'list' :
445- print ("Available packages and their ejectable items:\n " )
448+ logger . info ("Available packages and their ejectable items:" )
446449 for pkg in list_top_level_packages ():
447- print (f"- { pkg } :" )
450+ logger . info (f"- { pkg } :" )
448451 for item in sorted (list_module_contents (pkg ).keys ()):
449- print (f" • { item } " )
452+ logger . info (f" • { item } " )
450453 return
451454
452455 # Non-interactive mode: try to resolve each module name, suggest on typos
@@ -467,13 +470,13 @@ def eject(args, extra_args=[]):
467470 except FileNotFoundError :
468471 suggestions = get_close_matches (arg , available , n = 3 , cutoff = 0.6 )
469472 if suggestions :
470- print (f"Error: No module named '{ arg } ' found. Did you mean: { ', ' .join (suggestions )} ?" )
473+ logger . error (f"No module named '{ arg } ' found. Did you mean: { ', ' .join (suggestions )} ?" )
471474 else :
472- print (f"Error: No module named '{ arg } ' found." )
475+ logger . error (f"No module named '{ arg } ' found." )
473476 return
474477 except ValueError as e :
475478 # Ambiguous without a clear pkg.item
476- print (f"Error: { e } " )
479+ logger . error (f"{ e } " )
477480 return
478481
479482 eject_items (items_with_packages , dest )
@@ -487,6 +490,12 @@ def dev(args, extra_args=[]):
487490 Start a Xaibo development session
488491 :return:
489492 """
493+ if XaiboWebServer is None :
494+ logger .error ("XaiboWebServer is not available." )
495+ logger .error ("The webserver dependencies are required for 'xaibo dev'." )
496+ logger .error ("Install them with: uv add xaibo[webserver]" )
497+ sys .exit (1 )
498+
490499 sys .path .append (os .getcwd ())
491500 xaibo = Xaibo ()
492501
@@ -498,6 +507,12 @@ def serve(args, extra_args=[]):
498507 Run Xaibo server with just the OpenAI API
499508 :return:
500509 """
510+ if XaiboWebServer is None :
511+ logger .error ("XaiboWebServer is not available." )
512+ logger .error ("The webserver dependencies are required for 'xaibo serve'." )
513+ logger .error ("Install them with: uv add xaibo[webserver]" )
514+ sys .exit (1 )
515+
501516 sys .path .append (os .getcwd ())
502517
503518 xaibo = Xaibo ()
0 commit comments