Files
myagents/myclaude/cli.py
T
Zhengshou Lai bebf7ba17a feat(cli): merge chat into default behavior, default cwd to workspace/
- Remove standalone chat subcommand; chat becomes default behavior
- Default --cwd resolves to workspace/ instead of repo root
- Split CLAUDE.md: repo/ for CLI dev, workspace/ for daily workflow
- Add workspace/CLAUDE.md, workspace/.gitignore for tmp files
- Ignore MCP temp artifacts (.mcp.json, .playwright-mcp/)
- Clean up removed mail subcommand files
2026-04-23 08:38:59 +08:00

112 lines
2.8 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_myclaude_project_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:
root = get_myclaude_project_root()
fallback = Path.home() / ".myclaude"
if root == fallback:
stderr_console.print(
"[red]Cannot resolve myclaude project root.[/red] Run from the repo or set "
"[cyan]MYCLAUDE_PROJECT_ROOT[/cyan].",
)
raise SystemExit(1)
workspace = root / "workspace"
if workspace.is_dir():
return workspace
return 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()