machineconfig 3.82__py3-none-any.whl → 3.85__py3-none-any.whl

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.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

Files changed (32) hide show
  1. machineconfig/cluster/sessions_managers/zellij_local.py +2 -2
  2. machineconfig/cluster/sessions_managers/zellij_remote.py +2 -2
  3. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +2 -2
  4. machineconfig/jobs/python/vscode/api.py +8 -7
  5. machineconfig/scripts/python/ai/initai.py +1 -11
  6. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +115 -0
  7. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +78 -11
  8. machineconfig/scripts/python/cloud_copy.py +33 -27
  9. machineconfig/scripts/python/cloud_manager.py +0 -2
  10. machineconfig/scripts/python/cloud_mount.py +13 -10
  11. machineconfig/scripts/python/cloud_sync.py +30 -28
  12. machineconfig/scripts/python/croshell.py +46 -53
  13. machineconfig/scripts/python/dotfile.py +16 -16
  14. machineconfig/scripts/python/fire_jobs.py +32 -16
  15. machineconfig/scripts/python/fire_jobs_args_helper.py +43 -16
  16. machineconfig/scripts/python/helpers/helpers4.py +0 -2
  17. machineconfig/scripts/python/scheduler.py +0 -1
  18. machineconfig/scripts/python/share_terminal.py +41 -0
  19. machineconfig/scripts/python/start_slidev.py +15 -13
  20. machineconfig/scripts/python/start_terminals.py +19 -19
  21. machineconfig/scripts/python/t4.py +16 -0
  22. machineconfig/scripts/python/wifi_conn.py +16 -14
  23. machineconfig/scripts/python/wsl_windows_transfer.py +23 -29
  24. machineconfig/utils/ai/generate_file_checklist.py +17 -17
  25. {machineconfig-3.82.dist-info → machineconfig-3.85.dist-info}/METADATA +1 -1
  26. {machineconfig-3.82.dist-info → machineconfig-3.85.dist-info}/RECORD +29 -29
  27. {machineconfig-3.82.dist-info → machineconfig-3.85.dist-info}/entry_points.txt +5 -5
  28. machineconfig/cluster/templates/cli_gooey.py +0 -115
  29. machineconfig/jobs/python/vscode/link_ve.py +0 -63
  30. machineconfig/jobs/python/vscode/select_interpreter.py +0 -87
  31. {machineconfig-3.82.dist-info → machineconfig-3.85.dist-info}/WHEEL +0 -0
  32. {machineconfig-3.82.dist-info → machineconfig-3.85.dist-info}/top_level.txt +0 -0
@@ -4,13 +4,13 @@
4
4
  croshell
