"""Environment paths and quick navigation.""" import functools import os import subprocess from pathlib import Path import click from mycli.config import config from mycli.utils import handle_errors @functools.lru_cache(maxsize=1) def _get_paths() -> dict[str, Path]: """Lazy load paths from config.""" return config.get_all_paths() @click.group(name="env") def env_cmd(): """Environment paths and navigation.""" pass @env_cmd.command("goto") @click.argument("name") @handle_errors def goto(name): """Print path for cd (use: cd $(mycli env goto )).""" paths = _get_paths() if name not in paths: click.echo(f"Unknown path: {name}", err=True) click.echo(f"Available: {', '.join(paths.keys())}", err=True) raise click.Exit(1) click.echo(paths[name]) @env_cmd.command("list") @handle_errors def list_paths(): """List all configured paths.""" paths = _get_paths() max_len = max(len(k) for k in paths.keys()) for name, path in sorted(paths.items()): exists = "✓" if path.exists() else "✗" click.echo(f"{name:{max_len}} {exists} {path}") @env_cmd.command("cd") @click.argument("name") @handle_errors def cd_path(name): """Change directory (launches new shell).""" paths = _get_paths() if name not in paths: click.echo(f"Unknown path: {name}", err=True) raise click.Exit(1) target = paths[name] if not target.exists(): click.echo(f"Path does not exist: {target}", err=True) raise click.Exit(1) shell = os.environ.get("SHELL", "/bin/zsh") click.echo(f"Starting shell in: {target}") subprocess.run([shell], cwd=target) @env_cmd.command("status") @handle_errors def status(): """Show environment status.""" paths = _get_paths() click.secho("=== Paths ===", fg="cyan") for name, path in sorted(paths.items()): exists = "✓" if path.exists() else "✗" click.echo(f" {name:12} [{exists}] {path}") click.secho("\n=== OpenFOAM ===", fg="cyan") openfoam_path = "/Volumes/OpenFOAM/openfoam/build" if Path("/Volumes/OpenFOAM").exists(): click.secho(f" Mounted: {openfoam_path}", fg="green") else: click.secho(" Not mounted", fg="red") # API Keys status (without showing actual values) click.secho("\n=== API Keys ===", fg="cyan") api_keys = config.get("api_keys", {}) for name in api_keys.keys(): env_var = f"{name.upper()}_API_KEY" is_set = "✓" if os.environ.get(env_var) else "✗" click.echo(f" {name:12} [{is_set}] {env_var}") # Feishu Apps status click.secho("\n=== Feishu Apps ===", fg="cyan") feishu_apps = config.get("feishu_apps", {}) for app_name in feishu_apps.keys(): app_id_var = f"{app_name.upper()}_APP_ID" is_set = "✓" if os.environ.get(app_id_var) else "✗" click.echo(f" {app_name:12} [{is_set}] {app_id_var}") @env_cmd.command("export") @click.argument("name", required=False) def export_env(name): """Print export statements for environment variables. Examples: mycli env export # Export all mycli env export deepseek # Export specific API key mycli env export feishu # Export all Feishu apps eval "$(mycli env export)" # Load in current shell """ if name is None: # Export all _export_api_keys() _export_feishu_apps() elif name == "feishu": _export_feishu_apps() elif name in config.get("api_keys", {}): _export_api_key(name) elif name in config.get("feishu_apps", {}): _export_feishu_app(name) else: click.echo(f"Unknown export target: {name}", err=True) click.echo(f"Available: api_keys ({', '.join(config.get('api_keys', {}).keys())}), " f"feishu_apps ({', '.join(config.get('feishu_apps', {}).keys())})", err=True) raise click.Exit(1) def _export_api_key(name: str): """Export a single API key.""" api_keys = config.get("api_keys", {}) if name not in api_keys: return env_var = f"{name.upper()}_API_KEY" value = api_keys[name] click.echo(f"export {env_var}={value}") def _export_api_keys(): """Export all API keys.""" api_keys = config.get("api_keys", {}) for name in api_keys.keys(): _export_api_key(name) def _export_feishu_app(name: str): """Export a single Feishu app.""" feishu_apps = config.get("feishu_apps", {}) if name not in feishu_apps: return app = feishu_apps[name] prefix = name.upper() click.echo(f"export {prefix}_APP_ID={app['app_id']}") click.echo(f"export {prefix}_APP_SECRET={app['app_secret']}") def _export_feishu_apps(): """Export all Feishu apps.""" feishu_apps = config.get("feishu_apps", {}) for name in feishu_apps.keys(): _export_feishu_app(name) @env_cmd.command("init") @click.option("--shell", "-s", "shell_type", type=click.Choice(["bash", "zsh", "fish"]), default="zsh") def init_shell(shell_type): """Print shell initialization snippet. Add this to your ~/.zshrc or ~/.bashrc: eval "$(mycli env init)" """ snippet = f"""# MyCLI environment initialization # Add this line to your ~/.{shell_type}rc: # eval "$(mycli env init)" # Export API keys and app credentials eval "$(mycli env export 2>/dev/null)" """ click.echo(snippet)