# nasctl — Agent Guidance ## Build ```bash make build # frontend (Vite builds to internal/web/dist) + Go binary → bin/nasctl make build-go # Go only (requires internal/web/dist to exist) make run # dev run: uses .data/, NASCTL_EXEC_SYSTEM=false ``` The Vite config (`web/vite.config.ts`) outputs directly to `internal/web/dist` for Go embedding. Do not change `outDir`. ## Testing ```bash make test # go test ./... ``` No separate frontend test command; no lint/typecheck Makefile targets. ## Project Structure - `cmd/nasctl/main.go` — entrypoint, CLI flags - `internal/web/` — HTTP server, handlers, embed.go (frontend assets) - `internal/db/` — SQLite models and queries - `internal/modules/samba/`, `nfs/`, `users/` — config generators and system executors - `internal/engine/apply.go` — dirty→apply orchestration - `web/` — React frontend source (Vite + Tailwind + TypeScript) ## Key Runtime Behaviors - Changes (shares, exports, users) are staged in SQLite and marked **dirty**; they require `POST /api/apply` to take effect. - `NASCTL_EXEC_SYSTEM=false` (default in dev via `make run`) prevents real system changes: no service reloads, no useradd, no smbpasswd. - In production, set `NASCTL_EXEC_SYSTEM=true` and ensure `NASCTL_ALLOWED_ROOTS` restricts share/export paths. ## Environment Variables | Variable | Dev default | Production default | |---|---|---| | `NASCTL_ADDR` | `:8080` | `:8080` | | `NASCTL_DB` | `./.data/nasctl.db` | `/var/lib/nasctl/nasctl.db` | | `NASCTL_SMB_CONF` | `./.data/smb.conf` | `/etc/samba/smb.conf` | | `NASCTL_EXPORTS` | `./.data/exports` | `/etc/exports` | | `NASCTL_EXEC_SYSTEM` | `false` | `true` | | `NASCTL_ALLOWED_ROOTS` | (empty) | (empty = any absolute path) | ## Frontend Dev ```bash cd web && npm run dev # Vite on :5173, proxies /api to :8080 ``` Requires `web/node_modules` (run `cd web && npm install` first).