Features
Tandem is the layer between your keyboard and the model — multi-project
orchestration, real-browser automation, an Obsidian vault for memory, and a
fleet dashboard that actually knows what your agents cost. Every bullet below
maps to a registered feature in agents.json, a frontend route under
frontend/src/app/, or a row in the master competitor matrix.
1. Task & project management
Markdown tasks, kanban, dependencies, retries, budgets — every project tracked in one place.
- 7-stage pipeline (
inbox → planning → human_turn → active → review → paused → done) drives every task file undertasks/*.md; status, priority, dependencies, retry counter and token budget live in YAML frontmatter — seetasklib.pyand the/tasks+/kanbanroutes. (matrix: Task pipeline) - Hard task dependencies (
blocked_by/blockslists) plus auto-escalation: whenattemptshitsmax_retries, status flips topausedand the assigned agent is cleared. (matrix: Task dependencies, Retry counter) - Per-task token budgets enforced by
check_budget(); combined with goal tracking + streaks on/goals, you get a full PaperclipAI-style issue-management surface without an external tool. (matrix: Token budgets, Goal tracking)
2. Terminal & shell
Real native shell, tmux-persistent, multi-pane, 22 themes — your terminal lives where your work lives.
- WebSocket terminal server (
terminal-server.js, port 4201) runsnode-ptyagainst a real login shell; tmux session persistence means closing the browser does not kill the job. The surface lives at/terminal. (matrix: Integrated terminal, tmux persistence, Native shell) - Multi-pane grids (2 / 2×2 / 3×4 / 4×4) with drag-drop reorg via
terminal-grid.tsx; same xterm.js + WebGL stack the heavy desktop competitors charge for. (matrix: Multi-pane grids, Drag-drop reorg) - 22 themes shipping today — Dracula, Gruvbox, Tokyo Night, Monokai, One Dark,
Solarized Dark/Light, Catppuccin Mocha, Paper Sepia, Matrix Green, Sakura
Bloom and the original 11 — defined once in
frontend/src/lib/themes.ts. (matrix: 20+ themes)
3. Agent orchestration
19 named agents, per-agent ACL, worktree isolation, atomic claim — orchestration that survives a real fleet.
- Roster declared in
agents.json: COO, Architect, Executor, Verifier, Tracer, Vault, Website, Repo Scout, YouTube Scout, Code Reviewer, Security Reviewer, TDD Guide, Refactor Cleaner, Doc Updater, Build Error Resolver, Browser CDP, Codex CLI, Grok-Swarm, plus Spark templates — each with its ownsystem_prompt,allowed_tools,allowed_dirsand MCP config. (matrix: Named agent roster, Per-agent ACL) - Atomic task claim via
mc.py claim-task <id> <agent-id>(single-flight against SQLite); writing agents are forced into worktree isolation by.claude/hooks/enforce-worktree.shand auto-snapshotted on completion bypost-agent-snapshot.sh, so concurrent agents never collide on the working tree. (matrix: Atomic lock, Worktree isolation) - Live heartbeat + per-agent chat UI at
/agentsand/chats; chat panes route through the sameterminal-server.jstmux substrate, so the agent’s stdout is yours to read at any time. (matrix: Heartbeat, Chat interface per-agent)
4. Security & governance
Localhost-only by default, approval inbox, append-only audit trail — every action is reviewable.
- All three services (API
127.0.0.1:4200, terminal127.0.0.1:4201, frontend127.0.0.1:3000) refuse to bind0.0.0.0;block-rm.shblocksrm/find -deleteoutside/tmp/, and audit-trail tables (sessions,agent_spawns,approvals,provision_actions) have no DELETE endpoint by design. (matrix: Localhost-only) - Human-in-the-loop approval inbox at
/approvalsgates every agent action that touches money, the network, or the disk outside itsallowed_dirs; backed byapprovalsrows intandem.dband a frontend popover-driven approve/reject flow. (matrix: Approval inbox HITL) - Deterministic audit log: every task file carries an
## Activity Logsection thattasklib.append_audit_log()writes to, and every session links back viamc.py link-session. Pair that with the/adminagent_restart_modegate and you have a forensic trail you can replay. (matrix: Deterministic audit trail)
5. Browser & web automation
Real Chrome over CDP, your real logins, multi-daemon parallelism, skill-files per site — automation against the live web.
- The
browser-cdp/package speaks Chrome DevTools Protocol over WebSocket against your actual logged-in Chrome — no stealth-browser fingerprint games, no separate profile to keep warm. Surfaced through thebrowser-cdpagent inagents.jsonand the/browserroute. (matrix: Real-browser CDP, Real logged-in Chrome) - Multi-daemon mode runs N CDP daemons in parallel for fanout scraping; the
lead-scraping pipeline under
clients/lead-scraping/drives this viacore.httphelpers (safe_get,scan_body) so every fetched byte hits the safe-scrape scanner before it reaches LLM context. (matrix: Multi-daemon parallel browsers) - Per-site skill files (selectors, login flows, post-recipes) live under
skills/and load by site; the/skillspage surfaces them with loadouts and scope (global / local / project). (matrix: Skill files per site)
6. Knowledge & vault
Markdown is the source of truth — Obsidian vault, wiki ingestion, daily notes, weekly review, auto context.
- The whole vault root (
claude-brain/) is your Obsidian workspace; tasks are markdown files (not DB rows) so anything the agents write is immediately visible in Obsidian Bases, and anything you write in Obsidian is immediately visible to the agents. (matrix: Obsidian vault, Markdown as source of truth) raw/→wiki/ingestion pipeline:safe-scrape.pylands sources inraw/,raw-content-scan.pyclassifies them, and ingest skills compile flat kebab-case wiki pages with YAML frontmatter — viewable at/wiki. (matrix: Wiki / knowledge base, Ingestion pipeline)- Daily notes auto-appended on session export, weekly review workflow on
/weekly, and auto context management on/context— agents read their own working memory between turns instead of starting cold. (matrix: Daily notes, Weekly review, Auto context)
7. Integrations
Slack, Discord, Telegram, WhatsApp, webhooks, cron, CRM, local LLM — the connectors are already in the box.
- Socials engine (
socials/subpackage, ~4848 LOC, declared inrequirements-socials.txt) handles Slack, Discord, Telegram, WhatsApp, X, LinkedIn and YouTube posting through a unified compose+post adapter, surfaced at/socials. (matrix: Slack, Discord, Telegram/WhatsApp) - Webhook endpoints (
/api/webhooks/*) drive inbound events into the agent fleet; the/webhookspage lets you register, replay and inspect each one. Scheduled jobs run viaspark-scheduler.py(cron-style, stdlib only) and surface at/scheduled. (matrix: Webhooks, Scheduled jobs) - CRM at
/crmis wired to the lead-scraping pipeline; local LLM at/local-llmtalks to Ollama on127.0.0.1:11434(Spark workers default toqwen3.6:35b) for zero-egress inference. (matrix: CRM, Local LLM)
8. Dashboards & observability
Live fleet dashboard, real-time per-agent cost, heartbeat, per-agent chat — observability that matches the agent count.
/dashboardstreams agent state, task queue depth, and approvals backlog in real time;/agenticand/orchestrationdrill into the per-agent fleet view. (matrix: Live fleet dashboard)- Per-agent cost tracking at
/costsreads real Anthropic-shape token counts fromclaude --printJSONL transcripts — no estimates, no provider markup, every dollar attributed to the agent that spent it. (matrix: Per-agent cost tracking) - Pipeline status across the fleet at
/pipelinesand/activity; heartbeat surfaced both on the agent card and in the sidebar so a stuck agent is visible in one glance. (matrix: Pipeline status, Agent heartbeat)
9. Deployment
Self-hosted desktop or server, air-gapped by default — your machine, your bytes.
- Tauri desktop
.deb(tandem-desktop_<version>_amd64.deb) is the primary install path — one package, native window, backend auto-starts on launch and stops on close. README §“Install (Desktop App)”. (matrix: Self-hosted) - Server-only
.deb(tandem_<version>_all.deb) runs as a systemd service for server peers, exposing the browser UI on127.0.0.1:3000; same build pipeline, no Docker required. (matrix: Self-hosted server flavor) - Air-gapped by default: stdlib-only Python backend (no
pip installat runtime), every service binds127.0.0.1, andsafe-scrape.pyis the only sanctioned path to fetch external content. The build-deb scanner gate fails fast on any personal identifier before sha256 emission. (matrix: Air-gapped / on-prem)