diff --git a/.kiro/settings/mcp.json b/.kiro/settings/mcp.json index aa9cc51..de27a53 100644 --- a/.kiro/settings/mcp.json +++ b/.kiro/settings/mcp.json @@ -1,14 +1,5 @@ { "mcpServers": { - "aws-docs": { - "command": "uvx", - "args": ["awslabs.aws-documentation-mcp-server@latest"], - "env": { - "FASTMCP_LOG_LEVEL": "ERROR" - }, - "disabled": false, - "autoApprove": [] - }, "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp@latest"], diff --git a/README.md b/README.md index 27cb045..3e7be3b 100644 --- a/README.md +++ b/README.md @@ -1,256 +1,94 @@ # ArchNest -A self-hosted ops dashboard for a homelab/cloud setup: live infrastructure -monitoring across 9 real integration types, a categorized bookmark hub, a -full SSH suite (terminal, tunnels, file manager, host-to-host transfer, live -host metrics), Docker container management, and RDP/VNC/Telnet remote desktop -— all in one app, with zero mock data anywhere. +A multi-tenant SaaS platform for infrastructure management — SSH terminal, +Docker management, remote desktop, host metrics, file management, and 9 +real integration adapters from a single browser interface. Developer-first +alternative to enterprise RMM tools, starting at $2.50/month. -**This repo is private and will never be public.** This README is written for -the owner and for any AI session picking up the project cold — it should be -detailed enough that neither needs to re-derive context from scratch. +## Pricing -## What this is, in one paragraph +| | Starter | Pro | Team | +|---|---|---|---| +| Monthly | $2.50/mo | $4.25/mo | $12/mo | +| Annual | $25/yr | $45/yr | $95/yr | +| Hosts | 50 | 125 | Unlimited | +| Users | 5 | 50 | 200 | +| Remote Desktop | — | ✓ | ✓ | +| SSO | — | — | ✓ | -ArchNest replaced a Homarr-style bookmark dashboard plus a handful of -disconnected admin tools (Proxmox UI, Portainer, separate SSH terminals, -WinSCP-equivalents) with one app that talks directly to the underlying -systems. It started as a 6-page mockup/portfolio piece and has since grown -into an 11-page real tool with a real Fastify backend, real SSH/Docker/cloud -integrations, and no synthetic data — every number on every page comes from -a live API call, a SQLite-backed table, or an SSH command run against a -managed host. +## Features -## Current state & direction +**SSH Suite** — Terminal (multi-tab, split panes, persistent sessions), tunnels +(local/remote/SOCKS5), SFTP file manager, host-to-host transfer, host metrics +(5s polling), jump-host chaining, tmux, certificate auth (OPKSSH). -**Live and deployed** at `archnest.snsnetlabs.com`, auto-deploying on every -merge to `main` via `.github/workflows/deploy.yml`. All 11 pages and their -backend routes are built and working — there is no pending/on-hold page. +**Docker** — Management via TCP API, CLI over SSH, or push agent. Container +actions, logs, interactive exec, detail views. -Auth is feature-complete for self-hosted (Phases 1-3: user menu wiring, -password/sessions/login-log, multi-user roles with a 10-seat cap); Phase 4 -(Authentik SSO) is **deferred to a paid AWS add-on** — see `ROADMAP.md`. -Recently shipped: persistent terminal sessions across navigation, Docker -container visibility/management three ways (Engine TCP API, `docker` CLI over -SSH, and a read-only push agent — see `docs/docker-agent-monitoring.md`), and -the **Mesh Prerequisite Gate** — a universal CIDR-based mesh-verification -requirement (with a routed-mesh/VPC-peering fallback, not NetBird-specific), -configurable from Settings → Mesh and defaulting OFF so it can't lock the live -instance. +**Remote Desktop** — RDP/VNC/Telnet via Guacamole (Pro+). -There is no feature currently in progress. See `HANDOFF.md` for the latest -status and next steps. +**Integrations** — Proxmox, Docker, AWS, Cloudflare, NetBird, Uptime Kuma, +Weather, SSH, Remote Desktop. All real, no mocks. -If you're a fresh AI session: read this file, then `HANDOFF.md` (current -task state + standing workflow rules), then `design-decisions.md` (visual -conventions + accurate per-page implementation notes), then `ROADMAP.md` -(deferred/tiered work) and the `docs/` design docs (`docker-agent-monitoring.md`, -`mesh-prerequisite-gate.md`), then `TERMIX_MIGRATION.md` -(history of how the SSH/Docker/Guacamole feature set was built) if you need -that context. +**Bookmarks** — Categorized hub with favorites, link health, full CRUD. -## Pages +**Auth** — Cognito (OIDC/SAML SSO for Team), MFA, multi-user roles, audit log. -| Page | Route | What it does | -|------|-------|---------------| -| Glance | `/` | Home dashboard — system/integration health, resource overview, recent activity, shortcuts | -| Infrastructure | `/infrastructure` | Resource inventory across all integrations — distribution donut, per-resource status grid, integration health, activity | -| BookNest | `/booknest` | Categorized bookmark hub — quick access, favorites, link health, full CRUD | -| Terminal | `/terminal` | Web SSH terminal — multi-tab, split panes, tmux attach, cert auth (OPKSSH); **sessions stay connected across page navigation** | -| Tunnels | `/tunnels` | SSH tunnel manager — local/remote/dynamic (SOCKS5) forwarding, auto-start, live status | -| Files | `/files` | SFTP file browser/editor over managed SSH hosts, with host-to-host transfer | -| Containers | `/containers` | Docker containers across **three sources** (Engine TCP API, `docker` CLI over SSH, or a read-only push agent) — list/start/stop/restart/pause/remove, logs, interactive exec; tabbed with a clickable per-container detail view | -| Remote Desktop | `/remote-desktop` | RDP/VNC/Telnet sessions via a Guacamole sidecar | -| Host Metrics | `/host-metrics` | Live CPU/memory/disk/network/processes/ports/firewall/login-activity per SSH host, polled every 5s | -| Settings | `/settings` | Profile, Appearance, Security, Integrations, Notifications, Data & Backup, About — deep-linkable via `?tab=` | -| Help | `/help` | Static guided tour of every page above | -| Login / Enrollment | `/login`, `/enrollment` | Auth entry points — not in the sidebar nav | - -See `design-decisions.md`'s "Page Notes" section for a detailed, per-page -breakdown of layout, real data sources, and known quirks — it's kept in sync -with the actual code, not a spec written before the page existed. +**4 Themes** — ArchNest Dark, Midnight Blue, Forest, Light. ## Architecture -### Frontend (`/src`) -- React 19 + Vite + TypeScript, Tailwind CSS v4, Recharts (donuts/area - charts), Lucide React icons, React Router. -- `src/lib/api.ts` — typed fetch wrapper (`apiFetch`) + one function per - backend endpoint + matching TS interfaces. This is the contract between - frontend and backend; any new backend route needs a matching entry here. -- `src/lib/AuthContext.tsx` — auth state backed by `localStorage` (JWT - carrying a server-tracked session id; signing out revokes the session - server-side). -- `src/lib/TerminalSessionContext.tsx` — keeps SSH terminal sessions - (xterm + WebSocket + DOM node) alive above the router so they survive - in-app navigation; shared constants in `src/lib/terminalPrefs.ts`. -- `src/pages/` — one file per route (see table above), plus `Login.tsx` / - `Enrollment.tsx` for the unauthenticated/first-run flows. -- `src/components/` — `TopBar.tsx` (title, global search across pages/ - integrations/bookmarks, user dropdown), `Sidebar.tsx` (nav + system-health - rollup widget). -- `App.tsx` — route table, plus per-route hero-banner config (`showHero`, - `heroPaddingTop`, `heroObjectPosition` lookup maps) and `topBarHeight` - lookup for pages with a subtitle (currently only BookNest). +Hybrid: Akamai Cloud for compute, AWS for managed services. -### Backend (`/backend`) -- Fastify 5, TypeScript, ESM (`tsx` for dev, `tsc -b` for build), entrypoint - `src/server.ts`. -- `backend/src/db/index.ts` — SQLite schema + `logEvent()` audit log, - plus `sessions`/`login_events` tables and a multi-user `users` schema - (`role` admin/member + `active` columns). -- `backend/src/db/crypto.ts` — AES-256-GCM `encryptSecret`/`decryptSecret`, - keyed by `ARCHNEST_SECRET_KEY`. -- `backend/src/routes/` — one file per feature area: - - `auth.ts` — setup, login, profile, password change, sessions, - login audit log, and admin-only user management (`/api/setup`, - `/api/auth/*`, `/api/users`) - - `integrations.ts` — integration CRUD + connection testing - - `bookmarks.ts` — bookmarks + categories CRUD - - `events.ts` — activity log retrieval - - `terminal.ts` — SSH terminal WebSocket (`connect`/`input`/`resize`/ - `list_tmux`/`disconnect`) - - `tunnels.ts` — SSH tunnel CRUD + connect/disconnect - - `files.ts` — SFTP list/read/write/mkdir/rename/delete/chmod/download/upload - - `docker.ts` — Docker Engine TCP API: container list/stats/logs/actions + exec WebSocket - - `dockerSsh.ts` — Docker over SSH: runs the `docker` CLI on a remote SSH host (list/logs/actions + exec WebSocket); no dockerd socket exposed - - `agents.ts` — Docker monitoring agents: token-gated push ingest (`POST /api/agents/docker/report`) + read-only host/container views - - `guacamole.ts` — Guacamole WebSocket proxy for remote desktop - - `metrics.ts` — live host metrics endpoint - - `transfer.ts` — host-to-host file transfer orchestration (start/poll/cancel) - - `data.ts` — full backup export/import (integrations + secrets + bookmarks + tunnels) -- `backend/src/integrations/` — one adapter per type, all real (none are - stubs): `proxmox.ts`, `docker.ts`, `netbird.ts`, `cloudflare.ts`, `aws.ts`, - `uptimeKuma.ts`, `weather.ts`, `ssh.ts`, `remoteDesktop.ts`. Each implements - `testConnection()` (required) and `listResources()` (optional); - `registry.ts` maps `IntegrationType` → adapter. -- `backend/src/ssh/` — the shared SSH transport layer used by Terminal, - Files, Tunnels, Transfers, and Host Metrics: - - `connect.ts` — jump-host chaining, host-key verification, certificate auth - - `sftp.ts` — ephemeral SFTP connections for file ops - - `transfer.ts` — streamed host-to-host copy/move with progress + cancel - - `docker.ts` — runs the `docker` CLI over SSH for the Containers page's - "Docker over SSH" source (list/logs/actions + interactive exec) - - `metrics/` — 10 sequential collectors (cpu, memory, disk, uptime, - network, system, processes, ports, firewall, login-stats) — sequential - on purpose, to stay under OpenSSH's `MaxSessions` limit per host. -- Docker images run on Alpine; **OpenSSL legacy provider is enabled** in - `backend/Dockerfile` (`OPENSSL_CONF=/etc/ssl/openssl-legacy.cnf`) so - old-format encrypted PEM keys (`BEGIN RSA PRIVATE KEY` + `DEK-Info`) still - decrypt under OpenSSL 3 — don't remove this without understanding why. -- **Required env vars, no defaults**: `ARCHNEST_SECRET_KEY`, - `ARCHNEST_JWT_SECRET`. The server refuses to start without both. Optional: - `ARCHNEST_DB_PATH`, `PORT`, `ARCHNEST_GUAC_CRYPT_KEY` / - `ARCHNEST_GUACD_HOST` / `ARCHNEST_GUACD_PORT`, `ARCHNEST_CORS_ORIGIN`, - `ARCHNEST_SESSION_LOG_DIR` (optional terminal session logging), - `ARCHNEST_AGENT_TOKEN` (shared token enabling the Docker monitoring-agent - ingest endpoint — ingest is disabled / returns 503 when unset), - `ARCHNEST_AGENT_STALE_MS` (default 90000; when an agent report is shown stale). -- `backend/src/docker/` — Docker Engine TCP API client used by `docker.ts`. -- `agent/` — the standalone Docker monitoring agent (`archnest-docker-agent.sh` - + install/README). Runs on each Docker VM and pushes reports to ArchNest. +| Layer | Provider | Service | +|-------|----------|---------| +| Compute | Akamai | G7 Dedicated (4GB, ARM) | +| Load Balancer | Akamai | NodeBalancer | +| Frontend | Akamai | Object Storage | +| Database | Self-managed | PostgreSQL (RLS) | +| Cache | Self-managed | Redis | +| Auth | AWS | Cognito | +| Secrets | AWS | Secrets Manager | +| Storage | AWS | S3 | +| DNS | AWS | Route 53 | +| Email | AWS | SES | -## Development +**Infrastructure cost:** ~$66.50/month at 50 users. Scales to full AWS +(Fargate + Aurora) at 100+ users / $500+ MRR. -Frontend: -```bash -npm install -npm run dev -``` - -Backend: -```bash -cd backend -npm install -ARCHNEST_SECRET_KEY=$(openssl rand -hex 32) ARCHNEST_JWT_SECRET=$(openssl rand -hex 32) npm run dev -``` - -`ARCHNEST_DB_PATH` optionally overrides the SQLite file location (defaults to -a local path under `backend/`). `PORT` overrides the listen port (check -`server.ts` for the default). - -Type-check both before committing — this is the minimum bar, not a substitute -for testing in a browser: -```bash -npx tsc --noEmit # from repo root, frontend -cd backend && npx tsc --noEmit # backend -``` -Vite/the browser surface some runtime errors (e.g. missing icon exports — -see the lucide-react gotcha in `design-decisions.md`) that the type-checker -won't catch. +See [`docs/aws-architecture/system-design.md`](docs/aws-architecture/system-design.md) +for the full system design with diagrams, cost analysis, tier enforcement, +and scale-up path. ## Tech Stack -**Frontend** -- React 19 + Vite + TypeScript, React Router, Tailwind CSS v4 -- Recharts (donuts, line/area charts), Lucide React (icons) -- xterm.js (Terminal page terminal rendering) +**Frontend**: React 19, Vite 8, TypeScript, Tailwind CSS v4, React Router, +Recharts, Lucide React, xterm.js -**Backend** -- Fastify 5 + TypeScript, `tsx` for dev, `tsc -b` for build -- `better-sqlite3` for storage -- `@fastify/jwt` for auth tokens, `bcryptjs` for password hashing -- `zod` for request validation -- AES-256-GCM (Node `crypto`) for encrypting integration secrets at rest -- SSH client library powering the SSH transport layer (`backend/src/ssh/`) -- Guacamole Lite protocol for RDP/VNC/Telnet, proxied to a `guacd` sidecar +**Backend**: Fastify 5, TypeScript, PostgreSQL, Redis, zod, ssh2 -**Integrations**: Proxmox, Docker, NetBird, Cloudflare, AWS, Uptime Kuma, -Weather (wttr.in), SSH, Remote Desktop (RDP/VNC/Telnet via Guacamole) — see -`backend/src/integrations/` for adapter implementations. +**Auth**: AWS Cognito (OIDC/SAML SSO, MFA, PKCE) -**Deploy target:** Docker on `racknerd1` → Nginx Proxy Manager at -`archnest.snsnetlabs.com`. +**CI/CD**: Forgejo Actions → Docker → Akamai VM deploy -## Deployment +## Development -**Live and deployed.** `.github/workflows/deploy.yml` triggers on every push -to `main`: builds, SCPs the repo to `racknerd1`, and runs -`docker compose up -d --build` there, gated on an `/api/health` health check. -No further setup is needed — merging a PR to `main` redeploys automatically. +```bash +npm install && npm run dev # frontend +cd backend && npm install && npm run dev # backend +``` -`docker-compose.yml` runs 3 services: `archnest` (frontend), `archnest-backend`, -and `guacd` (remote desktop sidecar). +Type-check before committing: +```bash +npm run build # frontend +cd backend && npx tsc --noEmit # backend +``` -If a deploy fails, check the workflow run's `deploy` job steps in order: -`Pre-flight` (confirms host `.env` exists) → `Copy repo to racknerd1` → -`Build, restart, and clean up` → `Health check (backend /api/health)`. +## Documentation -One-time setup already done (reference only, shouldn't need repeating): host -provisioning (Docker/Compose on `racknerd1`, deploy SSH user, `/opt/archnest` -directory), `/opt/archnest/.env` populated from `.env.example` with real -secrets, `RACKNERD_HOST`/`RACKNERD_USER`/`RACKNERD_SSH_KEY` added as GitHub -Actions secrets, DNS/Nginx Proxy Manager pointed at the host. - -## Documentation map - -- **`README.md`** (this file) — architecture, tech stack, deployment, page list. -- **`HANDOFF.md`** — current task state, standing workflow rules (git workflow, - mock-data policy, secrets discipline), and the auth/SSO roadmap. Read this - before starting any new work session. -- **`design-decisions.md`** — visual/UX conventions (colors, typography, card - style, animations) plus a detailed, accurate-as-of-now "Page Notes" section - per page — what's actually rendered and where its data comes from. This is - the file to update whenever a page's layout or data source changes. -- **`TERMIX_MIGRATION.md`** — phase-by-phase history of how the SSH/Tunnels/ - Files/Containers/Remote Desktop/Host Metrics/Transfer/Data-export feature - set was built (originally scoped as a migration from a forked Termix - project, hence the name). Useful for historical "why was it built this - way" context on those specific features. -- **`.kiro/steering/design-rules.md`** — a condensed duplicate of - `design-decisions.md`'s Global Rules, auto-injected into every Kiro IDE - session (the Kiro extension reads `.kiro/steering/*` automatically). If you - update a global design rule, update both files in the same change — - `design-decisions.md` is canonical, this one just needs to stay in sync so - Kiro doesn't steer on stale info. - -Three older docs were deleted as part of a documentation cleanup: -`archnest-blueprint.md` and `glance.md` (the original 6-page mockup pitch and -an early Glance-only spec, both describing fictional config files and -placeholder numbers that never matched the real build), and -`.kiro/specs/archnest-dashboard/` (an abandoned Kiro spec — requirements-only, -no `design.md`/`tasks.md` ever followed — describing the same stale 6-page/ -80px-sidebar/Zustand-based vision). Their still-accurate content (color -palette, dropdown menu shape, card styling) was folded into -`design-decisions.md` and `.kiro/steering/design-rules.md`; everything else -was superseded by the real, deployed implementation described above. +| File | Content | +|------|---------| +| [`docs/aws-architecture/system-design.md`](docs/aws-architecture/system-design.md) | Full architecture, costs, tier enforcement | +| [`design-decisions.md`](design-decisions.md) | Visual conventions + per-page notes | +| [`HANDOFF.md`](HANDOFF.md) | Current state, workflow rules | +| [`ROADMAP.md`](ROADMAP.md) | Deferred/tiered work | diff --git a/backend/package-lock.json b/backend/package-lock.json index 9d2c05f..4adaa73 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -28,10 +28,10 @@ }, "devDependencies": { "@types/bcryptjs": "^2.4.6", - "@types/better-sqlite3": "^7.6.12", - "@types/node": "^22.10.5", + "@types/better-sqlite3": "^7.6.13", + "@types/node": "^22.20.0", "tsx": "^4.19.2", - "typescript": "^5.7.3" + "typescript": "^5.9.3" } }, "node_modules/@aws-crypto/crc32": { @@ -1259,9 +1259,9 @@ } }, "node_modules/@types/node": { - "version": "22.19.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.21.tgz", - "integrity": "sha512-VMeFBSCKQKmm2swI2kW51SFusDqekC6q9trBCvJ/JliDchFSuoYYKN7yVNjPthP1HKZcx3U1gI/wTcEBjEFKTA==", + "version": "22.20.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.0.tgz", + "integrity": "sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==", "dev": true, "license": "MIT", "dependencies": { diff --git a/backend/package.json b/backend/package.json index 480760b..632e243 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,9 +29,9 @@ }, "devDependencies": { "@types/bcryptjs": "^2.4.6", - "@types/better-sqlite3": "^7.6.12", - "@types/node": "^22.10.5", + "@types/better-sqlite3": "^7.6.13", + "@types/node": "^22.20.0", "tsx": "^4.19.2", - "typescript": "^5.7.3" + "typescript": "^5.9.3" } } diff --git a/docs/aws-architecture/archnest-architecture.png b/docs/aws-architecture/archnest-architecture.png new file mode 100644 index 0000000..b116d85 Binary files /dev/null and b/docs/aws-architecture/archnest-architecture.png differ diff --git a/docs/aws-architecture/generate_diagram.py b/docs/aws-architecture/generate_diagram.py new file mode 100644 index 0000000..12ca4f9 --- /dev/null +++ b/docs/aws-architecture/generate_diagram.py @@ -0,0 +1,73 @@ +from diagrams import Diagram, Cluster, Edge +from diagrams.aws.security import Cognito, SecretsManager +from diagrams.aws.storage import S3 +from diagrams.aws.network import Route53 +from diagrams.aws.compute import Lambda +from diagrams.aws.engagement import SES +from diagrams.onprem.container import Docker +from diagrams.onprem.compute import Server +from diagrams.onprem.database import PostgreSQL +from diagrams.onprem.inmemory import Redis +from diagrams.onprem.network import Nginx +from diagrams.onprem.client import User +from diagrams.generic.storage import Storage + +with Diagram("ArchNest SaaS - Hybrid Architecture", show=False, filename="/tmp/archnest-hybrid", direction="TB", outformat="png"): + + users = User("Tenants") + + with Cluster("Akamai Cloud"): + lb = Nginx("NodeBalancer\nHTTPS/WSS") + + with Cluster("G7 Dedicated (4GB, 2 vCPU, ARM)"): + backend = Server("Fastify\nBackend API") + websocket = Server("Fastify\nWebSocket Service") + guacd = Docker("guacd\n(RDP/VNC)") + + with Cluster("Data (Self-Managed)"): + postgres = PostgreSQL("PostgreSQL\n(RLS Enabled)") + redis = Redis("Redis\n(Sessions/Cache)") + + static = Storage("Object Storage\n(React SPA)") + + with Cluster("AWS (Managed Services Only)"): + cognito = Cognito("Cognito\nUser Pools + SSO") + pre_token = Lambda("Pre-Token\nLambda") + secrets = SecretsManager("Secrets Manager\nSSH Keys") + s3 = S3("S3\nBackups + Logs") + route53 = Route53("Route 53") + ses = SES("SES\nEmail") + stripe_lambda = Lambda("Stripe\nWebhook Lambda") + + with Cluster("Tenant Infrastructure"): + host1 = Server("SSH Host A") + host2 = Server("SSH Host B") + docker_host = Docker("Docker Host") + + # User flow + users >> route53 >> lb + lb >> static + lb >> backend + lb >> websocket + + # Backend connections + backend >> postgres + backend >> redis + backend >> secrets + backend >> s3 + websocket >> redis + websocket >> guacd + + # Auth + cognito >> pre_token + backend >> cognito + stripe_lambda >> cognito + + # Outbound to tenant hosts (direct, no NAT needed) + backend >> host1 + backend >> host2 + websocket >> host1 + websocket >> docker_host + + # Email + backend >> ses diff --git a/docs/aws-architecture/system-design.html b/docs/aws-architecture/system-design.html new file mode 100644 index 0000000..9a72e30 --- /dev/null +++ b/docs/aws-architecture/system-design.html @@ -0,0 +1,419 @@ + + + + + +ArchNest — Product Design Review + + + + +
+ +
+

ArchNest

+

Self-Hosted Product Design — Open Core + Paid Modules

+

Free self-hosted ops dashboard. Unlock features with $5 one-time module purchases. Own it forever. No subscriptions.

+
+ Free Core + $5/Module + Self-Hosted +
+
+ +

Business Model

+
+
+
How It Works
+
    +
  • Free core — genuinely useful self-hosted dashboard
  • +
  • $5 one-time purchase per module (30 modules available)
  • +
  • Bundles at discount ($10-$99)
  • +
  • Free core updates forever
  • +
  • Customer owns it — no vendor lock-in
  • +
+
+
+
Your Economics
+
    +
  • Infrastructure cost: ~$1/month (license server)
  • +
  • Profit margin: 95%+ per sale
  • +
  • Zero churn (one-time, not subscription)
  • +
  • Zero hosting cost per customer
  • +
  • Net per $5 module (after Stripe): $4.55
  • +
+
+
+ +

Free Core

+
+
Ships Free — No Purchase Required
+ + + + + + + + + + + + + + +
FeatureFree Limit
Dashboard (Glance)Full
Infrastructure OverviewFull
SSH Terminal1 tab, 1 pane
SSH TunnelsManual start only
SFTP File ManagerFull
Docker ManagementTCP API only, 1 source
Host MetricsBasic (CPU/memory/disk)
Bookmarks10 max
SSH Hosts3 max
Users1 (admin only)
ThemeArchNest Dark only
Help PageFull
+
+ +

Paid Modules — $5 Each

+ +

SSH Modules (8)

+
+
+
1. Multi-Pane Terminal
+

Split panes (2/4), multiple tabs

+
+
+
2. tmux Integration
+

Attach to existing tmux sessions

+
+
+
3. Jump-Host Chaining
+

Connect through intermediary hosts

+
+
+
4. Certificate Auth
+

OPKSSH certificate-based SSH auth

+
+
+
5. Tunnel Auto-Start
+

Tunnels start automatically on boot

+
+
+
6. Persistent Sessions
+

Terminal sessions survive navigation

+
+
+
7. Session Recording
+

Record terminal sessions to disk

+
+
+
8. Host-to-Host Transfer
+

Copy/move files between SSH hosts

+
+
+ +

Docker Modules (4)

+
+
+
9. Docker over SSH
+

Manage containers via CLI over SSH

+
+
+
10. Docker Push Agent
+

Outbound-only monitoring agent

+
+
+
11. Container Exec
+

Interactive shell into containers

+
+
+
12. Container Details
+

Full inspect: ports, networks, env, mounts

+
+
+ +

Integration Modules (6)

+
+
+
13. Unlimited SSH Hosts
+

Remove 3-host cap

+
+
+
14. Proxmox
+

VM/LXC management

+
+
+
15. AWS
+

EC2 + STS resource inventory

+
+
+
16. Cloudflare
+

DNS zones, resource listing

+
+
+
17. NetBird
+

Mesh peers, connectivity

+
+
+
18. Uptime Kuma
+

Monitor status/health

+
+
+ +

Desktop & Theme Modules (6)

+
+
+
19. Remote Desktop: RDP
+

Windows RDP via Guacamole

+
+
+
20. Remote Desktop: VNC
+

VNC sessions via Guacamole

+
+
+
21. Remote Desktop: Telnet
+

Telnet sessions via Guacamole

+
+
+
22. Theme: Midnight Blue
+
+
+
+
23. Theme: Forest
+
+
+
+
24. Theme: Light
+
+
+
+ +

Platform Modules (6)

+
+
+
25. Multi-User
+

Admin/member roles, up to 10 seats

+
+
+
26. Advanced Metrics
+

Network, processes, ports, firewall, login stats

+
+
+
27. Data Export/Import
+

Backup/restore full config as JSON

+
+
+
28. Audit Log
+

Full activity log with export

+
+
+
29. Unlimited Bookmarks
+

Remove 10-bookmark cap

+
+
+
30. Global Search
+

Search pages, integrations, bookmarks

+
+
+ +

Bundles

+
+
+
SSH Pro
+

$25

+

All 8 SSH modules (save $15)

+
+
+
Docker Pro
+

$15

+

All 4 Docker modules (save $5)

+
+
+
Remote Desktop
+

$10

+

RDP + VNC + Telnet (save $5)

+
+
+
All Themes
+

$10

+

3 extra themes (save $5)

+
+
+
Everything
+

$99

+

All 30 modules forever (save $51)

+
+
+ +

License System

+
+graph LR + BOOT[ArchNest Boot] --> CHECK[License Check
HTTPS to license server] + CHECK --> RESP[Signed Response
modules + valid_until] + RESP --> VALIDATE[Validate Ed25519
signature locally] + VALIDATE --> UNLOCK[Unlock purchased
modules] + UNLOCK --> WEEKLY[Re-check weekly] + WEEKLY --> CHECK +
+
+
+
How It Works
+
    +
  • Phone-home on boot + once weekly
  • +
  • Returns signed JSON: modules[] + valid_until (7 days)
  • +
  • Ed25519 signature validated locally (public key in code)
  • +
  • Works offline for 7 days between checks
  • +
  • After 7 days offline → falls back to free core
  • +
+
+
+
License Server Stack
+
    +
  • Cloudflare Workers (free tier: 100K req/day)
  • +
  • Cloudflare D1 database (free tier: 5GB)
  • +
  • Stripe for payments
  • +
  • Total cost: ~$1/month + Stripe fees
  • +
  • Net per module sale: $4.55 (after Stripe)
  • +
+
+
+ +

Purchase Flow

+
+graph LR + BROWSE[Browse Module Store
in Settings] --> BUY[Click Buy → $5] + BUY --> STRIPE[Stripe Checkout] + STRIPE --> WEBHOOK[Webhook → License Server] + WEBHOOK --> RECORD[Record purchase
in D1 database] + RECORD --> POLL[Next license check
returns new module] + POLL --> ACTIVE[Feature unlocks] +
+ +

Revenue Projections

+
+ + + + + + +
StageInstalls/moAvg Modules BoughtRevenue/mo
Early (month 1-3)503 modules ($15)$750
Growth (month 4-6)2004 modules ($20)$4,000
Steady (month 7-12)5005 modules ($25)$12,500
Mature (year 2)1,000$30 avg (bundles)$30,000
+

Infrastructure cost stays at ~$1/month regardless of scale. 95%+ margin at all stages.

+
+ +

What Changes From Current Code

+
+ + + + + + + + + +
AreaCurrentNew
DatabaseSQLiteSQLite (stays)
AuthLocal JWTLocal JWT (stays)
Multi-tenantN/ANot needed (single-tenant per install)
LicenseNoneWeekly phone-home + signature validation
Module gatingNoneFastify middleware + frontend lock UI
SettingsCurrent tabs+ "Module Store" tab
StripeNoneCheckout for purchases
+

Key insight: Almost no infrastructure changes. You're adding a license layer and a store UI — not rewriting anything.

+
+ +

Implementation Phases

+
+
+
Phase 1 — License Infrastructure
+
    +
  • Build license server (CF Workers + D1)
  • +
  • Add license check to backend
  • +
  • Add module enforcement middleware
  • +
  • Add "Module Store" tab in Settings
  • +
+
+
+
Phase 2 — Module Gating
+
    +
  • Define module boundaries in routes
  • +
  • Add lock UI to gated features
  • +
  • Free tier caps (3 hosts, 1 pane, 10 bookmarks)
  • +
+
+
+
Phase 3 — Purchase Flow
+
    +
  • Stripe Checkout integration
  • +
  • Module activation on webhook
  • +
  • Bundle discounts
  • +
  • Purchase history in Settings
  • +
+
+
+
Phase 4 — Distribution
+
    +
  • Public Docker image
  • +
  • Landing page + module catalog
  • +
  • Installation docs
  • +
  • Demo instance
  • +
+
+
+ +

Open Decisions

+ + + + + + + + +
#QuestionOptions
1Source code visibilityOpen-source (MIT) vs source-available (BSL) vs proprietary
2DistributionDocker Hub vs GitHub Container Registry
3Landing pageCloudflare Pages vs separate repo
4Refund policy30-day vs no refunds ($5 is low)
5Module store UXIn-app tab vs external website
6License transferUnlimited vs 1/year
+ +
+ +
+
+ Product Design Review + ArchNest — Self-Hosted + $5 Modules +
+
+ + +
+
+ + + + diff --git a/docs/aws-architecture/system-design.md b/docs/aws-architecture/system-design.md new file mode 100644 index 0000000..6aea006 --- /dev/null +++ b/docs/aws-architecture/system-design.md @@ -0,0 +1,326 @@ +# ArchNest — Self-Hosted Product Design + +> Open-core model: free self-hosted base with $5 one-time module purchases. +> No subscriptions. No SaaS. Customer owns it forever. + +--- + +## Business Model + +| Aspect | Detail | +|--------|--------| +| **Core** | Free, self-hosted, open-source (or source-available) | +| **Modules** | $5 one-time purchase each (lifetime license) | +| **Updates** | Free core updates forever. Module updates included. | +| **License** | Phone-home on boot + weekly check. Works offline between checks. | +| **Revenue** | Volume × $5. Target: high module attach rate per install. | +| **Infrastructure cost** | Near zero (license server + payment processor only) | + +--- + +## Free Core (What Ships for Free) + +The free tier must be genuinely useful — good enough to adopt, limited enough +to want more. + +| Feature | Included Free | +|---------|--------------| +| Dashboard (Glance page) | ✓ | +| Infrastructure overview | ✓ | +| SSH Terminal (1 tab, 1 pane) | ✓ | +| SSH Tunnels (manual start only) | ✓ | +| SFTP File Manager | ✓ | +| Docker management (TCP API only, 1 source) | ✓ | +| Host Metrics (basic: CPU/memory/disk) | ✓ | +| Bookmarks (10 max) | ✓ | +| Settings (Profile, Integrations) | ✓ | +| 3 SSH host integrations max | ✓ | +| 1 user (admin only) | ✓ | +| Single theme (ArchNest Dark) | ✓ | +| Help page | ✓ | + +**Why this works:** A solo developer with 1–3 servers can use ArchNest for +free with a functional terminal, basic Docker visibility, and file management. +The moment they want split panes, more hosts, multi-user, or RDP — they buy +modules. + +--- + +## Paid Modules ($5 Each) + +### SSH Modules + +| # | Module | What It Unlocks | +|---|--------|-----------------| +| 1 | **Multi-Pane Terminal** | Split panes (2/4), multiple tabs | +| 2 | **tmux Integration** | Attach to existing tmux sessions | +| 3 | **Jump-Host Chaining** | Connect through intermediary hosts (ProxyJump) | +| 4 | **Certificate Auth (OPKSSH)** | Certificate-based SSH authentication | +| 5 | **Tunnel Auto-Start** | Tunnels start automatically on boot | +| 6 | **Persistent Sessions** | Terminal sessions survive page navigation | +| 7 | **Session Recording** | Record terminal sessions to disk | +| 8 | **Host-to-Host Transfer** | Copy/move files between two SSH hosts | + +### Docker Modules + +| # | Module | What It Unlocks | +|---|--------|-----------------| +| 9 | **Docker over SSH** | Manage containers via `docker` CLI over SSH (no exposed socket) | +| 10 | **Docker Push Agent** | Outbound-only monitoring agent for Docker hosts | +| 11 | **Container Exec** | Interactive shell into running containers | +| 12 | **Container Detail View** | Full inspect: ports, networks, mounts, env, labels | + +### Integration Modules + +| # | Module | What It Unlocks | +|---|--------|-----------------| +| 13 | **Unlimited SSH Hosts** | Remove 3-host cap (unlimited integrations) | +| 14 | **Proxmox Integration** | VM/LXC management | +| 15 | **AWS Integration** | EC2 + STS resource inventory | +| 16 | **Cloudflare Integration** | DNS zones, resource listing | +| 17 | **NetBird Integration** | Mesh peers, connectivity | +| 18 | **Uptime Kuma Integration** | Monitor status/health | + +### Desktop & Display Modules + +| # | Module | What It Unlocks | +|---|--------|-----------------| +| 19 | **Remote Desktop (RDP)** | RDP sessions via Guacamole | +| 20 | **Remote Desktop (VNC)** | VNC sessions via Guacamole | +| 21 | **Remote Desktop (Telnet)** | Telnet sessions via Guacamole | +| 22 | **Theme: Midnight Blue** | Blue accent theme | +| 23 | **Theme: Forest** | Emerald accent theme | +| 24 | **Theme: Light** | Light mode theme | + +### Platform Modules + +| # | Module | What It Unlocks | +|---|--------|-----------------| +| 25 | **Multi-User** | Add users (admin/member roles, up to 10 seats) | +| 26 | **Advanced Metrics** | Full host metrics (network, processes, ports, firewall, login stats) | +| 27 | **Data Export/Import** | Backup/restore integrations + secrets + bookmarks + tunnels | +| 28 | **Audit Log** | Full activity audit log with export | +| 29 | **Unlimited Bookmarks** | Remove 10-bookmark cap | +| 30 | **Global Search** | Search across pages, integrations, bookmarks | + +--- + +## Bundles (Discounted) + +| Bundle | Modules Included | Price | Savings | +|--------|-----------------|-------|---------| +| **SSH Pro** | #1–8 (all SSH modules) | $25 | Save $15 | +| **Docker Pro** | #9–12 (all Docker modules) | $15 | Save $5 | +| **Remote Desktop** | #19–21 (RDP + VNC + Telnet) | $10 | Save $5 | +| **All Themes** | #22–24 (3 themes) | $10 | Save $5 | +| **Everything** | All 30 modules | $99 | Save $51 | + +--- + +## Revenue Model + +| Scenario | Installs/mo | Avg modules purchased | Revenue/mo | +|----------|-------------|----------------------|------------| +| Early (month 1-3) | 50 | 3 modules ($15 avg) | $750 | +| Growth (month 4-6) | 200 | 4 modules ($20 avg) | $4,000 | +| Steady (month 7-12) | 500 | 5 modules ($25 avg) | $12,500 | +| Mature (year 2) | 1,000 | 4 modules + bundles ($30 avg) | $30,000 | + +**Infrastructure cost:** ~$20-30/month (license server + Stripe + domain). +**Profit margin:** ~95%+ (no SaaS hosting, no per-tenant compute). + +--- + +## License System Architecture + +### Phone-Home (Light Touch) + +``` +┌─────────────────────┐ ┌────────────────────────┐ +│ Customer Install │ │ License Server │ +│ │ │ (Akamai / Cloudflare │ +│ Fastify Backend │────────▶│ Workers / Lambda) │ +│ on boot + weekly │ │ │ +│ │◀────────│ Returns: │ +│ Validates signed │ │ - licensed_modules[] │ +│ response locally │ │ - valid_until (7day) │ +└─────────────────────┘ │ - signature │ + └────────────────────────┘ +``` + +**How it works:** +1. Customer installs ArchNest (Docker Compose or bare metal) +2. On first boot, backend calls license server with install ID +3. License server returns a signed JSON payload: + - `modules`: list of purchased module slugs + - `valid_until`: timestamp (7 days from now) + - `signature`: Ed25519 signature of the payload +4. Backend validates the signature locally (public key embedded in code) +5. If signature valid and `valid_until` hasn't expired → features unlocked +6. Re-checks weekly. If server unreachable, works offline for 7 days. +7. After 7 days without a successful check → falls back to free core only + +**Grace period:** 7 days offline. Generous enough for server maintenance, +network issues, etc. If someone loses internet for a week, they keep working. + +### License Server Stack + +| Component | Provider | Cost | +|-----------|----------|------| +| License API | Cloudflare Workers (free tier: 100K req/day) | $0 | +| Database | Cloudflare D1 (free tier: 5GB) | $0 | +| Payment | Stripe (2.9% + $0.30 per transaction) | Per-sale | +| Domain | Route 53 or Cloudflare | $1/mo | +| **Total** | | **~$1/mo + Stripe fees** | + +At $5/module, Stripe takes ~$0.45 per transaction. Net per module: **$4.55**. + +### Purchase Flow + +``` +Customer browses modules in Settings → Module Store tab + → Clicks "Buy" → Stripe Checkout ($5) + → Stripe webhook → License server records purchase + → Customer's next license check returns new module + → Feature unlocks immediately (or within minutes on next poll) +``` + +### Install ID Generation + +- Generated on first boot: `SHA-256(machine-id + secret-key + timestamp)` +- Stored in the database +- Tied to Stripe customer on first purchase +- Transferable (customer can request a reset if they move servers) + +--- + +## Module Enforcement (Backend) + +```typescript +// Fastify plugin — runs before route handlers +const tierMiddleware = (app) => { + app.addHook('onRequest', async (req, reply) => { + const license = app.licenseCache; // refreshed weekly + req.modules = license?.modules ?? []; + }); +}; + +// Route-level check +app.get('/api/terminal/connect', { + preHandler: [requireModule('multi-pane-terminal')], + handler: terminalConnect +}); + +function requireModule(slug: string) { + return async (req, reply) => { + if (!req.modules.includes(slug)) { + reply.code(402).send({ + error: 'Module required', + module: slug, + price: '$5', + purchaseUrl: `https://archnest.io/modules/${slug}` + }); + } + }; +} +``` + +**Frontend enforcement:** +- Module-gated UI elements show a lock icon + "Unlock for $5" prompt +- Clicking opens the purchase flow (in-app or redirect to store) +- After purchase, UI refreshes and feature unlocks + +--- + +## Free Core Updates + +- All users get bug fixes, security patches, and core feature improvements +- Module features don't get stripped from updates — once bought, always works +- New modules may be added over time (new revenue without churning existing customers) +- Major version upgrades (v2, v3) may require a new "Everything" bundle purchase (TBD) + +--- + +## Comparison: SaaS vs Self-Hosted Module Model + +| | SaaS (old design) | Self-Hosted Modules (new) | +|---|---|---| +| Infra cost | $66-300/mo | ~$1/mo | +| Revenue model | Recurring ($2.50-12/mo) | One-time ($5/module) | +| Churn risk | High (monthly cancel) | None (one-time) | +| Support burden | High (you host it) | Low (they host it) | +| Profit margin | 60-65% | 95%+ | +| Scale limit | Your AWS bill | Their hardware | +| Customer lock-in | Subscription | Ownership (better reputation) | + +--- + +## Tech Stack (Unchanged) + +| Layer | Tech | +|-------|------| +| Frontend | React 19, Vite 8, TypeScript, Tailwind v4 | +| Backend | Fastify 5, TypeScript, SQLite (better-sqlite3) | +| Auth | Local JWT + bcrypt (self-hosted, no Cognito) | +| License | Phone-home to Cloudflare Workers | +| Payment | Stripe Checkout | +| Deploy | Docker Compose (customer's hardware) | +| CI/CD | Forgejo Actions | + +--- + +## What Changes From Current Codebase + +| Area | Current | New | +|------|---------|-----| +| Database | SQLite (stays) | SQLite (stays — no Postgres migration needed) | +| Auth | Local JWT (stays) | Local JWT (stays — no Cognito needed) | +| Multi-tenant | Not needed | Not needed (single-tenant per install) | +| License check | None | New: weekly phone-home + local signature validation | +| Module gating | None | New: Fastify middleware + frontend lock UI | +| Settings page | Current tabs | New: "Module Store" tab | +| Stripe | None | New: Stripe Checkout for purchases | + +**Key insight:** This model requires almost no infrastructure changes to the +current codebase. You're adding a license middleware layer and a store UI — +not rewriting the database, auth, or deployment. + +--- + +## Implementation Priority + +### Phase 1: License Infrastructure +1. Build license server (Cloudflare Workers + D1) +2. Add license check to backend (on boot + weekly cron) +3. Add module enforcement middleware +4. Add "Module Store" tab in Settings + +### Phase 2: Module Gating +1. Define module boundaries in code (which routes require which module) +2. Add lock UI to gated features in frontend +3. Free tier caps (3 hosts, 1 pane, 10 bookmarks) + +### Phase 3: Purchase Flow +1. Stripe integration (Checkout, webhooks) +2. Module activation on purchase +3. Bundle discounts +4. Purchase history in Settings + +### Phase 4: Distribution +1. Public Docker image on Docker Hub / GitHub Container Registry +2. Landing page with module catalog +3. Installation docs +4. Demo instance for prospects + +--- + +## Open Decisions + +| # | Question | Options | +|---|----------|---------| +| 1 | Source code visibility | Open-source (MIT/Apache) vs source-available (BSL) vs proprietary | +| 2 | Docker Hub vs self-hosted registry | Docker Hub (wider reach) vs GHCR (free private) | +| 3 | Landing page tech | Static site on Cloudflare Pages vs separate repo | +| 4 | Refund policy | 30-day no-questions vs no refunds ($5 is low enough) | +| 5 | Module store UX | In-app tab vs external website | +| 6 | License transfer | Allow unlimited vs 1 transfer per year | diff --git a/infrastructure/cloudformation.yml b/infrastructure/cloudformation.yml new file mode 100644 index 0000000..a638fb4 --- /dev/null +++ b/infrastructure/cloudformation.yml @@ -0,0 +1,173 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: > + ArchNest - Single-user self-hosted ops dashboard on AWS. + Deploys a t4g.small EC2 instance with Docker Compose. + +Parameters: + KeyPairName: + Type: String + Default: kiro-ide-key + Description: SSH key pair name for EC2 access + + InstanceType: + Type: String + Default: t4g.small + AllowedValues: + - t4g.micro + - t4g.small + - t4g.medium + Description: EC2 instance type (ARM/Graviton) + + VolumeSize: + Type: Number + Default: 30 + Description: EBS volume size in GB + +Resources: + # Security Group — allows SSH, HTTP, HTTPS, and the backend port + ArchNestSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: ArchNest security group + GroupName: archnest-sg + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 0.0.0.0/0 + Description: SSH access + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + Description: HTTP (redirect to HTTPS) + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + Description: HTTPS + - IpProtocol: tcp + FromPort: 8080 + ToPort: 8080 + CidrIp: 0.0.0.0/0 + Description: Frontend (direct, before proxy) + - IpProtocol: tcp + FromPort: 4000 + ToPort: 4000 + CidrIp: 0.0.0.0/0 + Description: Backend API + SecurityGroupEgress: + - IpProtocol: -1 + CidrIp: 0.0.0.0/0 + Description: All outbound (SSH to managed hosts, Docker pulls, etc.) + Tags: + - Key: Name + Value: archnest-sg + + # Elastic IP — stable public IP across stop/start + ArchNestEIP: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + Tags: + - Key: Name + Value: archnest-eip + + # EC2 Instance + ArchNestInstance: + Type: AWS::EC2::Instance + Properties: + InstanceType: !Ref InstanceType + KeyName: !Ref KeyPairName + ImageId: !FindInMap [RegionAMI, !Ref 'AWS::Region', AMI] + SecurityGroupIds: + - !Ref ArchNestSecurityGroup + BlockDeviceMappings: + - DeviceName: /dev/sda1 + Ebs: + VolumeSize: !Ref VolumeSize + VolumeType: gp3 + Encrypted: true + UserData: + Fn::Base64: | + #!/bin/bash + set -e + + # Update system + apt-get update -y + apt-get upgrade -y + + # Install Docker + apt-get install -y docker.io docker-compose-v2 git curl + systemctl enable --now docker + + # Create deploy directory + mkdir -p /opt/archnest + chown ubuntu:ubuntu /opt/archnest + + # Signal ready + echo "ArchNest instance ready" > /opt/archnest/READY + Tags: + - Key: Name + Value: archnest + + # Associate Elastic IP with instance + ArchNestEIPAssociation: + Type: AWS::EC2::EIPAssociation + Properties: + InstanceId: !Ref ArchNestInstance + EIP: !Ref ArchNestEIP + + # Budget alarm — $30/month ceiling + ArchNestBudget: + Type: AWS::Budgets::Budget + Properties: + Budget: + BudgetName: archnest-monthly + BudgetType: COST + TimeUnit: MONTHLY + BudgetLimit: + Amount: 30 + Unit: USD + NotificationsWithSubscribers: + - Notification: + NotificationType: ACTUAL + ComparisonOperator: GREATER_THAN + Threshold: 80 + Subscribers: + - SubscriptionType: EMAIL + Address: samueljamesinc@gmail.com + - Notification: + NotificationType: ACTUAL + ComparisonOperator: GREATER_THAN + Threshold: 100 + Subscribers: + - SubscriptionType: EMAIL + Address: samueljamesinc@gmail.com + +Mappings: + # Ubuntu 24.04 LTS ARM64 AMIs per region + RegionAMI: + us-east-1: + AMI: ami-0a7a4e87939439934 + us-east-2: + AMI: ami-0ea3405d2d2522162 + us-west-2: + AMI: ami-05d38da78ce859165 + +Outputs: + PublicIP: + Description: ArchNest public IP address + Value: !Ref ArchNestEIP + + SSHCommand: + Description: SSH into the instance + Value: !Sub 'ssh -i ~/.ssh/kiro_ide_key ubuntu@${ArchNestEIP}' + + InstanceId: + Description: EC2 Instance ID + Value: !Ref ArchNestInstance + + EstimatedMonthlyCost: + Description: Estimated monthly cost + Value: '~$15/month (t4g.small + 30GB gp3 + Elastic IP)' diff --git a/pics/glance-midnightblue-blueprint.png b/pics/glance-midnightblue-blueprint.png new file mode 100644 index 0000000..e7560d8 Binary files /dev/null and b/pics/glance-midnightblue-blueprint.png differ diff --git a/pics/midnight-blue-bg.png b/pics/midnight-blue-bg.png new file mode 100644 index 0000000..ddce2fe Binary files /dev/null and b/pics/midnight-blue-bg.png differ diff --git a/pics/midnight-blue-theme2.png b/pics/midnight-blue-theme2.png new file mode 100644 index 0000000..230e2ec Binary files /dev/null and b/pics/midnight-blue-theme2.png differ diff --git a/pics/setting-theme3-light-example.png b/pics/setting-theme3-light-example.png new file mode 100644 index 0000000..eb31b34 Binary files /dev/null and b/pics/setting-theme3-light-example.png differ diff --git a/pics/settingsbackground-blueprint b/pics/settings-theme2-example.png similarity index 100% rename from pics/settingsbackground-blueprint rename to pics/settings-theme2-example.png diff --git a/pics/settings-theme3-example.png b/pics/settings-theme3-example.png new file mode 100644 index 0000000..dbb0c36 Binary files /dev/null and b/pics/settings-theme3-example.png differ diff --git a/pics/theme2-bg.png b/pics/theme2-bg.png new file mode 100644 index 0000000..6756d7b Binary files /dev/null and b/pics/theme2-bg.png differ diff --git a/pics/theme2-light-bg.png b/pics/theme2-light-bg.png new file mode 100644 index 0000000..943f197 Binary files /dev/null and b/pics/theme2-light-bg.png differ diff --git a/pics/theme3-bg.png b/pics/theme3-bg.png new file mode 100644 index 0000000..6329fe3 Binary files /dev/null and b/pics/theme3-bg.png differ diff --git a/pics/theme3-light-bg.png b/pics/theme3-light-bg.png new file mode 100644 index 0000000..341c1a9 Binary files /dev/null and b/pics/theme3-light-bg.png differ