atriumatrium

Building an adapter

The SDK v2 declarative manifest spec.

atrium uses SDK v2 adapters, which are largely declarative. Most integration (binary discovery, session discovery, launch composition, launcher UI) lives in adapter.json. Shell scripts are only needed for the one method that stays dynamic — hooks.

SDK v1 (fully script-based: detect_running.sh, extract_session_id.sh, list_recent_sessions.sh, build_resume_command.sh) is deprecated and no longer supported.

Manifest schema

Canonical schema: atrium-adapters/schemas/adapter.schema.json.

{
  "sdkVersion": 2,
  "name": "my-tool",
  "displayName": "My Tool",
  "description": "My AI coding assistant",
  "accent": "#4CAF50",
  "binary": "my-tool",
  "version": "1.0.0",
  "author": "me",
  "skillInstallPath": "~/.my-tool/skills/atrium/SKILL.md",

  "binaryDiscovery": {
    "commands": ["my-tool"],
    "wellKnownPaths": [
      "~/.npm/bin/my-tool",
      "/usr/local/bin/my-tool",
      "/opt/homebrew/bin/my-tool",
      "~/.local/bin/my-tool"
    ]
  },

  "sessions": {
    "pattern": "~/.my-tool/history/*.json",
    "titleField": "title",
    "idField": "id"
  },

  "launch": {
    "base": ["my-tool"],
    "resumeFlag": ["--resume", "{session_id}"],
    "flagMap": {
      "thinking": ["--thinking"],
      "model": ["--model", "{value}"]
    }
  },

  "launcherOptions": [
    {
      "id": "thinking",
      "kind": "toggle",
      "label": "Thinking mode",
      "default": false
    },
    {
      "id": "model",
      "kind": "select",
      "label": "Model",
      "options": [
        { "label": "Fast", "value": "fast" },
        { "label": "Smart", "value": "smart" }
      ],
      "default": "smart"
    }
  ],

  "hooks": {
    "session-start": "atrium://hooks/my-tool/session-start",
    "session-end": "atrium://hooks/my-tool/session-end"
  },

  "methods": {
    "hooks": { "script": "hooks.sh" }
  }
}

Required fields

FieldTypeNotes
sdkVersionintegerMust be 2.
namekebab-case stringMachine ID. Must match the directory name.
displayNamestringShown in the launcher and Settings → Tools.
descriptionstringOne-liner.
accent#RRGGBBUI accent color for this adapter's panes.
binarystringName of the wrapped CLI tool.
versionsemverAdapter version, independent of the tool's version.
methodsobjectMaps method names to their implementation. In SDK v2 only hooks is typically needed.

Optional fields

FieldTypeNotes
skillInstallPathpath stringWhere to copy the canonical atrium skill. Tilde-expanded.
authorstring
binaryDiscoveryobjectHow atrium resolves the binary. See below.
sessionsobjectHow atrium lists recent sessions for the resume picker.
launchobjectHow atrium composes the launch command.
launcherOptionsarrayPer-launch UI inputs shown in the launcher.
hooksobjectEvent-name → atrium://hooks/<adapter>/<event> URI map.

binaryDiscovery

Atrium resolves the binary at launch by trying, in order:

  1. Each entry in commands as a command on the user's $PATH.
  2. Each entry in wellKnownPaths (tilde-expanded, checked for existence and executability).
The first hit wins. If nothing is found, launching fails with a clear error pointing to where the binary is expected.

Include well-known paths for common Node version managers (nvm, fnm, volta) if your tool is installed via npm, and the Homebrew ARM path (/opt/homebrew/bin) for Apple Silicon.

sessions

Describes where the tool stores its session history so atrium can populate the resume picker.

  • pattern — glob relative to the user's home directory.
  • titleField — JSON field inside each session file to use as the human label.
  • idField — JSON field to use as the session ID (passed to resumeFlag).
If your tool doesn't persist sessions or the history is somewhere unusual, omit sessions. The launcher will simply not show a recent-sessions picker.

launch

Composes the command atrium runs in the pane.

  • base — argv prefix, for example ["my-tool"]. atrium substitutes the resolved binary path as argv[0].
  • resumeFlag — template applied when resuming. {session_id} is substituted with the stored session ID.
  • flagMap — maps launcher option IDs to argv fragments. {value} substitutes a select/text option's value.

launcherOptions

Inline UI controls shown in the launcher bar when this adapter is selected. Supported kinds:

  • toggle — boolean switch. Present in argv only when true (via flagMap).
  • select — single-select dropdown with options[] of {label, value}.
  • text — free-form text input.
Each option has an id (referenced by flagMap), label, and optional default.

Prior to SDK v2, launcher options were a separate launcher_options.json file. That form is still supported (reference it via methods.launcher_options = { "static": "launcher_options.json" }), but inline is preferred.

hooks and hooks.sh

The hooks object lists which events your adapter emits. For each event, atrium registers an atrium://hooks/<adapter>/<event> endpoint.

hooks.sh is invoked once by atrium at install and uninstall time to let the adapter wire its hooks into the tool's own hook system. Contract:

#!/usr/bin/env bash
set -e

case "$1" in
  install)
    # Register this adapter's hooks with the tool.
    # Output JSON to stdout: { "subcommand": "install", "installed": true }
    ;;
  uninstall)
    # Remove the registrations.
    ;;
  status)
    # Report current state.
    ;;
esac

Timeout: 5 seconds for install/uninstall; hooks that exceed the timeout fail the operation but do not crash atrium.

Testing locally

  1. Clone atrium-adapters next to your atrium source tree.
  2. Drop your adapter directory into atrium-adapters/adapters/.
  3. Launch atrium's dev build (pnpm tauri dev). atrium checks the sibling path first in debug builds and will pick up your adapter immediately.
  4. Install it from Settings → Tools.
For a remote-installable adapter, open a PR to the atrium-adapters repository adding your adapter directory and an entry in registry.json.

Migration from SDK v1

If you have an SDK v1 adapter (four shell scripts + a minimal adapter.json), move each script's logic into the equivalent declarative block:

SDK v1 scriptSDK v2 equivalent
detect_running.shHandled automatically via process-tree introspection.
extract_session_id.shsessions.idField + adapter emits the session ID as part of session-start.
list_recent_sessions.shsessions.pattern + titleField + idField.
build_resume_command.shlaunch.resumeFlag.
hooks.sh is still needed for install/uninstall wiring. Everything else becomes JSON.