npm package: @principal-ai/agent-hooks
Description: Agent monitoring hooks for PrincipleMD - run with npx
Author: PrincipleMD Team
Latest version: 1.0.11

# Principle Hooks

Standalone hooks for capturing and forwarding agent events via HTTP or file storage. Supports Claude, Cline, Droid, and OpenCode agents.

## Supported Agents

- **Claude** - Claude AI Code agent (hooks via settings.json)
- **Cline** - VS Code Cline extension (hooks via settings.json, Claude-compatible)
- **Droid** - Factory AI Droid agent (hooks via settings.json)
- **OpenCode** - OpenCode agent (plugin-based, automated installer included)

## Installation

This package is designed to be run with `npx` without requiring global installation:

```bash
# Run with npx (requires configuration)
npx -p @principal-ai/agent-hooks claude-hook --port 3043 --dir ./hooks
npx -p @principal-ai/agent-hooks cline-hook --port 3043 --dir ./hooks
npx -p @principal-ai/agent-hooks droid-hook --port 3043 --dir ./hooks
```

### Alternative: Global Installation

```bash
# Install globally
npm install -g @principal-ai/agent-hooks

# Then run hooks directly
claude-hook --port 3043 --dir ./hooks
cline-hook --port 3043 --dir ./hooks
droid-hook --port 3043 --dir ./hooks

# Manage OpenCode plugin (uses plugin system, not hooks)
opencode-manager enable   # Install latest OpenCode plugin from npm
opencode-manager disable  # Uninstall OpenCode plugin
opencode-manager status   # Check installation status and version
opencode-manager update   # Update to latest version
opencode-manager check    # Check for updates
```

## Configuration

**Important:** This tool requires explicit configuration - either HTTP port(s) or a directory for file output must be specified.

### Command Line Options

- `--port <port>` - HTTP port to send events to (can be specified multiple times)
- `--dir <directory>` - Directory to save events when HTTP fails or as primary storage

### Environment Variables

- `PRINCIPLE_HOOK_PORTS` - Comma-separated list of ports (e.g., "3043,3044,3045")
- `PRINCIPLE_HOOK_DIR` - Default directory for file storage

### Usage Examples

```bash
# HTTP mode with single port
claude-hook --port 3043
cline-hook --port 3043
droid-hook --port 3043

# HTTP mode with multiple ports (tries each until success)
claude-hook --port 3043 --port 3044 --port 3045
cline-hook --port 3043 --port 3044 --port 3045
droid-hook --port 3043 --port 3044 --port 3045

# HTTP with file fallback
claude-hook --port 3043 --dir ./hook-events
cline-hook --port 3043 --dir ./hook-events
droid-hook --port 3043 --dir ./hook-events

# File-only mode (no HTTP ports specified)
claude-hook --dir ./hook-events
cline-hook --dir ./hook-events
droid-hook --dir ./hook-events

# Using environment variables
PRINCIPLE_HOOK_PORTS=3043,3044 PRINCIPLE_HOOK_DIR=/tmp/hooks claude-hook
PRINCIPLE_HOOK_PORTS=3043,3044 PRINCIPLE_HOOK_DIR=/tmp/hooks cline-hook
PRINCIPLE_HOOK_PORTS=3043,3044 PRINCIPLE_HOOK_DIR=/tmp/hooks droid-hook
```

## What These Hooks Do

These are minimal pass-through hooks that:

1. **Read JSON data from stdin** (from AI agents)
2. **Send to HTTP endpoint(s)** if configured with `--port`
3. **Save to file** if configured with `--dir` (as fallback or primary storage)
4. **Log errors** when a directory is configured

## Modes of Operation

### HTTP Mode
- Requires at least one `--port` specified
- Tries each port in sequence until success
- Exits with error if all ports fail (unless `--dir` is also specified)

### File Mode
- Requires `--dir` to be specified
- Used when no ports are configured
- Creates JSON files with timestamped events

### Hybrid Mode
- Specify both `--port` and `--dir`
- Tries HTTP first, falls back to file on failure
- Most resilient configuration

## File Storage

When a directory is configured with `--dir`, the following files are created:

