Skip to content
    ↑↓ select↵ openesc close
    English中文
    tenondecrpc

    Agent Monitor

    v1.2.1Agent Orchestration
    opencode-agent-monitor

    Monitor, audit, and analyze agent/subagent routing and tool usage in OpenCode sessions

    GitHub stars

    1

    Monthly installs

    128

    4 in 7 days

    Composite scoreSCORE

    34.1

    Multi-signal model

    Last commit

    1 month ago

    2026-07-20

    Install and configure

    opencode.json

    Writes to this project's opencode.json — applies to this repository only.

    opencode.json

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["opencode-agent-monitor@1.2.1"]
    }

    opencode loads npm dependencies through its embedded runtime on startup and caches them locally — no manual global install needed.

    Monitor, audit, and analyze agent/subagent routing and tool usage in OpenCode sessions.

    CI npm version License: MIT TypeScript

    Overview

    Agent Monitor is an OpenCode plugin that provides observability into how AI agents and subagents are routed, what tools they use, and whether task-domain assignments are appropriate. It writes structured JSON-line logs with optional sensitive data redaction, log rotation, and domain detection.

    Key Features

    • Open Domain Detection — Define your own domain categories with custom keyword patterns, or use the built-in defaults. No hardcoded types.
    • Agent-to-Domain Mapping — Tell the plugin which of your agents handle which domains, regardless of what you name them.
    • Routing Mismatch Alerts — Warns when a task's detected domain doesn't match the assigned agent's configured responsibilities.
    • Tool Usage Tracking — Logs all tool executions with session context.
    • Permission Auditing — Tracks permission requests and decisions.
    • Session Lifecycle — Monitors session creation, updates, compaction, errors, and deletion.
    • Sensitive Data Redaction — Automatically redacts API keys, tokens, passwords, and connection strings from logs.
    • Log Rotation — Automatic log file rotation with configurable size limits and retention.
    • Structured Logging — JSON-line format for easy parsing and analysis.
    • Zero Configuration — Works out of the box with sensible, secure defaults.

    Installation

    From npm (Recommended)

    1. Add the plugin to your opencode.json:
    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["opencode-agent-monitor"]
    }
    
    1. OpenCode will automatically install the plugin on next startup.

    From Local File

    1. Clone or download this repository:
    git clone https://github.com/tenondecrpc/opencode-agent-monitor.git
    cd opencode-agent-monitor
    npm install
    npm run build
    
    1. Copy the built plugin to your OpenCode plugins directory:
    # Project-level (inside your project's .opencode/ directory)
    cp dist/index.js .opencode/plugins/agent-monitor.js
    
    # Or global (shared across all projects — in your home directory)
    cp dist/index.js ~/.config/opencode/plugins/agent-monitor.js
    

    From Source (Development)

    git clone https://github.com/tenondecrpc/opencode-agent-monitor.git
    cd opencode-agent-monitor
    npm install
    npm run dev  # Watch mode for development
    

    Then reference the source file in your config:

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["./path/to/opencode-agent-monitor/src/index.ts"]
    }
    

    Usage

    Once installed, the plugin automatically starts monitoring. Logs are written inside the project/repo where OpenCode is running — not in the global OpenCode config directory.

    Where logs are stored

    OpenCode has two levels of config directories. The plugin uses the project-level directory for logs:

    Directory Scope Purpose
    ~/.config/opencode/ Global (home directory) OpenCode CLI global config — providers, models, TUI settings. The plugin does NOT write logs here.
    <project>/.opencode/ Per-project (inside the repo) Project-level agents, commands, plugins. This is where the plugin writes logs by default.

    Default log location:

    <your-project>/.opencode/agent-monitor.log
    

    Real example: if you run OpenCode in ~/projects/my-app/, the log file will be:

    ~/projects/my-app/.opencode/agent-monitor.log
    

    Each project gets its own log file. Logs are never shared across projects.

    How the plugin resolves config

    The plugin loads configuration from multiple sources. Project-level config always takes priority over global config:

    Priority Location Purpose
    1 (highest) <project>/.opencode/agent-monitor.json Project-specific settings — overrides everything
    2 <project>/.config/opencode/agent-monitor.json Alternative project location
    3 ~/.config/opencode/agent-monitor.json Global defaults — shared across all projects
    4 (lowest) Built-in defaults Sensible, secure defaults

    This means you can set global defaults in ~/.config/opencode/agent-monitor.json and override them per-project in <project>/.opencode/agent-monitor.json.

    Important: ~/.config/opencode/ is the global OpenCode config in your home directory. <project>/.config/opencode/ is a directory inside your project (rarely used). Most projects only have .opencode/ at the root.

    Log File Permissions

    The plugin automatically manages file and directory permissions for security:

    Resource Permission Meaning
    Log directory (.opencode/ inside project) 0o700 Only the owner can read, write, and traverse
    Log file (agent-monitor.log) 0o600 Only the owner can read and write

    Can I use a different log location? Yes. Set "logPath" in your config to any path. The plugin creates the directory if it doesn't exist and sets restricted permissions automatically.

    Supported path formats:

    Format Example Resolves to
    Relative ".opencode/agent-monitor.log" <project>/.opencode/agent-monitor.log
    Tilde (~) "~/.config/opencode/agent-monitor.log" Your home directory
    Absolute "/var/log/my-monitor.log" Exact path (as-is)

    Log Format

    Each line is a JSON object:

    {"ts":"2025-04-26T10:30:00.000Z","type":"tool.execute.after","tool":"bash","sessionID":"abc123","guessedDomains":["backend","cloud"],"domainConfidence":0.45}
    {"ts":"2025-04-26T10:30:01.000Z","type":"routing.mismatch","expectedDomains":["frontend"],"actualAgent":"backend","mismatches":["frontend"],"confidence":0.62}
    {"ts":"2025-04-26T10:30:02.000Z","type":"permission.asked","tool":"write","sessionID":"abc123"}
    

    Analyzing Logs

    Use jq or any JSON-line parser to analyze logs. All examples below show the 10 most recent entries (newest first):

    # View the 10 most recent routing mismatches
    jq 'select(.type == "routing.mismatch")' .opencode/agent-monitor.log | tail -r | head -n 40
    
    # Count tool usage by tool name
    jq -r 'select(.type | startswith("tool.")) | .tool' .opencode/agent-monitor.log | sort | uniq -c | sort -rn | head -10
    
    # View the 10 most recent permission requests
    jq 'select(.type | startswith("permission."))' .opencode/agent-monitor.log | tail -r | head -n 40
    
    # View the 10 most recent entries for a specific session
    jq 'select(.sessionID == "your-session-id")' .opencode/agent-monitor.log | tail -r | head -n 40
    
    # View the 10 most recent log entries of any type
    tail -r .opencode/agent-monitor.log | head -10 | jq '.'
    

    Tip: tail -r reverses the file (newest lines first) and head -10 limits output. Since each JSON object spans one line in the log file, tail -r | head -10 gives you the 10 most recent entries. For filtered queries, pipe through tail -r | head -n 40 (40 lines ≈ 10 JSON objects) to avoid loading the entire file.

    Configuration

    The plugin works with zero configuration. All settings use secure defaults.

    Quick Start: Simple JSON Config (No Code Required)

    Global config (shared across all projects):

    ~/.config/opencode/agent-monitor.json
    

    Project config (overrides global for this project only):

    <your-project>/.opencode/agent-monitor.json
    

    Project config always takes priority over global config. If both exist, they are merged with project settings winning.

    {
      "autoDetectAgents": true,
      "domains": [
        { "name": "data-science", "patterns": ["pandas", "numpy", "matplotlib"] }
      ],
      "mergeDomains": true
    }
    

    That's it. The plugin will:

    1. Auto-detect your agents from opencode.json and .opencode/agents/*.md
    2. Analyze their descriptions and prompts to figure out what domains they handle
    3. Generate agent-to-domain mappings automatically
    4. Merge your custom domains with the built-in defaults

    Full JSON Config Options

    Note: You don't need this file to get started. The plugin works with zero configuration — just install it and logs are written automatically. Only create agent-monitor.json if you want to override defaults.

    Config resolution order (later sources override earlier ones):

    1. ~/.config/opencode/agent-monitor.json — global defaults
    2. <project>/.opencode/agent-monitor.json — project overrides
    3. <project>/.config/opencode/agent-monitor.json — alternative project location
    4. userConfig — programmatic config (if using a TypeScript wrapper)

    About logPath: This field is optional. If omitted, logs go to <project>/.opencode/agent-monitor.log. If you set it, any path is accepted — relative (resolved against project), absolute, or tilde-prefixed (~).

    {
      "enabled": true,
      "maxLogSize": 10485760,
      "maxRotatedFiles": 5,
      "enableDomainDetection": true,
      "enableToolTracking": true,
      "enablePermissionTracking": true,
      "enableSessionTracking": true,
      "redactSensitiveData": true,
      "logLevel": "info",
      "emitRoutingWarnings": true,
      "excludedTools": [],
    
      "autoDetectAgents": true,
    
      "domains": [
        { "name": "data-science", "patterns": ["pandas", "numpy", "matplotlib"] },
        { "name": "mobile", "patterns": ["react native", "flutter", "swift"] }
      ],
      "mergeDomains": true,
    
      "agentMappings": [
        { "agentName": "my-ui-agent", "domains": ["frontend", "vision"] },
        { "agentName": "api-builder", "domains": ["backend", "cloud"] }
      ],
    
      "display": {
        "toasts": true,
        "structuredLogging": true
      }
    }
    

    Example with explicit logPath:

    // Write logs to your global OpenCode config directory (shared across projects)
    { "logPath": "~/.config/opencode/agent-monitor.log" }
    
    // Or keep it project-local (default behavior)
    { "logPath": ".opencode/agent-monitor.log" }
    

    Display Options

    The plugin has three levels of visibility, from always-on to optional:

    Level What Default Configurable?
    File logging All events written to <project>/.opencode/agent-monitor.log ✅ Always on No (mandatory)
    Structured logging Events sent to OpenCode's internal log viewer via client.app.log() ✅ On Yes
    Toast notifications Brief pop-up messages in the TUI for important events ✅ On Yes

    Toast Notifications

    When enabled, the plugin shows brief, non-intrusive toast messages for:

    • Routing mismatches — when a task's detected domain doesn't match the assigned agent
    • Session errors — when a session encounters an error
    • Permission denials — when a permission request is denied
    {
      "display": {
        "toasts": true
      }
    }
    

    Example toast: ⚠ Routing mismatch: "backend" handling [frontend]

    Toasts auto-dismiss and don't interrupt the workflow.

    Structured Logging

    When enabled (default), events are sent to OpenCode's internal logging system. These can be viewed through OpenCode's log viewer and filtered by service name agent-monitor.

    {
      "display": {
        "structuredLogging": false
      }
    }
    

    How Auto-Detection Works

    When autoDetectAgents is true (default), the plugin:

    1. Reads opencode.json — finds all agents in the "agent" section
    2. Reads agent markdown files — finds agents in <project>/.opencode/agents/*.md (or ~/.config/opencode/agents/*.md for globally-defined agents)
    3. Analyzes descriptions and prompts — uses the domain detection engine to figure out what each agent does
    4. Generates mappings — creates agentName → domains mappings automatically

    For built-in agents (build, plan, general, explore), the plugin already knows their domains.

    For custom agents, it analyzes text like:

    {
      "agent": {
        "security-reviewer": {
          "description": "Reviews code for security vulnerabilities, OWASP compliance, and encryption",
          "prompt": "You are a security expert. Look for XSS, CSRF, and injection attacks."
        }
      }
    }
    

    This auto-generates: { agentName: "security-reviewer", domains: ["security"] }

    Manual Override

    Auto-detected mappings are merged with manually configured ones. Manual mappings always take precedence:

    {
      "autoDetectAgents": true,
      "agentMappings": [{ "agentName": "my-agent", "domains": ["custom-domain"] }]
    }
    

    If auto-detection finds my-agent handles ["frontend"], the manual mapping ["custom-domain"] wins.

    Disable Auto-Detection

    {
      "autoDetectAgents": false
    }
    

    When disabled, only manually configured agentMappings are used. If no mappings are configured, the plugin falls back to substring matching (checks if agent name contains domain name).

    Basic Options

    Option Default Description
    enabled true Enable or disable the monitor
    logPath <project>/.opencode/agent-monitor.log Optional. Relative paths resolve against the project root. Tilde (~) expands to home. Absolute paths are used as-is.
    maxLogSize 10485760 (10 MB) Max log file size before rotation (0 = disabled)
    maxRotatedFiles 5 Number of rotated log files to keep
    enableDomainDetection true Enable domain detection and routing analysis
    enableToolTracking true Enable tool usage tracking
    enablePermissionTracking true Enable permission request tracking
    enableSessionTracking true Enable session lifecycle tracking
    redactSensitiveData true Redact secrets, keys, and tokens from logs
    logLevel "info" Log level for structured logging
    emitRoutingWarnings true Emit warnings for routing mismatches
    excludedTools [] Tools to exclude from tracking

    TypeScript Configuration (Advanced)

    For full programmatic control, create a plugin wrapper in TypeScript:

    // <your-project>/.opencode/plugins/agent-monitor.ts (project-level)
    // or ~/.config/opencode/plugins/agent-monitor.ts (global)
    import { AgentMonitor } from "opencode-agent-monitor"
    import {
      resolveConfigAsync,
      StructuredLogger,
      detectDomains,
      detectAgentMismatch,
    } from "opencode-agent-monitor/exports"
    
    // Option 1: Use the plugin as-is (auto-detects agents, uses defaults)
    export const AgentMonitorDefault = async (ctx) => {
      return AgentMonitor(ctx)
    }
    
    // Option 2: Build your own monitor with custom config
    export const AgentMonitorCustom = async ({ client, directory }) => {
      const config = await resolveConfigAsync(
        {
          domains: [
            {
              name: "data-science",
              patterns: ["pandas", "numpy", "matplotlib", "jupyter", "sklearn"],
            },
          ],
          mergeDomainDefinitions: true,
        },
        directory
      )
    
      const logger = new StructuredLogger(config)
    
      return {
        event: async ({ event }) => {
          await logger.write({ type: "event", eventType: event?.type })
        },
        // ... other hooks
      }
    }
    

    Agent-to-Domain Mappings

    With auto-detection enabled (default), you don't need to configure mappings manually — the plugin discovers your agents and generates mappings automatically.

    For manual configuration, use the JSON config file:

    {
      "agentMappings": [
        { "agentName": "my-ui-specialist", "domains": ["frontend", "vision"] },
        { "agentName": "api-builder", "domains": ["backend"] },
        { "agentName": "cloud-deployer", "domains": ["cloud", "security"] },
        {
          "agentName": "fullstack-dev",
          "domains": ["frontend", "backend", "cloud"]
        }
      ]
    }
    

    With these mappings:

    • If a task about "React components" is given to my-ui-specialistno mismatch (handles frontend)
    • If a task about "React components" is given to api-buildermismatch (doesn't handle frontend)
    • If a task about "React + Docker" is given to fullstack-devno mismatch (handles both)

    Fallback behavior (no mappings configured)

    If you don't configure agentMappings and auto-detection finds no agents, the plugin checks if the agent name contains the domain name:

    • Agent "frontend-agent" + task about "React" → no mismatch (name contains "frontend")
    • Agent "backend" + task about "React" → mismatch (name doesn't contain "frontend")

    Built-in Default Domains

    These domains ship as defaults but are not enforced as types. You can use any domain name you want.

    Domain Sample Keywords
    frontend React, Vue, CSS, UI, responsive, accessibility, component, layout
    backend API, REST, GraphQL, database, route, controller, service, webhook
    cloud AWS, GCP, Azure, Docker, Kubernetes, Terraform, CI/CD, deploy
    security IAM, secrets, encryption, vulnerability, OWASP, OAuth, JWT, RBAC
    architect Design pattern, SOLID, microservice, DDD, scalability, coupling
    qa Test, Jest, Cypress, regression, coverage, edge case, E2E
    documenter README, docs, changelog, migration, runbook, tutorial
    refiner Refactor, cleanup, lint, formatting, naming, dead code
    explore Search, discover, dependency, trace, convention, map
    vision Screenshot, image, visual, mockup, design, Figma
    general Summary, rewrite, utility, helper, script, automation

    Security

    This plugin follows security best practices:

    • Sensitive data redaction is enabled by default, protecting API keys, tokens, passwords, and connection strings
    • No data leaves your machine — all logs are written locally
    • No network calls — the plugin does not make any HTTP requests
    • Safe error handling — log failures never crash the plugin
    • Log rotation prevents unbounded disk usage

    See SECURITY.md for the full security policy.

    Project Structure

    opencode-agent-monitor/
    ├── src/
    │   ├── index.ts              # Plugin entry point
    │   ├── types.ts              # TypeScript type definitions (open Domain type)
    │   ├── config.ts             # Configuration resolution + agent mappings
    │   ├── logger.ts             # Structured logger with rotation
    │   └── domain-detector.ts    # Domain detection engine
    ├── tests/
    │   ├── domain-detector.test.ts
    │   ├── logger.test.ts
    │   └── config.test.ts
    ├── .github/
    │   ├── workflows/
    │   │   ├── ci.yml            # CI pipeline
    │   │   └── release.yml       # Release automation
    │   ├── ISSUE_TEMPLATE/
    │   └── pull_request_template.md
    ├── package.json
    ├── tsconfig.json
    ├── eslint.config.js
    ├── .prettierrc
    ├── .gitignore
    ├── README.md
    ├── CONTRIBUTING.md
    ├── SECURITY.md
    └── LICENSE
    

    Development

    Prerequisites

    Scripts

    npm install           # Install dependencies
    npm run build         # Build the plugin
    npm run dev           # Watch mode
    npm test              # Run tests
    npm run test:watch    # Run tests in watch mode
    npm run test:coverage # Run tests with coverage
    npm run lint          # Run ESLint
    npm run lint:fix      # Fix linting issues
    npm run format        # Format code with Prettier
    npm run typecheck     # Type check without emitting
    

    Running Tests

    npm test
    

    Publishing

    1. Update version in package.json
    2. Create a git tag: git tag v1.0.0
    3. Push the tag: git push origin v1.0.0
    4. The release workflow will publish to npm automatically

    Contributing

    We welcome contributions! Please see CONTRIBUTING.md for guidelines.

    Ways to Contribute

    • Report bugs via GitHub Issues
    • Suggest features or improvements
    • Submit pull requests
    • Improve documentation
    • Add new domain patterns to the defaults
    • Write tests

    License

    This project is licensed under the MIT License.

    Acknowledgments

    • Built for OpenCode — the open-source AI coding agent
    • Inspired by the need for agent observability in multi-agent workflows