5
5
  """
6
6
 
7
- import argparse
7
+ from typing import Annotated, Optional
8
+ import typer
8
9
  from machineconfig.utils.path_extended import PathExtended as PathExtended
9
10
  from machineconfig.utils.accessories import randstr
10
11
 
11
12
  from machineconfig.utils.options import choose_from_options
12
13
  from machineconfig.utils.ve import get_ve_activate_line
13
- from typing import Optional
14
14
  from rich.console import Console
15
15
  from rich.panel import Panel
16
16
  from rich.text import Text
@@ -79,62 +79,55 @@ __file__ = PathExtended(r'{path}')
79
79
  return pycode
80
80
 
81
81
 
82
- def build_parser():
83
- parser = argparse.ArgumentParser(description="Generic Parser to launch crocodile shell.")
84
- # A FLAG:
85
- parser.add_argument("--module", "-m", help="flag to run the file as a module as opposed to main.", action="store_true", default=False) # default is running as main, unless indicated by --module flag.
86
- parser.add_argument("--newWindow", "-w", help="flag for running in new window.", action="store_true", default=False)
87
- parser.add_argument("--nonInteratctive", "-N", help="flag for a non-interactive session.", action="store_true", default=False)
88
- parser.add_argument("--python", "-p", help="flag to use python over IPython.", action="store_true", default=False)
89
- parser.add_argument("--fzf", "-F", help="search with fuzzy finder for python scripts and run them", action="store_true", default=False)
90
-
91
- # OPTIONAL KEYWORD
92
- parser.add_argument("--ve", "-v", help="virtual enviroment to use, defaults to activated ve, if existed, else ve.", default=None)
93
- parser.add_argument("--profile", "-P", help="ipython profile to use, defaults to default profile.", default=None)
94
- parser.add_argument("--read", "-r", dest="read", help="read a binary file.", default="")
95
- parser.add_argument("--file", "-f", dest="file", help="python file path to interpret", default="")
96
- parser.add_argument("--cmd", "-c", dest="cmd", help="python command to interpret", default="")
97
- parser.add_argument("--terminal", "-t", dest="terminal", help="specify which terminal to be used. Default console host.", default="") # can choose `wt`
98
- parser.add_argument("--shell", "-S", dest="shell", help="specify which shell to be used. Defaults to CMD.", default="")
99
- parser.add_argument("--jupyter", "-j", dest="jupyter", help="run in jupyter interactive console", action="store_true", default=False)
100
- parser.add_argument("--stViewer", "-s", dest="streamlit_viewer", help="view in streamlit app", action="store_true", default=False)
101
-
102
- args = parser.parse_args()
103
- # print(f"Crocodile.run: args of the firing command = {args.__dict__}")
104
-
82
+ def main(
83
+ module: Annotated[bool, typer.Option("--module", "-m", help="flag to run the file as a module as opposed to main.")] = False,
84
+ newWindow: Annotated[bool, typer.Option("--newWindow", "-w", help="flag for running in new window.")] = False,
85
+ nonInteratctive: Annotated[bool, typer.Option("--nonInteratctive", "-N", help="flag for a non-interactive session.")] = False,
86
+ python: Annotated[bool, typer.Option("--python", "-p", help="flag to use python over IPython.")] = False,
87
+ fzf: Annotated[bool, typer.Option("--fzf", "-F", help="search with fuzzy finder for python scripts and run them")] = False,
88
+ ve: Annotated[Optional[str], typer.Option("--ve", "-v", help="virtual enviroment to use, defaults to activated ve, if existed, else ve.")] = None,
89
+ profile: Annotated[Optional[str], typer.Option("--profile", "-P", help="ipython profile to use, defaults to default profile.")] = None,
90
+ read: Annotated[str, typer.Option("--read", "-r", help="read a binary file.")] = "",
91
+ file: Annotated[str, typer.Option("--file", "-f", help="python file path to interpret")] = "",
92
+ cmd: Annotated[str, typer.Option("--cmd", "-c", help="python command to interpret")] = "",
93
+ terminal: Annotated[str, typer.Option("--terminal", "-t", help="specify which terminal to be used. Default console host.")] = "",
94
+ shell: Annotated[str, typer.Option("--shell", "-S", help="specify which shell to be used. Defaults to CMD.")] = "",
95
+ jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="run in jupyter interactive console")] = False,
96
+ streamlit_viewer: Annotated[bool, typer.Option("--stViewer", "-s", help="view in streamlit app")] = False,
97
+ ) -> None:
105
98
  # ==================================================================================
106
99
  # flags processing
107
- interactivity = "" if args.nonInteratctive else "-i"
108
- interpreter = "python" if args.python else "ipython"
109
- ipython_profile: Optional[str] = args.profile
110
- file = PathExtended.cwd() # initialization value, could be modified according to args.
100
+ interactivity = "" if nonInteratctive else "-i"
101
+ interpreter = "python" if python else "ipython"
102
+ ipython_profile: Optional[str] = profile
103
+ file_obj = PathExtended.cwd() # initialization value, could be modified according to args.
111
104
 
112
- if args.cmd != "":
105
+ if cmd != "":
113
106
  text = "🖥️ Executing command from CLI argument"
114
107
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
115
108
  import textwrap
116
109
 
117
- program = textwrap.dedent(args.cmd)
110
+ program = textwrap.dedent(cmd)
118
111
 
119
- elif args.fzf:
112
+ elif fzf:
120
113
  text = "🔍 Searching for Python files..."
121
114
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
122
115
  options = [str(item) for item in PathExtended.cwd().search("*.py", r=True)]
123
- file = choose_from_options(msg="Choose a python file to run", options=options, fzf=True, multi=False)
124
- assert isinstance(file, str)
125
- program = PathExtended(file).read_text(encoding="utf-8")
126
- text = f"📄 Selected file: {PathExtended(file).name}"
116
+ file_selected = choose_from_options(msg="Choose a python file to run", options=options, fzf=True, multi=False)
117
+ assert isinstance(file_selected, str)
118
+ program = PathExtended(file_selected).read_text(encoding="utf-8")
119
+ text = f"📄 Selected file: {PathExtended(file_selected).name}"
127
120
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
128
121
 
129
- elif args.file != "":
130
- file = PathExtended(args.file.lstrip()).expanduser().absolute()
131
- program = get_read_pyfile_pycode(file, as_module=args.module, cmd=args.cmd)
132
- text1 = f"📄 Loading file: {file.name}"
133
- text2 = f"🔄 Mode: {'Module' if args.module else 'Script'}"
122
+ elif file != "":
123
+ file_obj = PathExtended(file.lstrip()).expanduser().absolute()
124
+ program = get_read_pyfile_pycode(file_obj, as_module=module, cmd=cmd)
125
+ text1 = f"📄 Loading file: {file_obj.name}"
126
+ text2 = f"🔄 Mode: {'Module' if module else 'Script'}"
134
127
  console.print(Panel(f"{text1}\n{text2}", title="[bold blue]Info[/bold blue]"))
135
128
 
136
- elif args.read != "":
137
- if args.streamlit_viewer:
129
+ elif read != "":
130
+ if streamlit_viewer:
138
131
  # text = "📊 STARTING STREAMLIT VIEWER"
139
132
  # console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
140
133
  # from machineconfig.scripts.python.viewer import run
@@ -145,9 +138,9 @@ def build_parser():
145
138
  # """
