diff --git a/nanobot/cli/commands.py b/nanobot/cli/commands.py index 1c20b50..fc4c261 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -20,6 +20,7 @@ from prompt_toolkit.patch_stdout import patch_stdout from nanobot import __version__, __logo__ from nanobot.config.schema import Config +from nanobot.utils.helpers import sync_workspace_templates app = typer.Typer( name="nanobot", @@ -185,8 +186,7 @@ def onboard(): workspace.mkdir(parents=True, exist_ok=True) console.print(f"[green]✓[/green] Created workspace at {workspace}") - # Create default bootstrap files - _create_workspace_templates(workspace) + sync_workspace_templates(workspace) console.print(f"\n{__logo__} nanobot is ready!") console.print("\nNext steps:") @@ -198,36 +198,6 @@ def onboard(): -def _create_workspace_templates(workspace: Path): - """Create default workspace template files from bundled templates.""" - from importlib.resources import files as pkg_files - - templates_dir = pkg_files("nanobot") / "templates" - - for item in templates_dir.iterdir(): - if not item.name.endswith(".md"): - continue - dest = workspace / item.name - if not dest.exists(): - dest.write_text(item.read_text(encoding="utf-8"), encoding="utf-8") - console.print(f" [dim]Created {item.name}[/dim]") - - memory_dir = workspace / "memory" - memory_dir.mkdir(exist_ok=True) - - memory_template = templates_dir / "memory" / "MEMORY.md" - memory_file = memory_dir / "MEMORY.md" - if not memory_file.exists(): - memory_file.write_text(memory_template.read_text(encoding="utf-8"), encoding="utf-8") - console.print(" [dim]Created memory/MEMORY.md[/dim]") - - history_file = memory_dir / "HISTORY.md" - if not history_file.exists(): - history_file.write_text("", encoding="utf-8") - console.print(" [dim]Created memory/HISTORY.md[/dim]") - - (workspace / "skills").mkdir(exist_ok=True) - def _make_provider(config: Config): """Create the appropriate LLM provider from config.""" @@ -294,6 +264,7 @@ def gateway( console.print(f"{__logo__} Starting nanobot gateway on port {port}...") config = load_config() + sync_workspace_templates(config.workspace_path) bus = MessageBus() provider = _make_provider(config) session_manager = SessionManager(config.workspace_path) @@ -447,6 +418,7 @@ def agent( from loguru import logger config = load_config() + sync_workspace_templates(config.workspace_path) bus = MessageBus() provider = _make_provider(config) diff --git a/nanobot/utils/helpers.py b/nanobot/utils/helpers.py index 06d8fd5..8963138 100644 --- a/nanobot/utils/helpers.py +++ b/nanobot/utils/helpers.py @@ -76,4 +76,37 @@ def parse_session_key(key: str) -> tuple[str, str]: parts = key.split(":", 1) if len(parts) != 2: raise ValueError(f"Invalid session key: {key}") - return parts[0], parts[1] \ No newline at end of file + return parts[0], parts[1] + +def sync_workspace_templates(workspace: Path, silent: bool = False) -> list[str]: + """Sync bundled templates to workspace. Only creates missing files.""" + from importlib.resources import files as pkg_files + try: + tpl = pkg_files("nanobot") / "templates" + except Exception: + return [] + if not tpl.is_dir(): + return [] + + added: list[str] = [] + + def _write(src, dest: Path): + """Write src content (or empty string if None) to dest if missing.""" + if dest.exists(): + return + dest.parent.mkdir(parents=True, exist_ok=True) + dest.write_text(src.read_text(encoding="utf-8") if src else "", encoding="utf-8") + added.append(str(dest.relative_to(workspace))) + + for item in tpl.iterdir(): + if item.name.endswith(".md"): + _write(item, workspace / item.name) + _write(tpl / "memory" / "MEMORY.md", workspace / "memory" / "MEMORY.md") + _write(None, workspace / "memory" / "HISTORY.md") + (workspace / "skills").mkdir(exist_ok=True) + + if added and not silent: + from rich.console import Console + for name in added: + Console().print(f" [dim]Created {name}[/dim]") + return added