- `{agent}-hook-events.json` - Event data with timestamps
- `{agent}-hook-events-errors.json` - Error logs for debugging

## Integration

These hooks can be integrated with any system that:
1. Accepts JSON events via HTTP POST
2. Reads JSON event files from a directory

The hooks are agent-agnostic and can be used as a general-purpose event forwarding mechanism.

### OpenCode Plugin Management

OpenCode uses a plugin system instead of hooks. The `opencode-manager` fetches the latest agent-monitor plugin from npm and installs it automatically:

```bash
# Install the latest OpenCode agent-monitor plugin globally
npx @principal-ai/agent-hooks opencode-manager enable

# Install to current project only
npx @principal-ai/agent-hooks opencode-manager enable --local

# Use a custom port (default: 3043)
npx @principal-ai/agent-hooks opencode-manager enable --port 3044

# Check installation status and version
npx @principal-ai/agent-hooks opencode-manager status

# Check for updates
npx @principal-ai/agent-hooks opencode-manager check

# Update to latest version
npx @principal-ai/agent-hooks opencode-manager update

# Uninstall the plugin
npx @principal-ai/agent-hooks opencode-manager disable
```

**How it works:**
- `enable` fetches the latest agent-monitor plugin from npm registry
- Version tracking via manifest file (`.config/opencode/plugin/agent-monitor.manifest.json`)
- Integrity verification using npm SRI hashes
- `update` checks for newer versions and updates automatically
- Always pulls the latest version on fresh install

The OpenCode plugin will:
- Send Claude-formatted events to `http://localhost:3043/opencode-hook`
- Support all hook events: PreToolUse, PostToolUse, SessionStart, SessionEnd, etc.
- Block tool execution based on monitor service response
- Work with the same agent-manager service as other agents

### Cline Configuration

To use with Cline, create `.cline/settings.json` in your project root:

```json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "npx @principal-ai/agent-hooks cline-hook --port 3043",
        "timeout": 60
      }]
    }],
    "PostToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "npx @principal-ai/agent-hooks cline-hook --port 3043",
        "timeout": 60
      }]
    }],
    "UserPromptSubmit": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "npx @principal-ai/agent-hooks cline-hook --port 3043",
        "timeout": 60
      }]
    }],
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "npx @principal-ai/agent-hooks cline-hook --port 3043",
        "timeout": 60
      }]
    }]
  }
}
```

### Droid Configuration

To use with Factory AI Droid, enable hooks in Droid settings and configure them. First enable hooks:

1. Run `/settings` command in Droid
2. Navigate to the "Hooks" setting
3. Toggle it from "Disabled" to "Enabled"

Then configure hooks for different events. Here's an example configuration:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npx @principal-ai/agent-hooks droid-hook --port 3043",
            "timeout": 60
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npx @principal-ai/agent-hooks droid-hook --port 3043",
            "timeout": 60
          }
        ]
      }
    ],
    "UserPromptSubmit": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npx @principal-ai/agent-hooks droid-hook --port 3043",
            "timeout": 60
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "npx @principal-ai/agent-hooks droid-hook --port 3043",
            "timeout": 60
          }
        ]
      }
    ]
  }
}
```

## Private Package Considerations

This package can be published as a private npm package. For private packages:

1. **Use npm private registry** or **GitHub Packages**
2. **Configure authentication** in your CI/CD
3. **Use scoped package name** (`@principal-ai/agent-hooks`)

### Publishing to GitHub Packages

```bash
# Configure npm to use GitHub Packages
npm config set @principal-ai:registry https://npm.pkg.github.com

# Login with GitHub token
npm login --scope=@principal-ai --auth-type=legacy

# Publish
npm publish
```

### Using Private Package

Users will need to authenticate to access the private package:

```bash
# Configure registry for the scope
npm config set @principal-ai:registry https://npm.pkg.github.com

# Login (requires GitHub token with packages:read permission)
npm login --scope=@principal-ai --auth-type=legacy

# Now npx will work
npx -p @principal-ai/agent-hooks claude-hook
npx -p @principal-ai/agent-hooks cline-hook
npx -p @principal-ai/agent-hooks droid-hook
```

## License

MIT