portacode 0.3.17.dev2__tar.gz → 0.3.18.dev0__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.
Files changed (46) hide show
  1. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/PKG-INFO +1 -1
  2. portacode-0.3.18.dev0/portacode/_version.py +34 -0
  3. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/project_state_handlers.py +61 -11
  4. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode.egg-info/PKG-INFO +1 -1
  5. portacode-0.3.17.dev2/portacode/_version.py +0 -21
  6. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/.claude/agents/communication-manager.md +0 -0
  7. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/.claude/settings.local.json +0 -0
  8. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/.gitignore +0 -0
  9. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/.gitmodules +0 -0
  10. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/LICENSE +0 -0
  11. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/MANIFEST.in +0 -0
  12. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/Makefile +0 -0
  13. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/README.md +0 -0
  14. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/backup.sh +0 -0
  15. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/docker-compose.yaml +0 -0
  16. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/README.md +0 -0
  17. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/__init__.py +0 -0
  18. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/__main__.py +0 -0
  19. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/cli.py +0 -0
  20. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/README.md +0 -0
  21. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/__init__.py +0 -0
  22. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/client.py +0 -0
  23. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/README.md +0 -0
  24. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +0 -0
  25. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/__init__.py +0 -0
  26. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/base.py +0 -0
  27. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/file_handlers.py +0 -0
  28. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/registry.py +0 -0
  29. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/session.py +0 -0
  30. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/system_handlers.py +0 -0
  31. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/tab_factory.py +0 -0
  32. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/handlers/terminal_handlers.py +0 -0
  33. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/multiplex.py +0 -0
  34. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/connection/terminal.py +0 -0
  35. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/data.py +0 -0
  36. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/keypair.py +0 -0
  37. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode/service.py +0 -0
  38. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode.egg-info/SOURCES.txt +0 -0
  39. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode.egg-info/dependency_links.txt +0 -0
  40. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode.egg-info/entry_points.txt +0 -0
  41. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode.egg-info/requires.txt +0 -0
  42. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/portacode.egg-info/top_level.txt +0 -0
  43. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/pyproject.toml +0 -0
  44. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/restore.sh +0 -0
  45. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/setup.cfg +0 -0
  46. {portacode-0.3.17.dev2 → portacode-0.3.18.dev0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portacode
3
- Version: 0.3.17.dev2
3
+ Version: 0.3.18.dev0
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.3.18.dev0'
32
+ __version_tuple__ = version_tuple = (0, 3, 18, 'dev0')
33
+
34
+ __commit_id__ = commit_id = None
@@ -465,11 +465,6 @@ class FileSystemWatcher:
465
465
  super().__init__()
466
466
 
467
467
  def on_any_event(self, event):
468
- # Skip events for .git folder and its contents to avoid noise
469
- path_parts = Path(event.src_path).parts
470
- if '.git' in path_parts:
471
- return
472
-
473
468
  # Skip debug files to avoid feedback loops
474
469
  if event.src_path.endswith('project_state_debug.json'):
475
470
  return
@@ -479,7 +474,33 @@ class FileSystemWatcher:
479
474
  if event.event_type in ('opened', 'closed'):
480
475
  return
481
476
 
482
- logger.info("File system event: %s - %s", event.event_type, event.src_path)
477
+ # Handle .git folder events separately for git status monitoring
478
+ path_parts = Path(event.src_path).parts
479
+ if '.git' in path_parts:
480
+ # Get the relative path within .git directory
481
+ try:
482
+ git_index = path_parts.index('.git')
483
+ git_relative_path = '/'.join(path_parts[git_index + 1:])
484
+ git_file = Path(event.src_path).name
485
+
486
+ # Monitor git files that indicate repository state changes
487
+ should_monitor_git_file = (
488
+ git_file == 'index' or # Staging area changes
489
+ git_file == 'HEAD' or # Branch switches
490
+ git_relative_path.startswith('refs/heads/') or # Branch updates
491
+ git_relative_path.startswith('refs/remotes/') or # Remote tracking branches
492
+ git_relative_path.startswith('logs/refs/heads/') or # Branch history
493
+ git_relative_path.startswith('logs/HEAD') # HEAD history
494
+ )
495
+
496
+ if should_monitor_git_file:
497
+ logger.info("Git status change detected: %s - %s", event.event_type, event.src_path)
498
+ else:
499
+ return # Skip other .git files
500
+ except (ValueError, IndexError):
501
+ return # Skip if can't parse .git path
502
+ else:
503
+ logger.info("File system event: %s - %s", event.event_type, event.src_path)
483
504
 
484
505
  # Schedule async task in the main event loop from this watchdog thread
485
506
  if self.watcher.event_loop and not self.watcher.event_loop.is_closed():
@@ -503,11 +524,6 @@ class FileSystemWatcher:
503
524
  logger.warning("Watchdog not available, cannot start watching: %s", path)
504
525
  return
505
526
 
506
- # Extra safety check: never watch .git folders
507
- if Path(path).name == '.git':
508
- logger.debug("Refusing to watch .git folder: %s", path)
509
- return
510
-
511
527
  if path not in self.watched_paths:
512
528
  try:
513
529
  # Use recursive=False to watch only direct contents of each folder
@@ -523,6 +539,27 @@ class FileSystemWatcher:
523
539
  else:
524
540
  logger.debug("Path already being watched: %s", path)
525
541
 
542
+ def start_watching_git_directory(self, git_path: str):
543
+ """Start watching a .git directory for git status changes."""
544
+ if not WATCHDOG_AVAILABLE or not self.observer:
545
+ logger.warning("Watchdog not available, cannot start watching git directory: %s", git_path)
546
+ return
547
+
548
+ if git_path not in self.watched_paths:
549
+ try:
550
+ # Watch .git directory recursively to catch changes in refs/, logs/, etc.
551
+ self.observer.schedule(self.event_handler, git_path, recursive=True)
552
+ self.watched_paths.add(git_path)
553
+ logger.info("Started watching git directory (recursive): %s", git_path)
554
+
555
+ if not self.observer.is_alive():
556
+ self.observer.start()
557
+ logger.info("Started file system observer")
558
+ except Exception as e:
559
+ logger.error("Error starting git directory watcher for %s: %s", git_path, e)
560
+ else:
561
+ logger.debug("Git directory already being watched: %s", git_path)
562
+
526
563
  def stop_watching(self, path: str):
527
564
  """Stop watching a specific path."""
528
565
  if not WATCHDOG_AVAILABLE or not self.observer:
@@ -673,6 +710,13 @@ class ProjectStateManager:
673
710
  for monitored_folder in project_state.monitored_folders:
674
711
  self.file_watcher.start_watching(monitored_folder.folder_path)
675
712
 
713
+ # For git repositories, also watch the .git directory for git status changes
714
+ if project_state.is_git_repo:
715
+ git_dir_path = os.path.join(project_state.project_folder_path, '.git')
716
+ if os.path.exists(git_dir_path):
717
+ self.file_watcher.start_watching_git_directory(git_dir_path)
718
+ logger.debug("Started monitoring .git directory for git status changes: %s", git_dir_path)
719
+
676
720
  logger.debug("Watchdog synchronized: watching %d monitored folders individually", len(project_state.monitored_folders))
677
721
 
678
722
  async def _sync_all_state_with_monitored_folders(self, project_state: ProjectState):
@@ -1196,6 +1240,7 @@ class ProjectStateManager:
1196
1240
 
1197
1241
  # Update Git status
1198
1242
  if git_manager:
1243
+ project_state.git_branch = git_manager.get_branch_name()
1199
1244
  project_state.git_status_summary = git_manager.get_status_summary()
1200
1245
  project_state.git_detailed_status = git_manager.get_detailed_status()
1201
1246
 
@@ -1268,6 +1313,11 @@ class ProjectStateManager:
1268
1313
  for monitored_folder in project_state.monitored_folders:
1269
1314
  self.file_watcher.stop_watching(monitored_folder.folder_path)
1270
1315
 
1316
+ # Stop watching .git directory if it was being monitored
1317
+ if project_state.is_git_repo:
1318
+ git_dir_path = os.path.join(project_state.project_folder_path, '.git')
1319
+ self.file_watcher.stop_watching(git_dir_path)
1320
+
1271
1321
  # Clean up managers
1272
1322
  self.git_managers.pop(client_session_key, None)
1273
1323
  self.projects.pop(client_session_key, None)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portacode
3
- Version: 0.3.17.dev2
3
+ Version: 0.3.18.dev0
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
@@ -1,21 +0,0 @@
1
- # file generated by setuptools-scm
2
- # don't change, don't track in version control
3
-
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
-
6
- TYPE_CHECKING = False
7
- if TYPE_CHECKING:
8
- from typing import Tuple
9
- from typing import Union
10
-
11
- VERSION_TUPLE = Tuple[Union[int, str], ...]
12
- else:
13
- VERSION_TUPLE = object
14
-
15
- version: str
16
- __version__: str
17
- __version_tuple__: VERSION_TUPLE
18
- version_tuple: VERSION_TUPLE
19
-
20
- __version__ = version = '0.3.17.dev2'
21
- __version_tuple__ = version_tuple = (0, 3, 17, 'dev2')
File without changes