Ollert (a full kanban tool built into the app)
A complete kanban project tool — workspaces, boards, lists, cards, drag-and-drop, labels, members, checklists, comments, due dates and alternate views — brought into Omniscio as a native sidebar feature rather than an embedded web page. Off by default, and signed in with your existing Omniscio account.
What it is
A full-featured kanban project tool — workspaces, boards, lists, cards, drag-and-drop,
labels, members, checklists, comments, due dates, and the alternate board views —
brought into Omniscio as a native sidebar feature. It is a
React port of the standalone trello-web frontend, not an embedded web page.
Status: Phases 1–5 integration-hardened. The full app is mounted — sidebar entry, panel shell, boards/cards, card depth, alternate views, and realtime all ride the same hardened foundation (scoped CSS + portals, CSP for the API/images/socket, in-memory router, React-18-safe, error-contained). Auth unified with Omniscio's Global Auth (Firebase) 2026-07-16 — the plugin's own login + refresh-token persistence were removed. Off by default. Remaining: dark-mode reconciliation + help-site copy (Phase 6), and the backend deploy (incl. Firebase storage for attachment uploads). Engineering detail + invariants live in the feature contract (
.claude/memory/contracts/ollert-integration-contract.md).
Where to find it
What the user sees
- A "Ollert" row appears in the Omniscio sidebar (under the Omniscio built-ins group, in its alphabetical slot as "Ollert"), with the Ollert brand icon. The row only shows when the feature is enabled.
- Clicking it opens Ollert with a left navigation sidebar (Boards, Templates, Home, and your Workspaces — each expanding to its Boards / Members / Settings) beside the board panel — the same shape as Omniscio's other integrations, not a full-workspace takeover. The sidebar is resizable and theme-aware; signed out it shows a "sign in to Omniscio" strip. (No separate sessions list — Ollert hosts no Claude sessions of its own.)
- There is no separate Ollert sign-in. Ollert uses Omniscio's own sign-in (Global Auth) — sign in to Omniscio once and Ollert is authenticated automatically. When you are not signed in to Omniscio, Ollert shows a "Sign in to Omniscio to access your boards" prompt instead of the app.
How it behaves
How to turn it on
Ollert is gated on your ollertEnabled flag (default off; set by the 2026-05-23
data-presence migration for existing installs). There is no Settings toggle
anymore — the old "Enable Ollert" control, its nav row, and its search entry were
removed in the 2026-08-14 settings declutter (decision 2B). Settings → Ollert is
now a read-only landing reachable only by a direct deep link (?section=ollert).
While ollertEnabled is off, the sidebar row is hidden and nothing Ollert-related
loads.
Ollert talks to a separately-hosted Ollert backend (it is not run by Omniscio).
The backend URL is hardcoded to https://amcback.jls.dev/trello (the unified
amc-back server) in src/plugins/ollert/web/lib/runtime-config.ts — it's a fixed
deploy target, not a setting. To point at a different backend (e.g. a local dev
instance at http://localhost:8080/trello), set the VITE_API_URL env var. The
realtime WebSocket URL is derived from it (https://… → wss://…).
Sharing boards and cards (deep links)
Every card's ⋯ menu has a "Copy link to card" action. The board header has a
"Copy link to board" action. Both copy an omniscio:// deep link to the
clipboard — not a regular web URL.
What the link looks like:
- Card:
omniscio://ollert/card/<boardId>/<cardId> - Board:
omniscio://ollert/board/<boardId>
How it works for the recipient: anyone who has Omniscio installed and access to that board can paste the link into their browser address bar or double-click it from a document, and Omniscio will open directly to that card or board. No copy-pasting of board names or searching required.
Implementation note (for agents): the link is built by
DEEP_LINK_OLLERT_BUILD IPC handler (src/main/services/deep-link.ts,
ollertCardDeepLink / ollertBoardDeepLink builders). The renderer calls it
via the window.__AMC_OLLERT_LINKS__ bridge installed in OllertPanel.tsx, then
writes the result to the clipboard. The router that opens Omniscio to the right card or
board on receipt is in src/renderer/src/lib/deep-link-router.ts. Build,
parse, and route logic are unit-tested in
tests/unit/deep-link-ollert-invite.test.ts and
tests/unit/lib/deep-link-router-ollert-invite.test.ts.
Recent additions (2026-06-17)
Promote members to admin. On the workspace members page (and the workspace
overview's members dialog), a workspace admin sees an Admin / Member dropdown
on each member row and can promote or demote anyone except the workspace owner
(whose role is fixed). Backed by PATCH /workspaces/:id/members/:userId.
Custom colours everywhere. Card labels, card covers, list tints, and board backgrounds now offer a custom colour picker as the first option, followed by the default swatches (the swatch sets were also expanded). Any colour is allowed — the backend validates a well-formed hex rather than checking a fixed palette.
Clickable links in comments. Card comments use a small rich-text editor (bold, italic, bullet/numbered lists, and an insert-link button). Typed URLs also become clickable automatically. Comment content is sanitized on both save and display, so links open safely in a new tab.
Filter shows all members. On a board that is visible to the whole workspace (not private), the member filter — and the assign-to-card picker — now list every workspace member, not just those explicitly added to the board. Assigning a workspace member to a card adds them to the board automatically.
Pending invitations show on the members page. The workspace members page now
lists pending (invited-but-not-yet-joined) members in a "Pending invitations"
section below the roster, with a revoke action — previously they appeared only
inside the invite popup. The section is admin-only and reuses InvitationsPanel
(rendered with its invite form hidden); the invite form still lives in the
"Invite Workspace members" dialog.
Done lists + unified completion. A card has one "done" state — the
completed flag. The hover-reveal circle on the card front (board, table,
calendar) and the "Mark as complete" checkbox in the due-date popover now
drive the same flag (the date pill shows "· Done" whenever the card is
complete); the legacy dueComplete column is mirrored to it on the server for
the overdue index. A list's ⋯ List actions menu has a "Mark as done
list" toggle — any number of lists per board may be done lists, shown with a
green Done badge in the column header. Dragging a card into a done list
auto-marks it complete; dragging it back out into a normal list
un-completes it (reordering within the list never changes completion). Backend:
is_done_list on the lists table (migration 0020); the rule lives in
cards.service moveCard and the mirror in updateCard.
Custom fields in the card's "Add" menu. A card's Add menu now has a Custom Fields item that opens an inline picker listing the board's custom fields with a typed editor for each — so fields you create are reachable where you go to add things to a card. The fields also still appear in the card's own Custom Fields section; both edit the same values.
For agents
How it is built (for agents)
The vendored Ollert source lives in src/plugins/ollert/ and is deliberately
isolated from Omniscio's tooling (its own ESLint/Prettier ignores, its own
tsconfig.json via npm run typecheck:ollert, and its own scoped Tailwind build).
Omniscio owns only the thin integration glue.
Key decisions and the four port challenges:
- Routing. Ollert uses URL routes (React Router). Inside Omniscio those run in an
in-memory router (
MemoryRouter) scoped to the panel, so all ~208 Ollert components keep theiruseParams/useNavigatecalls unchanged. Omniscio's renderer still owns the real browser URL. The composition root issrc/plugins/ollert/web/amc/AmcOllertApp.tsx(replaces the standaloneweb/main.tsx). - Styling collision. Ollert and Omniscio both define tokens like
surfaceandaccent. Ollert gets its own scoped Tailwind build — every utility is namespaced under a.ollert-scopewrapper (important: '.ollert-scope', preflight off), and its palette lives on.ollert-scope/.dark .ollert-scopeas RGB-channel CSS vars. The prebuilt, committedollert.generated.cssis imported by the panel; regenerate it withnpm run build:ollert-css. - Shared types. Ollert imports framework-free types from
@ollert/shared, which is vendored undersrc/plugins/ollert/shared/. The API client is loosely typed on purpose (Eden Treatytreaty<any>) to stay decoupled from the un-vendored backend — but that looseness stays inside the transport. The plugin's public domain types (WorkspaceSummary,BoardSummary,BoardSnapshot,SnapshotCard,BoardStats, …) are declared by hand insrc/plugins/ollert/web/lib/api-types.ts, and each feature'sapi.tsderives its exported aliases from those rather than fromtypeof api. Without that split theanypropagated outward and every one of those public types wasany, so a field rename on the wire compiled clean at every consumer; now it is a type error. Notetreaty<any>is still exported, so a direct transport call site stays loose — the guarantee covers the plugin's public surface, not its call sites. - Auth. Ollert is unified with Omniscio's Global Auth (Firebase) — there is no
separate Ollert login.
OllertPanelinstalls awindow.__AMC_OLLERT_SESSION__bridge whosegetToken()fetches a Firebase ID token from Omniscio's main process over IPC (ollert:get-firebase-token); the API client attaches it asBearerauth per request and retries once on a401with a freshly fetched token (the main process auto-refreshes tokens near their 1-hour expiry — no plugin-side refresh-token persistence). The panel gates on Omniscio sign-in (a "Sign in to Omniscio" prompt, zero network, when signed out); on sign-in it callsGET /auth/me, which auto-creates/ links the backend account. The old email/password login/register/forgot UI and the encryptedtrelloRefreshTokenrefresh persistence were removed in this unification.
Theme. Omniscio owns the .dark class on <html>; the scoped .dark .ollert-scope
tokens follow it. Omniscio's panel feeds Ollert's ThemeContext a value derived from
Omniscio's theme store rather than mounting Ollert's own provider (which would fight
Omniscio's identical <html>.dark mechanism). Full dark-mode reconciliation is a later
polish step.
Network exception. Unlike the rest of Omniscio (where the renderer never makes
direct network calls), the Ollert panel calls its API directly from the
renderer. This is the user's own Ollert session to a separate service — not a
paid Omniscio credential — and Omniscio's CSP already permits the external https:// +
wss:// calls. The only credential that touches Main is Omniscio's Firebase ID token,
minted per request and never persisted by the plugin.
Where it is wired in Omniscio
- Sidebar registration:
src/shared/integration-registry.ts(id: 'ollert',featureFlag: 'ollertEnabled') +src/renderer/src/integrations/ui-registry.ts(icon + lazy panel + lazyOllertSidebarassidebarComponent,mobilePrefersPanel: true; nopanelOwnsLayout— the linear-board shape). - Virtual-project sentinel:
OLLERT_PROJECT_ID = '__ollert__'insrc/shared/virtual-project-ids.ts(also inVIRTUAL_FOLDER_PATHS). - Sidebar hide-when-off gate:
SIDEBAR_RENDER_GATESinsrc/renderer/src/stores/project-visibility.ts. - Panel host (Omniscio glue):
src/renderer/src/features/ollert/OllertPanel.tsx. - Pane-2 nav sidebar (Omniscio glue):
src/renderer/src/features/ollert/OllertSidebar.tsx— drives the panel via the vendorednavigateTobridge, reflects its route + sign-in status fromsrc/plugins/ollert/web/lib/ollert-ui-bridge.ts(published byUiStateBridgein the composition root), and reuses the vendoreduseWorkspacesthrough the singletonqueryClient(shared cache). The vendoredDashboardShellhides its OWN internal sidebar when Omniscio-hosted (isNativeSession()). - Settings:
sections/ollert/OllertSettings.tsx— a read-only deep-link landing (no nav row, no toggle, no search entry), reachable only by?section=ollert.
Related
- mission-control.md — the built-in board app, which is a different product in the same sidebar.
- notion-board.md — the board integration pointed at a Notion database.
- deep-links.md — the
omniscio://links the board's copy-link actions produce.
Last verified 2026-10-01