Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion osa/application/di.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dishka import AsyncContainer, make_async_container

from osa.cli.util.paths import OSAPaths
from osa.config import Config
from osa.domain.deposition.util.di import DepositionProvider
from osa.domain.validation.util.di import ValidationProvider
Expand All @@ -14,6 +15,9 @@
def create_container() -> AsyncContainer:
config = Config()

# OSAPaths reads OSA_DATA_DIR from environment automatically
paths = OSAPaths()

return make_async_container(
PersistenceProvider(),
OciProvider(),
Expand All @@ -22,6 +26,6 @@ def create_container() -> AsyncContainer:
EventProvider(),
DepositionProvider(),
ValidationProvider(),
context={Config: config},
context={Config: config, OSAPaths: paths},
scopes=Scope, # type: ignore[arg-type] # Custom scope class
)
92 changes: 2 additions & 90 deletions osa/cli/commands/admin.py
Original file line number Diff line number Diff line change
@@ -1,103 +1,15 @@
"""Administrative commands for OSA management."""

import shutil
import sys
from pathlib import Path

import cyclopts

from osa.cli.console import get_console
from osa.cli.util import DaemonManager, OSAPaths, ServerStatus
from osa.cli.util import OSAPaths, read_server_state

app = cyclopts.App(name="admin", help="Administrative commands")


@app.command
def clean(
force: bool = False,
keep_config: bool = False,
keep_logs: bool = False,
) -> None:
"""Wipe OSA data directories to start fresh.

Stops the server if running, then removes:
- ~/.local/share/osa/ (database, vectors)
- ~/.local/state/osa/ (server state, logs)
- ~/.cache/osa/ (search cache)
- ~/.config/osa/ (unless --keep-config)

Args:
force: Skip confirmation prompt.
keep_config: Keep the config directory (~/.config/osa).
keep_logs: Keep the logs directory.
"""
console = get_console()
paths = OSAPaths()

# Check which directories exist
dirs_to_clean: list[tuple[str, Path]] = []
if paths.data_dir.exists():
dirs_to_clean.append(("Data", paths.data_dir))
if paths.state_dir.exists():
dirs_to_clean.append(("State", paths.state_dir))
if paths.cache_dir.exists():
dirs_to_clean.append(("Cache", paths.cache_dir))
if paths.config_dir.exists() and not keep_config:
dirs_to_clean.append(("Config", paths.config_dir))

if not dirs_to_clean:
console.info("Nothing to clean - no OSA directories exist")
return

# Check if server is running
daemon = DaemonManager()
status_info = daemon.status()

if status_info.status == ServerStatus.RUNNING:
if not force:
console.warning(f"Server is running (PID {status_info.pid})")
response = input("Stop server and clean? [y/N] ").strip().lower()
if response != "y":
console.info("Aborted")
sys.exit(1)
console.info("Stopping server...")
daemon.stop()

# Confirm before wiping
if not force:
console.print("[bold]This will delete:[/bold]")
for name, path in dirs_to_clean:
console.print(f" [cyan]{path}[/cyan] [dim]({name.lower()})[/dim]")
if keep_logs:
console.print(f" [dim](keeping logs at {paths.logs_dir})[/dim]")
if keep_config and paths.config_dir.exists():
console.print(f" [dim](keeping config at {paths.config_dir})[/dim]")
console.print()
response = input("Are you sure? [y/N] ").strip().lower()
if response != "y":
console.info("Aborted")
sys.exit(1)

# Perform cleanup
for name, path in dirs_to_clean:
if name == "State" and keep_logs:
# Delete everything in state except logs
for item in path.iterdir():
if item == paths.logs_dir:
continue
if item.is_dir():
shutil.rmtree(item)
else:
item.unlink()
console.success(f"Cleaned {path} (logs preserved)")
else:
shutil.rmtree(path)
console.success(f"Removed {path}")

console.print()
console.info("Run 'osa init' to set up OSA again")


@app.command
def info() -> None:
"""Show information about OSA directories and status."""
Expand Down Expand Up @@ -147,7 +59,7 @@ def exists_marker(path: Path) -> str:

# Server status
console.print()
state = paths.read_server_state()
state = read_server_state(paths.server_state_file)
if state:
from osa.cli.console import relative_time

Expand Down
143 changes: 0 additions & 143 deletions osa/cli/commands/init.py

This file was deleted.

Loading
Loading