portacode 1.4.15__py3-none-any.whl → 1.4.15.dev1__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.
- portacode/_version.py +2 -2
- portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +95 -14
- portacode/connection/handlers/project_state/manager.py +3 -25
- portacode/connection/handlers/proxmox_infra.py +413 -364
- portacode/connection/terminal.py +0 -80
- {portacode-1.4.15.dist-info → portacode-1.4.15.dev1.dist-info}/METADATA +1 -1
- {portacode-1.4.15.dist-info → portacode-1.4.15.dev1.dist-info}/RECORD +11 -11
- {portacode-1.4.15.dist-info → portacode-1.4.15.dev1.dist-info}/WHEEL +1 -1
- {portacode-1.4.15.dist-info → portacode-1.4.15.dev1.dist-info}/entry_points.txt +0 -0
- {portacode-1.4.15.dist-info → portacode-1.4.15.dev1.dist-info}/licenses/LICENSE +0 -0
- {portacode-1.4.15.dist-info → portacode-1.4.15.dev1.dist-info}/top_level.txt +0 -0
portacode/connection/terminal.py
CHANGED
|
@@ -685,7 +685,6 @@ class TerminalManager:
|
|
|
685
685
|
try:
|
|
686
686
|
# Initialize project state
|
|
687
687
|
project_state = await manager.initialize_project_state(session_name, project_folder_path)
|
|
688
|
-
await self._restore_tabs_from_session_metadata(manager, project_state, session)
|
|
689
688
|
|
|
690
689
|
# Send initial project state to the client
|
|
691
690
|
initial_state_payload = {
|
|
@@ -711,85 +710,6 @@ class TerminalManager:
|
|
|
711
710
|
|
|
712
711
|
except Exception as exc:
|
|
713
712
|
logger.exception("terminal_manager: Error initializing project states for new sessions: %s", exc)
|
|
714
|
-
|
|
715
|
-
async def _restore_tabs_from_session_metadata(self, manager, project_state, session):
|
|
716
|
-
"""Restore open tabs/active tab from client session metadata if available."""
|
|
717
|
-
if not session or not project_state:
|
|
718
|
-
return
|
|
719
|
-
|
|
720
|
-
descriptors = session.get("open_tabs") or []
|
|
721
|
-
if not descriptors:
|
|
722
|
-
return
|
|
723
|
-
|
|
724
|
-
session_id = project_state.client_session_id
|
|
725
|
-
logger.info("terminal_manager: 🧭 Restoring %d tabs from metadata for session %s", len(descriptors), session_id)
|
|
726
|
-
|
|
727
|
-
for descriptor in descriptors:
|
|
728
|
-
parsed = self._parse_tab_descriptor(descriptor)
|
|
729
|
-
if not parsed:
|
|
730
|
-
continue
|
|
731
|
-
|
|
732
|
-
tab_type = parsed.get("tab_type")
|
|
733
|
-
file_path = parsed.get("file_path")
|
|
734
|
-
metadata = parsed.get("metadata", {})
|
|
735
|
-
|
|
736
|
-
if tab_type == "file" and file_path:
|
|
737
|
-
try:
|
|
738
|
-
await manager.open_file(session_id, file_path, set_active=False)
|
|
739
|
-
except Exception as exc:
|
|
740
|
-
logger.warning("terminal_manager: Failed to restore file tab %s for session %s: %s", file_path, session_id, exc)
|
|
741
|
-
continue
|
|
742
|
-
|
|
743
|
-
if tab_type == "diff" and file_path:
|
|
744
|
-
from_ref = metadata.get("from") or metadata.get("from_ref")
|
|
745
|
-
to_ref = metadata.get("to") or metadata.get("to_ref")
|
|
746
|
-
if not from_ref or not to_ref:
|
|
747
|
-
logger.warning("terminal_manager: Skipping diff tab %s for session %s because from/to references are missing", file_path, session_id)
|
|
748
|
-
continue
|
|
749
|
-
from_hash = metadata.get("from_hash") or metadata.get("fromHash")
|
|
750
|
-
to_hash = metadata.get("to_hash") or metadata.get("toHash")
|
|
751
|
-
try:
|
|
752
|
-
await manager.open_diff_tab(session_id, file_path, from_ref, to_ref, from_hash=from_hash, to_hash=to_hash)
|
|
753
|
-
except Exception as exc:
|
|
754
|
-
logger.warning("terminal_manager: Failed to restore diff tab %s for session %s: %s", file_path, session_id, exc)
|
|
755
|
-
continue
|
|
756
|
-
|
|
757
|
-
logger.debug("terminal_manager: Unknown tab descriptor ignored for session %s: %s", session_id, descriptor)
|
|
758
|
-
|
|
759
|
-
active_index = session.get("active_tab")
|
|
760
|
-
try:
|
|
761
|
-
active_index_int = int(active_index) if active_index is not None else None
|
|
762
|
-
except (TypeError, ValueError):
|
|
763
|
-
active_index_int = None
|
|
764
|
-
|
|
765
|
-
if active_index_int is not None and active_index_int >= 0:
|
|
766
|
-
current_tabs = list(project_state.open_tabs.values())
|
|
767
|
-
if 0 <= active_index_int < len(current_tabs):
|
|
768
|
-
try:
|
|
769
|
-
await manager.set_active_tab(session_id, current_tabs[active_index_int].tab_id)
|
|
770
|
-
except Exception as exc:
|
|
771
|
-
logger.warning("terminal_manager: Failed to set active tab for session %s: %s", session_id, exc)
|
|
772
|
-
else:
|
|
773
|
-
logger.debug("terminal_manager: Active tab index %s out of range for session %s", active_index_int, session_id)
|
|
774
|
-
|
|
775
|
-
def _parse_tab_descriptor(self, descriptor: str) -> Optional[Dict[str, Any]]:
|
|
776
|
-
"""Parse a URL-friendly tab descriptor string."""
|
|
777
|
-
if not descriptor:
|
|
778
|
-
return None
|
|
779
|
-
|
|
780
|
-
try:
|
|
781
|
-
parts = descriptor.split("|")
|
|
782
|
-
tab_type = parts[0] if parts else None
|
|
783
|
-
file_path = parts[1] if len(parts) > 1 else None
|
|
784
|
-
metadata = {}
|
|
785
|
-
for part in parts[2:]:
|
|
786
|
-
if "=" in part:
|
|
787
|
-
key, value = part.split("=", 1)
|
|
788
|
-
metadata[key] = value
|
|
789
|
-
return {"tab_type": tab_type, "file_path": file_path, "metadata": metadata}
|
|
790
|
-
except Exception as exc:
|
|
791
|
-
logger.warning("terminal_manager: Failed to parse tab descriptor '%s': %s", descriptor, exc)
|
|
792
|
-
return None
|
|
793
713
|
|
|
794
714
|
async def _send_targeted_terminal_list(self, message: Dict[str, Any], target_sessions: List[str]) -> None:
|
|
795
715
|
"""Send terminal_list command to specific client sessions.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
portacode/README.md,sha256=4dKtpvR8LNgZPVz37GmkQCMWIr_u25Ao63iW56s7Ke4,775
|
|
2
2
|
portacode/__init__.py,sha256=oB3sV1wXr-um-RXio73UG8E5Xx6cF2ZVJveqjNmC-vQ,1086
|
|
3
3
|
portacode/__main__.py,sha256=jmHTGC1hzmo9iKJLv-SSYe9BSIbPPZ2IOpecI03PlTs,296
|
|
4
|
-
portacode/_version.py,sha256=
|
|
4
|
+
portacode/_version.py,sha256=Gl8_1Kg3vuWq9htOanvxRd3kbf_a48CP9mpOXGbiomk,719
|
|
5
5
|
portacode/cli.py,sha256=mGLKoZ-T2FBF7IA9wUq0zyG0X9__-A1ao7gajjcVRH8,21828
|
|
6
6
|
portacode/data.py,sha256=5-s291bv8J354myaHm1Y7CQZTZyRzMU3TGe5U4hb-FA,1591
|
|
7
7
|
portacode/keypair.py,sha256=0OO4vHDcF1XMxCDqce61xFTlFwlTcmqe5HyGsXFEt7s,5838
|
|
@@ -12,9 +12,9 @@ portacode/connection/README.md,sha256=f9rbuIEKa7cTm9C98rCiBbEtbiIXQU11esGSNhSMiJ
|
|
|
12
12
|
portacode/connection/__init__.py,sha256=atqcVGkViIEd7pRa6cP2do07RJOM0UWpbnz5zXjGktU,250
|
|
13
13
|
portacode/connection/client.py,sha256=jtLb9_YufqPkzi9t8VQH3iz_JEMisbtY6a8L9U5weiU,14181
|
|
14
14
|
portacode/connection/multiplex.py,sha256=L-TxqJ_ZEbfNEfu1cwxgJ5vUdyRzZjsMy2Kx1diiZys,5237
|
|
15
|
-
portacode/connection/terminal.py,sha256=
|
|
15
|
+
portacode/connection/terminal.py,sha256=oyLPOVLPlUuN_eRvHPGazB51yi8W8JEF3oOEYxucGTE,45069
|
|
16
16
|
portacode/connection/handlers/README.md,sha256=HsLZG1QK1JNm67HsgL6WoDg9nxzKXxwkc5fJPFJdX5g,12169
|
|
17
|
-
portacode/connection/handlers/WEBSOCKET_PROTOCOL.md,sha256=
|
|
17
|
+
portacode/connection/handlers/WEBSOCKET_PROTOCOL.md,sha256=nbu1iQkqCCuUOyCdItBAETO0ab2UNWV060VpS8WyAhY,102810
|
|
18
18
|
portacode/connection/handlers/__init__.py,sha256=WSeBmi65GWFQPYt9M3E10rn0uZ_EPCJzNJOzSf2HZyw,2921
|
|
19
19
|
portacode/connection/handlers/base.py,sha256=oENFb-Fcfzwk99Qx8gJQriEMiwSxwygwjOiuCH36hM4,10231
|
|
20
20
|
portacode/connection/handlers/chunked_content.py,sha256=h6hXRmxSeOgnIxoU8CkmvEf2Odv-ajPrpHIe_W3GKcA,9251
|
|
@@ -22,7 +22,7 @@ portacode/connection/handlers/diff_handlers.py,sha256=iYTIRCcpEQ03vIPKZCsMTE5aZb
|
|
|
22
22
|
portacode/connection/handlers/file_handlers.py,sha256=nAJH8nXnX07xxD28ngLpgIUzcTuRwZBNpEGEKdRqohw,39507
|
|
23
23
|
portacode/connection/handlers/project_aware_file_handlers.py,sha256=AqgMnDqX2893T2NsrvUSCwjN5VKj4Pb2TN0S_SuboOE,9803
|
|
24
24
|
portacode/connection/handlers/project_state_handlers.py,sha256=v6ZefGW9i7n1aZLq2jOGumJIjYb6aHlPI4m1jkYewm8,1686
|
|
25
|
-
portacode/connection/handlers/proxmox_infra.py,sha256=
|
|
25
|
+
portacode/connection/handlers/proxmox_infra.py,sha256=73Lvf_VjiXLAfVlegBDH9VXr7JzXyN3SKESHhyd-v6s,73699
|
|
26
26
|
portacode/connection/handlers/registry.py,sha256=qXGE60sYEWg6ZtVQzFcZ5YI2XWR6lMgw4hAL9x5qR1I,6181
|
|
27
27
|
portacode/connection/handlers/session.py,sha256=uNGfiO_1B9-_yjJKkpvmbiJhIl6b-UXlT86UTfd6WYE,42219
|
|
28
28
|
portacode/connection/handlers/system_handlers.py,sha256=fr12QpOr_Z8KYGUU-AYrTQwRPAcrLK85hvj3SEq1Kw8,14757
|
|
@@ -35,7 +35,7 @@ portacode/connection/handlers/project_state/__init__.py,sha256=5ucIqk6Iclqg6bKkL
|
|
|
35
35
|
portacode/connection/handlers/project_state/file_system_watcher.py,sha256=r9_UKxWTbzum0jGqxIafe68Ced2Y3xOp3ZmkpBOfRpw,8573
|
|
36
36
|
portacode/connection/handlers/project_state/git_manager.py,sha256=iGQ7LYIA7uHsZHdj3HEc_LYo7S1Lqv6-AeyyMwknBPo,70027
|
|
37
37
|
portacode/connection/handlers/project_state/handlers.py,sha256=qgOSt26rxAGNxW07AoevTwDPBdxblX4J-dX-EjOKtg4,38232
|
|
38
|
-
portacode/connection/handlers/project_state/manager.py,sha256=
|
|
38
|
+
portacode/connection/handlers/project_state/manager.py,sha256=pRMZqPOTK9YE3abNxiAbnERIJmRys673HFOEIBiKnm4,67184
|
|
39
39
|
portacode/connection/handlers/project_state/models.py,sha256=EZTKvxHKs8QlQUbzI0u2IqfzfRRXZixUIDBwTGCJATI,4313
|
|
40
40
|
portacode/connection/handlers/project_state/utils.py,sha256=LsbQr9TH9Bz30FqikmtTxco4PlB_n0kUIuPKQ6Fb_mo,1665
|
|
41
41
|
portacode/link_capture/__init__.py,sha256=93LjyYDqzOimsIDBhsPibTl7tr-8DiIzyDF7JWQkE2A,1231
|
|
@@ -65,7 +65,7 @@ portacode/utils/__init__.py,sha256=NgBlWTuNJESfIYJzP_3adI1yJQJR0XJLRpSdVNaBAN0,3
|
|
|
65
65
|
portacode/utils/diff_apply.py,sha256=4Oi7ft3VUCKmiUE4VM-OeqO7Gk6H7PF3WnN4WHXtjxI,15157
|
|
66
66
|
portacode/utils/diff_renderer.py,sha256=S76StnQ2DLfsz4Gg0m07UwPfRp8270PuzbNaQq-rmYk,13850
|
|
67
67
|
portacode/utils/ntp_clock.py,sha256=VqCnWCTehCufE43W23oB-WUdAZGeCcLxkmIOPwInYHc,2499
|
|
68
|
-
portacode-1.4.15.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
|
|
68
|
+
portacode-1.4.15.dev1.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
|
|
69
69
|
test_modules/README.md,sha256=Do_agkm9WhSzueXjRAkV_xEj6Emy5zB3N3VKY5Roce8,9274
|
|
70
70
|
test_modules/__init__.py,sha256=1LcbHodIHsB0g-g4NGjSn6AMuCoGbymvXPYLOb6Z7F0,53
|
|
71
71
|
test_modules/test_device_online.py,sha256=QtYq0Dq9vME8Gp2O4fGSheqVf8LUtpsSKosXXk56gGM,1654
|
|
@@ -91,8 +91,8 @@ testing_framework/core/playwright_manager.py,sha256=Tw46qwxIhOFkS48C2IWIQHHNpEe-
|
|
|
91
91
|
testing_framework/core/runner.py,sha256=j2QwNJmAxVBmJvcbVS7DgPJUKPNzqfLmt_4NNdaKmZU,19297
|
|
92
92
|
testing_framework/core/shared_cli_manager.py,sha256=BESSNtyQb7BOlaOvZmm04T8Uezjms4KCBs2MzTxvzYQ,8790
|
|
93
93
|
testing_framework/core/test_discovery.py,sha256=2FZ9fJ8Dp5dloA-fkgXoJ_gCMC_nYPBnA3Hs2xlagzM,4928
|
|
94
|
-
portacode-1.4.15.dist-info/METADATA,sha256=
|
|
95
|
-
portacode-1.4.15.dist-info/WHEEL,sha256=
|
|
96
|
-
portacode-1.4.15.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
-
portacode-1.4.15.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
-
portacode-1.4.15.dist-info/RECORD,,
|
|
94
|
+
portacode-1.4.15.dev1.dist-info/METADATA,sha256=dDo_VYpC29NGZXMz95iwBAedzWnWhDFiU69MnZNSMwU,13051
|
|
95
|
+
portacode-1.4.15.dev1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
96
|
+
portacode-1.4.15.dev1.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
+
portacode-1.4.15.dev1.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
+
portacode-1.4.15.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|