Files
myagents/myclaude/cli.py
T
Zhengshou Lai 475a0911e2 feat(workspace): make workspace location configurable via env var
- Add MYCLAUDE_WORKSPACE_ROOT env var, default ~/workspace
- Auto-create workspace directory if it does not exist
- Move workspace/CLAUDE.md + .gitignore to workspace_template/
- Remove hardcoded symlink paths from workspace template
- Update get_workspace_root() with env-var priority logic
- Update metabot bots.json defaultWorkingDirectory to ~/workspace
2026-04-23 08:47:22 +08:00

101 lines
2.4 KiB
Python

"""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.option(
"--dangerously-allow-browser-control",
is_flag=True,
default=False,
help="Forward to claude: allow browser automation without confirmation.",
)
@click.pass_context
def cli(
ctx: click.Context,
cwd: str | None,
dangerously_allow_browser_control: bool,
) -> 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]
if dangerously_allow_browser_control:
cmd.append("--dangerously-allow-browser-control")
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()