CLAUDE.md
CLAUDE.mdCLAUDE.mdroot
Quality
89/100
Scores the file, not the repository.Length
991 words
8 headings · 1 code blocksRepository
0
— · pushed 32 days agoLast changed
3 days ago
First indexed 3 days ago.1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## Project Overview67Hovimestari ("Butler" in Finnish) is a Go-based personal AI butler assistant inspired by Geoffrey Litt's Stevens assistant. It stores "memories" in a single SQLite table, imports data from multiple sources (calendars, weather, manual input), and generates personalized daily briefs using Google Gemini API. The project emphasizes simplicity with a pure Go implementation for easy cross-compilation.89## Development Workflow1011**Build System**: Uses [Task](https://taskfile.dev/) runner instead of Make (see `Taskfile.yml`). Build depends on lint and test passing.1213**Critical Commands**:1415- `task build` - Build for current OS/ARCH (runs lint + test first)16- `task build-linux` - Cross-compile for Linux AMD64 (CGO-free)17- `task test` - Run all tests (deterministic, no external deps)18- `task lint` - Run golangci-lint (required before commit)19- `task deps` - Tidy Go module dependencies2021**Application Commands**:2223- `task import-calendar` - Import WebCal/iCalendar events with smart/full_refresh modes24- `task import-weather` - Import MET Norway weather forecasts25- `task import-water-quality` - Import water quality data for specific locations26- `task generate-brief` - Generate daily brief using LLM and current memories27- `task add-memory CONTENT="text" RELEVANCE_DATE="2025-01-01" SOURCE="manual"` - Add manual memory28- `task init-config` - Initialize config (reads GEMINI_API_KEY, WEBCAL_URL from env)29- `task run` - Build and run the application30- `task publish` - Deploy binary to remote server3132**Utility Commands**:3334- `task upgrade-deps` - Upgrade all Go dependencies35- `task clean` - Clean all build artifacts36- `task clean-build` - Clean build directory only37- `task clean-linux` - Clean Linux build artifacts3839**Direct CLI Usage**: `./build/hovimestari <command> --config=/path/to/config.json --log-level=debug`4041**Available CLI Commands**:4243- `import-calendar` - Import calendar events from WebCal/iCalendar URLs44- `import-weather` - Import weather forecasts from MET Norway45- `import-water-quality` - Import water quality data46- `generate-brief` - Generate personalized daily brief47- `show-brief-context` - Show context that would be sent to LLM without generating brief (debug)48- `add-memory` - Add manual memory entry49- `init-config` - Initialize configuration file50- `list-models` - List available Gemini LLM models5152## Architecture5354**CLI Framework**: Uses `alecthomas/kong` (not Cobra) for command parsing in `cmd/hovimestari/main.go`. Global flags: `--config`, `--log-level`5556**Core Data Flow**:57581. **Import Phase**: Various importers fetch data → format as memories → store in SQLite592. **Brief Generation**: `internal/brief/brief.go` queries relevant memories → combines with prompts → sends to LLM → outputs to multiple destinations6061**Key Components**:6263- `internal/store/store.go` - Two SQLite tables (`memories` and `calendar_events`) with source-based organization64- `internal/config/viper.go` - Viper configuration with XDG Base Directory support65- `internal/brief/brief.go` - Brief generation orchestrator combining memories + LLM66- `internal/llm/gemini.go` - Google Gemini API client (supports multiple models)67- `internal/logging/handler.go` - Custom slog handler for human-readable output68- `internal/output/` - Multi-destination system (CLI, Discord, Telegram)6970**Importers Pattern**:7172- `internal/importer/calendar/` - WebCal imports with smart (upsert) vs full_refresh (replace_all) strategies73- `internal/importer/weather/` - MET Norway API integration74- Commands in `cmd/hovimestari/commands/` for manual data entry7576**Design Principles**:7778- **Two-Table Design**:79 - `memories` table for general memories (weather, manual entries, etc.) with hierarchical `source` field (e.g., "weather:helsinki", "manual")80 - `calendar_events` table for structured calendar data with proper datetime columns81- **Pure Go**: Uses `modernc.org/sqlite` (no CGO) for cross-compilation without Docker82- **XDG Compliance**: Config files follow standard (`~/.config/hovimestari/`)83- **Extensible I/O**: Output system supports multiple simultaneous destinations8485## Configuration8687**Files**: `config.json`, `prompts.json`, `memories.db` (SQLite)8889**Config Resolution Order**:90911. `--config` flag path922. `$XDG_CONFIG_HOME/hovimestari/` (usually `~/.config/hovimestari/`)933. Directory containing executable9495**Key Config Fields**:9697- `gemini_api_key`, `gemini_model` - LLM configuration98- `calendars[]` with `update_mode: "smart"|"full_refresh"` - Calendar import strategy99- `outputs.enable_cli`, `outputs.discord_webhook_urls[]`, `outputs.telegram_bots[]` - Multi-destination output100- `family[]` with optional birthdays - Birthday tracking in briefs101102## Memory System103104Data is stored in two SQLite tables:105106**1. `memories` table** - For general memories (weather, manual entries):107108- `content` - Formatted text (e.g., "Weather: Sunny, 20°C in Helsinki")109- `source` - Hierarchical source identifier (e.g., "weather:helsinki", "manual")110- `relevance_date` - When memory is relevant (used for brief filtering)111- `uid` - Optional unique identifier for deduplication112113**2. `calendar_events` table** - For structured calendar data:114115- `uid` - Unique event identifier (prevents duplicates)116- `summary` - Event title/summary117- `start_time`, `end_time` - Event datetime range118- `location` - Event location (optional)119- `description` - Event description (optional)120- `source` - Hierarchical source identifier (e.g., "calendar:work", "calendar:personal")121- `created_at` - When the event was imported122123## Testing124125Tests exist for deterministic functions in `*_test.go` files:126127- Calendar URL conversion and event formatting128- Weather forecast formatting129- Output system behavior130131Run with `task test` or `go test ./...`. Tests avoid external dependencies (network, database, LLM calls).132133## Development Guidelines134135**Code Style**: Follow `.clinerules/go-codestyle.md` conventions:136137- Use `fmt.Errorf("failed to X: %w", err)` for error wrapping138- Prefer standard library, use `alecthomas/kong` for CLI, `spf13/viper` for config139- Use `modernc.org/sqlite` for SQLite (CGO-free)140- Use `slog` for logging, `fmt.Printf` for interactive output141142**Testing Strategy**:143144- Tests avoid external dependencies (network, database, LLM calls)145- Focus on deterministic functions: URL conversion, data formatting, parsing146- Examples: `calendar_test.go` (event formatting), `weather_test.go` (forecast formatting)147- Run `task test` (includes in build pipeline)148149**Adding New Features**:150151- **New Importer**: Create package in `internal/importer/`, implement similar interface to calendar importer152- **New Command**: Add file in `cmd/hovimestari/commands/`, follow Kong CLI pattern153- **New Config**: Update `Config` struct in `internal/config/viper.go`, add to `config.example.json`154155**Memory Storage Pattern**:156157```go158// Pattern 1: General memories (weather, manual entries)159content := fmt.Sprintf("Weather: %s, %.1f°C in %s", condition, temp, location)160source := "weather:" + locationName // Hierarchical source naming161uid := "" // Optional unique identifier for deduplication162// Store in memories table163164// Pattern 2: Calendar events (stored in dedicated table)165calendarEvent := CalendarEvent{166 UID: event.UID,167 Summary: event.Summary,168 StartTime: event.Start,169 EndTime: event.End,170 Location: event.Location,171 Description: event.Description,172 Source: "calendar:" + calendarName, // Hierarchical source naming173}174// Store in calendar_events table175```176177**Cross-Compilation**: Pure Go implementation enables simple `GOOS=linux GOARCH=amd64 go build` without Docker or CGO178179**Commit Requirements**: Always run `task build` (includes lint + test) before commits180
Also in lepinkainen/hovimestari
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| lepinkainen/hovimestari.clinerules/project.md · 0 | Cline rules | archtypesdatabaseagent-behaviour+1 | 58/100 | 3 days ago | |
| lepinkainen/hovimestari.clinerules/go-codestyle.md · 0 | Cline rules | testlint-formatstyletesting-strategy+1 | 64/100 | 3 days ago | |
| lepinkainen/hovimestariAGENTS.md · 0 | AGENTS.md | buildtestlint-formatstyle+4 | 86/100 | 3 days ago | |
| lepinkainen/hovimestariGEMINI.md · 0 | GEMINI.md | teststylearchtesting-strategy+1 | 81/100 | 3 days ago |
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| livewire/livewireCLAUDE.md · 24k | CLAUDE.md | setupbuildteststyle+4 | 100/100 | 3 days ago | |
| filamentphp/filamentCLAUDE.md · 32k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| stacklok/toolhiveCLAUDE.md · 2.0k | CLAUDE.md | buildteststylearch+4 | 100/100 | 3 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago |
