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

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 projects
  • host/ โ€” infrastructure configs
  • agent/ โ€” agent definitions
  • space/ โ€” workspaces and planning
  • task/ โ€” 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

CommandAliasDescription
base start <name>sLaunch or resume a tmux session with provider selection
base kill <name>kStop a session (runs post-kill hooks)
base listls, lList projects with optional realm, type, path, and description output
base statusstShow active tmux sessions, registered project count, and git state for active sessions

Project

CommandAliasDescription
base new <name>nScaffold 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 migratemigCheck 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

CommandAliasDescription
base boxbxList project box items, send messages or files, mark items done, or clear the box
base inboxinCompatibility 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 beamsendSend keystrokes to one tmux session or broadcast to all active sessions

System

CommandAliasDescription
base doctorโ€”Check system health, base capabilities, provider drift, and instruction parity
base mcp-syncmcpResolve .mcp.json and synchronize Claude, Codex, and Gemini MCP configuration
base selftesttestEnd-to-end integration suite
base docsdGenerate shell aliases for ~/.bashrc
base telemetryteleView CLI telemetry for the last day, week, or all time
base clipcSave, list, search, copy, delete, or clear clipboard history
base flagsflagList feature flags or set a flag to true or false

Orchestration

CommandAliasDescription
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

CommandAliasDescription
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

ServicePortScopeDescription
based-api31337Loopback onlyExpress + MCP server. Domain adapters, agent query, orchestrator, mailbox.
based-web1337All interfacesExpress + React SPA (Vite). File ops, terminal, search, git, explorer. Proxies /api/based/* to based-api.
@based/sharedโ€”LibraryShared 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 projects
  • host/ โ€” infrastructure configs
  • agent/ โ€” agent definitions
  • space/ โ€” workspaces and planning
  • task/ โ€” 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/:

FilePurpose
.envSecrets, ports, paths
flags.yamlFeature flags
cli-profiles.yamlRealm โ†’ credential mapping
hosts.yamlInfrastructure inventory
intelligence.yamlAI provider chain + health
basedrcShell config
tmux.conftmux session config
telemetry.jsonlUnified 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.

DomainDescription
projectsDiscovered bases โ€” name, path, type, realm, tags, lifecycle
sessionsProvider sessions with token/tool metadata (Claude, Codex, Gemini)
artifactsCLAUDE.md, agents, rules, commands, hooks, skills, MCP configs
gitStatus, branch, recent commits per base
logsService + tmux logs, searchable
memoryMEMORY.md + topic files per base
configBase manifests (frontmatter fields)
healthNode + service state
viewsArtifact aggregation (shared scanner)
usageToken + cost analytics across providers
filesFile listing + content (parallel per-project scan, budget-limited)
hostsInfrastructure inventory from hosts.yaml
wikiIngested 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

MethodPathDescription
GET/api/agentSelf-describing manifest โ€” every domain, field, filter
GET/api/agent/query?q=Cross-domain fan-out search
GET/api/agent/:domainList per domain
GET/api/agent/:domain/:idEntity detail
GET/api/agent/projects/:name/fullMulti-domain aggregate for one project

Core

MethodPathDescription
GET/POST/api/basesManifest CRUD + stats
GET/api/hostsInfrastructure inventory from hosts.yaml
GET/api/based/sessionsProvider session discovery
GET/api/based/sessions/statsSession summary
GET/api/based/sessions/:id/messagesSession message history
GET/api/based/sessions/:id/toolsSession tool call history
GET/api/based/statusLive base status summary
GET/api/based/logsLog search
GET/api/based/usageToken + cost stats
GET/api/based/viewsArtifact aggregation
*/api/messagesMailbox + ack (seq model)
*/api/notesMarkdown note CRUD
*/api/orchestratorPlans, tasks, verification, memory/dream
GET/api/intelligenceProviders + health + query
*/api/claude-accountsAccount management
GET/api/systemDiagnostics + telemetry

based-web (port 1337)

File operations

