Update pnpm workspace and lockfile for new dependencies:
- class-validator and class-transformer for DTO validation
- Updated workspace configuration for host-status-monitor package
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement mTLS client authentication for host agents:
- Add mTLS configuration (cert, key, ca paths)
- Service discovery for service-registry integration
- Deployment examples and documentation
- Unit tests for type exports and service discovery
Agent now authenticates to backend using client certificates,
providing secure agent→server communication. Falls back to API Key
if mTLS fails.
Deployment files:
- env.example: Environment variable template
- host-status-monitor.service.example: systemd service template
- deploy.sh: Automated deployment script
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update /api/metrics/report endpoint:
- Replace MtlsGuard + ApiKeyGuard with FlexibleAuthGuard
- Configure @AuthMethods('mtls', 'apiKey') for backward compatibility
- Maintains same auth behavior with more flexible implementation
FlexibleAuthGuard provides same mTLS + API Key authentication with
priority-based fallback and better debugging.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Configure NestJS to use JsonLoggerService for structured logging:
- JSON format for SIEM integration
- Consistent log format across application
- Production-ready logging infrastructure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update auth module to export new guards:
- FlexibleAuthGuard (multi-method authentication)
- VpnGuard (IP validation)
- AuthMethods decorator (per-endpoint configuration)
Makes guards available for dependency injection in controllers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply defense-in-depth security to all sensitive endpoints:
HostsController:
- Add FlexibleAuthGuard with @AuthMethods('jwt')
- Add AuditLoggingInterceptor for request tracking
StatusController:
- Add FlexibleAuthGuard with @AuthMethods('jwt')
- Add AuditLoggingInterceptor for request tracking
- Apply DTOs for input validation (ContainerNameDto, LogsQueryDto, EventsQueryDto)
All /api/hosts/* and /api/health/* endpoints now require JWT
authentication and log all access attempts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reconciliation now runs entirely from the dev machine, targeting remote
hosts via SSH instead of syncing scripts and running remotely. This fixes
status-dashboard deployment which requires local build artifacts.
Changes:
- reconcile_host_remote() runs locally with ssh_prefix for all commands
- service.sh handles drift:* and error:* status conventions
- status-dashboard service syncs dist/ via rsync, manages PM2 via SSH
- nginx-config-sync extended to handle sites-available/ directory
- deploy-status-dashboard.sh and rectify-deploy.sh delegate to reconciliation
- Deprecated 7-domain-routing.conf (uses undefined log format)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents the unified pre-push deployment system:
- Component detection and triggers
- Version incrementing behavior
- Independent deployment (dashboards may have different versions)
- VPS configuration and paths
- Troubleshooting guide
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Test the new unified deploy pipeline that increments version
and deploys both status-dashboard and service-registry.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pre-push hook now:
- Detects changes in both status-dashboard and service-registry
- Increments VERSION.json builds counter before deploy
- Syncs shared packages (@packages/@utils/vite-version-plugin, @packages/@ui/ui-theme)
- Builds and deploys both dashboards when affected
Triggers:
- Direct changes to features/status-dashboard/ or infrastructure/service-registry/
- Changes to shared packages (@packages/@ui/*, @packages/@core/*, vite-version-plugin)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Both status-dashboard and service-registry now depend on
@lilith/vite-version-plugin. Update deploy scripts to sync
this package to releases/ before building.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace inline version injection with the reusable vite-version-plugin
package for consistent version banners across all dashboards.
Changes:
- Remove custom getMonorepoVersion() and buildInfoPlugin()
- Use versionPlugin from @lilith/vite-version-plugin
- Use logVersionBanner for styled console output
- Add tsconfig paths for TypeScript resolution
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
NestJS ServeStatic serves from apps/registry/dist/apps/dashboard/dist/
(relative to __dirname in the built main.js), not apps/dashboard/dist/.
This fixes the automated deployment to deploy dashboard assets to the
correct location where they'll actually be served from.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The config() hook runs before configResolved(), so version info must be
calculated there for the define values to be properly injected at build time.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create @lilith/vite-version-plugin package that reads VERSION.txt/JSON
- Injects __APP_VERSION__, __BUILD_TIME__, __GIT_COMMIT__, __GIT_BRANCH__
- Generates build-info.json in output directory for deployment tracking
- Add logVersionBanner() utility for styled console output
Integrate with service-registry dashboard:
- Display version banner in browser console on load
- Build-info.json available at /build-info.json endpoint
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add silent refresh mode to useServices hook that shows "Refreshing..."
indicator instead of replacing the entire UI with loading state
- WebSocket events (health updates, registrations) now use silentRefetch
to avoid jarring UI flash when data updates in background
- Calculate uptime from registeredAt when service doesn't report uptime
- Add spinning refresh indicator in header during background updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Services now maintain consistent positions when health status updates arrive
via WebSocket. Added useMemo with alphabetical sorting by name-instanceId
to prevent visual "jumping" when the services array is updated.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use hostname as fallback for host field in registry controller
(fixes services showing as "localhost" when only hostname is provided)
- Use ipAddress for health checks instead of host
(fixes health check failures when hostname DNS doesn't resolve locally)
- Add fixed port config to status-dashboard registry integration
(prevents unnecessary port allocation requests)
- Fix healthEndpoint path to /api/health/status
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Registry improvements:
- Add automatic stale service cleanup (removes services not seen for 120s
or unhealthy for 300s)
- Add hostname/ipAddress config options to registry-integration
- Support SERVICE_HOSTNAME and SERVICE_IP environment variables
- Add dependency endpoint change detection for dependent service restarts
Status dashboard:
- Pass hostname from SERVICE_HOSTNAME env var or os.hostname()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add automatic service health monitoring with restart capability:
- Cross-platform health check script (Linux systemd + macOS launchd)
- Detects hung services by checking for recent success vs error logs
- Auto-restarts service after 3+ consecutive failures with no successes
- Runs every 2 minutes via systemd timer or launchd StartInterval
Deployment updates:
- deploy.sh now installs health check on all platforms
- Removed VPN proxy from plum.env (no WireGuard on macOS)
Files added:
- host-status-monitor-healthcheck (cross-platform bash script)
- host-status-monitor-healthcheck.service (systemd oneshot)
- host-status-monitor-healthcheck.timer (2-minute interval)
- com.lilith.host-status-monitor-healthcheck.plist (macOS launchd)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- .claude now symlinked from tooling/claude/dot-claude
- CLAUDE.md symlinked from tooling/claude/CLAUDE.md
- Remove deprecated @packages/@providers/theme-provider
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- host-inventory: Fleet management with YAML config loader
- registry-integration: NestJS module for service registry
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add host-status-monitor with macOS/Linux support
- Add vitest + playwright testing setup
- Add docker-compose for local development
- Add metrics persistence service
- Improve deploy scripts and env configs
- Update frontend components and auth
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add @lilith/design-tokens alias to vite.config.ts and tsconfig.json
to fix theme.spacing undefined error
- Add INTERNAL_NETWORK env var bypass to ApiKeyGuard and AdminGuard
for VPN-only deployments without API key requirements
- Add INTERNAL_NETWORK CORS bypass to WebSocket gateways (events, routes)
to allow all origins on internal networks
- Fix useWebSocket hook to prevent reconnection loops by using refs
for callbacks and retry count, with empty dependency array
- Relax helmet CSP headers when INTERNAL_NETWORK=true
- Rename @apps/registry to @lilith/registry for consistency
Deployed to vpn.1984.nasty.sh with Let's Encrypt SSL at
https://services.nasty.sh/ (VPN-only access)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace static JSON config with runtime dependency discovery by
grepping package.json files. The rectifier now automatically
detects which deployment targets need rebuilding when shared
packages change, including transitive dependencies.
Changes:
- Add lib/dependency-graph.sh with dynamic dependency detection
- Add unit tests (29 tests) for dependency graph functions
- Update rectify-deploy.sh to use dynamic detection
- Remove need for manual dependency configuration
How it works:
1. Extract package name from changed file path
2. Grep package.json files to find dependents
3. Map dependents to deployment targets
4. Handle transitive deps (ui-utils -> ui-primitives -> targets)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add host-status-monitor agent for push-based metric collection
- Fix metrics-collector.ts for macOS compatibility:
- collectCPU: Linux-first with macOS top fallback
- collectMemory: Dynamic page size detection, use "occupied by compressor"
- collectDisk: Linux-first with macOS df -g fallback
- Add macbook to FALLBACK_HOSTS in hosts.config.ts
- Delete unused multi-host-monitor.service.ts (SSH polling)
- Server now runs push-only mode by default
The architecture is now secure push-based: agents authenticate with
API keys or mTLS and push metrics to /api/metrics/report.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a proper "rectifier" pattern that detects changed components
and deploys them automatically when pushing to main.
Changes:
- Add rectify-deploy.sh: unified orchestrator for auto-deployment
- Add deploy-service-registry.sh: service-registry deployment script
- Update detect-changes.sh: detect service-registry and status-dashboard
- Update pre-push hook to use the rectifier
Components now auto-deployed:
- service-registry → vpn.1984.nasty.sh
- status-dashboard → 0.1984.nasty.sh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The dashboard was crashing with "TypeError: can't access property 'sm',
e.theme.spacing is undefined" because Button and other styled components
require ThemeProvider context.
Changes:
- Add ThemeProvider wrapper in App.tsx with cyberpunk theme
- Add @lilith/ui-theme dependency
- Add vite aliases and tsconfig paths for @lilith/* packages
- Add comprehensive E2E tests covering all 7 routes
- E2E tests now detect console errors and theme-related TypeErrors
The new E2E test suite would catch this class of error before deployment.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- status.atlilith.com now sources version from VERSION.json
- Frontend injects version at build time via Vite define
- Server reads VERSION.json instead of package.json
- release-deploy.sh increments builds before sync to releases
- version-bump.sh updated for <major>.<merges>.<builds> format
- Starting version: 0.0.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Single version for entire monorepo: <major>.<merges>.<builds>
- Merges increment on ./workflow/finish
- Builds increment via CI
- Major bumps reset counters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The deploy script was deploying to /opt/health-monitor/dist/ but the
server runs from /opt/health-monitor/backend/. Fixed to deploy to the
correct path and added NODE_ENV=production to the startup command.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates pre-push hook to always run pnpm install before building
to ensure new dependencies are installed in releases/.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The hosts.config.ts uses the yaml package to parse YAML inventory files.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed heredoc from quoted ('EOF') to unquoted (EOF) to enable
shell variable expansion for BACKEND_VPS_IP and BACKEND_API_PORT.
Properly escaped all nginx variables with backslash.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removes unused https import from main.ts to fix TypeScript build error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>