devs-cli 1.2.0__tar.gz → 2.0.0__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 (31) hide show
  1. {devs_cli-1.2.0/devs_cli.egg-info → devs_cli-2.0.0}/PKG-INFO +1 -1
  2. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/cli.py +86 -0
  3. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/config.py +9 -2
  4. {devs_cli-1.2.0 → devs_cli-2.0.0/devs_cli.egg-info}/PKG-INFO +1 -1
  5. {devs_cli-1.2.0 → devs_cli-2.0.0}/pyproject.toml +1 -1
  6. {devs_cli-1.2.0 → devs_cli-2.0.0}/LICENSE +0 -0
  7. {devs_cli-1.2.0 → devs_cli-2.0.0}/README.md +0 -0
  8. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/__init__.py +0 -0
  9. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/core/__init__.py +0 -0
  10. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/core/integration.py +0 -0
  11. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/exceptions.py +0 -0
  12. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs/utils/__init__.py +0 -0
  13. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs_cli.egg-info/SOURCES.txt +0 -0
  14. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs_cli.egg-info/dependency_links.txt +0 -0
  15. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs_cli.egg-info/entry_points.txt +0 -0
  16. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs_cli.egg-info/requires.txt +0 -0
  17. {devs_cli-1.2.0 → devs_cli-2.0.0}/devs_cli.egg-info/top_level.txt +0 -0
  18. {devs_cli-1.2.0 → devs_cli-2.0.0}/setup.cfg +0 -0
  19. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_cli.py +0 -0
  20. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_cli_clean.py +0 -0
  21. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_cli_misc.py +0 -0
  22. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_cli_start.py +0 -0
  23. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_cli_stop.py +0 -0
  24. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_cli_vscode.py +0 -0
  25. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_container_manager.py +0 -0
  26. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_e2e.py +0 -0
  27. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_error_parsing.py +0 -0
  28. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_integration.py +0 -0
  29. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_live_mode.py +0 -0
  30. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_project.py +0 -0
  31. {devs_cli-1.2.0 → devs_cli-2.0.0}/tests/test_workspace_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devs-cli
3
- Version: 1.2.0
3
+ Version: 2.0.0
4
4
  Summary: DevContainer Management Tool - Manage multiple named devcontainers for any project
5
5
  Author: Dan Lester
6
6
  License-Expression: MIT
