diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..fcdb37ed --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,143 @@ +# AGENTS.md + +Guidance for human and AI contributors working in this repository. + +## 1. Purpose + +Paperclip is a control plane for AI-agent companies. +The current implementation target is V1 and is defined in `doc/SPEC-implementation.md`. + +## 2. Read This First + +Before making changes, read in this order: + +1. `doc/GOAL.md` +2. `doc/PRODUCT.md` +3. `doc/SPEC-implementation.md` +4. `doc/DEVELOPING.md` +5. `doc/DATABASE.md` + +`doc/SPEC.md` is long-horizon product context. +`doc/SPEC-implementation.md` is the concrete V1 build contract. + +## 3. Repo Map + +- `server/`: Express REST API and orchestration services +- `ui/`: React + Vite board UI +- `packages/db/`: Drizzle schema, migrations, DB clients +- `packages/shared/`: shared types, constants, validators, API path constants +- `doc/`: operational and product docs + +## 4. Dev Setup (Auto DB) + +Use embedded PGlite in dev by leaving `DATABASE_URL` unset. + +```sh +pnpm install +pnpm dev +``` + +This starts: + +- API: `http://localhost:3100` +- UI: `http://localhost:5173` + +Quick checks: + +```sh +curl http://localhost:3100/api/health +curl http://localhost:3100/api/companies +``` + +Reset local dev DB: + +```sh +rm -rf data/pglite +pnpm dev +``` + +## 5. Core Engineering Rules + +1. Keep changes company-scoped. +Every domain entity should be scoped to a company and company boundaries must be enforced in routes/services. + +2. Keep contracts synchronized. +If you change schema/API behavior, update all impacted layers: +- `packages/db` schema and exports +- `packages/shared` types/constants/validators +- `server` routes/services +- `ui` API clients and pages + +3. Preserve control-plane invariants. +- Single-assignee task model +- Atomic issue checkout semantics +- Approval gates for governed actions +- Budget hard-stop auto-pause behavior +- Activity logging for mutating actions + +4. Do not replace strategic docs wholesale unless asked. +Prefer additive updates. Keep `doc/SPEC.md` and `doc/SPEC-implementation.md` aligned. + +## 6. Database Change Workflow + +When changing data model: + +1. Edit `packages/db/src/schema/*.ts` +2. Ensure new tables are exported from `packages/db/src/schema/index.ts` +3. Generate migration: + +```sh +pnpm db:generate +``` + +4. Validate compile: + +```sh +pnpm -r typecheck +``` + +Notes: +- `packages/db/drizzle.config.ts` reads compiled schema from `dist/schema/*.js` +- `pnpm db:generate` compiles `packages/db` first + +## 7. Verification Before Hand-off + +Run this full check before claiming done: + +```sh +pnpm -r typecheck +pnpm test:run +pnpm build +``` + +If anything cannot be run, explicitly report what was not run and why. + +## 8. API and Auth Expectations + +- Base path: `/api` +- Board access is treated as full-control operator context +- Agent access uses bearer API keys (`agent_api_keys`), hashed at rest +- Agent keys must not access other companies + +When adding endpoints: + +- apply company access checks +- enforce actor permissions (board vs agent) +- write activity log entries for mutations +- return consistent HTTP errors (`400/401/403/404/409/422/500`) + +## 9. UI Expectations + +- Keep routes and nav aligned with available API surface +- Use company selection context for company-scoped pages +- Surface failures clearly; do not silently ignore API errors + +## 10. Definition of Done + +A change is done when all are true: + +1. Behavior matches `doc/SPEC-implementation.md` +2. Typecheck, tests, and build pass +3. Contracts are synced across db/shared/server/ui +4. Docs updated when behavior or commands change + diff --git a/doc/CLIPHUB.md b/doc/CLIPHUB.md index 6a55c325..30e7c280 100644 --- a/doc/CLIPHUB.md +++ b/doc/CLIPHUB.md @@ -8,7 +8,7 @@ ClipHub is the public registry where people share, discover, and download Paperc ## What It Is -ClipHub is to Paperclip what a package registry is to a programming language. Paperclip already supports exportable org configs (see SPEC.md §2). ClipHub is the public directory where those exports live. +ClipHub is to Paperclip what a package registry is to a programming language. Paperclip already supports exportable org configs (see [SPEC.md](./SPEC.md) §2). ClipHub is the public directory where those exports live. A user builds a working company in Paperclip — a dev shop, a marketing agency, a research lab, a content studio — exports the template, and publishes it to ClipHub. Anyone can browse, search, download, and spin up that company on their own Paperclip instance. diff --git a/doc/DEVELOPING.md b/doc/DEVELOPING.md new file mode 100644 index 00000000..60e05b70 --- /dev/null +++ b/doc/DEVELOPING.md @@ -0,0 +1,58 @@ +# Developing + +This project can run fully in local dev without setting up PostgreSQL manually. + +## Prerequisites + +- Node.js 20+ +- pnpm 9+ + +## Start Dev + +From repo root: + +```sh +pnpm install +pnpm dev +``` + +This starts: + +- API server: `http://localhost:3100` +- UI: `http://localhost:5173` + +## Database in Dev (Auto-Handled) + +For local development, leave `DATABASE_URL` unset. +The server will automatically use embedded PGlite and persist data at: + +- `./data/pglite` + +No Docker or external database is required for this mode. + +## Quick Health Checks + +In another terminal: + +```sh +curl http://localhost:3100/api/health +curl http://localhost:3100/api/companies +``` + +Expected: + +- `/api/health` returns `{"status":"ok"}` +- `/api/companies` returns a JSON array + +## Reset Local Dev Database + +To wipe local dev data and start fresh: + +```sh +rm -rf data/pglite +pnpm dev +``` + +## Optional: Use External Postgres + +If you set `DATABASE_URL`, the server will use that instead of embedded PGlite. diff --git a/GOAL.md b/doc/GOAL.md similarity index 100% rename from GOAL.md rename to doc/GOAL.md diff --git a/PRODUCT.md b/doc/PRODUCT.md similarity index 98% rename from PRODUCT.md rename to doc/PRODUCT.md index 5c265aa1..90e18b9c 100644 --- a/PRODUCT.md +++ b/doc/PRODUCT.md @@ -82,4 +82,4 @@ More detailed task structure TBD. ## Further Detail -See [SPEC.md](./SPEC.md) for the full technical specification and [doc/TASKS.md](./doc/TASKS.md) for the task management data model. +See [SPEC.md](./SPEC.md) for the full technical specification and [TASKS.md](./TASKS.md) for the task management data model. diff --git a/doc/SPEC-implementation.md b/doc/SPEC-implementation.md new file mode 100644 index 00000000..b732c568 --- /dev/null +++ b/doc/SPEC-implementation.md @@ -0,0 +1,765 @@ +# Paperclip V1 Implementation Spec + +Status: Implementation contract for first release (V1) +Date: 2026-02-17 +Audience: Product, engineering, and agent-integration authors +Source inputs: `GOAL.md`, `PRODUCT.md`, `SPEC.md`, `DATABASE.md`, current monorepo code + +## 1. Document Role + +`SPEC.md` remains the long-horizon product spec. +This document is the concrete, build-ready V1 contract. +When there is a conflict, `SPEC-implementation.md` controls V1 behavior. + +## 2. V1 Outcomes + +Paperclip V1 must provide a full control-plane loop for autonomous agents: + +1. A human board creates a company and defines goals. +2. The board creates and manages agents in an org tree. +3. Agents receive and execute tasks via heartbeat invocations. +4. All work is tracked through tasks/comments with audit visibility. +5. Token/cost usage is reported and budget limits can stop work. +6. The board can intervene anywhere (pause agents/tasks, override decisions). + +Success means one operator can run a small AI-native company end-to-end with clear visibility and control. + +## 3. Explicit V1 Product Decisions + +These decisions close open questions from `SPEC.md` for V1. + +| Topic | V1 Decision | +|---|---| +| Tenancy | Single-tenant deployment, multi-company data model | +| Company model | Company is first-order; all business entities are company-scoped | +| Board | Single human board operator per deployment | +| Org graph | Strict tree (`reports_to` nullable root); no multi-manager reporting | +| Visibility | Full visibility to board and all agents in same company | +| Communication | Tasks + comments only (no separate chat system) | +| Task ownership | Single assignee; atomic checkout required for `in_progress` transition | +| Recovery | No automatic reassignment; stale work is surfaced, not silently fixed | +| Agent adapters | Built-in `process` and `http` adapters | +| Auth | Session auth for board, API keys for agents | +| Budget period | Monthly UTC calendar window | +| Budget enforcement | Soft alerts + hard limit auto-pause | +| Deployment modes | Embedded PGlite default; Docker/hosted Postgres supported | + +## 4. Current Baseline (Repo Snapshot) + +As of 2026-02-17, the repo already includes: + +- Node + TypeScript backend with REST CRUD for `agents`, `projects`, `goals`, `issues`, `activity` +- React UI pages for dashboard/agents/projects/goals/issues lists +- PostgreSQL schema via Drizzle with embedded PGlite fallback when `DATABASE_URL` is unset + +V1 implementation extends this baseline into a company-centric, governance-aware control plane. + +## 5. V1 Scope + +## 5.1 In Scope + +- Company lifecycle (create/list/get/update/archive) +- Goal hierarchy linked to company mission +- Agent lifecycle with org structure and adapter configuration +- Task lifecycle with parent/child hierarchy and comments +- Atomic task checkout and explicit task status transitions +- Board approvals for hires and CEO strategy proposal +- Heartbeat invocation, status tracking, and cancellation +- Cost event ingestion and rollups (agent/task/project/company) +- Budget settings and hard-stop enforcement +- Board web UI for dashboard, org chart, tasks, agents, approvals, costs +- Agent-facing API contract (task read/write, heartbeat report, cost report) +- Auditable activity log for all mutating actions + +## 5.2 Out of Scope (V1) + +- Plugin framework and third-party extension SDK +- Revenue/expense accounting beyond model/token costs +- Knowledge base subsystem +- Public marketplace (ClipHub) +- Multi-board governance or role-based human permission granularity +- Automatic self-healing orchestration (auto-reassign/retry planners) + +## 6. Architecture + +## 6.1 Runtime Components + +- `server/`: REST API, auth, orchestration services +- `ui/`: Board operator interface +- `packages/db/`: Drizzle schema, migrations, DB clients (Postgres and PGlite) +- `packages/shared/`: Shared API types, validators, constants + +## 6.2 Data Stores + +- Primary: PostgreSQL +- Local default: embedded PGlite at `./data/pglite` +- Optional local prod-like: Docker Postgres +- Optional hosted: Supabase/Postgres-compatible + +## 6.3 Background Processing + +A lightweight scheduler/worker in the server process handles: + +- heartbeat trigger checks +- stuck run detection +- budget threshold checks +- stale task reporting generation + +Separate queue infrastructure is not required for V1. + +## 7. Canonical Data Model (V1) + +All core tables include `id`, `created_at`, `updated_at` unless noted. + +## 7.0 Auth Tables + +Human auth tables (`users`, `sessions`, and provider-specific auth artifacts) are managed by the selected auth library. This spec treats them as required dependencies and references `users.id` where user attribution is needed. + +## 7.1 `companies` + +- `id` uuid pk +- `name` text not null +- `description` text null +- `status` enum: `active | paused | archived` + +Invariant: every business record belongs to exactly one company. + +## 7.2 `agents` + +- `id` uuid pk +- `company_id` uuid fk `companies.id` not null +- `name` text not null +- `role` text not null +- `title` text null +- `status` enum: `active | paused | idle | running | error | terminated` +- `reports_to` uuid fk `agents.id` null +- `capabilities` text null +- `adapter_type` enum: `process | http` +- `adapter_config` jsonb not null +- `context_mode` enum: `thin | fat` default `thin` +- `budget_monthly_cents` int not null default 0 +- `spent_monthly_cents` int not null default 0 +- `last_heartbeat_at` timestamptz null + +Invariants: + +- agent and manager must be in same company +- no cycles in reporting tree +- `terminated` agents cannot be resumed + +## 7.3 `agent_api_keys` + +- `id` uuid pk +- `agent_id` uuid fk `agents.id` not null +- `company_id` uuid fk `companies.id` not null +- `name` text not null +- `key_hash` text not null +- `last_used_at` timestamptz null +- `revoked_at` timestamptz null + +Invariant: plaintext key shown once at creation; only hash stored. + +## 7.4 `goals` + +- `id` uuid pk +- `company_id` uuid fk not null +- `title` text not null +- `description` text null +- `level` enum: `company | team | agent | task` +- `parent_id` uuid fk `goals.id` null +- `owner_agent_id` uuid fk `agents.id` null +- `status` enum: `planned | active | achieved | cancelled` + +Invariant: at least one root `company` level goal per company. + +## 7.5 `projects` + +- `id` uuid pk +- `company_id` uuid fk not null +- `goal_id` uuid fk `goals.id` null +- `name` text not null +- `description` text null +- `status` enum: `backlog | planned | in_progress | completed | cancelled` +- `lead_agent_id` uuid fk `agents.id` null +- `target_date` date null + +## 7.6 `issues` (core task entity) + +- `id` uuid pk +- `company_id` uuid fk not null +- `project_id` uuid fk `projects.id` null +- `goal_id` uuid fk `goals.id` null +- `parent_id` uuid fk `issues.id` null +- `title` text not null +- `description` text null +- `status` enum: `backlog | todo | in_progress | in_review | done | blocked | cancelled` +- `priority` enum: `critical | high | medium | low` +- `assignee_agent_id` uuid fk `agents.id` null +- `created_by_agent_id` uuid fk `agents.id` null +- `created_by_user_id` uuid fk `users.id` null +- `request_depth` int not null default 0 +- `billing_code` text null +- `started_at` timestamptz null +- `completed_at` timestamptz null +- `cancelled_at` timestamptz null + +Invariants: + +- single assignee only +- task must trace to company goal chain via `goal_id`, `parent_id`, or project-goal linkage +- `in_progress` requires assignee +- terminal states: `done | cancelled` + +## 7.7 `issue_comments` + +- `id` uuid pk +- `company_id` uuid fk not null +- `issue_id` uuid fk `issues.id` not null +- `author_agent_id` uuid fk `agents.id` null +- `author_user_id` uuid fk `users.id` null +- `body` text not null + +## 7.8 `heartbeat_runs` + +- `id` uuid pk +- `company_id` uuid fk not null +- `agent_id` uuid fk not null +- `invocation_source` enum: `scheduler | manual | callback` +- `status` enum: `queued | running | succeeded | failed | cancelled | timed_out` +- `started_at` timestamptz null +- `finished_at` timestamptz null +- `error` text null +- `external_run_id` text null +- `context_snapshot` jsonb null + +## 7.9 `cost_events` + +- `id` uuid pk +- `company_id` uuid fk not null +- `agent_id` uuid fk `agents.id` not null +- `issue_id` uuid fk `issues.id` null +- `project_id` uuid fk `projects.id` null +- `goal_id` uuid fk `goals.id` null +- `billing_code` text null +- `provider` text not null +- `model` text not null +- `input_tokens` int not null default 0 +- `output_tokens` int not null default 0 +- `cost_cents` int not null +- `occurred_at` timestamptz not null + +Invariant: each event must attach to agent and company; rollups are aggregation, never manually edited. + +## 7.10 `approvals` + +- `id` uuid pk +- `company_id` uuid fk not null +- `type` enum: `hire_agent | approve_ceo_strategy` +- `requested_by_agent_id` uuid fk `agents.id` null +- `requested_by_user_id` uuid fk `users.id` null +- `status` enum: `pending | approved | rejected | cancelled` +- `payload` jsonb not null +- `decision_note` text null +- `decided_by_user_id` uuid fk `users.id` null +- `decided_at` timestamptz null + +## 7.11 `activity_log` + +- `id` uuid pk +- `company_id` uuid fk not null +- `actor_type` enum: `agent | user | system` +- `actor_id` uuid/text not null +- `action` text not null +- `entity_type` text not null +- `entity_id` uuid/text not null +- `details` jsonb null +- `created_at` timestamptz not null default now() + +## 7.12 Required Indexes + +- `agents(company_id, status)` +- `agents(company_id, reports_to)` +- `issues(company_id, status)` +- `issues(company_id, assignee_agent_id, status)` +- `issues(company_id, parent_id)` +- `issues(company_id, project_id)` +- `cost_events(company_id, occurred_at)` +- `cost_events(company_id, agent_id, occurred_at)` +- `heartbeat_runs(company_id, agent_id, started_at desc)` +- `approvals(company_id, status, type)` +- `activity_log(company_id, created_at desc)` + +## 8. State Machines + +## 8.1 Agent Status + +Allowed transitions: + +- `idle -> running` +- `running -> idle` +- `running -> error` +- `error -> idle` +- `idle -> paused` +- `running -> paused` (requires cancel flow) +- `paused -> idle` +- `* -> terminated` (board only, irreversible) + +## 8.2 Issue Status + +Allowed transitions: + +- `backlog -> todo | cancelled` +- `todo -> in_progress | blocked | cancelled` +- `in_progress -> in_review | blocked | done | cancelled` +- `in_review -> in_progress | done | cancelled` +- `blocked -> todo | in_progress | cancelled` +- terminal: `done`, `cancelled` + +Side effects: + +- entering `in_progress` sets `started_at` if null +- entering `done` sets `completed_at` +- entering `cancelled` sets `cancelled_at` + +## 8.3 Approval Status + +- `pending -> approved | rejected | cancelled` +- terminal after decision + +## 9. Auth and Permissions + +## 9.1 Board Auth + +- Session-based auth for human operator +- Board has full read/write across all companies in deployment +- Every board mutation writes to `activity_log` + +## 9.2 Agent Auth + +- Bearer API key mapped to one agent and company +- Agent key scope: + - read org/task/company context for own company + - read/write own assigned tasks and comments + - create tasks/comments for delegation + - report heartbeat status + - report cost events +- Agent cannot: + - bypass approval gates + - modify company-wide budgets directly + - mutate auth/keys + +## 9.3 Permission Matrix (V1) + +| Action | Board | Agent | +|---|---|---| +| Create company | yes | no | +| Hire/create agent | yes (direct) | request via approval | +| Pause/resume agent | yes | no | +| Create/update task | yes | yes | +| Force reassign task | yes | limited | +| Approve strategy/hire requests | yes | no | +| Report cost | yes | yes | +| Set company budget | yes | no | +| Set subordinate budget | yes | yes (manager subtree only) | + +## 10. API Contract (REST) + +All endpoints are under `/api` and return JSON. + +## 10.1 Companies + +- `GET /companies` +- `POST /companies` +- `GET /companies/:companyId` +- `PATCH /companies/:companyId` +- `POST /companies/:companyId/archive` + +## 10.2 Goals + +- `GET /companies/:companyId/goals` +- `POST /companies/:companyId/goals` +- `GET /goals/:goalId` +- `PATCH /goals/:goalId` +- `DELETE /goals/:goalId` (soft delete optional, hard delete board-only) + +## 10.3 Agents + +- `GET /companies/:companyId/agents` +- `POST /companies/:companyId/agents` +- `GET /agents/:agentId` +- `PATCH /agents/:agentId` +- `POST /agents/:agentId/pause` +- `POST /agents/:agentId/resume` +- `POST /agents/:agentId/terminate` +- `POST /agents/:agentId/keys` (create API key) +- `POST /agents/:agentId/heartbeat/invoke` + +## 10.4 Tasks (Issues) + +- `GET /companies/:companyId/issues` +- `POST /companies/:companyId/issues` +- `GET /issues/:issueId` +- `PATCH /issues/:issueId` +- `POST /issues/:issueId/checkout` +- `POST /issues/:issueId/release` +- `POST /issues/:issueId/comments` +- `GET /issues/:issueId/comments` + +### 10.4.1 Atomic Checkout Contract + +`POST /issues/:issueId/checkout` request: + +```json +{ + "agentId": "uuid", + "expectedStatuses": ["todo", "backlog", "blocked"] +} +``` + +Server behavior: + +1. single SQL update with `WHERE id = ? AND status IN (?) AND (assignee_agent_id IS NULL OR assignee_agent_id = :agentId)` +2. if updated row count is 0, return `409` with current owner/status +3. successful checkout sets `assignee_agent_id`, `status = in_progress`, and `started_at` + +## 10.5 Projects + +- `GET /companies/:companyId/projects` +- `POST /companies/:companyId/projects` +- `GET /projects/:projectId` +- `PATCH /projects/:projectId` + +## 10.6 Approvals + +- `GET /companies/:companyId/approvals?status=pending` +- `POST /companies/:companyId/approvals` +- `POST /approvals/:approvalId/approve` +- `POST /approvals/:approvalId/reject` + +## 10.7 Cost and Budgets + +- `POST /companies/:companyId/cost-events` +- `GET /companies/:companyId/costs/summary` +- `GET /companies/:companyId/costs/by-agent` +- `GET /companies/:companyId/costs/by-project` +- `PATCH /companies/:companyId/budgets` +- `PATCH /agents/:agentId/budgets` + +## 10.8 Activity and Dashboard + +- `GET /companies/:companyId/activity` +- `GET /companies/:companyId/dashboard` + +Dashboard payload must include: + +- active/running/paused/error agent counts +- open/in-progress/blocked/done issue counts +- month-to-date spend and budget utilization +- pending approvals count +- stale task count + +## 10.9 Error Semantics + +- `400` validation error +- `401` unauthenticated +- `403` unauthorized +- `404` not found +- `409` state conflict (checkout conflict, invalid transition) +- `422` semantic rule violation +- `500` server error + +## 11. Heartbeat and Adapter Contract + +## 11.1 Adapter Interface + +```ts +interface AgentAdapter { + invoke(agent: Agent, context: InvocationContext): Promise; + status(run: HeartbeatRun): Promise; + cancel(run: HeartbeatRun): Promise; +} +``` + +## 11.2 Process Adapter + +Config shape: + +```json +{ + "command": "string", + "args": ["string"], + "cwd": "string", + "env": {"KEY": "VALUE"}, + "timeoutSec": 900, + "graceSec": 15 +} +``` + +Behavior: + +- spawn child process +- stream stdout/stderr to run logs +- mark run status on exit code/timeout +- cancel sends SIGTERM then SIGKILL after grace + +## 11.3 HTTP Adapter + +Config shape: + +```json +{ + "url": "https://...", + "method": "POST", + "headers": {"Authorization": "Bearer ..."}, + "timeoutMs": 15000, + "payloadTemplate": {"agentId": "{{agent.id}}", "runId": "{{run.id}}"} +} +``` + +Behavior: + +- invoke by outbound HTTP request +- 2xx means accepted +- non-2xx marks failed invocation +- optional callback endpoint allows asynchronous completion updates + +## 11.4 Context Delivery + +- `thin`: send IDs and pointers only; agent fetches context via API +- `fat`: include current assignments, goal summary, budget snapshot, and recent comments + +## 11.5 Scheduler Rules + +Per-agent schedule fields in `adapter_config`: + +- `enabled` boolean +- `intervalSec` integer (minimum 30) +- `maxConcurrentRuns` fixed at `1` for V1 + +Scheduler must skip invocation when: + +- agent is paused/terminated +- an existing run is active +- hard budget limit has been hit + +## 12. Governance and Approval Flows + +## 12.1 Hiring + +1. Agent or board creates `approval(type=hire_agent, status=pending, payload=agent draft)`. +2. Board approves or rejects. +3. On approval, server creates agent row and initial API key (optional). +4. Decision is logged in `activity_log`. + +Board can bypass request flow and create agents directly via UI; direct create is still logged as a governance action. + +## 12.2 CEO Strategy Approval + +1. CEO posts strategy proposal as `approval(type=approve_ceo_strategy)`. +2. Board reviews payload (plan text, initial structure, high-level tasks). +3. Approval unlocks execution state for CEO-created delegated work. + +Before first strategy approval, CEO may only draft tasks, not transition them to active execution states. + +## 12.3 Board Override + +Board can at any time: + +- pause/resume/terminate any agent +- reassign or cancel any task +- edit budgets and limits +- approve/reject/cancel pending approvals + +## 13. Cost and Budget System + +## 13.1 Budget Layers + +- company monthly budget +- agent monthly budget +- optional project budget (if configured) + +## 13.2 Enforcement Rules + +- soft alert default threshold: 80% +- hard limit: at 100%, trigger: + - set agent status to `paused` + - block new checkout/invocation for that agent + - emit high-priority activity event + +Board may override by raising budget or explicitly resuming agent. + +## 13.3 Cost Event Ingestion + +`POST /companies/:companyId/cost-events` body: + +```json +{ + "agentId": "uuid", + "issueId": "uuid", + "provider": "openai", + "model": "gpt-5", + "inputTokens": 1234, + "outputTokens": 567, + "costCents": 89, + "occurredAt": "2026-02-17T20:25:00Z", + "billingCode": "optional" +} +``` + +Validation: + +- non-negative token counts +- `costCents >= 0` +- company ownership checks for all linked entities + +## 13.4 Rollups + +Read-time aggregate queries are acceptable for V1. +Materialized rollups can be added later if query latency exceeds targets. + +## 14. UI Requirements (Board App) + +V1 UI routes: + +- `/` dashboard +- `/companies` company list/create +- `/companies/:id/org` org chart and agent status +- `/companies/:id/tasks` task list/kanban +- `/companies/:id/agents/:agentId` agent detail +- `/companies/:id/costs` cost and budget dashboard +- `/companies/:id/approvals` pending/history approvals +- `/companies/:id/activity` audit/event stream + +Required UX behaviors: + +- global company selector +- quick actions: pause/resume agent, create task, approve/reject request +- conflict toasts on atomic checkout failure +- clear stale-task indicators +- no silent background failures; every failed run visible in UI + +## 15. Operational Requirements + +## 15.1 Environment + +- Node 20+ +- `DATABASE_URL` optional +- if unset, auto-use PGlite and push schema + +## 15.2 Migrations + +- Drizzle migrations are source of truth +- no destructive migration in-place for V1 upgrade path +- provide migration script from existing minimal tables to company-scoped schema + +## 15.3 Logging and Audit + +- structured logs (JSON in production) +- request ID per API call +- every mutation writes `activity_log` + +## 15.4 Reliability Targets + +- API p95 latency under 250 ms for standard CRUD at 1k tasks/company +- heartbeat invoke acknowledgement under 2 s for process adapter +- no lost approval decisions (transactional writes) + +## 16. Security Requirements + +- store only hashed agent API keys +- redact secrets in logs (`adapter_config`, auth headers, env vars) +- CSRF protection for board session endpoints +- rate limit auth and key-management endpoints +- strict company boundary checks on every entity fetch/mutation + +## 17. Testing Strategy + +## 17.1 Unit Tests + +- state transition guards (agent, issue, approval) +- budget enforcement rules +- adapter invocation/cancel semantics + +## 17.2 Integration Tests + +- atomic checkout conflict behavior +- approval-to-agent creation flow +- cost ingestion and rollup correctness +- pause while run is active (graceful cancel then force kill) + +## 17.3 End-to-End Tests + +- board creates company -> hires CEO -> approves strategy -> CEO receives work +- agent reports cost -> budget threshold reached -> auto-pause occurs +- task delegation across teams with request depth increment + +## 17.4 Regression Suite Minimum + +A release candidate is blocked unless these pass: + +1. auth boundary tests +2. checkout race test +3. hard budget stop test +4. agent pause/resume test +5. dashboard summary consistency test + +## 18. Delivery Plan + +## Milestone 1: Company Core and Auth + +- add `companies` and company scoping to existing entities +- add board session auth and agent API keys +- migrate existing API routes to company-aware paths + +## Milestone 2: Task and Governance Semantics + +- implement atomic checkout endpoint +- implement issue comments and lifecycle guards +- implement approvals table and hire/strategy workflows + +## Milestone 3: Heartbeat and Adapter Runtime + +- implement adapter interface +- ship `process` adapter with cancel semantics +- ship `http` adapter with timeout/error handling +- persist heartbeat runs and statuses + +## Milestone 4: Cost and Budget Controls + +- implement cost events ingestion +- implement monthly rollups and dashboards +- enforce hard limit auto-pause + +## Milestone 5: Board UI Completion + +- add company selector and org chart view +- add approvals and cost pages +- add operational dashboard and stale-task surfacing + +## Milestone 6: Hardening and Release + +- full integration/e2e suite +- seed/demo company templates for local testing +- release checklist and docs update + +## 19. Acceptance Criteria (Release Gate) + +V1 is complete only when all criteria are true: + +1. A board user can create multiple companies and switch between them. +2. A company can run at least one active heartbeat-enabled agent. +3. Task checkout is conflict-safe with `409` on concurrent claims. +4. Agents can update tasks/comments and report costs with API keys only. +5. Board can approve/reject hire and CEO strategy requests in UI. +6. Budget hard limit auto-pauses an agent and prevents new invocations. +7. Dashboard shows accurate counts/spend from live DB data. +8. Every mutation is auditable in activity log. +9. App runs with embedded PGlite by default and with external Postgres via `DATABASE_URL`. + +## 20. Post-V1 Backlog (Explicitly Deferred) + +- plugin architecture +- richer workflow-state customization per team +- milestones/labels/dependency graph depth beyond V1 minimum +- realtime transport optimization (SSE/WebSockets) +- public template marketplace integration (ClipHub) diff --git a/SPEC.md b/doc/SPEC.md similarity index 100% rename from SPEC.md rename to doc/SPEC.md diff --git a/doc/specs/ui.md b/doc/specs/ui.md new file mode 100644 index 00000000..c7779393 --- /dev/null +++ b/doc/specs/ui.md @@ -0,0 +1,1001 @@ +# Paperclip UI Spec + +Status: Draft +Date: 2026-02-17 + +## 1. Design Philosophy + +Paperclip's UI is a professional-grade control plane, not a toy dashboard. It should feel like the kind of tool you live in all day — fast, keyboard-driven, information-dense without being cluttered, dark-themed by default. Every pixel should earn its place. + +Design principles: + +- **Dense but scannable.** Show maximum information without requiring clicks to reveal it. Use whitespace to separate, not to pad. +- **Keyboard-first.** Global shortcuts for search (Cmd+K), new issue (C), navigation. Power users should rarely touch the mouse. +- **Contextual, not modal.** Inline editing over dialog boxes. Dropdowns over page navigations. The user's mental context should never be broken unnecessarily. +- **Dark theme default.** Neutral grays, not pure black. Accent colors used sparingly for status and priority. Text is the primary visual element. + +### Color System + +- **Background:** `hsl(220, 13%, 10%)` (dark charcoal, not pure black) +- **Surface/Card:** `hsl(220, 13%, 13%)` +- **Border:** `hsl(220, 10%, 18%)` +- **Text primary:** `hsl(220, 10%, 90%)` +- **Text secondary:** `hsl(220, 10%, 55%)` +- **Accent (interactive):** `hsl(220, 80%, 60%)` (muted blue) + +Status colors (consistent across all entities): +- **Backlog:** gray `hsl(220, 10%, 45%)` +- **Todo:** gray-blue `hsl(220, 20%, 55%)` +- **In Progress:** yellow `hsl(45, 90%, 55%)` +- **In Review:** violet `hsl(270, 60%, 60%)` +- **Done:** green `hsl(140, 60%, 50%)` +- **Cancelled:** gray `hsl(220, 10%, 40%)` +- **Blocked:** amber `hsl(25, 90%, 55%)` + +Priority indicators: +- **Critical:** red circle, filled +- **High:** orange circle, half-filled +- **Medium:** yellow circle, outline +- **Low:** gray circle, outline, dashed + +### Typography + +- **Font:** System font stack (Inter if loaded, else `-apple-system, BlinkMacSystemFont, 'Segoe UI'`) +- **Body:** 13px / 1.5 line-height +- **Labels/metadata:** 11px / uppercase tracking +- **Headings:** 14-18px / semi-bold, never all-caps + +### Icons + +Use `lucide-react` throughout. Every sidebar item, every status indicator, every action button should have an icon. Icons are 16px in nav, 14px inline. + +--- + +## 2. Application Shell + +The app is a three-zone layout: + +``` +┌──────────┬────────────────────────────────────────────────┐ +│ │ Breadcrumb bar │ +│ Sidebar ├──────────────────────────┬─────────────────────┤ +│ (240px) │ Main content │ Properties panel │ +│ │ (flex-1) │ (320px, optional) │ +│ │ │ │ +└──────────┴──────────────────────────┴─────────────────────┘ +``` + +- **Sidebar:** Fixed left, 240px. Collapsible to icon-only (48px) via toggle or keyboard shortcut. +- **Breadcrumb bar:** Spans the full width above main+properties. Shows navigation path, entity actions, and view controls. +- **Main content:** Scrollable. Contains the primary view (list, detail, chart, etc). +- **Properties panel:** Right side, 320px. Shown on detail views (issue detail, project detail, agent detail). Hidden on list views and dashboard. Resizable. + +The properties panel slides in when you click into a detail view and slides out when you go back to a list. It is NOT a sidebar — it's contextual to the selected entity. + +--- + +## 3. Sidebar + +The sidebar is the primary navigation. It is grouped into logical sections with collapsible headers. + +### 3.1 Company Header + +Top of sidebar. Always visible. + +``` +┌─────────────────────────┐ +│ [icon] Acme Corp ▼ │ ← Company switcher dropdown +├─────────────────────────┤ +│ [🔍] [✏️] │ ← Search + New Issue +└─────────────────────────┘ +``` + +**Company switcher** is a dropdown button that occupies the full width of the sidebar header. It shows: +- Company icon (first letter avatar with company color, or uploaded icon) +- Company name (truncated with ellipsis if long) +- Chevron-down icon + +Clicking opens a dropdown with: +- List of all companies (with status dot: green=active, yellow=paused, gray=archived) +- Search field at top of dropdown (for users with many companies) +- Divider +- `+ Create company` action at the bottom + +Below the company name, a row of icon buttons: +- **Search** (magnifying glass icon) — opens Cmd+K search modal +- **New Issue** (pencil/square-pen icon) — opens new issue modal in the current company context + +### 3.2 Personal Section + +No section header — these are always at the top, below the company header. + +``` + Inbox 3 + My Issues +``` + +- **Inbox** — items requiring the board operator's attention. Badge count on the right. Includes: pending approvals, stale tasks, budget alerts, failed heartbeats. The number is the total unread/unresolved count. +- **My Issues** — issues created by or assigned to the board operator. + +### 3.3 Work Section + +Section header: **Work** (collapsible, with a chevron toggle) + +``` + Work ▼ + Issues + Projects + Goals + Views +``` + +- **Issues** — main task list for the selected company. This is the workhorse view. +- **Projects** — project list. Projects group issues and link to goals. +- **Goals** — company goal hierarchy. +- **Views** — saved filter/sort configurations (e.g., "Critical bugs", "Unassigned tasks", "CEO's tasks"). Users can create, name, and pin custom views here. + +### 3.4 Company Section + +Section header: **Company** (collapsible) + +``` + Company ▼ + Dashboard + Org Chart + Agents + Costs + Activity +``` + +- **Dashboard** — company health overview: agent statuses, task velocity, cost burn, pending approvals count. +- **Org Chart** — interactive tree visualization of the agent reporting hierarchy. +- **Agents** — flat list of all agents with status, role, last heartbeat, spend. +- **Costs** — cost dashboard with breakdowns by agent, project, model, time. +- **Activity** — audit log of all system events. + +Note: Approvals do not have a top-level sidebar entry. They are surfaced through the **Inbox** (primary interaction point), **Dashboard** (pending count metric), and **inline on entity pages** (e.g., an agent detail page shows the approval that authorized its hire). The `/approvals` route still exists and is reachable via "See all approvals" links in Inbox and Dashboard, but it is not in the sidebar navigation. + +### 3.5 Section Behavior + +- Each section header is clickable to collapse/expand its children. +- Collapsed state persists in localStorage. +- Active nav item is highlighted with a left-border accent and background tint. +- Hovering a nav item shows a subtle background highlight. +- Badge counts are right-aligned, rendered as small pills (e.g., `3` in a rounded rect). +- Icons are 16px, left-aligned, with 8px gap to label text. + +### 3.6 Sidebar Icons + +Each nav item has a distinctive icon (lucide-react): + +| Item | Icon | +|------|------| +| Inbox | `Inbox` | +| My Issues | `CircleUser` | +| Issues | `CircleDot` | +| Projects | `Hexagon` | +| Goals | `Target` | +| Views | `LayoutList` | +| Dashboard | `LayoutDashboard` | +| Org Chart | `GitBranch` | +| Agents | `Bot` | +| Costs | `DollarSign` | +| Activity | `History` | + +--- + +## 4. Breadcrumb Bar + +The breadcrumb bar sits above the main content and properties panel. It serves as both navigation and context indicator. + +### 4.1 Structure + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Projects › Paperclip › Issues › CLIP-42 [⭐] [···] [🔔] [⬜] │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +**Left side:** +- Breadcrumb segments, separated by `›` chevrons. +- Each segment is clickable to navigate to that level. +- Current segment is non-clickable, slightly bolder text. +- Star icon to favorite/pin the current entity. +- Three-dot menu for entity actions (delete, archive, duplicate, copy link, etc.) + +**Right side:** +- Notification bell (if in a detail view — subscribe to changes on this entity) +- Panel toggle (show/hide the right properties panel) + +### 4.2 View-Specific Tabs + +On certain detail pages, the breadcrumb bar also contains a tab row below the breadcrumbs: + +**Project detail:** +``` + Overview Updates Issues Settings +``` + +**Agent detail:** +``` + Overview Heartbeats Issues Costs +``` + +Tabs are rendered as pill-shaped buttons. Active tab has a subtle background fill. + +--- + +## 5. Issues (Task Management) + +Issues are the core work unit. This section details the full issue experience. + +### 5.1 Issue List View + +The issue list is the default view when clicking "Issues" in the sidebar. + +**Layout:** +``` +┌─────────────────────────────────────────────────────────────────┐ +│ [All Issues] [Active] [Backlog] [⚙ Settings] [≡ Filter] [Display ▼] │ +├─────────────────────────────────────────────────────────────────┤ +│ ▼ Todo 3 [+] │ +│ ☐ --- CLIP-5 ○ Implement user auth @CTO Feb 16 │ +│ ☐ --- CLIP-3 ○ Set up CI pipeline @DevOps Feb 16 │ +│ ☐ --- CLIP-8 ○ Write API documentation @Writer Feb 17 │ +│ │ +│ ▼ In Progress 2 [+] │ +│ ☐ !!! CLIP-1 ◐ Build landing page @FE Feb 15 │ +│ ☐ --- CLIP-4 ◐ Database schema design @CTO Feb 14 │ +│ │ +│ ▼ Backlog 5 [+] │ +│ ☐ --- CLIP-9 ◌ Research competitors Feb 17 │ +│ ... │ +└─────────────────────────────────────────────────────────────────┘ +``` + +**Top toolbar:** +- **Status tabs:** `All Issues`, `Active` (todo + in_progress + in_review + blocked), `Backlog`. Each tab shows a status icon and count. Active tab is filled, others outlined. +- **Settings gear:** Configure issue display defaults, custom fields. +- **Filter button:** Opens a filter bar below the toolbar. +- **Display dropdown:** Toggle between grouping modes (by status, by priority, by assignee, by project, none) and layout modes (list, board/kanban). + +**Grouping:** +- Issues are grouped by status by default (matching the reference screenshots). +- Each group header shows: collapse chevron, status icon, status name, count, and a `+` button to create a new issue in that status. +- Groups are collapsible. Collapsed groups show just the header with count. + +**Issue rows:** +Each row contains, left to right: +1. **Checkbox** — for bulk selection. Hidden by default, appears on hover (left of priority). +2. **Priority indicator** — icon representing critical/high/medium/low (see Color System above). Always visible. +3. **Issue key** — e.g., `CLIP-5`. Monospace, muted color. The prefix is derived from the project (or company if no project). +4. **Status circle** — clickable to open status change dropdown (same as reference screenshot). The circle's fill/color reflects current status. +5. **Title** — primary text, truncated with ellipsis if too long. +6. **Assignee** — avatar (agent icon) + agent name, right-aligned. If unassigned, shows a dashed circle placeholder. +7. **Date** — creation date or target date, muted text, far right. + +**Row interactions:** +- Click row → navigate to issue detail view. +- Click status circle → opens inline status dropdown (Backlog, Todo, In Progress, In Review, Done, Cancelled) with keyboard numbers as shortcuts (1-6). +- Click checkbox → selects for bulk actions. When any checkbox is selected, a bulk action bar appears at the bottom of the list. +- Hover → shows checkbox, and row gets subtle background highlight. +- Right-click → context menu (same actions as three-dot menu). + +**Bulk action bar:** +When one or more issues are selected, a floating bar appears at the bottom: +``` +┌─────────────────────────────────────────────────────────┐ +│ 3 selected [Status ▼] [Priority ▼] [Assignee ▼] [Project ▼] [🗑 Delete] [✕ Cancel] │ +└─────────────────────────────────────────────────────────┘ +``` + +### 5.2 Issue Filter Bar + +Clicking "Filter" reveals a filter bar below the toolbar: + +``` +┌─────────────────────────────────────────────────────────┐ +│ [+ Add filter] Status is Todo, In Progress [×] │ +│ Priority is Critical, High [×] │ +│ Assignee is CTO-Agent [×] │ +└─────────────────────────────────────────────────────────┘ +``` + +- Each filter is a chip showing `field operator value`. +- Click a chip to edit it. +- `×` removes the filter. +- `+ Add filter` opens a dropdown of available fields: Status, Priority, Assignee, Project, Goal, Created date, Labels, Creator. +- Filters are AND-composed. +- Active filters persist in the URL query string so they're shareable/bookmarkable. + +### 5.3 Issue Detail View (Three-Pane) + +Clicking an issue opens the detail view. The main content area splits into two zones, with the sidebar still visible on the left. + +``` +┌──────────┬────────────────────────────────┬──────────────────────┐ +│ │ Issues › CLIP-42 │ │ +│ Sidebar │ │ Properties [+] │ +│ │ Fix user authentication bug │ │ +│ │ Implement proper token... │ Status In Progress │ +│ │ │ Priority High │ +│ │ ┌──────────────────────────┐ │ Assignee CTO │ +│ │ │ Properties bar (inline) │ │ Project Auth │ +│ │ │ In Progress · High · │ │ Goal Security │ +│ │ │ CTO · Auth project · ... │ │ Labels bug, auth│ +│ │ └──────────────────────────┘ │ Start Feb 15 │ +│ │ │ Target Feb 20 │ +│ │ Description │ Created Feb 14 │ +│ │ ───────────────── │ │ +│ │ The current authentication │ ───────────────── │ +│ │ system has a token refresh... │ Activity │ +│ │ │ CTO commented 2h │ +│ │ Comments │ Status → In Prog │ +│ │ ───────────────── │ Created by Board │ +│ │ [avatar] CTO · 2 hours ago │ │ +│ │ I've identified the root... │ │ +│ │ │ │ +│ │ [avatar] DevOps · 1 hour ago │ │ +│ │ The CI is set up to run... │ │ +│ │ │ │ +│ │ ┌──────────────────────────┐ │ │ +│ │ │ Write a comment... │ │ │ +│ │ └──────────────────────────┘ │ │ +└──────────┴────────────────────────────────┴──────────────────────┘ +``` + +#### Middle Pane (Main Content) + +**Header area:** +- Issue title, large (18px, semi-bold), editable on click (inline editing). +- Subtitle: issue key `CLIP-42` in muted text. +- Below the title: inline properties bar showing key properties as clickable chips (same pattern as reference screenshots): `[○ In Progress] [!!! High] [👤 CTO] [📅 Target date] [📁 Auth] [···]`. Each chip is clickable to change that property inline. + +**Description:** +- Markdown-rendered description. +- Click to edit — opens a markdown editor in-place. +- Support for headings, lists, code blocks, links, images. + +**Subtasks (if any):** +- Listed below description as a collapsible section. +- Each subtask is a mini issue row (status circle + title + assignee). +- `+ Add subtask` button at the bottom. + +**Comments:** +- Chronological list of comments. +- Each comment shows: author avatar/icon, author name, timestamp, body (markdown rendered). +- Comment input at the bottom — a text area with markdown support and a "Comment" button. +- Comments from agents show a bot icon; comments from the board show a user icon. + +#### Right Pane (Properties Panel) + +**Header:** "Properties" label with a `+` button to add a custom field. + +**Property list:** Each property is a row with label on the left and editable value on the right. + +| Property | Control | +|----------|---------| +| Status | Dropdown with status options + colored dot | +| Priority | Dropdown with priority options + icon | +| Assignee | Agent picker dropdown with search | +| Project | Project picker dropdown | +| Goal | Goal picker dropdown | +| Labels | Multi-select tag input | +| Lead | Agent picker | +| Members | Multi-select agent picker | +| Start date | Date picker | +| Target date | Date picker | +| Created by | Read-only text | +| Created | Read-only timestamp | +| Billing code | Text input | + +Below properties, a divider, then: + +**Activity section:** +- "Activity" header with "See all" link. +- Compact timeline of recent events: status changes, assignment changes, comments, etc. +- Each entry: icon + description + relative timestamp. + +### 5.4 New Issue Modal + +Triggered by the sidebar pencil icon, keyboard shortcut `C`, or the `+` buttons in the issue list. + +``` +┌─────────────────────────────────────────────────────────┐ +│ [📁 CLIP] › New issue [Save as draft] [↗] [×] │ +├─────────────────────────────────────────────────────────┤ +│ │ +│ Issue title │ +│ ___________________________________________________ │ +│ │ +│ Add a description... │ +│ │ +│ │ +│ │ +│ │ +├─────────────────────────────────────────────────────────┤ +│ [○ Todo] [--- Priority] [👤 Assignee] [📁 Project] │ +│ [🏷 Labels] [···] │ +├─────────────────────────────────────────────────────────┤ +│ [📎] [◻ Create more] [Create issue] │ +└─────────────────────────────────────────────────────────┘ +``` + +**Top bar:** +- Breadcrumb showing context: project key (or company key) `›` "New issue". +- "Save as draft" button. +- Expand icon (open as full page instead of modal). +- Close `×`. + +**Body:** +- Title field: large input, placeholder "Issue title". Auto-focused on open. +- Description: markdown editor below, placeholder "Add a description...". Expandable. + +**Property chips (bottom bar):** +- Compact row of property buttons. Each opens a dropdown to set that property. +- Default chips shown: Status (defaults to Todo), Priority, Assignee, Project, Labels. +- `···` more button reveals: Goal, Start date, Target date, Billing code, Parent issue. + +**Footer:** +- Attachment button (paperclip icon). +- "Create more" toggle — when on, creating an issue clears the form and stays open for rapid entry. +- "Create issue" primary button. + +**Behavior:** +- `Cmd+Enter` submits the form. +- If opened from within a project context, the project is pre-filled. +- If opened from a specific status group's `+` button, that status is pre-filled. +- The slug/key is auto-generated from the project prefix + incrementing number (shown in breadcrumb). + +### 5.5 Issue Board View (Kanban) + +Accessible via Display dropdown → Board layout. + +Columns represent statuses: Backlog | Todo | In Progress | In Review | Done + +Each card shows: +- Issue key (muted) +- Title (primary text) +- Priority icon (bottom-left) +- Assignee avatar (bottom-right) + +Cards are draggable between columns. Dragging a card to a new column changes its status (with transition validation — invalid transitions show an error toast). + +Each column header has a `+` button to create a new issue in that status. + +--- + +## 6. Projects + +### 6.1 Project List View + +Similar to the issue list but for projects. + +``` +┌─────────────────────────────────────────────────────────┐ +│ Projects [+ New project] │ +├─────────────────────────────────────────────────────────┤ +│ [icon] Paperclip Auth Backlog CTO Feb 20 │ +│ [icon] Marketing Site In Progress CMO Mar 01 │ +│ [icon] API v2 Planned CTO Mar 15 │ +└─────────────────────────────────────────────────────────┘ +``` + +Each row: project icon (colored hexagon), name, status badge, lead agent, target date. + +### 6.2 Project Detail View (Three-Pane) + +Uses the same three-pane layout as issue detail. + +**Breadcrumb tabs:** Overview | Updates | Issues | Settings + +**Overview tab (middle pane):** +- Project icon + name (editable) +- Description (markdown, editable) +- Inline properties bar: `[◌ Backlog] [--- No priority] [👤 Lead] [📅 Target date] [🏢 Team] [···]` +- "Resources" section: linked documents, URLs +- "Write first project update" CTA (for project updates/status posts) +- Description (markdown body) +- Milestones section (collapsible): list of milestone markers with date and status + +**Issues tab:** filtered issue list showing only issues in this project. Same controls as the main issues view. + +**Right pane (properties):** Status, Priority, Lead, Members, Start date, Target date, Teams, Labels, Goal link. + +**Activity section:** at the bottom of the properties panel. + +--- + +## 7. Goals + +### 7.1 Goal List View + +Goals are displayed as a hierarchical tree, since goals have parent-child relationships. + +``` +┌─────────────────────────────────────────────────────────┐ +│ Goals [+ New goal] │ +├─────────────────────────────────────────────────────────┤ +│ ▼ 🎯 Build the #1 AI note-taking app Company Active│ +│ ▼ 🎯 Grow signups to 10k Team Active│ +│ 🎯 Launch marketing campaign Agent Planned │ +│ 🎯 Optimize onboarding funnel Agent Planned │ +│ ▼ 🎯 Ship v2.0 with AI features Team Active│ +│ 🎯 Implement smart search Task Planned │ +│ 🎯 Build auto-summarization Task Planned │ +└─────────────────────────────────────────────────────────┘ +``` + +Each row: expand chevron (if has children), target icon, title, level badge (Company/Team/Agent/Task), status badge. + +Indentation reflects hierarchy. Clicking a goal opens its detail view. + +### 7.2 Goal Detail View + +Three-pane layout. Middle pane shows title, description, child goals, and linked projects. Right pane shows properties (level, status, owner agent, parent goal) and activity. + +--- + +## 8. Dashboard + +The dashboard is the company health overview. Shown when clicking "Dashboard" in the Company section. + +### 8.1 Layout + +``` +┌──────────┬──────────────────────────────────────────────┐ +│ │ Dashboard │ +│ Sidebar │ │ +│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────┐│ +│ │ │ Agents │ │ Tasks │ │ Costs │ │Apprvl││ +│ │ │ 12 total │ │ 47 open │ │ $234.50 │ │ 3 ││ +│ │ │ 8 active │ │ 12 prog │ │ 67% bud │ │pending│ +│ │ │ 2 paused │ │ 3 block │ │ │ │ ││ +│ │ │ 1 error │ │ 28 done │ │ │ │ ││ +│ │ └─────────┘ └─────────┘ └─────────┘ └──────┘│ +│ │ │ +│ │ ┌────────────────────┐ ┌─────────────────────┐│ +│ │ │ Recent Activity │ │ Stale Tasks ││ +│ │ │ ... │ │ ... ││ +│ │ └────────────────────┘ └─────────────────────┘│ +└──────────┴──────────────────────────────────────────────┘ +``` + +**Top row: Metric cards** (4 across) +1. **Agents** — total, active, running, paused, error counts. Each with colored dots. +2. **Tasks** — open, in progress, blocked, done counts. +3. **Costs** — month-to-date spend in dollars, budget utilization percentage with a mini progress bar. +4. **Approvals** — pending count (clickable to navigate to Inbox, which is the primary approval interaction point). + +**Bottom row: Detail panels** (2 across) +5. **Recent Activity** — last ~10 activity log entries, compact timeline format. +6. **Stale Tasks** — tasks that have been in progress for too long without updates. Each shows issue key, title, assignee, time since last activity. + +All cards and panels are clickable to navigate to their respective full pages. + +--- + +## 9. Org Chart + +Interactive visualization of the agent reporting hierarchy. + +### 9.1 Tree View + +``` + ┌─────────┐ + │ CEO │ + │ running │ + └────┬────┘ + ┌────────────┼────────────┐ + ┌────┴────┐ ┌────┴────┐ ┌───┴─────┐ + │ CTO │ │ CMO │ │ CFO │ + │ active │ │ idle │ │ paused │ + └────┬────┘ └────┬────┘ └─────────┘ + ┌────┴────┐ ┌────┴────┐ + │ Dev-1 │ │ Mktg-1 │ + │ running │ │ idle │ + └─────────┘ └─────────┘ +``` + +Each node shows: +- Agent name +- Role/title (smaller text) +- Status dot (colored by agent status) +- Agent avatar (bot icon with unique color per agent) + +Nodes are clickable to navigate to agent detail. + +### 9.2 Interactions + +- Zoom/pan with mouse wheel and drag. +- Click a node to select it — shows a brief tooltip with key info (last heartbeat, current task, spend). +- Double-click a node to navigate to agent detail page. +- Right-click node for context menu: View, Pause, Resume, Invoke heartbeat, Edit. + +--- + +## 10. Agents + +### 10.1 Agent List View + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Agents [+ New agent] │ +├─────────────────────────────────────────────────────────────────┤ +│ [🤖] CEO ceo ● Running $45.20/$100 2m ago │ +│ [🤖] CTO cto ● Active $23.10/$100 5m ago │ +│ [🤖] Dev-1 engineer ○ Idle $12.40/$50 15m ago │ +│ [🤖] CMO marketing ○ Idle $8.30/$50 30m ago │ +│ [🤖] DevOps devops ⚠ Paused $31.00/$50 1h ago │ +└─────────────────────────────────────────────────────────────────┘ +``` + +Columns: Avatar/icon, Name, Role, Status (with colored dot), Cost (spent/budget this month), Last Heartbeat (relative time). + +Clicking a row navigates to agent detail. + +### 10.2 Agent Detail View (Three-Pane) + +**Breadcrumb tabs:** Overview | Heartbeats | Issues | Costs + +**Overview (middle pane):** +- Agent name + role +- Capabilities description +- Adapter type + config summary +- Current task (if any) +- Reports to: [clickable agent name] +- Direct reports: list of agents + +**Heartbeats tab:** table of heartbeat runs — time, source (manual/scheduler), status, duration, error (if any). Invoke button at top. + +**Issues tab:** issues assigned to this agent. + +**Costs tab:** cost breakdown for this agent — by model, by time period, with budget progress bar. + +**Right pane properties:** Status, Role, Title, Reports To, Adapter Type, Context Mode, Budget (monthly), Spent (monthly), Last Heartbeat. + +**Quick actions** in breadcrumb bar: [Pause] [Resume] [Invoke Heartbeat] [···] + +--- + +## 11. Approvals (Contextual, Not Standalone) + +Approvals are governance gates — decisions the board must make (hire an agent, approve a CEO strategy). They are NOT work items. Their data model stays separate from issues (different status machine, side-effect triggers, unstructured payload). But they don't need their own top-level nav entry. + +### 11.1 Where Approvals Surface + +**1. Inbox (primary).** Pending approvals are the highest-priority inbox items. The board operator sees them front and center with inline approve/reject actions (see Section 14). + +**2. Dashboard metric card.** The "Pending Approvals" card shows the count and links to the full approvals list. + +**3. Inline on entity pages.** When an entity was created via an approval, the detail page shows a contextual banner: +- Agent detail page: `"Hired via approval — requested by CEO on Feb 15"` with a link to the approval record. +- An agent in `pending` status (not yet created) could show: `"Pending approval — requested by CEO"` with approve/reject actions inline. + +**4. Activity log.** Approval events (created, approved, rejected) appear in the activity timeline like any other event. + +### 11.2 Approvals List Page (`/approvals`) + +This page still exists — it's the "See all" destination from Inbox and Dashboard. But it's not in the sidebar. + +``` +┌─────────────────────────────────────────────────────────┐ +│ Approvals [Pending] [Approved] [Rejected] [All] │ +├─────────────────────────────────────────────────────────┤ +│ 🟡 Hire Agent: "Marketing Analyst" CEO 2h ago │ +│ 🟡 CEO Strategy: "Q2 Growth Plan" CEO 4h ago │ +│ 🟢 Hire Agent: "DevOps Engineer" CTO 1d ago │ +└─────────────────────────────────────────────────────────┘ +``` + +Status tabs filter by approval status. Each row: status dot, type, title/summary (from payload), requester, relative time. + +### 11.3 Approval Detail View + +Three-pane layout. Middle pane renders the approval payload nicely based on type: + +**`hire_agent` type:** Shows proposed agent name, role, title, reports-to, capabilities, adapter config, budget. Essentially a preview of the agent that will be created. + +**`approve_ceo_strategy` type:** Shows the strategy text, proposed goal breakdown, initial task structure. + +For pending approvals, prominent action buttons at the top of the middle pane: +``` +┌─────────────────────────────────────────────────────────┐ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Decision note (optional): _________________________ │ │ +│ │ [✕ Reject] [✓ Approve] │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ │ +│ Hire Agent Request │ +│ ───────────────── │ +│ Name: Marketing Analyst │ +│ Role: marketing │ +│ Reports to: CMO │ +│ Budget: $100/month │ +│ ... │ +└─────────────────────────────────────────────────────────┘ +``` + +Right pane: Type, Status, Requested by, Requested at, Decided by, Decided at, Decision note. Activity timeline below. + +--- + +## 12. Costs + +### 12.1 Cost Dashboard + +``` +┌─────────────────────────────────────────────────────────┐ +│ Costs Feb 2026 │ +├─────────────────────────────────────────────────────────┤ +│ ┌──────────────────────────────────────────────────────┐│ +│ │ Month-to-date: $234.50 / $500.00 [====-------] 47% ││ +│ └──────────────────────────────────────────────────────┘│ +│ │ +│ By Agent By Project │ +│ ┌──────────────────────┐ ┌──────────────────────┐ │ +│ │ CEO $45.20 │ │ Auth $67.30 │ │ +│ │ CTO $23.10 │ │ Marketing $34.50 │ │ +│ │ Dev-1 $12.40 │ │ API v2 $12.00 │ │ +│ │ ... │ │ ... │ │ +│ └──────────────────────┘ └──────────────────────┘ │ +│ │ +│ Recent Cost Events │ +│ ┌──────────────────────────────────────────────────────┐│ +│ │ CEO openai/gpt-5 1,234 in / 567 out $0.89 2m ago│ +│ │ ... │ +│ └──────────────────────────────────────────────────────┘│ +└─────────────────────────────────────────────────────────┘ +``` + +Top: company-wide budget progress bar (large, prominent). + +Two side-by-side tables: breakdown by agent and by project. Each row shows entity name and spend amount. + +Bottom: recent cost events table with agent, provider/model, token counts, cost, and timestamp. + +--- + +## 13. Activity Log + +A chronological, filterable audit trail. + +``` +┌─────────────────────────────────────────────────────────┐ +│ Activity [Filter by type ▼] │ +├─────────────────────────────────────────────────────────┤ +│ 🤖 CEO created issue CLIP-12 "Fix auth" 2 min ago │ +│ 👤 Board approved hire "Marketing Analyst" 5 min ago │ +│ 🤖 CTO changed CLIP-8 status → In Progress 10 min ago │ +│ ⚙ System paused agent DevOps (budget limit) 15 min ago│ +│ 🤖 Dev-1 commented on CLIP-5 30 min ago │ +│ ... │ +└─────────────────────────────────────────────────────────┘ +``` + +Each entry: actor icon (bot for agent, user for board, gear for system), actor name, action description with entity links, relative timestamp. + +Filterable by: actor type (agent/user/system), entity type (issue/agent/project/etc), action type, time range. + +Infinite scroll with "Load more" fallback. + +--- + +## 14. Inbox + +The inbox is the board operator's primary action center. It aggregates everything that needs human attention, with approvals as the highest-priority category. + +### 14.1 Inbox List View + +``` +┌─────────────────────────────────────────────────────────┐ +│ Inbox [Mark all read] │ +├─────────────────────────────────────────────────────────┤ +│ APPROVALS See all approvals → │ +│ ● 🛡 Hire Agent: "Marketing Analyst" │ +│ │ Requested by CEO · 2h ago │ +│ │ Role: marketing · Reports to: CMO · Budget: $100/mo │ +│ │ [✕ Reject] [✓ Approve] │ +│ │ │ +│ ● 🛡 CEO Strategy: "Q2 Growth Plan" │ +│ │ Requested by CEO · 4h ago │ +│ │ [View details →] │ +│ │ +│ ALERTS │ +│ ● 🔴 Agent Error: DevOps heartbeat failed 1h ago │ +│ ● ⚠ Budget Alert: CEO at 80% monthly budget 3h ago │ +│ │ +│ STALE WORK │ +│ ⏰ CLIP-3 "Set up CI pipeline" — no update in 24h │ +│ ⏰ CLIP-7 "Write tests" — no update in 36h │ +└─────────────────────────────────────────────────────────┘ +``` + +### 14.2 Inbox Categories + +Items are grouped by category, with the most actionable items first: + +**Approvals pending** (top priority). Each approval item shows: +- Shield icon + approval type + title +- Requester + relative timestamp +- Key payload summary (1 line — agent name/role for hires, plan title for strategies) +- Inline **[Approve]** and **[Reject]** buttons for simple approvals (hire_agent). Clicking Approve/Reject shows a brief confirmation with an optional decision note field. +- **[View details →]** link for complex approvals (approve_ceo_strategy) that need full review before deciding. +- "See all approvals →" link in the category header navigates to `/approvals`. + +**Alerts.** Agent errors (failed heartbeats, error status) and budget alerts (agents or company approaching 80% or 100% limits). Each links to the relevant agent or cost page. + +**Stale work.** Tasks in `in_progress` or `todo` with no activity (no comments, no status changes) beyond a configurable threshold (default: 24h). Each shows issue key, title, and time since last activity. Clicking navigates to the issue. + +### 14.3 Inbox Behavior + +- Unread items have a filled blue dot indicator on the left. +- Clicking an item marks it as read. +- Approvals disappear from the inbox once approved/rejected (they move to the resolved state). +- Alerts disappear when the underlying condition is resolved (agent resumed, budget increased). +- The sidebar badge count reflects total unresolved inbox items. +- Inbox is computed from live data (pending approvals query + alert conditions), not a separate notification table. This keeps it simple for V1. + +--- + +## 15. Search (Cmd+K Modal) + +Global search accessible via `Cmd+K` or the sidebar search icon. + +``` +┌─────────────────────────────────────────────────────────┐ +│ 🔍 Search issues, agents, projects... │ +├─────────────────────────────────────────────────────────┤ +│ Recent │ +│ 📋 CLIP-42 Fix user authentication bug │ +│ 🤖 CEO │ +│ 📁 Auth project │ +├─────────────────────────────────────────────────────────┤ +│ Actions │ +│ ✏️ Create new issue C │ +│ 🤖 Create new agent │ +│ 📁 Create new project │ +└─────────────────────────────────────────────────────────┘ +``` + +- Type-ahead search across all entity types (issues, agents, projects, goals). +- Results grouped by type with icons. +- Recent items shown when input is empty. +- Quick actions section at the bottom. +- Arrow keys to navigate, Enter to select, Escape to close. + +--- + +## 16. Keyboard Shortcuts + +| Shortcut | Action | +|----------|--------| +| `Cmd+K` | Open search | +| `C` | Create new issue | +| `Cmd+Enter` | Submit form (in modals) | +| `Escape` | Close modal / deselect | +| `[` | Toggle sidebar collapsed | +| `]` | Toggle properties panel | +| `J` / `K` | Navigate up/down in lists | +| `Enter` | Open selected item | +| `Backspace` | Go back | +| `S` | Toggle status on selected issue | +| `X` | Toggle checkbox selection | +| `Cmd+A` | Select all (in list context) | + +--- + +## 17. Responsive Behavior + +- **>1400px:** Full three-pane layout (sidebar + main + properties). +- **1024-1400px:** Sidebar collapses to icons. Properties panel available via toggle. +- **<1024px:** Sidebar hidden (hamburger menu). Properties panel hidden (toggle or tab). + +The properties panel is always dismissible — it should never block the main content. + +--- + +## 18. Empty States + +Every list view should have a thoughtful empty state: + +- **No issues:** "No issues yet. Create your first issue to start tracking work." with a `[Create issue]` button. +- **No agents:** "No agents in this company. Create an agent to start building your team." with a `[Create agent]` button. +- **No company selected:** "Select a company to get started." with a company switcher or `[Create company]` button. + +Empty states should use a muted illustration (simple line art, not cartoons) and a single call-to-action. + +--- + +## 19. Loading and Error States + +- **Loading:** Skeleton placeholders matching the layout of the expected content (not spinners). Skeleton blocks animate with a subtle shimmer. +- **Error:** Inline error message with a retry button. Never a full-page error unless the app itself is broken. +- **Conflict (409):** Toast notification: "This issue was updated by another user. Refresh to see changes." with a [Refresh] action. +- **Optimistic updates:** Status changes and property edits should update immediately in the UI, with rollback on failure. + +--- + +## 20. Component Library + +Build on top of shadcn/ui components with these customizations: + +| Component | Base | Customization | +|-----------|------|---------------| +| StatusBadge | Badge | Colored dot + label, entity-specific palettes | +| PriorityIcon | custom | SVG circles with fills matching priority | +| EntityRow | custom | Standardized list row with hover/select states | +| PropertyEditor | custom | Label + inline-editable value with dropdown | +| CommentThread | custom | Avatar + author + timestamp + markdown body | +| BreadcrumbBar | Breadcrumb | Integrated with router, tabs, and entity actions | +| CommandPalette | Dialog | Cmd+K search with type-ahead and actions | +| FilterBar | custom | Composable filter chips with add/remove | +| SidebarNav | custom | Grouped, collapsible, badge-supporting nav | + +--- + +## 21. URL Structure + +All routes are company-scoped after company selection (company context stored in React context, not URL): + +``` +/ → redirects to /dashboard +/dashboard → company dashboard +/inbox → inbox / attention items +/my-issues → board operator's issues +/issues → issue list +/issues/:issueId → issue detail +/projects → project list +/projects/:projectId → project detail (overview tab) +/projects/:projectId/issues → project issues +/goals → goal hierarchy +/goals/:goalId → goal detail +/org → org chart +/agents → agent list +/agents/:agentId → agent detail +/approvals → approval list +/approvals/:approvalId → approval detail +/costs → cost dashboard +/activity → activity log +/companies → company management (list/create) +/settings → company settings +``` + +--- + +## 22. Implementation Priority + +### Phase 1: Shell and Navigation +1. Sidebar redesign (grouped sections, icons, company switcher, badges) +2. Breadcrumb bar component +3. Three-pane layout system +4. Cmd+K search modal +5. Install `lucide-react` + +### Phase 2: Issue Management (Core) +6. Issue list view with grouping, filtering, status circles +7. Issue detail view (three-pane with properties panel) +8. New issue modal +9. Issue comments +10. Bulk selection and actions +11. Kanban board view + +### Phase 3: Entity Detail Views +12. Project list + detail view +13. Goal hierarchy view +14. Agent list + detail view + +### Phase 4: Company-Level Views +15. Inbox with inline approval actions (primary approval UX) +16. Dashboard redesign with metric cards +17. Org chart interactive visualization +18. Cost dashboard +19. Activity log with filtering +20. Approvals list page (accessed via Inbox "See all", not sidebar) + +### Phase 5: Polish +21. Keyboard shortcuts +22. Responsive behavior +23. Empty states and loading skeletons +24. Error handling and toasts +25. Saved views (custom filters)