Agent Integration Guide¶
Adding New Coding Agents to the Coding System
This guide provides step-by-step instructions for integrating new AI coding assistants into the agent-agnostic Coding system.
1-File Integration
Adding a new agent requires only a single config file (config/agents/<name>.sh). No changes to shared code needed.
Overview¶
The Coding system supports multiple AI coding assistants through a config-driven architecture. All agents share common infrastructure:
- Tmux Session Wrapping - Unified status bar rendering via
tmux-session-wrapper.sh - Live Session Logging (LSL) - Automatic transcript monitoring
- Knowledge Management - VKB server and semantic analysis
- Constraint Monitoring - Real-time code quality enforcement
- Health Monitoring - System status and recovery
- Browser Automation - Playwright integration
- Session Continuity - Cross-session context
- Pipe-Pane Capture - Optional I/O capture for non-native agents (prompt detection, hook firing)
Architecture¶
Agent-Agnostic Design¶

The system follows a layered architecture:
- Agent Layer - Your AI coding assistant (Claude, CoPilot, OpenCode, Mastracode, etc.)
- Tmux Wrapper Layer - Shared
tmux-session-wrapper.shwraps all agents in tmux with unified status bar - Config Layer - Agent definitions in
config/agents/<name>.sh - Orchestration Layer -
launch-agent-common.shhandles all shared startup (Docker, services, monitoring) - Common Setup Layer - Shared initialization (LSL, monitoring, gitignore)
- Shared Services Layer - VKB, Semantic Analysis, Constraints, LSL
- Adapter Layer - Abstract interface + agent implementations (loaded dynamically)
Integration Flow¶

When a new agent is launched:
bin/codingvalidates config exists inconfig/agents/<name>.sh- Shared orchestrator (
launch-agent-common.sh) sources the config - Network detection — VPN/CN status, proxy auto-configuration
- Services start (Docker compose brings up the
coding-servicescontainer stack) - Agent-specific hooks run (
agent_check_requirements,agent_pre_launch) - Agent validates API connectivity (
validate_agent_connectivity) - Agent launches wrapped in tmux session with unified status bar
Startup Sequence¶

Network-Aware Agent Selection¶

The launcher detects the network environment and automatically configures each agent:
| Scenario | Proxy | Claude Code | OpenCode | Copilot CLI |
|---|---|---|---|---|
| Inside VPN | Required (proxydetox) | Anthropic via proxy | GH Copilot Enterprise via proxy | GH API via proxy |
| Outside VPN | Cleared | Anthropic direct | Anthropic direct | GH API direct |
| Inside VPN, no proxy | Missing | Blocked | Blocked | Blocked |
Key behaviors:
detect-network.shruns early in the startup pipeline (before agent hooks)- Inside CN: auto-detects proxydetox on
127.0.0.1:3128, setsHTTP_PROXY/HTTPS_PROXY - Outside CN: clears proxy env vars that would route through a non-existent proxy
- OpenCode auto-switches model:
github-copilot-enterprise/claude-opus-4.6(VPN) →claude-opus-4-6(public) - All agents call
validate_agent_connectivity()to verify API reachability before launch CODING_FORCE_CN=true/falseoverrides detection for testing
Launcher Service-Startup Flow¶

