Developers
Developer overview
meith is an Electron desktop workbench backed by a local tool runtime. Everything routes through one validated registry.
The main process is the authority for state and side effects. The renderer, CLI, plugins, and agent runtime all reach application capabilities through the same validated ToolRegistry.
That design keeps the app consistent: opening a tab from the UI, running meith open, or letting an agent control a browser tab all go through the same tool definition, validation, permission, logging, and persistence path.
Packages
meith is a pnpm monorepo built from four packages.
| Package | Role |
|---|---|
@meith/shared | Zod schemas and inferred types for app state, tabs, projects, tools, agents, plugins, logs, settings, IDs, and result helpers. |
@meith/protocol | Tool contracts, tool descriptors, NDJSON protocol messages, naming helpers, and public plugin bridge types. |
@meith/desktop | Electron main/preload/renderer, services, tool registration, socket server, IPC, browser/terminal hosts, agents, plugins, storage, and packaging. |
@meith/cli | Terminal client that discovers a running runtime and calls tools over the local socket. |
Authority model
The runtime is centered on packages/desktop/src/main/bootstrap.ts. bootstrap(userDataPath, options) wires the services, registers tools, starts the local socket server, writes config, publishes an instance record, hydrates state, and returns the service container.
Renderer IPC ─────┐
CLI socket ───────┤
Plugin bridge ────┤
Agent MCP bridge ─┼── ToolRegistry ── services ── app state / files / browser / processes
Internal calls ───┘ToolRegistry.call() is the common choke point. It:
- rejects unknown tools,
- validates arguments with each tool's Zod schema,
- asks
PermissionServiceto authorize privileged calls, - applies timeout and cancellation handling,
- passes an abort signal and optional event emitter to the tool,
- normalizes returned values into a
ToolResult, - logs and audits every call.
Services
The main services are created in bootstrap.ts:
AppStateServiceowns persisted app state and emits reactive state changes.BrowserTabServiceowns browser/workspace tab records and delegates live web contents to aBrowserViewHost.SpaceServicecreates, updates, switches, and closes workspaces.ProjectServicedetects folders, opens projects into spaces, generates templates, prewarms generated projects, and starts project run commands.WorkspaceFileServicereads, writes, patches, searches, and diagnoses files inside trusted workspace boundaries.DevServerServiceandTerminalServicestart and track managed processes, dev servers, and terminal sessions.PluginHostServiceinstalls plugins, stores grants, and gates plugin bridge APIs.AgentServicestores sessions and messages, runs the configured adapter, and gates agent tool calls.McpBridgeServiceexposes per-agent-session tools over a localhost MCP-style HTTP endpoint for external ACP agents.PermissionServiceauthorizes non-renderer privileged calls and writes audit entries.StorageServiceexposes read-only storage introspection, andToolSocketServiceexposes the registry over a local NDJSON socket.
Persistence
Runtime data lives under the user data path passed to bootstrap(). In normal use, discovery data lives under ~/.meith.
~/.meith/config.jsonrecords the active runtime socket, app version, protocol version, user data path, instance path, and managed CLI launcher.~/.meith/instances/<pid>.jsonrecords live runtime instances so the CLI can list, target, or kill them.<userData>/state.jsonstores spaces, projects, tabs, file edit events, plugins, and settings.<userData>/logs.jsonland<userData>/audit.jsonlstore app logs and tool authorization records.
JsonStore writes bounded JSON atomically and runs migrations before schema validation. Corrupt state is backed up and reset to defaults instead of crashing the app.Development modes
# desktop app
pnpm dev
# renderer-only mock mode
pnpm dev:renderer
# headless main-process runtime
pnpm --filter @meith/desktop dev:headless
# full verification
pnpm check