146
139
  # PROGRAM_PATH.write_text(data=final_program, encoding="utf-8")
147
140
  return None
148
- file = PathExtended(str(args.read).lstrip()).expanduser().absolute()
149
- program = get_read_data_pycode(str(file))
150
- text = f"📄 Reading data from: {file.name}"
141
+ file_obj = PathExtended(str(read).lstrip()).expanduser().absolute()
142
+ program = get_read_data_pycode(str(file_obj))
143
+ text = f"📄 Reading data from: {file_obj.name}"
151
144
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
152
145
 
153
146
  else: # if nothing is specified, then run in interactive mode.
@@ -174,9 +167,9 @@ print(f"🐊 Crocodile Shell | Running @ {Path.cwd()}")
174
167
  pyfile = PathExtended.tmp().joinpath(f"tmp_scripts/python/croshell/{randstr()}.py")
175
168
  pyfile.parent.mkdir(parents=True, exist_ok=True)
176
169
 
177
- if args.read != "":
170
+ if read != "":
178
171
  title = "Reading Data"
179
- elif args.file != "":
172
+ elif file != "":
180
173
  title = "Running Python File"
181
174
  else:
182
175
  title = "Executed code"
@@ -194,7 +187,7 @@ print(f"🐊 Crocodile Shell | Running @ {Path.cwd()}")
194
187
  {activate_ve_line}
195
188
 
