Personal project workbench for solo vibe coders. Kanban board, AI tool tracking, agent session history β backed by Firmament (Supabase).
Named for Odin's raven of memory.
Muninn gives you one place to manage your projects, track AI subscriptions, and review what your agents have been doing β across every machine.
- Board β Kanban board with drag-and-drop, filtering, search, and project archiving
- Tools β AI subscription tracker with cost summaries and renewal alerts
- Agents β Paginated session history with interface/machine filters
- Settings β Connection status, theme toggle, version info
All data lives in your Supabase instance (Firmament) with realtime sync across tabs and machines.
| Layer | Choice |
|---|---|
| UI | React 19 + Vite |
| Styling | Tailwind CSS + HSL CSS variables |
| State | Zustand (devtools + persist) |
| Backend | Supabase (@supabase/supabase-js) |
| Drag & drop | @hello-pangea/dnd |
| Panels | react-resizable-panels |
| Icons | @phosphor-icons/react |
| Fonts | IBM Plex Sans + IBM Plex Mono |
| Router | React Router v7 |
| Tests | Vitest + Testing Library |
- Node.js 18+
- A Supabase project (the app uses anon key auth β no login required)
git clone https://github.com/alecvdp/muninn.git
cd muninn
npm installcp .env.example .envEdit .env with your Supabase credentials:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key-here
Muninn reads from four Firmament tables. If you're starting fresh, apply these migrations to your Supabase project:
Projects table (add kanban columns):
alter table projects
add column if not exists board_status text default 'idea',
add column if not exists board_position integer default 0,
add column if not exists archived_at timestamptz;Tools table (new):
create table tools (
id uuid primary key default gen_random_uuid(),
name text not null,
category text not null default 'to-check-out',
cost numeric(10,2) default 0,
billing_cycle text,
renewal_date date,
platform text[] default '{}',
url text,
tags text[] default '{}',
notes text default '',
created_at timestamptz default now(),
updated_at timestamptz default now()
);
alter table tools enable row level security;
create policy "Allow all access" on tools for all using (true) with check (true);Enable realtime (for live sync):
alter publication supabase_realtime add table projects;
alter publication supabase_realtime add table tools;The agent_sessions and memories tables are managed by personal-mcp β Muninn reads from them but doesn't write.
npm run devOpen http://localhost:5173.
| Command | What it does |
|---|---|
npm run dev |
Start dev server (Vite, port 5173) |
npm run build |
Type-check with tsc, then build for production |
npm run preview |
Preview the production build locally |
npm run lint |
Run ESLint |
npm test |
Run tests (Vitest, 123 tests) |
npm run test:watch |
Run tests in watch mode |
muninn/
βββ src/
β βββ components/
β β βββ agents/ # SessionFeed, SessionCard
β β βββ board/ # KanbanBoard, KanbanColumn, ProjectCard
β β βββ detail/ # ProjectDetail, ToolDetail, CreateProjectDetail
β β βββ layout/ # AppBar, Navbar, DetailPanel
β β βββ tools/ # ToolsGrid, ToolCard
β β βββ ui/ # ErrorBoundary, ErrorToast
β βββ lib/
β β βββ supabase.ts # Typed Supabase client
β β βββ dates.ts # Date utilities (renewal checks)
β βββ pages/
β β βββ BoardPage.tsx # Kanban with search/filter/archive
β β βββ ToolsPage.tsx # Tool grid with cost summary
β β βββ AgentsPage.tsx # Session feed with filters
β β βββ SettingsPage.tsx
β β βββ NotFoundPage.tsx
β βββ store/
β β βββ projects.ts # Projects CRUD, kanban state, realtime
β β βββ tools.ts # Tools CRUD, cost calculations, realtime
β β βββ sessions.ts # Sessions with pagination + server-side filters
β β βββ ui.ts # Panel state, theme (persisted)
β βββ types/
β β βββ index.ts # Shared row/insert/update types
β βββ database.types.ts # Generated Supabase schema types
β βββ App.tsx # Layout shell (AppBar + Navbar + Outlet + DetailPanel)
β βββ main.tsx # Router + ErrorBoundary
β βββ index.css # CSS variables, dark/light themes
βββ supabase/
β βββ migrations/ # SQL migrations
βββ docs/
β βββ screenshot.png
βββ SPEC.md # Original design spec
βββ .env.example
βββ vite.config.ts
βββ vitest.config.ts
βββ tailwind.config.js
βββ package.json
ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ
β β Navbar (view title, theme toggle) β
β App ββββββββββββββββββββββββ¬βββββββββββββββββββββββ€
β Bar β β β
β β Main Content β Detail Panel β
β 48px β (board / tools / β (440px, resizable, β
β β agents / settings) β opens on click) β
β β β β
ββββββββ΄βββββββββββββββββββββββ΄βββββββββββββββββββββββ
- AppBar β Icon rail on the left. Board, Tools, Agents, Settings.
- Navbar β Top bar with view title and theme toggle.
- Detail Panel β Slides in from the right when you click a card. Escape to close. Focus-trapped for accessibility.
The home view. Projects displayed as cards in kanban columns:
| Column | Status | Color |
|---|---|---|
| Idea | idea |
Blue |
| Todo | todo |
Yellow |
| In Progress | in-progress |
Orange |
| Paused | paused |
Gray |
| Done | done |
Green |
Features:
- Drag cards between columns to change status
- Reorder within columns (fractional positioning, handles filtered views)
- Search by name/description
- Filter by priority (P1βP5)
- Toggle archived projects visibility
- Click any card to edit in the detail panel
- Create new projects with the + button
Track AI subscriptions and tools you're evaluating.
Summary stats bar at the top shows:
- Total monthly cost
- Total annual cost
- Active tool count
- Tools renewing within 30 days (highlighted)
Each tool card shows name, category badge (Using/To Check Out), cost, billing cycle, platform icons, renewal date, and tags.
Filters: Search by name, filter by category, filter by platform.
Chronological feed of agent sessions from the agent_sessions table.
- Sessions grouped by date
- Paginated (25 per page, "Load more" button)
- Filter by interface (claude-code, claude.ai, amp, etc.)
- Filter by machine (midgard, mini-ygg, etc.)
- Server-side filtering (queries pushed to Supabase, not client-side)
Dark and light themes via CSS variables. Toggle in the navbar or Settings page. Theme preference persists in localStorage.
Colors use HSL format for easy customization β edit src/index.css to adjust:
:root {
--brand: 25 82% 54%; /* Warm orange accent */
--bg-surface: 0 0% 13%; /* Main background */
--bg-muted: 0 0% 11%; /* Sidebar, panels */
--text-normal: 0 0% 77%; /* Body text */
}Kanban column colors and tool category badges use semantic CSS variables (--status-idea, --category-using, etc.) so themes stay consistent.
Projects and Tools use Supabase Realtime channels. Changes on one machine appear instantly on others β no refresh needed.
The subscription lifecycle uses a global registry pattern to survive Vite HMR without orphaning channels. Each store tracks subscriber count and only removes the channel when the last consumer unmounts.
Build and deploy as a static site:
npm run buildThe dist/ folder can go to Cloudflare Pages, Vercel, Netlify, GitHub Pages, or any static host. Set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY as environment variables in your hosting platform.
App crashes on load with "Missing Supabase environment variables":
You need a .env file. Copy .env.example to .env and fill in your Supabase project URL and anon key.
Projects don't sync between tabs/machines:
Check that the supabase_realtime publication includes the projects table. Run:
alter publication supabase_realtime add table projects;Drag and drop feels janky after many reorders: Fractional positioning can accumulate precision issues over time. A future improvement would normalize positions periodically.
Build warns about chunk size:
The 660KB bundle is primarily @hello-pangea/dnd + Supabase client. Code splitting via React.lazy() is tracked as a future improvement.
Muninn's visual design and component architecture are heavily inspired by Vibe Kanban:
- Three-zone layout (AppBar + main + detail panel)
- Card styling with border overlap trick
- HSL color token system
- IBM Plex typography
- Phosphor icon set
Full design spec: SPEC.md
"Muninn and Huginn fly each day over the spacious earth. I fear for Huginn, that he come not back, yet more anxious am I for Muninn." β Odin
MIT License β Built for solo builders who ship.
