Documentation structure: - docs/README.md - Documentation index - docs/getting-started.md - Installation and first run - docs/usage.md - Dashboard features and usage - docs/configuration.md - Full configuration reference - docs/multi-device.md - Agent setup and PKI management - docs/security.md - Authentication, RBAC, mTLS - docs/api.md - Complete REST API reference - docs/deployment.md - Production deployment guide - docs/troubleshooting.md - Common issues and solutions - docs/development.md - Contributing and building Total: ~80KB of documentation covering all features 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.5 KiB
9.5 KiB
Development Guide
This guide covers building, testing, and contributing to Tyto.
Prerequisites
- Go 1.23+
- Node.js 22+
- Docker & Docker Compose
- Make (optional)
- protoc (for gRPC development)
Getting the Source
git clone https://somegit.dev/vikingowl/tyto.git
cd tyto
Project Structure
tyto/
├── backend/
│ ├── cmd/
│ │ ├── server/ # HTTP/SSE server entry point
│ │ ├── agent/ # Lightweight agent entry point
│ │ └── tyto/ # CLI tool
│ ├── internal/
│ │ ├── api/ # HTTP handlers and routes
│ │ ├── alerts/ # Alert management
│ │ ├── auth/ # Authentication (local, LDAP)
│ │ ├── collectors/ # Metric collectors
│ │ │ ├── gpu/ # Multi-vendor GPU support
│ │ │ └── logs/ # Log collectors
│ │ ├── config/ # Configuration loading
│ │ ├── database/ # SQLite/PostgreSQL
│ │ ├── history/ # Historical data storage
│ │ ├── models/ # Data structures
│ │ ├── pki/ # Certificate management
│ │ ├── server/ # gRPC hub for agents
│ │ └── sse/ # Server-Sent Events broker
│ ├── proto/ # gRPC protocol definitions
│ ├── go.mod
│ └── Dockerfile
├── frontend/
│ ├── src/
│ │ ├── lib/
│ │ │ ├── api/ # API clients
│ │ │ ├── components/ # Svelte components
│ │ │ ├── stores/ # Svelte stores
│ │ │ ├── types/ # TypeScript types
│ │ │ └── utils/ # Utility functions
│ │ └── routes/ # SvelteKit routes
│ ├── package.json
│ └── Dockerfile
├── docs/ # Documentation
├── scripts/ # Build and install scripts
├── docker-compose.yml
└── docker-compose.prod.yml
Backend Development
Running Locally
cd backend
# Install dependencies
go mod download
# Run the server
go run ./cmd/server
# Run with specific config
go run ./cmd/server --config ../config.dev.yaml
Building
# Build server binary
go build -o tyto ./cmd/server
# Build agent binary
go build -o tyto-agent ./cmd/agent
# Build CLI
go build -o tyto-cli ./cmd/tyto
# Build with optimizations
CGO_ENABLED=0 go build -ldflags="-s -w" -o tyto ./cmd/server
Cross-Compilation
# Linux AMD64
GOOS=linux GOARCH=amd64 go build -o tyto-linux-amd64 ./cmd/server
# Linux ARM64
GOOS=linux GOARCH=arm64 go build -o tyto-linux-arm64 ./cmd/server
# macOS
GOOS=darwin GOARCH=amd64 go build -o tyto-darwin-amd64 ./cmd/server
Running Tests
# All tests
go test ./...
# With coverage
go test -cover ./...
# Specific package
go test ./internal/collectors/...
# Verbose output
go test -v ./internal/api/...
Linting
# Install golangci-lint
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Run linter
golangci-lint run
gRPC Development
# Install protoc plugins
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# Generate Go code from proto files
protoc --go_out=. --go-grpc_out=. proto/*.proto
Frontend Development
Running Locally
cd frontend
# Install dependencies
npm install
# Start development server
npm run dev
# With specific API URL
VITE_API_URL=http://localhost:8080 npm run dev
Building
# Production build
npm run build
# Preview production build
npm run preview
Running Tests
# Unit tests
npm test
# Watch mode
npm run test:watch
# With coverage
npm run test:coverage
Linting & Formatting
# Lint
npm run lint
# Format
npm run format
# Type check
npm run check
Docker Development
Building Images
# Build all images
docker compose build
# Build specific service
docker compose build backend
docker compose build frontend
# Build without cache
docker compose build --no-cache
Running with Docker
# Start all services
docker compose up
# Start in background
docker compose up -d
# View logs
docker compose logs -f
# Stop services
docker compose down
Development with Hot Reload
# Mount source for hot reload
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
Adding a New Collector
- Create collector file in
backend/internal/collectors/:
// backend/internal/collectors/example.go
package collectors
import "github.com/vikingowl/tyto/internal/models"
type ExampleCollector struct {
// collector state
}
func NewExampleCollector() *ExampleCollector {
return &ExampleCollector{}
}
func (c *ExampleCollector) Collect() (*models.ExampleStats, error) {
// Collect metrics from system
return &models.ExampleStats{
// ...
}, nil
}
- Add model in
backend/internal/models/:
// backend/internal/models/example.go
package models
type ExampleStats struct {
Available bool `json:"available"`
Value int `json:"value"`
}
- Integrate in
backend/internal/collectors/all.go:
func (c *AllCollectors) Collect() *models.AllMetrics {
metrics := &models.AllMetrics{
// ...existing...
Example: c.example.Collect(),
}
return metrics
}
- Add frontend component in
frontend/src/lib/components/.
Adding a New API Endpoint
- Add handler in
backend/internal/api/:
// backend/internal/api/example.go
package api
import (
"github.com/gin-gonic/gin"
)
func (s *Server) exampleHandler(c *gin.Context) {
// Handle request
c.JSON(200, gin.H{"status": "ok"})
}
- Register route in
backend/internal/api/routes.go:
func (s *Server) setupRoutes() {
// ...existing routes...
api := s.router.Group("/api/v1")
api.GET("/example", s.exampleHandler)
}
- Add frontend API client in
frontend/src/lib/api/:
// frontend/src/lib/api/example.ts
export async function getExample(): Promise<ExampleResponse> {
const response = await fetch('/api/v1/example');
return response.json();
}
Testing
Backend Unit Tests
// backend/internal/collectors/cpu_test.go
package collectors
import (
"testing"
)
func TestCPUCollector(t *testing.T) {
collector := NewCPUCollector("/proc")
stats, err := collector.Collect()
if err != nil {
t.Fatalf("Collect() failed: %v", err)
}
if len(stats.Cores) == 0 {
t.Error("Expected at least one CPU core")
}
}
Frontend Component Tests
// frontend/src/lib/components/CpuCard.test.ts
import { render } from '@testing-library/svelte';
import CpuCard from './CpuCard.svelte';
test('renders CPU usage', () => {
const { getByText } = render(CpuCard, {
props: {
cpu: { totalUsage: 50, cores: [] }
}
});
expect(getByText('50%')).toBeInTheDocument();
});
Integration Tests
# Start test environment
docker compose -f docker-compose.test.yml up -d
# Run integration tests
go test -tags=integration ./tests/...
# Cleanup
docker compose -f docker-compose.test.yml down
Code Style
Go
- Follow Effective Go
- Use
gofmtfor formatting - Use meaningful variable names
- Keep functions small and focused
- Document exported functions and types
TypeScript/Svelte
- Use TypeScript strict mode
- Follow Svelte conventions
- Use Prettier for formatting
- Prefer composition over inheritance
- Keep components focused
Commit Messages
Follow Conventional Commits:
feat: add GPU temperature monitoring
fix: resolve memory leak in SSE broker
docs: update API documentation
refactor: simplify collector interface
test: add integration tests for auth
Pull Request Process
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make changes and commit
- Run tests:
go test ./...andnpm test - Run linters:
golangci-lint runandnpm run lint - Push to your fork
- Open a Pull Request
PR Checklist
- Tests pass
- Linting passes
- Documentation updated
- Commit messages follow convention
- No breaking changes (or documented)
Release Process
- Update version in
internal/version/version.go - Update CHANGELOG.md
- Create git tag:
git tag v1.2.3 - Push tag:
git push origin v1.2.3 - CI builds and publishes releases
Debugging
Backend
# Run with debug logging
TYTO_LOG_LEVEL=debug go run ./cmd/server
# Use delve debugger
dlv debug ./cmd/server
Frontend
- Use browser DevTools
- React/Svelte DevTools extension
console.logfor quick debugging
Docker
# Shell into container
docker exec -it tyto-backend /bin/sh
# View container logs
docker logs tyto-backend -f
# Inspect container
docker inspect tyto-backend
Performance Profiling
Go Profiling
import _ "net/http/pprof"
// Access at http://localhost:8080/debug/pprof/
# CPU profile
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30
# Memory profile
go tool pprof http://localhost:8080/debug/pprof/heap
Frontend Performance
- Use Lighthouse in Chrome DevTools
- React Profiler for component performance
- Network tab for API timing