"""Myclaude CLI entrypoint.""" import os import shutil import subprocess from importlib.metadata import PackageNotFoundError, version from pathlib import Path import click from rich.console import Console from myclaude.commands import update_cmd, upgrade_cmd from myclaude.project_root import get_workspace_root stderr_console = Console(stderr=True) def _package_version() -> str: try: return version("myclaude") except PackageNotFoundError: return "0.0.0" def _resolve_chat_cwd() -> Path: return get_workspace_root() @click.group( invoke_without_command=True, context_settings={ "ignore_unknown_options": True, "allow_extra_args": True, }, ) @click.version_option(version=_package_version()) @click.option( "--cwd", "-C", is_flag=False, flag_value=".", default=None, type=click.Path(dir_okay=True, file_okay=False), help="Use specified path as working directory (default: workspace/).", ) @click.pass_context def cli( ctx: click.Context, cwd: str | None, ) -> None: """Myclaude: CLI toolkit. Run without subcommands to start Claude Code in workspace/. Extra arguments pass through to claude. """ if ctx.invoked_subcommand is not None: return binary = os.environ.get("CLAUDE_BIN") or shutil.which("claude") if not binary: stderr_console.print( "[red]claude CLI not found in PATH.[/red] Install Claude Code or set " "[cyan]CLAUDE_BIN[/cyan].", ) raise SystemExit(127) if cwd is None: chat_cwd = _resolve_chat_cwd() else: chat_cwd = Path(cwd).resolve() if not chat_cwd.is_dir(): stderr_console.print(f"[red]Not a directory:[/red] {cwd}") raise SystemExit(1) cmd: list[str] = [binary, "--dangerously-skip-permissions"] cmd.extend(ctx.args) proc = subprocess.run(cmd, cwd=str(chat_cwd), check=False) raise SystemExit(proc.returncode) cli.add_command(update_cmd) cli.add_command(upgrade_cmd, name="upgrade") def main() -> None: cli() if __name__ == "__main__": main()