portacode 0.3.20.dev1__tar.gz → 0.3.20.dev2__tar.gz
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-0.3.20.dev1 → portacode-0.3.20.dev2}/PKG-INFO +1 -1
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/_version.py +2 -2
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/git_manager.py +20 -3
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/handlers.py +21 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/manager.py +15 -1
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode.egg-info/PKG-INFO +1 -1
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/.claude/agents/communication-manager.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/.claude/settings.local.json +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/.gitignore +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/.gitmodules +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/LICENSE +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/MANIFEST.in +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/Makefile +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/backup.sh +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/docker-compose.yaml +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/__main__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/cli.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/client.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/base.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/file_handlers.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/file_system_watcher.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/models.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/utils.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state_handlers.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/registry.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/session.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/system_handlers.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/tab_factory.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/terminal_handlers.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/multiplex.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/terminal.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/data.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/keypair.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/service.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode.egg-info/SOURCES.txt +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode.egg-info/dependency_links.txt +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode.egg-info/entry_points.txt +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode.egg-info/requires.txt +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode.egg-info/top_level.txt +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/pyproject.toml +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/restore.sh +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/run_tests.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/setup.cfg +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/setup.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test.sh +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_device_online.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_file_operations.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_login_flow.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_navigate_testing_folder.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_terminal_interaction.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_terminal_start.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/.env.example +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/README.md +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/cli.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/__init__.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/base_test.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/cli_manager.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/hierarchical_runner.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/playwright_manager.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/runner.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/shared_cli_manager.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/test_discovery.py +0 -0
- {portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/requirements.txt +0 -0
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.3.20.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 3, 20, '
|
|
20
|
+
__version__ = version = '0.3.20.dev2'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 3, 20, 'dev2')
|
|
@@ -1075,9 +1075,26 @@ class GitManager:
|
|
|
1075
1075
|
# Convert to relative path from repo root
|
|
1076
1076
|
rel_path = os.path.relpath(file_path, self.repo.working_dir)
|
|
1077
1077
|
|
|
1078
|
-
#
|
|
1079
|
-
|
|
1080
|
-
|
|
1078
|
+
# Check if repository has any commits (HEAD exists)
|
|
1079
|
+
has_commits = False
|
|
1080
|
+
try:
|
|
1081
|
+
# Try to get HEAD commit to check if repository has commits
|
|
1082
|
+
self.repo.head.commit
|
|
1083
|
+
has_commits = True
|
|
1084
|
+
except Exception:
|
|
1085
|
+
logger.debug("Repository has no commits yet (no HEAD)")
|
|
1086
|
+
has_commits = False
|
|
1087
|
+
|
|
1088
|
+
if has_commits:
|
|
1089
|
+
# Repository has commits - use git restore --staged
|
|
1090
|
+
self.repo.git.restore('--staged', rel_path)
|
|
1091
|
+
logger.info("Successfully unstaged file using restore: %s", rel_path)
|
|
1092
|
+
else:
|
|
1093
|
+
# Repository has no commits - use git rm --cached
|
|
1094
|
+
# This handles the case where files are staged but no initial commit exists
|
|
1095
|
+
self.repo.git.rm('--cached', rel_path)
|
|
1096
|
+
logger.info("Successfully unstaged file using rm --cached (no HEAD): %s", rel_path)
|
|
1097
|
+
|
|
1081
1098
|
return True
|
|
1082
1099
|
|
|
1083
1100
|
except Exception as e:
|
|
@@ -395,6 +395,13 @@ class ProjectStateGitStageHandler(AsyncHandler):
|
|
|
395
395
|
project_state = manager.projects[source_client_session]
|
|
396
396
|
project_state.git_status_summary = git_manager.get_status_summary()
|
|
397
397
|
project_state.git_detailed_status = git_manager.get_detailed_status()
|
|
398
|
+
|
|
399
|
+
# Force clear the last signature to ensure update is sent
|
|
400
|
+
# This is necessary because git operations should always trigger client updates
|
|
401
|
+
if hasattr(project_state, '_last_sent_signature'):
|
|
402
|
+
logger.info("Forcing git stage update by clearing signature cache")
|
|
403
|
+
project_state._last_sent_signature = None
|
|
404
|
+
|
|
398
405
|
await manager._send_project_state_update(project_state, server_project_id)
|
|
399
406
|
|
|
400
407
|
return {
|
|
@@ -444,6 +451,13 @@ class ProjectStateGitUnstageHandler(AsyncHandler):
|
|
|
444
451
|
project_state = manager.projects[source_client_session]
|
|
445
452
|
project_state.git_status_summary = git_manager.get_status_summary()
|
|
446
453
|
project_state.git_detailed_status = git_manager.get_detailed_status()
|
|
454
|
+
|
|
455
|
+
# Force clear the last signature to ensure update is sent
|
|
456
|
+
# This is necessary because git operations should always trigger client updates
|
|
457
|
+
if hasattr(project_state, '_last_sent_signature'):
|
|
458
|
+
logger.info("Forcing git unstage update by clearing signature cache")
|
|
459
|
+
project_state._last_sent_signature = None
|
|
460
|
+
|
|
447
461
|
await manager._send_project_state_update(project_state, server_project_id)
|
|
448
462
|
|
|
449
463
|
return {
|
|
@@ -493,6 +507,13 @@ class ProjectStateGitRevertHandler(AsyncHandler):
|
|
|
493
507
|
project_state = manager.projects[source_client_session]
|
|
494
508
|
project_state.git_status_summary = git_manager.get_status_summary()
|
|
495
509
|
project_state.git_detailed_status = git_manager.get_detailed_status()
|
|
510
|
+
|
|
511
|
+
# Force clear the last signature to ensure update is sent
|
|
512
|
+
# This is necessary because git operations should always trigger client updates
|
|
513
|
+
if hasattr(project_state, '_last_sent_signature'):
|
|
514
|
+
logger.info("Forcing git revert update by clearing signature cache")
|
|
515
|
+
project_state._last_sent_signature = None
|
|
516
|
+
|
|
496
517
|
await manager._send_project_state_update(project_state, server_project_id)
|
|
497
518
|
|
|
498
519
|
return {
|
|
@@ -887,10 +887,24 @@ class ProjectStateManager:
|
|
|
887
887
|
logger.info("🔍 [TRACE] _send_project_state_update called for session: %s", project_state.client_session_id)
|
|
888
888
|
|
|
889
889
|
# Create state signature for change detection
|
|
890
|
+
# Include detailed git file information to ensure staging/unstaging triggers updates
|
|
891
|
+
git_detailed_signature = None
|
|
892
|
+
if project_state.git_detailed_status:
|
|
893
|
+
# Create a more detailed signature that captures individual file staging states
|
|
894
|
+
staged_files = tuple(sorted([(f.file_abs_path, f.change_type) for f in project_state.git_detailed_status.staged_changes]))
|
|
895
|
+
unstaged_files = tuple(sorted([(f.file_abs_path, f.change_type) for f in project_state.git_detailed_status.unstaged_changes]))
|
|
896
|
+
untracked_files = tuple(sorted([f.file_abs_path for f in project_state.git_detailed_status.untracked_files]))
|
|
897
|
+
git_detailed_signature = {
|
|
898
|
+
"head_commit_hash": project_state.git_detailed_status.head_commit_hash,
|
|
899
|
+
"staged_files": staged_files,
|
|
900
|
+
"unstaged_files": unstaged_files,
|
|
901
|
+
"untracked_files": untracked_files
|
|
902
|
+
}
|
|
903
|
+
|
|
890
904
|
current_state_signature = {
|
|
891
905
|
"git_branch": project_state.git_branch,
|
|
892
906
|
"git_status_summary": project_state.git_status_summary,
|
|
893
|
-
"git_detailed_status":
|
|
907
|
+
"git_detailed_status": git_detailed_signature,
|
|
894
908
|
"open_tabs": tuple((tab.tab_id, tab.tab_type, tab.title) for tab in project_state.open_tabs.values()),
|
|
895
909
|
"active_tab": project_state.active_tab.tab_id if project_state.active_tab else None,
|
|
896
910
|
"items_count": len(project_state.items),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/file_handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/project_state/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/system_handlers.py
RENAMED
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/tab_factory.py
RENAMED
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/portacode/connection/handlers/terminal_handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/test_modules/test_navigate_testing_folder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/hierarchical_runner.py
RENAMED
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/playwright_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{portacode-0.3.20.dev1 → portacode-0.3.20.dev2}/testing_framework/core/shared_cli_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|