devs-cli 2.0.3__tar.gz → 2.0.5__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.
- {devs_cli-2.0.3/devs_cli.egg-info → devs_cli-2.0.5}/PKG-INFO +1 -1
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/cli.py +77 -9
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/config.py +8 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5/devs_cli.egg-info}/PKG-INFO +1 -1
- {devs_cli-2.0.3 → devs_cli-2.0.5}/pyproject.toml +1 -1
- {devs_cli-2.0.3 → devs_cli-2.0.5}/LICENSE +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/README.md +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/__init__.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/core/__init__.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/core/integration.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/exceptions.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs/utils/__init__.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs_cli.egg-info/SOURCES.txt +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs_cli.egg-info/dependency_links.txt +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs_cli.egg-info/entry_points.txt +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs_cli.egg-info/requires.txt +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/devs_cli.egg-info/top_level.txt +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/setup.cfg +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_cli.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_cli_clean.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_cli_misc.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_cli_start.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_cli_stop.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_cli_vscode.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_container_manager.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_e2e.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_error_parsing.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_integration.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_live_mode.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_project.py +0 -0
- {devs_cli-2.0.3 → devs_cli-2.0.5}/tests/test_workspace_manager.py +0 -0
|
@@ -794,31 +794,41 @@ def runtests(dev_name: str, reset_workspace: bool, live: bool, env: tuple, debug
|
|
|
794
794
|
|
|
795
795
|
|
|
796
796
|
@cli.command()
|
|
797
|
-
@click.argument('dev_name')
|
|
797
|
+
@click.argument('dev_name', required=False)
|
|
798
|
+
@click.option('--auth', is_flag=True, help='Set up tunnel authentication (interactive, one-time setup)')
|
|
798
799
|
@click.option('--status', is_flag=True, help='Check tunnel status instead of starting')
|
|
799
800
|
@click.option('--kill', 'kill_tunnel', is_flag=True, help='Kill running tunnel')
|
|
800
801
|
@click.option('--live', is_flag=True, help='Start container with current directory mounted as workspace')
|
|
801
802
|
@click.option('--env', multiple=True, help='Environment variables to pass to container (format: VAR=value)')
|
|
802
803
|
@debug_option
|
|
803
|
-
def tunnel(dev_name: str, status: bool, kill_tunnel: bool, live: bool, env: tuple, debug: bool) -> None:
|
|
804
|
+
def tunnel(dev_name: str, auth: bool, status: bool, kill_tunnel: bool, live: bool, env: tuple, debug: bool) -> None:
|
|
804
805
|
"""Start a VS Code tunnel in devcontainer.
|
|
805
806
|
|
|
806
807
|
VS Code tunnels allow you to connect VS Code directly to the container
|
|
807
808
|
without SSH - the container initiates an outbound connection to Microsoft's
|
|
808
809
|
tunnel service, and your local VS Code connects through that.
|
|
809
810
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
811
|
+
First-time setup requires authentication:
|
|
812
|
+
devs tunnel --auth
|
|
813
|
+
|
|
814
|
+
After that, tunnels run in the background automatically.
|
|
814
815
|
|
|
815
816
|
DEV_NAME: Development environment name
|
|
816
817
|
|
|
817
|
-
Example: devs tunnel
|
|
818
|
+
Example: devs tunnel --auth # One-time auth setup (no project needed)
|
|
819
|
+
Example: devs tunnel sally # Start tunnel (background)
|
|
818
820
|
Example: devs tunnel sally --status # Check tunnel status
|
|
819
821
|
Example: devs tunnel sally --kill # Stop running tunnel
|
|
820
|
-
Example: devs tunnel sally --live # Start with current directory mounted
|
|
821
822
|
"""
|
|
823
|
+
# Handle authentication mode - no project or dev_name needed
|
|
824
|
+
if auth:
|
|
825
|
+
_handle_tunnel_auth(debug=debug)
|
|
826
|
+
return
|
|
827
|
+
|
|
828
|
+
# All other modes require dev_name
|
|
829
|
+
if not dev_name:
|
|
830
|
+
raise click.UsageError("DEV_NAME is required unless using --auth")
|
|
831
|
+
|
|
822
832
|
check_dependencies()
|
|
823
833
|
project = get_project()
|
|
824
834
|
|
|
@@ -865,7 +875,7 @@ def tunnel(dev_name: str, status: bool, kill_tunnel: bool, live: bool, env: tupl
|
|
|
865
875
|
)
|
|
866
876
|
|
|
867
877
|
else:
|
|
868
|
-
# Start the tunnel (
|
|
878
|
+
# Start the tunnel (background)
|
|
869
879
|
container_manager.start_tunnel(
|
|
870
880
|
dev_name=dev_name,
|
|
871
881
|
workspace_dir=workspace_dir,
|
|
@@ -879,6 +889,64 @@ def tunnel(dev_name: str, status: bool, kill_tunnel: bool, live: bool, env: tupl
|
|
|
879
889
|
sys.exit(1)
|
|
880
890
|
|
|
881
891
|
|
|
892
|
+
def _handle_tunnel_auth(debug: bool) -> None:
|
|
893
|
+
"""Handle VS Code tunnel authentication.
|
|
894
|
+
|
|
895
|
+
Runs the VS Code CLI on the host to authenticate. Auth is stored
|
|
896
|
+
in ~/.devs/vscode-cli/ and bind-mounted into containers.
|
|
897
|
+
"""
|
|
898
|
+
try:
|
|
899
|
+
config.ensure_directories()
|
|
900
|
+
|
|
901
|
+
console.print("🔐 Setting up VS Code tunnel authentication...")
|
|
902
|
+
console.print(f" Configuration will be saved to: {config.vscode_cli_dir}")
|
|
903
|
+
console.print("")
|
|
904
|
+
console.print(" Starting interactive authentication...")
|
|
905
|
+
console.print(" Follow the prompts to authenticate with GitHub")
|
|
906
|
+
console.print("")
|
|
907
|
+
|
|
908
|
+
env = os.environ.copy()
|
|
909
|
+
env['VSCODE_CLI_DATA_DIR'] = str(config.vscode_cli_dir)
|
|
910
|
+
|
|
911
|
+
cmd = ['code', 'tunnel', 'user', 'login', '--provider', 'github']
|
|
912
|
+
|
|
913
|
+
if debug:
|
|
914
|
+
console.print(f"[dim]Running: {' '.join(cmd)}[/dim]")
|
|
915
|
+
console.print(f"[dim]VSCODE_CLI_DATA_DIR: {config.vscode_cli_dir}[/dim]")
|
|
916
|
+
|
|
917
|
+
result = subprocess.run(cmd, env=env, check=False)
|
|
918
|
+
|
|
919
|
+
if result.returncode == 0:
|
|
920
|
+
console.print("")
|
|
921
|
+
console.print("✅ Tunnel authentication configured successfully!")
|
|
922
|
+
console.print(f" Configuration saved to: {config.vscode_cli_dir}")
|
|
923
|
+
console.print(" This authentication will be shared across all devcontainers")
|
|
924
|
+
console.print("")
|
|
925
|
+
console.print("💡 You can now start tunnels from any project:")
|
|
926
|
+
console.print(" devs tunnel <name>")
|
|
927
|
+
else:
|
|
928
|
+
console.print("")
|
|
929
|
+
console.print("[yellow]Authentication was cancelled or failed.[/yellow]")
|
|
930
|
+
|
|
931
|
+
except FileNotFoundError:
|
|
932
|
+
console.print("❌ VS Code CLI not found on host machine")
|
|
933
|
+
console.print("")
|
|
934
|
+
console.print("Please install VS Code CLI first:")
|
|
935
|
+
console.print(" https://code.visualstudio.com/docs/editor/command-line")
|
|
936
|
+
console.print("")
|
|
937
|
+
console.print("Or install the standalone CLI:")
|
|
938
|
+
console.print(" curl -fSL 'https://update.code.visualstudio.com/latest/cli-linux-x64/stable' -o /tmp/vscode-cli.tar.gz")
|
|
939
|
+
console.print(" sudo tar -xf /tmp/vscode-cli.tar.gz -C /usr/local/bin")
|
|
940
|
+
sys.exit(1)
|
|
941
|
+
|
|
942
|
+
except Exception as e:
|
|
943
|
+
console.print(f"❌ Failed to configure tunnel authentication: {e}")
|
|
944
|
+
if debug:
|
|
945
|
+
import traceback
|
|
946
|
+
console.print(traceback.format_exc())
|
|
947
|
+
sys.exit(1)
|
|
948
|
+
|
|
949
|
+
|
|
882
950
|
@cli.command()
|
|
883
951
|
@click.option('--all-projects', is_flag=True, help='List containers for all projects')
|
|
884
952
|
def list(all_projects: bool) -> None:
|
|
@@ -16,6 +16,7 @@ class Config(BaseConfig):
|
|
|
16
16
|
BRIDGE_DIR = Path.home() / ".devs" / "bridge"
|
|
17
17
|
CLAUDE_CONFIG_DIR = Path.home() / ".devs" / "claudeconfig"
|
|
18
18
|
CODEX_CONFIG_DIR = Path.home() / ".devs" / "codexconfig"
|
|
19
|
+
VSCODE_CLI_DIR = Path.home() / ".devs" / "vscode-cli"
|
|
19
20
|
|
|
20
21
|
@property
|
|
21
22
|
def container_labels(self) -> Dict[str, str]:
|
|
@@ -40,6 +41,12 @@ class Config(BaseConfig):
|
|
|
40
41
|
self.codex_config_dir = Path(codex_config_env)
|
|
41
42
|
else:
|
|
42
43
|
self.codex_config_dir = self.CODEX_CONFIG_DIR
|
|
44
|
+
|
|
45
|
+
vscode_cli_env = os.getenv("DEVS_VSCODE_CLI_DIR")
|
|
46
|
+
if vscode_cli_env:
|
|
47
|
+
self.vscode_cli_dir = Path(vscode_cli_env)
|
|
48
|
+
else:
|
|
49
|
+
self.vscode_cli_dir = self.VSCODE_CLI_DIR
|
|
43
50
|
|
|
44
51
|
def get_default_workspaces_dir(self) -> Path:
|
|
45
52
|
"""Get default workspaces directory for CLI package."""
|
|
@@ -58,6 +65,7 @@ class Config(BaseConfig):
|
|
|
58
65
|
super().ensure_directories()
|
|
59
66
|
self.claude_config_dir.mkdir(parents=True, exist_ok=True)
|
|
60
67
|
self.codex_config_dir.mkdir(parents=True, exist_ok=True)
|
|
68
|
+
self.vscode_cli_dir.mkdir(parents=True, exist_ok=True)
|
|
61
69
|
|
|
62
70
|
|
|
63
71
|
# Global config instance
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|