-
Notifications
You must be signed in to change notification settings - Fork 0
Desktop Mode
aisrf desktop runs the whole gateway on your own machine for one reviewer: it binds to the loopback interface, keeps its state in a per-user application directory, generates its secrets on first run and opens the dashboard in a native window or your browser. It is the default suggestion of the install scripts and the quickest way to try AISRF. Implementation: aisrf/desktop.py; CLI wiring: the desktop command in aisrf/cli.py and the aisrf-desktop console script in pyproject.toml.
-
configure_environment(force=True)resolves the app directory, creates it, seedsaisrf.env(see below) and exportsAISRF_DATA_DIR,AISRF_LOG_DIR,AISRF_DATABASE_URLandAISRF_HOMEinto the process environment withos.environ.setdefault, so anything you set explicitly still wins. -
DesktopServerbuilds auvicorn.Configforaisrf.main:create_app(factory mode, one worker, host127.0.0.1, a free port fromfree_port()unless--portis given, log level fromAISRF_LOG_LEVEL) and runs it in a daemon thread namedaisrf-uvicorn. -
wait_for_health()pollshttp://127.0.0.1:<port>/healthzevery 250 ms for up to 60 s; if the thread dies or the timeout passes the server is stopped and the command exits with code 1 and the message "the gateway did not become healthy; check the log directory for details". - It prints a banner:
AISRF 1.0.0 desktop mode
app directory : /home/you/.local/share/aisrf
settings file : /home/you/.local/share/aisrf/aisrf.env
starting the gateway ...
dashboard : http://127.0.0.1:43211
sign in as : admin / admin (change it under Settings)
API token : AISRF_ADMIN_API_TOKEN in aisrf.env (for the aisrf CLI and MCP)
press Ctrl+C to stop
- It installs signal handlers (SIGINT, SIGTERM and SIGBREAK on Windows raise
KeyboardInterrupt), then tries a pywebview window; when that is unavailable it opens the system browser withwebbrowser.open()and waits while the server thread is alive. - On window close, Ctrl+C or a signal,
DesktopServer.stop()setsshould_exit, joins the thread for 15 s, then forces exit and waits 5 more seconds; the command prints "gateway stopped". If the gateway dies on its own the exit code is 1 with "the gateway stopped unexpectedly".
Everything else is the normal gateway: point local agents at http://127.0.0.1:<port>/v1 with an agent key, use the same REST API, MCP endpoint at /mcp, and CLI (aisrf tickets list --url http://127.0.0.1:<port> --token <AISRF_ADMIN_API_TOKEN>).
app_dir() follows the platformdirs conventions without the dependency. AISRF_HOME always wins when set.
| OS | Directory |
|---|---|
| Linux and other POSIX |
$XDG_DATA_HOME/aisrf, default ~/.local/share/aisrf
|
| macOS | ~/Library/Application Support/AISRF |
| Windows |
%LOCALAPPDATA%\AISRF (fallback ~\AppData\Local\AISRF) |
Layout inside the directory:
aisrf.env generated settings (0600 on POSIX)
data/aisrf.db SQLite database, WAL mode (plus aisrf.db-wal and aisrf.db-shm while running)
data/codereview/ work directories of code review runs
logs/aisrf.jsonl service log, rotating 50 MB x 10
logs/agents/<id>.jsonl one rotating file per agent, 20 MB x 5
The same directory logic applies to the PyInstaller binaries for every command (serve, init-db, agent create, ...): packaging/pyinstaller/launcher.py calls configure_environment() before handing over to the CLI, and it activates whenever sys.frozen is set or AISRF_HOME is present. A pip install without AISRF_HOME keeps writing to ./data and ./logs except in desktop mode, where the app directory is forced.
ensure_env_file() creates <app dir>/aisrf.env when it is missing or when either generated key is empty:
# Generated by AISRF on first run. Keep this file private: it holds the key that encrypts
# stored upstream credentials and the admin API token used by the CLI and the MCP server.
# Delete a line to have it regenerated; any AISRF_* setting can be added here.
AISRF_SECRET_KEY=<secrets.token_urlsafe(48)>
AISRF_ADMIN_API_TOKEN=<secrets.token_urlsafe(48)>
Rules: existing values are preserved (repeated starts return the same secrets), only missing keys are regenerated, the file is chmod 0600 on POSIX, comments and blank lines are ignored, surrounding quotes are stripped. Any AISRF_* setting can be added, for example AISRF_ADMIN_PASSWORD=..., AISRF_PORT=8080 (for serve), AISRF_APPROVAL_TIMEOUT_SECONDS=600 or AISRF_DATABASE_URL=postgresql+asyncpg://.... Values from the file are applied with setdefault, so a real environment variable overrides the file. Deleting the AISRF_SECRET_KEY line regenerates it on the next start, which makes previously stored upstream credentials unreadable; treat that as a reset.
_open_window() imports webview (pywebview). When the import succeeds it creates a 1360 x 880 window (minimum 900 x 600) titled <AISRF_APP_NAME> <version> and blocks until the window is closed; closing it stops the gateway. Missing GUI backends are common, so pywebview logging is set to CRITICAL and any exception (no GTK, Qt or WebView2 runtime) prints native window unavailable (...), opening the browser instead and falls back.
- pip install:
uv pip install --python .venv/bin/python "aisrf[desktop]"addspywebview>=5. Linux additionally needs GTK (python3-gi,gir1.2-webkit2-4.1) or Qt (PyQt5+PyQtWebEngine) bindings; macOS uses WebKit and Windows uses WebView2 (present on Windows 11 and updated Windows 10). - Binaries: pywebview is excluded from the bundle (
EXCLUDESinpackaging/pyinstaller/manifest.py), so the binaries always open the system browser. - Browser fallback:
webbrowser.open(url); the process then idles until Ctrl+C. With--no-browsernothing is opened and only the URL is printed.
aisrf desktop [--port N] [--no-window] [--no-browser]
aisrf-desktop [--port N] [--port=N] [--no-window] [--no-browser] [-h | --help]
| Flag | Effect |
|---|---|
--port N |
bind 127.0.0.1:N instead of a random free port; use it when agents need a stable URL |
--no-window |
skip pywebview and open the system browser |
--no-browser |
open nothing, just print the URL (also implies no window when combined with --no-window; on its own the window is still tried) |
The aisrf-desktop console script parses the same flags by hand and exits with status 2 on an unknown argument. Environment variables apply as usual: AISRF_HOME relocates the directory, AISRF_LOG_LEVEL=DEBUG makes uvicorn verbose, AISRF_ADMIN_PASSWORD sets the admin password on a fresh database.
Close the window, press Ctrl+C in the terminal, or send SIGTERM to the process. Shutdown runs the FastAPI lifespan teardown: sweeper cancelled, notifier stopped, campaign, scan and code review runners shut down, HTTP client and database engine disposed. Pending tickets stay PENDING in the database and expire later through the sweeper when the gateway runs again; synchronous callers get a connection error.
Desktop mode has no state of its own beyond the app directory, so upgrading is upgrading the binary or the package:
- Binary: re-run
scripts/install.shorscripts/install.ps1whileaisrfis not running (the Windows installer refuses to overwrite a runningaisrf.exe). The app directory, database andaisrf.envare untouched. - pip:
pipx upgrade aisrforuv pip install --python .venv/bin/python -U "git+https://github.com/keyuraghao/aisrf.git".
The schema is extended with create_all on the next start. Back up data/aisrf.db and aisrf.env before a major version.
| Goal | Action |
|---|---|
| Forget the admin password | stop, run aisrf create-reviewer newadmin --role admin with AISRF_HOME pointing at the app directory (the binary sets it automatically), sign in with the new account and change the old one under Settings > Reviewers |
| New admin API token | delete the AISRF_ADMIN_API_TOKEN line in aisrf.env, start again; update every MCP client config |
| Wipe tickets and agents but keep the secrets | stop, delete data/aisrf.db (and -wal, -shm), start again; agents and their upstream keys must be recreated |
| Full factory reset | stop and delete the whole app directory (rm -rf ~/.local/share/aisrf, rm -rf ~/Library/Application\ Support/AISRF, or Remove-Item -Recurse $env:LOCALAPPDATA\AISRF) |
| Move the state elsewhere | copy the directory and set AISRF_HOME=/new/path before starting |
A full reset also deletes the audit chain; export it first with aisrf report audit --format json --out audit.json if you need the history.
AISRF, AI Security & Research Framework. github.com/keyuraghao/aisrf, Apache License 2.0.
Start
Gateway
- Gateway-Endpoints-and-Headers
- Request-Normalization
- Policy-Engine
- Agents-and-Credentials
- Configuration-Reference
- Settings-Center
Review
Security analysis
Red teaming
Code review
Interfaces
Operations
Project