All agents share identical container-startup logic via launch-agent-common.sh:
- Container reuse (health check before starting new containers)
- Docker compose service startup
- Docker MCP config generation
Quick Start (1 File)¶
Create config/agents/myagent.sh:
#!/bin/bash
# Agent definition: My Agent
# Sourced by launch-agent-common.sh
AGENT_NAME="myagent"
AGENT_DISPLAY_NAME="MyAgent"
AGENT_COMMAND="myagent"
AGENT_SESSION_PREFIX="myagent"
AGENT_SESSION_VAR="MYAGENT_SESSION_ID"
AGENT_TRANSCRIPT_FMT="myagent"
AGENT_ENABLE_PIPE_CAPTURE=true
AGENT_PROMPT_REGEX='>\s+([^\n\r]+)[\n\r]'
AGENT_REQUIRES_COMMANDS="myagent"
# Verify agent CLI is available
agent_check_requirements() {
if ! command -v myagent &>/dev/null; then
_agent_log "Error: myagent CLI is not installed or not in PATH"
exit 1
fi
_agent_log "myagent CLI detected"
}
That's it. Now test:
# Verify config is discovered
coding --agent myagent --dry-run
# Launch (if myagent binary is installed)
coding --agent myagent
What You Get Automatically
- Docker container startup
- Monitoring verification
- LSL transcript monitoring
- Tmux session with status bar
- Pipe-pane I/O capture (since
AGENT_ENABLE_PIPE_CAPTURE=true) - Session registration and cleanup
- All shared infrastructure
Agent Config Reference¶
Required Variables¶
| Variable | Description | Example |
|---|---|---|
AGENT_NAME | Internal identifier (used in env vars) | "myagent" |
AGENT_COMMAND | Binary/script to exec inside tmux | "myagent" or "$CODING_REPO/bin/my-wrapper" |
Optional Variables¶
| Variable | Default | Description |
|---|---|---|
AGENT_DISPLAY_NAME | $AGENT_NAME | Human-readable name for log messages |
AGENT_SESSION_PREFIX | $AGENT_NAME | Prefix for session ID ({prefix}-{PID}-{timestamp}) |
AGENT_SESSION_VAR | (none) | Env var to export session ID as (e.g. CLAUDE_SESSION_ID) |
AGENT_TRANSCRIPT_FMT | $AGENT_NAME | Transcript format identifier |
AGENT_ENABLE_PIPE_CAPTURE | false | Enable tmux pipe-pane I/O capture |
AGENT_PROMPT_REGEX | (none) | Regex for prompt detection (required if capture enabled) |
AGENT_REQUIRES_COMMANDS | $AGENT_COMMAND | Space-separated list of required CLI binaries |
Hook Functions¶
Define these functions in your config to customize behavior:
# Called after services start, before agent launch
# Use to verify agent-specific dependencies
agent_check_requirements() {
# Return non-zero or exit 1 to block launch
}
# Called just before tmux wrapping
# Use to start agent-specific services, log info
agent_pre_launch() {
# Start HTTP adapter, set env vars, etc.
}
# Called on EXIT/INT/TERM (before PSM cleanup)
# Use to stop agent-specific background processes
agent_cleanup() {
# Kill background servers, etc.
}
Hook Environment
All hooks have access to _agent_log for logging, $CODING_REPO, $TARGET_PROJECT_DIR, $SESSION_ID, and all other env vars set by the orchestrator.
Optional Enhancements¶
Agent Adapter (for programmatic API access)¶
If other components need to interact with your agent programmatically, create lib/agent-api/adapters/myagent-adapter.js:
import { BaseAdapter } from '../base-adapter.js';
class MyAgentAdapter extends BaseAdapter {
constructor(config = {}) {
super(config);
this.capabilities = ['memory', 'browser', 'logging'];
}
async initialize() { this.initialized = true; }
async cleanup() { /* cleanup resources */ }
// Implement methods from API Contract below
}
export default MyAgentAdapter;
The adapter is loaded automatically by convention: lib/agent-api/adapters/${agentType}-adapter.js.
Agent-Specific Launcher (thin wrapper)¶
If you need to customize the sourcing order or add pre-config logic, create scripts/launch-myagent.sh:
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CODING_REPO="$(dirname "$SCRIPT_DIR")"
export CODING_REPO
source "$SCRIPT_DIR/agent-common-setup.sh"
source "$SCRIPT_DIR/launch-agent-common.sh"
launch_agent "$CODING_REPO/config/agents/myagent.sh" "$@"
If no launch-myagent.sh exists, bin/coding automatically falls back to launch-generic.sh.
API Contract¶
AgentAdapter Interface¶
All adapters MUST implement these methods:
Lifecycle Methods¶
Command Execution¶
Memory Operations¶
async memoryCreate(entities: Entity[]): Promise<CreateResult>
async memoryCreateRelations(relations: Relation[]): Promise<CreateResult>
async memorySearch(query: string): Promise<Entity[]>
async memoryRead(): Promise<GraphData>
async memoryDelete(entityNames: string[]): Promise<DeleteResult>
Browser Operations¶
async browserNavigate(url: string): Promise<NavigationResult>
async browserAct(action: string, variables: Record<string, any>): Promise<ActionResult>
async browserExtract(): Promise<string>
async browserScreenshot(options?: ScreenshotOptions): Promise<Buffer>
Logging Operations¶
async logConversation(data: ConversationEntry): Promise<LogResult>
async readConversationHistory(options?: HistoryOptions): Promise<ConversationEntry[]>
Utility Methods¶
Type Definitions¶
Full Type Definitions (click to expand)
interface Entity {
name: string;
entityType: string;
observations: string[];
significance?: number;
created?: string;
lastUpdated?: string;
metadata?: Record<string, any>;
}
interface Relation {
from: string;
to: string;
relationType: string;
created?: string;
metadata?: Record<string, any>;
}
interface GraphData {
nodes: Entity[];
edges: Relation[];
metadata?: { nodeCount: number; edgeCount: number; lastAccessed: string; };
}
interface CreateResult { success: boolean; created?: number; updated?: number; errors?: string[]; }
interface DeleteResult { success: boolean; deleted: number; notFound: number; }
interface NavigationResult { success: boolean; url?: string; error?: string; }
interface ActionResult { success: boolean; result?: any; error?: string; }
interface ConversationEntry { timestamp: string; type: string; content: any; metadata?: Record<string, any>; }
interface LogResult { success: boolean; logFile?: string; error?: string; }
interface HistoryOptions { limit?: number; startDate?: Date; endDate?: Date; type?: string; }
Testing¶
Test Checklist¶
- [ ] Config:
config/agents/<name>.shexists with required variables - [ ] Dry-run:
coding --agent <name> --dry-runsucceeds - [ ] Detection: Agent detected by
AgentDetector(check withcoding --help) - [ ] Launch: Agent starts via
coding --agent <name> - [ ] Tmux: Agent launches inside tmux session with status bar
- [ ] LSL: Transcripts monitored and classified
- [ ] Monitoring: StatusLine health monitoring active
- [ ] Cleanup: Graceful shutdown works (
agent_cleanupcalled) - [ ] E2E:
tests/integration/launcher-e2e.shpasses
Validation Commands¶
# Dry-run (safe, no actual launch)
coding --agent myagent --dry-run
# Check detection
coding --help
# Launch agent
coding --agent myagent
# Check LSL status
coding --lsl-status
# Run full E2E test suite
./tests/integration/launcher-e2e.sh
Examples¶
Claude Code (config/agents/claude.sh)¶
AGENT_COMMAND="$CODING_REPO/bin/claude-mcp"— launches via MCP wrapperAGENT_ENABLE_PIPE_CAPTURE=false— Claude has native transcript supportagent_check_requirements()— checks MCP sync statusagent_pre_launch()— logs container startup info
GitHub Copilot CLI (config/agents/copilot.sh)¶
AGENT_COMMAND="copilot"— launches copilot CLI directlyAGENT_ENABLE_PIPE_CAPTURE=true— captures I/O via tmux pipe-paneAGENT_PROMPT_REGEX— detects submitted prompts via❯markeragent_pre_launch()— starts HTTP adapter serveragent_cleanup()— stops HTTP adapter on exit

