---
title: Mission Control (the project management system built into the app)
---

# Mission Control

## What it is

Omniscio's built-in **project management system**, built as an isolated React sub-app and surfaced inside Omniscio as a sidebar virtual project. Gated on `missionControlEnabled` (default off). **Phase 2 (Board core / Main Table) shipped** (on top of Phase 0 auth + Phase 1 workspace shell) — opening a board renders the signature **Main Table**: groups of items with a **typed-EAV column engine** (status, text, long-text, numbers, people, date, timeline, dropdown, checkbox), inline cell editing, status pills with Edit Labels, a Column Center to add columns, and group-footer summaries. **Phase 2b** added the **item card** (a modal with an Updates feed), **item duplicate/delete**, and a **batch-action bar** (multi-select → archive/delete). **Phase 2c** added **drag-and-drop reorder** (items within/across groups + groups, via `@dnd-kit`) and a **WS realtime board channel** — every mutation publishes a `board-changed` event over `/realtime` and connected clients reload (the client disconnects on unmount). **Phase 3a** added the **view system**: a `views` table + a view-switcher (Main Table + saved views), the first alternate view — **Kanban** (group items by a status column, drag a card between columns to set its status) — and four more column types (link, email, phone, rating). **Phase 3b** added two more views — **Calendar** (place items on a month grid by a date column, with an unscheduled strip) and **Cards** (a gallery) — plus an add-view menu and the country/week/world-clock column types. Alternate views are just `views` rows whose `type` (a free string) + `config` the frontend switches on, so a new view is a component + a render branch — no backend change. **Phase 3c** added the **Main Table view controls** — search (across the item name + all column text), sort (by a column or name, asc/desc), a per-column contains filter, and hide-columns — all client-side over the loaded board data (no backend). **Phase 3d** added the **Chart** view — bucket items by a column and render the counts as a bar or pie (group-by + chart type are local UI state); it's a config-only view over the loaded data. **Phase 3e** added the **Timeline/Gantt** view — bars across a time track by a timeline column, with month gridlines, an unscheduled strip, **milestone markers** (zero-duration items render as diamond shapes instead of bars), and a **Critical Path** toggle (CPM algorithm highlights the longest dependency chain with accent color on bars and arrows). So the board now has **six views** (Main Table, Kanban, Calendar, Cards, Chart, Timeline). **Phase 3f** added the last view — **Form**: a board→form whose submissions create items, backed by a **public (unauthenticated), tokened** submit endpoint (`formsPublicRoutes` in amc-back). That endpoint is deliberately narrow: token-gated, create-only, accepts values only for the form's configured fields, validates each through the column-type registry, and returns no board data. The board now has **ten views**: Main Table (default) plus nine addable views — Kanban, Cards/Gallery, Calendar, Chart, Timeline/Gantt, Roadmap, Form, Workload, and Map (the last three added post-Phase 3; see dedicated sections below). **Phase 4** begins the cross-board surfaces. **Phase 4a** shipped **Search Everything** — a backend `GET /search?q=` and a `SearchPage` (debounced, opens a result on click; the top-bar search routes here). It began **items-only** (grouped by board); a parity fast-follow **broadened it to four result types — items, boards, dashboards, and people, grouped by type** (private boards you're not a member of are excluded from every group) — see **Grouped search** below. **Phase 4b** shipped **My Work** — a backend `GET /my-work` that returns the items assigned to me (matched by `auth.userId` against any People column value, account-scoped) each with one derived date (the board's first date/timeline column the item has set), and a `MyWorkPage` that buckets them into monday's six date sections (Past dates / Today / This week / Next week / Later / Without a date) as a table; clicking a row opens its board. A **fast-follow** upgraded My Work pixel-near: `GET /my-work` now also resolves, per the item's board, the **first column of each type** (group, people, status, priority) so the page renders the full table — name · Group · Board · People · Date · Status · Priority — with **colored, collapsible time-bucket sections**, an **overdue** alert on past dates, a **New item / + Add task** board→group picker (creates via the shared `POST /items`), and a working **Calendar tab**. The calendar is the board's grid reused: `CalendarView`'s month/week/day grid was extracted into a shared presentational **`CalendarGrid`** (driven by a generic `CalEvent[]` + `useCalendarNav`/`CalendarNav`); the board became a thin adapter and `MyWorkCalendar` feeds it cross-board items as uniform light-blue "Due date" events. The enrich is read-only (no migration); status vs priority are distinct backend column **types**, so they separate cleanly. Bucketing/overdue math is unit-tested (`tests/unit/plugins/mission-control/my-work-buckets.test.ts`); spec `docs/superpowers/specs/mission-control-my-work-design.md`, plan `docs/superpowers/plans/2026-06-08-mission-control-my-work.md`. **Phase 4c** shipped **Notifications** — a `notifications` table whose rows are written ONLY as a server-side side-effect of an owner-checked mutation (a People-column write that adds you → an `assigned` notification; an `@YourName` in an item update → a `mentioned` one; the actor is never notified about their own action), read via `GET /notifications` + `GET /notifications/unread-count` (both owner-scoped by `auth.userId`) with `POST /:id/read` + `POST /read-all`, and a `NotificationsPage` (a bell feed with tabs All / Unread / I was mentioned / Assigned to me, mark-read on click, mark-all-read) plus a top-bar bell badge. **Phase 4d** shipped **Dashboards** — a `dashboards` table (workspace-scoped + account-isolated like boards) with an opaque `config` JSONB (`boardIds` + `widgets`); it's **config-only** (no per-widget backend), with CRUD via `dashboardsRoutes`. The `DashboardPage` computes every widget client-side over the existing ownership-checked `GET /boards/:id/full` (so a foreign board id in config just 404s — no leak); a left-nav "Dashboards" section lists + creates them. **Phase 4d-redesign** rebuilt it pixel-near monday: a header (favorite star, inline-rename, Export ▾ / Invite / ⋯ overflow), a toolbar (**+ Add widget** dropdown, **N connected board** → connect-boards modal, type-to-filter, save with dirty-dot, **People** + **Filter** scopers, settings gear), a polished empty state, and a **drag-and-resize grid** (`react-grid-layout`; per-widget `layout {x,y,w,h}` stored in `config`). Editing is always-on with a **draft + debounced-autosave** model (no Edit/View toggle). Widgets: **Numbers** (abbreviated $378k figure), **Chart** (bar / column / pie / donut / line), the sprint trio **Velocity / Planned-vs-unplanned / Burndown** (frontend-computed from configured sprint/effort/done/date columns — Velocity faithful, the other two documented **approximations** since there's no sprint-history backend). Battery/Table/Apps remain in code but off the menu. Toolbar **People**/**Filter** write `config.filters` and scope every widget's data via a shared `applyFilters` (a rule only constrains boards that have its column); **Export** rasterises the grid with `html-to-image` (PNG / print-to-PDF); **Invite** reuses the member directory. Pure logic (`dashboardLayout` / `sprintData` / `dashboardFilter`) is unit-tested; design spec at `docs/superpowers/specs/mission-control-dashboard-redesign-design.md`. **Phase 4e** shipped the **Activity log** — an `activity_log` table whose rows are written ONLY server-side (via `lib/activity.ts`) as a side-effect of an owner-checked item mutation (item **created / renamed / deleted** and **column value changed**, each with a prev→next summary; the actor is joined separately, not baked into the text), read via `GET /activity?boardId=&itemId?=` (gated by `ownedBoard`, newest-first), and surfaced two ways — the **ItemCard Activity tab** (item-level) and a **board-level Activity modal** from the board header (both render a shared `ActivityFeed`). **All Phase 4 cross-board surfaces now ship** (Search, My Work, Notifications, Dashboards, Activity log). Next: the automations engine (Phase 5).

## Where to find it

It appears as its own project in the sidebar once the feature is enabled, and everything from here down lives inside it.

### UI surface

A **"Mission Control"** row in the projects sidebar (alphabetical slot after MCP Servers, before PR Merge Queue), shown only while `missionControlEnabled` is on. Enable it at **Settings → Built-in Apps → Mission Control**. Clicking the row mounts the Mission Control app full-pane. Mission Control IS a spawnable session host (`spawnable-session-host`): `__mission_control__` is in `SPAWNABLE_VIRTUAL_PROJECT_SENTINELS` + `MANAGED_WORKDIRS`, with a sidebar Sessions tab, overlay swap to `SessionPanel`, PM-oriented system-prompt shim, and Ctrl+T support (following the Supermail session-host pattern). Auth is via Omniscio's Firebase Global Auth — users sign in once via Omniscio; when not signed in to Omniscio, a "Not signed in" placeholder is shown.

## How it behaves

### Entity types

Mission Control supports **seven entity types** (the `McEntityType` union in `types-branded-ids.ts`). Agents building import, onboarding, or cross-entity code need to know all seven — not just boards.

| Type          | Category        | Description                                                 | Feature dir              | Routes                              | Extra gate     |
| ------------- | --------------- | ----------------------------------------------------------- | ------------------------ | ----------------------------------- | -------------- |
| `board`       | Work management | Kanban/table project boards — the primary work surface      | `features/board/`        | `/board/:id`                        | —              |
| `dashboard`   | Reporting       | Cross-board widget dashboards (Phase 4d)                    | `features/dashboards/`   | `/dashboard/:id`                    | —              |
| `goal`        | Strategy        | OKR-style goals and objectives                              | `features/goals/`        | `/goals`, `/goal/:id`               | —              |
| `portfolio`   | Strategy        | High-level portfolio views across boards                    | `features/portfolios/`   | `/portfolios`, `/portfolio/:id`     | —              |
| `document`    | Content         | Rich-text documents                                         | `features/documents/`    | `/documents`, `/document/:id`       | `pm-documents` |
| `spreadsheet` | Content         | Spreadsheet workbooks                                       | `features/spreadsheets/` | `/spreadsheets`, `/spreadsheet/:id` | `pm-documents` |
| `form`        | Content         | Standalone form builders (distinct from in-board Form view) | `features/forms/`        | `/forms`, `/form/:id`               | `pm-documents` |

All seven require `missionControlEnabled`. Documents, spreadsheets, and forms also require the `pm-documents` feature flag (default on) — when off, their nav sections, template categories, and routes are hidden. See `pm-documents-spreadsheets-forms-contract.md`.

**Template categories vs. entity types:** Five of the seven are template categories (boards, dashboards, documents, spreadsheets, forms). Goals and portfolios are entity types but NOT template categories — they have no preset/template system. See `pm-template-categories.ts`.

### Competitor-to-MC entity type mapping

Eleven import adapters (registered in `adapter-registry.ts`) convert competitor data into MC entities. The import IR operates at four levels: `board → group → column → item`. The `PLATFORM_TO_PRESET` mapping in `pm-import-platforms.ts` routes each platform to a starting preset.

| Source            | Competitor entity | MC type    | Import status                | Notes                                          |
| ----------------- | ----------------- | ---------- | ---------------------------- | ---------------------------------------------- |
| **Trello**        | Boards            | `board`    | Importable                   | Preset: `trello`                               |
| **Notion**        | Databases         | `board`    | Importable                   | Preset: `notion`                               |
| **Notion**        | Pages             | `document` | Not yet (`supported: false`) | Adapter exists, path not wired                 |
| **Jira**          | Projects          | `board`    | Importable                   | Preset: `engineering-jira`                     |
| **Jira**          | Confluence pages  | `document` | Not yet                      | No adapter yet                                 |
| **Monday**        | Boards            | `board`    | Importable                   | Preset: `operations`                           |
| **Monday**        | Workdocs          | `document` | Not yet (`supported: false`) | Adapter exists, path not wired                 |
| **Asana**         | Projects          | `board`    | Importable                   | Preset: `asana`                                |
| **Asana**         | Goals             | `goal`     | Not yet (`supported: false`) | Adapter exists, path not wired                 |
| **Linear**        | Teams             | `board`    | Importable                   | Preset: `engineering-linear`                   |
| **Linear**        | Projects          | —          | Not yet (`supported: false`) | No MC equivalent for Linear's project grouping |
| **ClickUp**       | Lists / Spaces    | `board`    | Importable                   | Preset: `clickup`                              |
| **ClickUp**       | Docs              | `document` | Not yet (`supported: false`) | Adapter exists, path not wired                 |
| **Airtable**      | Tables / Bases    | `board`    | Importable                   | Preset: `airtable`                             |
| **CSV**           | —                 | `board`    | Importable                   | Generic file import                            |
| **Google Sheets** | —                 | `board`    | Importable                   | Generic file import                            |
| **Excel**         | —                 | `board`    | Importable                   | Generic file import                            |

**Import gaps (declared `supported: false` in adapters):** Competitor pages/docs (Notion pages, Monday workdocs, ClickUp docs) → MC `document`; competitor goals (Asana goals) → MC `goal`. The MC entity types exist and have full UIs — only the import adapters need wiring.

**No MC equivalent yet:** Wiki/knowledge-base systems (beyond documents), whiteboards/canvas (Miro, FigJam-style), and standalone timeline tools exist as competitor entity types but have no dedicated `McEntityType`. Timelines are handled by the board's Timeline/Gantt view rather than a separate entity.

### Workspace shell (Phase 1)

Once authenticated, the panel mounts a `MemoryRouter` (Omniscio owns the real URL) → an `AppShell`: a **top bar** (wordmark, search bar, notifications bell with unread badge, and an **account menu** — an avatar button at the far right that opens a dropdown with the user's identity, a theme toggle, and a log-out option; matches Ollert's `AccountMenu` pattern) and a **left nav** with a workspace switcher (a monday workspace header + ⋯ actions menu — see Workspaces functionality below), a "My Work" entry (the cross-board My Work table + calendar — see Phase 4b), and the board list for the active workspace. The **Favorites**, **Boards**, and **Dashboards** sections are each independently **collapsible** — click the section header (chevron + label) to toggle; state persists in localStorage (`mc.nav.<section>.collapsed`) and is swept on sign-out. Action buttons (+, T) remain visible when a section is collapsed. The shared hook is `useNavCollapse` (`features/nav/lib/useNavCollapse.ts`). Clicking **+** creates a board (with a default group) and navigates to it. **Home** shows recent boards (first-N for now) with empty states; **workspace** and **board** routes render their own pages (the board is a Phase-2 placeholder). The whole tree comes from one backend aggregate, `GET /nav/tree` → `{ workspaces: [{ ...ws, folders, boards }] }`, fetched by `useNavTree()`.

The backend (`amc-back/`) adds account-scoped CRUD modules — `workspaces`, `folders`, `boards` (each guarded by a shared `requireAuth` Elysia plugin that verifies the Firebase ID token via `admin.auth().verifyIdToken()` and derives `{ userId, accountId }`, filtering every query by `accountId`; dual-auth: also accepts legacy JWT during migration) — plus the `/nav/tree` aggregate. Registering a new account auto-seeds a "Main workspace".

## Related

- [Mission Control part 2](mission-control-part-2.md) — the Main Table, the alternate views, and the per-board features.
- [Mission Control part 3](mission-control-part-3.md) — workspaces, accounts, people, permissions and publishing.
- [Mission Control part 4](mission-control-part-4.md) — the integrations: templates, calendars, meetings, search and notifications.
- [Mission Control part 5](mission-control-part-5.md) — the automation engine, the event bridge, the data mirror and the command surface.
- [mc-templates.md](mc-templates.md) — saving a board's structure as a reusable template.

### See also

- [mission-control-integration-contract.md](../../.claude/memory/contracts/mission-control-integration-contract.md) — the invariants + the tests that guard them
- [pm-inbox-contract.md](../../.claude/memory/contracts/pm-inbox-contract.md) — inbox source invariants + tests
- [pm-board-templates-contract.md](../../.claude/memory/contracts/pm-board-templates-contract.md) — board template save/deploy/gallery/editor invariants
- [pm-calendar-overlay-contract.md](../../.claude/memory/contracts/pm-calendar-overlay-contract.md) — calendar overlay invariants
- [pm-session-link-contract.md](../../.claude/memory/contracts/pm-session-link-contract.md) — session linking invariants
- [pm-search-integration-contract.md](../../.claude/memory/contracts/pm-search-integration-contract.md) — search/embeddings/knowledge invariants
- [pm-setup-wizard-contract.md](../../.claude/memory/contracts/pm-setup-wizard-contract.md) — setup wizard + preset picker invariants
- [pm-cross-entity-link-contract.md](../../.claude/memory/contracts/pm-cross-entity-link-contract.md) — cross-entity linking invariants (KMS, mind map, flowchart, whiteboard)
- [pm-voice-actions-contract.md](../../.claude/memory/contracts/pm-voice-actions-contract.md) — voice command + semantic search + webhook invariants
- [pm-time-tracker-bridge-contract.md](../../.claude/memory/contracts/pm-time-tracker-bridge-contract.md) — time tracker bridge invariants (hub-spoke #3)
- [INDEX.md](INDEX.md)
- [Integration standards](../plans/integration-standards.md)

