fix(chat): register --cwd as Click option for shell completion
Replace manual ctx.args parsing with a proper @click.option using is_flag=False and flag_value='.'. This enables tab completion for the --cwd / -C option and directory-only path completion after it. Also bump click dependency to >=8.3.2 to avoid the optional-value regression in 8.3.0/8.3.1.
This commit is contained in:
+18
-48
@@ -3,7 +3,6 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import click
|
import click
|
||||||
@@ -27,45 +26,6 @@ def _resolve_chat_cwd() -> Path:
|
|||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
def _parse_cwd_from_args(args: list[str]) -> tuple[str | None, list[str]]:
|
|
||||||
"""
|
|
||||||
Parse --cwd with optional value from args.
|
|
||||||
|
|
||||||
Returns (cwd_value, remaining_args).
|
|
||||||
--cwd alone -> cwd_value='.'
|
|
||||||
--cwd /path -> cwd_value='/path'
|
|
||||||
--cwd . -> cwd_value='.'
|
|
||||||
"""
|
|
||||||
cwd_value: str | None = None
|
|
||||||
remaining: list[str] = []
|
|
||||||
skip_next = False
|
|
||||||
|
|
||||||
for i, arg in enumerate(args):
|
|
||||||
if skip_next:
|
|
||||||
skip_next = False
|
|
||||||
continue
|
|
||||||
|
|
||||||
if arg in ("--cwd", "-C"):
|
|
||||||
# Check if next arg exists and is not a flag
|
|
||||||
if i + 1 < len(args) and not args[i + 1].startswith("-"):
|
|
||||||
cwd_value = args[i + 1]
|
|
||||||
skip_next = True
|
|
||||||
else:
|
|
||||||
# --cwd alone, default to current directory
|
|
||||||
cwd_value = "."
|
|
||||||
elif arg.startswith("--cwd="):
|
|
||||||
cwd_value = arg[6:]
|
|
||||||
elif arg.startswith("-C="):
|
|
||||||
cwd_value = arg[3:]
|
|
||||||
elif arg.startswith("-C") and len(arg) > 2:
|
|
||||||
# -C/path or -C.
|
|
||||||
cwd_value = arg[2:]
|
|
||||||
else:
|
|
||||||
remaining.append(arg)
|
|
||||||
|
|
||||||
return cwd_value, remaining
|
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
"chat",
|
"chat",
|
||||||
context_settings={
|
context_settings={
|
||||||
@@ -79,8 +39,21 @@ def _parse_cwd_from_args(args: list[str]) -> tuple[str | None, list[str]]:
|
|||||||
default=False,
|
default=False,
|
||||||
help="Forward to claude: bypass permission checks (sandbox / isolated use only).",
|
help="Forward to claude: bypass permission checks (sandbox / isolated use only).",
|
||||||
)
|
)
|
||||||
|
@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: myclaude project root).",
|
||||||
|
)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def chat_cmd(ctx: click.Context, dangerously_skip_permissions: bool) -> None:
|
def chat_cmd(
|
||||||
|
ctx: click.Context,
|
||||||
|
dangerously_skip_permissions: bool,
|
||||||
|
cwd: str | None,
|
||||||
|
) -> None:
|
||||||
"""Run `claude` in the myclaude repo so CLAUDE.md and .claude/ apply; extra args pass through.
|
"""Run `claude` in the myclaude repo so CLAUDE.md and .claude/ apply; extra args pass through.
|
||||||
|
|
||||||
\b
|
\b
|
||||||
@@ -97,21 +70,18 @@ def chat_cmd(ctx: click.Context, dangerously_skip_permissions: bool) -> None:
|
|||||||
)
|
)
|
||||||
raise SystemExit(127)
|
raise SystemExit(127)
|
||||||
|
|
||||||
# Parse --cwd from raw args (Click doesn't support optional values natively)
|
if cwd is None:
|
||||||
cwd_value, remaining_args = _parse_cwd_from_args(ctx.args)
|
|
||||||
|
|
||||||
if cwd_value is None:
|
|
||||||
chat_cwd = _resolve_chat_cwd()
|
chat_cwd = _resolve_chat_cwd()
|
||||||
else:
|
else:
|
||||||
chat_cwd = Path(cwd_value).resolve()
|
chat_cwd = Path(cwd).resolve()
|
||||||
if not chat_cwd.is_dir():
|
if not chat_cwd.is_dir():
|
||||||
stderr_console.print(f"[red]Not a directory:[/red] {cwd_value}")
|
stderr_console.print(f"[red]Not a directory:[/red] {cwd}")
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
cmd: list[str] = [binary]
|
cmd: list[str] = [binary]
|
||||||
if dangerously_skip_permissions:
|
if dangerously_skip_permissions:
|
||||||
cmd.append("--dangerously-skip-permissions")
|
cmd.append("--dangerously-skip-permissions")
|
||||||
cmd.extend(remaining_args)
|
cmd.extend(ctx.args)
|
||||||
|
|
||||||
proc = subprocess.run(cmd, cwd=str(chat_cwd), check=False)
|
proc = subprocess.run(cmd, cwd=str(chat_cwd), check=False)
|
||||||
raise SystemExit(proc.returncode)
|
raise SystemExit(proc.returncode)
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ version = "0.1.0"
|
|||||||
description = "Myclaude CLI: package update and Claude Code launcher for this repo"
|
description = "Myclaude CLI: package update and Claude Code launcher for this repo"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"click>=8.0.0",
|
"click>=8.3.2",
|
||||||
"rich>=13.0.0",
|
"rich>=13.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user