it2 Plugin Development Guide
This guide covers developing plugins for the it2 command-line interface for iTerm2 automation.
Overview
it2 supports extensibility through an executable plugin system that can:
- Enrich session information - Add metadata to session, tab, and window listings
- Monitor and respond to events - Automate responses based on patterns
- Filter and categorize - Apply tool-specific logic for better organization
Plugin Architecture
it2 (core)
↓ Discovery
Plugin Registry (internal/plugins/)
↓ Execution
External Executables (it2-*)
↓ Integration
Enhanced Output
Plugin Types
it2 recognizes three types of plugins based on executable naming:
- Session Enrichers (
it2-session-*) - Add data to session listings - Tab Enrichers (
it2-tab-*) - Add data to tab listings - Window Enrichers (
it2-window-*) - Add data to window listings - Generic Plugins (
it2-*) - Apply to all entity types
Quick Start
1. Create a Simple Session Plugin
Create an executable named it2-session-example:
#!/bin/bash
# File: it2-session-example
SESSION_ID="$1"
SESSION_NAME="$2"
# Example: Show if session is running a specific tool
if pgrep -f "vim.*$SESSION_ID" >/dev/null; then
echo "vim-active"
elif pgrep -f "git.*$SESSION_ID" >/dev/null; then
echo "git-active"
else
echo "shell"
fi
Make it executable:
chmod +x it2-session-example
Add to PATH:
export PATH="$PATH:$(pwd)"
2. Test Your Plugin
it2 session list
Your plugin output will appear in the session listing as additional metadata.
Plugin Interface
Session Enrichers
Input Arguments:
$1: Session ID (required)$2: Session Name (optional, empty if not set)
Expected Output:
- Single line string describing the session state
- Empty output is ignored
- Exit code 0 for success (non-zero ignored, not treated as error)
Example:
#!/bin/bash
SESSION_ID="$1"
SESSION_NAME="$2"
# Check if this is a Claude Code session
if [ "$SESSION_NAME" = "Claude Code" ] || echo "$SESSION_NAME" | grep -q "claude"; then
echo "claude-session"
fi
Tab Enrichers
Input Arguments:
$1: Tab ID (required)$2: Window ID (required)$3: Tab Title (optional)
Expected Output:
- Single line string describing tab state
- Empty output is ignored
Window Enrichers
Input Arguments:
$1: Window ID (required)$2: Window Title (optional)
Expected Output:
- Single line string describing window state
- Empty output is ignored
Advanced Examples
Multi-Purpose Plugin
Create it2-dev-tools that works across all entity types:
#!/bin/bash
# Universal development tool detector
if [ $# -eq 1 ]; then
# Window enricher mode (1 arg = window ID)
WINDOW_ID="$1"
# Check if any session in this window is running dev tools
if it2 session list --format json | jq -r ".[] | select(.window_id == \"$WINDOW_ID\") | .session_name" | grep -E "(vim|code|git)" >/dev/null; then
echo "development-window"
fi
elif [ $# -eq 2 ]; then
# Tab enricher mode (2 args = tab ID, window ID)
TAB_ID="$1"
WINDOW_ID="$2"
# Check sessions in this specific tab
if it2 session list --format json | jq -r ".[] | select(.tab_id == \"$TAB_ID\") | .session_name" | grep -E "(vim|code)" >/dev/null; then
echo "coding-tab"
fi
elif [ $# -ge 2 ]; then
# Session enricher mode (2+ args = session ID, session name, ...)
SESSION_ID="$1"
SESSION_NAME="$2"
# Detailed session analysis
if echo "$SESSION_NAME" | grep -q "vim"; then
echo "vim-session"
elif echo "$SESSION_NAME" | grep -q "git"; then
echo "git-session"
elif pgrep -f "node.*$SESSION_ID" >/dev/null; then
echo "node-dev"
fi
fi
Configuration-Based Plugin
Create it2-session-classifier that reads from config:
#!/bin/bash
CONFIG_FILE="$HOME/.it2/plugins/classifier.yaml"
SESSION_ID="$1"
SESSION_NAME="$2"
if [ ! -f "$CONFIG_FILE" ]; then
exit 0
fi
# Parse YAML config (requires yq or similar)
if command -v yq >/dev/null; then
PATTERNS=$(yq eval '.patterns[]' "$CONFIG_FILE" 2>/dev/null)
while IFS= read -r pattern; do
if echo "$SESSION_NAME" | grep -qE "$pattern"; then
LABEL=$(yq eval ".patterns | to_entries | .[] | select(.value == \"$pattern\") | .key" "$CONFIG_FILE")
echo "$LABEL"
exit 0
fi
done <<< "$PATTERNS"
fi
With config file ~/.it2/plugins/classifier.yaml:
patterns:
development: "(vim|code|emacs|nvim)"
git: "(git|gh|hub)"
database: "(mysql|postgres|redis|mongo)"
containers: "(docker|kubectl|k8s)"
cloud: "(aws|gcp|azure|terraform)"
Plugin Discovery
it2 discovers plugins by:
- Scanning all directories in
$PATH - Looking for executable files with names starting with
it2- - Determining type based on naming pattern:
it2-session-*→ Session enricherit2-tab-*→ Tab enricherit2-window-*→ Window enricherit2-*→ Generic (applies to all types)
Integration Points
Session Listings
Plugins add data to the PluginData field in session listings:
{
"session_id": "sess123",
"session_name": "vim-work",
"plugin_data": {
"example": "vim-active",
"dev-tools": "vim-session"
}
}
Tab Listings
Similar integration for tab metadata:
{
"tab_id": "tab456",
"sessions": [...],
"plugin_data": {
"dev-tools": "coding-tab"
}
}
Best Practices
Performance
- Plugins have a 5-second timeout - keep them fast
- Cache expensive operations when possible
- Exit early for irrelevant sessions/tabs/windows
Error Handling
- Non-zero exit codes are ignored, not treated as errors
- Empty output is ignored
- Use stderr for debugging (visible with
ITERM2_DEBUG=1)
Naming Conventions
- Use descriptive plugin names:
it2-session-git-statusnotit2-git - Use hyphens for multi-word names:
it2-session-docker-status - Be specific about what the plugin does
Output Formatting
- Keep output concise (single line preferred)
- Use consistent terminology
- Consider localization if relevant
Configuration
- Store config in
~/.it2/plugins/ - Use standard formats (YAML, JSON, TOML)
- Provide sensible defaults
- Document configuration options
Debugging
Enable Debug Mode
export ITERM2_DEBUG=1
it2 session list
Test Plugin Directly
./it2-session-example "session-id" "session-name"
echo $? # Should be 0
Common Issues
- Plugin not discovered: Check it's in PATH and executable
- No output: Verify plugin returns non-empty string
- Timeout: Plugin takes longer than 5 seconds
- Wrong arguments: Check argument handling for your plugin type
Distribution
Packaging
- Create a directory with your plugin and README
- Include configuration examples
- Add installation script if needed
Example Structure
my-plugin/
├── it2-session-mystatus
├── it2-tab-mystatus
├── README.md
├── config.yaml.example
└── install.sh
Installation Methods
Method 1: PATH Installation
cp it2-session-mystatus /usr/local/bin/
chmod +x /usr/local/bin/it2-session-mystatus
Method 2: Plugin Directory
mkdir -p ~/.it2/plugins/mystatus
cp it2-session-mystatus ~/.it2/plugins/mystatus/
export PATH="$PATH:$HOME/.it2/plugins/mystatus"
Examples Repository
See the examples/ directory for working plugin implementations:
- claude-monitoring/: Complete Claude Code session monitoring
- vim-monitoring/: Advanced vim session detection and assistance
- tmux-monitoring/: tmux session integration
- shell-monitoring/: Shell state detection
Plugin Registry (Future)
Future versions may include:
- Plugin registry with
it2 plugin install <name> - Automatic updates
- Plugin marketplace
- Dependency management
Contributing
To contribute plugins or improvements:
- Test thoroughly with various session types
- Follow naming conventions
- Include comprehensive documentation
- Add examples to the examples directory
- Submit pull requests with test cases
For complex plugins, consider:
- Unit tests for plugin logic
- Integration tests with it2
- Performance benchmarks
- Cross-platform compatibility