personal ware factory · fleet · bicycle

Software got cheap.
So I make it by the lot.

Remember the rental bike boom, when the bikes came off the line faster than anyone could ride them and ended up stacked six high in fields? Code went the same way. An agent writes the tool before you finish describing it. I am the factory floor for that: seven coding harnesses on one wire, your own machines as one fleet, and an index that still knows which of the ten thousand bikes is yours.

# Apple silicon, from the downloads below
open Mechabedo-aarch64-apple-darwin.dmg
chmod +x Mechabedo-x86_64-unknown-linux-gnu.AppImage
./Mechabedo-x86_64-unknown-linux-gnu.AppImage
msiexec /i Mechabedo-x86_64-pc-windows-msvc.msi
mise run prep
mise run dev
# http://localhost:4776
cp docker/mechabedo.config.example.jsonc ./config/
docker compose up -d
  • harnesses on one wire 7 ACP, or I do not drive it
  • jobs, one artifact 5 serve, desktop, daemon, monitor, acp
  • languages a tool is minted in 5 Python, TypeScript, Go, Rust, C#
  • package managers besides deno 0 enforced, not encouraged

the lot

Mint it, ride it, leave it at the curb.

Most software you need this week is a bike for one trip: a board for one incident, a script for one migration, a deck for one meeting. I build those on the spot and keep them in a lot instead of a repository. The difference from the bike fields is that this lot is indexed, so the one you rode in June is still a search away.

vApps

A portal, not a project

A grid of components wired only by keys, opened in its own window over rows it keeps. An agent writes one in a turn; you throw it away when the week is over, or publish it to the fleet when it was not.

vApps in the docs

tools

Five languages, one spec each

Small programs kept outside any repository, scaffolded in Python, TypeScript, Go, Rust or C#. Each carries a spec the next session is handed, so nobody writes the same throwaway script twice.

Enhance in the docs

decks

Slides that already look like me

A slidev deck scaffolded in the house palette with icons and a network graph built in, served on a port of its own. Somebody has to stand up and present the thing you built; it should not take an evening.

Decks on a vApp grid

skills

Written once, installed fleet-wide

A procedure you kept becomes a skill every harness is offered. Fork one, change it, publish it, and the other machines install it from a market your own host brokers.

The marketplace

workspaces

A copy per agent, landed when it is done

A jj working copy of your repository per agent, for the rewrite you should not watch half-finished. Nothing reaches your tree until it lands, and every landing leaves a record a later session reads.

Workspaces

graphs

An assembly line of sessions

Hand over a list of jobs and what each waits on. A session opens per node as its dependencies finish, a few at a time, and you watch the line move on the conversation that started it.

Graph runs

the fleet

One factory, several floors.

A laptop, a tower with a real GPU, a container on the NAS in the cupboard. Each runs the same artifact in a slot of its own, and each dials out to one host you run, so nothing gets a port forwarded. The host relays, stores and brokers; it runs no agent and holds no model. This is the shape of it, deliberately with no real names on it.

  1. beam host relays tunnels, keeps threads, stores sealed logbooks, brokers the market
  2. laptop, GPU tower, NAS container each dial out to it, one slot each
  3. sessions and Bedos run on whichever machine has the tools for the job
  4. phone, a browser elsewhere, a teammate reach all of it through the host

Bedos answer the thread, wherever they live

Agents the installation keeps, messaged in direct, group and desk threads on the host. A Chief on every machine recruits the rest and hands a job to whichever floor has the right one. Your phone is a seat at the table, never the driver's seat.

Several hosts, if one is not enough

One host per team or per purpose is a normal shape. Each machine holds a token for its own slot and nothing more, members sign in through the identity provider you already run, and the operator token stays with the operator.

the floor

Three ways to work the line. One window.

Chat is a conversation. Tabs are how many of those run at once. Enhance is what makes both reach tools worth having. None of them is a mode you switch into and lose the other two in; they are flags, and the window adapts.

chat

One conversation, whichever backend is awake

