diff --git a/AGENTS.md b/AGENTS.md index ccfff084..342f34f1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,220 +1,32 @@ # AGENTS.md -Guide for agentic coding assistants working in the Officer monorepo. +Guidance for any coding agent working in the Officer platform repo. -## What Is Officer +**The instructions live in [`CLAUDE.md`](CLAUDE.md). Read it first — this file only points there.** -Officer is an **AI-powered intranet server** for small and medium businesses. It's a self-hosted platform that gives each team member a personal AI assistant, file storage, terminal, code editor, workspaces, and project management — all under centralized admin control. +Kept separate so agents that look for `AGENTS.md` by convention find the same guidance as those that +look for `CLAUDE.md`, without the two drifting apart. The previous contents of this file had drifted +badly: they described Officer as a multi-user intranet for small businesses, with a user-invitation +API, a `bun dev` serving a separate dashboard on port 5000, and a closing instruction to be +"multi-user aware — always consider user isolation and role-based access". None of that is true. -**Think of it as**: a self-hosted, AI-native company intranet where every employee gets their own workspace with shared organizational resources and automation. +## Orientation -### Multi-User Architecture +Officer is a self-hosted personal platform that **serves exactly one person — the owner of the +server**. There is no tenancy, no roles, no user management. If a design question turns on "which +user", the answer is the owner. -- **Role hierarchy**: Member → Admin → Owner → Super Admin -- **Bootstrap flow**: First user registers as Super Admin, then invites the team -- **Per-user isolation**: Files, sessions, settings, workspaces, and tasks are scoped per user under `$DATA_PATH/{email}/` -- **Shared org resources**: Global tasks/skills/processes, server-level settings (SMTP, AI providers, TTS/STT/OCR), pluggable applications and resources -- **Multi-scope resolution**: Tasks, skills, and processes resolve user → global → native (built-in), enabling org-wide shared automation +This repo is one of two. The other, `capabilities/`, holds the agent's tasks, tools and skills as +plain files, and is where most changes belong — adding or changing a task needs no code change here +and no restart. -### Core Capabilities +- [`CLAUDE.md`](CLAUDE.md) — this repo's architecture, conventions and code style +- [`docs/working-on-officer.md`](docs/working-on-officer.md) — the deployment-wide guide: which + directory a change belongs in, how to run and verify it, the task system, and the failure modes + worth knowing about +- `CONVENTIONS.md` — component organisation and React patterns, with rationale +- `TODO.md` — current direction; takes precedence where it disagrees with anything else -1. **AI Chat** — Multi-provider (Claude, OpenCode, Pi-Mono) with sessions, attachments, speech-to-text, slash commands -2. **File Browser** — Full filesystem access per user (upload, mkdir, copy, move, delete) -3. **File Viewer** — Preview video, images, code, text, markdown -4. **Terminal** — WebSocket-based PTY terminal with Docker sandboxing -5. **Code Editor** — Monaco-based IDE with file tabs -6. **Projects** — Project management with per-project workspace layouts, git init -7. **Workspaces** — Customizable panel-based layouts (split, resize, swap, drag) -8. **Automation/Skills/Tasks/Processes** — Markdown-based capability definitions with YAML frontmatter -9. **Dev Server** — Start/stop project dev servers with auto-port discovery and live proxy -10. **Dashboard Widgets** — Clock, weather, pomodoro, daily goals, quick notes -11. **Settings** — User preferences, server config, resource management - -## Quick Start Commands - -### Development - -```bash -bun dev # Dashboard + API server (port 5000) -bun dev:emailer # Emailer workspace -``` - -### Building - -```bash -bun run prebuild # Run prebuild tasks -bun run build:web # Build web app -bun run build:dashboard # Build dashboard -bun run build:editor # Build editor (app + extension + runtime) -``` - -### Code Quality - -```bash -bun format # Format all files (Prettier, required before commit) -bun format:check # Check formatting without writing -bunx tsgo # TypeScript type checking -``` - -**Note:** No automated tests configured yet. Always run `bun format` before committing. - -## Project Structure - -``` -src/ -├── apps/ -│ └── officer-web/ # Main web UI (React 19) -│ ├── Screens/ -│ │ ├── Authentication/ # Login, verify, reset password -│ │ └── Dashboard/ # All main screens (Home, Files, Chat, Terminal, Projects, etc.) -│ ├── state/ # App-specific state hooks -│ ├── lib/ # Utilities -│ └── locales/ # i18n translations -│ -├── servers/ -│ ├── api/ # REST API (Hono, port 5000) -│ │ ├── auth/ # Authentication (JWT + WebAuthn passkeys) -│ │ ├── users/ # User management (invite, CRUD) -│ │ ├── sessions/ # Multi-provider chat sessions -│ │ ├── workspaces/ # Workspace & project state -│ │ ├── tasks/ # Task definitions (CRUD + chat) -│ │ ├── skills/ # Skill definitions (CRUD + chat) -│ │ ├── processes/ # Process definitions (CRUD + chat) -│ │ ├── file-browser/ # Filesystem access (multi-root) -│ │ ├── terminal/ # WebSocket PTY terminal -│ │ ├── dev-server/ # Project dev server management -│ │ ├── pi/ # AI agent integration -│ │ ├── scrape/ # Web scraping (Playwright) -│ │ ├── upload/ # File uploads -│ │ ├── settings/ # User settings & state -│ │ ├── server-settings/ # Server-wide config (SMTP, AI, TTS, etc.) -│ │ ├── dock/ # Dock configuration -│ │ ├── plans/ # Markdown plans -│ │ ├── task-logs/ # Task execution logs -│ │ └── landing-page-data/# Registration status -│ └── _middlewares/ # Auth, rate limiting, CORS, body parsing -│ -├── databases/ -│ └── officer_db/ # JSON file-based auth store (users, passkeys, tokens) -│ -└── workspaces/ # 13 shared packages - ├── types/ # Central type re-exports - ├── definitions/ # Constants, enums (roles, statuses, devices) - ├── config/ # URL configs, env vars - ├── helpers/ # cn(), formatters, slug, debounce, queue - ├── hooks/ # 90+ hooks (useClient, useForm, useAuth, etc.) - ├── state/ # React Query state hooks (useSettings, useChatSessions, etc.) - ├── components/ # 89 components (shadcn/ui base + custom) - ├── officerdev/ # Core workspace/panel framework + 11 built-in apps - ├── i18n/ # Internationalization - ├── injector/ # DOM manipulation for visual editing - ├── widgets/ # Dashboard widgets (clock, weather, pomodoro, etc.) - ├── emailer/ # React-email templates + SMTP - └── sounds/ # Audio feedback library -``` - -## Path Aliases - -- `@/` → `src/apps/officer-web/` -- `@@/` → `src/servers/` -- `@/components/*` → `src/workspaces/components/*` - -## Tech Stack - -- **Runtime**: Bun -- **Language**: TypeScript 5.9 (strict mode, verbatimModuleSyntax) -- **Frontend**: React 19, React Router, React Query, Tailwind CSS, shadcn/ui -- **Backend**: Hono framework, JWT auth, WebAuthn passkeys -- **Storage**: JSON file-based (auth store + user data), no traditional DB for most data -- **Build**: Vite -- **AI**: Claude Agent SDK, multi-provider support - -## Code Style Guide - -### Imports - -Order: **types → external → workspace → relative** - -```ts -import type { Experiment } from 'types'; -import { useState } from 'react'; -import { useQuery } from '@tanstack/react-query'; -import { useExperiment } from 'hooks/use-experiment'; -import { formatDate } from '../helpers'; -``` - -Type-only imports required (verbatimModuleSyntax): -```ts -import { ActionModals, type ActionModalsTypes } from './ActionModals'; -import type { FormEvent } from 'react'; -``` - -### TypeScript - -- Strict mode always — no `any` -- Prefer `type` over `interface` -- Colocate prop types with components as named exports -- Early returns for null/undefined guards -- Use optional chaining and nullish coalescing: `obj?.prop ?? fallback` - -### Functions - -- Arrow functions for simple/one-liners -- Regular functions for complex multi-line logic -- Named exports only (never default exports) -- Extract params type when signature gets long (no multiline params) - -```ts -export const formatDate = (ts: number) => new Date(ts).toLocaleDateString(); -export function calculateStats(data: DataPoint[]) { /* ... */ } -``` - -### React Components - -- Functional components with named prop types -- Arrow function syntax -- No useMemo/useCallback (React 19 compiler handles optimization) - -```tsx -type CardProps = { title: string; onClick: () => void }; -export const Card = ({ title, onClick }: CardProps) =>
{title}
; -``` - -### State Management - -- **React Query** for server state -- **useGlobal()** for UI state (backed by query cache, no Context needed) -- **useWorkspacesState()** for persistent workspace layouts (server-synced) -- **useQueryState()** for URL-synced state -- **usePanelChannel()** for inter-panel pub/sub communication -- **Manager pattern** for complex hooks — return object with state + methods -- **Derived state** — compute in hook, not in components - -### Naming Conventions - -- **Components**: `PascalCase.tsx` (e.g., `ExperimentCard.tsx`) -- **Everything else**: `kebab-case.ts` (e.g., `use-experiment.ts`, `format-date.ts`) -- **Hooks**: `use-*.ts` or `useFeatureName.ts` - -### Formatting (Prettier) - -- Semicolons: always -- Quotes: single (JS/TS), double (JSX) -- Trailing commas: all -- Indent: 2 spaces -- Line width: 120 characters - -### Error Handling - -- Use try/catch for async operations -- Include context in error messages (IDs, resource names) -- Always async/await (never .then() chains) - -## General Guidelines - -- **Database-first** approach — schema → API → UI -- **Self-documenting code** — clear naming, minimal comments -- **Explicit over implicit** — no magic -- **Workspace dependencies** — use `workspace:*` -- **Multi-user aware** — always consider user isolation and role-based access when adding features -- **File-based storage** — user data lives under `$DATA_PATH/{email}/`, respect the per-user boundary +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.