This document covers development setup, building, and testing for Mitto.
- Go 1.23 or later
- Make (for build automation)
- macOS 10.15+ (for building the macOS app)
- Command Line Tools (
xcode-select --install) for macOS builds
# Build the CLI binary
make build
# Install to your GOPATH/bin
make install
# Build and run with arguments
make run ARGS="cli"
make run ARGS="web --port 8080"# Build the macOS app bundle (creates Mitto.app)
make build-mac-app
# Clean and rebuild
make clean-mac-app && make build-mac-appThe app bundle is created in the project root as Mitto.app.
# Clean CLI build artifacts
make clean
# Clean macOS app
make clean-mac-app
# Clean everything
make clean clean-mac-app# Run all unit tests (Go + JS)
make test
# Run Go unit tests only
make test-go
# Run JavaScript unit tests
make test-js
# Run integration tests (requires mock ACP server)
make build-mock-acp
make test-integration
# Run Playwright UI tests
make test-ui
# Run linter
make lint- Use
t.TempDir()for file-based tests - Use table-driven tests for multiple scenarios
- Test both success and error paths
func TestSomething(t *testing.T) {
tmpDir := t.TempDir()
// ... test code
}# Format code
make fmt
# Run linter (golangci-lint)
make lint
# Run go vet directly
go vet ./...cmd/mitto/ → CLI entry point
cmd/mitto-app/ → macOS app entry point
config/ → Embedded default configuration
internal/ → Internal packages
├── acp/ → ACP protocol client
├── agents/ → Agent definitions and manager
├── appdir/ → Platform-native directories
├── auxiliary/ → Background ACP session for utility tasks
├── client/ → Go client for Mitto REST API + WebSocket (used in tests)
├── cmd/ → CLI commands (Cobra)
├── config/ → Configuration loading
├── conversion/ → Markdown-to-HTML conversion, file link detection
├── defense/ → Scanner defense, blocklist, IP metrics
├── fileutil/ → JSON file utilities
├── hooks/ → Lifecycle hooks (startup, shutdown)
├── logging/ → Structured logging utilities
├── mcpserver/ → MCP protocol server
├── processors/ → Message processors (text, command, prompt modes)
├── runner/ → Restricted runner, sandbox execution
├── secrets/ → Secure credential storage (Keychain)
├── session/ → Session persistence (Store/Recorder/Player/Queue/Flags)
└── web/ → Web server and API
platform/mac/ → macOS resources (icons, plist)
web/ → Embedded frontend assets
docs/ → Documentation
tests/ → Integration and UI tests
# Interactive CLI with default ACP server
./mitto cli
# With specific server
./mitto cli --acp claude-code
# With debug logging
./mitto cli --debug# Start web server on default port
./mitto web
# Custom port
./mitto web --port 3000
# With specific working directory
./mitto web --dir /path/to/project# Run the built app
open Mitto.app
# With environment overrides
MITTO_ACP_SERVER=claude-code open Mitto.app
MITTO_WORK_DIR=/path/to/project open Mitto.app
# Serve static files from disk for hot-reloading (frontend development)
MITTO_STATIC_DIR=./web/static ./Mitto.app/Contents/MacOS/mitto-appThe native app does not accept CLI flags. Use the MITTO_STATIC_DIR
environment variable (the app's equivalent of the CLI mitto web --static-dir)
to serve static assets from a directory instead of the embedded assets. This
lets you edit files in web/static/ and see changes on refresh, without
rebuilding the app. Resolution priority is MITTO_STATIC_DIR > config
(web.static_dir) > embedded assets. Paths are resolved relative to the app's
working directory, so prefer an absolute path when launching via open.
# CLI
mitto cli --debug
# Web
mitto web --debugThe web frontend uses no build step - edit files in web/static/ and refresh the browser.
web/static/app.js- Main Preact applicationweb/static/lib.js- Pure utility functionsweb/static/styles.css- Custom CSSweb/static/index.html- HTML shell with CDN imports
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
make test - Format code:
make fmt - Submit a pull request
See architecture.md for detailed information about the codebase structure.