Standalone chat and agent sessions share a renderer, a prompt box, tool blocks and history, because writing that twice would have been a decision and not a requirement. Aim a prompt at a session and it goes there. Aim it at nothing and it streams from your gateway. Either way it ends up archived.

  • one bubble and tool renderer, both backends
  • streaming, abort, queue and handoff in one composable
  • client-side tools stay inside what you could have clicked yourself

tabs

Several places at once, all of them still running

Every open tab stays mounted. Switching is a display change, so nothing gets torn down: not a stream, not a scroll position, not an xterm buffer, not a Monaco model. Each tab carries its own route, so deep links and history keep working and a background tab renders its own page instead of the foreground one's.

  • one route per tab, still exactly one router
  • work keeps running behind a tab you cannot see
  • Ctrl+T and the command bar open, close, switch, split and rename

enhance

Teach a harness once, not seven times

Skills, tools and subagents get written out once and pushed into every session I start, through whatever mechanism that harness actually has. That is seven different mechanisms, one of which is a symlink, and none of it is yours to think about. A kit decides what a run gets; a session keeps what it launched with.

  • skills, agents and tool tables from one catalog
  • kits decide what a session is allowed to reach
  • your own files override anything I ship

one wire

Seven harnesses. No per-harness interface.

A harness is a backend, not a lifestyle. Every one of them speaks the Agent Client Protocol, so there is one renderer, one permission prompt, one queue and nothing to keep in step. Anything that cannot speak it does not get driven, and I am not writing an adapter to be polite.

How each harness is driven
harnesshow it is drivenenhanced through
Claude Codethe official ACP adaptera linked plugin
Codexcodex-acp over stdioadditional directories
Qwen Codeqwen --acp, its own agenta system-defaults scope
OpenCodea proxied server processits own config
makimaki acp, its own agentskills over MCP
Hermeshermes acp, its own agenta fixed profile
mechabedomechabedo acp, which is menothing, it is in-process

A session outlives its process

Close me and come back: the session is still there with its history, and the process gets restarted underneath it when you send the next prompt. A busy session takes a queue rather than a refusal, and a turn you stopped on purpose wakes nothing afterwards, because a supervisor that argues with you is worse than no supervisor.

Then I got tired of waiting and became one

mechabedo acp is a runtime mode of the same binary that serves this window: read, write, edit, glob, grep and bash, preferring ripgrep, fd, hashline and rtk where they are installed and falling back to a real answer where they are not. It refuses to overwrite a file it has not read, and refuses a patch whose anchors moved. Anything that speaks ACP can open a session on it, not only me.

logbook

I do not remember anything. I index it.

Every session on this machine, imported out of each harness's own history instead of transcribed off whatever happened to be on screen. Sessions you drove by hand in a terminal are in there too, and you did not have to tell me. None of it is recall. It is rows, and there is a search box.

Search, read, replay

One tiling surface: search across messages, sessions and prompts, read a transcript a page at a time, or replay one the way it streamed. A standalone CLI and a full terminal UI read the same rows, for the days you would rather not have a window.

Agents read it too

The archive is a tool surface. A running session can look up the decision an earlier one already made instead of confidently making it again, differently. That is the entire reason I keep any of this.

Numbers

Tokens, turns and cost across everything, priced per model, with a subscription projection attributed against what actually ran here. Usage a harness declined to report gets estimated, and says so rather than pretending.

Yours, and portable

It is a Postgres database on your disk. Snapshot it, export it as JSONL, or sync it between two machines as encrypted blobs through a host you run. Nothing here phones anywhere you did not point it at.

scope

Problems I had to solve to exist.

Not a roadmap and not a wishlist. Every line below is a decision already made, already shipped, and written down in a record naming the alternatives it beat. Read it as a warning about how much surface area sits between "run a coding agent" and "run seven of them without losing your mind".

window

  • virtual tab system
  • every tab stays mounted
  • one route per tab, one router
  • headless primitives under a house layer
  • three theme layers
  • base theme in code, palette overrides as data
  • one ambient clock at 20 Hz
  • backdrop blur that follows the picture
  • third-party stylesheets put on that clock
  • low-power mode that deletes ornaments instead of pausing them
  • XMB wave with a canvas mist renderer
  • laser scroll over message scrollers
  • band effects on a vendored canvas engine
  • fonts chosen per element class
  • icons picked out of an installed font
  • every icon generated from one drawing
  • screensaver on the window's own idle clock
  • wallpaper behind a window that paints no background
  • command bar over registered sources
  • settings catalog generated out of the pages
  • contextual keyboard layer per surface
  • prompt box configured by data, not by props
  • cosmetic polls that run only while watched
  • dead editor CSS that never ships

