@fwdslsh/pace
v0.1.0
Published
Project Autonomous Coding Environment - Long-running agent orchestrator
Maintainers
Readme
Orchestrator - Long-Running Agent Harness
A Bun/TypeScript implementation that orchestrates continuous coding agent sessions using multiple agent SDKs for maximum visibility and flexibility. Supports both the Claude Agent SDK and OpenCode SDK.
Features
- Multi-SDK Support: Choose between Claude Agent SDK or OpenCode SDK at runtime
- Full Visibility: Stream all messages, tool uses, and results from agent sessions
- Automatic Feature Progression: Works through features in priority order
- Session Management: Configurable session limits, failure thresholds, and delays
- Progress Tracking: Monitors feature completion and provides detailed statistics
- Rich Output: Shows system messages, assistant responses, tool executions, and results
- JSON Output: Machine-readable output for scripting and CI/CD integration
- Home Directory Override: Custom SDK home directories for testing and multi-environment setups
- Comprehensive Testing: Full test suite with 90+ tests covering all functionality
Installation
Quick Install (Recommended)
Install the latest version using the installation script:
# Install system-wide (requires sudo)
curl -fsSL https://raw.githubusercontent.com/fwdslsh/pace/main/install.sh | bash
# Install to user directory (~/.local/bin)
curl -fsSL https://raw.githubusercontent.com/fwdslsh/pace/main/install.sh | bash -s -- --user
# Install specific version
curl -fsSL https://raw.githubusercontent.com/fwdslsh/pace/main/install.sh | bash -s -- --version v0.1.0Install via NPM
# Global installation
npm install -g @fwdslsh/pace
# Or use npx (no installation required)
npx @fwdslsh/pace --helpInstall from Source
For development or building from source:
git clone https://github.com/fwdslsh/pace.git
cd pace
bun install
bun run cli.ts --helpBuild Binaries
To create standalone executables:
# Build for current platform
bun run build
# Build for all platforms
bun run build:allEnvironment Variables
For Claude SDK (default):
export ANTHROPIC_API_KEY=your-api-key-hereFor OpenCode SDK:
# Optional - defaults to http://localhost:4096
export OPENCODE_SERVER_URL=http://localhost:4096Usage
The orchestrator provides multiple commands for different tasks:
bun run cli.ts [COMMAND] [OPTIONS]Available Commands:
run- Run the orchestrator (default)status- Show project status and progressvalidate- Validate feature_list.json structureupdate- Update a feature's pass/fail statushelp- Show help message
Quick Start
Run the orchestrator:
bun run cli.ts
# or explicitly
bun run cli.ts run --max-sessions 10Check project status:
bun run cli.ts status
bun run cli.ts status --verbose
bun run cli.ts status --json # JSON output for scriptingValidate feature list:
bun run cli.ts validate
bun run cli.ts validate --json # JSON outputUpdate feature status:
bun run cli.ts update F001 pass
bun run cli.ts update F002 fail
bun run cli.ts update F001 pass --json # JSON outputUsing OpenCode SDK:
bun run cli.ts run --sdk opencodeOverride SDK home directory:
# Useful for testing or multi-environment setups
bun run cli.ts run --home-dir /custom/path/.claude
bun run cli.ts run --home-dir ~/.config/opencode-testCommon Options
Run until all features pass:
bun run cli.ts --until-complete
# or
npm run cli:completeRun a specific number of sessions:
bun run cli.ts --max-sessions 20Adjust failure tolerance:
bun run cli.ts --max-failures 5Preview without executing:
bun run cli.ts --dry-run --max-sessions 5Command Options
Run Command:
--sdk SDK Agent SDK to use: 'claude' or 'opencode' (default: claude)
--project-dir, -d DIR Project directory (default: current directory)
--home-dir DIR Override SDK home directory (~/.claude or ~/.config/opencode)
--max-sessions, -n N Maximum number of sessions to run (default: 10)
--max-failures, -f N Stop after N consecutive failures (default: 3)
--delay SECONDS Seconds to wait between sessions (default: 5)
--until-complete Run until all features pass (implies unlimited sessions)
--dry-run Show what would be done without executing
--json Output results in JSON format
--help, -h Show this help messageStatus Command:
--verbose, -v Show detailed breakdown by category
--json Output results in JSON format
--project-dir, -d DIR Project directory (default: current directory)Validate Command:
--json Output results in JSON format
--project-dir, -d DIR Project directory (default: current directory)Update Command:
bun run cli.ts update <feature-id> <pass|fail>
--json Output results in JSON format
--project-dir, -d DIR Project directory (default: current directory)How It Works
Workflow
- Orient: Reads project state from
feature_list.jsonandclaude-progress.txt - Select Feature: Chooses the next failing feature by priority (critical → high → medium → low)
- Execute: Invokes Claude Agent SDK with the coding agent prompt
- Stream Output: Shows all system messages, tool uses, and results in real-time
- Verify: Checks if the feature was marked as passing in
feature_list.json - Repeat: Continues to next feature or stops based on conditions
Stopping Conditions
The orchestrator stops when:
- All features are passing (success!)
- Maximum sessions reached
- Maximum consecutive failures reached
- User interrupts (Ctrl+C)
Output Examples
System Initialization:
📋 Session initialized:
- Model: claude-sonnet-4-5-20250929
- CWD: /path/to/project
- Tools: Read, Write, Edit, Bash, Grep, Glob, ...
- Permission mode: acceptEditsTool Execution:
🔧 Tool: Read
Input: {
"file_path": "/path/to/file.ts",
"offset": 1,
"limit": 50
}
✅ Tool result: [file contents...]Session Result:
🎯 Session Result
============================================================
Status: success
Turns: 12
Duration: 45.32s
API Time: 38.21s
Cost: $0.0234
Tokens: 15234 in / 2891 out
Cache: 12890 read / 0 created
Result: Feature AUTH-001 implemented successfully
============================================================JSON Output for Scripting and CI/CD
All commands support --json flag for machine-readable output, perfect for scripting and CI/CD integration.
Status JSON Output
bun run cli.ts status --json{
"progress": {
"passing": 5,
"failing": 3,
"total": 8,
"percentage": 62.5
},
"projectName": "My Project",
"nextFeatures": [
{
"id": "F001",
"description": "Feature description",
"priority": "high",
"category": "core"
}
],
"workingDirectory": "/path/to/project"
}Validation JSON Output
bun run cli.ts validate --json{
"valid": true,
"errorCount": 0,
"errors": [],
"stats": {
"total": 8,
"passing": 5,
"failing": 3,
"byCategory": {
"core": 3,
"ui": 2,
"api": 3
},
"byPriority": {
"critical": 1,
"high": 3,
"medium": 3,
"low": 1
}
}
}Update JSON Output
bun run cli.ts update F001 pass --json{
"success": true,
"featureId": "F001",
"oldStatus": "failing",
"newStatus": "passing",
"description": "Feature description",
"category": "core",
"progress": {
"passing": 6,
"total": 8,
"percentage": 75
}
}Run JSON Output
bun run cli.ts run --json --max-sessions 5{
"sdk": "claude",
"sessionsRun": 5,
"featuresCompleted": 2,
"finalProgress": "7/8",
"completionPercentage": 87.5,
"elapsedTime": "5m 32s",
"isComplete": false,
"progress": {
"passing": 7,
"total": 8
}
}CI/CD Integration Example
#!/bin/bash
# ci-test.sh - Run orchestrator and check exit code
# Run orchestrator
bun run cli.ts run --max-sessions 10 --json > results.json
EXIT_CODE=$?
# Parse results
PASSING=$(jq '.progress.passing' results.json)
TOTAL=$(jq '.progress.total' results.json)
echo "Test Results: $PASSING/$TOTAL features passing"
# Exit with orchestrator's exit code (0 if complete, 1 if incomplete)
exit $EXIT_CODESDK Comparison
Claude Agent SDK
The default SDK provides rich integration with Anthropic's Claude:
- Full Tool Visibility: See every tool call Claude makes with inputs and outputs
- Session Management: Automatic conversation history and context management
- Permission Control: Fine-grained control over file edits and command execution
- Cost Tracking: Built-in usage and cost reporting per session
- Project Context: Automatic loading of
CLAUDE.mdand project settings - Better Debugging: Clear visibility into why Claude makes each decision
Usage:
bun run cli.ts --sdk claude --max-sessions 10Requirements:
ANTHROPIC_API_KEYenvironment variable- Internet connection to Anthropic API
OpenCode SDK
Alternative SDK for OpenCode-powered agent sessions:
- Local or Remote: Connect to local or hosted OpenCode servers
- Event Streaming: Real-time session events and status updates
- Flexible Backend: Support for multiple AI providers
- Session Management: Create and monitor sessions programmatically
Usage:
# Local OpenCode server (default)
bun run cli.ts --sdk opencode
# Remote OpenCode server
OPENCODE_SERVER_URL=http://your-server:4096 bun run cli.ts --sdk opencodeRequirements:
- OpenCode server running (default:
http://localhost:4096) - Optional: Custom server URL via
OPENCODE_SERVER_URL
Which SDK to Choose?
| Feature | Claude SDK | OpenCode SDK | | -------------------- | ---------- | ------------ | | Cost Tracking | ✅ | ❌ | | Tool Call Details | ✅ | ✅ | | Streaming Events | ✅ | ✅ | | Local Execution | ❌ | ✅ | | Multiple Providers | ❌ | ✅ | | Built-in Permissions | ✅ | ❌ | | Requires API Key | ✅ | Varies |
Integration with Feature List
The orchestrator expects a feature_list.json file in the project directory with this structure:
{
"features": [
{
"id": "AUTH-001",
"description": "Implement user authentication",
"priority": "critical",
"passes": false
},
{
"id": "UI-002",
"description": "Add dark mode toggle",
"priority": "medium",
"passes": true
}
],
"metadata": {
"lastUpdated": "2025-11-28T10:30:00Z"
}
}Troubleshooting
Claude SDK Issues
Agent SDK not found:
bun install @anthropic-ai/claude-agent-sdkAPI key not set:
export ANTHROPIC_API_KEY=your-api-key-herePermission errors:
The orchestrator uses permissionMode: 'acceptEdits' to auto-accept file edits. Adjust in the code if you need different behavior.
OpenCode SDK Issues
OpenCode SDK not found:
bun install @opencode-ai/sdkCannot connect to OpenCode server:
Make sure OpenCode server is running:
# Check if server is accessible curl http://localhost:4096/healthSet custom server URL if needed:
export OPENCODE_SERVER_URL=http://your-server:4096
Session events not streaming:
- OpenCode SDK uses event streaming with session ID filtering
- Check that the OpenCode server is properly emitting events
- Verify network connectivity to the server
General Issues
No features progressing: Check that:
- The coding agent prompt is appropriate for your project
- Features are clearly defined in
feature_list.json - The project environment is properly initialized (see
init.sh) - The selected SDK is properly configured and accessible
Comparison to Python Version
| Feature | Python Version | TypeScript (Bun) Version | | ------------- | ------------------------ | ---------------------------- | | Runtime | Python 3 | Bun | | API | Subprocess to Claude CLI | Claude Agent SDK | | Visibility | Command output only | Full message streaming | | Tool Tracking | None | Complete with inputs/outputs | | Cost Tracking | None | Built-in per session | | Performance | Subprocess overhead | Direct SDK calls | | Debugging | Limited | Rich event stream |
Project Structure
The codebase is organized into modular components for better maintainability:
pace/
├── cli.ts # Main CLI entry point
├── src/
│ ├── types.ts # Shared TypeScript type definitions
│ ├── feature-manager.ts # Feature list operations (load, save, query)
│ ├── validators.ts # Feature list validation logic
│ ├── status-reporter.ts # Status display and reporting
│ ├── orchestrator.ts # Main orchestration logic
│ └── sdk/
│ ├── base.ts # SDK abstraction interface
│ ├── claude.ts # Claude Agent SDK implementation
│ └── opencode.ts # OpenCode SDK implementation
├── tests/ # Comprehensive test suite (90+ tests)
│ ├── feature-manager.test.ts
│ ├── validators.test.ts
│ ├── status-reporter.test.ts
│ ├── orchestrator.test.ts
│ └── cli.test.ts
├── examples/
│ ├── show_status.py # Python reference implementation
│ ├── update_feature.py # Python reference implementation
│ └── validate_features.py # Python reference implementation
└── package.jsonModule Responsibilities
- cli.ts: Command-line interface, argument parsing, command routing
- orchestrator.ts: Main orchestration loop, session management, stopping conditions
- feature-manager.ts: All operations on feature_list.json (CRUD, queries, statistics)
- validators.ts: Validation logic for feature lists, error formatting
- status-reporter.ts: Display project status, progress, git history
- sdk/: SDK implementations following the AgentSessionRunner interface
- base.ts: Interface definition for SDK runners
- claude.ts: Claude Agent SDK wrapper with full event streaming
- opencode.ts: OpenCode SDK wrapper with event streaming
Testing
The project includes a comprehensive test suite with 90+ tests covering all functionality.
Running Tests
# Run all tests
bun test
# Run tests in watch mode
bun test --watch
# Run specific test file
bun test tests/feature-manager.test.ts
# Run with verbose output
bun test --verboseTest Coverage
The test suite includes:
Unit Tests:
tests/feature-manager.test.ts- Feature list operations (41 tests)tests/validators.test.ts- Validation logic (13 tests)tests/status-reporter.test.ts- Status reporting (13 tests)tests/orchestrator.test.ts- Orchestration logic (14 tests)
Integration Tests:
tests/cli.test.ts- End-to-end CLI testing (20 tests)
Test Organization
tests/
├── feature-manager.test.ts # Feature CRUD operations
├── validators.test.ts # Feature list validation
├── status-reporter.test.ts # Status display and JSON output
├── orchestrator.test.ts # Session orchestration
└── cli.test.ts # CLI integration testsWriting New Tests
Tests use Bun's built-in test runner:
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
describe('MyFeature', () => {
beforeEach(() => {
// Setup code
});
afterEach(() => {
// Cleanup code
});
it('should do something', () => {
expect(1 + 1).toBe(2);
});
});Home Directory Override for Testing
Use --home-dir to test with different SDK configurations without affecting your main setup:
# Test with a temporary Claude config
bun run cli.ts run --home-dir /tmp/test-claude --dry-run
# Test with a separate OpenCode config
bun run cli.ts run --sdk opencode --home-dir /tmp/test-opencode --dry-runDevelopment
Modifying Orchestrator Behavior
Key areas to customize:
- Prompt Construction:
src/orchestrator.ts-buildCodingPrompt()method - Feature Selection:
src/feature-manager.ts-getNextFeature()method - Success Criteria:
src/orchestrator.ts-runCodingSession()after execution - Output Formatting:
src/sdk/claude.tsorsrc/sdk/opencode.ts- message handling
Adding New SDK Implementations
- Create a new file in
src/sdk/(e.g.,src/sdk/myai.ts) - Implement the
AgentSessionRunnerinterface fromsrc/sdk/base.ts - Add the SDK choice to
SDKChoicetype insrc/types.ts - Update
Orchestrator.getSessionRunner()insrc/orchestrator.ts - Update CLI help text and README
Adding New Commands
- Add command to the
ParsedArgs['command']union incli.ts - Create a
handle<Command>()function - Add command to the
switchstatement inmain() - Update
printHelp()with command documentation
Release Process
PACE uses automated GitHub Actions for building and releasing:
Creating a Release
Tag a version:
git tag v0.2.0 git push origin v0.2.0Automated workflow:
- Builds binaries for all platforms (Linux, macOS, Windows on x64 and arm64)
- Creates GitHub release with binaries attached
- Publishes to npm registry as
@fwdslsh/pace
Manual Workflow Dispatch
You can also trigger releases manually from GitHub Actions:
Actions → Release → Run workflow → Enter tag (e.g., v0.2.0)Binary Artifacts
Each release includes standalone executables:
pace-linux-x64- Linux x86_64pace-linux-arm64- Linux ARM64pace-darwin-x64- macOS Intelpace-darwin-arm64- macOS Apple Siliconpace-windows-x64.exe- Windows x86_64
Installation Methods
Users can install PACE via:
Installation script (recommended):
curl -fsSL https://raw.githubusercontent.com/fwdslsh/pace/main/install.sh | bashNPM (for Node.js/Bun projects):
npm install -g @fwdslsh/paceDirect download from GitHub releases:
wget https://github.com/fwdslsh/pace/releases/latest/download/pace-linux-x64 chmod +x pace-linux-x64 mv pace-linux-x64 /usr/local/bin/pace
License
MIT License - see LICENSE file for details.
