atlus/ATLUS_CONTEXT.md
roberts f9743bb29a Initial commit — Atlus web desktop environment for SBCs
Full-stack implementation: FastAPI backend with PAM auth, WebSocket
stats/terminal, and vanilla JS frontend with tiling desktop shell.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 16:53:46 -05:00

514 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Atlus — Project Context
## What Is Atlus?
Atlus is a lightweight, web-based desktop environment designed for headless single-board computers (SBCs) such as the Orange Pi, Raspberry Pi, and similar ARM-based Linux systems. It provides a browser-accessible interface that replaces the need for SSH or VNC for everyday system management tasks.
The goal is not to replicate a full desktop environment — it is to provide the *right* tools for managing a headless SBC in a way that feels natural, fast, and accessible from any device on the local network.
---
## Problem Statement
Headless SBCs are increasingly used as always-on servers, astrophotography rigs, NAS boxes, home automation hubs, and more. Current management options are:
- **SSH** — powerful but unfriendly for non-developers and tedious for routine tasks
- **VNC / noVNC** — requires a full desktop environment, heavy, slow, not purpose-built
- **Cockpit / Webmin** — generic server admin tools, not tailored to SBC use cases, complex UI
There is no lightweight, purpose-built web desktop for SBCs that feels like an OS rather than a server admin panel.
---
## Core Philosophy
- **Web-native first** — no X server required for core functionality
- **Purposefully minimal** — only the tools that matter for headless SBC management
- **Locally hosted** — runs entirely on the SBC, no cloud dependency
- **Accessible from anything** — phone, tablet, laptop — any browser on the local network
- **Tiling over floating** — apps open in the center stage, not as draggable windows
- **Extensible** — apps/widgets can be added as plugins
---
## Target Users
- Makers and hobbyists running headless SBCs for specific purposes (astrophotography, NAS, IoT, etc.)
- Home lab users who want lightweight management without full desktop overhead
- Anyone who currently lives in SSH and wishes there was something better
---
## ✅ Finalized Layout — Three-Column Shell
The Atlus UI is a fixed three-column layout inspired by tiling window managers (awesomewm, i3). There are no draggable or floating windows. Everything is tiled, cascaded, or tabbed within the center stage.
```
┌────────┬─────────────────────────────┬────────────────┐
│ │ Stage Tab Bar │ │
│ Left ├─────────────────────────────┤ Right Panel │
│ Dock │ │ │
│ │ Center Stage │ - Hostname │
│ App │ (active app view) │ - Date/Time │
│ Icons │ │ - Network │
│ │ One app at a time, │ - CPU/RAM/ │
│ (vert) │ or tiled side-by-side │ Disk/Temp │
│ │ │ - Services │
│ Gear ├─────────────────────────────┤ (toggles + │
│ (foot) │ Layout Controls (tab bar) │ open → ) │
└────────┴─────────────────────────────┴────────────────┘
```
### Left Dock
- Vertical strip of app launcher icons — no labels, tooltip on hover
- Top: Atlus "A" logo — opens a system menu (shutdown, restart, about)
- Core apps listed in order (configurable in settings)
- Separator line between core apps and plugins
- Bottom: Settings gear icon (always pinned)
- Active app highlighted with accent border/background
- Badge dot on plugin icons when they have status to report (e.g. ASI Bridge syncing)
### Center Stage
- The primary content area — full height, fills remaining width
- One app visible at a time by default
- **Tab bar** at top shows all open apps; click to switch (previous app minimizes)
- **Layout toggle buttons** (top-right of tab bar) switch between:
- Single pane (full width)
- Horizontal split (two panes side-by-side, 50/50 default)
- Vertical split (stacked, stretch goal)
- Each pane has its own macOS-style titlebar (traffic light dots + title)
- When a second app is opened in split mode, it takes the secondary pane
### Right Panel
- Always visible, fixed width (~220px), never replaced by an app
- **Top section:** Hostname, date, time (live), WiFi name + status, Ethernet status
- **Middle section:** Live system stats — CPU %, Memory used/total, Storage %, CPU temp
- Each stat: compact uppercase label + current value + colored progress bar
- Colors: green (healthy), amber (moderate), red (high)
- **Bottom section:** Services list
- Each service: toggle (on/off), name, ↗ open button
- Toggle maps to `systemctl start/stop`
- ↗ opens that service's detail/control view in the center stage
- Services list is configurable per deployment
---
## Architecture Overview
### Backend Daemon
- Language: **Python (FastAPI + asyncio)**
- Runs as a systemd service on boot
- Exposes a REST API and WebSocket endpoint
- Responsibilities:
- File system access and management
- Systemd service control (start/stop/restart/status)
- Process/task enumeration
- System stats (CPU, RAM, disk, network, temperature) via psutil
- Notification/event bus (watches logs, mount points, service states)
- X11 app process spawner (Xvfb + x11vnc per app — Phase 4 only)
### Frontend
- Language: **Vanilla JS + CSS** (no framework — keep it lightweight and portable)
- No build step — served directly as static files by the FastAPI backend
- Communicates via REST for actions, WebSocket for live stat updates
- CSS custom properties for theming
- IBM Plex Mono for system data; Inter for UI chrome
### X11 App Embedding (Phase 4 — Optional/Advanced)
- For GUI apps that require X (e.g., Nextcloud desktop client)
- Each app spawns its own Xvfb virtual framebuffer
- x11vnc streams that framebuffer over WebSocket via noVNC
- Embedded as a pane in the center stage — not a floating window
- Isolated per-app — no shared display, no full desktop environment needed
---
## Built-in Apps (Core)
### ⚙️ System Settings
The unified configuration hub for the SBC. Organized into sections:
- **General** — System name/hostname, date & time (manual or NTP), timezone
- **Users** — User management, password changes, add/remove users
- **Security** — Screen lock timeout, session timeout, auth settings
- **Applications** — Choose which apps appear in the dock; enable/disable on startup
- **Services** — Which systemd services appear in the right panel; autostart configuration
- **Network** — Per-interface settings (WiFi SSID/password, static IP vs DHCP, DNS); shown for all detected interfaces (eth0, wlan0, etc.)
- **Storage / Automount** — USB automount rules, mount point configuration, eject behavior
- **About** — Atlus version, system info, OS details
---
### 📟 Terminal
A fully functional web-based terminal. No restrictions, no simplifications — behaves identically to SSH or a local terminal session. Powered by xterm.js on the frontend and ptyprocess on the backend for a real PTY.
#### Custom On-Screen Keyboard (Critical)
The system keyboard (iOS/Android) is **never triggered**. Atlus uses its own purpose-built on-screen keyboard for all terminal input. This is non-negotiable — the native keyboard is hostile to terminal use (autocorrect, autocapitalize, no Escape, no function keys, unpredictable behavior).
**How it works technically:**
- The xterm.js terminal canvas is focused but never triggers a system keyboard (it is not an `<input>` or `<textarea>`)
- All key input is intercepted via the custom keyboard UI — keys send characters directly to the terminal via `terminal.input(char)` and escape sequences for special keys
- The terminal pane never calls `.focus()` on any element that would summon the system keyboard
- `inputmode="none"` set on any focusable elements within the terminal pane as a belt-and-suspenders measure
**Custom keyboard layout — three rows:**
```
Row 1 (special/modifier):
[ Esc ] [ Tab ] [ Ctrl ] [ Alt ] [ ` ] [ ~ ] [ | ] [ \ ] [ / ]
Row 2 (function keys, scrollable):
[ F1 ] [ F2 ] [ F3 ] [ F4 ] [ F5 ] [ F6 ] [ F7 ] [ F8 ] [ F9 ] [ F10 ] [ F11 ] [ F12 ]
Row 3 (navigation):
[ ↑ ] [ ↓ ] [ ← ] [ → ] [ Home ] [ End ] [ PgUp ] [ PgDn ] [ Del ]
```
**Modifier key behavior:**
- Ctrl, Alt are sticky — tap once to arm, next key sends the combo (e.g. Ctrl → C sends `\x03`)
- Armed modifier keys are visually highlighted
- Double-tap a modifier to lock it (Ctrl+lock for vim, etc.)
**Standard alphanumeric input:**
- A compact QWERTY layout below the special rows handles letter/number/symbol input
- Numbers row across the top of the QWERTY section
- Shift key for capitals — also sticky
- Common terminal symbols promoted to easy reach: `$`, `#`, `>`, `-`, `_`, `.`
**Keyboard can be:**
- Toggled show/hide via a keyboard icon button in the terminal pane titlebar
- Resized (compact vs. full) — compact shows only the special row + QWERTY condensed
- On physical keyboard connected to iPad: custom keyboard hides, physical keys work natively through xterm.js
**Other terminal features:**
- Full color output, cursor control, scrollback
- Resize-aware (terminal resizes with the pane, keyboard height accounted for)
- Copy: long-press selection in terminal → copy action
- Paste: paste button on keyboard toolbar injects clipboard content via `terminal.input()`
- Multiple terminal tabs within the terminal pane (Phase 2)
---
### 🗂 File Manager
Unique dual-pane design. Key characteristics:
- **Single or dual folder view** — toggle between one panel (full width) and two side-by-side panels
- **List view only** — no icon grid; each row shows: icon type indicator, filename, size, modified date, permissions
- **Drag and drop** — files can be dragged between panels or into folders within a panel
- **Sidebar** — shows filesystem tree: home, root, and all detected mounts (USB, SMB, etc.)
- **Features per file/selection:**
- Preview (text, image, FITS header for astrophotography files)
- Compress / extract (zip, tar.gz)
- Copy, move, rename, delete
- Properties (permissions, owner, size on disk)
- **Mount management** — right-click a mount point to unmount; USB devices show an eject option
- **Path bar** — editable breadcrumb path at the top of each panel
- **No thumbnails** — performance-first; list only
---
### 📊 Task Manager
htop-inspired, but scoped and web-native. Shows:
- Process list: PID, name, CPU %, MEM %, status, user
- Sortable columns
- Kill / signal process action
- Filter to show only Atlus-relevant processes (or toggle to show all)
- Summary bar at top: total CPU, RAM, load average — mirrors the right panel stats but with more detail
- Auto-refreshes every 2 seconds via WebSocket
---
### 🌐 Network Monitor
Per-interface detail view:
- Interface name, MAC, state (up/down)
- IP addresses (IPv4 + IPv6)
- Gateway, DNS servers
- Live throughput (bytes in/out per second)
- For WiFi: SSID, signal strength, frequency band
---
### 🔧 Settings
*(see System Settings above — Settings is the dock entry point into the System Settings app)*
---
### Plugin Apps (Installable)
| App | Dock Icon | Description |
|---|---|---|
| **ASI Bridge** | `🔭` | ASI Air mount status, transfer log, Nextcloud sync, session summary |
| **Log Viewer** | `📝` | Real-time tail of any systemd service log via WebSocket |
| **INDI Control** | *(future)* | INDI server management for astrophotography rigs |
---
## Design Language
### Aesthetic
- Dark, utilitarian, refined — high-end terminal meets modern OS
- Inspired by: awesomewm, macOS terminal, Linear app
- Flat — no gradients, no heavy shadows, no decorative elements
### Typography
- **IBM Plex Mono** — all system data, file paths, IPs, timestamps, terminal output
- **Inter** — UI chrome, labels, app names, navigation
- Two weights only: 400 regular, 500 medium
### Color System
- Background layers (dark → light): `#0d0f14``#111318``#161b27`
- Borders: `#1e2130` (structural), `#2a2d36` (component-level)
- Text: `#c8ccd8` (primary), `#8891a8` (secondary), `#4a5068` (muted), `#2e3348` (ghost)
- Accent (active/selected): `#6ea6f0`
- Status: `#3ab86a` (ok/green), `#e09a2a` (warning/amber), `#e05a4a` (error/red)
### Motion
- Subtle only: tab switches, service toggle state, stat bar transitions
- Status values update live via WebSocket — no manual refresh needed
---
## ✅ Touch-First Design — Primary Target: iPad & Tablets
Atlus is **touch-first**. Desktop mouse/keyboard is secondary. Every interaction must be comfortable with a finger on a tablet screen. This affects every component.
### Touch Target Sizing
- **Minimum tap target: 48×48px** for all interactive elements (Apple HIG / Material guidelines)
- Dock icons: 56×56px minimum hit area
- File rows: minimum 48px tall
- Settings rows: minimum 48px tall
- Service toggles: at least 44px tall hit area (even if visually smaller)
- Tab bar items: minimum 44px tall
- All buttons: minimum 44px tall
### No Hover Dependency
- **No tooltips as primary labels** — dock icons must show a label below the icon (not on hover)
- No hover-only states for anything critical
- All context menus triggered by **long-press**, not right-click
- Hover styles may exist as a progressive enhancement for mouse users, but never as the only way to discover functionality
### Gesture Support
- **Swipe left/right** on the center stage to switch between open apps (like iOS app switching)
- **Swipe right from left edge** to reveal/toggle the dock on smaller screens
- **Swipe left from right edge** to reveal/toggle the right panel on smaller screens
- **Long-press** on files for context menu (cut, copy, rename, delete, compress, properties)
- **Long-press** on dock icon for app options (remove from dock, move)
- **Pull down** on file list to refresh directory
- **Pinch to zoom** in terminal and file preview — browser native
### Layout Adaptations for Touch
#### Landscape (primary tablet orientation):
- Three-column layout as designed — dock (72px wide), stage (flex), right panel (240px)
- Dock shows icon + label underneath (not tooltip)
- All rows/items generously spaced
#### Portrait / Narrow screens:
- Dock collapses to a slide-in drawer (swipe from left or tap hamburger)
- Right panel collapses to a slide-in drawer (swipe from right or tap info button in tab bar)
- Center stage goes full-width
- Tab bar remains visible at top
#### Phone (stretch goal, not v1):
- Bottom tab bar replaces left dock
- Right panel accessible via bottom sheet
### File Manager — Touch Adaptations
- Row height: 52px minimum
- Drag and drop uses **touch drag** (touchstart/touchmove/touchend events) not mouse drag
- Selection via long-press + drag, or tap checkbox mode
- Checkbox mode: tap a file to enter selection mode, then tap others to multi-select
- Context menu on long-press: open, preview, copy, move, rename, compress, delete
- No right-click context menu (or: right-click works as fallback for mouse users)
### Terminal — Touch Adaptations
- Software keyboard appears automatically on tap
- Toolbar of common keys above the software keyboard: Escape, Tab, Ctrl, arrow keys, pipe, tilde
- Pinch to adjust font size
- Two-finger scroll for scrollback
### Settings — Touch Adaptations
- All form rows 52px+ tall
- Toggle switches 51×31px (standard iOS-style)
- Sidebar nav items 48px tall minimum
- Save/cancel buttons large and thumb-reachable (bottom of content, full-width or right-aligned with generous padding)
### Right Panel — Touch Adaptations
- Service rows 52px tall — the toggle and ↗ button are both easy targets
- On narrow screens: collapses, accessible via swipe or button
### General Touch Rules
- No double-click interactions — everything single tap or long-press
- Scroll areas must be `-webkit-overflow-scrolling: touch` (momentum scrolling)
- `touch-action` set appropriately on draggable items
- Input fields: `font-size: 16px` minimum to prevent iOS auto-zoom on focus
- Avoid `position: fixed` where possible — use `position: sticky` for headers/toolbars
- All modals/dialogs centered and thumb-reachable, not tiny desktop-style popups
---
## Astrophotography Reference Deployment
The initial real-world deployment target:
```
[ASI Air] ──ethernet──▶ [Orange Pi 5 Max / Atlus] ──nextcloud──▶ [Home Server]
192.168.10.120 192.168.10.121 (eth to ASI Air)
192.168.1.121 (wifi to home network)
```
The **ASI Bridge** plugin panel shows:
- ASI Air SMB mount status (connected / disconnected / error)
- Nextcloud client sync status (idle / syncing / error)
- Live transfer log (filename, size, timestamp, sync result)
- Session summary (frames captured tonight, total GB transferred)
- Quick actions: remount share, restart sync service, clear log
---
## Tech Stack
| Component | Technology |
|---|---|
| Backend | Python 3.11+, FastAPI, asyncio, uvicorn |
| WebSockets | FastAPI WebSocket |
| System stats | psutil |
| Terminal | xterm.js (frontend) + ptyprocess (backend) |
| File ops | Python pathlib / os |
| Service mgmt | subprocess + systemctl |
| X11 embedding | Xvfb + x11vnc + noVNC (Phase 4 only) |
| Frontend | Vanilla JS, CSS custom properties, no build step |
| Fonts | IBM Plex Mono + Inter (Google Fonts CDN or self-hosted) |
| Packaging | Single systemd service + `install.sh` bootstrap script |
| Target OS | Debian/Ubuntu ARM64 (DietPi, Armbian, Raspberry Pi OS) |
---
## Project Phases
### Phase 1 — Core Shell *(start here)*
- [ ] Repo and project structure setup
- [ ] FastAPI backend — `/api/stats` endpoint (CPU, RAM, disk, temp, network IPs)
- [ ] WebSocket endpoint — push live stats every 2s
- [ ] Static frontend served by FastAPI
- [ ] Three-column shell layout (dock, stage, right panel) — HTML/CSS skeleton
- [ ] Right panel wired to live WebSocket stats + clock
- [ ] Left dock with app icons and active state
- [ ] Terminal app — xterm.js frontend + ptyprocess PTY backend
- [ ] App switching — clicking dock icon loads app into center stage
### Phase 2 — File Manager + Service Control
- [ ] File Manager — directory listing, navigate, breadcrumb path, sidebar mounts
- [ ] Service Manager — list systemd units, start/stop/restart via API
- [ ] Right panel service toggles wired to real systemctl calls
- [ ] Log Viewer — real-time tail of service logs via WebSocket stream
- [ ] Split pane layout — two apps tiled side by side
### Phase 3 — Plugin System + ASI Bridge
- [ ] Plugin architecture — self-contained module (backend route + frontend panel JS)
- [ ] ASI Bridge plugin — mount watcher, transfer log, Nextcloud sync status
- [ ] Settings app — configure dock items, services list, hostname display
### Phase 4 — X11 App Embedding *(advanced)*
- [ ] Xvfb process spawner via API call
- [ ] x11vnc per-app streaming to WebSocket
- [ ] noVNC embedded as a center stage pane
- [ ] Nextcloud Qt client embedded as live X11 panel
---
## ✅ Finalized Project Decisions
| Decision | Answer |
|---|---|
| **Project type** | Single monorepo — frontend served by FastAPI backend |
| **Framing** | Full desktop environment — not a server admin panel |
| **Authentication** | Username + password (session token after login) |
| **Default port** | 7779 |
| **Installation** | `curl \| bash` installer script |
| **License** | GPL |
| **Theming** | Dark only for v1 — light mode planned, CSS variables structured for it from day one |
| **Target OS** | DietPi (Debian ARM64) — installer targets DietPi, Armbian, Ubuntu Server as fallbacks |
| **Terminal sessions** | Multiple — tabbed terminals within the terminal pane |
| **Boot / login** | Branded login/boot screen before the desktop loads |
| **Filesystem access** | Full — same as any desktop environment |
| **Terminal user** | Runs as the logged-in system user |
| **Multiple clients** | Yes — multiple browsers/devices can connect simultaneously, all receive live WebSocket updates |
| **File operations** | Confirm destructive actions only (delete, overwrite) |
| **Service detection** | Auto-detect all systemd services — user manages visibility in Settings |
| **ASI Bridge when disconnected** | Show disconnected badge — still openable, shows a disconnected state screen |
| **Plugin (ASI Bridge)** | Built-in from day one, bundled with Atlus core |
| **Dock order** | Hard-coded for v1, configurable in Settings v2 |
| **Right panel width** | Fixed 240px for v1 |
---
## Project Structure (Monorepo)
```
atlus/
├── README.md
├── LICENSE # GPL
├── install.sh # curl | bash installer
├── atlus.service # systemd unit file template
├── backend/
│ ├── main.py # FastAPI app entry point
│ ├── config.py # Config, paths, constants
│ ├── auth.py # Username/password auth, session tokens
│ ├── routers/
│ │ ├── stats.py # /api/stats — CPU, RAM, disk, temp, network
│ │ ├── files.py # /api/files — filesystem operations
│ │ ├── services.py # /api/services — systemd management
│ │ ├── processes.py # /api/processes — task manager
│ │ ├── terminal.py # /api/terminal — PTY websocket
│ │ ├── settings.py # /api/settings — read/write config
│ │ └── plugins/
│ │ └── asi_bridge.py # ASI Air bridge plugin routes
│ ├── ws/
│ │ └── manager.py # WebSocket connection manager (multi-client broadcast)
│ └── requirements.txt
├── frontend/
│ ├── index.html # Login/boot screen
│ ├── desktop.html # Main desktop shell
│ ├── css/
│ │ ├── variables.css # CSS custom properties (colors, spacing, typography)
│ │ ├── shell.css # Three-column layout
│ │ ├── dock.css
│ │ ├── panel.css
│ │ ├── stage.css
│ │ ├── keyboard.css # Custom on-screen keyboard
│ │ └── apps/
│ │ ├── terminal.css
│ │ ├── files.css
│ │ ├── settings.css
│ │ └── tasks.css
│ ├── js/
│ │ ├── atlus.js # Core shell, app switching, WebSocket client
│ │ ├── auth.js # Login screen logic
│ │ ├── keyboard.js # Custom on-screen keyboard
│ │ └── apps/
│ │ ├── terminal.js # xterm.js + PTY integration
│ │ ├── files.js # File manager
│ │ ├── settings.js # Settings app
│ │ ├── tasks.js # Task manager
│ │ ├── services.js # Service manager
│ │ └── asi_bridge.js # ASI Bridge plugin panel
│ └── assets/
│ └── atlus-logo.svg
└── plugins/ # Future third-party plugins live here
```
---
## Open Questions (Deferred — Not Blocking v1)
- **Portrait collapse behavior**: Slide-in drawers vs. bottom tab bar — decide when building responsive CSS
- **Terminal keyboard quick-key row**: Exact key selection — decide during keyboard build
---
*Last updated: 2026-03-13*
*Project status: Planning complete ✅ — all decisions finalized — ready to build Phase 1*