machineconfig 5.22__py3-none-any.whl → 5.24__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 (39) hide show
  1. machineconfig/cluster/sessions_managers/helpers/zellij_local_helper.py +298 -0
  2. machineconfig/cluster/sessions_managers/helpers/zellij_local_helper_restart.py +77 -0
  3. machineconfig/cluster/sessions_managers/helpers/zellij_local_helper_with_panes.py +228 -0
  4. machineconfig/cluster/sessions_managers/helpers/zellij_local_manager_helper.py +165 -0
  5. machineconfig/cluster/sessions_managers/wt_local.py +100 -75
  6. machineconfig/cluster/sessions_managers/wt_local_manager.py +17 -21
  7. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  8. machineconfig/cluster/sessions_managers/wt_remote_manager.py +16 -8
  9. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
  10. machineconfig/cluster/sessions_managers/zellij_local.py +79 -371
  11. machineconfig/cluster/sessions_managers/zellij_local_manager.py +20 -168
  12. machineconfig/cluster/sessions_managers/zellij_remote.py +38 -39
  13. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +13 -10
  14. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +2 -6
  15. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
  16. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -17
  17. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -17
  18. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +1 -1
  19. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  20. machineconfig/scripts/python/ai/solutions/generic.py +15 -4
  21. machineconfig/scripts/python/cloud_repo_sync.py +7 -5
  22. machineconfig/scripts/python/count_lines.py +6 -6
  23. machineconfig/scripts/python/fire_agents_help_launch.py +6 -1
  24. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -3
  25. machineconfig/scripts/python/interactive.py +39 -3
  26. machineconfig/scripts/windows/share_smb.ps1 +0 -6
  27. machineconfig/setup_linux/ve.sh +1 -6
  28. machineconfig/setup_linux/web_shortcuts/interactive.sh +1 -6
  29. machineconfig/setup_windows/ve.ps1 +0 -1
  30. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +2 -10
  31. machineconfig/utils/source_of_truth.py +1 -1
  32. machineconfig-5.24.dist-info/METADATA +81 -0
  33. {machineconfig-5.22.dist-info → machineconfig-5.24.dist-info}/RECORD +36 -33
  34. machineconfig/cluster/sessions_managers/ffile.py +0 -4
  35. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  36. machineconfig-5.22.dist-info/METADATA +0 -188
  37. {machineconfig-5.22.dist-info → machineconfig-5.24.dist-info}/WHEEL +0 -0
  38. {machineconfig-5.22.dist-info → machineconfig-5.24.dist-info}/entry_points.txt +0 -0
  39. {machineconfig-5.22.dist-info → machineconfig-5.24.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- from typing import Dict, Optional, List, Any
2
+ from typing import Optional, Any
3
3
  from pathlib import Path
4
4
  import logging
5
5
  import json
@@ -11,18 +11,18 @@ from machineconfig.cluster.sessions_managers.wt_utils.layout_generator import WT
11
11
  from machineconfig.cluster.sessions_managers.wt_utils.process_monitor import WTProcessMonitor
12
12
  from machineconfig.cluster.sessions_managers.wt_utils.session_manager import WTSessionManager
13
13
  from machineconfig.cluster.sessions_managers.wt_utils.status_reporter import WTStatusReporter
14
- from machineconfig.utils.schemas.layouts.layout_types import TabConfig
14
+ from machineconfig.utils.schemas.layouts.layout_types import TabConfig, LayoutConfig
15
15
 
16
16
  logging.basicConfig(level=logging.INFO)
17
17
  logger = logging.getLogger(__name__)
18
- TMP_LAYOUT_DIR = Path.home().joinpath("tmp_results", "wt_layouts", "layout_manager")
18
+ TMP_LAYOUT_DIR = Path.home() / "tmp_results" / "wt_layouts"
19
19
 
20
20
 
21
21
  class WTRemoteLayoutGenerator:
22
- def __init__(self, remote_name: str, session_name_prefix: str):
23
- self.remote_name = remote_name
24
- self.session_name = session_name_prefix + "_" + WTLayoutGenerator.generate_random_suffix()
25
- self.tabs: List[TabConfig] = []
22
+ def __init__(self, layout_config: LayoutConfig, remote_name: str, session_name: str):
23
+ self.remote_name: str = remote_name
24
+ self.session_name: str = session_name
25
+ self.layout_config: LayoutConfig = layout_config.copy()
26
26
  self.script_path: Optional[str] = None
27
27
 
28
28
  # Initialize modular components
@@ -32,22 +32,30 @@ class WTRemoteLayoutGenerator:
32
32
  self.session_manager = WTSessionManager(self.remote_executor, self.session_name, TMP_LAYOUT_DIR)
33
33
  self.status_reporter = WTStatusReporter(self.process_monitor, self.session_manager)
34
34
 
35
- # Tabs are stored and used as List[TabConfig]; no legacy dict compatibility
36
-
37
- def create_wt_layout(self, tabs: List[TabConfig], output_dir: Optional[str]) -> str:
38
- logger.info(f"Creating Windows Terminal layout with {len(tabs)} tabs for remote '{self.remote_name}'")
39
- self.tabs = tabs
40
- if output_dir:
41
- output_path = Path(output_dir)
42
- else:
43
- output_path = TMP_LAYOUT_DIR
44
- self.script_path = self.layout_generator.create_wt_script(self.tabs, output_path, self.session_name)
45
- return self.script_path
35
+ def create_layout_file(self) -> bool:
36
+ """Create Windows Terminal layout file and return success status."""
37
+ tab_count = len(self.layout_config["layoutTabs"])
38
+ logger.info(f"Creating Windows Terminal layout with {tab_count} tabs for remote '{self.remote_name}'")
39
+
40
+ # Extract tabs from layout_config
41
+ tabs: list[TabConfig] = self.layout_config["layoutTabs"]
42
+ script_content = self.layout_generator.create_wt_script(tabs, self.session_name, window_name=None)
43
+
44
+ # Write to file
45
+ tmp_layout_dir = Path.home() / "tmp_results" / "wt_layouts" / "remote"
46
+ tmp_layout_dir.mkdir(parents=True, exist_ok=True)
47
+ random_suffix = WTLayoutGenerator.generate_random_suffix(8)
48
+ script_file = tmp_layout_dir / f"wt_layout_{self.session_name}_{random_suffix}.ps1"
49
+ script_file.write_text(script_content, encoding="utf-8")
50
+ self.script_path = str(script_file.absolute())
51
+
52
+ logger.info(f"✅ Remote layout created: {self.script_path}")
53
+ return True
46
54
 
47
55
  # Legacy methods for backward compatibility
48
56
 
49
- def to_dict(self) -> Dict[str, Any]:
50
- return {"remote_name": self.remote_name, "session_name": self.session_name, "tabs": self.tabs, "script_path": self.script_path, "created_at": datetime.now().isoformat(), "class_name": self.__class__.__name__}
57
+ def to_dict(self) -> dict[str, Any]:
58
+ return {"remote_name": self.remote_name, "session_name": self.session_name, "layout_config": self.layout_config, "script_path": self.script_path, "created_at": datetime.now().isoformat(), "class_name": self.__class__.__name__}
51
59
 
52
60
  def to_json(self, file_path: Optional[str]) -> str:
53
61
  # Generate file path if not provided
@@ -95,29 +103,18 @@ class WTRemoteLayoutGenerator:
95
103
  logger.warning(f"Class name mismatch: expected {cls.__name__}, got {data.get('class_name')}")
96
104
 
97
105
  # Create new instance
98
- # Extract session name prefix by removing the suffix
99
- session_name = data["session_name"]
100
- if "_" in session_name:
101
- session_name_prefix = "_".join(session_name.split("_")[:-1])
102
- else:
103
- session_name_prefix = session_name
104
-
105
- instance = cls(remote_name=data["remote_name"], session_name_prefix=session_name_prefix)
106
-
107
- # Restore state
108
- instance.session_name = data["session_name"]
109
- # New schema only
110
- if "tabs" in data:
111
- instance.tabs = data["tabs"]
112
- else:
113
- instance.tabs = []
106
+ instance = cls(
107
+ layout_config=data["layout_config"],
108
+ remote_name=data["remote_name"],
109
+ session_name=data["session_name"]
110
+ )
114
111
  instance.script_path = data["script_path"]
115
112
 
116
113
  logger.info(f"✅ Loaded WTRemoteLayoutGenerator from: {file_path}")
117
114
  return instance
118
115
 
119
116
  @staticmethod
120
- def list_saved_sessions(directory_path: Optional[str]) -> List[str]:
117
+ def list_saved_sessions(directory_path: Optional[str]) -> list[str]:
121
118
  if directory_path is None:
122
119
  dir_path = Path.home() / "tmp_results" / "wt_sessions" / "serialized"
123
120
  else:
@@ -132,7 +129,7 @@ class WTRemoteLayoutGenerator:
132
129
 
133
130
  if __name__ == "__main__":
134
131
  # Example usage
135
- sample_tabs: List[TabConfig] = [
132
+ sample_tabs: list[TabConfig] = [
136
133
  {"tabName": "🤖Bot1", "startDir": "~/code/bytesense/bithence", "command": "python bot1.py --create_new_bot True"},
137
134
  {"tabName": "🤖Bot2", "startDir": "~/code/bytesense/bithence", "command": "python bot2.py --create_new_bot True"},
138
135
  {"tabName": "📊Monitor", "startDir": "~", "command": "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10"},
@@ -144,10 +141,21 @@ if __name__ == "__main__":
144
141
  session_name = "test_remote_session"
145
142
 
146
143
  try:
144
+ # Create layout config from tabs
145
+ sample_layout: LayoutConfig = {
146
+ "layoutName": "RemoteBots",
147
+ "layoutTabs": sample_tabs
148
+ }
149
+
147
150
  # Create layout using the remote generator
148
- generator = WTRemoteLayoutGenerator(remote_name=remote_name, session_name_prefix=session_name)
149
- script_path = generator.create_wt_layout(sample_tabs, None)
150
- print(f"✅ Remote layout created successfully: {script_path}")
151
+ generator = WTRemoteLayoutGenerator(
152
+ layout_config=sample_layout,
153
+ remote_name=remote_name,
154
+ session_name=session_name
155
+ )
156
+ generator.create_layout_file()
157
+
158
+ print(f"✅ Remote layout created successfully: {generator.script_path}")
151
159
 
152
160
  # Check if Windows Terminal is available on remote
153
161
  wt_available = generator.remote_executor.check_wt_available()
@@ -170,7 +178,7 @@ if __name__ == "__main__":
170
178
  # Demonstrate loading (using the full path)
171
179
  loaded_generator = WTRemoteLayoutGenerator.from_json(saved_path)
172
180
  print(f"✅ Session loaded successfully: {loaded_generator.session_name}")
173
- print(f"📊 Loaded tabs: {[tab['tabName'] for tab in loaded_generator.tabs]}")
181
+ print(f"📊 Loaded tabs: {[tab['tabName'] for tab in loaded_generator.layout_config['layoutTabs']]}")
174
182
 
175
183
  # Show command preview
176
184
  preview = generator.layout_generator.generate_wt_command(sample_tabs)
@@ -178,7 +186,7 @@ if __name__ == "__main__":
178
186
 
179
187
  # Demonstrate status checking
180
188
  print(f"\n🔍 Checking command status on remote '{remote_name}':")
181
- generator.status_reporter.print_status_report(generator.tabs)
189
+ generator.status_reporter.print_status_report(sample_tabs)
182
190
 
183
191
  # Show Windows Terminal overview
184
192
  print("\n🖥️ Windows Terminal Overview:")
@@ -8,13 +8,14 @@ from rich.console import Console
8
8
  from machineconfig.utils.scheduler import Scheduler
9
9
  from machineconfig.cluster.sessions_managers.wt_local import run_command_in_wt_tab
10
10
  from machineconfig.cluster.sessions_managers.wt_remote import WTRemoteLayoutGenerator
11
- from machineconfig.utils.schemas.layouts.layout_types import TabConfig
11
+ from machineconfig.cluster.sessions_managers.wt_utils.layout_generator import WTLayoutGenerator
12
+ from machineconfig.utils.schemas.layouts.layout_types import TabConfig, LayoutConfig
12
13
 
13
- TMP_SERIALIZATION_DIR = Path.home().joinpath("tmp_results", "session_manager", "wt", "remote_manager")
14
14
 
15
15
  # Module-level logger to be used throughout this module
16
16
  logger = logging.getLogger(__name__)
17
17
  console = Console()
18
+ TMP_SERIALIZATION_DIR = Path.home() / "tmp_results" / "wt_sessions" / "serialized"
18
19
 
19
20
 
20
21
  class WTSessionManager:
@@ -23,10 +24,15 @@ class WTSessionManager:
23
24
  self.machine2wt_tabs = machine2wt_tabs # Store the original config
24
25
  self.managers: list[WTRemoteLayoutGenerator] = []
25
26
  for machine, tab_config in machine2wt_tabs.items():
26
- an_m = WTRemoteLayoutGenerator(remote_name=machine, session_name_prefix=self.session_name_prefix)
27
- # Convert legacy dict[str, tuple[str,str]] to List[TabConfig]
27
+ # Convert legacy dict[str, tuple[str,str]] to LayoutConfig
28
28
  tabs: list[TabConfig] = [{"tabName": name, "startDir": cwd, "command": cmd} for name, (cwd, cmd) in tab_config.items()]
29
- an_m.create_wt_layout(tabs=tabs, output_dir=None)
29
+ layout_config: LayoutConfig = {
30
+ "layoutName": f"{session_name_prefix}_{machine}",
31
+ "layoutTabs": tabs
32
+ }
33
+ session_name = f"{session_name_prefix}_{WTLayoutGenerator.generate_random_suffix(8)}"
34
+ an_m = WTRemoteLayoutGenerator(layout_config=layout_config, remote_name=machine, session_name=session_name)
35
+ an_m.create_layout_file()
30
36
  self.managers.append(an_m)
31
37
 
32
38
  def ssh_to_all_machines(self) -> str:
@@ -52,7 +58,8 @@ class WTSessionManager:
52
58
  if scheduler.cycle % 2 == 0:
53
59
  statuses = []
54
60
  for _idx, an_m in enumerate(self.managers):
55
- a_status = an_m.process_monitor.check_all_commands_status(an_m.tabs)
61
+ tabs = an_m.layout_config["layoutTabs"]
62
+ a_status = an_m.process_monitor.check_all_commands_status(tabs)
56
63
  statuses.append(a_status)
57
64
  keys = []
58
65
  for item in statuses:
@@ -220,7 +227,8 @@ class WTSessionManager:
220
227
  wt_status = manager.session_manager.check_wt_session_status()
221
228
 
222
229
  # Get commands status for this session
223
- commands_status = manager.process_monitor.check_all_commands_status(manager.tabs)
230
+ tabs = manager.layout_config["layoutTabs"]
231
+ commands_status = manager.process_monitor.check_all_commands_status(tabs)
224
232
 
225
233
  # Calculate summary for this session
226
234
  running_count = sum(1 for status in commands_status.values() if status.get("running", False))
@@ -343,7 +351,7 @@ class WTSessionManager:
343
351
  # Get Windows Terminal version
344
352
  wt_version = manager.session_manager.get_wt_version()
345
353
 
346
- overview[remote_name] = {"windows_info": windows_info, "wt_processes": wt_processes, "wt_version": wt_version, "session_name": manager.session_name, "tab_count": len(manager.tabs)}
354
+ overview[remote_name] = {"windows_info": windows_info, "wt_processes": wt_processes, "wt_version": wt_version, "session_name": manager.session_name, "tab_count": len(manager.layout_config["layoutTabs"])}
347
355
 
348
356
  except Exception as e:
349
357
  overview[manager.remote_name] = {"error": str(e), "session_name": manager.session_name}
@@ -130,34 +130,21 @@ class WTLayoutGenerator:
130
130
 
131
131
  return " ".join(wt_parts)
132
132
 
133
- def create_wt_script(self, tabs: List[TabConfig], output_dir: Path, session_name: str, window_name: str | None = None) -> str:
134
- """Create a Windows Terminal PowerShell script and return its absolute path."""
133
+ def create_wt_script(self, tabs: List[TabConfig], session_name: str, window_name: str | None = None) -> str:
134
+ """Create a Windows Terminal PowerShell script content and return it as string."""
135
135
  self.validate_tab_config(tabs)
136
136
 
137
137
  # Generate unique suffix for this script
138
138
  random_suffix = self.generate_random_suffix()
139
139
  wt_command = self.generate_wt_command(tabs, window_name or session_name)
140
140
 
141
- try:
142
- # Create output directory if it doesn't exist
143
- output_dir.mkdir(parents=True, exist_ok=True)
144
-
145
- # Create PowerShell script
146
- ps1_file = output_dir / f"wt_layout_{session_name}_{random_suffix}.ps1"
147
-
148
- # Create PowerShell script content
149
- text = f"""# Windows Terminal layout for {session_name}
141
+ # Create PowerShell script content
142
+ script_content = f"""# Windows Terminal layout for {session_name}
150
143
  # Generated on {random_suffix}
151
144
  {wt_command}
152
145
  """
153
- ps1_file.write_text(text, encoding="utf-8")
154
-
155
- logger.info(f"Windows Terminal PowerShell script created: {ps1_file.absolute()}")
156
- return str(ps1_file.absolute())
157
-
158
- except OSError as e:
159
- logger.error(f"Failed to create PowerShell script: {e}")
160
- raise
146
+ logger.info("Windows Terminal PowerShell script content generated")
147
+ return script_content
161
148
 
162
149
  def generate_split_pane_command(self, tabs: List[TabConfig], window_name: str | None = None) -> str:
163
150
  """Generate Windows Terminal command with split panes instead of separate tabs."""