196
189
  """
197
- if args.jupyter:
190
+ if jupyter:
198
191
  fire_line = f"code --new-window {str(pyfile)}"
199
192
  else:
200
193
  fire_line = interpreter
@@ -216,10 +209,10 @@ print(f"🐊 Crocodile Shell | Running @ {Path.cwd()}")
216
209
 
217
210
  subprocess.run(final_program, shell=True, check=True)
218
211
 
219
- # if platform.system() == "Windows":
220
- # return subprocess.run([f"powershell", "-Command", res], shell=True, capture_output=False, text=True, check=True)
221
- # else: return subprocess.run([res], shell=True, capture_output=False, text=True, check=True)
212
+
213
+ def arg_parser() -> None:
214
+ typer.run(main)
222
215
 
223
216
 
224
217
  if __name__ == "__main__":
225
- build_parser()
218
+ arg_parser()
@@ -3,21 +3,17 @@
3
3
  from machineconfig.utils.path_extended import PathExtended as PathExtended
4
4
  from machineconfig.utils.links import symlink_func
5
5
  from machineconfig.utils.source_of_truth import LIBRARY_ROOT, REPO_ROOT
6
- import argparse
6
+ from typing import Annotated
7
+ import typer
7
8
 
8
9
 
9
- def main():
10
- parser = argparse.ArgumentParser(description="FTP client")
11
-
12
- parser.add_argument("file", help="file/folder path.", default="")
13
- # FLAGS
14
- parser.add_argument("--overwrite", "-o", help="Overwrite.", action="store_true") # default is False
15
- # optional
16
- parser.add_argument("-d", "--dest", help="destination folder", default="")
17
-
18
- args = parser.parse_args()
19
- orig_path = PathExtended(args.file).expanduser().absolute()
20
- if args.dest == "":
10
+ def main(
11
+ file: Annotated[str, typer.Argument(help="file/folder path.")],
12
+ overwrite: Annotated[bool, typer.Option("--overwrite", "-o", help="Overwrite.")] = False,
13
+ dest: Annotated[str, typer.Option("--dest", "-d", help="destination folder")] = "",
14
+ ) -> None:
15
+ orig_path = PathExtended(file).expanduser().absolute()
16
+ if dest == "":
21
17
  if "Local" in str(orig_path):
22
18
  junction = orig_path.split(at="Local", sep=-1)[1]
23
19
  elif "Roaming" in str(orig_path):
@@ -28,11 +24,11 @@ def main():
28
24
  junction = orig_path.rel2home()
29
25
  new_path = PathExtended(REPO_ROOT).joinpath(junction)
30
26
  else:
31
- dest_path = PathExtended(args.dest).expanduser().absolute()
27
+ dest_path = PathExtended(dest).expanduser().absolute()
32
28
  dest_path.mkdir(parents=True, exist_ok=True)
33
29
  new_path = dest_path.joinpath(orig_path.name)
34
30
 
35
- symlink_func(this=orig_path, to_this=new_path, prioritize_to_this=args.overwrite)
31
+ symlink_func(this=orig_path, to_this=new_path, prioritize_to_this=overwrite)
36
32
 
37
33
  print("""
38
34
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -48,5 +44,9 @@ def main():
48
44
  """)
49
45
 
50
46
 
47
+ def arg_parser() -> None:
48
+ typer.run(main)
49
+
50
+
51
51
  if __name__ == "__main__":
52
- main()
52
+ arg_parser()
@@ -8,7 +8,6 @@ fire
8
8
  """
9
9
 
10
10
  from machineconfig.scripts.python.helpers.helpers4 import search_for_files_of_interest
11
- from machineconfig.scripts.python.helpers.helpers4 import convert_kwargs_to_fire_kwargs_str
12
11
  from machineconfig.scripts.python.helpers.helpers4 import parse_pyfile
13
12
  from machineconfig.scripts.python.helpers.helpers4 import get_import_module_code
14
13
  from machineconfig.utils.ve import get_ve_activate_line, get_ve_path_and_ipython_profile
@@ -17,7 +16,7 @@ from machineconfig.utils.path_helper import match_file_name, sanitize_path
17
16
 
18
17
  from machineconfig.utils.path_extended import PathExtended as PathExtended
19
18
  from machineconfig.utils.accessories import get_repo_root, randstr
20
- from machineconfig.scripts.python.fire_jobs_args_helper import FireJobArgs, extract_kwargs
19
+ from machineconfig.scripts.python.fire_jobs_args_helper import FireJobArgs, extract_kwargs, parse_fire_args_from_context
21
20
  import platform
22
21
  from typing import Optional, Annotated
23
22
  from pathlib import Path
@@ -26,7 +25,7 @@ import typer
26
25
  # import os
27
26
 
28
27
 
29
- def route(args: FireJobArgs) -> None:
28
+ def route(args: FireJobArgs, fire_args: str = "") -> None:
30
29
  if args.layout:
31
30
  from machineconfig.scripts.python.fire_jobs_layout_helper import handle_layout_args
32
31
 
@@ -49,11 +48,12 @@ def route(args: FireJobArgs) -> None:
49
48
  ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(choice_file)
50
49
  if ipy_profile is None:
51
50
  ipy_profile = "default"
52
- activate_ve_line = get_ve_activate_line(ve_root=args.ve or ve_root_from_file or "$HOME/code/machineconfig/.venv")
53
51
 
54
52
  if choice_file.suffix == ".py":
55
- kwargs = extract_kwargs(args)
53
+ kwargs = extract_kwargs(args) # This now returns empty dict, but kept for compatibility
54
+ activate_ve_line = get_ve_activate_line(ve_root=args.ve or ve_root_from_file or "$HOME/code/machineconfig/.venv")
56
55
  else:
