Based 2.0
Where humans and agents work together.
Based is a personal AI workflow platform that turns your filesystem into a shared workspace for you and your AI agents. It orchestrates Claude, Codex, Gemini, and Ollama from a single control plane โ CLI, API, MCP, and web UI.
Based doesn't wrap providers behind a proxy or replace their CLIs. It runs them as real terminal sessions, coordinates their work through a shared filesystem, and gives you full visibility into what they're doing.
What's in the box
๐ฅ๏ธ Terminal-First
tmux sessions are the real workspace. Based launches, monitors, and coordinates them. Real PTY, real shell, real tools.
๐ 13 Queryable Domains
Projects, sessions, artifacts, git, logs, memory, config, health, views, usage, files, hosts โ all searchable from one API call.
๐ค Multi-Provider
Claude, Codex, Gemini, Ollama. Same workspace, same tools, same context. Providers compete on strengths, not lock-in.
๐ง Agent System
11 specialized agents, skill definitions, slash commands, hooks, and a memory system that persists across sessions.
๐ฌ Messaging
Three messaging pathways: Box (file drop), Msg (structured mailbox), Beam (real-time tmux). Agents communicate without HTTP.
๐ Web UI
24 navigation modes, Monaco editor, integrated terminal, kanban, notes, dashboards โ with adaptive shells for phone, tablet, and desktop.
Architecture at a glance
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ You / Agent โ
โโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโค
โ CLI โ Web UI โ MCP โ REST API โ
โ base * โ :1337 โ 123 tools โ /api/* โ
โโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโโโโโโค
โ based-api (:31337) โ
โ 13 domain adapters ยท agent query ยท orchestrator โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Filesystem (DATA_ROOT) โ
โ bases ยท sessions ยท memory ยท config ยท telemetry โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Intelligence Providers โ
โ Claude CLI ยท Codex CLI ยท Gemini CLI ยท Ollama โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Quick links
- Quick Start โ first session in 2 minutes
- CLI Reference โ terminal command reference
- REST API โ full endpoint reference
- MCP Server โ 123 tools for native agent access
- Agent System โ specialized agents and skills
Quick Start
Create a base and start a provider session.
1. Initialize a base
# In any project directory
base new myproject
Creates a base.md manifest. Based discovers it automatically on the next scan.
2. Start a session
base start myproject
Launches a tmux session with your preferred AI provider. Based auto-selects from the intelligence chain, or you can specify:
base start myproject --provider claude
base start myproject --provider codex
3. Check status
base status
Reports active tmux sessions, project count, and git state.
4. Query across everything
# CLI (via API)
curl -s "http://localhost:31337/api/agent/query?q=deploy" -H "Authorization: Bearer $TOKEN"
# MCP (from any connected agent)
based_query({ query: "deploy" })
Searches all 13 domains in parallel โ projects, sessions, files, git, logs, memory, config, and more.
5. Open the web UI
# Default: http://localhost:1337
open http://localhost:1337
Full IDE-like interface with 24 navigation modes, Monaco editor, integrated terminal, and real-time filesystem sync.
Core Concepts
The ideas that make Based work.
Bases
A base is any directory with a base.md manifest. It's the atomic unit of Based โ a project, a service, a set of docs, a task. Based discovers bases by scanning DATA_ROOT and its subdirectories.
# base.md frontmatter
---
name: my-api
type: code
realm: production
tags: [api, express, deployed]
lifecycle: active
priority: high
---
# my-api
Express backend for the main product.
## Notes
- Deployed to .11
- Uses PostgreSQL
Convention over configuration
Based uses typed subdirectories under DATA_ROOT:
code/โ source code projectshost/โ infrastructure configsagent/โ agent definitionsspace/โ workspaces and planningtask/โ task-scoped work
Drop a directory in the right place with a base.md, and Based picks it up. No registration, no imports, no config files.
Sessions
Sessions are real tmux terminal sessions where AI providers run. Based discovers sessions from provider-specific stores:
~/.claude/projects/**/*.jsonlโ Claude Code~/.codex/sessions/YYYY/MM/DD/*.jsonlโ Codex~/.gemini/sessions/*.jsonlโ Gemini
Every session has token counts, tool call history, and timing metadata โ all queryable from the API.
The filesystem is the database
Based doesn't use a database. Project manifests, memory files, config, mailbox messages, telemetry โ everything is a file. This means:
- Git tracks all changes automatically
- Any editor can modify any data
- Agents read and write directly โ no ORM, no migration
- Backup is
rsync
Agent-first design
Every API endpoint returns structured, typed data. The Agent API (/api/agent/) is self-describing โ one call returns every domain, every field, every filter, and example queries in natural language. Any agent can understand the entire platform without reading documentation.
CLI Reference
Terminal-native command reference.
The base command dispatches to base-<cmd> scripts. All commands share helpers from base-lib (path resolution, telemetry, hooks).
Sessions
| Command | Alias | Description |
|---|---|---|
base start <name> | s | Launch or resume a tmux session with provider selection |
base kill <name> | k | Stop a session (runs post-kill hooks) |
base list | ls, l | List projects with optional realm, type, path, and description output |
base status | st | Show active tmux sessions, registered project count, and git state for active sessions |
Project
| Command | Alias | Description |
|---|---|---|
base new <name> | n | Scaffold a new base with manifest |
base manifest | โ | Scan, read, validate, and migrate canonical base.md manifests |
base wiki | โ | Initialize, browse, ingest, query, apply, and lint per-base wiki pages |
base migrate | mig | Check or perform lossless legacy .base.yaml to base.md migration; writes require confirmation |
base migration | โ | Dry-run, back up, restore, or self-test data migrations |
Messaging
| Command | Alias | Description |
|---|---|---|
base box | bx | List project box items, send messages or files, mark items done, or clear the box |
base inbox | in | Compatibility alias for base box |
base msg | โ | Active mailbox transport with send, inbox, and channel-scoped acknowledgment |
base mail | โ | Passive mailbox transport with send, inbox, and channel-scoped acknowledgment |
base beam | send | Send keystrokes to one tmux session or broadcast to all active sessions |
System
| Command | Alias | Description |
|---|---|---|
base doctor | โ | Check system health, base capabilities, provider drift, and instruction parity |
base mcp-sync | mcp | Resolve .mcp.json and synchronize Claude, Codex, and Gemini MCP configuration |
base selftest | test | End-to-end integration suite |
base docs | d | Generate shell aliases for ~/.bashrc |
base telemetry | tele | View CLI telemetry for the last day, week, or all time |
base clip | c | Save, list, search, copy, delete, or clear clipboard history |
base flags | flag | List feature flags or set a flag to true or false |
Orchestration
| Command | Alias | Description |
|---|---|---|
base swarm | โ | Start plans, add tasks, inspect status, and stop tasks or plans |
base memory | โ | Extract plan memory, run dream consolidation, or compact stored plans |
Analysis
| Command | Alias | Description |
|---|---|---|
base audit | โ | Run a read-only pain-pattern audit over transcripts, mailbox, system journal, telemetry, and MCP lifecycle |
base mine | โ | Index and query git, mailbox, transcript, telemetry, audit, and loop history without modifying source corpus files |
Shell Aliases
Generated by base docs --apply.
b โ base
bl โ base list
bs โ base status
ho โ base inbox
bd โ base doctor
Realm wrappers
Based provides realm-aware credential wrappers for common CLIs:
wr <cmd> โ Wrangler (Cloudflare), injects token by realm
aw <cmd> โ Appwrite, switches profile by realm
gh-wrap <cmd> โ GitHub CLI, switches account by realm
Realm mapping is configured in cli-profiles.yaml.
System Architecture
Two services, one filesystem, many providers.
Services
| Service | Port | Scope | Description |
|---|---|---|---|
based-api | 31337 | Loopback only | Express + MCP server. Domain adapters, agent query, orchestrator, mailbox. |
based-web | 1337 | All interfaces | Express + React SPA (Vite). File ops, terminal, search, git, explorer. Proxies /api/based/* to based-api. |
@based/shared | โ | Library | Shared errors, logger, path/validation helpers, intelligence query. |
WebSockets
/wsโ real-time filesystem change events (file create/update/delete)/ws-terminalโ interactive terminal I/O (shell access from the browser)
Proxy architecture
based-web sits in front. Browser calls hit :1337, which strips Origin headers and injects the bearer token before forwarding to :31337. The browser never sees the API token.
Deploy model
Based separates development and production onto different machines. Edits happen on dev, deploys push to production via rsync, and builds always happen on the target machine (never locally) to avoid chunk hash drift between environments.
Data Layer
The filesystem is the database.
Canonical roots
DATA_ROOT=/data # default
BASED_SCAN_ROOTS=/data # discovery paths
Typed subdirectories:
code/โ source code projectshost/โ infrastructure configsagent/โ agent definitionsspace/โ workspaces and planningtask/โ task-scoped work
Base manifests
Canonical format is base.md โ markdown with YAML frontmatter:
---
name: my-project
type: code
realm: production
tags: [api, express]
lifecycle: active
completion: 0.7
priority: high
assignee: tree
depends_on: [shared-lib]
custom:
deploy_target: ".11"
---
# my-project
Project description and notes here.
base.md is the only active manifest format. Legacy .base.yaml support was retired after the canonical cutover; base migrate remains as a one-shot recovery tool.
Global config
Lives in /data/based/config/:
| File | Purpose |
|---|---|
.env | Secrets, ports, paths |
flags.yaml | Feature flags |
cli-profiles.yaml | Realm โ credential mapping |
hosts.yaml | Infrastructure inventory |
intelligence.yaml | AI provider chain + health |
basedrc | Shell config |
tmux.conf | tmux session config |
telemetry.jsonl | Unified append-only telemetry |
Per-base artifacts
.claude/
agents/*.md โ agent definitions
skills/*/SKILL.md โ reusable skills
commands/*.md โ slash commands
settings.json โ hooks, permissions, shortcuts
hooks/ โ pre/post-tool-use scripts
.mcp.json โ per-base MCP server config
.memory/
MEMORY.md โ memory index
topics/*.md โ topic-scoped memory files
13 Domains
Everything is queryable.
Based organizes all data into 13 domain adapters. Each domain is searchable individually or via cross-domain fan-out (/api/agent/query). Each adapter has a 5-second timeout; partial failures are surfaced in data.errors.
| Domain | Description |
|---|---|
projects | Discovered bases โ name, path, type, realm, tags, lifecycle |
sessions | Provider sessions with token/tool metadata (Claude, Codex, Gemini) |
artifacts | CLAUDE.md, agents, rules, commands, hooks, skills, MCP configs |
git | Status, branch, recent commits per base |
logs | Service + tmux logs, searchable |
memory | MEMORY.md + topic files per base |
config | Base manifests (frontmatter fields) |
health | Node + service state |
views | Artifact aggregation (shared scanner) |
usage | Token + cost analytics across providers |
files | File listing + content (parallel per-project scan, budget-limited) |
hosts | Infrastructure inventory from hosts.yaml |
wiki | Ingested docs โ semantic search, lint state, page lifecycle |
Cross-domain search
# Search across all 13 domains
GET /api/agent/query?q=deploy
# Response shape
{
"results": [...],
"errors": [...],
"meta": {
"byDomain": {
"projects": 3,
"files": 12,
"git": 5,
...
}
}
}
REST API
Full endpoint reference.
based-api (port 31337)
Agent API
| Method | Path | Description |
|---|---|---|
| GET | /api/agent | Self-describing manifest โ every domain, field, filter |
| GET | /api/agent/query?q= | Cross-domain fan-out search |
| GET | /api/agent/:domain | List per domain |
| GET | /api/agent/:domain/:id | Entity detail |
| GET | /api/agent/projects/:name/full | Multi-domain aggregate for one project |
Core
| Method | Path | Description |
|---|---|---|
| GET/POST | /api/bases | Manifest CRUD + stats |
| GET | /api/hosts | Infrastructure inventory from hosts.yaml |
| GET | /api/based/sessions | Provider session discovery |
| GET | /api/based/sessions/stats | Session summary |
| GET | /api/based/sessions/:id/messages | Session message history |
| GET | /api/based/sessions/:id/tools | Session tool call history |
| GET | /api/based/status | Live base status summary |
| GET | /api/based/logs | Log search |
| GET | /api/based/usage | Token + cost stats |
| GET | /api/based/views | Artifact aggregation |
| * | /api/messages | Mailbox + ack (seq model) |
| * | /api/notes | Markdown note CRUD |
| * | /api/orchestrator | Plans, tasks, verification, memory/dream |
| GET | /api/intelligence | Providers + health + query |
| * | /api/claude-accounts | Account management |
| GET | /api/system | Diagnostics + telemetry |
based-web (port 1337)
File operations
| Method | Path | Description |
|---|---|---|
| GET | /api/files/content | Read text file |
| GET | /api/files/raw | Stream binary with Content-Type |
| GET | /api/files/list | Flat file listing |
| POST | /api/files/write | Write file |
| POST | /api/files/move | Move/rename |
| POST | /api/files/mkdir | Create directory |
| POST | /api/files/upload | Upload file |
| DELETE | /api/files/ | Delete file |
Explorer + Search
| Method | Path | Description |
|---|---|---|
| GET | /api/explorer/:baseId/list?path= | Lazy directory listing |
| GET | /api/explorer/__all__/list | All registered bases |
| GET | /api/explorer/:baseId/artifacts | Claude artifact discovery |
| GET | /api/search | Content search |
| GET | /api/git | Status, branch, history |
Other
| Method | Path | Description |
|---|---|---|
| * | /api/terminal | Terminal session control |
| * | /api/kanban | Board persistence |
| * | /api/templates | Template CRUD |
| GET | /api/music | Local track control |
| GET | /api/processes | tmux process summary |
| GET | /api/cli-tools | Detected binaries + health |
| GET | /api/system | Host metrics, telemetry, CLI detection |
Authentication
Bearer token, timing-safe.
API token
The API accepts the configured API_TOKEN as a bearer token. It does not issue API tokens through a login route.
curl -s http://127.0.0.1:31337/api/agent/ \
-H "Authorization: Bearer $API_TOKEN"
Web proxy
The web frontend at :1337 handles auth transparently โ it strips Origin headers and injects the bearer token before forwarding to the API. The browser never sees the raw token.
Security model
- Bearer token with timing-safe comparison (no timing attacks)
- API server binds to loopback only (:31337) โ not reachable from network
- Path validation: base-path containment checks reject directory traversal
- File APIs surface all entries (including dotfiles) โ no hidden policy, full transparency
MCP Server
123 tools for native agent access.
Based exposes 123 registered tools over the Model Context Protocol, spanning platform data, coordination, workspace operations, automation, and infrastructure. The generated registry validates every tool against the capability registry.
| Role | Allowed tools |
|---|---|
coordinator | 123 |
worker | 95 |
observer | 61 |
Identity
| Tool | Description |
|---|---|
based_whoami | Returns your agent identity: who you are, what project you're in, and who your peers are. |
based_peers | List active agents in your project that you can communicate with. |
based_agent_bootstrap | Agent-first orientation in one call. |
based_agents_list | List configured sub-agents from parent base.md manifests, including their canonical tmux session names when valid. |
Coordination
| Tool | Description |
|---|---|
based_agent_contact | Unified agent-to-agent send. |
based_agent_followup | Inspect or advance an outstanding wait. |
based_inbox | Read your inbox โ messages other agents have sent you. |
based_ack | Advance your inbox cursor to a sequence number after processing messages. |
based_message | Active: writes the message to the recipient's mailbox AND sends an activation ping to their tmux session. |
based_mail | Passive: writes to the recipient's mailbox only. |
based_send_raw | Inject text directly into a tmux terminal session. |
based_session_read | Read the terminal screen of another agent's tmux session. |
Query and Projects
| Tool | Description |
|---|---|
based_query | Cross-domain search across all 13 based domains (projects, sessions, artifacts, git, logs, memory, config, health, hosts, views, usage, files, wiki) |
based_projects_list | List registered projects with metadata, tags, and paths |
based_project_full | Get full project aggregate โ all domains for a single project |
based_sessions_list | List Claude Code sessions with summaries and timestamps |
based_artifacts_list | List Claude Code artifacts (CLAUDE.md, agents, rules, commands, hooks, skills, MCP servers) |
based_config_get | Get project configuration (base manifest) including deploy config, Claude flags, hooks |
based_usage_stats | Get Claude Code usage statistics (tokens, costs, sessions) per project |
based_logs_search | Search tmux session logs and operation logs |
based_system_guide | Full Based platform reference โ architecture, CLI tools, API endpoints, MCP tools, deploy procedures, conventions, and safety boundaries. |
Git and Repositories
| Tool | Description |
|---|---|
based_git_status | Get git status for a project โ branch, recent commits, modified files |
based_git_host_status | Read-only status for a project's configured git host (Forgejo or GitHub). |
based_git_host_sync | Push every git-tracked base with git.host=forgejo to the local Forgejo on demand. |
based_git_host_list | List all repos on the configured git host (currently Forgejo). |
based_repo_log | Recent commits on a Forgejo repo. |
based_repo_diff | Compare two refs on a Forgejo repo via the compare API. |
based_repo_issue_list | List issues on a Forgejo repo. |
based_repo_push | Push a single project to Forgejo on demand. |
Health and Doctor
| Tool | Description |
|---|---|
based_health_check | Check health status of all registered nodes and services |
based_base_doctor | Self-diagnose against the onboarding contract. |
based_mcp_health | Inspect this Based MCP server instance: uptime, identity, registered tool count, and recent lifecycle events |
based_connections | List devices currently connected to the Based web UI. |
Deploy and Authentication
| Tool | Description |
|---|---|
based_env_check | Validate current agent's credentials for one or more services. |
based_auth_recheck | Non-destructive auth re-resolution. |
based_auth_refresh | DESTRUCTIVE โ rotates/restores stored credentials for a service. |
based_preflight | Run pre-deploy checks for a project without actually deploying. |
based_deploy | Deploy a project component to its configured target. |
based_deploy_status | Check the health of a project's deployed services. |
based_cloudflare_deploy | DEPLOY a Cloudflare project (Pages or Workers โ wrangler routes based on the project's wrangler.toml). |
based_cloudflare_logs | Tail recent Cloudflare logs for a project. |
Wiki
| Tool | Description |
|---|---|
based_wiki_pages | List wiki pages for a base, or read a specific page by path |
based_wiki_search | Search wiki pages by content/title/path |
based_wiki_update | Write a wiki page directly under .wiki/pages for a base. |
based_wiki_delete | Delete a wiki page under .wiki/pages. |
based_wiki_ingest_start | Start an async wiki ingest job from URL, inline text, or a base-scoped source file |
based_wiki_job_get | Get wiki ingest job status/details |
based_wiki_job_apply | Apply proposed wiki page changes for a completed ingest review job |
based_wiki_query | Query wiki pages and synthesize a retrieval summary answer |
based_wiki_lint | Run wiki lint checks (orphan pages, broken links, stubs, missing titles) |
Clipboard
| Tool | Description |
|---|---|
based_clip_list | List recent clipboard history entries captured from Based terminal and CLI copy paths |
based_clip_search | Search clipboard history text with case-insensitive substring matching |
based_clip_save | Append text to clipboard history |
based_clip_delete | Delete one clipboard history entry. |
based_clip_clear | Clear clipboard history. |
Files
| Tool | Description |
|---|---|
based_files_search | Search for files by name or content across projects |
based_files_list | List files in a base-relative directory. |
based_files_read | Read one file from a base using a base-relative path. |
based_files_write | Write one UTF-8 text file inside a base. |
based_files_mkdir | Create a directory inside a base. |
based_files_move | Move or rename a file/directory inside one base. |
based_files_delete | Delete a file or directory inside a base. |
Uploads
| Tool | Description |
|---|---|
based_uploads_create | Create an upload from base64 content. |
based_uploads_get | Read upload metadata by id, including rawUrl and viewUrl. |
based_uploads_list | List uploads, optionally scoped to one base. |
based_uploads_delete | Delete an upload metadata record so raw/view URLs stop resolving. |
Notes
| Tool | Description |
|---|---|
based_notes_list | List notes, optionally scoped to one base. |
based_notes_get | Read a single note by id |
based_notes_create | Create a note attached to a base |
based_notes_update | Update a note. |
based_notes_delete | Delete a note. |
Kanban
| Tool | Description |
|---|---|
based_kanban_list_boards | List Kanban boards, optionally scoped to one base. |
based_kanban_get_board | Read a Kanban board with columns and cards |
based_kanban_create_board | Create a Kanban board for a base |
based_kanban_create_card | Create a Kanban card in a column |
based_kanban_update_card | Update a Kanban card. |
based_kanban_move_card | Move a Kanban card to a column and position. |
based_kanban_get_board_activity | Read recent Kanban board activity events with agent/human provenance |
based_kanban_subscribe_board_activity | Return a polling cursor for Kanban board activity. |
based_kanban_delete_card | Delete a Kanban card. |
based_kanban_delete_board | Delete a Kanban board. |
Loops
| Tool | Description |
|---|---|
based_loops_list | List configured loops with state, cadence, and history preview |
based_loops_get | Read one loop detail including manifest, prompt, state, and recent history |
based_loops_create | Create a loop from structured settings |
based_loops_run | Trigger an immediate non-destructive loop run. |
based_loops_pause | Pause a loop |
based_loops_resume | Resume a paused loop |
based_loops_update_settings | Update structured loop settings and/or prompt. |
based_loops_archive | Archive a loop to .trash. |
Memory
| Tool | Description |
|---|---|
based_memory_search | Search unified memory across base .memory/MEMORY.md, read-only provider harness memory, and central legacy memory. |
based_memory_list | List unified memory records across base memory, provider harness memory, and central legacy memory. |
based_memory_get | Read one base memory file in full. |
based_memory_create | Create a new memory file. |
based_memory_update | Replace an existing memory file. |
based_memory_append | Append to an existing memory file. |
based_memory_delete | Delete a memory file. |
Hosts
| Tool | Description |
|---|---|
based_hosts_list | List registered infrastructure hosts (servers, VMs, networks) |
based_hosts_get | Read one registered host or VM by name. |
based_hosts_create | Create a registered infrastructure host in hosts.yaml. |
based_hosts_update | Update a registered infrastructure host in hosts.yaml. |
based_hosts_delete | Delete a registered infrastructure host from hosts.yaml. |
Bases
| Tool | Description |
|---|---|
based_bases_create | Create a new base directory, canonical base.md manifest, and provider-native CLAUDE.md, AGENTS.md, and GEMINI.md instruction roots through the managed instruction lifecycle. |
based_bases_update | Update a base manifest through the canonical base.md writer. |
based_bases_delete | Delete a base manifest by default, or the whole base directory when deleteFiles=true. |
Tmux
| Tool | Description |
|---|---|
based_tmux_list_sessions | List tmux sessions with base/provider attribution and optional runtime metadata. |
based_tmux_get_session | Read one tmux session screen with optional full-history capture and runtime metadata. |
based_tmux_start_session | Start a canonical agent or configured sub-agent tmux session with base start. |
based_tmux_send_keys | Send literal text to a tmux session, optionally followed by Enter. |
based_tmux_restart_session | Restart a canonical agent tmux session by killing it and running base start again. |
based_tmux_kill_session | Kill one tmux session and remove its Based runtime record. |
Processes
| Tool | Description |
|---|---|
based_processes_list | List OS processes with port and tmux attribution, optionally filtered by base. |
based_processes_kill | Signal an OS process. |
based_processes_restart | Restart an allowlisted system service via systemctl. |
Views
| Tool | Description |
|---|---|
based_views_list | List view definitions and their discovered artifacts (repos, agents, skills) |
based_views_artifact_create | Create a provider instruction file or Claude agent, skill, or command artifact. |
based_views_artifact_update | Replace a provider instruction file or Claude agent, skill, or command artifact. |
based_views_artifact_delete | Delete a Claude agent, skill, or command artifact. |
Intelligence
| Tool | Description |
|---|---|
intelligence_query | Send a prompt to AI providers (codex, gemini, ollama, claude) with automatic fallback by priority |
intelligence_profiles | Read the unified intelligence profile catalog with exact model ids, backend execution health, quota health, model availability, and approval-gated candidates. |
intelligence_providers | List all configured AI providers with health status, priority, and type |
intelligence_health | Health-check all AI providers and update their status |
Registry and Drift
| Tool | Description |
|---|---|
based_capability_registry | Inspect the Based capability registry: UI routes, REST routes, MCP tools, CRUD coverage, compact parity, cross-base behavior, sidebar use, confirmations, and known gaps per domain. |
based_provider_drift_check | Read-only provider CLI drift check. |
Web Frontend
24 routes. Three shells. One state.
What's in it
- File explorer โ lazy-loaded tree with Monaco code editor
- Terminal โ full interactive shell (tmux sessions from the browser)
- Session browser โ see every AI session, token usage, tool calls
- Kanban โ persistent boards for task tracking
- Notes โ markdown scratch space
- Memory browser โ view/search agent memory topics
- Real-time sync โ filesystem changes appear instantly via WebSocket
Adaptive shells
The web UI uses three physical shell components instead of one responsive layout:
- CompactShell (<640px) โ single pane, bottom tab bar, sheets for secondary content
- TabletShell (640โ1024px) โ icon rail, slide-over panels
- DesktopShell (1024px+) โ full 5-column IDE layout, ultrawide-aware
All three consume the same Zustand store. Shared state, distinct rendering. Desktop-only features render a placeholder on compact โ not a broken miniature.
Terminal
tmux is the workspace. Based gives you a window into it.
Every Based session is a tmux session. When you run base start, it creates a tmux session, launches your AI provider inside it, and wires up the context. When you run base beam, it sends keystrokes to that tmux session. When you run base kill, it stops it. tmux is the backbone โ Based orchestrates on top of it.
The web UI gives you access to these sessions from the browser. You can launch sessions, watch their output, type into them, split into panes, and broadcast commands โ all without leaving the Based interface.
Launching sessions
The fastest way to start working is the Quick Command panel in the right sidebar. Pick a base and a provider, click, and you're in a session:
# From the CLI:
base start myproject # auto-select provider
base start myproject --provider claude # specific provider
base start myproject --provider codex # or codex, gemini, ollama
Sessions persist independently of the browser โ close the tab, come back later, the tmux session is still running. Reattach from the web UI or from your local terminal with tmux attach.
Panes and layouts
Split the terminal view into multiple panes to watch several sessions at once:
- Groups โ up to 2 panes per group, unlimited groups
- Grid mode โ maximize to see all panes at once (2-up, L-layout, or auto-grid)
- Per-pane focus โ click a pane to focus it, the rest stay visible
Broadcast mode
Toggle broadcast to type the same input into every pane simultaneously โ useful for running the same command across multiple projects or providers at once.
Beam (remote keystrokes)
Send commands to any tmux session without switching to it:
base beam myproject "npm test" # type into a specific session
base beam --all "git pull" # broadcast to every session
This is how agents communicate in real-time โ beam is one of the three messaging pathways alongside Box and Msg.
Context sidebar
When the terminal is active, the right sidebar shows Quick Commands โ one-click launch buttons organized by base ร provider. No typing base start every time.
Agent System
8 specialists. Skills, commands, hooks.
Based ships with 11 specialized agent definitions in .claude/agents/. Each agent gets a focused role, relevant context, and appropriate tool access.
Specialized agents
| Agent | Role |
|---|---|
auditor | Codebase audits, gap analysis, compliance |
pain-auditor | Surfaces pain patterns from audit output |
test-author | Writes regression tests from pain patterns |
tester | Playwright + integration tests |
bug-fixer | Root-cause analysis + targeted fixes |
fix-proposer | Generates fix proposals against audit findings |
reviewer | Code review against project standards |
frontend-dev | React / TypeScript / Tailwind |
backend-dev | Express / Node / API work |
cli-dev | Bash / CLI scripting |
docs-writer | Reference documentation |
Supporting artifacts
.claude/skills/*/SKILL.mdโ reusable skill invocations.claude/commands/*.mdโ slash commands for interactive use.claude/settings.jsonโ hooks, permissions, shortcuts.claude/hooks/โ pre/post-tool-use scripts (approval gates, logging)
Intelligence Layer
Session adapters, model profiles, and observable routing.
Based separates provider-backed terminal sessions from intelligence execution. Session adapters discover and load work from four provider families. Intelligence providers and profiles determine how model-backed platform tasks execute.
Session adapters
| Provider | Session role |
|---|---|
| Claude | Claude Code sessions and transcripts |
| Codex | Codex sessions and transcripts |
| Gemini | Gemini sessions and transcripts |
| Ollama | Local Ollama sessions |
Session selection remains direct:
base start myproject --provider claude
base start myproject --provider codex
base start myproject --provider gemini
base start myproject --provider ollama
Providers and profiles
An intelligence provider defines an execution backend: command or API route, enabled state, priority, health, and whether it participates in automatic selection. A profile selects a specific model and carries its provider, model ID, quota family, smoke command, enabled state, and routing metadata.
| Choice | Behavior |
|---|---|
auto | Try enabled, auto-eligible providers in routing order |
provider-default | Use one provider backend without choosing a model profile |
profile | Use the exact provider and model declared by a Based profile |
GET /api/intelligence/profiles returns the unified read-only choice catalog. Each row combines execution health, provider binary state, quota health, model availability, deprecation state, and selectability. Reading the catalog never invokes a model or changes configuration.
Automatic execution
Automatic queries consider enabled providers whose autoEligible value is not false. Lower priority values run first. Providers explicitly marked unhealthy remain fallback-only instead of being silently removed. The first successful non-empty response wins; otherwise the query returns the last failure.
POST /api/intelligence/query
{
"prompt": "Summarize current deployment risk",
"selection": { "kind": "profile", "value": "codex_sol" }
}
Routing tiers
Tier policy is observe-first: it exposes configured routes, quota posture, and recent would-route decisions without invoking a provider or changing provider configuration.
| Tier | Cadence | Profiles | Degrades to |
|---|---|---|---|
reflex | 15 minutes | codex_spark | โ |
narrative | Daily | codex_sol, then claude_opus | reflex |
council | Weekly and monthly | codex_sol and claude_opus | narrative |
GET /api/intelligence/tiers/status reports the current policy and observations. Journal cadence assignments are exposed separately through /api/intelligence/journal-settings.
Model discovery and approval
Model Discovery is a source-managed loop. Provider CLIs and APIs are treated as the catalog authority. The loop records model IDs, aliases, visibility, profile state, quota metadata, and source health without storing credentials, prompts, model responses, or raw provider output.
GET /api/intelligence/model-availabilityreads the latest stored discovery report and never launches a provider CLI.- A discovered candidate is not enabled or routed automatically.
- Enabling a candidate profile requires an explicit operator action and a fresh successful discovery report.
- Assigning an enabled profile to a tier or Journal cadence is a separate explicit action.
- A profile cannot be disabled while a tier still selects it.
Health and quota
| Endpoint | Signal |
|---|---|
GET /api/intelligence/providers | Configured provider backends and current public configuration |
GET /api/intelligence/health | Refresh provider execution health |
GET /api/intelligence/usage-window | Rolling provider token usage against configured plan limits |
GET /api/intelligence/profiles | Combined execution, binary, quota, and model-availability health |
Provider drift
The provider drift check is read-only. It reports resolved CLI paths and versions, install source, shadowed installs, MCP configuration drift, lifecycle-path evidence, and agent resource-scope status. It does not install, upgrade, rewrite configuration, change launch mode, or promote provider homes.
# API
GET /api/system/provider-drift
# MCP
based_provider_drift_check()
intelligence_profiles()
intelligence_providers()
intelligence_health()
Orchestrator Mode
Coordinator + workers + verification. Feature-flagged.
The orchestrator enables multi-agent coordination with role-based tool scoping. It's behind feature flags โ enable when ready.
How it works
- Coordinator creates a plan with discrete tasks
- Workers execute tasks with scoped tool access
- Verification step validates each completed task
- Communication happens via the mailbox system
Role-scoped tools
When role_scoped_tools flag is enabled:
| Role | Tools |
|---|---|
observer | Read-only query tools |
worker | Task execution tools |
coordinator | Planning + orchestration tools only (never touches files) |
Feature flags
coordinator_modeโ enable the coordinator rolerole_scoped_toolsโ restrict tools by agent roleverify_executionโ require verification after task completion
CLI
base swarm start "ship the release"
base swarm status [planId]
base swarm task <planId> "run verification" --verify
base swarm stop <planId>
Memory System
Persistent context across sessions.
Each base gets a .memory/ directory that persists across sessions. Agents read from it automatically; Based indexes it for search.
Structure
.memory/
MEMORY.md โ index file, always loaded into context
topics/
deploy.md โ deployment notes and procedures
gotchas.md โ hard-won debugging lessons
preferences.md โ coding style and conventions
architecture.md โ design decisions and rationale
Pipeline
base memoryโ manual extraction + consolidation- Auto-dream (feature-flagged:
auto_dream,auto_memory_extract) โ background pipeline that synthesizes sessions into memory topics automatically
Search
# MCP
based_memory_search({ query: "deploy procedure" })
# API (via agent query)
GET /api/agent/memory?q=deploy
Messaging
Box. Msg. Beam. Three pathways.
Based has three messaging systems, each for a different use case. No HTTP between agents โ everything is filesystem or tmux.
Box (file drop)
Drop anything into a base's inbox/ directory. Markdown, images, links, data files. The simplest possible messaging โ it's a folder.
base box myproject # open box
base box send myproject --file note.md # drop a file
Msg (structured mailbox)
JSONL append-only files per participant under /data/based/state/mailbox/. Sequence + acknowledge model โ receivers mark messages as processed.
base msg send alice "review the deploy script" --channel based-web:general
base msg inbox alice --channel based-web:general
base msg ack alice 5 --channel based-web:general
Also available via API (/api/messages) and MCP โ see based_agent_contact, based_inbox, and based_ack.
Beam (real-time tmux)
Send keystrokes directly to a tmux session. Real-time, zero latency, no intermediary.
base beam myproject "npm test" # type into session
base beam --all "git pull" # broadcast to all
Pairs
Two agents. One project. Emergent routing.
Pairs is not a feature โ it's a behavior that emerges from Based's existing primitives. When two AI providers work the same project, they communicate through the shared filesystem and mailbox system. Over time, they start routing tasks to each other based on strengths.
How it works
- Start two sessions on the same base with different providers
- They share: filesystem,
.memory/, mailbox, git state - Msg and Box handle coordination โ no orchestrator needed
- Each provider develops a model of the other's strengths
base start myproject --provider claude # session 1
base start myproject --provider codex # session 2
# They communicate via:
base msg send codex "review the auth module"
base box send myproject --file findings.md
Why it works
Different models have genuinely different strengths. Opus excels at architecture and nuanced decisions. Codex is faster at file-level edits and test writing. When they can communicate, they self-organize around these strengths without being told to.
Deploy Pipeline
Release-aware development and production deployment.
Development and production use separate scripts. Production deployment runs preflights, preserves protected runtime configuration, promotes versioned releases, and supports rollback. Source commits remain an explicit operator action.
Commands
./deploy/deploy-dev.sh all # build + adopt a release locally
./deploy/deploy-prod.sh all # promote a release to production
./deploy/deploy-prod.sh all --smoke # deploy with post-deploy smoke checks
./deploy/deploy-prod.sh health # verify API + web are responding
./deploy/deploy-prod.sh rollback previous # roll back to the previous release
Workflow
- Edit on your dev machine
- Commit changes explicitly โ deployment does not auto-commit
- Build on the target machine (never locally โ avoids chunk hash drift)
- Releases are versioned and promoted; a failed health check auto-rolls-back to the previous release
Feature Flags
Ship incrementally. flags.yaml.
| Flag | Description | Default |
|---|---|---|
coordinator_mode | Enable orchestrator coordinator role | off |
role_scoped_tools | Restrict MCP tools by agent role | on |
mailbox_ipc | File-backed mailbox messaging | on |
worktree_isolation | Git worktree per session | off |
auto_memory_extract | Auto-extract memory from sessions | off |
auto_dream | Background reflection/consolidation | off |
context_compaction_v2 | v2 compaction algorithm | off |
verify_execution | Require verification after tasks | off |
# View flags
base flags
# Set a flag
base flags set coordinator_mode true
Configuration
Convention-driven. Minimal config.
Environment
# /data/based/config/.env
DATA_ROOT=/data
BASED_SCAN_ROOTS=/data
API_TOKEN=your_token_here
PORT_API=31337
PORT_WEB=1337
basedrc
Shell configuration sourced by the CLI:
# /data/based/config/basedrc
export BASED_SCAN_ROOTS="/data"
export BASED_CONFIG_DIR="/data/based/config"
hosts.yaml
Infrastructure inventory:
hosts:
- name: gpu-server
ip: 10.0.0.10
role: proxmox
specs: "64 cores, 192GB RAM"
- name: inference
ip: 10.0.0.20
role: inference
specs: "128GB DDR5, local models"
intelligence.yaml
Provider chain:
providers:
- name: codex
priority: 1
enabled: true
- name: gemini
priority: 2
enabled: true
- name: ollama
priority: 4
endpoint: "http://localhost:11434"
enabled: true
Telemetry
Append-only. Local-only. Your data.
Based logs usage events to a single JSONL file. No external services, no analytics platforms. The data stays on your machine.
Sources
Events are collected from three surfaces, all appending to the same file:
- CLI โ every
basecommand, session start/stop - API โ deploy events, per-route instrumentation
- Web UI โ navigation, file saves, searches, messaging
Event types
| Source | Events |
|---|---|
| CLI | cli_command, session_started, session_ended |
| API | deploy_started, deploy_completed, per-route instrumentation |
| Web | tab_viewed, file_saved, search_performed, box_sent, msg_sent, beam_sent |
Read
GET /api/system/telemetry?period=24h # last 24 hours
GET /api/system/telemetry?period=7d # last week
GET /api/system/telemetry?period=all # everything
base telemetry # CLI view
The recent-activity homepage widget is the live visualization of this data.
Flow Triggers
Your workspace knows deep work isn't just code โ it's state of mind.
What it is
Based includes a built-in audio player designed for one thing: getting into flow state. This isn't a music app. There's no library browser, no recommendations, no social features. You queue a few tracks you already know work for you, hit play, and forget about it for hours.
Why it's in a dev tool
Research supports what deep workers already know intuitively: intentional music selection โ choosing specific tracks to regulate your cognitive state โ has a direct positive effect on performance (PMC, 2023). Not background noise. Not Spotify's algorithmic playlist. The three songs you've listened to 400 times that flip the switch in your brain.
The key finding: autonomous control over music (choosing what, when, and why) is what drives the benefit. That's why it's built in. You stay in your workspace. No alt-tab, no context switch, no notification from a streaming app breaking your concentration.
Where it lives
Flow triggers are web-only. The web server exposes GET /api/music/tracks (list audio files in $MUSIC_DIR, default /data/music/tracks) and GET /api/music/stream/:filename (stream with HTTP Range support). Playback โ queue, loop, current track โ lives client-side in the mini-player bar.
Design principles
- Minimal surface. Queue, play, pause, skip, loop. That's it. If you want equalizers and crossfade, use a music app.
- Local files only. No streaming integration, no API keys, no accounts. Your MP3s, your FLAC files, your WAVs. Drag from Finder, paste a path, done.
- Loop-first. Default behavior is queue loop. Most flow state usage is the same 2โ5 tracks on repeat for an entire session. The player assumes that.
- No interruptions. No "up next" popups, no end-of-track silence, no notifications. Gapless playback. The audio is infrastructure, not an experience.
- Session-scoped. Your queue lives with your Based session. Different projects can have different flow tracks. Start a session, your flow tracks are already there.
Web UI
The web frontend includes a minimal player bar at the bottom of the workspace โ track name, progress, play/pause, skip, loop toggle. It stays out of the way. Click to expand for queue management. Collapse and it's a single 32px bar.
The philosophy
Based treats the human operator as a first-class citizen. Agents get memory, messaging, orchestration. Humans get those too โ plus the tools that sustain long sessions. Flow triggers exist because the workspace should support the whole workflow, not just the code part.
Three songs on repeat for six hours. You know the ones.
Known Gotchas
Hard-won lessons.
If you're using Based
$TMUXin the web terminal โ ifbase startfrom the web UI tries to switch your existing tmux instead of creating a new session, make sure$TMUXis unset in the terminal's shell environment. Based handles this automatically, but custom shell configs can re-set it.- YAML numbers โ YAML parses
31337as a number, not a string. If you're comparing ports or IDs in manifests, be aware that"31337" !== 31337. - Build on the production machine โ always run builds on the deploy target, not locally. Vite chunk hashes differ between machines, which breaks browser caching.
- ESM imports need
.jsextensions โ if you're writing plugins or extending Based, all TypeScript imports must include.jsin the import path. TS compiles but doesn't rewrite them.
If you're contributing to Based
See docs/HARD-WON-FIXES.md in the repo for the full developer gotchas list (pino version pinning, symlink handling in readdir, localStorage migration patterns, etc.).
Deck, Journal & Chronicle
Live execution, structured events, and synthesized operational history.
Deck, Chronicle, and Journal provide three views of ongoing work. Deck shows active sessions now. Chronicle records structured operational events. Journal synthesizes Chronicle plus direct git, release, transcript-intent, and typed-ingredient evidence into day, week, and month narratives.
Deck
Deck is the multi-session operator wall. Each column represents a session and combines identity, provider attribution, runtime status, attention state, and a bounded activity feed. Attention states distinguish work that is running, waiting on the operator, waiting on a peer, failed, stale, or has new output.
- Open a session directly in the terminal from its column.
- Pin, hide, order, group, and filter columns without changing session state.
- Use the Attention strip to find sessions requiring attention.
- Hydrate the wall once, then request cursor-based deltas for displayed columns.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/based/deck | Hydrate the operator wall |
| POST | /api/based/deck/delta | Fetch cursor-based updates for selected session columns |
Chronicle
Chronicle is the structured event corpus behind operational history. Events can be filtered by base, correlation ID, event kind, confidence, time, and result limit.
Current event kinds include shipped, fixed, launched, deployed, decided, blocked, waiting on operator, abandoned, reviewed, operator questions and decisions, incidents, and notes. Confidence is recorded as explicit, inferred, or weak.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/chronicle/summary | Read corpus summary information |
| GET | /api/chronicle/events | Read filtered Chronicle events |
| POST | /api/chronicle/backfill | Backfill events from selected mailbox, release, and git sources |
| POST | /api/chronicle/kanban-bridge/run | Run the Chronicle-to-Kanban bridge with optional dry-run and cursor controls |
Journal
Journal reads Chronicle-backed evidence into canonical operational summaries. The web view supports day, week, and month periods, base filtering, daily renditions, synthesis provenance, degraded-fallback warnings, evidence counts, and citations.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/journal/summary | Read the journal index, optionally for one base |
| GET | /api/journal/latest | Read the latest canonical digest |
| GET | /api/journal/day/:date | Read a day and optionally select a rendition |
| GET | /api/journal/day/:date/renditions | List available daily renditions |
| GET | /api/journal/week/:week | Read an ISO week summary |
| GET | /api/journal/month/:month | Read a month summary |
| POST | /api/journal/backfill | Backfill canonical journal periods |
| POST | /api/journal/candidate/backfill | Backfill a date range with optional base allowlist and synthesis controls |
Evidence flow
mailbox + releases + git โ Chronicle events โ Kanban bridge
Chronicle + git + releases + transcript intents + typed ingredients
โ
Journal day/week/month
โ
narrative + provenance + citations
Journal preserves provenance alongside prose. A fallback rendition is labeled as degraded so it is not mistaken for a successful model synthesis.
Sub-agents
Configured agents inside a base โ each with its own provider, role, and working directory.
A base can declare named sub-agents in its base.md frontmatter. Each sub-agent gets its own tmux session, provider binding, and instruction contract, while staying inside the parent base's filesystem.
Configuration
# base.md frontmatter
agents:
reviewer:
provider: claude # claude | codex | gemini | ollama (required)
instructionsFile: subagents/reviewer/CLAUDE.md
instructionContractVersion: 1
role: worker # coordinator | worker | observer (default: coordinator)
cwd: packages/api # relative path inside the parent base
model: opus # optional provider model override
custom:
args: [...] # optional extra provider CLI args
The cwd is sandboxed: it must be a relative path that resolves inside the parent base. Escapes (.., absolute paths) are rejected at start.
Lifecycle
base start mybase --agent reviewer # start the configured sub-agent
base start mybase --fork exp1 # fork a Claude session under a safe fork id
base start mybase --fork exp1 --fork-source latest # or a specific session id
Sub-agent sessions are named <base>-sub-<id>-<provider>. Versioned instruction contracts (instructionContractVersion: 1) are checked before launch and fail closed when the exact provider-native target is missing or drifted. Unversioned legacy rows remain warning-only until deliberately migrated.
Identity
based_whoami distinguishes sub-agents from primary sessions: it returns sessionKind, parentProject, and subAgentId alongside session, provider, project, role, and peers. Peers and mailbox routing resolve sub-agent session names natively.
Roles
The role binds the MCP tool allowlist for the session: coordinator (full surface), worker (execution surface), observer (read-only surface). Role scoping is enforced at the MCP layer via the role_scoped_tools flag (default on).
Loops & Automation
Operator-visible recurring work. Nothing runs that isn't in the inventory.
Based declares recurring work in one source registry. The Loops view presents operator-meaningful provider loops, source-managed system loops, ambient heartbeat state, external systemd truth, and peer parity; internal runtime mechanics surface in Status. The browser is an operational surface, not an execution owner: schedulers in the API own the clocks.
Five automation classes
| Class | What it is | Clock owner |
|---|---|---|
| Provider loops | Operator-created intelligence workflows โ /data/loops/<id>/manifest.yaml + prompt.md | Loop scheduler |
| System loops | Source-declared platform maintenance (11 definitions): model/host discovery, journal rollups, resource pressure, session cleanup and supervision, instruction lifecycle scans, provider drift, wiki lint, chronicle bridging | System-loop scheduler with lease + run history |
| Ambient services | Continuous pollers, not scheduled runs: chronicle harvester, wiki session watcher, activation watchdog | Ambient service runtime (heartbeats, bounded counters) |
| External systemd workflows | Audit and Forgejo mirror โ declared in the registry, owned by systemd. Based reports desired vs. observed state; it never starts or stops these units | systemd |
| Internal mechanics | Session expiry, terminal maintenance, API runtime clocks โ registered so recurring work can't hide from the inventory and surfaced through Status | API runtime |
Control model
Source definitions own id, cadence default, effect class, handler, requirements, timeout, and history bounds. A host override (loop-overrides.yaml) may change only the fields the definition explicitly allows โ normally enabled and cadence. State and changed-run history live under /data/based/state/system-loops/<id>/.
Surfaces
- Web โ the Loops navigation mode: inventory, run history, run-now, pause/resume where the definition allows it
- API โ
/api/loops, ambient status at/api/loops/ambient - MCP โ
based_loops_list / get / create / run / pause / resume / update_settings / archive
Kanban
Boards humans and agents move cards on together.
File-backed boards and cards with a full event log. Agents operate boards through MCP with actor attribution, so a card moved by an agent is distinguishable from a card moved by you.
Surfaces
- Web โ the Kanban navigation mode: boards, columns, drag-and-drop, activity feed
- MCP โ
based_kanban_list_boards / get_board / create_board / delete_board,based_kanban_create_card / update_card / move_card / delete_card,based_kanban_get_board_activity / subscribe_board_activity
Activity
Every mutation is an event with an actor. get_board_activity reads the log; subscribe_board_activity returns a polling cursor with a suggested next-poll interval, so an agent can poll for a card landing in its column. The chronicle bridge can mirror platform events onto boards as cards (default off; operator-controlled).
Notes
Base-associated notes shared by Web and MCP.
Note records carry a title, content, optional language (for syntax-highlighted snippets), tags, a pinned flag, and an optional base association. They live in the shared notes store, and Web and MCP clients read and write the same records.
Surfaces
- Web โ the Notes navigation mode: markdown editing, tag filters, pinning
- MCP โ
based_notes_list / get / create / update / delete
Uploads & Capture
Get files into the workspace from anywhere.
Drop a file in the web UI and it lands in the right base. The upload store enforces a size cap (100 MB default), routes into typed directories (code / host / agent / space / task), and refuses writes into protected paths. Captured items integrate with the clipboard surface for reuse.
Surfaces
- Web โ drag-and-drop upload, capture review
- API โ
/api/based/uploads - MCP โ
based_uploads_create / get / list / delete
Capability Registry
One typed map of what the platform can do โ and where.
Every capability domain (22 today: agents, notes, loops, kanban, wiki, clipboard, captures, files, sessions, terminals, mailbox, memory, bases, hosts, views, templates, processes, git, intelligence, health, usage, status) is declared once in a typed registry, with its UI, REST, and MCP coverage, CRUD actions, confirmation requirements, and known gaps recorded side by side.
Why it matters
- Parity is checkable. If a domain has a REST route but no MCP tool (or vice versa), the registry records it as a known gap instead of letting the surfaces silently diverge.
- References are generated. The MCP tool reference and role allowlists are generated from source and validated against the registry โ counts can't rot in prose.
- Drift is detected. A drift check compares the registry against the live tool surface.
Audit & Mining
The platform studies its own exhaust.
Pain-pattern audit
base audit scans Claude and Codex transcripts, mailbox and inbox state, the system journal, telemetry, MCP lifecycle, provider drift, onboarding, and coordination state for recurring pain patterns. Findings are classified, scored, and reported. Ad hoc runs default to no broadcast; the scheduled systemd service explicitly broadcasts at the critical threshold. The timer is reported on the Loops surface as an external workflow.
Three specialized agents close the loop: pain-auditor surfaces patterns and proposes fix vs. test vs. observe, test-author writes the smallest regression test that would catch a pattern, and fix-proposer drafts fixes against findings without committing them.
Corpus mining
base mine builds a read-only local SQLite index of derived metadata from git, mailbox, transcripts, telemetry, audit, and loop history. It supports SQL and metadata-only FTS queries plus a coordination-gap report. Mailbox payloads, transcript bodies, audit finding bodies, and loop narratives are not stored, and source corpus files are never mutated.
Process & Resource Safety
Observe first, confirm mutations, and recheck before termination.
Based separates pressure detection, cleanup recommendations, and termination authority. Resource monitoring is read-only. The process janitor produces advisory dry-runs only. Manual and policy-driven termination use separate confirmation and ownership checks.
Resource pressure
GET /api/system/resource-pressure returns host load, memory and swap metrics, process summaries, configured thresholds, findings, and an overall ok, warn, or critical status.
| Finding | Signal |
|---|---|
load | One-minute load average normalized by CPU core count |
command_class_rss | Aggregate RSS for a command class |
orphan_rss | RSS attributed to processes without a live session association |
runaway_tool_rss | Long-running, high-RSS search-tool processes |
Default RSS thresholds are 8 GiB for warning and 16 GiB for critical. Default load thresholds are 1.0 and 2.0 per CPU core. Deployments can override them with BASED_LEAK_RSS_WARN, BASED_LEAK_RSS_CRIT, BASED_LOAD_WARN, and BASED_LOAD_CRIT.
RSS totals are pressure heuristics because shared memory can be counted more than once across process trees. A pressure finding does not terminate a process.
Monitoring loop
The source-managed Resource Pressure loop is enabled by default on a five-minute cadence. It samples host and process pressure, records metadata-only telemetry, keeps bounded history, and can emit alerts. Its effect is messaging, not process termination. The loop compares consecutive samples and may add class_rss_growth findings.
Session and process cleanup
The Session and Process Cleanup loop is disabled by default. Its read-only report identifies eligible stale sessions, leaked processes, and local servers still running after deploy evidence.
- Observe mode never terminates anything.
- Saving cleanup policy updates metadata and scheduling only; it performs no termination.
- Active mode requires an enabled protected policy whose mode is
active. - A manual active run first presents a candidate preview and requires explicit operator confirmation.
- Every session and process is live-rechecked immediately before termination.
- Targets rejected by the live check are left running and reported as failures.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/system/session-process-cleanup | Read policy and the current observe report |
| PUT | /api/system/session-process-cleanup | Update policy metadata and loop scheduling without terminating anything |
| POST | /api/system/session-process-cleanup/deploy-event | Record metadata-only deploy evidence for later classification |
Process janitor
The intelligence-assisted process janitor is advisory. It builds a process-tree dossier and can run an approve-all dry-run that records verdicts and audit metadata. The current janitor surface has no kill endpoint and no execution branch.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/system/process-janitor | Read the process-tree dossier and policy context |
| POST | /api/system/process-janitor/dry-run | Generate advisory verdicts without executing them |
Manual process controls
The Processes view combines OS processes, listening ports, tmux attribution, command classes, host memory, and confirmed controls.
| Surface | Safety contract |
|---|---|
GET /api/based/processes | Read-only process inventory with optional user and listening-port filters |
POST /api/based/processes/:pid/kill | Requires TERM or KILL plus confirmation equal to the PID |
| Bulk process kill | Runs confirmed per-PID requests with bounded concurrency; root-owned rows cannot be bulk-killed |
| Bulk tmux kill | Runs confirmed per-session requests and preserves failed selections for review |
based_processes_kill | Requires confirm=true and refuses root- or foreign-owned processes unless the API itself runs as root |
based_processes_restart | Restarts only an allowlisted system service and requires confirm=true |
Operational endpoints
# Read current pressure
GET /api/system/resource-pressure
# Inspect processes
GET /api/based/processes
# Read cleanup candidates without action
GET /api/system/session-process-cleanup
# Generate advisory janitor verdicts
POST /api/system/process-janitor/dry-run
Philosophy
Why Based exists.
Local-first
Your tools. Your terminal. Your filesystem. No cloud dependency, no account required, no data leaves your machine. Based runs on your hardware and uses your existing AI subscriptions through their official CLIs. When a provider changes their terms, you switch โ Based doesn't care which model you use.
Terminal-native
The terminal is the workspace, not a feature of the workspace. tmux sessions are real, processes are real, file edits are real. The web UI is a window into the terminal world, not a replacement for it.
Convention over configuration
Drop a base.md in a directory. That's it. No registration, no database migration, no config files beyond the manifest. Based discovers, indexes, and serves.
Agent-first, human-usable
Every API is designed for agents to discover and use at runtime. But every interface also works for humans โ the CLI is fast, the web UI is full-featured, the docs are readable. The best tools serve both.
Co-work, not automation
Based doesn't automate humans out of the loop. It puts humans and agents in the same workspace with shared context, shared tools, and transparent communication. The human decides what matters; the agents help execute.