@synchronic1/harness-ranger
v0.3.1
Published
Enhanced tool registry, session management, and permission context patterns for OpenClaw
Maintainers
Readme
HarnessRanger - Enhanced Tool Harness for OpenClaw
A production-ready plugin implementing advanced harness patterns from Claude Code's porting workspace:
- Enhanced Tool Registry with semantic matching
- Permission-Aware Tool Execution
- Token-Aware Session Management with intelligent compaction
- Structured Streaming Responses with event pipeline
Architecture
harness-ranger/
├── src/
│ ├── tool-registry.js # Semantic tool discovery & metadata management
│ ├── permission-context.js # Permission-aware execution gating
│ ├── session-manager.js # Token-aware session persistence
│ └── streaming-responses.js # Structured event streaming pipeline
├── index.js # Plugin entrypoint & lifecycle hooks
├── package.json
└── README.mdInstallation
Clone or copy to
~/.openclaw/plugins/harness-rangerAdd to
openclaw.json:
{
"plugins": {
"allow": ["harness-ranger"],
"entries": {
"harness-ranger": {
"enabled": true,
"config": {
"maxContextTurns": 12,
"maxBudgetTokens": 4000,
"compactAfterTurns": 16,
"semanticMatchingThreshold": 0.6
}
}
}
}
}- Install dependencies:
cd ~/.openclaw/plugins/harness-ranger
npm installUsage
Enhanced Tool Registry
Register tools with metadata:
plugin.registerTool('analyze-code', codeAnalyzer, {
description: 'Analyzes source code for patterns and issues',
category: 'analysis',
tags: ['code', 'patterns', 'linting'],
permission: 'user'
});Find tools using semantic matching:
const matches = plugin.findTools('analyze my python code', {
category: 'analysis',
recentToolNames: ['code-review']
});
// Returns tools sorted by relevance scorePermission-Aware Execution
The plugin automatically checks permissions before tool execution:
const result = await plugin.beforeToolExecution('analyze-code', params, {
user: { id: 'user123', roles: ['developer'] },
resource: '/path/to/code',
sessionId: 'sess-456'
});
if (!result.allowed) {
console.log(`Denied: ${result.reason}`);
}Token-Aware Session Management
Sessions automatically compact when token budgets are exceeded:
const session = await plugin.getSession('sess-456');
// Compaction happens automatically if needed
plugin.addTurn('sess-456', 'Analyze this code', 'Here\'s the analysis...', []);Structured Streaming
Stream responses with structured events:
for await (const event of plugin.streamResponse(generator, {
sessionId: 'sess-456'
})) {
switch (event.type) {
case 'message_start':
console.log('Starting response...');
break;
case 'message_delta':
console.log('Content:', event.content);
break;
case 'message_stop':
console.log(`Complete (${event.totalTokens} tokens)`);
break;
}
}Configuration
{
// Session management
maxContextTurns: 12, // Keep last N turns in memory
maxBudgetTokens: 4000, // Max tokens before compaction
compactAfterTurns: 16, // Force compact after this many turns
// Tool discovery
semanticMatchingThreshold: 0.6, // Min score for tool matches (0-1)
// Storage
sessionDir: '.openclaw/sessions', // Where to persist sessions
// Security
deniedTools: ['exec', 'shell'], // Tools that are always denied
restrictedResources: {
'admin-panel': ['root-user'] // Tool -> allowed resources
}
}Patterns Implemented
1. Modular Registry Pattern
Central registry with discoverable capabilities, metadata-driven tool dispatch, and permission-aware filtering.
const registry = plugin.toolRegistry;
registry.registerTool(name, handler, metadata);
const matches = registry.findTools(query, context);2. Permission Gating
Contextual permission checks before tool execution with support for user roles, resource restrictions, and rate limiting.
const permission = plugin.permissionContext.canExecute(
toolName, user, resource
);3. Session Persistence
Token-aware session management with automatic compaction, usage tracking, and conversation replay.
const session = plugin.sessionManager.getSession(sessionId);
plugin.sessionManager.recordToolCall(sessionId, toolName, params);4. Streaming Pipeline
Structured event streaming with clear visibility into decision-making: message_start → command_match → tool_match → message_delta → message_stop
for await (const event of plugin.streamResponse(generator, context)) {
// Handle different event types
}Testing
npm test # Run unit tests
npm run lint # Check code style
npm run build # Build TypeScript (if enabled)CI/CD
GitHub Actions workflows included:
- ci.yml - Lint, test, build, security audit
- code-review.yml - Automated PR code review with analysis
API Reference
Plugin Instance Methods
initialize(runtime)- Initialize with OpenClaw runtimefindTools(query, context)- Find tools by semantic matchgetSession(sessionId)- Get or create sessionregisterTool(name, handler, metadata)- Register custom toolstreamResponse(generator, context)- Stream with structured eventsgetStatus()- Get plugin metrics and status
Tool Registry
registerTool(name, handler, metadata)findTools(query, context)getTool(name)getToolMetadata(name)listTools(filter)updateToolMetadata(name, updates)removeTool(name)export()
Permission Context
canExecute(toolName, user, resource)denyTool(toolName)allowTool(toolName)restrictResource(toolName, resources)getDeniedTools()
Session Manager
getSession(sessionId)addTurn(sessionId, userMsg, assistantMsg, toolCalls)recordToolCall(sessionId, toolName, params)recordToolResult(sessionId, toolName, result)shouldCompact(sessionId)compactSession(sessionId)saveSession(sessionId)loadSession(sessionId)deleteSession(sessionId)listSessions()
Contributing
- Create a branch for your feature
- Make changes and add tests
- Run
npm test && npm run lint - Push and create a PR
- CI/CD pipeline runs automatically with code review feedback
License
MIT
