Agent extension quickstart

Create an installable agent-provider package. This first version recognizes a foreground command and deliberately reports no session; the next step is to map its journal.

Before you start

You need Node 24 or later, npm, and a Terminay Server where you can manage extensions.

1. Create the package

Shell
mkdir my-terminay-agent && cd my-terminay-agent
npm init -y
npm install @terminay/extension-api
# Add package.json and extension.js from this guide.
npm pack

Create two files at the package root: package.json and extension.js.

JSON
{
  "name": "my-terminay-agent",
  "version": "0.1.0",
  "type": "module",
  "files": ["extension.js"],
  "dependencies": {
    "@terminay/extension-api": "^1.2.0"
  },
  "terminay": {
    "manifestVersion": 1,
    "id": "com.example.my-agent",
    "displayName": "My agent",
    "api": "^1.2.0",
    "engines": { "terminay": ">=1.0.0", "node": ">=24" },
    "entrypoint": "extension.js",
    "permissions": ["agent-observation"],
    "contributes": {
      "agentProviders": [{
        "id": "com.example.my-agent/cli",
        "displayName": "My agent",
        "processMatchers": [{ "executableName": "my-agent" }],
        "mappings": [{ "mappingVersion": "0.1", "providerVersionRange": ">=0" }],
        "requiredEnvironmentCapabilities": ["agent-journal"]
      }]
    }
  }
}

The terminay object is the extension manifest. Its IDs are stable public identities, so choose a reverse-domain prefix you control.

2. Register an agent provider

TypeScript
import { defineAgentProvider, defineExtension } from '@terminay/extension-api';

const provider = defineAgentProvider({
  mappingVersion: '0.1',
  matchesForeground(process) {
    return process.executableName === 'my-agent';
  },
  async observe(terminal) {
    // Return not-bound until you add your agent's journal lookup and mapping.
    return { state: 'not-bound' };
  },
});

export default defineExtension({
  activate(context) {
    context.subscriptions.add(
      context.agents.registerProvider('com.example.my-agent/cli', provider),
    );
  },
});

The manifest contribution and registerProvider() call use the same provider ID. Terminay starts the extension, calls activate(), and disposes the registration when it stops the package.

3. Pack and install it

Shell
npm pack
  1. In Terminay, open Settings → Extensions for the target server.
  2. Choose Install package file and select the generated .tgz.
  3. Review the package identity, requested permission, and trusted-code warning, then confirm.

Terminay validates the packed archive and starts the package in an isolated extension host. It does not run install scripts or native builds during installation.

Next: bind a real session

Add an agent-journal observation capability, locate a journal through terminal.observation, then return a jsonlSession() that maps journal records to Terminay lifecycle events.

Read the extension anatomy →