diff --git a/docs/02-usage/020_running.md b/docs/02-usage/020_running.md index a1c49fa3..6a126368 100644 --- a/docs/02-usage/020_running.md +++ b/docs/02-usage/020_running.md @@ -162,8 +162,8 @@ to get a list of all available options. Some useful options include: * `--project `: specify the project to work on by name or path. - * `--project-from-cwd`: auto-detect the project from current working directory - (looking for a directory containing `.serena/project.yml` or `.git` in parent directories, activating the current directory if none is found); + * `--project-from-cwd`: auto-detect the project from current working directory + (looking for a directory containing `.serena/project.yml` or `.git` in parent directories and activating the containing directory as the project root, if any). This option is intended for CLI-based agents like Claude Code, Gemini and Codex, which are typically started from within the project directory and which do not change directories during their operation. * `--language-backend JetBrains`: use the Serena JetBrains Plugin as the language backend (overriding the default backend configured in the central configuration) diff --git a/docs/02-usage/030_clients.md b/docs/02-usage/030_clients.md index 2329ffb5..8db7e6e8 100644 --- a/docs/02-usage/030_clients.md +++ b/docs/02-usage/030_clients.md @@ -96,7 +96,7 @@ claude mcp add --scope user serena -- uvx --from git+https://github.com/oraios/s ``` Whenever you start Claude Code, Serena will search up from the current directory for `.serena/project.yml` or `.git` markers, -activating the current directory as the project if neither is found. +activating the containing directory as the project (if any). This mechanism makes it suitable for a single global MCP configuration. **Maximum Token Efficiency.** To maximize token efficiency, you may want to use Claude Code's diff --git a/src/serena/cli.py b/src/serena/cli.py index 2c1c9406..73aeb6c9 100644 --- a/src/serena/cli.py +++ b/src/serena/cli.py @@ -55,15 +55,14 @@ Overriding them means that they no longer apply, so you will need to re-specify them in addition to further modes if you want to keep them.""" -def find_project_root(root: str | Path | None = None) -> str: +def find_project_root(root: str | Path | None = None) -> str | None: """Find project root by walking up from CWD. Checks for .serena/project.yml first (explicit Serena project), then .git (git root). - Falls back to CWD if no marker is found. :param root: If provided, constrains the search to this directory and below (acts as a virtual filesystem root). Search stops at this boundary. - :return: absolute path to project root (falls back to CWD if no marker found) + :return: absolute path to project root or None if not suitable root is found """ current = Path.cwd().resolve() boundary = Path(root).resolve() if root is not None else None @@ -86,8 +85,7 @@ def find_project_root(root: str | Path | None = None) -> str: if (directory / ".git").exists(): # .git can be file (worktree) or dir return str(directory) - # Fall back to CWD - return str(current) + return None # --------------------- Utilities ------------------------------------- @@ -274,7 +272,10 @@ class TopLevelCommands(AutoRegisteringGroup): if project is not None or project_file_arg is not None: raise click.UsageError("--project-from-cwd cannot be used with --project or positional project argument") project = find_project_root() - log.info("Auto-detected project root: %s", project) + if project is not None: + log.info("Auto-detected project root: %s", project) + else: + log.warning("No project root found from %s; not activating any project", os.getcwd()) project_file = project_file_arg or project factory = SerenaMCPFactory(context=context, project=project_file, memory_log_handler=memory_log_handler)