docs GitHub

Concepts

Modules

Every service in Vyre is a module on one contract: projects, recall, the vault, Lumen, and anything you install yourself. A module is a folder with a module.json that says what it does, and an entry file that exports start(ctx). Because every module is wired the same way, a new one shows up to Claude (as an MCP tool), to the surfaces (over HTTP) and to the terminal (through vyre call) without special cases. The contract itself is on the module contract.

Kinds of module

KindWhere it livesExamples
Corecore/<name>/ in the Vyre packageprojects, recall, memory, vault, watchers, threads, sessions, gate, names, link, relay, artifacts, github, team, spend
Harnesscore/harness/, called by the Claude Code plugin in harness/harness (Brief, Enrich, Rules, Learn and Stop, as tools the hooks call)
Surfaces and Mac pieceslocal/<name>/capsule (Lumen), hands (computer use on macOS), chrome (Vyre Computer on the Mac), voice, screen
First-party optionalmodules/<name>/hands-desktop, chrome (the box's side of Vyre Computer)
Yours, or third-party~/.vyre/modules/<name>/anything you write or install

The kind changes nothing about the contract. A module you write gets the same ctx as the vault does.

Some parts of vyred are plumbing, not modules, and have no module.json: the config, the store, the event log, the loader, the daemon, the CLI and the transcript adapter (core/config, core/store, core/events, core/modules, core/daemon, core/cli, core/transcripts). Every module gets them through ctx. Do not list them under requires.

A module's name comes from its manifest, not its folder: core/switchboard/ is the threads module, local/hands-mac/ is hands, and modules/hands-chrome/ and local/hands-chrome-mac/ are both chrome, the box's side and the Mac's side of Vyre Computer. See modules for the full list.

How vyred loads them

When vyred starts, it:

  1. Discovers. It looks for a module.json one level down in each of these folders, in this order: core/, local/, modules/ (all in the Vyre package), then ~/.vyre/modules/.
  2. Validates each manifest (the rules are on the module contract). An invalid one is recorded as invalid with its problems and never started.
  3. Picks the modules for this machine. A module runs when this machine's kind (solo, server or device, see the box and the Mac) maps to one of its roles, box or local (both when omitted), or when config.json lists it under modules.enable. modules.disable switches one off whatever its roles say.
  4. Orders them so each starts after everything it requires. A missing dependency or a cycle fails the module that needs it.
  5. Starts them one at a time: imports the entry file (index.js, or the manifest's main), then awaits start(ctx).

If two modules share a name, the first one found wins. Vyre's own folders come before yours, so a module of yours named vault is reported as ignored and does not replace the vault. The one shared name is chrome, which Vyre ships twice for different machines: the copy that is not on for this machine steps aside and is listed as off.

When a module fails

A module that throws in start, fails validation, or needs one that is not running is marked failed or invalid with the reason. Its tools, streams and routes are removed. The rest of vyred keeps running: one broken module never takes down search or the vault.

vyre modules      # every module, its version, and whether it started
vyre status       # counts running and failed modules

Install a module

Put its folder in ~/.vyre/modules/ and restart vyred:

vyre down && vyre up
vyre modules

A module runs inside vyred, as you, with access to the store. Install only code you trust. In a Claude Code session with the Vyre plugin, a write into ~/.vyre/modules/ is asked about before it happens, because of that.

Next