go/CLAUDE.md
Snider 0cb6a4cff3 docs: update CLAUDE.md to reflect pure DI framework
Remove stale references to extracted packages (pkg/ws, pkg/webview,
pkg/mcp, cmd/bugseti, cmd/core-gui). Replace Taskfile commands with
`core go` equivalents. Describe current pkg/core + pkg/log scope.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 14:48:02 +00:00

3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Core (forge.lthn.ai/core/go) is a dependency injection and service lifecycle framework for Go. It provides a typed service registry, lifecycle hooks, and a message-passing bus for decoupled communication between services.

This is the foundation layer — it has no CLI, no GUI, and minimal dependencies (go-io, go-log, testify).

Build & Development Commands

This project uses core go commands (no Taskfile). Build configuration lives in .core/build.yaml.

# Run all tests
core go test

# Generate test coverage
core go cov
core go cov --open      # Opens coverage HTML report

# Format, lint, vet
core go fmt
core go lint
core go vet

# Quality assurance
core go qa              # fmt + vet + lint + test
core go qa full         # + race, vuln, security

# Build
core build              # Auto-detects project type
core build --ci         # All targets, JSON output

Run a single test: core go test --run TestName

Architecture

Core Framework (pkg/core/)

The Core struct is the central application container managing:

  • Services: Named service registry with type-safe retrieval via ServiceFor[T]()
  • Actions/IPC: Message-passing system where services communicate via ACTION(msg Message) and register handlers via RegisterAction()
  • Lifecycle: Services implementing Startable (OnStartup) and/or Stoppable (OnShutdown) interfaces are automatically called during app lifecycle

Creating a Core instance:

core, err := core.New(
    core.WithService(myServiceFactory),
    core.WithAssets(assets),
    core.WithServiceLock(),  // Prevents late service registration
)

Service Registration Pattern

Services are registered via factory functions that receive the Core instance:

func NewMyService(c *core.Core) (any, error) {
    return &MyService{runtime: core.NewServiceRuntime(c, opts)}, nil
}

core.New(core.WithService(NewMyService))
  • WithService: Auto-discovers service name from package path, registers IPC handler if service has HandleIPCEvents method
  • WithName: Explicitly names a service

ServiceRuntime Generic Helper (runtime.go)

Embed ServiceRuntime[T] in services to get access to Core and typed options:

type MyService struct {
    *core.ServiceRuntime[MyServiceOptions]
}

Error Handling (e.go)

Use the E() helper for contextual errors:

return core.E("service.Method", "what failed", underlyingErr)

Test Naming Convention

Tests use _Good, _Bad, _Ugly suffix pattern:

  • _Good: Happy path tests
  • _Bad: Expected error conditions
  • _Ugly: Panic/edge cases

Packages

Package Description
pkg/core DI container, service registry, lifecycle, query/task bus
pkg/log Structured logger service with Core integration

Go Workspace

Uses Go 1.25 workspaces. This module is part of the workspace at ~/Code/go.work.

After adding modules: go work sync