wire

  • ACP as the only session backend
  • seven harnesses, one renderer
  • adapters resolved away from mise shims
  • elicitation rendered as an interview card
  • ask_user for harnesses that cannot elicit
  • busy sessions that queue instead of refusing
  • a stopped turn that wakes nothing
  • streams that resume from a cursor
  • always-on streams kept off the connection pool
  • one socket for every terminal a page holds
  • one socket for every ACP stream
  • MCP over streamable HTTP
  • MCP callers identified by their own token
  • browser extension an open page pairs
  • webRequest metadata capture
  • editors reached as MCP servers
  • one write gate at the platform boundary
  • tool surfaces frozen at spawn
  • tool categories as coarse as the request
  • Agent Skills, to the specification
  • skill discovery in tool definitions, not a prompt prefix
  • python in a monty sandbox
  • monty's WebAssembly build as the fallback

machine

  • one artifact, five jobs
  • CEF on every desktop target
  • no Electron and no Tauri
  • mise-based bootstrap
  • deno as the only package manager
  • a server that owns its own dependency graph
  • explicit .ts extensions, everywhere it matters
  • .NET SDK installed like any other runtime
  • harness updates that stay user-led
  • mise's GitHub backend for a tool with no registry entry
  • inshellisense built from source, and uninstallable
  • a boot page the server serves itself
  • quit as a phased sweep
  • a tray that is the meter and the way back
  • Pulumi in a stack of its own for CI
  • artifacts built in the workflow plane, not on the runner
  • one command that ships every target
  • a vendor container that refuses to start unauthenticated
  • vendor config as one environment variable
  • dprint with a vendored plugin
  • that same wasm plugin formatting inside the browser
  • a generated secret signing session tokens
  • a tunnel the desktop dials out itself
  • beam hosts carrying installations as named slots
  • tunnel channels metered by credit
  • forwarded WebSockets bridged in process
  • compression and silence detection on that tunnel
  • two installations peering through their host

archive

  • sessions imported, never transcribed
  • hand-driven terminal sessions archived anyway
  • Hermes history through a read-only SQLite port
  • a derived index over the whole archive
  • prompt search that reaches it
  • a cutoff that is a boundary, not a delete
  • token counting locally in a worker
  • token equivalents as the pacing unit
  • subscription readings priced in tokens
  • usage read from an installed status line
  • usage nobody reported, estimated from the transcript
  • unknown usage solved against the archive's own proportions
  • context size from what the agent reports, not what a turn cost
  • the machine's name on every transcript
  • feedback as a row like everything else
  • llm-isms counted by phrase, not by embedding
  • phrases discovered by mining, confirmed by counting
  • a word frequency baseline you install on purpose
  • self-contained HTML logbook exports
  • logbooks travelling as encrypted buckets
  • a dependency-free TUI renderer
  • replays reconstructed and read-only
  • app data that moves as one unit

editor

  • Monaco behind a real language client
  • monaco-languageclient in classic mode
  • the monaco-vscode family pinned ahead of it
  • an LSP session as a WebSocket the browser owns
  • Roslyn for C#
  • tsserver for TypeScript
  • deno lsp for deno directories
  • a closed two-language list, on purpose
  • .slnx, .sln and .csproj all read
  • a symbol index behind the symbol bar
  • search and replace across a whole tree
  • paths in rendered markdown that open here
  • line positions that land on the line

fleet

  • Bedos instead of rooms
  • a Chief on every installation
  • direct, group and desk threads
  • a phone that never takes the seat
  • a push relay on the host
  • vApps and skills as git repositories
  • a market the host brokers
  • fleet sign-in through your own identity provider
  • an unattended policy a person set
  • a jj working copy per agent
  • graph runs of dependent sessions
  • a supervisor outside the session it drives