OpenCode (config/agents/opencode.sh)¶
- 25-line config file, zero shared code changes
- Demonstrates the minimum integration:
AGENT_NAME+AGENT_COMMAND+agent_check_requirements() - Native LSL support: The transcript monitor reads directly from OpenCode's SQLite database (
~/.local/share/opencode/opencode.db) — no pipe-pane capture needed for session logging

Mastracode (config/agents/mastra.sh)¶
AGENT_COMMAND="mastracode"— launches standalone mastracode TUIAGENT_ENABLE_PIPE_CAPTURE=false— uses lifecycle hook transcripts for LSLAGENT_INSTALL_COMMAND="npm install -g mastracode"— auto-installs on first launchagent_pre_launch()— handles first-run OAuth setup, network-adaptive model selection, hooks config- Transcript capture via
MastraTranscriptReaderreading NDJSON from mastra lifecycle hooks - Observational memory via km-core
GraphKMStoreat.data/knowledge-graph/(legacy LibSQL/SQLite.observations/observations.dbarchived 2026-06-05 under Phase 44 Plan 18)

Troubleshooting¶
Agent Not Detected¶
- Does
config/agents/<name>.shexist? - Is
AGENT_REQUIRES_COMMANDSset to the correct binary name? - Is the binary in PATH? (
which <binary>)
Dry-Run Fails¶
- Check
config/agents/<name>.shdefinesAGENT_NAMEandAGENT_COMMAND - Check for syntax errors:
bash -n config/agents/<name>.sh
Services Not Starting¶
- Are required ports available (8080, etc.)?
- Is Docker running?
- Does
start-services.shcomplete successfully?
Pipe-Pane Capture Not Working¶
- Is
AGENT_ENABLE_PIPE_CAPTURE=trueset in config? - Is
AGENT_PROMPT_REGEXa valid regex? - Check capture file exists:
ls $CODING_REPO/.logs/capture/ - Check capture-monitor.js logs