1+ from codetide .core .defaults import DEFAULT_SERIALIZATION_PATH
2+ from codetide import CodeTide
3+
4+ from pathlib import Path
5+ import argparse
6+ import asyncio
7+ import time
8+
9+ def safe_print (string :str ):
10+ try :
11+ # First try printing directly
12+ print (string )
13+ except (UnicodeEncodeError , UnicodeError ):
14+ try :
15+ # Try with UTF-8 encoding
16+ import sys
17+ if sys .stdout .encoding != 'utf-8' :
18+ sys .stdout .reconfigure (encoding = 'utf-8' ) # Python 3.7+
19+ print (string )
20+ except Exception :
21+ # Fallback to ASCII-safe output
22+ print (string .encode ('ascii' , 'replace' ).decode ('ascii' ))
23+
24+ async def init_project (args , force_build : bool = False , flush : bool = False ) -> CodeTide :
25+ storagePath = Path (args .project_path ) / DEFAULT_SERIALIZATION_PATH
26+ try :
27+ if force_build :
28+ raise FileNotFoundError ()
29+
30+ tide = CodeTide .deserialize (storagePath )
31+ await tide .check_for_updates (serialize = True , include_cached_ids = True )
32+ if flush :
33+ safe_print (f"[INIT] Initialized from cache: { storagePath } " )
34+
35+ except FileNotFoundError :
36+ st = time .time ()
37+ tide = await CodeTide .from_path (rootpath = args .project_path )
38+ tide .serialize (storagePath , include_cached_ids = True )
39+ if flush :
40+ safe_print (f"[INIT] Fresh parse of { args .project_path } : { len (tide .codebase .root )} files in { time .time ()- st :.2f} s" )
41+ return tide
42+
43+ async def handle_get (args ):
44+ tide = await init_project (args )
45+ result = tide .get (args .ids , context_depth = args .degree , as_string = True )
46+ if result :
47+ safe_print (result )
48+ else :
49+ safe_print (f"[GET] No matches found for { args .ids } " )
50+
51+ async def handle_tree (args ):
52+ tide = await init_project (args )
53+ result = tide .codebase .get_tree_view (args .include_modules , args .include_types )
54+ safe_print (result )
55+
56+ async def handle_reset (args ):
57+ tide = await init_project (args )
58+ await tide ._reset ()
59+ tide .serialize (include_cached_ids = True )
60+ safe_print (f"reseted project in { args .project_path } " )
61+
62+ def main ():
63+ parser = argparse .ArgumentParser (description = "CLI for VSCode Extension" )
64+ subparsers = parser .add_subparsers (dest = "command" , required = True )
65+
66+ parser_project = subparsers .add_parser ("project" , help = "Initialize project parser" )
67+ parser_project .add_argument ("project_path" , help = "Path to the current workspace/project" )
68+ parser_project .set_defaults (func = init_project , force_build = True , flush = True )
69+
70+ parser_get = subparsers .add_parser ("get" , help = "Get one or more items by ID" )
71+ parser_get .add_argument ("project_path" , help = "Path to the current workspace/project" )
72+ parser_get .add_argument ("ids" , nargs = "+" , help = "List of item IDs to get" )
73+ parser_get .add_argument ("--degree" , type = int , default = 1 , help = "Depth of retrieval" )
74+ parser_get .set_defaults (func = handle_get )
75+
76+ parser_tree = subparsers .add_parser ("tree" , help = "Get tree view of the codebase" )
77+ parser_tree .add_argument ("project_path" , help = "Path to the current workspace/project" )
78+ parser_tree .add_argument ("--include-modules" , action = "store_true" , help = "Include modules in tree view" )
79+ parser_tree .add_argument ("--include-types" , action = "store_true" , help = "Include types in tree view" )
80+ parser_tree .set_defaults (func = handle_tree )
81+
82+ parser_parse = subparsers .add_parser ("refresh" , help = "Refresh a tide project by reseting it" )
83+ parser_parse .add_argument ("project_path" , help = "Path to the current workspace/project" )
84+ parser_parse .set_defaults (func = handle_reset )
85+
86+ args = parser .parse_args ()
87+ asyncio .run (args .func (args ))
88+
89+ if __name__ == "__main__" :
90+ ### TODO if copy to clipboard pass compact_mode = true to handle_get
91+ main ()
0 commit comments