This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Clockwork is a dual-mode time tracking system that automatically tracks work time based on git commits:
- MCP Server Mode - Exposes time tracking as MCP tools for integration with Claude and other LLM applications
- TUI Mode - Interactive terminal user interface for direct interaction with keyboard navigation
Both modes share the same embedded bbolt database and business logic.
Module Path: github.com/techthos/clockwork
# Build binary
go build -o clockwork ./cmd/clockwork
# Install to GOPATH/bin
go install ./cmd/clockwork
# Run MCP server mode (default)
./clockwork
# Run TUI mode
./clockwork tui
# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Run specific package tests
go test ./internal/db -v
go test ./internal/git -v
go test ./internal/tui -v
# Tidy dependencies
go mod tidyAfter building, configure the clockwork server in your MCP client:
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"clockwork": {
"command": "/absolute/path/to/clockwork"
}
}
}Edit ~/.claude/config.json:
{
"mcpServers": {
"clockwork": {
"command": "/absolute/path/to/clockwork"
}
}
}Note: Use the absolute path to the binary. If you ran go install, the binary is at $(go env GOPATH)/bin/clockwork (typically ~/go/bin/clockwork).
The server auto-creates its database at ~/.local/clockwork/default.db on first run.
The core workflow aggregates git commits into worklog entries:
- Retrieve last entry's commit hash (
store.GetLastEntry) - establishes baseline - Fetch commits since that hash (
git.GetCommitsSince) - usesgit log <hash>..HEAD - Aggregate commit messages (
git.AggregateCommits) - formats into summary - Calculate duration (
git.CalculateDuration) - single commit = 30min, multiple = time span + 30min buffer - Store entry with latest commit hash (
store.CreateEntry) - becomes next baseline
internal/server/server.go implements 8 MCP tools via the mcp-go library (v0.9.0):
- Tool definitions use
mcp.NewTool()with schema descriptors - Handlers access arguments via
request.Params.Arguments(map[string]interface{}) - Required strings extracted via
getRequiredString()helper - Errors returned as
mcp.NewToolResultError(string) - Success returns
mcp.NewToolResultText(string)with JSON-marshaled data
Project tools: create_project, update_project, delete_project, list_projects Entry tools: create_entry, update_entry, delete_entry, list_entries
bbolt key-value store at ~/.local/clockwork/default.db:
- Two buckets:
projectsandentries - All operations wrapped in transactions (
db.Update,db.View) - Data stored as JSON-marshaled bytes with UUID keys
GetLastEntry()iterates entries, filters by project_id, returns most recent by created_atDeleteProject()cascades to all associated entries
internal/git/ uses exec.Command("git", ...):
GetCommitsSince(repoPath, sinceHash)- executesgit log --pretty=format:%H|%an|%s|%at [sinceHash..HEAD]- Parses pipe-delimited output into
[]models.CommitInfo - Empty
sinceHashreturns all commits GetLatestCommitHash()runsgit rev-parse HEAD- All operations require absolute repo paths (
filepath.Abs())
internal/tui/ implements a terminal user interface using tview:
Main Components:
app.go- Application shell with page management and navigationprojects.go- Projects list view (table with CRUD operations)entries.go- Entries list view with filtering and summary footerstats.go- Statistics dashboard with breakdownsproject_form.go- Project create/edit modal formsentry_form.go- Entry create/edit with git/manual modesmodals.go- Reusable error/confirm/info dialogstheme.go- Color scheme constantshelpers.go- Formatting utilities (duration, dates, percentages)
Navigation Flow:
Projects View (default)
→ Entries View (filtered by project)
→ Statistics View (with filters)
→ Entry Forms (git/manual modes)
→ Project Forms (create/edit)
Keyboard Shortcuts:
- Global:
Ctrl+C/Ctrl+Q= quit,Esc= close modal - Projects:
n= new,e= edit,d= delete,Enter= view entries,q= quit - Entries:
n= new,e= edit,d= delete,i= toggle invoiced,f= filter,s= stats,q= back - Stats:
f= filter,r= refresh,q= back
Filtering:
FilterOptionsstruct tracks current filters (project, date range, invoiced status)- Filters persist within a session, reset between entries/stats views
- Uses
store.ListEntriesFiltered()andstore.GetStatistics()with filter parameters
TUI vs MCP Mode:
- Both use same
db.Storeinterface - no database layer changes needed - Entry point (
main.go) checks fortuiargument to determine mode - Only one mode can run at a time due to bbolt's single-writer file lock
Entry point (cmd/clockwork/main.go) → server.New():
- Resolves
~/.local/clockwork/default.dbpath - Calls
db.New()to initialize bbolt store - Creates
server.MCPServerinstance ("clockwork", "1.0.0") - Registers all 8 tools via
registerTools() - Serves via stdio transport with
server.ServeStdio()
- Database tests use
t.TempDir()for isolation - Git tests use static mock data (no actual git commands)
- Models tests verify struct creation and field access
- No server integration tests (MCP tools tested via manual client interaction)
- All database errors wrapped with context (
fmt.Errorf(...%w, err)) - MCP tool errors converted to strings via
.Error()method - Server initialization errors logged to stderr and exit(1)
Core:
- github.com/mark3labs/mcp-go v0.9.0 - MCP protocol (stdio transport)
- go.etcd.io/bbolt v1.3.11 - Embedded key-value database
- github.com/google/uuid v1.6.0 - UUID generation
TUI:
- github.com/rivo/tview v0.42.0 - Terminal UI framework (high-level widgets)
- github.com/gdamore/tcell/v2 v2.8.1 - Terminal cell-based view (tview dependency)
System:
- System git command required (not a Go dependency)
Production: ~/.local/clockwork/default.db
Tests: t.TempDir()/<testname>.db
Important Limitation: Only one instance can hold the database lock at a time (bbolt limitation). This means:
- Cannot run MCP server and TUI simultaneously
- Attempting to start TUI while MCP server is running will fail with "timeout" error
- Attempting to start MCP server while TUI is running will fail with "timeout" error
- This is by design for data integrity - bbolt ensures single-writer safety
After building, launch the TUI:
./clockwork tuiQuick Start:
- Press
nin Projects view to create first project - Enter project name and git repository path
- Press
Enteron project to view entries - Press
nto create entry (choose Git or Manual mode) - Git mode: automatically aggregates commits since last entry
- Manual mode: enter duration (e.g., "1h 30m") and message
- Press
sfrom entries view to see statistics - Press
fto apply filters (project, date range, invoiced status)
Entry Creation Modes:
- Git Mode: Fetches commits since last entry, auto-calculates duration, generates message from commit summaries
- Manual Mode: User enters duration and message manually (for non-git work like meetings)