Manages dashboard frontend lifecycle.
Responsibilities: - Ensure npm dependencies installed - Start npm dev server (dev mode) or build for production - Launch browser automatically - Clean up npm processes on shutdown
Usage
launcher = DashboardLauncher(port=8344) launcher.start() # Starts npm and opens browser
... orchestrator runs ...
launcher.stop() # Cleanup
Or as context manager
with DashboardLauncher(port=8344): # orchestrator.serve() runs pass # Automatically cleaned up
Initialize dashboard launcher.
Parameters:
Name | Type | Description | Default |
port | int | HTTP port where dashboard will be served (default: 8344) | 8344 |
frontend_dir | Path | None | Optional frontend directory path (defaults to FRONTEND_DIR) | None |
Source code in src/flock/dashboard/launcher.py
| def __init__(
self,
port: int = 8344,
frontend_dir: Path | None = None,
static_dir: Path | None = None,
):
"""Initialize dashboard launcher.
Args:
port: HTTP port where dashboard will be served (default: 8344)
frontend_dir: Optional frontend directory path (defaults to FRONTEND_DIR)
"""
self.port = port
self.frontend_dir = frontend_dir or FRONTEND_DIR
self.static_dir = static_dir or Path(__file__).parent / "static"
self.dev_mode = os.getenv("DASHBOARD_DEV", "0") == "1"
self._npm_process: subprocess.Popen | None = None
|
Functions
start
Start dashboard: install deps, start npm, launch browser.
This method: 1. Ensures npm dependencies are installed 2. Starts npm dev server (dev mode) or builds production 3. Launches browser to dashboard URL
Source code in src/flock/dashboard/launcher.py
| def start(self) -> None:
"""Start dashboard: install deps, start npm, launch browser.
This method:
1. Ensures npm dependencies are installed
2. Starts npm dev server (dev mode) or builds production
3. Launches browser to dashboard URL
"""
print(f"[Dashboard] Starting dashboard on port {self.port}")
print(f"[Dashboard] Mode: {'DEVELOPMENT' if self.dev_mode else 'PRODUCTION'}")
print(f"[Dashboard] Frontend directory: {self.frontend_dir}")
# Step 1: Ensure dependencies installed
self._ensure_npm_dependencies()
# Step 2: Start npm process
self._start_npm_process()
# Step 3: Launch browser
self._launch_browser()
|
stop
Stop dashboard and cleanup npm processes.
Attempts graceful termination, falls back to kill if needed.
Source code in src/flock/dashboard/launcher.py
| def stop(self) -> None:
"""Stop dashboard and cleanup npm processes.
Attempts graceful termination, falls back to kill if needed.
"""
if self._npm_process is None:
return
print("[Dashboard] Stopping npm process...")
try:
# Try graceful termination first
self._npm_process.terminate()
# Wait up to 5 seconds for process to exit
for _ in range(5):
if self._npm_process.poll() is not None:
print("[Dashboard] npm process stopped gracefully")
return
time.sleep(1)
# Force kill if still running
print("[Dashboard] npm process did not stop gracefully, forcing kill...")
self._npm_process.kill()
self._npm_process.wait(timeout=2)
print("[Dashboard] npm process killed")
except Exception as e:
print(f"[Dashboard] Error stopping npm process: {e}")
finally:
self._npm_process = None
|
__enter__
Context manager entry: start dashboard.
Source code in src/flock/dashboard/launcher.py
| def __enter__(self):
"""Context manager entry: start dashboard."""
self.start()
return self
|
__exit__
__exit__(exc_type, exc_val, exc_tb)
Context manager exit: stop dashboard.
Source code in src/flock/dashboard/launcher.py
| def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit: stop dashboard."""
self.stop()
return False # Don't suppress exceptions
|