docs: update CLAUDE.md and AGENTS.md for entity-based architecture

- Update architecture section to reflect actual file structure
- Document entity system (sensor, binary_sensor, switch, light, button)
- Add MQTT topic documentation
- Add NixOS/home-manager integration section
- Update commands section
- Replace metrics-specialist with entity-specialist
- Replace events-specialist with nix-specialist
- Update mqtt-specialist context for current topic structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ryan 2026-01-19 21:33:51 -08:00
parent 1629c8d5d2
commit 904bef4aa7
2 changed files with 84 additions and 40 deletions

View File

@ -27,17 +27,17 @@ Use this agent to review code changes before committing.
**Trigger:** Before creating commits or PRs. **Trigger:** Before creating commits or PRs.
## metrics-specialist ## entity-specialist
Use this agent when working on system metric collection. Use this agent when working on entity configuration or the entity system.
**Responsibilities:** **Responsibilities:**
- Understand Linux /proc and /sys interfaces - Understand entity types (sensor, binary_sensor, switch, light, button)
- Know cross-platform metric collection strategies - Design shell commands for state polling and actions
- Ensure metrics are properly typed and documented - Ensure proper Home Assistant discovery payloads
- Validate metric units and normalization - Validate entity configuration options
**Context:** Systant collects CPU, memory, disk, and network metrics. Metrics should be normalized (percentages 0-100, bytes for sizes) and include metadata for Home Assistant discovery. **Context:** Systant uses a unified "entity" system where all metrics and controls are defined as entities in TOML config. Each entity has a `state_command` and optionally `on_command`/`off_command`/`press_command` depending on type.
## mqtt-specialist ## mqtt-specialist
@ -50,20 +50,19 @@ Use this agent when working on MQTT publishing or Home Assistant integration.
- Handle connection lifecycle (connect, reconnect, disconnect) - Handle connection lifecycle (connect, reconnect, disconnect)
- Design topic hierarchies for commands and events - Design topic hierarchies for commands and events
**Context:** Systant publishes to MQTT with Home Assistant auto-discovery. Topics follow the pattern `systant/{hostname}/{metric_type}`. Command topics use `systant/{hostname}/command/{action}`. **Context:** Systant publishes to MQTT with Home Assistant auto-discovery. Topics follow the pattern `systant/{hostname}/{entity_id}/state` for state updates, `systant/{hostname}/{entity_id}/set` for switch/light commands, and `homeassistant/{type}/{hostname}_{entity_id}/config` for discovery.
## events-specialist ## nix-specialist
Use this agent when working on the event/command system. Use this agent when working on Nix packaging or the home-manager module.
**Responsibilities:** **Responsibilities:**
- Design secure command execution with allowlists - Maintain the Nix flake and package definition
- Implement event handlers and action dispatching - Update the home-manager module options
- Ensure proper input validation and sanitization - Handle fixed-output derivations for npm dependencies
- Handle timeouts and error reporting - Ensure cross-system compatibility
- Consider security implications of remote command execution
**Context:** Systant listens for MQTT commands and executes configured actions. Security is paramount - all commands must be validated against an allowlist, inputs sanitized, and execution sandboxed where possible. **Context:** Systant is packaged as a Nix flake with a home-manager module. The package uses a two-phase build: FOD for `bun install`, then `bun build --compile` for the binary. The home-manager module creates a systemd user service.
## debug-investigator ## debug-investigator

View File

@ -16,30 +16,49 @@ Systant is a lightweight CLI tool written in Bun/TypeScript that:
### Architecture ### Architecture
``` ```
index.ts # CLI entry point (yargs) index.ts # CLI entry point
src/ src/
commands/ # CLI command handlers config.ts # TOML configuration loading
metrics/ # System metric collectors mqtt.ts # MQTT client, publishing, and HA discovery
mqtt/ # MQTT client and publishing entities.ts # Entity management (state polling, command handling)
events/ # MQTT event listeners and handlers
actions/ # Executable actions (shell, service, notify)
ha/ # Home Assistant discovery
config/ # Configuration loading
``` ```
### Event/Command System ### Entity System
Systant subscribes to MQTT topics and executes configured actions: Systant uses a unified "entity" concept that combines state monitoring and command handling. Entity types:
``` - **sensor**: Read-only numeric/string values (CPU usage, temperature, etc.)
Topic: systant/{hostname}/command/{action} - **binary_sensor**: Read-only on/off states (service running, etc.)
Payload: { "args": [...], "timeout": 30 } - **switch**: Controllable on/off with `on_command` and `off_command`
- **light**: Same as switch, for display/monitor control
- **button**: Press-only actions with `press_command`
Topic: systant/{hostname}/event/{event_name} Each entity is defined in TOML with shell commands:
Payload: { ... event data ... }
```toml
[entities.cpu_usage]
type = "sensor"
state_command = "awk '/^cpu / {print int(($2+$4)*100/($2+$4+$5))}' /proc/stat"
unit = "%"
icon = "mdi:chip"
name = "CPU Usage"
[entities.headphones]
type = "switch"
state_command = "pactl get-default-sink | grep -q usb && echo ON || echo OFF"
on_command = "pactl set-default-sink alsa_output.usb-..."
off_command = "pactl set-default-sink alsa_output.pci-..."
``` ```
Actions are sandboxed and configurable via allowlists in the config file. Security is critical - never execute arbitrary commands without validation. ### MQTT Topics
```
systant/{hostname}/{entity_id}/state # State updates
systant/{hostname}/{entity_id}/set # Commands (for switch/light)
systant/{hostname}/{entity_id}/press # Button presses
systant/{hostname}/availability # Online/offline status
homeassistant/{type}/{hostname}_{id}/config # HA auto-discovery
```
### Key Design Decisions ### Key Design Decisions
@ -51,10 +70,29 @@ Actions are sandboxed and configurable via allowlists in the config file. Securi
## Tech Stack ## Tech Stack
- **Runtime**: Bun (not Node.js) - **Runtime**: Bun (not Node.js)
- **CLI**: yargs - **Config**: TOML (smol-toml)
- **Config**: TOML - **MQTT**: mqtt.js
- **MQTT**: mqtt.js or Bun-native when available - **Packaging**: Nix flake with home-manager module
- **Package**: Nix flake for reproducible builds
### NixOS/Home Manager Integration
```nix
# flake.nix inputs
inputs.systant.url = "git+ssh://...";
# Add overlay for pkgs.systant
nixpkgs.overlays = [ inputs.systant.overlays.default ];
# Import home-manager module
home-manager.sharedModules = [ inputs.systant.homeManagerModules.default ];
# In user config
services.systant = {
enable = true;
settings = { /* TOML as Nix attrset */ };
# or: configFile = ./systant.toml;
};
```
## Bun Conventions ## Bun Conventions
@ -105,10 +143,17 @@ Watch mode: `bun test --watch`
## Commands ## Commands
```bash ```bash
bun run start # Run in development # Development
bun run dist # Build standalone binary bun run index.ts run --config systant.toml
bun test # Run tests
bun test --watch # Watch mode # Build standalone binary
bun build index.ts --compile --outfile systant
# Nix build
nix build .#systant
# Run tests
bun test
``` ```
## Planning Protocol ## Planning Protocol