Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/codebase/structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ internal/
- `.golangci.yml` - Linter config: `default: all` with errorlint strict
(errorf + errorf-multi + comparison + asserts), goconst/gomodguard
disabled
- `go.mod` - Go 1.27.2; deps include bubbletea v2 / lipgloss v2 / huh v2,
- `go.mod` - Go 1.27.3; deps include bubbletea v2 / lipgloss v2 / huh v2,
gorm + modernc sqlite, any-llm-go, modelcontextprotocol/go-sdk
- `docs/` - Hugo site (guides, reference, blog)
- `plans/` - Design documents (committed to repo)
Expand Down
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
maintenance schedules, appliances, vendors, incidents, and expenses. It uses a
single SQLite database file with no cloud dependencies.

- **Language**: Go 1.27.2
- **Language**: Go 1.27.3
- **TUI framework**: Charmbracelet Bubble Tea + lipgloss + huh forms
- **ORM**: GORM with pure-Go SQLite (`modernc.org/sqlite`)
- **LLM**: Optional integration via `any-llm-go` (Ollama, OpenAI-compatible)
Expand Down
11 changes: 0 additions & 11 deletions .govulncheck-exclude
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,3 @@ GO-2025-3689
GO-2025-3695
GO-2025-3824
GO-2025-4251

# Go stdlib vulns with no fix in Go 1.25.x yet (fixed in 1.25.8 / 1.26.1).
# Re-evaluate after nixpkgs picks up Go 1.25.8+.
# os.FileInfo Root escape; micasa never uses os.Root
GO-2026-4602
# net/url IPv6 parsing; micasa only connects to localhost ollama
GO-2026-4601
# crypto/x509 malformed cert panic; micasa does not verify x509 certs
GO-2026-4600
# crypto/x509 email constraint enforcement; same as above
GO-2026-4599
2 changes: 1 addition & 1 deletion deploy/docker-compose.caddy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

services:
caddy:
image: caddy@sha256:844f60b64e4724a5aa8245e019dace0d3f199f7433ce6c57676cb30a920dbad9 # 2-alpine
image: caddy@sha256:eb4d35b7452d1ab6171fbdbe8d9275b2301dad6dad92115d91e19fb9b24d510f # 2-alpine
environment:
DOMAIN: ${DOMAIN}
ports:
Expand Down
2 changes: 1 addition & 1 deletion deploy/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

services:
postgres:
image: postgres@sha256:a02db8cac496f15b094798a38254f14d6e00741f709360e5e00bb6668ea31636 # 17-alpine
image: postgres@sha256:eee6c6e1b0894fa4fe0075eb054af9fd1cf39a35321c2d4110626cfe506411fb # 17-alpine
environment:
POSTGRES_USER: micasa
POSTGRES_DB: micasa
Expand Down
4 changes: 2 additions & 2 deletions deploy/relay/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the Apache License, Version 2.0

# golang 1.27-alpine
FROM golang@sha256:f92b6ef800e499660581efdabdf25d9d817a9d124eaf900924f0504e7e27e12d AS build
FROM golang@sha256:b8c9b82affbbb82a020bbcf998dad2ba9516944ac7e883524642a481a9505e9c AS build
ARG BUILD_TAGS
WORKDIR /src
COPY go.mod go.sum ./
Expand All @@ -11,7 +11,7 @@ COPY . .
RUN CGO_ENABLED=0 go build -trimpath ${BUILD_TAGS:+-tags "$BUILD_TAGS"} -o /relay ./cmd/relay

# distroless static-debian12
FROM gcr.io/distroless/static-debian12@sha256:a9fcaedd4c9b59e12dd65d954f0b5044f19b0647a8a3712e77205df9e7b102cd
FROM gcr.io/distroless/static-debian12@sha256:d75cdd72874d4790092fcb1b058493ecf6bb5bf2b2b897045b00ff01d91843f2
COPY --from=build /relay /relay
EXPOSE 8080
ENTRYPOINT ["/relay"]
2 changes: 1 addition & 1 deletion docs/content/docs/development/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ linkTitle = "Building"

## Prerequisites

- **Go 1.26.5+** (the only hard requirement)
- **Go 1.27.3+** (the only hard requirement)
- **Nix** (optional, but provides the full dev environment)

## Quick build
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/development/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ for use as a dependency will be closed.
## Setup

1. Fork and clone the repo
2. Enter the dev shell: `nix develop` (or install Go 1.26.5+ manually)
2. Enter the dev shell: `nix develop` (or install Go 1.27.3+ manually)
3. The dev shell auto-installs pre-commit hooks on first entry

## Pre-commit hooks
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ brew install micasa

## Go install

Requires Go 1.26.5+:
Requires Go 1.27.3+:

```sh
go install github.com/micasa-dev/micasa/cmd/micasa@latest
Expand Down
18 changes: 9 additions & 9 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

module github.com/micasa-dev/micasa

go 1.27.2
go 1.27.3

require (
charm.land/bubbles/v2 v2.2.1
Expand Down
3 changes: 2 additions & 1 deletion internal/app/extraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func newExtractionModel(t *testing.T, steps map[extractionStep]stepStatus) *Mode
}
for si, status := range steps {
ex.Steps[si] = extractionStepInfo{Status: status}
//exhaustive:ignore // test helper only sets known steps
// test helper only sets known steps
//exhaustive:ignore
switch si {
case stepText:
ex.hasText = true
Expand Down
3 changes: 2 additions & 1 deletion internal/app/form_validators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ func TestFormDataStructsHaveNoReferenceFields(t *testing.T) {
rt := reflect.TypeOf(s)
t.Run(rt.Name(), func(t *testing.T) {
for f := range rt.Fields() {
//exhaustive:ignore // only reference kinds matter here
// only reference kinds matter here
//exhaustive:ignore
switch f.Type.Kind() {
case reflect.Pointer, reflect.Slice, reflect.Map,
reflect.Chan, reflect.Func, reflect.Interface:
Expand Down
3 changes: 2 additions & 1 deletion internal/app/model_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ func (m *Model) updateForm(msg tea.Msg) (tea.Model, tea.Cmd) {
}
}
}
//exhaustive:ignore // third-party enum (charmbracelet/huh)
// third-party enum (charmbracelet/huh)
//exhaustive:ignore
switch m.fs.form.State {
case huh.StateCompleted:
return m, m.saveForm()
Expand Down
3 changes: 2 additions & 1 deletion internal/app/mouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ func (m *Model) handleMouseClick(msg tea.MouseClickMsg) (tea.Model, tea.Cmd) {

// handleMouseWheel dispatches wheel events to scroll handlers.
func (m *Model) handleMouseWheel(msg tea.MouseWheelMsg) (tea.Model, tea.Cmd) {
//exhaustive:ignore // third-party enum (charmbracelet/x/ansi); only vertical scroll is handled
// third-party enum (charmbracelet/x/ansi); only vertical scroll is handled
//exhaustive:ignore
switch msg.Button {
case tea.MouseWheelUp:
return m.handleScroll(-1)
Expand Down
9 changes: 6 additions & 3 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ func walkEnvFields(v reflect.Value, prefix string, extra map[string]string) erro
// setFieldFromEnv assigns a string value from an environment variable to a
// reflected config field, converting types as needed.
func setFieldFromEnv(fv reflect.Value, envVar, val string) error {
//exhaustive:ignore // only config-relevant kinds
// only config-relevant kinds
//exhaustive:ignore
switch fv.Kind() {
case reflect.String:
fv.SetString(val)
Expand All @@ -435,7 +436,8 @@ func setFieldFromEnv(fv reflect.Value, envVar, val string) error {
}

func setFieldFromEnvPtr(fv reflect.Value, envVar, val string) error {
//exhaustive:ignore // only config-relevant kinds
// only config-relevant kinds
//exhaustive:ignore
switch fv.Type().Elem().Kind() {
case reflect.Bool:
b, err := strconv.ParseBool(val)
Expand Down Expand Up @@ -592,7 +594,8 @@ func formatValue(v reflect.Value) (string, error) {
return val.String(), nil
}

//exhaustive:ignore // only config-relevant kinds
// only config-relevant kinds
//exhaustive:ignore
switch v.Kind() {
case reflect.String:
return v.String(), nil
Expand Down
6 changes: 4 additions & 2 deletions internal/config/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,8 @@ func formatTOMLValue(v reflect.Value) (string, bool) {
return strconv.Quote(string(text)), true
}

//exhaustive:ignore // only config-relevant kinds
// only config-relevant kinds
//exhaustive:ignore
switch v.Kind() {
case reflect.String:
return strconv.Quote(v.String()), true
Expand Down Expand Up @@ -326,7 +327,8 @@ func isEmptyValue(v reflect.Value) bool {
return v.IsNil()
}

//exhaustive:ignore // only config-relevant kinds
// only config-relevant kinds
//exhaustive:ignore
switch v.Kind() {
case reflect.String:
return v.String() == ""
Expand Down
3 changes: 2 additions & 1 deletion internal/config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ func newConfigValidator() *validator.Validate {

mustRegister(v, "nonneg_duration", func(fl validator.FieldLevel) bool {
field := fl.Field()
//exhaustive:ignore // only numeric kinds relevant
// only numeric kinds relevant
//exhaustive:ignore
switch field.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return field.Int() >= 0
Expand Down
3 changes: 2 additions & 1 deletion internal/data/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ func StructDefault[T any](fieldName string) string {
}

func setFieldDefault(field reflect.Value, tag string) {
//exhaustive:ignore // only handle types used in model/config defaults
// only handle types used in model/config defaults
//exhaustive:ignore
switch field.Kind() {
case reflect.String:
if tag == defaultTagToday {
Expand Down
Loading