fix(cli): resolve persistence bug, lint issues, and import placement (#8675 / #8623)
CI / benchmark-publish (pull_request) Has been skipped
CI / push-validation (pull_request) Successful in 45s
CI / helm (pull_request) Successful in 51s
CI / lint (pull_request) Failing after 1m19s
CI / build (pull_request) Successful in 1m17s
CI / benchmark-regression (pull_request) Failing after 1m32s
CI / quality (pull_request) Successful in 1m30s
CI / typecheck (pull_request) Successful in 1m35s
CI / security (pull_request) Successful in 2m7s
CI / integration_tests (pull_request) Successful in 4m48s
CI / e2e_tests (pull_request) Successful in 4m58s
CI / unit_tests (pull_request) Failing after 6m15s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / status-check (pull_request) Failing after 3s
CI / benchmark-publish (pull_request) Has been skipped
CI / push-validation (pull_request) Successful in 45s
CI / helm (pull_request) Successful in 51s
CI / lint (pull_request) Failing after 1m19s
CI / build (pull_request) Successful in 1m17s
CI / benchmark-regression (pull_request) Failing after 1m32s
CI / quality (pull_request) Successful in 1m30s
CI / typecheck (pull_request) Successful in 1m35s
CI / security (pull_request) Successful in 2m7s
CI / integration_tests (pull_request) Successful in 4m48s
CI / e2e_tests (pull_request) Successful in 4m58s
CI / unit_tests (pull_request) Failing after 6m15s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / status-check (pull_request) Failing after 3s
This commit is contained in:
@@ -40,6 +40,11 @@ from cleveragents.core.exceptions import (
|
||||
ValidationError,
|
||||
)
|
||||
|
||||
from cleveragents.cli.commands.project_switch import switch_project
|
||||
|
||||
|
||||
_FORMAT_HELP = "Output format: json, yaml, plain, or rich (default: rich)"
|
||||
|
||||
# Create sub-app for project commands
|
||||
app = typer.Typer(help="Project management commands")
|
||||
file_filter_app = typer.Typer(
|
||||
@@ -48,8 +53,7 @@ file_filter_app = typer.Typer(
|
||||
console = _get_console()
|
||||
err_console = _get_err_console()
|
||||
|
||||
# Reusable --format option description
|
||||
_FORMAT_HELP = "Output format: json, yaml, plain, table, or rich (default: rich)"
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -994,17 +998,6 @@ def delete(
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Switch subcommand — delegates to standalone project_switch module
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
from cleveragents.cli.commands.project_switch import (
|
||||
switch_project,
|
||||
)
|
||||
|
||||
|
||||
@app.command(name="switch")
|
||||
def switch(
|
||||
name: Annotated[
|
||||
|
||||
@@ -12,6 +12,8 @@ Commands:
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from typing import Any
|
||||
|
||||
import typer
|
||||
@@ -58,8 +60,16 @@ def switch_project(
|
||||
err_console.print(f"[red]Project not found:[/red] {name}")
|
||||
raise typer.Exit(1) from exc
|
||||
|
||||
# Persist active-project selection to user config
|
||||
_persist_active_project(container, name)
|
||||
# Persist active-project selection via the project's .cleveragents dir
|
||||
proj_path = getattr(proj, 'path', None) or getattr(proj, 'local_path', None)
|
||||
if proj_path is not None:
|
||||
_persist_active_project(Path(proj_path), name)
|
||||
else:
|
||||
# Fallback: write to cwd project marker
|
||||
try:
|
||||
_persist_active_project(Path.cwd(), name)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
data = svc.project_to_dict(proj)
|
||||
|
||||
@@ -72,63 +82,22 @@ def switch_project(
|
||||
console.print(format_output(data, output_format))
|
||||
|
||||
|
||||
def _persist_active_project(container: Any, namespaced_name: str) -> None:
|
||||
"""Persist the active project name to ``~/.cleveragents/config.toml``.
|
||||
|
||||
Reads an existing config (if present), updates the
|
||||
``active_project`` key, and writes back. If no config file
|
||||
exists yet, one is created with the default directory structure.
|
||||
def _persist_active_project(project_dir: Path, namespaced_name: str) -> None:
|
||||
"""Persist the project name to {project_dir}/.cleveragents/project.name.
|
||||
|
||||
Args:
|
||||
container: The application DI container.
|
||||
project_dir: The resolved path of the project directory to use as context.
|
||||
namespaced_name: The project's namespaced name to persist.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
# Resolve the base data directory (same location ProjectService uses)
|
||||
# Write project name inside the project's .cleveragents dir
|
||||
clever_dir = project_dir / ".cleveragents"
|
||||
try:
|
||||
settings = getattr(container, "settings", None)
|
||||
if settings is not None:
|
||||
base_dir = getattr(settings, "data_path", Path.home() / ".cleveragents")
|
||||
else:
|
||||
base_dir = Path.home() / ".cleveragents"
|
||||
except Exception:
|
||||
base_dir = Path.home() / ".cleveragents"
|
||||
|
||||
config_file = base_dir / "config.toml"
|
||||
|
||||
# Ensure directory exists
|
||||
try:
|
||||
config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
except Exception:
|
||||
# Silently fail on write if home dir is not writable
|
||||
clever_dir.mkdir(parents=True, exist_ok=True)
|
||||
except OSError:
|
||||
return
|
||||
|
||||
# Read existing config if present (simple key-value TOML)
|
||||
current_lines: list[str] = []
|
||||
name_file = clever_dir / "project.name"
|
||||
try:
|
||||
if config_file.exists():
|
||||
raw_config = config_file.read_text()
|
||||
current_lines = raw_config.strip().splitlines(keepends=True) if raw_config.strip() else []
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Update or append active_project key
|
||||
_found_active = False
|
||||
new_lines: list[str] = []
|
||||
for line in current_lines:
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("active_project"):
|
||||
new_lines.append(f'active_project = "{namespaced_name}"\n')
|
||||
_found_active = True
|
||||
else:
|
||||
new_lines.append(line)
|
||||
|
||||
if not _found_active:
|
||||
new_lines.append("\n" + f'active_project = "{namespaced_name}"\n')
|
||||
|
||||
try:
|
||||
config_file.write_text("".join(new_lines), encoding="utf-8")
|
||||
except Exception:
|
||||
# Silently fail on write if not writable
|
||||
pass
|
||||
name_file.write_text(namespaced_name, encoding="utf-8")
|
||||
except OSError:
|
||||
pass # Silently fail on write
|
||||
|
||||
Reference in New Issue
Block a user