MethodPathDescription
GET/api/files/contentRead text file
GET/api/files/rawStream binary with Content-Type
GET/api/files/listFlat file listing
POST/api/files/writeWrite file
POST/api/files/moveMove/rename
POST/api/files/mkdirCreate directory
POST/api/files/uploadUpload file
DELETE/api/files/Delete file

Explorer + Search

MethodPathDescription
GET/api/explorer/:baseId/list?path=Lazy directory listing
GET/api/explorer/__all__/listAll registered bases
GET/api/explorer/:baseId/artifactsClaude artifact discovery
GET/api/searchContent search
GET/api/gitStatus, branch, history

Other

MethodPathDescription
*/api/terminalTerminal session control
*/api/kanbanBoard persistence
*/api/templatesTemplate CRUD
GET/api/musicLocal track control
GET/api/processestmux process summary
GET/api/cli-toolsDetected binaries + health
GET/api/systemHost 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.

RoleAllowed tools
coordinator123
worker95
observer61

Identity

ToolDescription
based_whoamiReturns your agent identity: who you are, what project you're in, and who your peers are.
based_peersList active agents in your project that you can communicate with.
based_agent_bootstrapAgent-first orientation in one call.
based_agents_listList configured sub-agents from parent base.md manifests, including their canonical tmux session names when valid.

Coordination

ToolDescription
based_agent_contactUnified agent-to-agent send.
based_agent_followupInspect or advance an outstanding wait.
based_inboxRead your inbox โ€” messages other agents have sent you.
based_ackAdvance your inbox cursor to a sequence number after processing messages.
based_messageActive: writes the message to the recipient's mailbox AND sends an activation ping to their tmux session.
based_mailPassive: writes to the recipient's mailbox only.
based_send_rawInject text directly into a tmux terminal session.
based_session_readRead the terminal screen of another agent's tmux session.

Query and Projects

ToolDescription
based_queryCross-domain search across all 13 based domains (projects, sessions, artifacts, git, logs, memory, config, health, hosts, views, usage, files, wiki)
based_projects_listList registered projects with metadata, tags, and paths
based_project_fullGet full project aggregate โ€” all domains for a single project
based_sessions_listList Claude Code sessions with summaries and timestamps
based_artifacts_listList Claude Code artifacts (CLAUDE.md, agents, rules, commands, hooks, skills, MCP servers)
based_config_getGet project configuration (base manifest) including deploy config, Claude flags, hooks
based_usage_statsGet Claude Code usage statistics (tokens, costs, sessions) per project
based_logs_searchSearch tmux session logs and operation logs
based_system_guideFull Based platform reference โ€” architecture, CLI tools, API endpoints, MCP tools, deploy procedures, conventions, and safety boundaries.

Git and Repositories

ToolDescription
based_git_statusGet git status for a project โ€” branch, recent commits, modified files
based_git_host_statusRead-only status for a project's configured git host (Forgejo or GitHub).
based_git_host_syncPush every git-tracked base with git.host=forgejo to the local Forgejo on demand.
based_git_host_listList all repos on the configured git host (currently Forgejo).
based_repo_logRecent commits on a Forgejo repo.
based_repo_diffCompare two refs on a Forgejo repo via the compare API.
based_repo_issue_listList issues on a Forgejo repo.
based_repo_pushPush a single project to Forgejo on demand.

Health and Doctor

ToolDescription
based_health_checkCheck health status of all registered nodes and services
based_base_doctorSelf-diagnose against the onboarding contract.
based_mcp_healthInspect this Based MCP server instance: uptime, identity, registered tool count, and recent lifecycle events
based_connectionsList devices currently connected to the Based web UI.

Deploy and Authentication

