From 04c0d890572da6eec64414bf8738a1fe0cba7f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 31 Jul 2026 16:11:29 +0000 Subject: [PATCH] docs: bring the live docs back in line with the code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First pass of the documentation audit. Every doc was read against what the code actually does now; this commit fixes the ones worth keeping and deletes the ones that were only describing a past. Corrected: - CLAUDE.md — said seven WebSocket providers (there are eight, and terminal/vault are byte relays now, not translating bridges), listed channels/ as "Telegram / WhatsApp / Discord bridges" (they are gone; what remains is how /chat drives an agent turn), missed officer-wallet in the PM2 list and notify/ in the layout, and described the per-account email SQLite stores without saying they are the sidecar's and that nothing in the platform opens them. Further Reading pointed at four files that no longer exist and missed the four newest. - docs/working-on-officer.md — PM2 list was four sidecars short, and it still explained the officer-claude rename as news. Replaced with the thing a reader actually needs: which process to restart for which change, and why restarting officer no longer costs you a terminal or an agent session. - TODO.md — the "dead username plumbing" item was mostly resolved by deleting the channels, and two email items pointed at api/email/email-db.ts, which is sidecar/email/store.ts now. - AGENTS.md — trailing paragraph listed the design notes being deleted here. - MUSIC_API.md — playlists were entirely undocumented: seven endpoints the phone app has no reference for. Added from the sidecar's own contract. - docs/jobs-unification.md — phases 1-3 shipped, so it now says so at the top. Phase 4 (push notifications) is the only reason the file still exists, and email sync is explicitly no longer part of it. Deleted, all superseded rather than merely old: - PHONE_APP.md — a February plan for apps that now exist, with their own repo and README. - MARKETING_WEBSITE.md — a plan for a site this repo does not contain. - SECURITY_AUDIT.md + SECURITY_FIXES.md — a February audit of a codebase since restructured; it still cites queue/handlers, which is now empty. - docs/DOCKERIZATION_PLAN.md — cites pty-sidecar, whatsapp and projects, all deleted. - SETUP_GUIDE.md — documents systemd units and setup scripts replaced by PM2 and `bun setup`. Not harmless: /etc/systemd/system/officer-pty-sidecar.service is still enabled on this host, pointing at a `monorepo/` directory that no longer exists, and has been failing to start ever since. That guide is how it got there. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 4 +- CLAUDE.md | 26 +- MARKETING_WEBSITE.md | 716 --------------------- MUSIC_API.md | 18 + PHONE_APP.md | 1208 ------------------------------------ SECURITY_AUDIT.md | 593 ------------------ SECURITY_FIXES.md | 81 --- SETUP_GUIDE.md | 286 --------- TODO.md | 17 +- docs/DOCKERIZATION_PLAN.md | 404 ------------ docs/jobs-unification.md | 5 + docs/working-on-officer.md | 13 +- 12 files changed, 56 insertions(+), 3315 deletions(-) delete mode 100644 MARKETING_WEBSITE.md delete mode 100644 PHONE_APP.md delete mode 100644 SECURITY_AUDIT.md delete mode 100644 SECURITY_FIXES.md delete mode 100644 SETUP_GUIDE.md delete mode 100644 docs/DOCKERIZATION_PLAN.md diff --git a/AGENTS.md b/AGENTS.md index 342f34f1..d289c0ce 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,6 +27,4 @@ and no restart. - `CONVENTIONS.md` — component organisation and React patterns, with rationale - `TODO.md` — current direction; takes precedence where it disagrees with anything else -The other Markdown files in this repo root (`OFFICERDEV_*.md`, `MARKETING_WEBSITE.md`, -`PHONE_APP.md`, `SECURITY_AUDIT.md`, `SETUP_*.md`, …) are older design notes and have not been kept -current. Treat the code as the source of truth. +Treat the code as the source of truth where anything disagrees with it. diff --git a/CLAUDE.md b/CLAUDE.md index 6e5f5315..c68c8b9b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,7 +3,7 @@ ## Project Overview Officer is a self-hosted personal platform for one person: the server owner. It bundles an AI agent, -a terminal, a file browser, a code editor, email, chat channels, a remote desktop and customisable +a terminal, a file browser, a code editor, email, a bitcoin wallet, a remote desktop and customisable dashboards behind a single web app. **Single-user is a hard invariant, not a stage.** There is exactly one account, created once by @@ -17,15 +17,16 @@ One Bun process (`src/server.tsx`) serves everything: - the React SPA, via Bun's HTML import of `src/apps/officer-web/index.html` (HMR in dev) - the REST API, a Hono app mounted at `/api` (`src/servers/hono.ts`) -- seven WebSocket providers — terminal, chat, task-runner, pipeline, cliamp, cliamp-audio, - desktop — plus the vault notifications hub and a sidecar registration socket +- eight WebSocket providers — terminal, chat, task-runner, pipeline, cliamp, cliamp-audio, desktop, + vault — plus a sidecar registration socket. `terminal` is a byte relay onto the pty sidecar's own + listener, not a translating bridge; `vault` is the same shape onto Vaultwarden's notifications hub. - a browser relay on its own port (`BROWSER_RELAY_PORT`, default 18792) Long-running and privileged work lives in **sidecars**: separate processes that dial back in over `/api/sidecar/register` and are tracked in `src/servers/sidecar-registry.ts`. PM2 runs them (`ecosystem.config.cjs`): `officer` (the server), `officer-anthropic-proxy`, `officer-agent`, `officer-opencode`, `officer-email`, `officer-pty`, `officer-vnc`, `officer-music`, `officer-vault`, -`officer-slskd`, `officer-headscale`, `officer-transmission`, `officer-invoiceshelf`. +`officer-slskd`, `officer-headscale`, `officer-transmission`, `officer-invoiceshelf`, `officer-wallet`. **`officer-anthropic-proxy` and `officer-agent` are not the same thing.** The proxy holds the Anthropic credential and forwards API traffic; the agent is the process that spawns `claude`. They were one entry @@ -48,7 +49,8 @@ src/ │ ├── hono.ts # router composition; everything under /api │ ├── _middlewares/ # auth, body parsing, origin validation, rate limiting │ ├── api// # one folder per feature, each exporting a router -│ ├── channels/ # Telegram / WhatsApp / Discord bridges +│ ├── channels/ # send-claude-code / send-opencode — how /chat drives an agent turn +│ ├── notify/ # outbound notifications (Discord webhook, env-configured) │ ├── queue/ # background job engine │ └── sidecar/ # sidecar implementations + the wire protocol ├── databases/officer_db/ # the only database (Postgres + Drizzle) @@ -83,8 +85,9 @@ email accounts, queue and pipeline jobs. Schema in `src/schema/`, hand-written q **The filesystem** holds everything the agent authors. `OFFICER_ITEMS_DIR` contains one directory per item under `skills/`, `tools/`, `tasks/`, `processes/`, `extensions/` — no database rows, no -scope tiers. `DATA_PATH//` holds the managed home, attachments and per-account email SQLite -stores. Path helpers live in `src/servers/data-path.ts`; note `getHomeDir` (the managed home under +scope tiers. `DATA_PATH//` holds the managed home, attachments and the per-account email SQLite +stores — those are the **email sidecar's**, and nothing in the platform opens them. Path helpers live in +`src/servers/data-path.ts`; note `getHomeDir` (the managed home under `DATA_PATH`) versus `getOwnerHomeDir` (the owner's real login home when `HOME_DIR` is set, which is where terminals, chats and task runs actually execute). @@ -245,12 +248,15 @@ link-focusable). Half the app still does this; none of the new code should. ## Further Reading -- `CONVENTIONS.md` — component organisation, state management, React patterns, with rationale - `docs/navigation-audit.md` — **authoritative** on routing/navigation: the opaque-click anti-pattern, a severity-ranked findings table, the channel-selection map and the four-phase plan +- `docs/sidecar-topology.md` — where the sidecar architecture is going, and what was considered and dropped +- `docs/working-on-officer.md` — how to run, restart and check your work on this machine +- `docs/wallet-key-custody.md` — what the platform can and cannot see of the wallet - `TODO.md` — current direction and deferred work; **takes precedence over this file where they disagree** - `src/apps/CLAUDE.md` — shared frontend patterns - `src/databases/CLAUDE.md` — database patterns +- `CONVENTIONS.md` — component organisation, state management and React patterns, with rationale; + `src/workspaces/officerdev/APP_CONVENTIONS.md` and `HOOK_CONVENTIONS.md` for panel apps and hooks -The other markdown files in the repo root (`OFFICERDEV_*.md`, `MARKETING_WEBSITE.md`, `PHONE_APP.md`, -`SECURITY_AUDIT.md`, `SETUP_*.md`, …) are older design notes. Treat the code as the source of truth. +Treat the code as the source of truth where anything here disagrees with it. diff --git a/MARKETING_WEBSITE.md b/MARKETING_WEBSITE.md deleted file mode 100644 index 2b4cb12a..00000000 --- a/MARKETING_WEBSITE.md +++ /dev/null @@ -1,716 +0,0 @@ -# Officer.dev Marketing Website Plan - -> Written by Claude for Claude. This document covers the full marketing website — structure, copy, visuals, and demo video plans. When resuming, read this first and walk the user through the strategy before building. - ---- - -## Table of Contents - -1. [Positioning & Messaging Strategy](#1-positioning--messaging-strategy) -2. [Site Map](#2-site-map) -3. [Page-by-Page Breakdown](#3-page-by-page-breakdown) -4. [Copy Bank](#4-copy-bank) -5. [Visual Identity for Marketing](#5-visual-identity-for-marketing) -6. [Demo Videos Plan](#6-demo-videos-plan) -7. [Technical Implementation](#7-technical-implementation) -8. [Launch Considerations](#8-launch-considerations) - ---- - -## 1. Positioning & Messaging Strategy - -### The Core Idea - -Officer is not a developer tool. It's not an AI chatbot wrapper. It's an **operating system** — a central place where AI does your repetitive work so you can do what matters. - -### Positioning Triangle - -``` - OFFICER - / \ - Easier More Powerful - than than - | | - OpenClaw Claude Work - (open source (polished but - but complex) locked down) -``` - -**vs. OpenClaw/Open Source AI tools**: "You shouldn't need a CS degree to use AI. Officer gives you the same power — with a UI your team actually wants to use." - -**vs. Claude Work/Enterprise AI**: "Enterprise AI is a walled garden. Officer is open source, self-hosted, and yours. No data leaves your servers unless you say so." - -**vs. Building it yourself**: "You could stitch together 15 tools and spend months on glue code. Or you could install Officer in five minutes." - -### Messaging Pillars - -| Pillar | For Individuals | For Companies | -|--------|----------------|---------------| -| **Automation** | "Automate your life. Have more time to live it." | "Every minute your team spends on repetitive work is a minute wasted." | -| **AI-Native** | "An AI that doesn't just chat — it acts." | "Give every employee an AI-powered workspace." | -| **Self-Hosted** | "Your data, your server, your rules." | "Enterprise-grade AI without enterprise-grade surveillance." | -| **Open Source** | "Built in the open. Extend it however you want." | "No vendor lock-in. No surprise pricing changes." | - -### Tagline Options - -**Primary (hero):** -> **Your AI-powered operating system — everywhere.** - -**Alternatives to test:** -> **Stop managing. Start living.** -> -> **The last tool you'll need.** -> -> **One platform. Everything automated.** - -**For the business/enterprise angle:** -> **What if your entire company ran itself?** -> -> **The company intranet that actually works.** -> -> **Fortunes are lost to repetitive work every day. Not anymore.** - -### Tone of Voice - -- **Confident but not arrogant** — we know what we are, we don't trash competitors -- **Clear and direct** — no jargon, no buzzword soup -- **Warm** — the duck mascot sets the tone. Serious product, friendly personality -- **Action-oriented** — every section should make you want to try it - ---- - -## 2. Site Map - -``` -officer.dev/ -├── / (Landing / Home) -├── /features -│ ├── /features/ai-assistant -│ ├── /features/file-management -│ ├── /features/automation -│ └── /features/workspaces -├── /pricing -├── /docs (external link to docs site) -├── /marketplace (coming soon / waitlist) -├── /enterprise -├── /open-source -├── /blog (future) -└── /about -``` - ---- - -## 3. Page-by-Page Breakdown - -### 3.1 Landing Page (Home) - -The landing page is the entire pitch in one scroll. It must convert three different audiences: individual users, small teams, and enterprises. - -#### Section 1: Hero - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ [Nav: Logo | Features | Pricing | Docs | GitHub]│ -│ [ Star on GitHub | Login]│ -│ │ -│ Your AI-powered operating │ -│ system — everywhere. │ -│ │ -│ Open source. Self-hosted. Free forever. │ -│ │ -│ [ Get Started — Free ] [ Watch Demo ▶ ] │ -│ │ -│ 🦆 (animated duck walks across) │ -│ │ -│ ┌──────────────────────────────────────────┐ │ -│ │ │ │ -│ │ (Hero product screenshot/video) │ │ -│ │ Dashboard with widgets + chat open │ │ -│ │ │ │ -│ └──────────────────────────────────────────┘ │ -│ │ -│ Trusted by developers at [logos if available] │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -**Copy:** -- Headline: "Your AI-powered operating system — everywhere." -- Subheadline: "Open source. Self-hosted. Free forever." -- CTA Primary: "Get Started — Free" -- CTA Secondary: "Watch Demo" -- Background: landscape1.png with gradient overlay - -**Behavior:** -- Duck walks across the hero from right to left (CSS/JS animation, lightweight — not the 3D model) -- Product screenshot below the fold, slightly overlapping -- Subtle parallax on scroll -- GitHub stars badge updates live - -#### Section 2: The Problem - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ Every day, you... │ -│ │ -│ ┌────────┐ ┌────────┐ ┌────────┐ │ -│ │ Rename │ │ Organize│ │ Copy │ │ -│ │ 47 │ │ files │ │ data │ │ -│ │ files │ │ into │ │ between│ │ -│ │ │ │ folders │ │ apps │ │ -│ └────────┘ └────────┘ └────────┘ │ -│ │ -│ ┌────────┐ ┌────────┐ ┌────────┐ │ -│ │ Format │ │ Convert │ │ Search │ │ -│ │ reports│ │ formats │ │ through│ │ -│ │ │ │ │ │ docs │ │ -│ └────────┘ └────────┘ └────────┘ │ -│ │ -│ This isn't work. It's busywork. │ -│ And it costs more than you think. │ -│ │ -│ [$X,XXX per employee per year wasted] │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -**Copy:** -- "Every day, you rename files. Organize folders. Copy data between apps. Format reports. Convert formats. Search through documents." -- "This isn't work. It's busywork." -- "And it's costing you more than you think." -- Animated counter or stat: estimated cost of repetitive work per employee/year - -#### Section 3: The Solution (Feature Overview) - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ Meet Officer. │ -│ │ -│ The platform that combines AI, file management, │ -│ automation, and workspaces into one self-hosted │ -│ operating system. │ -│ │ -│ ┌─────────────────────────────────────────┐ │ -│ │ │ │ -│ │ (Animated product showcase) │ │ -│ │ Cycling through: Chat → Files → │ │ -│ │ Automation → Dashboard │ │ -│ │ │ │ -│ └─────────────────────────────────────────┘ │ -│ │ -│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ -│ │ 🤖 │ │ 📁 │ │ ⚡ │ │ 🏠 │ │ -│ │ AI │ │Files │ │Auto- │ │Work- │ │ -│ │Assist│ │ │ │mate │ │space │ │ -│ └──────┘ └──────┘ └──────┘ └──────┘ │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -**Four feature cards:** - -1. **AI Assistant** — "Not just chat. An AI that reads your files, runs your tasks, and gets things done." -2. **File Management** — "Your entire digital life in one place. Browse, preview, edit, convert, transcribe." -3. **Automation** — "Build workflows that run themselves. Tasks, cron jobs, pipelines — without writing code." -4. **Workspaces** — "Your desk, digitized. Combine any tool into a custom layout that fits how you work." - -Each card links to its feature detail page. - -#### Section 4: For You / For Your Team (Split Section) - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ ┌─────────────────┐ ┌─────────────────────┐ │ -│ │ │ │ │ │ -│ │ FOR YOU │ │ FOR YOUR COMPANY │ │ -│ │ │ │ │ │ -│ │ "Automate your │ │ "What if your │ │ -│ │ life. Have more │ │ entire team had an │ │ -│ │ time to live │ │ AI-powered intranet │ │ -│ │ it." │ │ that actually │ │ -│ │ │ │ worked?" │ │ -│ │ • Personal AI │ │ │ │ -│ │ assistant │ │ • Role-based access │ │ -│ │ • File organiz- │ │ • Shared workspaces │ │ -│ │ ation on │ │ • Company-wide │ │ -│ │ autopilot │ │ automation │ │ -│ │ • Smart dash- │ │ • Self-hosted: │ │ -│ │ board with │ │ your data stays │ │ -│ │ your goals │ │ on your servers │ │ -│ │ • Voice notes, │ │ • Plugin ecosystem │ │ -│ │ OCR, TTS │ │ for custom needs │ │ -│ │ │ │ │ │ -│ │ [Try Free →] │ │ [Enterprise →] │ │ -│ │ │ │ │ │ -│ └─────────────────┘ └─────────────────────┘ │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -#### Section 5: How It Works - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ Up and running in 5 minutes. │ -│ │ -│ 1. Install │ -│ ┌──────────────────────────────────┐ │ -│ │ $ curl -fsSL install.officer.dev │ │ -│ │ | sh │ │ -│ └──────────────────────────────────┘ │ -│ One command. That's it. │ -│ │ -│ 2. Open your browser │ -│ Navigate to localhost:5000. │ -│ Create your admin account. │ -│ │ -│ 3. Start automating │ -│ Your AI assistant is ready. │ -│ Your files are connected. │ -│ Your first automation is one click away. │ -│ │ -│ [Get Started — Free] │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -#### Section 6: Open Source & Community - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ Built in the open. Extended by everyone. │ -│ │ -│ Officer is open source under [LICENSE]. │ -│ Read every line. Modify anything. │ -│ Self-host for free, forever. │ -│ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ ⭐ │ │ 🔌 │ │ 🎨 │ │ -│ │ [count] │ │ Plugins │ │ Themes │ │ -│ │ GitHub │ │ Build & │ │ Make it │ │ -│ │ Stars │ │ share │ │ yours │ │ -│ └──────────┘ └──────────┘ └──────────┘ │ -│ │ -│ Marketplace coming soon. │ -│ Build plugins. Sell themes. Earn money. │ -│ │ -│ [Star on GitHub ⭐] [Join the community] │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -#### Section 7: Pricing Preview - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ Simple pricing. No surprises. │ -│ │ -│ ┌──────────┐ ┌───────────┐ ┌──────────┐ │ -│ │ Self- │ │ Cloud │ │ Enter- │ │ -│ │ Hosted │ │ │ │ prise │ │ -│ │ │ │ │ │ │ │ -│ │ FREE │ │ $XX/mo │ │ Custom │ │ -│ │ forever │ │ per user │ │ │ │ -│ │ │ │ │ │ │ │ -│ │ Full │ │ Everything│ │ SLA, │ │ -│ │ features │ │ hosted & │ │ support, │ │ -│ │ Your │ │ managed │ │ custom │ │ -│ │ servers │ │ for you │ │ features │ │ -│ │ │ │ │ │ │ │ -│ │ [Install]│ │ [Start] │ │ [Talk] │ │ -│ └──────────┘ └───────────┘ └──────────┘ │ -│ │ -│ All plans include all features. │ -│ The only difference is who runs the server. │ -│ │ -└──────────────────────────────────────────────────┘ -``` - -**Key messaging**: "All plans include all features. The only difference is who runs the server." This is a powerful differentiator. No feature gating. - -#### Section 8: CTA / Footer - -``` -┌──────────────────────────────────────────────────┐ -│ │ -│ Ready to stop wasting time? │ -│ │ -│ [Get Started — Free] [Book a Demo] │ -│ │ -│ ───────────────────────────────────────────── │ -│ │ -│ officer.dev │ -│ Product: Features | Pricing | Docs │ -│ Community: GitHub | Discord | Blog │ -│ Company: About | Enterprise | Contact │ -│ │ -│ © 2026 Officer.dev │ -│ │ -└──────────────────────────────────────────────────┘ -``` - ---- - -### 3.2 Features Page (`/features`) - -Overview page with anchor-linked sections for each feature area. Each section has: -- Feature title & one-line pitch -- 3-4 bullet capabilities -- Embedded demo video or animated screenshot -- CTA to try it - -**Feature areas:** - -#### AI Assistant (`/features/ai-assistant`) -- Multi-provider (Claude, OpenCode, Pi-Mono) -- File-aware — reads, edits, and creates files -- Task-aware — runs automation on your behalf -- Voice input, image analysis, code understanding -- Session persistence across devices - -**Demo video**: Show a conversation where the user asks "organize my downloads folder by file type" and the AI does it, showing the file browser updating in real-time. - -#### File Management (`/features/file-management`) -- Browse, upload, download, search -- Built-in viewers: text, images, PDFs, audio, video -- AI-powered: OCR, text-to-speech, transcription, audio extraction -- Video transcoding for any format -- Archive extraction (zip, tar, 7z, rar) -- Git clone, yt-dlp download integration - -**Demo video**: Upload a photo of a receipt → OCR extracts the text → AI categorizes the expense. All in Officer. - -#### Automation (`/features/automation`) -- Tasks triggered by file type, schedule, or manually -- Workflows chaining multiple steps -- Cron jobs for recurring work -- Background processes -- Skills system — teach AI new capabilities - -**Demo video**: Show setting up a task that compresses images when they're uploaded to a specific folder. - -#### Workspaces (`/features/workspaces`) -- Multi-panel layouts -- Combine chat + files + any tool -- Save and switch between workspace configurations -- Create workspace templates for team - -**Demo video**: Building a "Content Creation" workspace with file browser on the left, AI chat in the middle, and preview on the right. - ---- - -### 3.3 Pricing Page (`/pricing`) - -Three tiers, feature-complete across all. The difference is hosting and support. - -**Self-Hosted (Free)** -- All features, unlimited users -- You host, you manage -- Community support (GitHub, Discord) -- "Perfect for developers, homelab enthusiasts, and teams who want full control." - -**Cloud (Subscription — $XX/user/month)** -- All features, unlimited -- We host and manage everything -- Automatic updates, backups, SSL -- Email support -- "For teams who want Officer without the DevOps." - -**Enterprise (Custom)** -- Everything in Cloud -- SLA with guaranteed uptime -- Priority support with dedicated account manager -- Custom feature development -- SSO/SAML integration -- Audit logging -- On-premises deployment assistance -- "For organizations that need enterprise-grade guarantees." - -**Below the pricing cards:** -- FAQ section (Is it really free? Can I migrate between plans? What about data portability?) -- "Need something custom?" → Contact form -- "Building plugins?" → Marketplace waitlist signup - ---- - -### 3.4 Enterprise Page (`/enterprise`) - -**Audience**: IT decision-makers, CTOs, operations managers. - -**Tone**: Professional, emphasizing reliability, security, and ROI. - -**Sections:** - -1. **Hero**: "The company intranet that works for you — literally." -2. **Problem**: "Your team uses 12 different tools. None of them talk to each other. Officer replaces the glue." -3. **Security**: "Self-hosted means your data never leaves your servers. Full audit logging. Role-based access. SOC 2 compliance roadmap." -4. **ROI Calculator**: Interactive widget — input team size, estimated hours on repetitive tasks → shows annual savings -5. **Consultancy**: "Our team builds custom integrations, plugins, and workflows tailored to your operations." -6. **Case studies**: (placeholder for future customer stories) -7. **CTA**: "Book a Demo" → Calendly or contact form - ---- - -### 3.5 Open Source Page (`/open-source`) - -**Audience**: Developers, contributors, plugin builders. - -**Sections:** - -1. **Hero**: "Built in the open. Extended by everyone." -2. **Why Open Source**: Philosophy statement — transparency, community ownership, no vendor lock-in -3. **Contributing**: Quick guide to getting started, link to CONTRIBUTING.md -4. **Plugin Development**: Overview of the plugin system, link to docs -5. **Marketplace Preview**: "Coming soon — build and sell plugins, themes, and automations. Earn money from your work." -6. **GitHub Stats**: Stars, forks, contributors, recent commits -7. **CTA**: "Star on GitHub" / "Join Discord" - ---- - -## 4. Copy Bank - -### Headlines (A/B test candidates) - -**Automation-focused:** -- "Your AI-powered operating system — everywhere." -- "Stop doing. Start automating." -- "The work that works itself." -- "Automate everything. Miss nothing." - -**For individuals:** -- "Your second brain. But it actually does things." -- "AI that doesn't just answer — it acts." -- "Automate your life. Have more time to live it." - -**For companies:** -- "What if your team's busywork just... disappeared?" -- "The company intranet that works for you — literally." -- "Fortunes are lost to repetitive work every day. Meet the fix." -- "Every employee deserves an AI assistant. Now they can have one." - -**Open source angle:** -- "Open source. Self-hosted. No strings attached." -- "Your data. Your server. Your AI." -- "The power of enterprise AI. The freedom of open source." - -### Social Proof (to collect/create) - -- GitHub stars count -- "Used by X developers/companies" -- Testimonials (collect after launch) -- "Featured in [publications]" (aim for Hacker News, ProductHunt, etc.) - -### Microcopy - -- Install CTA: "Get Started — Free" -- Cloud CTA: "Start your trial" -- Enterprise CTA: "Book a demo" -- GitHub CTA: "Star on GitHub" -- Newsletter CTA: "Get updates" -- Marketplace waitlist: "Join the waitlist" - ---- - -## 5. Visual Identity for Marketing - -### Design System Adaptation - -The product uses a duck-themed design (teal, yellow, forest green, glass-morphism with pixel grid). The marketing site should feel like the same brand but optimized for conversion: - -**Colors:** -- Primary: `#F4C430` (Duck Yellow) — CTAs, highlights -- Secondary: `#0891B2` (Duck Teal) — links, accents -- Dark: `#14532D` (Duck Dark) — text, headings -- Background: Soft cream/beige (`#F5F0E8`) or white with subtle grid texture -- Dark mode: Support it, matching the product's dark theme - -**Typography:** -- Headings: Bold, system-ui stack with the same skewed/3D shadow effect as the logo (but subtler for readability) -- Body: Clean sans-serif (Inter or system-ui), 18px base -- Code: Monospace for install commands and API examples - -**The Duck:** -- Hero: Subtle walking animation (lightweight 2D sprite or CSS, not the 3D model — save loading time) -- Scroll companion: Small duck that appears in corners, reacts to scroll -- 404 page: Lost duck illustration -- Loading states: Duck waddle animation - -**Photography/Visuals:** -- Product screenshots with the landscape backgrounds -- Minimal mockups (no fake Chrome windows — just clean screenshots with rounded corners and shadow) -- Feature diagrams: Simple, geometric, using brand colors - -**Grid Pattern:** -- Carry the pixel grid texture from the product into section backgrounds -- Use it subtly — don't overwhelm the content - -### Section Visual Hierarchy - -| Section | Background | Text Color | -|---------|-----------|------------| -| Hero | landscape1.png with dark overlay | White | -| Problem | White/cream | Dark green | -| Solution | Subtle grid pattern | Dark green | -| For You/Company | Split — light teal / light yellow | Dark | -| How It Works | White | Dark | -| Open Source | Dark (forest green) | Yellow/white | -| Pricing | White/cream | Dark | -| CTA | Teal gradient | White/yellow | - ---- - -## 6. Demo Videos Plan - -### Product Demo Reel (60s — for hero) - -A fast-paced showcase that cycles through the major features: - -| Time | Scene | Description | -|------|-------|-------------| -| 0-5s | Cold open | Tagline appears over landscape. Duck walks in. | -| 5-12s | Chat | User asks AI to "summarize all PDFs in my project folder." AI responds with tool use, result appears. | -| 12-20s | Files | File browser opens. User uploads files, previews images, plays audio. Quick montage. | -| 20-30s | Automation | User creates a task. It runs automatically. Toast notification: "Task complete." | -| 30-40s | Workspace | Multi-panel workspace assembles itself — chat + files + viewer. User drags to resize. | -| 40-48s | Dashboard | Widgets dashboard: clock, weather, goals getting checked off, pomodoro timer running. | -| 48-55s | Scale | "For you. For your team. For your company." — zoom out to show multiple users. | -| 55-60s | CTA | Logo + "Open source. Self-hosted. Free forever." + URL | - -### Feature-Specific Demos (30s each) - -**AI Assistant Demo:** -- Show real conversation with tool use -- AI reads a file, suggests changes, user approves -- Emphasis on the AI *doing things*, not just chatting - -**File Management Demo:** -- Upload → organize → preview → AI actions (OCR, transcribe) -- Show the breadth of file types supported -- yt-dlp download as a wow moment - -**Automation Demo:** -- Create a task that processes files automatically -- Show it triggering on file upload -- End with "Set it up once. It runs forever." - -**Workspaces Demo:** -- Start with empty screen -- Build a workspace: add chat, files, viewer -- Split panels, resize -- "Your desk. Your way." - -### Recording Guidelines - -- **Resolution**: 1920x1080 for landscape, 1080x1920 for portrait (social) -- **Browser**: Clean browser, no bookmarks bar, no extensions visible -- **Data**: Use realistic-looking sample data (not lorem ipsum) -- **Cursor**: Smooth, deliberate movements. No jitter. -- **Speed**: 1.5x natural speed for repetitive parts, real-time for "wow" moments -- **Music**: Upbeat instrumental for playful, ambient electronic for professional - ---- - -## 7. Technical Implementation - -### Stack Recommendation - -The marketing site should be **separate from the main monorepo** — it's a public website with different deployment, SEO, and performance requirements. - -**Recommended stack:** -- **Framework**: Astro (static-first, great SEO, supports React islands for interactive parts) -- **Styling**: Tailwind CSS (matches the product's design system) -- **Animations**: Framer Motion (for scroll-triggered animations) -- **Hosting**: Vercel or Cloudflare Pages (fast global CDN) -- **CMS**: Markdown files for blog posts (future) -- **Analytics**: Plausible or PostHog (privacy-friendly) - -**Alternative**: If the team prefers to keep everything in the monorepo's React ecosystem, a Next.js or Vite app could work. But Astro's static output and built-in SEO features make it better for a marketing site. - -### Project Location - -Create at `/home/pastilhas/projects/officer.dev/website/` — separate from the monorepo but within the project directory. - -### SEO Strategy - -**Target keywords:** -- "self-hosted AI platform" -- "open source AI assistant" -- "AI-powered intranet" -- "personal AI operating system" -- "self-hosted automation" -- "open source alternative to [Claude Work/Notion AI/etc.]" -- "AI file management" - -**Technical SEO:** -- Static HTML pages (Astro) -- Proper meta tags, OpenGraph images per page -- JSON-LD structured data -- Sitemap.xml -- Fast Core Web Vitals (landscape images need lazy loading + WebP conversion) - -### Performance Considerations - -- landscape1.png is 16MB — must be converted to WebP/AVIF and served responsive -- The 3D duck model (40MB total) should NOT be on the marketing site — use a lightweight 2D animation instead -- Use the rubber-duck.png (1.6MB) at reduced size for the duck character -- Lazy load everything below the fold - ---- - -## 8. Launch Considerations - -### Pre-Launch Checklist - -- [ ] Marketing site live with all sections -- [ ] Product demo video recorded and embedded -- [ ] GitHub repo public with README, CONTRIBUTING.md, LICENSE -- [ ] Installation script (`install.officer.dev`) working -- [ ] Documentation site (even minimal) live -- [ ] Discord/community channel created -- [ ] Social accounts created (Twitter/X, LinkedIn) -- [ ] ProductHunt launch page drafted -- [ ] Hacker News "Show HN" post drafted -- [ ] Email waitlist for cloud/marketplace - -### Launch Channels - -| Channel | Content | Timing | -|---------|---------|--------| -| Hacker News | "Show HN: Officer — open-source, AI-powered OS for automating your life" | Day 1 | -| ProductHunt | Full launch with screenshots, video, maker story | Day 1 | -| Reddit | r/selfhosted, r/homelab, r/opensource, r/artificial | Day 1 | -| Twitter/X | Thread: "I built an OS that automates my life. It's open source." | Day 1 | -| LinkedIn | Professional angle: "Every company wastes $X on repetitive work" | Day 2 | -| Dev.to / Hashnode | Technical deep-dive blog post | Week 1 | -| YouTube | Full demo video (5min) | Week 1 | - -### Post-Launch - -- Monitor GitHub issues and community channels -- Publish weekly blog posts (features, tutorials, philosophy) -- Start marketplace waitlist campaign -- Collect testimonials from early adopters -- Begin enterprise outreach - ---- - -## Appendix: Competitor Landscape - -| Product | What it is | Officer's advantage | -|---------|-----------|-------------------| -| **Notion** | Wiki + project management | Officer has AI that acts, not just organizes. Self-hosted. | -| **Obsidian** | Markdown knowledge base | Officer is broader — files, AI, automation, not just notes. | -| **Nextcloud** | Self-hosted file sync | Officer has native AI, automation, and workspaces. | -| **n8n** | Workflow automation | Officer combines automation with AI + file management + UI. | -| **Claude Work** | Enterprise AI chat | Officer is open source, self-hosted, and more extensible. | -| **OpenClaw** | Open source AI tools | Officer is friendlier, more polished, broader scope. | -| **Home Assistant** | Home automation | Different domain, but similar self-hosted philosophy. Potential integration. | - -Officer's unique position: **No one else combines AI + files + automation + workspaces in a single self-hosted platform.** That's the moat. diff --git a/MUSIC_API.md b/MUSIC_API.md index eb941bd1..d6431fd6 100644 --- a/MUSIC_API.md +++ b/MUSIC_API.md @@ -293,6 +293,24 @@ launch to offer "resume". --- +### Playlists + +Server-side playlists, scoped to the calling user. Items are track **keys** — the same +`/` strings favorites uses — so a playlist survives a reindex as long as the file stays +put. `404` throughout means "not yours or not there"; the two are deliberately indistinguishable. + +| method | path | body | returns | +|---|---|---|---| +| `GET` | `/api/music/playlists` | — | `[{ id, name, count, createdAt, updatedAt }]`, most recent first | +| `POST` | `/api/music/playlists` | `{ name }` | `201` with the row; `409` if the name is taken | +| `GET` | `/api/music/playlists/:id` | — | `{ id, name, items: [key], … }` | +| `PATCH` | `/api/music/playlists/:id` | `{ name }` | rename; `409` if taken | +| `DELETE` | `/api/music/playlists/:id` | — | deletes it, items cascade | +| `POST` | `/api/music/playlists/:id/items` | `{ keys: [] }` | append → `{ count }` | +| `PUT` | `/api/music/playlists/:id/items` | `{ keys: [] }` | replace the whole list → `{ count }` | + +`PUT` is how you reorder or remove: send the list you want, in order. There is no per-item delete. + ## Notes - **Covers are server-compressed** (≤600px / q5) — sync them as-is; no client-side resizing needed. diff --git a/PHONE_APP.md b/PHONE_APP.md deleted file mode 100644 index 661406d4..00000000 --- a/PHONE_APP.md +++ /dev/null @@ -1,1208 +0,0 @@ -# Officer Mobile App Plan - -> This document is written by Claude for Claude. It contains the full plan for native mobile apps (Kotlin/Android + Swift/iOS) for the Officer platform, based on a thorough study of the monorepo. When resuming this work, read this document first, then explain the plan to the user before starting implementation. - ---- - -## Table of Contents - -1. [Current Web App Summary](#1-current-web-app-summary) -2. [What to Include vs Exclude](#2-what-to-include-vs-exclude) -3. [Architecture Overview](#3-architecture-overview) -4. [Authentication](#4-authentication) -5. [Site Map](#5-site-map) -6. [Screen-by-Screen Breakdown](#6-screen-by-screen-breakdown) -7. [Tablet Adaptations](#7-tablet-adaptations) -8. [Technical Challenges](#8-technical-challenges) -9. [API Integration Notes](#9-api-integration-notes) -10. [Shared Design Language](#10-shared-design-language) -11. [Implementation Phases](#11-implementation-phases) - ---- - -## 1. Current Web App Summary - -Officer is an AI-assisted personal backend for life management. The web app (`officer-web`) is a React 19 SPA talking to a Hono API server (port 5000). Key features: - -| Feature | Description | -|---------|-------------| -| **Chat** | Multi-provider AI chat (Claude, OpenCode, Pi-Mono) via WebSockets. Sessions persisted as JSON files. Supports images, file attachments, model selection, working directory context. | -| **File Browser** | Full file manager with upload/download, rename, copy/move, search, archive extraction, git clone, yt-dlp download, OCR, TTS, transcription, audio extraction, video transcoding. Multiple "roots" (home, ~, officer.dev). | -| **Workspaces** | Multi-panel layouts combining chat, files, terminal, code editor. Panels can be split horizontally/vertically. State persisted per workspace. | -| **Terminal** | Sandboxed Docker terminals and host terminals (Super Admin). WebSocket-based PTY. | -| **Code Editor** | Text editor with syntax highlighting (PrismJS). | -| **Dashboard** | Widget panel (clock, weather, pomodoro, daily goals, quick notes) + workspace launcher + chat launcher. | -| **Automation** | Builder for workflows, pipelines, processes, services, cron jobs, tasks, skills. | -| **Tasks** | File-based task definitions (TASK.md) that can be triggered on files/directories. Native/global/user scopes. | -| **Skills** | AI skill library (SKILL.md files) injected into chat system prompts. | -| **Settings** | User profile, system settings, server resources, AI harness configuration. | -| **Auth** | Email/password + passkey (WebAuthn). JWT tokens. Role-based access (Member, Admin, Owner, Super Admin). | - -The API is at `/api/*` with JWT auth on all protected routes. WebSockets for chat (`/api/harness/*/ws`) and terminal (`/api/terminal/ws`). - ---- - -## 2. What to Include vs Exclude - -### Include (core mobile experience) - -| Feature | Rationale | -|---------|-----------| -| **Chat** | The #1 use case. Having an AI assistant in your pocket is the killer feature. Voice input makes it even better on mobile. | -| **File Browser** | Essential for viewing/managing files. Mobile adds camera upload, share sheet integration. Simplified but fully functional. | -| **Dashboard / Widgets** | Perfect for mobile - quick glance at clock, weather, goals, notes. Widget-style info is native to mobile platforms. | -| **Notifications** | Mobile-exclusive feature. Push notifications for chat completions, task results, long downloads finishing. | -| **Settings** | Profile, preferences. Subset of web settings. | -| **Session History** | Browse and resume past chat sessions. | -| **Quick Actions** | Share sheet integration (share URL/text/image to Officer for chat or file upload). | - -### Include (reduced scope) - -| Feature | What changes | -|---------|-------------| -| **File Viewer** | View files (text, images, PDFs, audio, video) but no full code editor. Read-only text with syntax highlighting. | -| **Tasks** | View and trigger tasks, see logs. No task creation/editing (too complex for mobile). | -| **Skills** | Browse skill library. No editing. | -| **Workspaces** | View workspace list, open a workspace (but as a single-panel experience, not multi-panel). | - -### Exclude (not suitable for phone) - -| Feature | Rationale | -|---------|-----------| -| **Terminal** | Typing shell commands on a phone keyboard is miserable. The sandboxed Docker terminal is a power-user web feature. | -| **Code Editor (write mode)** | Writing code on a phone is impractical. Read-only viewing with syntax highlighting is fine. | -| **Multi-panel workspaces** | Phone screens can't meaningfully split into panels. Tablet gets a simplified version (see section 7). | -| **Automation Builder** | Complex drag-and-drop/form-heavy workflow builder. Keep this web-only. | -| **Server/Resource Management** | Admin infrastructure management (installing databases, configuring services). Web-only. | -| **System Settings** | Server configuration, AI harness setup, plugin management. Web-only. | - -### Mobile-Exclusive Features (not on web) - -| Feature | Description | -|---------|-------------| -| **Push Notifications** | FCM (Android) / APNs (iOS) for chat completions, task results, downloads. | -| **Voice Input** | Native speech-to-text for chat messages. Much better than web speech API. | -| **Camera Integration** | Take photo and send to chat or upload to file browser directly. | -| **Share Sheet** | Receive shared content (URLs, text, images) from other apps. | -| **Biometric Auth** | Fingerprint/Face ID as alternative to passkey/password. | -| **Home Screen Widgets** | Android widgets / iOS widgets for quick notes, pomodoro, weather. | -| **Offline Queue** | Queue chat messages when offline, send when reconnected. | -| **Background Downloads** | File downloads and yt-dlp downloads continue in background. | - ---- - -## 3. Architecture Overview - -### Platform Strategy - -Two fully native apps sharing no code, but sharing identical: -- API contract (same REST + WebSocket endpoints) -- UX flows and information architecture -- Design language (adapted to each platform's conventions) - -``` -┌──────────────┐ ┌──────────────┐ -│ Android App │ │ iOS App │ -│ (Kotlin) │ │ (Swift) │ -│ │ │ │ -│ Jetpack │ │ SwiftUI │ -│ Compose │ │ │ -│ Material 3 │ │ Native iOS │ -│ │ │ Components │ -└──────┬───────┘ └──────┬───────┘ - │ │ - └────────┬───────────┘ - │ - ┌──────┴──────┐ - │ Officer API │ - │ (Hono) │ - │ port 5000 │ - └─────────────┘ -``` - -### Android Stack - -| Layer | Technology | -|-------|-----------| -| UI | Jetpack Compose + Material 3 | -| Navigation | Compose Navigation | -| Networking | Ktor Client (HTTP + WebSocket) | -| State | ViewModel + StateFlow | -| DI | Hilt | -| Storage | DataStore (preferences), Room (offline cache) | -| Images | Coil | -| Push | Firebase Cloud Messaging | -| Auth | BiometricPrompt API | -| Background | WorkManager | - -### iOS Stack - -| Layer | Technology | -|-------|-----------| -| UI | SwiftUI | -| Navigation | NavigationStack (iOS 16+) | -| Networking | URLSession + native WebSocket (URLSessionWebSocketTask) | -| State | @Observable (iOS 17+) / ObservableObject | -| DI | Swift native (Environment, protocol-based) | -| Storage | UserDefaults, SwiftData (offline cache) | -| Images | AsyncImage + custom cache | -| Push | APNs | -| Auth | LocalAuthentication (Face ID / Touch ID) | -| Background | BGTaskScheduler | - -### Minimum OS Versions - -- **Android**: API 26 (Android 8.0) - covers 95%+ of devices, gives us WorkManager, BiometricPrompt, etc. -- **iOS**: iOS 16 - gives us NavigationStack, modern SwiftUI features. iOS 17 for @Observable if we want it. - ---- - -## 4. Authentication - -### Flow - -``` -App Launch - │ - ├─ Has stored JWT? ──Yes──► Validate token (GET /api/auth/me) - │ │ - │ Valid? ──Yes──► Home Screen - │ │ - │ No ──► Login Screen - │ - └─ No ──► Login Screen - │ - ├─ Email/Password - │ POST /api/auth/signin - │ ► Store JWT securely - │ ► Home Screen - │ - ├─ Passkey (WebAuthn) - │ ► Platform passkey flow - │ ► Store JWT securely - │ - └─ Biometric Unlock (returning user) - ► Decrypt stored JWT - ► Validate & proceed -``` - -### Token Storage - -- **Android**: EncryptedSharedPreferences (AndroidX Security) -- **iOS**: Keychain Services - -### Biometric Integration - -On first successful login, offer to enable biometric unlock: -1. User logs in with email/password or passkey -2. App prompts: "Enable Face ID / Fingerprint for quick access?" -3. If yes: encrypt JWT with biometric-bound key, store in Keychain/Keystore -4. On next launch: biometric prompt → decrypt JWT → validate → proceed - -### Server URL Configuration - -The mobile app needs to know where the Officer API lives. First-launch flow: - -1. "Enter your Officer server URL" input -2. Validate by hitting `GET /api/server-settings/plugins` (public endpoint) -3. Store URL in app preferences -4. Proceed to login - -This is important because Officer is self-hosted - there's no central server. - ---- - -## 5. Site Map - -``` -App -├── Login -│ ├── Server URL Setup (first launch) -│ ├── Email/Password -│ ├── Passkey -│ └── Biometric Unlock -│ -├── Home (Tab 1) -│ ├── Widget Dashboard -│ │ ├── Clock -│ │ ├── Weather -│ │ ├── Pomodoro Timer -│ │ ├── Daily Goals -│ │ └── Quick Notes -│ └── Workspace Quick Access -│ -├── Chat (Tab 2) -│ ├── Session List -│ │ ├── Active Sessions -│ │ └── Archived Sessions -│ ├── New Chat -│ └── Chat Session -│ ├── Message Thread -│ ├── Model Selector -│ ├── Image Attachment -│ ├── Voice Input -│ └── Tool Use Display -│ -├── Files (Tab 3) -│ ├── Directory Browser -│ │ ├── Grid/List View -│ │ ├── Search -│ │ ├── Sort/Filter -│ │ └── Context Actions -│ │ ├── Open/Preview -│ │ ├── Share -│ │ ├── Rename -│ │ ├── Copy/Move -│ │ ├── Delete -│ │ ├── Download to Device -│ │ └── Upload (camera, gallery, files) -│ └── File Viewer -│ ├── Text (syntax highlighted, read-only) -│ ├── Image -│ ├── PDF -│ ├── Audio Player -│ ├── Video Player -│ └── AI Actions (OCR, TTS, Transcribe) -│ -├── Activity (Tab 4) -│ ├── Task List -│ │ ├── Native Tasks -│ │ ├── Global Tasks -│ │ └── User Tasks -│ ├── Task Logs -│ └── Running Processes -│ -└── Settings (Tab 5 / Profile) - ├── Profile - │ ├── Name, Username, Avatar - │ ├── Password Change - │ └── Passkey Management - ├── App Preferences - │ ├── Theme (Light/Dark/System) - │ ├── Notification Settings - │ ├── Default Chat Model - │ ├── Biometric Lock - │ └── Server URL - └── About / Logout -``` - -### Navigation Pattern - -**Bottom Tab Bar** with 4 primary tabs + profile access: - -``` -┌─────────────────────────────────────┐ -│ │ -│ [Screen Content] │ -│ │ -├─────┬─────┬─────┬─────┬────────────┤ -│ Home│ Chat│Files│ Act.│ Settings │ -│ 🏠 │ 💬 │ 📁 │ ⚡ │ ⚙️ │ -└─────┴─────┴─────┴─────┴────────────┘ -``` - -- **Home**: Dashboard with widgets -- **Chat**: Session list → chat view -- **Files**: File browser → file viewer -- **Activity**: Tasks, logs, processes -- **Settings**: Profile and preferences - -On Android: Material 3 NavigationBar. On iOS: UITabBarController / SwiftUI TabView. - ---- - -## 6. Screen-by-Screen Breakdown - -### 6.1 Login Screen - -``` -┌─────────────────────────┐ -│ │ -│ [Officer Logo] │ -│ │ -│ ┌───────────────────┐ │ -│ │ Server URL │ │ ← Only on first launch or -│ └───────────────────┘ │ tap "Change server" -│ │ -│ ┌───────────────────┐ │ -│ │ Email │ │ -│ └───────────────────┘ │ -│ ┌───────────────────┐ │ -│ │ Password │ │ -│ └───────────────────┘ │ -│ │ -│ [ Sign In ] │ -│ │ -│ ── or ── │ -│ │ -│ [ Sign in with Passkey ] │ -│ │ -│ Forgot password? │ -│ │ -└─────────────────────────┘ -``` - -**Behavior:** -- Server URL field shown on first launch or when tapped -- Email/password fields with proper keyboard types -- "Sign in with Passkey" triggers platform WebAuthn flow -- On success: store JWT, navigate to Home -- On returning user with biometric enabled: show biometric prompt immediately, with "Use password instead" fallback - ---- - -### 6.2 Home / Dashboard - -``` -┌─────────────────────────┐ -│ Officer [Avatar]│ -├─────────────────────────┤ -│ │ -│ ┌──────┐ ┌──────────┐│ -│ │ 14:32│ │ Weather ││ -│ │ Fri │ │ 22° ☀️ ││ -│ └──────┘ └──────────┘│ -│ │ -│ ┌──────────────────┐ │ -│ │ 🍅 Pomodoro │ │ -│ │ 18:42 remaining │ │ -│ │ [Start] [Reset] │ │ -│ └──────────────────┘ │ -│ │ -│ ┌──────────────────┐ │ -│ │ Daily Goals │ │ -│ │ ☑ Exercise │ │ -│ │ ☐ Read 30min │ │ -│ │ ☐ Journal │ │ -│ │ [+ Add goal] │ │ -│ └──────────────────┘ │ -│ │ -│ ┌──────────────────┐ │ -│ │ Quick Notes │ │ -│ │ Tap to add... │ │ -│ └──────────────────┘ │ -│ │ -│ Workspaces │ -│ ┌────┐ ┌────┐ ┌────┐ │ -│ │ WS1│ │ WS2│ │ WS3│ │ -│ └────┘ └────┘ └────┘ │ -│ │ -└─────────────────────────┘ -``` - -**Behavior:** -- Scrollable vertical layout -- Widgets are cards that can be reordered (long-press drag) -- Widget data syncs with web app via user settings API -- Workspace cards show name + icon, tap opens workspace (single-panel mode on phone) -- Pull-to-refresh updates widget data -- Avatar tap opens Settings - -**Widget Implementation:** -- Clock: Local device time (no API needed) -- Weather: Can use device location + weather API, or sync from web app settings -- Pomodoro: Local timer with state synced to server (so it persists across devices) -- Daily Goals: Stored in user settings, synced -- Quick Notes: Stored in user settings, synced - ---- - -### 6.3 Chat - Session List - -``` -┌─────────────────────────┐ -│ Chat [+ New]│ -├─────────────────────────┤ -│ [🔍 Search sessions...] │ -├─────────────────────────┤ -│ │ -│ Today │ -│ ┌──────────────────┐ │ -│ │ 🤖 Debug login │ │ -│ │ Claude · 2h ago │ │ -│ │ Last: "The issue │ │ -│ │ was in the..." │ │ -│ └──────────────────┘ │ -│ ┌──────────────────┐ │ -│ │ 🤖 Refactor API │ │ -│ │ Pi-Mono · 5h ago │ │ -│ │ Last: "I've upda- │ │ -│ │ ted the router..." │ │ -│ └──────────────────┘ │ -│ │ -│ Yesterday │ -│ ┌──────────────────┐ │ -│ │ 🤖 Recipe ideas │ │ -│ │ Claude · 1d ago │ │ -│ └──────────────────┘ │ -│ │ -│ Archived ▸ │ -│ │ -└─────────────────────────┘ -``` - -**Behavior:** -- Sessions fetched from `GET /api/sessions?provider=all` -- Grouped by date (Today, Yesterday, This Week, Older) -- Each card shows: session name, provider icon, time, last message preview -- Swipe left to delete, swipe right to archive -- Long-press for context menu (rename, archive, delete) -- "Archived" section expandable -- Search filters sessions by name -- FAB or top-right button for new chat - -**Data Source:** -- `GET /api/sessions?provider=claude` (and opencode, pi-mono) -- Sessions are JSON files on the server, API returns metadata -- Message preview from last assistant message - ---- - -### 6.4 Chat - Conversation - -``` -┌─────────────────────────┐ -│ ← Debug login [···] │ -│ Claude 3.5 Sonnet ▾ │ -├─────────────────────────┤ -│ │ -│ ┌─ You ────────────┐ │ -│ │ The login page │ │ -│ │ throws a 401... │ │ -│ └──────────────────┘ │ -│ │ -│ ┌─ Claude ─────────┐ │ -│ │ Looking at the │ │ -│ │ auth middleware... │ │ -│ │ │ │ -│ │ ┌─ Tool Use ────┐ │ │ -│ │ │ 📄 Read file │ │ │ -│ │ │ auth/jwt.ts │ │ │ -│ │ └──────────────┘ │ │ -│ │ │ │ -│ │ The issue is in │ │ -│ │ the token verify │ │ -│ │ ```ts │ │ -│ │ if (!jti) ... │ │ -│ │ ``` │ │ -│ └──────────────────┘ │ -│ │ -├─────────────────────────┤ -│ ┌───────────────┐ 📎 🎤│ -│ │ Message... │ [Send]│ -│ └───────────────┘ │ -└─────────────────────────┘ -``` - -**Behavior:** -- WebSocket connection to `/api/harness/{provider}/ws` -- Messages stream in real-time (assistant:partial → assistant:text) -- Tool use blocks shown as collapsible cards (collapsed by default) -- Code blocks with syntax highlighting and copy button -- Markdown rendering for assistant messages -- Model selector dropdown in the header (or a bottom sheet) -- Attachment button (📎) opens picker: Camera, Photo Library, Files -- Microphone button (🎤) for voice input (speech-to-text → send as text) -- Send button disabled while assistant is generating -- "Stop" button appears during generation -- Pull-down to load older messages (if session has many) -- `[···]` menu: Rename session, View in files, Delete, Share - -**WebSocket Message Protocol:** -``` -Client sends: - { type: 'chat', prompt, sessionId, model, images?, attachmentIds? } - { type: 'resume', sessionId } - { type: 'stop' } - -Server sends: - { type: 'session:init', sessionId, name } - { type: 'assistant:partial', text } - { type: 'assistant:text', text } - { type: 'tool:use', name, input } - { type: 'tool:result', result } - { type: 'result', cost?, duration?, turns? } - { type: 'error', message } - { type: 'stopped' } -``` - -**Offline Behavior:** -- If offline when sending, queue message locally -- Show "Queued - will send when online" indicator -- On reconnect, send queued messages in order -- Previously loaded messages remain visible offline (cached in local DB) - -**Voice Input:** -- Tap and hold microphone for continuous recording -- Or tap once to start, tap again to stop -- Platform native speech recognition -- Transcribed text placed in input field for review before sending -- User can edit before sending - ---- - -### 6.5 Files - Directory Browser - -``` -┌─────────────────────────┐ -│ ← Files [···] │ -│ / > Documents > Work │ -├─────────────────────────┤ -│ [🔍 Search files...] │ -├─────────────────────────┤ -│ Sort: Name ▾ [≡] [⊞] │ -├─────────────────────────┤ -│ │ -│ 📁 Projects → │ -│ 📁 Reports → │ -│ 📄 notes.md 3KB │ -│ 🖼️ photo.jpg 1.2MB │ -│ 🎵 song.mp3 4.5MB │ -│ 📹 demo.mp4 45.2MB │ -│ 📦 backup.zip 12.0MB │ -│ │ -│ [+ Upload] │ -│ │ -└─────────────────────────┘ -``` - -**Behavior:** -- Breadcrumb navigation at top (scrollable horizontal) -- Tap folder to navigate in, tap file to open viewer -- Long-press for context menu: - - Open / Preview - - Share (native share sheet) - - Rename - - Copy / Move (enter selection mode) - - Delete - - Download to device - - AI actions (OCR, TTS, Transcribe - based on file type) -- Pull-to-refresh -- FAB or bottom button for upload (Camera, Photo Library, Files picker) -- Multi-select mode (long-press first item, then tap others) -- Swipe actions: left = delete, right = share -- Grid/List view toggle -- Sort by name/date/size -- Search with debounce (calls `/api/file-browser/search`) - -**Root Selection:** -- Dropdown or segmented control at top for root selection -- Only show non-home roots for Super Admin users -- Default to "home" - -**Upload Sources:** -- Device file picker -- Camera (take photo) -- Photo library -- Share sheet (from other apps) -- Drag & drop (tablet only) - ---- - -### 6.6 Files - File Viewer - -``` -┌─────────────────────────┐ -│ ← notes.md [↗] [···]│ -├─────────────────────────┤ -│ │ -│ # Meeting Notes │ -│ │ -│ ## Action Items │ -│ - Fix login bug │ -│ - Update docs │ -│ - Review PR #42 │ -│ │ -│ ## Discussion │ -│ We talked about the │ -│ new mobile app and... │ -│ │ -│ │ -│ │ -│ │ -└─────────────────────────┘ -``` - -**Viewer Types:** - -| File Type | Viewer | Notes | -|-----------|--------|-------| -| `.md` | Rendered Markdown | With proper styling | -| `.txt`, `.json`, `.ts`, `.js`, etc. | Syntax-highlighted text | Read-only, with line numbers | -| `.jpg`, `.png`, `.gif`, `.svg`, `.webp` | Image viewer | Pinch to zoom, pan | -| `.pdf` | PDF viewer | Native PDF rendering | -| `.mp3`, `.wav`, `.flac`, `.ogg` | Audio player | Play/pause, seek, speed control | -| `.mp4`, `.webm`, `.mov` | Video player | Native player, fullscreen support | -| `.mkv`, `.avi` | Video player (transcoded) | Uses `/api/file-browser/transcode` endpoint | -| Other | Download prompt | "This file type can't be previewed. Download?" | - -**Header Actions:** -- [↗] Share via native share sheet -- [···] Menu: Download to device, AI actions (contextual), Open in chat, Delete - -**AI Actions (contextual):** -- Images: OCR (extract text) -- Text files: TTS (read aloud) -- Audio/Video: Transcribe -- Video: Extract audio - ---- - -### 6.7 Activity - -``` -┌─────────────────────────┐ -│ Activity │ -├─────────────────────────┤ -│ [Tasks] [Logs] [Procs] │ -├─────────────────────────┤ -│ │ -│ Native Tasks │ -│ ┌──────────────────┐ │ -│ │ 📋 Format Code │ │ -│ │ Formats source │ │ -│ │ files with... │ │ -│ │ [Run ▶] │ │ -│ └──────────────────┘ │ -│ ┌──────────────────┐ │ -│ │ 📋 Compress Imgs │ │ -│ │ Optimizes image │ │ -│ │ files in... │ │ -│ │ [Run ▶] │ │ -│ └──────────────────┘ │ -│ │ -│ User Tasks │ -│ ┌──────────────────┐ │ -│ │ 📋 Backup DB │ │ -│ │ Runs pg_dump... │ │ -│ │ [Run ▶] │ │ -│ └──────────────────┘ │ -│ │ -└─────────────────────────┘ -``` - -**Tabs:** -1. **Tasks**: List of available tasks (native/global/user). Each shows name, description, trigger types. "Run" button opens a sheet to select target file/directory. -2. **Logs**: Recent task execution logs. Each shows task name, status (success/failure), timestamp, duration. Tap to see full log output. -3. **Processes**: Currently running background processes. Show name, status, uptime. No start/stop controls (too dangerous on mobile - manage via web). - -**Task Runner:** -- When "Run" is tapped, show a bottom sheet: - - Select target file/directory (mini file browser) - - Confirm and run - - Show real-time output in a scrollable log view - - Toast on completion - ---- - -### 6.8 Settings - -``` -┌─────────────────────────┐ -│ Settings │ -├─────────────────────────┤ -│ │ -│ ┌──────────────────┐ │ -│ │ 👤 John Doe │ │ -│ │ john@example.com │ │ -│ │ Super Admin │ │ -│ └──────────────────┘ │ -│ │ -│ Profile │ -│ Name, Username, Avatar │ -│ Change Password → │ -│ Passkeys → │ -│ │ -│ ───────────────────── │ -│ │ -│ App │ -│ Theme System │ -│ Notifications → │ -│ Default Model Claude │ -│ Biometric Lock [🔘] │ -│ │ -│ ───────────────────── │ -│ │ -│ Connection │ -│ Server 192.168.1.5 → │ -│ Status Connected 🟢│ -│ │ -│ ───────────────────── │ -│ │ -│ [ Sign Out ] │ -│ │ -│ Officer v1.0.0 │ -│ │ -└─────────────────────────┘ -``` - -**Sections:** -1. **Profile card**: Avatar, name, email, role. Tap to edit. -2. **Profile**: Name/username editing, avatar upload (camera or gallery), password change, passkey management. -3. **App**: Theme (light/dark/system), notification preferences, default chat model/provider, biometric lock toggle. -4. **Connection**: Current server URL (editable), connection status indicator, last sync time. -5. **Sign Out**: Clears JWT, biometric keys, navigates to login. - ---- - -## 7. Tablet Adaptations - -Tablets (iPad, Android tablets/foldables) get an enhanced layout while using the same app binary. Detection via screen width: -- **Phone**: < 600dp (Android) / Compact (iOS) -- **Tablet**: >= 600dp (Android) / Regular (iOS) - -### 7.1 Navigation - -**Phone**: Bottom tab bar (5 tabs) -**Tablet**: Side navigation rail (Android) / Sidebar (iOS) - -``` -Tablet Layout: -┌────┬──────────────────────────────┐ -│ │ │ -│ 🏠 │ │ -│ 💬 │ [Main Content] │ -│ 📁 │ │ -│ ⚡ │ │ -│ │ │ -│ │ │ -│ ⚙️ │ │ -└────┴──────────────────────────────┘ -``` - -### 7.2 Chat on Tablet - -**Split view**: Session list on left (1/3), conversation on right (2/3). - -``` -┌────┬──────────┬───────────────────┐ -│ │Sessions │ Debug login │ -│ 🏠 │──────────│ Claude 3.5 Sonnet │ -│ 💬 │ Debug.. │───────────────────│ -│ 📁 │ Refact.. │ │ -│ ⚡ │ Recipe.. │ [Messages...] │ -│ │ │ │ -│ │ │ │ -│ │ ├───────────────────│ -│ ⚙️ │ │ [Input] [Send] │ -└────┴──────────┴───────────────────┘ -``` - -### 7.3 Files on Tablet - -**Split view**: Directory browser on left, file viewer on right. Tap a file to preview it in the right pane without navigating away. - -``` -┌────┬──────────┬───────────────────┐ -│ │ / > Docs │ notes.md │ -│ 🏠 │──────────│───────────────────│ -│ 💬 │ 📁 Proj │ # Meeting Notes │ -│ 📁 │ 📁 Reps │ │ -│ ⚡ │ 📄 note │ ## Action Items │ -│ │ 🖼️ phot │ - Fix login bug │ -│ │ 🎵 song │ - Update docs │ -│ │ │ │ -│ ⚙️ │ │ │ -└────┴──────────┴───────────────────┘ -``` - -### 7.4 Dashboard on Tablet - -Widgets in a 2-3 column grid instead of single column. More widgets visible at once. - -``` -┌────┬──────────────────────────────┐ -│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ -│ 🏠 │ │Clock │ │Weath.│ │Pomo │ │ -│ 💬 │ └──────┘ └──────┘ └──────┘ │ -│ 📁 │ ┌─────────────┐ ┌──────────┐│ -│ ⚡ │ │ Daily Goals │ │ Quick ││ -│ │ │ ☑ Exercise │ │ Notes ││ -│ │ │ ☐ Read 30min │ │ ... ││ -│ │ └─────────────┘ └──────────┘│ -│ ⚙️ │ Workspaces │ -│ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ -└────┴──────────────────────────────┘ -``` - -### 7.5 Tablet-Only Features - -| Feature | Description | -|---------|-------------| -| **Drag & Drop** | Drag files between panes, drag text into chat | -| **Keyboard Shortcuts** | External keyboard support with shortcuts (Cmd+N for new chat, etc.) | -| **Picture-in-Picture** | Video playback continues in PiP when navigating away | -| **Multi-Window** | Android: Split screen support. iPad: Stage Manager support. | - ---- - -## 8. Technical Challenges - -### 8.1 WebSocket Lifecycle on Mobile - -**Problem**: Mobile OSes aggressively kill background connections. WebSocket to chat/terminal will disconnect when app is backgrounded. - -**Solution**: -- Detect app going to background → gracefully close WebSocket -- On foreground → reconnect WebSocket, resume session -- Use `{ type: 'resume', sessionId }` to restore chat state -- Buffer any pending assistant output server-side (the server already does this - messages are saved to JSON files) -- Show "Reconnecting..." indicator when connection drops -- Implement exponential backoff for reconnection attempts - -**Android specifics:** -- Use `ProcessLifecycleOwner` to detect app lifecycle -- Consider foreground service for active chat sessions (shows notification "Chat in progress") - -**iOS specifics:** -- Use `UIApplication.willResignActiveNotification` / `didBecomeActiveNotification` -- Background URL session for critical requests -- Use `BGAppRefreshTask` for periodic sync - -### 8.2 Push Notifications - -**Problem**: The Officer API server currently has no push notification infrastructure. - -**Required Backend Changes:** -1. New endpoint: `POST /api/devices/register` — stores FCM/APNs token per user -2. New database table: `DeviceTokens` (userId, token, platform, createdAt) -3. Server-side notification triggers: - - Chat: When assistant finishes responding and user's WebSocket is disconnected - - Tasks: When a long-running task completes - - Downloads: When yt-dlp or git clone finishes -4. Firebase Admin SDK (Android) + APNs library (iOS) on the server - -**Notification Types:** -| Type | Title | Body | Action | -|------|-------|------|--------| -| Chat complete | "Claude responded" | First 100 chars of response | Open chat session | -| Task complete | "Task finished" | "Format Code completed successfully" | Open task log | -| Download complete | "Download ready" | "video.mp4 downloaded" | Open file browser | -| Error | "Task failed" | "Backup DB failed: connection refused" | Open task log | - -### 8.3 File Upload from Mobile - -**Problem**: Mobile file uploads have different sources than web (camera, photo library, share sheet). - -**Solution**: -- Use platform file pickers that support multiple sources -- Camera capture: Take photo → upload via `POST /api/file-browser/upload` -- Compress images before upload (configurable quality setting) -- Show upload progress (the existing XHR-based upload in `useFiles.ts` supports progress) -- Background upload for large files using WorkManager (Android) / BGTaskScheduler (iOS) -- Resume interrupted uploads if possible - -### 8.4 Offline Support - -**Problem**: Users may open the app with no connectivity. - -**Strategy**: Read-heavy offline, write-queued. - -| Feature | Offline Behavior | -|---------|-----------------| -| Dashboard | Cached widget data, local timer for pomodoro | -| Chat history | Cached session list and recent messages | -| New chat | Queue message, show "Will send when online" | -| File browser | Show last cached directory listing | -| File viewer | Show cached/downloaded files only | -| Settings | Show cached profile, edits queued | - -**Local Database Schema (Room / SwiftData):** -``` -ChatSessions: id, name, provider, lastMessagePreview, updatedAt, isArchived -ChatMessages: id, sessionId, role, content, timestamp (cache recent N per session) -DirectoryCache: path, root, entriesJson, cachedAt -FileCache: path, root, localPath, size, cachedAt (for downloaded/viewed files) -PendingActions: id, type, payload, createdAt, status -``` - -### 8.5 Deep Linking & Share Sheet - -**URL Scheme**: `officer://` -**Universal Links**: `https://officer.dev/app/...` (if applicable) - -**Deep Link Routes:** -- `officer://chat/{sessionId}` — open specific chat -- `officer://files?path=/Documents` — open file browser at path -- `officer://chat/new?prompt=...` — start new chat with prefilled text - -**Share Sheet Integration (receiving):** -- Register app as share target for: text, URLs, images, files -- When content is shared to Officer: - 1. Show a sheet: "Send to Chat" or "Upload to Files" - 2. If Chat: open new chat with shared content as first message - 3. If Files: open file browser with upload in current directory - -### 8.6 Image Handling in Chat - -**Problem**: The web app sends images as base64 in the WebSocket message. Large images on mobile could cause memory issues. - -**Solution**: -1. Before sending, resize images to max 2048px on longest edge -2. Compress to JPEG at 85% quality (unless PNG is needed for screenshots) -3. Convert to base64 and include in chat message -4. Show thumbnail in the message thread, tap to view full-size -5. Consider using the upload endpoint first, then sending attachment IDs instead of base64 (check if API supports this path — it does via `attachmentIds` in the chat message) - -### 8.7 Markdown & Code Rendering - -**Problem**: Rendering rich markdown with code blocks, tables, and images in native views. - -**Android Solution:** -- Use a Markdown library (Markwon or compose-markdown) -- Code blocks: custom span with monospace font + syntax highlighting -- Consider a lightweight WebView-based renderer for complex markdown as fallback - -**iOS Solution:** -- Use `AttributedString` with custom markdown parsing -- Or use a SwiftUI markdown library (MarkdownUI) -- Code blocks: custom view with monospace font + syntax highlighting - -**Code Syntax Highlighting:** -- Android: Highlight.js via WebView, or a native library like CodeView -- iOS: Splash or Highlightr library - -### 8.8 Streaming Text Display - -**Problem**: Chat responses stream token-by-token via WebSocket. Need smooth text rendering without layout thrashing. - -**Solution**: -- Buffer incoming tokens (e.g., collect for 50ms before rendering) -- Use a single mutable text state that appends -- Avoid re-rendering the entire message list on each token -- Only the last (active) message bubble needs updating -- Auto-scroll to bottom during streaming, unless user has scrolled up - -### 8.9 Security - -**Concerns:** -- JWT stored on device must be encrypted -- Biometric key binding for stored credentials -- Certificate pinning for API connections (optional but recommended for self-hosted) -- No sensitive data in logs -- Clear all data on sign out -- Jailbreak/root detection (optional) - -**Android:** -- EncryptedSharedPreferences for tokens -- Android Keystore for biometric-bound keys -- ProGuard/R8 for release builds - -**iOS:** -- Keychain with `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` -- Secure Enclave for biometric keys -- App Transport Security (ATS) enforced - -### 8.10 Self-Hosted Server Discovery - -**Problem**: Officer is self-hosted. Users need to point the app at their server. The server might be on a local network, behind a VPN, or on the public internet. - -**Solution**: -- First-launch: manual URL entry with validation -- Local network: mDNS/Bonjour discovery (optional nice-to-have) -- QR code scanning from web app settings page (generate QR with server URL + optional auth token) -- Store multiple server profiles (for users who have dev/prod setups) -- Connection status indicator in settings - ---- - -## 9. API Integration Notes - -### Endpoints the Mobile App Will Use - -**Auth:** -- `POST /api/auth/signin` — login -- `POST /api/auth/signup` — register (if enabled) -- `POST /api/auth/signout` — logout -- `GET /api/auth/me` — validate token, get user info -- `POST /api/auth/change-password` — password change -- `*/passkeys/*` — passkey registration/auth - -**Chat:** -- `GET /api/sessions?provider={provider}` — list sessions -- `DELETE /api/sessions/{provider}/{id}` — delete session -- `POST /api/sessions/{provider}/{id}/rename` — rename session -- `POST /api/sessions/{provider}/{id}/archive` — archive session -- WebSocket `/api/harness/{provider}/ws` — chat communication - -**Files:** -- `GET /api/file-browser/ls?path={path}&root={root}` — list directory -- `GET /api/file-browser/read?path={path}` — read text file -- `GET /api/file-browser/raw?path={path}` — raw file (binary, supports Range) -- `GET /api/file-browser/search?q={query}` — search files -- `POST /api/file-browser/mkdir` — create directory -- `POST /api/file-browser/write` — write file -- `POST /api/file-browser/upload` — upload files (multipart) -- `POST /api/file-browser/rename` — rename -- `POST /api/file-browser/copy` — copy -- `POST /api/file-browser/move` — move -- `DELETE /api/file-browser/rm` — delete -- `GET /api/file-browser/download?path={path}` — download file -- `POST /api/file-browser/download` — download multiple as zip -- `GET /api/file-browser/transcode?path={path}` — transcode video -- `POST /api/file-browser/tts` — text-to-speech -- `POST /api/file-browser/ocr` — OCR image -- `POST /api/file-browser/transcribe` — transcribe audio -- `POST /api/file-browser/extract-audio` — extract audio from video -- `POST /api/file-browser/extract` — extract archive -- `POST /api/file-browser/git-clone` — clone git repo -- `POST /api/file-browser/download-video` — yt-dlp download - -**Tasks:** -- `GET /api/tasks` — list tasks -- `GET /api/tasks/{name}` — task details -- `POST /api/tasks/{name}/run` — run task - -**Task Logs:** -- `GET /api/task-logs` — list logs -- `GET /api/task-logs/{id}` — log details - -**Processes:** -- `GET /api/processes` — list processes - -**Settings:** -- `GET /api/user/settings` — user settings -- `PUT /api/user/settings` — update settings -- `PUT /api/auth/users` — update profile - -**Upload:** -- `POST /api/upload` — upload attachments (for chat) - -**Scrape:** -- `POST /api/scrape` — scrape URL (for sharing URLs to chat) - -### New Endpoints Needed - -| Endpoint | Purpose | -|----------|---------| -| `POST /api/devices/register` | Register push notification token | -| `DELETE /api/devices/{token}` | Unregister device on logout | -| `GET /api/sessions/{provider}/{id}/messages` | Get messages for a session (currently read from files, need API endpoint) | - -### Authentication Header - -All requests include: `Authorization: Bearer {jwt_token}` - -WebSocket connections pass token as query parameter: `?token={jwt_token}` - ---- - -## 10. Shared Design Language - -While each platform follows its native design guidelines (Material 3 for Android, Human Interface Guidelines for iOS), some design elements should be consistent: - -### Color Palette - -From the web app's Tailwind theme: -- **Primary (Teal)**: `duck-teal` — used for primary actions, active states -- **Accent (Yellow)**: `duck-yellow` — used for text on primary, highlights -- **Dark**: `duck-dark` — text, icons -- **Background**: Light/dark mode adaptive - -Both apps should use these brand colors while adapting to platform conventions: -- Android: Material 3 dynamic color with Officer palette as seed -- iOS: Officer palette with system-adaptive backgrounds - -### Typography - -- **Android**: Roboto (system default), with monospace for code -- **iOS**: SF Pro (system default), with SF Mono for code -- Both: Similar size scale, consistent heading hierarchy - -### Iconography - -- **Android**: Material Symbols (outlined) -- **iOS**: SF Symbols -- Map lucide-react icons used in web to platform equivalents - -### Animations - -- **Android**: Material Motion (shared element transitions, container transforms) -- **iOS**: Spring animations, matched geometry effects -- Both: Smooth transitions between screens, subtle feedback on interactions - ---- - -## 11. Implementation Phases - -### Phase 1: Foundation (MVP) - -**Goal**: Core functionality that makes the app useful enough to ship. - -| Feature | Details | -|---------|---------| -| Auth | Email/password login, token storage, biometric unlock | -| Server setup | URL configuration, validation | -| Chat | New chat, session list, real-time conversation with streaming | -| Chat basics | Text messages, model selection, session management | -| Settings | Profile view, theme, logout | - -**Estimated screens**: Login, Home (simple), Chat List, Chat Conversation, Settings - -### Phase 2: Files & Polish - -**Goal**: File management and mobile-specific enhancements. - -| Feature | Details | -|---------|---------| -| File browser | Directory listing, navigation, search | -| File viewer | Text, images, PDF, audio, video | -| File actions | Upload (camera, files), download, rename, delete | -| Chat attachments | Image attachment, voice input | -| Push notifications | Basic chat completion notifications | - -**Estimated screens**: File Browser, File Viewer, enhanced Chat - -### Phase 3: Productivity - -**Goal**: Dashboard, tasks, and deeper integration. - -| Feature | Details | -|---------|---------| -| Dashboard | Widget system (clock, weather, pomodoro, goals, notes) | -| Tasks | Task list, run tasks, view logs | -| Workspace quick access | Open workspaces (single-panel) | -| Share sheet | Receive content from other apps | -| Offline support | Cached data, queued actions | - -**Estimated screens**: Dashboard, Task List, Task Logs, enhanced Home - -### Phase 4: Tablet & Advanced - -**Goal**: Tablet optimization and advanced features. - -| Feature | Details | -|---------|---------| -| Tablet layouts | Split views for chat, files | -| Tablet navigation | Side rail / sidebar | -| Home screen widgets | Android widgets, iOS widgets | -| AI file actions | OCR, TTS, Transcribe from mobile | -| Multi-select | Batch file operations | -| Deep linking | URL scheme, universal links | - -### Phase 5: Nice-to-Haves - -| Feature | Details | -|---------|---------| -| QR code server setup | Scan from web to configure | -| Local network discovery | mDNS/Bonjour | -| Picture-in-Picture | Video PiP on tablet | -| Passkey auth | Full WebAuthn support | -| Keyboard shortcuts | External keyboard on tablet | -| Skills browser | View and search skills library | -| Background downloads | yt-dlp and git clone in background | - ---- - -## Appendix: Decision Log - -| Decision | Rationale | -|----------|-----------| -| Native (Kotlin + Swift) over cross-platform | User preference. Also gives best performance, platform-native UX, and full access to platform APIs (biometrics, push, background tasks, share sheet). | -| Exclude terminal | Phone keyboards make shell commands impractical. The sandboxed Docker setup is inherently desktop-oriented. | -| Exclude code editor (write) | Writing code on a phone is poor UX. Read-only with syntax highlighting is sufficient for review. | -| Exclude automation builder | Complex form-heavy UI that doesn't translate to small screens. | -| Include chat as primary feature | AI assistant in your pocket is the strongest mobile use case. Voice input makes it even more compelling on mobile. | -| Bottom tabs (phone) / Side rail (tablet) | Standard navigation patterns for each form factor. 5 top-level destinations fits within guidelines. | -| Offline-first for reads, queue for writes | Mobile connectivity is unreliable. Showing cached data is better than empty screens. | -| Phase 1 = Auth + Chat | Chat is the killer feature. Get it right first, everything else is complementary. | diff --git a/SECURITY_AUDIT.md b/SECURITY_AUDIT.md deleted file mode 100644 index 9f9dee81..00000000 --- a/SECURITY_AUDIT.md +++ /dev/null @@ -1,593 +0,0 @@ -# Security Audit — Officer.dev Pi-Monorepo - -**Date:** 2026-02-25 -**Scope:** Full-stack audit of server, frontend, and infrastructure code. - ---- - -## Executive Summary - -The codebase has solid foundations (JWT + argon2 auth, WebAuthn passkeys, token blacklisting, Docker-sandboxed terminals, role-based access control). However, several critical and high-severity vulnerabilities exist — primarily around CORS misconfiguration, weak secret management, unauthenticated admin routes, XSS via `rehype-raw`, and token exposure in URLs. - -**Totals:** 5 Critical, 13 High, 14 Medium, 9 Low, 5 Info - ---- - -## CRITICAL - -### C1. Weak JWT Secret — `"officer"` - -**Files:** `.env` (line 2), `src/servers/jwt.ts` (lines 2, 25) - -The live `.env` contains `JWT_SECRET="officer"` — a single dictionary word. The `.env.example` uses `"change-me"`. The server uses a non-null assertion (`JWT_SECRET!`) with no startup validation for length or complexity. - -**Impact:** Complete authentication bypass. Anyone who knows/guesses the secret can forge JWTs for any user including Super Admin. - -**Remediation:** -- Generate a cryptographically random secret: `openssl rand -base64 32` -- Add a startup guard: throw if `JWT_SECRET` is absent or shorter than 32 characters -- Update `.env.example` with a placeholder: `JWT_SECRET=` - ---- - -### C2. Global CORS Wildcard on All API Routes - -**File:** `src/servers/hono.ts` (lines 36–42) - -```ts -cors({ origin: '*', allowHeaders: ['Content-Type', 'Authorization'] }) -``` - -Applied to every route. The `Authorization` header allowlist means any website can make cross-origin requests using a victim's token (obtained via XSS or other leaks). - -**Impact:** Full cross-origin request forgery against all API endpoints for users tricked into visiting a malicious page. - -**Remediation:** Replace `origin: '*'` with the allowlist from `origin-validation.ts` (`ALLOWED_ORIGINS`). Use a dynamic origin validation function in the CORS middleware. - ---- - -### C3. Server-Settings Routes Entirely Unauthenticated - -**Files:** `src/servers/hono.ts` (lines 46–48), `src/servers/api/server-settings/server-settings.ts` - -The `serverSettingsRouter` is mounted on the **public** router (outside `protectedRouter`). All sub-routes — SMTP, TTS, STT, OCR, SearXNG, Pi-Mono, Claude Code, OpenCode, applications, resources — have no auth checks. Any unauthenticated request can read settings (including masked credentials), write new settings, and trigger software installs. - -**Impact:** Full server configuration takeover by any unauthenticated user. - -**Remediation:** Move `serverSettingsRouter` inside `protectedRouter`. Add Super Admin role checks on all write operations. Exempt only `GET /api/server-settings/onboarding-complete` as public. - ---- - -### C4. Unauthenticated Dev-Server WebSocket Proxy - -**Files:** `src/server.tsx` (lines 114–139), `src/servers/api/dev-server/router.ts` (lines 241–268), `src/servers/hono.ts` (line 49) - -The dev-server proxy (`/api/dev-server-proxy/*`) is mounted on the public router. WebSocket upgrades carry no authentication. The HTTP proxy has no auth gate either. Additionally, the Referer header fallback allows probing any running dev server. - -**Impact:** Unauthenticated access to dev-servers spawned for any user, which may expose internal APIs, HMR endpoints, or local services. - -**Remediation:** Require a valid JWT (via query param) before upgrading WebSocket connections. Apply `userMiddleware` to the HTTP proxy router. - ---- - -### C5. AI Chat Messages Rendered with `rehype-raw` — LLM-Driven XSS - -**File:** `src/workspaces/officerdev/src/apps/Chat/components/MessageBubble.tsx` (lines 132, 181) - -```tsx -{assistantText} -``` - -AI-generated assistant responses containing HTML tags (`