npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-agent-monitor

v1.2.1

Published

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

Downloads

1,811

Readme

opencode-agent-monitor

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