@@ -778,6 +778,92 @@ def runtests(dev_name: str, reset_workspace: bool, live: bool, env: tuple, debug
778
778
  sys.exit(1)
779
779
 
780
780
 
781
+ @cli.command()
782
+ @click.argument('dev_name')
783
+ @click.option('--status', is_flag=True, help='Check tunnel status instead of starting')
784
+ @click.option('--kill', 'kill_tunnel', is_flag=True, help='Kill running tunnel')
785
+ @click.option('--live', is_flag=True, help='Start container with current directory mounted as workspace')
786
+ @click.option('--env', multiple=True, help='Environment variables to pass to container (format: VAR=value)')
787
+ @debug_option
788
+ def tunnel(dev_name: str, status: bool, kill_tunnel: bool, live: bool, env: tuple, debug: bool) -> None:
789
+ """Start a VS Code tunnel in devcontainer.
790
+
791
+ VS Code tunnels allow you to connect VS Code directly to the container
792
+ without SSH - the container initiates an outbound connection to Microsoft's
793
+ tunnel service, and your local VS Code connects through that.
794
+
795
+ This is useful for:
796
+ - Connecting to containers on remote servers without port forwarding
797
+ - Working through firewalls (only outbound connections needed)
798
+ - Avoiding the "double-hop" of SSH + container attach
799
+
800
+ DEV_NAME: Development environment name
801
+
802
+ Example: devs tunnel sally # Start tunnel (interactive)
803
+ Example: devs tunnel sally --status # Check tunnel status
804
+ Example: devs tunnel sally --kill # Stop running tunnel
805
+ Example: devs tunnel sally --live # Start with current directory mounted
806
+ """
807
+ check_dependencies()
808
+ project = get_project()
809
+
810
+ # Load environment variables from DEVS.yml and merge with CLI --env flags
811
+ devs_env = DevsConfigLoader.load_env_vars(dev_name, project.info.name)
812
+ cli_env = parse_env_vars(env) if env else {}
813
+ extra_env = merge_env_vars(devs_env, cli_env) if devs_env or cli_env else None
814
+
815
+ if extra_env:
816
+ console.print(f"Environment variables: {', '.join(f'{k}={v}' for k, v in extra_env.items())}")
817
+
818
+ container_manager = ContainerManager(project, config)
819
+ workspace_manager = WorkspaceManager(project, config)
820
+
821
+ try:
822
+ # Ensure workspace exists (handles live mode internally)
823
+ workspace_dir = workspace_manager.create_workspace(dev_name, live=live)
824
+
825
+ if status:
826
+ # Check tunnel status
827
+ is_running, status_msg = container_manager.get_tunnel_status(
828
+ dev_name=dev_name,
829
+ workspace_dir=workspace_dir,
830
+ debug=debug,
831
+ live=live,
832
+ extra_env=extra_env
833
+ )
834
+ if is_running:
835
+ console.print(f"Tunnel status for {dev_name}:")
836
+ console.print(status_msg)
837
+ else:
838
+ console.print(f"No tunnel running in {dev_name}")
839
+ console.print(f" {status_msg}")
840
+
841
+ elif kill_tunnel:
842
+ # Kill the tunnel
843
+ console.print(f"Stopping tunnel in {dev_name}...")
844
+ container_manager.kill_tunnel(
845
+ dev_name=dev_name,
846
+ workspace_dir=workspace_dir,
847
+ debug=debug,
848
+ live=live,
849
+ extra_env=extra_env
850
+ )
851
+
852
+ else:
853
+ # Start the tunnel (interactive)
854
+ container_manager.start_tunnel(
855
+ dev_name=dev_name,
856
+ workspace_dir=workspace_dir,
857
+ debug=debug,
858
+ live=live,
859
+ extra_env=extra_env
860
+ )
861
+
862
+ except (ContainerError, WorkspaceError) as e:
863
+ console.print(f"Error with tunnel for {dev_name}: {e}")
864
+ sys.exit(1)
865
+
866
+
781
867
  @cli.command()
782
868
  @click.option('--all-projects', is_flag=True, help='List containers for all projects')
783
869
  def list(all_projects: bool) -> None:
@@ -2,14 +2,14 @@
2
2
 
3
3
  import os
4
4
  from pathlib import Path
5
- from typing import Optional
5
+ from typing import Dict, Optional
6
6
 
7
7
  from devs_common.config import BaseConfig
8
8
 
9
9
 
10
10
  class Config(BaseConfig):
11
11
  """Configuration settings for devs CLI."""
12
-
12
+
13
13
  # Default settings
14
14
  PROJECT_PREFIX = "dev"
15
15
  WORKSPACES_DIR = Path.home() / ".devs" / "workspaces"
@@ -17,6 +17,13 @@ class Config(BaseConfig):
17
17
  CLAUDE_CONFIG_DIR = Path.home() / ".devs" / "claudeconfig"
18
18
  CODEX_CONFIG_DIR = Path.home() / ".devs" / "codexconfig"
19
19
 
20
+ @property
21
+ def container_labels(self) -> Dict[str, str]:
22
+ """Standard labels applied to containers created by CLI."""
23
+ labels = super().container_labels
24
+ labels["devs.source"] = "cli"
25
+ return labels
26
+
20
27
  def __init__(self) -> None:
21
28
  """Initialize configuration with environment variable overrides."""
22
29
  super().__init__()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devs-cli
3
- Version: 1.2.0
3
+ Version: 2.0.0
4
4
  Summary: DevContainer Management Tool - Manage multiple named devcontainers for any project
5
5
  Author: Dan Lester
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devs-cli"
7
- version = "1.2.0"
7
+ version = "2.0.0"
8
8
  description = "DevContainer Management Tool - Manage multiple named devcontainers for any project"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
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