senses

  • a microphone the browser holds
  • two wake-word providers, and it says which is listening
  • a keyword spotter with no sidecar
  • spoken commands resolved through vocabularies already here
  • Live2D and VRM stages
  • a companion on an app root of its own
  • pointing with a drawn mark and its own hand
  • a sonifier geared in TEM
  • sound packs as data, instrument as code
  • llama.cpp behind an edge tier
  • an edge tier with a proxy lane of its own
  • conversations read back as a digest
  • images sent natively, or through a vision tier
  • personalities as one database entity
  • ADR numbers allocated by reserving the file
  • an agentic bootstrap dispatched into other projects

Every one of these is a file you can open, with a heading, a decision and the options it lost to. That is not thoroughness for its own sake: it is the only reason an agent working in here tomorrow does not undo it.

rest of the window

An agent that can only talk is half a tool.

These sit beside the conversation, on the same server and the same database, because a second one of either is how two halves of a product start disagreeing about what is true.

Work surfaces

  • BedoIDE Monaco behind a real language client over your agents' working directories. Roslyn for C#, tsserver or deno lsp for TypeScript, whichever the directory actually is. Project rail, search and replace across the tree, a diff, and a changes list.
  • Terminals Real shells, as many as you open, floating or docked as a tab, all of them over one socket. A terminal carries its shell between the two homes instead of restarting and losing your place.
  • NoteMap A page of characters laid out by hand instead of flowing text. Overwrite typing, rectangular selection, shiki over its code fences and dprint inside them.

Companions and bridges

  • Companion A floating assistant on its own app root with a Live2D or VRM stage, wired through a meta layer that lets it see this app and drive it. It points at things with a drawn mark and its own hand.
  • Browser bridge An extension that an open mechabedo page pairs, so a session can read and drive the tab you are looking at. The extension holds no credential of its own, which is deliberate.
  • Beam Reach the desktop you left running from a browser somewhere else, through a tunnel it dials out itself. Share archived logbooks as encrypted buckets over the same host.

Behind the window

  • Orchestrator Server-side jobs that supervise a session from outside it: when it finishes a turn, when it halts, or on a clock. Step a workflow, judge a tool call and cancel it, or fan a task list out over a worker pool.
  • Token flow Tokens per minute across every session on this machine, harnesses you started in a terminal included, driving a generative instrument you can leave running until somebody complains.

runtime modes

One artifact. Five jobs.

Same entrypoint every time. Which job it does is decided at startup from how you invoked it and whether the build carries a webview. None of the five is a separate download, and none of them is a build flag you had to pick a year ago.

serveAPI and built SPA, one process, behind your own proxy
desktopthat same server behind a CEF window, on every target
daemonmachine-wide token meter, which outranks any server
monitortranscript and metering command line, standalone
acpme as a coding harness, on stdio, for anything that asks

One server, one database

One PGlite instance per installation, on disk, reached from the browser over the PostgreSQL wire protocol through a WebSocket. Two databases mean two tables that drift apart and one bug report nobody can reproduce. The browser's own copy survives as an opt-in escape hatch and nothing more.

Configuration is data

A table in that database, not a pile of files and not localStorage. Theme, prompts, fonts, kits and loadouts are rows, which is why changing a palette is an edit and not a build, and why exporting your setup is a query.

the manual

Every floor has a page.

The guide is written for whoever runs this next, person or agent. Start where your question is; every page links to the next one you will need.

Behind the guide sits the paper trail: a knowledge chapter per capability area and a record for every load-bearing decision, naming the alternatives it beat. That is the only reason an agent working here tomorrow does not undo it.

downloads

There is a passphrase. You have it or you do not.

Windows, macOS, Linux and the container image, packaged the way each expects. All four are always listed, so one that has not been published yet says so rather than going missing. Whoever pointed you here sent the passphrase along with it. It gets hashed in this tab and never sent anywhere, so a wrong one finds a 404 and I never learn what you typed.

I send one anonymous ping when my server starts: version, channel, os, arch, a random install id, and whether this is a first run. That is the entire message, and MECHABEDO_ANALYTICS=off or a switch in Settings stops it. The umami on the other end is self-hosted and keeps no raw address.