ToolDescription
based_env_checkValidate current agent's credentials for one or more services.
based_auth_recheckNon-destructive auth re-resolution.
based_auth_refreshDESTRUCTIVE โ€” rotates/restores stored credentials for a service.
based_preflightRun pre-deploy checks for a project without actually deploying.
based_deployDeploy a project component to its configured target.
based_deploy_statusCheck the health of a project's deployed services.
based_cloudflare_deployDEPLOY a Cloudflare project (Pages or Workers โ€” wrangler routes based on the project's wrangler.toml).
based_cloudflare_logsTail recent Cloudflare logs for a project.

Wiki

ToolDescription
based_wiki_pagesList wiki pages for a base, or read a specific page by path
based_wiki_searchSearch wiki pages by content/title/path
based_wiki_updateWrite a wiki page directly under .wiki/pages for a base.
based_wiki_deleteDelete a wiki page under .wiki/pages.
based_wiki_ingest_startStart an async wiki ingest job from URL, inline text, or a base-scoped source file
based_wiki_job_getGet wiki ingest job status/details
based_wiki_job_applyApply proposed wiki page changes for a completed ingest review job
based_wiki_queryQuery wiki pages and synthesize a retrieval summary answer
based_wiki_lintRun wiki lint checks (orphan pages, broken links, stubs, missing titles)

Clipboard

ToolDescription
based_clip_listList recent clipboard history entries captured from Based terminal and CLI copy paths
based_clip_searchSearch clipboard history text with case-insensitive substring matching
based_clip_saveAppend text to clipboard history
based_clip_deleteDelete one clipboard history entry.
based_clip_clearClear clipboard history.

Files

ToolDescription
based_files_searchSearch for files by name or content across projects
based_files_listList files in a base-relative directory.
based_files_readRead one file from a base using a base-relative path.
based_files_writeWrite one UTF-8 text file inside a base.
based_files_mkdirCreate a directory inside a base.
based_files_moveMove or rename a file/directory inside one base.
based_files_deleteDelete a file or directory inside a base.

Uploads

ToolDescription
based_uploads_createCreate an upload from base64 content.
based_uploads_getRead upload metadata by id, including rawUrl and viewUrl.
based_uploads_listList uploads, optionally scoped to one base.
based_uploads_deleteDelete an upload metadata record so raw/view URLs stop resolving.

Notes

ToolDescription
based_notes_listList notes, optionally scoped to one base.
based_notes_getRead a single note by id
based_notes_createCreate a note attached to a base
based_notes_updateUpdate a note.
based_notes_deleteDelete a note.

Kanban

ToolDescription
based_kanban_list_boardsList Kanban boards, optionally scoped to one base.
based_kanban_get_boardRead a Kanban board with columns and cards
based_kanban_create_boardCreate a Kanban board for a base
based_kanban_create_cardCreate a Kanban card in a column
based_kanban_update_cardUpdate a Kanban card.
based_kanban_move_cardMove a Kanban card to a column and position.
based_kanban_get_board_activityRead recent Kanban board activity events with agent/human provenance
based_kanban_subscribe_board_activityReturn a polling cursor for Kanban board activity.
based_kanban_delete_cardDelete a Kanban card.
based_kanban_delete_boardDelete a Kanban board.

Loops

ToolDescription
based_loops_listList configured loops with state, cadence, and history preview
based_loops_getRead one loop detail including manifest, prompt, state, and recent history
based_loops_createCreate a loop from structured settings
based_loops_runTrigger an immediate non-destructive loop run.
based_loops_pausePause a loop
based_loops_resumeResume a paused loop
based_loops_update_settingsUpdate structured loop settings and/or prompt.
based_loops_archiveArchive a loop to .trash.

Memory

ToolDescription
based_memory_searchSearch unified memory across base .memory/MEMORY.md, read-only provider harness memory, and central legacy memory.
based_memory_listList unified memory records across base memory, provider harness memory, and central legacy memory.
based_memory_getRead one base memory file in full.
based_memory_createCreate a new memory file.
based_memory_updateReplace an existing memory file.
based_memory_appendAppend to an existing memory file.
based_memory_deleteDelete a memory file.

Hosts

ToolDescription
based_hosts_listList registered infrastructure hosts (servers, VMs, networks)
based_hosts_getRead one registered host or VM by name.
based_hosts_createCreate a registered infrastructure host in hosts.yaml.
based_hosts_updateUpdate a registered infrastructure host in hosts.yaml.
based_hosts_deleteDelete a registered infrastructure host from hosts.yaml.

Bases

ToolDescription
based_bases_createCreate 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_updateUpdate a base manifest through the canonical base.md writer.
based_bases_deleteDelete a base manifest by default, or the whole base directory when deleteFiles=true.

Tmux

ToolDescription
based_tmux_list_sessionsList tmux sessions with base/provider attribution and optional runtime metadata.
based_tmux_get_sessionRead one tmux session screen with optional full-history capture and runtime metadata.
based_tmux_start_sessionStart a canonical agent or configured sub-agent tmux session with base start.
based_tmux_send_keysSend literal text to a tmux session, optionally followed by Enter.
based_tmux_restart_sessionRestart a canonical agent tmux session by killing it and running base start again.
based_tmux_kill_sessionKill one tmux session and remove its Based runtime record.

Processes

ToolDescription
based_processes_listList OS processes with port and tmux attribution, optionally filtered by base.
based_processes_killSignal an OS process.
based_processes_restartRestart an allowlisted system service via systemctl.

Views

ToolDescription
based_views_listList view definitions and their discovered artifacts (repos, agents, skills)
based_views_artifact_createCreate a provider instruction file or Claude agent, skill, or command artifact.
based_views_artifact_updateReplace a provider instruction file or Claude agent, skill, or command artifact.
based_views_artifact_deleteDelete a Claude agent, skill, or command artifact.

Intelligence

ToolDescription
intelligence_querySend a prompt to AI providers (codex, gemini, ollama, claude) with automatic fallback by priority
intelligence_profilesRead the unified intelligence profile catalog with exact model ids, backend execution health, quota health, model availability, and approval-gated candidates.
intelligence_providersList all configured AI providers with health status, priority, and type
intelligence_healthHealth-check all AI providers and update their status

Registry and Drift

ToolDescription
based_capability_registryInspect 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_checkRead-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

AgentRole
auditorCodebase audits, gap analysis, compliance
pain-auditorSurfaces pain patterns from audit output
test-authorWrites regression tests from pain patterns
testerPlaywright + integration tests
bug-fixerRoot-cause analysis + targeted fixes
fix-proposerGenerates fix proposals against audit findings
reviewerCode review against project standards
frontend-devReact / TypeScript / Tailwind
backend-devExpress / Node / API work
cli-devBash / CLI scripting
docs-writerReference 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

ProviderSession role
ClaudeClaude Code sessions and transcripts
CodexCodex sessions and transcripts
GeminiGemini sessions and transcripts
OllamaLocal 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.

ChoiceBehavior
autoTry enabled, auto-eligible providers in routing order
provider-defaultUse one provider backend without choosing a model profile
profileUse 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.

TierCadenceProfilesDegrades to
reflex15 minutescodex_sparkโ€”
narrativeDailycodex_sol, then claude_opusreflex
councilWeekly and monthlycodex_sol and claude_opusnarrative

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-availability reads 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

EndpointSignal
GET /api/intelligence/providersConfigured provider backends and current public configuration
GET /api/intelligence/healthRefresh provider execution health
GET /api/intelligence/usage-windowRolling provider token usage against configured plan limits
GET /api/intelligence/profilesCombined 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

  1. Coordinator creates a plan with discrete tasks
  2. Workers execute tasks with scoped tool access
  3. Verification step validates each completed task
  4. Communication happens via the mailbox system

Role-scoped tools

When role_scoped_tools flag is enabled:

RoleTools
observerRead-only query tools
workerTask execution tools
coordinatorPlanning + orchestration tools only (never touches files)

Feature flags

  • coordinator_mode โ€” enable the coordinator role
  • role_scoped_tools โ€” restrict tools by agent role
  • verify_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

  1. Start two sessions on the same base with different providers
  2. They share: filesystem, .memory/, mailbox, git state
  3. Msg and Box handle coordination โ€” no orchestrator needed
  4. 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

  1. Edit on your dev machine
  2. Commit changes explicitly โ€” deployment does not auto-commit
  3. Build on the target machine (never locally โ€” avoids chunk hash drift)
  4. Releases are versioned and promoted; a failed health check auto-rolls-back to the previous release

Feature Flags

Ship incrementally. flags.yaml.

FlagDescriptionDefault
coordinator_modeEnable orchestrator coordinator roleoff
role_scoped_toolsRestrict MCP tools by agent roleon
mailbox_ipcFile-backed mailbox messagingon
worktree_isolationGit worktree per sessionoff
auto_memory_extractAuto-extract memory from sessionsoff
auto_dreamBackground reflection/consolidationoff
context_compaction_v2v2 compaction algorithmoff
verify_executionRequire verification after tasksoff
# 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 base command, session start/stop
  • API โ€” deploy events, per-route instrumentation
  • Web UI โ€” navigation, file saves, searches, messaging

Event types

SourceEvents
CLIcli_command, session_started, session_ended
APIdeploy_started, deploy_completed, per-route instrumentation
Webtab_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

  • $TMUX in the web terminal โ€” if base start from the web UI tries to switch your existing tmux instead of creating a new session, make sure $TMUX is unset in the terminal's shell environment. Based handles this automatically, but custom shell configs can re-set it.
  • YAML numbers โ€” YAML parses 31337 as 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 .js extensions โ€” if you're writing plugins or extending Based, all TypeScript imports must include .js in 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.
MethodPathPurpose
GET/api/based/deckHydrate the operator wall
POST/api/based/deck/deltaFetch 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.

MethodPathPurpose
GET/api/chronicle/summaryRead corpus summary information
GET/api/chronicle/eventsRead filtered Chronicle events
POST/api/chronicle/backfillBackfill events from selected mailbox, release, and git sources
POST/api/chronicle/kanban-bridge/runRun 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.

MethodPathPurpose
GET/api/journal/summaryRead the journal index, optionally for one base
GET/api/journal/latestRead the latest canonical digest
GET/api/journal/day/:dateRead a day and optionally select a rendition
GET/api/journal/day/:date/renditionsList available daily renditions
GET/api/journal/week/:weekRead an ISO week summary
GET/api/journal/month/:monthRead a month summary
POST/api/journal/backfillBackfill canonical journal periods
POST/api/journal/candidate/backfillBackfill 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

ClassWhat it isClock owner
Provider loopsOperator-created intelligence workflows โ€” /data/loops/<id>/manifest.yaml + prompt.mdLoop scheduler
System loopsSource-declared platform maintenance (11 definitions): model/host discovery, journal rollups, resource pressure, session cleanup and supervision, instruction lifecycle scans, provider drift, wiki lint, chronicle bridgingSystem-loop scheduler with lease + run history
Ambient servicesContinuous pollers, not scheduled runs: chronicle harvester, wiki session watcher, activation watchdogAmbient service runtime (heartbeats, bounded counters)
External systemd workflowsAudit and Forgejo mirror โ€” declared in the registry, owned by systemd. Based reports desired vs. observed state; it never starts or stops these unitssystemd
Internal mechanicsSession expiry, terminal maintenance, API runtime clocks โ€” registered so recurring work can't hide from the inventory and surfaced through StatusAPI 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.

FindingSignal
loadOne-minute load average normalized by CPU core count
command_class_rssAggregate RSS for a command class
orphan_rssRSS attributed to processes without a live session association
runaway_tool_rssLong-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.
MethodPathPurpose
GET/api/system/session-process-cleanupRead policy and the current observe report
PUT/api/system/session-process-cleanupUpdate policy metadata and loop scheduling without terminating anything
POST/api/system/session-process-cleanup/deploy-eventRecord 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.

MethodPathPurpose
GET/api/system/process-janitorRead the process-tree dossier and policy context
POST/api/system/process-janitor/dry-runGenerate 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.

SurfaceSafety contract
GET /api/based/processesRead-only process inventory with optional user and listening-port filters
POST /api/based/processes/:pid/killRequires TERM or KILL plus confirmation equal to the PID
Bulk process killRuns confirmed per-PID requests with bounded concurrency; root-owned rows cannot be bulk-killed
Bulk tmux killRuns confirmed per-session requests and preserves failed selections for review
based_processes_killRequires confirm=true and refuses root- or foreign-owned processes unless the API itself runs as root
based_processes_restartRestarts 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.