# AGENTS.md Instructions for AI coding agents (Claude Code, Codex, Cursor, etc.). ## Project Overview Quip Node Desktop Manager — a Tauri v2 desktop app that orchestrates and monitors a Quip network node running in Docker. Rust backend + vanilla HTML/CSS/JS frontend. ## Architecture ``` quip-node-manager/ ├── src/ # Frontend (vanilla HTML/CSS/JS) │ ├── index.html │ ├── styles.css │ └── app.js └── src-tauri/ # Rust backend (Tauri v2) ├── Cargo.toml ├── tauri.conf.json ├── capabilities/ │ └── default.json └── src/ ├── main.rs # Entry point ├── lib.rs # Tauri builder, command registration ├── settings.rs # AppSettings + shared types (NodeConfig, etc.) ├── secret.rs # Node secret (64-char hex) management ├── config.rs # config.toml generation ├── docker.rs # Docker CLI shell-out ├── log_stream.rs # docker logs -f streaming → Tauri events ├── network.rs # Public IP detection, port forwarding check ├── update.rs # App + image update checks └── checklist.rs # 6 pre-flight checks → checklist-update events ``` ## Key Details - **Tauri version**: v2 - **JS tooling**: Bun - **App version**: v0.0.0 - **Window size**: 900×700 - **Data directory**: `~/quip-data/` - **Container name**: `quip-node` - **Container port**: 20049/udp ## Docker Images - CPU: `registry.gitlab.com/quip.network/quip-protocol/quip-network-node-cpu:latest` - CUDA: `registry.gitlab.com/quip.network/quip-protocol/quip-network-node-cuda:latest` - Selected via `AppSettings.image_tag` (`"cpu"` or `"cuda"`) ## Data Files (all in `~/quip-data/`) | File | Purpose | |------|---------| | `app-settings.json` | GUI state (managed by desktop app) | | `config.toml` | Node config (generated by desktop app) | | `node-secret.json` | `{ "secret": "<64-hex>" }` | | `trust.db` | TOFU peer DB (managed by container) | ## Shared Types (defined in `settings.rs`) - `GpuBackend` — `Local | Modal | Mps` - `QpuConfig` — `{ url, api_key }` - `NodeConfig` — CPU/GPU/QPU/port/secret/peers config - `AppSettings` — wraps NodeConfig + UI state - `ContainerStatus` — `{ running, container_id, image, status_text }` ## Frontend IPC The frontend uses `window.__TAURI__.core.invoke` (withGlobalTauri: true). Events emitted by backend: - `node-log` → `{ timestamp, level, message }` - `node-status` → `{ state: "running"|"degraded"|"stopped" }` - `checklist-update` → `Vec<{ id, passed, label }>` - `docker-pull-progress` → `{ layer, status, progress }` ## Commands ```bash # Development bun run dev # Production build bun run build # Install dependencies bun install ``` ## Code Standards - All Rust files: `// SPDX-License-Identifier: AGPL-3.0-or-later` header - All JS files: `// SPDX-License-Identifier: AGPL-3.0-or-later` header - Tauri commands return `Result` - No relative imports (`..`) in Rust — use `crate::module::Type` - Line length ≤ 100 chars ## License AGPL-3.0-or-later. All new source files require the standard license header.