* Phase 1: Build-Time Version Injection in Daemon - Create internal/version package for build-time version management - Update RPC server to use version.GetVersion() instead of hardcoded constant - Update HTTP API handlers to use version package - Configure workflow to inject version during build with -ldflags - Update tests to use version package This allows nightly builds to report version as "0.1.0-YYYYMMDD-nightly" while dev builds show "0.1.0". 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Phase 2: Dynamic Tauri App Configuration - Create nightly Tauri config with distinct productName and identifier - Update workflow to use nightly config for scheduled builds - Nightly builds will create CodeLayer-Nightly.app with separate identifier This enables side-by-side installation of stable and nightly builds. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Add pre-generated nightly icons with color rotation * Phase 3: Update workflow to use nightly icons for scheduled builds * Phase 4: Configure Daemon Paths and Ports via Build Flags Configure the nightly daemon to use different default paths and ports by injecting them at build time using ldflags. Changes: - Make DefaultDatabasePath, DefaultSocketPath, and DefaultHTTPPort injectable via ldflags in hld/config/config.go - Add setDefaults() function to handle string-to-int conversion for HTTP port - Update release workflow to inject nightly configuration for scheduled builds: - Database: ~/.humanlayer/daemon-nightly.db - Socket: ~/.humanlayer/daemon-nightly.sock - HTTP Port: 7778 - Regular builds continue to use standard defaults This allows nightly and stable daemons to run side-by-side without conflicts. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Phase 5: Update Homebrew Cask for Side-by-Side Support - Add automated nightly cask updates to release workflow - Calculate SHA256 and construct release URLs - Checkout homebrew tap repository - Generate codelayer-nightly.rb with proper configuration - Commit and push updates automatically - Update nightly cask to support side-by-side installation - Renamed binaries with -nightly suffix - Uses nightly-specific data paths - No conflicts declared with stable cask - Add TODO for future stable release automation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Add test_nightly mode to workflow for testing nightly build behavior * Fix nightly icons: Convert 32x32.png and Square30x30Logo.png to RGBA format * Use HUMANLAYER_HOMEBREW_CASK_WRITE_GITHUB_PAT for homebrew tap authentication * change test_nightly to release_nightly --------- Co-authored-by: Claude <noreply@anthropic.com>
humanlayer-wui
Web/desktop UI for the HumanLayer daemon (hld) built with Tauri and React.
Development
Running in Development Mode
-
Build the daemon (required for auto-launch):
make daemon-dev-build -
Start CodeLayer in development mode:
make codelayer-dev
The daemon starts automatically and invisibly when the app launches. No manual daemon management needed.
Disabling Auto-Launch (Advanced Users)
If you prefer to manage the daemon manually:
export HUMANLAYER_WUI_AUTOLAUNCH_DAEMON=false
make codelayer-dev
Using an External Daemon
To connect to a daemon running on a specific port:
export HUMANLAYER_DAEMON_HTTP_PORT=7777
make codelayer-dev
Building for Production
To build CodeLayer with bundled daemon:
make codelayer-bundle
This will:
- Build the daemon for macOS ARM64
- Build the humanlayer CLI for macOS ARM64
- Copy both to the Tauri resources
- Build CodeLayer with the bundled binaries
The resulting DMG will include both binaries and automatically manage their lifecycle.
Daemon Management
The daemon lifecycle is completely automatic:
In development mode:
- Daemon starts invisibly when CodeLayer launches
- Each git branch gets its own daemon instance
- Database is copied from
daemon-dev.dbtodaemon-{branch}.db - Socket and port are isolated per branch
- Use debug panel (bottom-left settings icon) for manual control if needed
In production mode:
- Daemon starts invisibly when CodeLayer launches
- Uses default paths (
~/.humanlayer/daemon.db) - Stops automatically when the app exits
- No user interaction or awareness required
Error Handling:
- If daemon fails to start, app continues normally
- Connection can be established later via debug panel (dev) or automatically on retry
- All errors are logged but never interrupt the user experience
MCP Testing
To test MCP functionality:
In development:
- Ensure you have
humanlayerinstalled globally:npm install -g humanlayer - Start CodeLayer:
make codelayer-dev - Configure Claude Code to use
humanlayer mcp claude_approvals - The MCP server will connect to your running daemon
In production (after Homebrew installation):
- Claude Code can directly execute
humanlayer mcp claude_approvals - No npm or npx required - Homebrew automatically created symlinks in PATH
- The MCP server connects to the daemon started by CodeLayer
- Verify PATH setup is working:
which humanlayershould show/usr/local/bin/humanlayer
Troubleshooting MCP connection:
- If MCP can't find
humanlayer, restart Claude Code after installation - If launched from Dock, Claude Code may have limited PATH - launch from Terminal instead
- Check daemon is running:
ps aux | grep hld - Check MCP logs in Claude Code for connection errors
Quick Start for Frontend Development
Always use React hooks, never the daemon client directly:
import { useApprovals } from '@/hooks'
function MyComponent() {
const { approvals, loading, error, approve } = useApprovals()
// ... render UI
}
Documentation
- Architecture Overview - System design and data flow
- Developer Guide - Best practices and examples
- API Reference - Hook and type documentation
Status
⚠️ Experimental - APIs may change