feat: add --dir option to onboard command for Multiple Instances

- Add --dir parameter to specify custom base directory for config and workspace
- Enables Multiple Instances initialization with isolated configurations
- Config and workspace are created under the specified directory
- Maintains backward compatibility with default ~/.nanobot/
- Updates help text and next steps with actual paths
- Updates README.md with --dir usage examples for Multiple Instances

Example usage:
  nanobot onboard --dir ~/.nanobot-A
  nanobot onboard --dir ~/.nanobot-B
  nanobot onboard  # uses default ~/.nanobot/
This commit is contained in:
skiyo
2026-03-09 16:17:01 +08:00
parent f19cefb1b9
commit dfb4537867
2 changed files with 43 additions and 16 deletions

View File

@@ -939,6 +939,21 @@ Run multiple nanobot instances simultaneously with separate configs and runtime
### Quick Start ### Quick Start
**Initialize instances:**
```bash
# Create separate instance directories
nanobot onboard --dir ~/.nanobot-telegram
nanobot onboard --dir ~/.nanobot-discord
nanobot onboard --dir ~/.nanobot-feishu
```
**Configure each instance:**
Edit `~/.nanobot-telegram/config.json`, `~/.nanobot-discord/config.json`, etc. with different channel settings and workspaces.
**Run instances:**
```bash ```bash
# Instance A - Telegram bot # Instance A - Telegram bot
nanobot gateway --config ~/.nanobot-telegram/config.json nanobot gateway --config ~/.nanobot-telegram/config.json
@@ -1038,7 +1053,8 @@ nanobot gateway --config ~/.nanobot-telegram/config.json --workspace /tmp/nanobo
| Command | Description | | Command | Description |
|---------|-------------| |---------|-------------|
| `nanobot onboard` | Initialize config & workspace | | `nanobot onboard` | Initialize config & workspace at `~/.nanobot/` |
| `nanobot onboard --dir <path>` | Initialize config & workspace at custom directory |
| `nanobot agent -m "..."` | Chat with the agent | | `nanobot agent -m "..."` | Chat with the agent |
| `nanobot agent -w <workspace>` | Chat against a specific workspace | | `nanobot agent -w <workspace>` | Chat against a specific workspace |
| `nanobot agent -w <workspace> -c <config>` | Chat against a specific workspace/config | | `nanobot agent -w <workspace> -c <config>` | Chat against a specific workspace/config |

View File

@@ -168,43 +168,54 @@ def main(
@app.command() @app.command()
def onboard(): def onboard(
dir: str | None = typer.Option(None, "--dir", help="Base directory for config and workspace (default: ~/.nanobot/)"),
):
"""Initialize nanobot configuration and workspace.""" """Initialize nanobot configuration and workspace."""
from nanobot.config.loader import get_config_path, load_config, save_config from nanobot.config.loader import load_config, save_config
from nanobot.config.schema import Config from nanobot.config.schema import Config
config_path = get_config_path() # Determine base directory
if dir:
base_dir = Path(dir).expanduser().resolve()
else:
base_dir = Path.home() / ".nanobot"
config_path = base_dir / "config.json"
workspace_path = base_dir / "workspace"
# Ensure base directory exists
base_dir.mkdir(parents=True, exist_ok=True)
# Create or update config
if config_path.exists(): if config_path.exists():
console.print(f"[yellow]Config already exists at {config_path}[/yellow]") console.print(f"[yellow]Config already exists at {config_path}[/yellow]")
console.print(" [bold]y[/bold] = overwrite with defaults (existing values will be lost)") console.print(" [bold]y[/bold] = overwrite with defaults (existing values will be lost)")
console.print(" [bold]N[/bold] = refresh config, keeping existing values and adding new fields") console.print(" [bold]N[/bold] = refresh config, keeping existing values and adding new fields")
if typer.confirm("Overwrite?"): if typer.confirm("Overwrite?"):
config = Config() config = Config()
save_config(config) save_config(config, config_path)
console.print(f"[green]✓[/green] Config reset to defaults at {config_path}") console.print(f"[green]✓[/green] Config reset to defaults at {config_path}")
else: else:
config = load_config() config = load_config(config_path)
save_config(config) save_config(config, config_path)
console.print(f"[green]✓[/green] Config refreshed at {config_path} (existing values preserved)") console.print(f"[green]✓[/green] Config refreshed at {config_path} (existing values preserved)")
else: else:
save_config(Config()) save_config(Config(), config_path)
console.print(f"[green]✓[/green] Created config at {config_path}") console.print(f"[green]✓[/green] Created config at {config_path}")
# Create workspace # Create workspace
workspace = get_workspace_path() if not workspace_path.exists():
workspace_path.mkdir(parents=True, exist_ok=True)
console.print(f"[green]✓[/green] Created workspace at {workspace_path}")
if not workspace.exists(): sync_workspace_templates(workspace_path)
workspace.mkdir(parents=True, exist_ok=True)
console.print(f"[green]✓[/green] Created workspace at {workspace}")
sync_workspace_templates(workspace)
console.print(f"\n{__logo__} nanobot is ready!") console.print(f"\n{__logo__} nanobot is ready!")
console.print("\nNext steps:") console.print("\nNext steps:")
console.print(" 1. Add your API key to [cyan]~/.nanobot/config.json[/cyan]") console.print(f" 1. Add your API key to [cyan]{config_path}[/cyan]")
console.print(" Get one at: https://openrouter.ai/keys") console.print(" Get one at: https://openrouter.ai/keys")
console.print(" 2. Chat: [cyan]nanobot agent -m \"Hello!\"[/cyan]") console.print(f" 2. Chat: [cyan]nanobot agent -m \"Hello!\" --config {config_path} --workspace {workspace_path}[/cyan]")
console.print("\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]") console.print("\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]")