File size: 7,333 Bytes
4d393e8 06662a4 4d393e8 06662a4 4d393e8 06662a4 4d393e8 e3f3c8e 4d393e8 06662a4 4d393e8 06662a4 4d393e8 06662a4 4d393e8 e3f3c8e 4d393e8 e3f3c8e 06662a4 4d393e8 06662a4 e3f3c8e 06662a4 e3f3c8e 4d393e8 a8391ca e3f3c8e a8391ca e3f3c8e a8391ca 06662a4 4d393e8 06662a4 4d393e8 06662a4 4d393e8 06662a4 4d393e8 06662a4 4d393e8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | """
`dw init` command.
Initializes a local DiffWeave workspace in the current directory.
Supports binding by Workspace Name or UUID, with automatic creation.
"""
from __future__ import annotations
from pathlib import Path
from typing import Optional
import typer
from rich.prompt import Prompt
from diffweave.cli.config import save_config, load_config
from diffweave.cli.output import print_success, print_info, print_error, print_json
from diffweave.mcp.client import DiffWeaveMCPClient
def init_command(
workspace: Optional[str] = typer.Option(
None,
"--workspace",
"-w",
help="Workspace name or UUID to bind to (e.g. 'security-policies' or 'heart')",
),
create: Optional[str] = typer.Option(
None,
"--create",
"-c",
help="Create a new workspace with this name",
),
as_json: bool = typer.Option(False, "--json", help="Output machine-readable JSON"),
):
"""
Initialize a DiffWeave workspace in the current directory (.diffweave/).
You can specify a workspace by its unique name or its UUID.
"""
client = DiffWeaveMCPClient()
# Load authenticated identity
from diffweave.cli.credentials import load_credentials
creds = load_credentials()
auth_email = creds.get("email") if creds else None
current_uid = None
try:
from diffweave.bridge.db_store import get_engine
from sqlalchemy import text
eng = get_engine()
with eng.connect() as conn:
if auth_email:
u_row = conn.execute(text("SELECT id FROM users WHERE LOWER(email)=:e"), {"e": auth_email.lower()}).first()
if u_row:
current_uid = str(u_row[0])
except Exception:
pass
try:
# Check MCP server availability and get available workspaces
workspaces = client.call_tool_sync("list_workspaces")
except Exception as e:
workspaces = []
target_ws = None
target_name = (create or workspace or "").strip()
if create:
clean_create = create.strip()
# Enforce unique workspace name check
try:
from diffweave.bridge.db_store import get_engine
from sqlalchemy import text
eng = get_engine()
with eng.connect() as conn:
if current_uid:
existing = conn.execute(
text("SELECT id, name FROM workspaces WHERE created_by = :uid AND LOWER(TRIM(name)) = LOWER(TRIM(:n)) AND (status != 'DELETED' OR status IS NULL)"),
{"uid": current_uid, "n": clean_create}
).first()
else:
existing = conn.execute(
text("SELECT id, name FROM workspaces WHERE LOWER(TRIM(name)) = LOWER(TRIM(:n)) AND (status != 'DELETED' OR status IS NULL)"),
{"n": clean_create}
).first()
if existing:
print_error(f"Error: A workspace named '{clean_create}' already exists. Workspace names must be unique.")
raise typer.Exit(code=1)
except typer.Exit:
raise
except Exception:
pass
try:
target_ws = client.call_tool_sync("create_workspace", {"name": clean_create})
if not as_json:
print_success(f"Created new DocWeave workspace: [bold]{target_ws['name']}[/bold] ({target_ws['id']})")
except Exception as e:
print_error(f"Failed to create workspace: {e}")
raise typer.Exit(code=1)
elif target_name:
# 1. Match by Workspace Name or UUID in user's workspaces
target_ws = next(
(
w for w in workspaces
if w.get("name", "").strip().lower() == target_name.lower()
or str(w.get("id", "")).strip().lower() == target_name.lower()
),
None,
)
# 2. Check database directly (ensuring user ownership scoping)
if not target_ws:
try:
from diffweave.bridge.db_store import get_engine
from sqlalchemy import text
eng = get_engine()
with eng.connect() as conn:
if current_uid:
# Scoped to current authenticated user
ws_row = conn.execute(
text("SELECT id, name, description FROM workspaces WHERE created_by = :uid AND (LOWER(TRIM(name)) = LOWER(TRIM(:n)) OR id::text = :n) AND (status != 'DELETED' OR status IS NULL)"),
{"uid": current_uid, "n": target_name}
).first()
else:
ws_row = conn.execute(
text("SELECT id, name, description FROM workspaces WHERE (LOWER(TRIM(name)) = LOWER(TRIM(:n)) OR id::text = :n) AND (status != 'DELETED' OR status IS NULL)"),
{"n": target_name}
).first()
if ws_row:
target_ws = {
"id": str(ws_row[0]),
"name": ws_row[1],
"description": ws_row[2] or "",
}
except Exception:
pass
# 3. If workspace does not exist yet for this user, auto-create it under their account
if not target_ws:
try:
target_ws = client.call_tool_sync("create_workspace", {"name": target_name})
if not as_json:
print_success(f"Initialized new workspace: [bold]{target_ws['name']}[/bold] ({target_ws['id']})")
except Exception:
target_ws = {"id": target_name, "name": target_name, "description": ""}
elif workspaces:
# If running interactively with no argument, pick first or prompt
if len(workspaces) == 1:
target_ws = workspaces[0]
else:
print_info("Available workspaces:")
for idx, w in enumerate(workspaces, 1):
print_info(f" [{idx}] {w['name']} ({w['id']})")
choice = Prompt.ask("Select workspace index", default="1")
try:
target_ws = workspaces[int(choice) - 1]
except Exception:
target_ws = workspaces[0]
else:
# Auto-create default
try:
target_ws = client.call_tool_sync("create_workspace", {"name": "Default Workspace"})
except Exception as e:
print_error(f"No workspaces exist and failed to create one: {e}")
raise typer.Exit(code=1)
# Save to local .diffweave/config.json
config_data = {
"workspace_id": str(target_ws["id"]),
"workspace_name": target_ws.get("name", target_name),
"mcp_server": "docweave",
}
cfg_path = save_config(config_data)
if as_json:
print_json({"initialized": True, "config_path": str(cfg_path), **config_data})
else:
print_success(
f"Initialized DiffWeave workspace in [bold]{Path.cwd() / '.diffweave'}[/bold]\n"
f"Bound to: [cyan]{target_ws.get('name', target_name)}[/cyan] ({target_ws['id']})"
)
|