Mission Control (the project management system built into the app)
Omniscio's own project management system, opening as a sidebar project like any other: boards of typed columns, a set of alternate views over the same data, and the cross-board surfaces around them. This is the overview page — the detail sits on the parts below it.
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 in amc-back. 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 — the Main Table, the alternate views, and the per-board features.
- Mission Control part 3 — workspaces, accounts, people, permissions and publishing.
- Mission Control part 4 — the integrations: templates, calendars, meetings, search and notifications.
- Mission Control part 5 — the automation engine, the event bridge, the data mirror and the command surface.
- mc-templates.md — saving a board's structure as a reusable template.
See also
- mission-control-integration-contract.md — the invariants + the tests that guard them
- pm-inbox-contract.md — inbox source invariants + tests
- pm-board-templates-contract.md — board template save/deploy/gallery/editor invariants
- pm-calendar-overlay-contract.md — calendar overlay invariants
- pm-session-link-contract.md — session linking invariants
- pm-search-integration-contract.md — search/embeddings/knowledge invariants
- pm-setup-wizard-contract.md — setup wizard + preset picker invariants
- pm-cross-entity-link-contract.md — cross-entity linking invariants (KMS, mind map, flowchart, whiteboard)
- pm-voice-actions-contract.md — voice command + semantic search + webhook invariants
- pm-time-tracker-bridge-contract.md — time tracker bridge invariants (hub-spoke #3)
- INDEX.md
- Integration standards
Last verified 2026-10-06