Skip to content

Latest commit

 

History

History
91 lines (75 loc) · 5.76 KB

File metadata and controls

91 lines (75 loc) · 5.76 KB

CLAUDE.md

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

Development commands

  • go run . — run the TUI from the repository root.
  • go install ./cmd/nnmon — install the nnmon CLI entrypoint.
  • go build ./... — compile all packages.
  • go build ./cmd/nnmon — compile just the installable CLI entrypoint.
  • go test ./... — run the full test suite.
  • go test ./internal/app ./internal/metrics — run the most frequently touched package tests while iterating on UI or sampling changes.
  • go test ./internal/app -run TestProcessSearchInputUpdatesQuery — run a single test by name; swap in the target package and test name as needed.
  • go fmt ./... — apply the repo’s standard formatting.
  • go vet ./... — lightweight static analysis; there is no dedicated repo lint config checked in.
  • go mod tidy — only when dependencies change.

High-level architecture

Entrypoints are intentionally thin

  • main.go and cmd/nnmon/main.go both do the same thing: create app.New(), run it through Bubble Tea, and use the alternate screen.
  • Almost all product logic lives under internal/.

internal/app is the application coordinator

  • The app uses a single Bubble Tea model, defined in internal/app/state.go.
  • Model owns terminal dimensions, active view, process/network/storage sub-state, the latest metrics.Snapshot, the shared history store, and the control.Executor.
  • internal/app/update.go is the main event loop. It handles:
    • terminal resize
    • periodic polling
    • manual refresh
    • keyboard routing
    • metric collection results
    • action execution results
  • internal/app/layout.go is the top-level renderer. It decides between the normal screen, the help modal, the action modal, and the “terminal too small” fallback.

Metrics flow is snapshot-based, not ad hoc

  • internal/metrics/snapshot.go defines the shared data contract between collectors and UI.
  • UI code should treat metrics.Snapshot as the canonical read model for the current screen.
  • internal/metrics/service.go does not collect everything on every UI tick. It uses scheduled lanes:
    • fast lane every 750ms: CPU, memory, network
    • medium lane every 3s: processes
    • slow lane every 15s: host and disk
  • CollectModeFull bypasses those intervals for manual refreshes.
  • SampleCache stores lane timestamps and previous network totals so incremental refreshes can compute rates without reinitializing state.

Historical charts are fed from refresh results

  • internal/app/history.go keeps fixed-length series (default 32 points).
  • After each successful collection, internal/app/update.go only pushes series for the metric groups that were actually refreshed.
  • Reuse this history store for sparklines or short trend views instead of introducing separate history caches.

Collectors are responsible for shaping monitor data before UI sees it

  • internal/metrics/collectors_process.go gathers process data with gopsutil, filters out unusable entries, sorts by RSS, and caps the sample size.
  • Network rate calculation depends on cached previous totals, so changes to network collection should preserve cache semantics.
  • Disk and process collectors already perform ranking/trimming; the UI mostly renders curated snapshot data instead of re-collecting or re-normalizing it.

internal/control isolates side effects and platform-specific behavior

  • Process-management actions are defined via the action catalog in internal/control/catalog.go.
  • The UI never sends OS signals directly; it opens an action palette and executes through the control.Executor interface.
  • control.DefaultExecutor() currently returns LocalProcessExecutor.
  • On darwin and linux, internal/control/local_process_unix.go maps actions to real Unix signals.
  • On unsupported platforms, local_process_unsupported.go keeps the feature present but non-functional with clear status messages.
  • New management actions should follow the same pattern: catalog entry, capability gating, confirm behavior for dangerous actions, then executor support.

Important repository conventions

  • Keep package boundaries strict:
    • internal/app for Bubble Tea state, layout, input handling, and rendering
    • internal/metrics for sampling, snapshot shaping, and metric formatting
    • internal/control for OS-facing management actions and executor logic
  • This is a single-model Bubble Tea app. Prefer extending app.Model and its sub-state over introducing global state or parallel controller layers.
  • If a new metric is expensive to collect, assign it to the appropriate sampling lane instead of attaching it to every 750ms tick.
  • Tests live next to the code they cover. The main coverage areas today are:
    • internal/app: layout, keyboard behavior, action palette behavior, filtering/search flows
    • internal/metrics: scheduled collection behavior
    • internal/control: capability and executor behavior

Navigation/view caveat

  • viewStorage and storage rendering/tests exist, but the storage page is not currently wired into the main navigation.
  • The active navigation path only exposes overview, processes, and network.
  • If you re-enable or add a view, update all of these together:
    • orderedViews in internal/app/state.go
    • keyboard shortcuts in internal/app/input.go
    • renderActiveView and help/footer copy in internal/app/layout.go
    • any affected tests in internal/app/model_test.go

Existing style and workflow hints from the repo

  • Use standard Go naming and formatting conventions.
  • Prefer feature-oriented filenames like view_processes.go and collectors_network.go.
  • Recent commit messages use short imperative subjects such as Refine process view layout and sampling and Add installable nnmon CLI entrypoint.