Skip to content

Interoperability ​

The universal integration is a shell command plus a Markdown skill. All integrations are optional and thin; vendor-specific code lives in separate packages and is tested with recorded fixtures, so core schema evolution never depends on a vendor release.

The adapter contract ​

Adapters implement BatonAdapter from @baton/adapter-sdk:

ts
interface BatonAdapter {
  getProjectContext(): Promise<ProjectContext>;        // root, id, initialized
  getSessionMetadata(): Promise<SessionMetadata>;      // harness, opaque id, model
  subscribeEvents?(handler: (event: AdapterEvent) => void): () => void;
  renderNotice?(input: RenderNoticeInput): void;
}

Rules:

  • No adapter may require raw messages or hidden prompts.
  • AdapterEvent carries only normalized 0–1 signals plus the harness name and an optional opaque session id.
  • Evaluate events with evaluateEvent(event, config, lastPromptAt, previousPressure) from @baton/core, or shell out to baton detect --event '<json>' for identical semantics, cooldown handling, and JSON contract.
  • Automation recommends and prepares; it never terminates a session or launches another agent.

Environment matrix (spec §15) ​

EnvironmentMVP integrationAutomation signalResume path
Claude CodeProject skill; optional PreCompact hookexplicit command; hook event/baton-resume-style command or baton resume
CodexProject instructions + MCP configexplicit command; session boundaryMCP handoff_resume or CLI brief
CursorProject rule + terminal taskexplicit action; user-triggered new chatpaste rendered resume brief
Gemini CLIProject command/extension; MCP if supportedexplicit command; lifecycle hook if stableCLI or MCP resume
Open-source harnessesnpm package + CLI; documented event adapternormalized detect --event JSONCLI/MCP

Event format ​

json
{
  "harness": "your-harness",
  "session_id": "opaque-or-null",
  "material_event": "pre_compaction",
  "signals": {
    "contextPressure": 0.92,
    "turnPressure": 0.6,
    "elapsedPressure": null,
    "workBoundary": false,
    "handoffRequest": false,
    "changePressure": 0.4,
    "stuckSignal": null,
    "resumeReadiness": 0.9
  }
}

Unavailable signals are null, never guessed. The detector's output includes the inputs actually used and human-readable reasons, so every recommendation is auditable. See examples/adapter-events/events.json for fixtures.

Released under the MIT License.