56
+ activate_ve_line = ""
57
57
  kwargs = {}
58
58
 
59
59
  # ========================= choosing function to run
@@ -93,7 +93,6 @@ def route(args: FireJobArgs) -> None:
93
93
  if choice_file.suffix == ".py":
94
94
  if args.streamlit:
95
95
  import socket
96
-
97
96
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
98
97
  try:
99
98
  s.connect(("8.8.8.8", 1))
@@ -217,8 +216,7 @@ except ImportError as _ex:
217
216
  # both selected function and kwargs are mentioned in the made up script, therefore no need for fire module.
218
217
  command = f"{exe} {choice_file} "
219
218
  elif choice_function is not None:
220
- kwargs_str = convert_kwargs_to_fire_kwargs_str(kwargs)
221
- command = f"{exe} -m fire {choice_file} {choice_function} {kwargs_str}"
219
+ command = f"{exe} -m fire {choice_file} {choice_function} {fire_args}"
222
220
  elif args.streamlit:
223
221
  # for .streamlit config to work, it needs to be in the current directory.
224
222
  if args.holdDirectory:
@@ -230,8 +228,7 @@ except ImportError as _ex:
230
228
  command = rf""" cd /d {choice_file.parent} & {exe} {choice_file.name} """
231
229
  else:
232
230
  if choice_file.suffix == "":
233
- kwargs_raw = " ".join(args.kw) if args.kw is not None else ""
234
- command = f"{exe} {choice_file} {kwargs_raw}"
231
+ command = f"{exe} {choice_file} {fire_args}"
235
232
  else:
236
233
  # command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {PathExtended.cwd()}"
237
234
  command = f"{exe} {choice_file} "
@@ -330,7 +327,8 @@ python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
330
327
 
331
328
 
