Move completed implementation plans (2026-04-20), design specs, and audit documents to docs/archive/ for historical reference while keeping the main docs/ directory focused on active documentation. Archived: - 1 implementation plan (superpowers/plans/) - 2 design specs (superpowers/specs/) - 3 design documents (designs/) - 5 audit/proposal documents (root level) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
4.9 KiB
Installer Implementation Plan
Phase 0 Findings Summary
See installer-recon.md for full details.
Key finding: A new POST /api/v1/auth/setup endpoint is required to allow first-admin creation via HTTP when the app runs in Docker. Both installers depend on this.
Dependency Graph
[1] Setup endpoint (server/auth.js)
↓
[2a] CLI installer (install.sh) [2b] Web installer (tools/installer/)
↓ ↓
[3] .dockerignore update + docs
Steps 2a and 2b are independent and can be built in parallel, but both depend on Step 1.
Deliverables
1. Setup Bootstrap Endpoint (blocking — ~1h, complexity: low)
File: server/auth.js — add new route before the auth guard.
POST /api/v1/auth/setup
Behavior:
- Query
SELECT COUNT(*) FROM users— if > 0, return403 { error: "Setup already completed", code: 403 } - Validate input:
username(3-64 chars, alphanumeric +._-),display_name(1-128 chars),password(min 8 chars) - Hash password with bcrypt (cost 12), insert user with
role: 'admin' - Return
201 { user: { id, username, display_name, avatar_color, role } } - Rate-limited (reuse existing
loginLimiteror a custom one) - No session/CSRF required (unauthenticated endpoint)
- Mounted at
/api/v1/auth/setupinserver/index.js(before therequireAuthmiddleware)
Test: Add test:setup script. Verify: creates admin when no users exist, returns 403 when users exist, validates input.
2a. CLI Installer — install.sh (~3h, complexity: medium)
File: install.sh in repository root.
Wizard steps (7 total):
- Prerequisites check: Docker, docker compose, openssl (or /dev/urandom fallback), curl, jq (optional, graceful fallback)
- Basic config: domain/IP (default:
localhost), port (default:3000), timezone - Security secrets: SESSION_SECRET + DB_ENCRYPTION_KEY — each with [G]enerate / [M]anual
- Weather (optional): ask if wanted, prompt for API key
- Calendar (optional): Google OAuth / Apple CalDAV, each skippable
- Review & launch: display masked .env, confirm, write
.env, rundocker compose up -d, poll/healthevery 2s (120s timeout) - Admin creation: prompt username, display_name, password (read -s), POST to
/api/v1/auth/setup
Features:
- Color output (detect tty, ANSI fallback)
--env-file <path>non-interactive mode: skip wizard, use provided .env, run docker + admin creation- Ctrl+C trap for clean exit
- On docker failure: show
docker compose logs --tail 50 - Works on Linux + macOS (bash, no bashisms beyond
read -s)
2b. Web Installer — tools/installer/ (~4h, complexity: high)
Files:
tools/installer/install-server.js— zero-dependency Node.js HTTP servertools/installer/install.html— single-file SPA (inline CSS + JS)tools/installer/README.md
Server endpoints (port 8090):
| Method | Path | Purpose |
|---|---|---|
| GET | / |
Serve install.html |
| GET | /api/defaults |
Env var catalog with classifications |
| POST | /api/generate-secret |
crypto.randomBytes(32).toString('hex') |
| POST | /api/save-env |
Write .env to project root |
| POST | /api/start |
docker compose up -d |
| GET | /api/status |
Container health polling |
| POST | /api/create-admin |
Proxy to Oikos /api/v1/auth/setup |
Server features:
- Node.js built-ins only (http, fs, child_process, crypto, path)
- Binds to
127.0.0.1:8090 - Auto-terminates after successful admin creation (or 30min idle)
- CORS not needed (same origin)
UI design direction: Clean, calm, trustworthy. Dark-mode-aware. Progress bar. Subtle step transitions. Google Fonts (loaded at runtime for installer only — installer is temporary, not part of the Docker image).
Steps mirror CLI: config → secrets → integrations → review → docker start → admin creation → success.
3. Documentation & Housekeeping (~30min, complexity: low)
- Update
docs/installation.mdto reference both installer paths - Add
tools/to.dockerignore - Add
install.shto.dockerignore
Commit Sequence
feat(api): add first-run setup endpoint for admin bootstrapserver/auth.js: new/setuprouteserver/index.js: mount before auth guardtest-setup.js+package.jsontest script
feat(installer): add CLI install scriptinstall.sh
feat(installer): add web-based installer server and UItools/installer/install-server.jstools/installer/install.htmltools/installer/README.md
chore: add installer files to .dockerignore and update docs.dockerignoreadditionsdocs/installation.mdupdates
Decisions (confirmed)
- Fonts: System font stack in web installer. No Google Fonts, no external dependencies.
- No Docker-exec fallback: Installer targets current version with setup endpoint only.
- TRUST_PROXY: Only via
.env. Don't modifydocker-compose.yml.