332
329
  def main(
333
- path: Annotated[str, typer.Argument(help="The directory containing the jobs")] = ".",
330
+ ctx: typer.Context,
331
+ path: Annotated[str, typer.Argument(help="Path to the Python file to run")] = ".",
334
332
  function: Annotated[Optional[str], typer.Argument(help="Function to run")] = None,
335
333
  ve: Annotated[str, typer.Option("--ve", "-v", help="Virtual environment name")] = "",
336
334
  cmd: Annotated[bool, typer.Option("--cmd", "-B", help="Create a cmd fire command to launch the job asynchronously")] = False,
@@ -351,10 +349,13 @@ def main(
351
349
  Nprocess: Annotated[int, typer.Option("--Nprocess", "-p", help="Number of processes to use")] = 1,
352
350
  zellij_tab: Annotated[Optional[str], typer.Option("--zellij_tab", "-z", help="Open in a new zellij tab")] = None,
353
351
  watch: Annotated[bool, typer.Option("--watch", "-w", help="Watch the file for changes")] = False,
354
- kw: Annotated[Optional[list[str]], typer.Option("--kw", help="Keyword arguments to pass to the function in the form of k1 v1 k2 v2 ... (meaning k1=v1, k2=v2, etc)")] = None,
355
352
  layout: Annotated[bool, typer.Option("--layout", "-L", help="Use layout configuration (Zellij Or WindowsTerminal)")] = False,
356
353
  ) -> None:
357
354
  """Main function to process fire jobs arguments."""
355
+
356
+ # Get Fire arguments from context
357
+ fire_args = parse_fire_args_from_context(ctx)
358
+
358
359
  args = FireJobArgs(
359
360
  path=path,
360
361
  function=function,
@@ -377,16 +378,31 @@ def main(
377
378
  Nprocess=Nprocess,
378
379
  zellij_tab=zellij_tab,
379
380
  watch=watch,
380
- kw=kw,
381
381
  layout=layout,
382
382
  )
383
- route(args)
383
+ try:
384
+ route(args, fire_args)
385
+ except SystemExit:
386
+ # Re-raise SystemExit to preserve exit codes and allow clean exits
387
+ raise
388
+ except Exception as e:
389
+ # For other exceptions, print clean error message and exit
390
+ import sys
391
+ print(f"❌ Error: {e}", file=sys.stderr)
392
+ sys.exit(1)
384
393
 
385
394
 
386
395
  def main_from_parser():
387
- typer.run(main)
396
+ # from trogon.typer import init_tui
397
+ # from trogon.typer import init_tui
398
+ from typer import Typer
399
+ app = Typer(add_completion=False)
400
+ app.command(context_settings={"allow_extra_args": True, "allow_interspersed_args": False})(main)
401
+ # typer.run(main)
402
+ # init_tui(app)
403
+ app()
388
404
 
389
405
 
390
406
  if __name__ == "__main__":
391
407
  # options, func_args = parse_pyfile(file_path="C:/Users/aalsaf01/code/machineconfig/myresources/crocodile/core.py")
392
- pass
408
+ main_from_parser()
@@ -1,6 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from typing import Optional, Annotated
3
- import typer
2
+ from typing import Optional, Any
4
3
 
5
4
 
6
5
  @dataclass
@@ -28,21 +27,49 @@ class FireJobArgs:
28
27
  Nprocess: int = 1
29
28
  zellij_tab: Optional[str] = None
30
29
  watch: bool = False
31
- kw: Optional[list[str]] = None
32
30
  layout: bool = False
33
31
 
34
32
 
35
33
  def extract_kwargs(args: FireJobArgs) -> dict[str, object]:
36
- str2obj = {"True": True, "False": False, "None": None}
37
- if args.kw is not None:
38
- assert len(args.kw) % 2 == 0, f"args.kw must be a list of even length. Got {len(args.kw)}"
39
- kwargs = dict(zip(args.kw[::2], args.kw[1::2]))
40
- kwargs: dict[str, object]
41
- for key, value in kwargs.items():
42
- if value in str2obj:
43
- kwargs[key] = str2obj[str(value)]
44
- if args.function is None: # if user passed arguments and forgot to pass function, then assume they want to run the main function.
45
- args.choose_function = True
46
- else:
47
- kwargs = {}
48
- return kwargs
34
+ """Extract kwargs from command line using -- separator.
35
+
36
+ Returns empty dict since kwargs are now parsed directly from sys.argv
37
+ using the -- separator pattern in the main function.
38
+ """
39
+ return {}
40
+
41
+
42
+ def parse_fire_args_from_argv() -> str:
43
+ """Parse arguments after -- separator for Fire compatibility.
44
+
45
+ Returns:
46
+ String of Fire-compatible arguments to append to command
47
+ """
48
+ import sys
49
+
50
+ if '--' in sys.argv:
51
+ separator_index = sys.argv.index('--')
52
+ fire_args = sys.argv[separator_index + 1:]
53
+ # Join all Fire arguments - they should already be in Fire format
54
+ return ' '.join(fire_args) if fire_args else ''
55
+
56
+ return ''
57
+
58
+
59
+ def parse_fire_args_from_context(ctx: Any) -> str:
60
+ """Parse Fire arguments from typer context.
61
+
62
+ Args:
63
+ ctx: Typer context containing raw arguments
64
+
65
+ Returns:
66
+ String of Fire-compatible arguments to append to command
67
+ """
68
+ # Get remaining args that weren't consumed by typer
69
+ if hasattr(ctx, 'args') and ctx.args:
70
+ args = ctx.args
71
+ # Filter out the -- separator if present
72
+ if args and args[0] == '--':
73
+ args = args[1:]
74
+ return ' '.join(args)
75
+ return ''
@@ -2,9 +2,7 @@ from typing import Any, Callable, Optional
2
2
  import inspect
3
3
  import os
4
4
 
5
- # import argparse
6
5
  from machineconfig.utils.path_extended import PathExtended as PathExtended
7
- # from machineconfig.utils.utils import choose_ssh_host
8
6
 
9
7
 
10
8
  def search_for_files_of_interest(path_obj: PathExtended):
@@ -4,7 +4,6 @@
4
4
  # from machineconfig.utils.scheduling import PathExtended, Report, DEFAULT_CONFIG, read_task_from_dir, main
5
5
 
6
6
  # def main_parse():
7
- # import argparse
8
7
  # print("\n" + "=" * 50)
9
8
  # print("📅 Welcome to the Scheduler CLI")
10
9
  # print("=" * 50 + "\n")
@@ -0,0 +1,41 @@
1
+
2
+
3
+ from pathlib import Path
4
+ from typing import Optional
5
+ # import typer
6
+
7
+
8
+ """
9
+ reference:
10
+ # https://github.com/tsl0922/ttyd/wiki/Serving-web-fonts
11
+ # -t "fontFamily=CaskaydiaCove" bash
12
+ # --terminal-type xterm-kitty
13
+
14
+ """
15
+
16
+
17
+ def share_terminal(port: int, password: Optional[str]) -> None:
18
+ if password is None:
19
+ pwd_path = Path.home().joinpath("dotfiles/creds/passwords/quick_password")
20
+ if pwd_path.exists():
21
+ password = pwd_path.read_text(encoding="utf-8").strip()
22
+ else:
23
+ raise ValueError("Password not provided and default password file does not exist.")
24
+
25
+ import socket
26
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
27
+ s.connect(('8.8.8.8',80))
28
+ local_ip_v4 = s.getsockname()[0]
29
+ s.close()
30
+
31
+ print(f"\n🌐 Access your terminal at: http://{local_ip_v4}:{port}\n")
32
+
33
+ code = f"""
34
+ #!/bin/bash
35
+ uv run --python 3.13 --with machineconfig install -ttyd
36
+
37
+ ttyd --writable -t enableSixel=true --port {port} --credential "$USER:{password}" -t 'theme={"background": "black"}' bash
38
+
39
+ """
40
+ import subprocess
41
+ subprocess.run(code, shell=True, check=True)
@@ -6,6 +6,8 @@ from machineconfig.utils.source_of_truth import CONFIG_PATH
6
6
  from machineconfig.utils.code import print_code
7
7
  from machineconfig.utils.path_extended import PathExtended as PathExtended
8
8
  from machineconfig.utils.terminal import Terminal
9
+ from typing import Annotated, Optional
10
+ import typer
9
11
  import subprocess
10
12
  import platform
11
13
 
@@ -47,28 +49,24 @@ def jupyter_to_markdown(file: PathExtended):
47
49
  return op_dir
48
50
 
49
51
 
50
- def main() -> None:
51
- import argparse
52
-
52
+ def main(
53
+ directory: Annotated[Optional[str], typer.Option("-d", "--directory", help="📁 Directory of the report.")] = None,
54
+ jupyter_file: Annotated[Optional[str], typer.Option("-j", "--jupyter-file", help="📓 Jupyter notebook file to convert to slides. If not provided, slides.md is used.")] = None,
55
+ ) -> None:
53
56
  print("\n" + "=" * 50)
54
57
  print("🎥 Welcome to the Slidev Presentation Tool")
55
58
  print("=" * 50 + "\n")
56
59
 
57
- parser = argparse.ArgumentParser()
58
- parser.add_argument("-d", "--directory", default=None, help="📁 Directory of the report.")
59
- parser.add_argument("-j", "--jupyter-file", default=None, help="📓 Jupyter notebook file to convert to slides. If not provided, slides.md is used.")
60
- args = parser.parse_args()
61
-
62
60
  port = PORT_DEFAULT
63
61
 
64
- if args.jupyter_file is not None:
62
+ if jupyter_file is not None:
65
63
  print("📓 Jupyter file provided. Converting to markdown...")
66
- report_dir = jupyter_to_markdown(PathExtended(args.jupyter_file))
64
+ report_dir = jupyter_to_markdown(PathExtended(jupyter_file))
67
65
  else:
68
- if args.directory is None:
66
+ if directory is None:
69
67
  report_dir = PathExtended.cwd()
70
68
  else:
71
- report_dir = PathExtended(args.directory)
69
+ report_dir = PathExtended(directory)
72
70
 
73
71
  assert report_dir.exists(), f"❌ Directory {report_dir} does not exist."
74
72
  assert report_dir.is_dir(), f"❌ {report_dir} is not a directory."
@@ -108,5 +106,9 @@ def main() -> None:
108
106
  print_code(code=program, lexer="bash", desc="Run the following command to start the presentation")
109
107
 
110
108
 
109
+ def arg_parser() -> None:
110
+ typer.run(main)
111
+
112
+
111
113
  if __name__ == "__main__":
112
- main()
114
+ arg_parser()
@@ -3,7 +3,8 @@
3
3
  from machineconfig.utils.options import choose_from_options, get_ssh_hosts
4
4
  import platform
5
5
  from itertools import cycle
6
- from typing import Literal
6
+ from typing import Literal, Optional, Annotated
7
+ import typer
7
8
 
8
9
 
9
10
  COLOR_SCHEMES = ["Campbell", "Campbell Powershell", "Solarized Dark", "Ubuntu-ColorScheme", "Retro"]
@@ -70,40 +71,35 @@ wt --window {window} --title {hosts[0]} powershell -Command "ssh {host_linux} {s
70
71
  return cmd
71
72
 
72
73
 
73
- def main():
74
- import argparse
75
-
74
+ def main(
75
+ panes: Annotated[Optional[int], typer.Option("--panes", "-p", help="🔲 The number of panes to open.")] = 4,
76
+ vertical: Annotated[bool, typer.Option("--vertical", "-V", help="↕️ Switch orientation to vertical from default horizontal.")] = False,
77
+ window: Annotated[int, typer.Option("--window", "-w", help="🪟 The window ID to use.")] = 0,
78
+ hosts: Annotated[Optional[list[str]], typer.Option("--hosts", "-H", help="🌐 The hosts to connect to.")] = None,
79
+ ) -> None:
76
80
  print("\n" + "=" * 50)
77
81
  print("🖥️ Welcome to the Terminal Starter Tool")
78
82
  print("=" * 50 + "\n")
79
83
 
80
- parser = argparse.ArgumentParser()
81
- parser.add_argument("--panes", "-p", type=int, help="🔲 The number of panes to open.", default=4)
82
- parser.add_argument("--vertical", "-V", action="store_true", help="↕️ Switch orientation to vertical from default horizontal.")
83
- parser.add_argument("--window", "-w", type=int, help="🪟 The window ID to use.", default=0) # 0 refers to this window.
84
- parser.add_argument("--hosts", "-H", type=str, nargs="*", help="🌐 The hosts to connect to.", default=None)
85
- args = parser.parse_args()
86
-
87
- if args.panes:
84
+ if panes:
88
85
  print("🔲 Configuring panes...")
89
- cmd = f"wt --window {args.window} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
86
+ cmd = f"wt --window {window} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
90
87
  cmd += f" `; new-tab --colorScheme '{next(THEMES_ITER)}' --profile pwsh --title 't2' --tabColor '#f59218' "
91
88
  cmd += f" `; new-tab --colorScheme '{next(THEMES_ITER)}' --profile pwsh --title 't3' --tabColor '#009999' "
92
- for idx in range(args.panes):
89
+ for idx in range(panes):
93
90
  if idx % 2 == 0:
94
91
  cmd += f" `; move-focus down split-pane --horizontal --size {next(SIZE_ITER)} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
95
92
  else:
96
93
  cmd += f" `; move-focus up split-pane --vertical --size {next(SIZE_ITER)} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
97
94
 
98
95
  else:
99
- if args.hosts is None:
96
+ if hosts is None:
100
97
  print("🌐 No hosts provided. Displaying options...")
101
98
  hosts = choose_from_options(msg="Select hosts:", options=get_ssh_hosts() + [THIS_MACHINE], multi=True, fzf=True)
102
99
  else:
103
- print("🌐 Using provided hosts:", args.hosts)
104
- hosts = args.hosts
100
+ print("🌐 Using provided hosts:", hosts)
105
101
  assert isinstance(hosts, list)
106
- cmd = main_windows_and_wsl(window=args.window, hosts=hosts, orientation="vertical" if args.vertical else "horizontal")
102
+ cmd = main_windows_and_wsl(window=window, hosts=hosts, orientation="vertical" if vertical else "horizontal")
107
103
 
108
104
  print("\n📋 Generated Command:")
109
105
  print("-" * 50)
@@ -117,5 +113,9 @@ def main():
117
113
  print("✅ Command saved successfully!\n")
118
114
 
119
115
 
116
+ def arg_parser() -> None:
117
+ typer.run(main)
118
+
119
+
120
120
  if __name__ == "__main__":
121
- main()
121
+ arg_parser()
@@ -0,0 +1,16 @@
1
+
2
+ import typer
3
+
4
+
5
+ def func(name: str):
6
+ print(f"Hello, {name}! from func")
7
+
8
+ def hello(name: str):
9
+ print(f"Hello, {name}!")
10
+
11
+ def main():
12
+ typer.run(hello)
13
+
14
+ if __name__ == "__main__":
15
+ # typer.run(hello)
16
+ pass