The Caddyfile generator now emits static-frontend routes that root directly at
<source>/<build.outputs[0]> (e.g. /data/repos/castle/app/dist) instead of a copy
under ~/.castle/artifacts/content. Removes _copy_app_static and the central
content-dir staging entirely; rebuilds are live without a copy step.
- caddyfile.py: manifest-driven static routes (castle-app at /, others at /<name>)
- ReactViteHandler.install just builds in place (no copy); uninstall is a no-op
- is_active(static frontend) = repo dist exists
- test isolation updated for the generator's config use
Dashboard + power-graph-app verified serving from repo dist; 168 tests pass.
Move all instance state into ~/.castle/ with clear separation:
- code/ — user project source (was components/)
- artifacts/ — generated specs, built content (was generated/, static/)
- data/ — service runtime data (was /data/castle/)
- secrets/ — credentials
castle.yaml moves to ~/.castle/castle.yaml as the canonical location.
Source paths use repo: prefix for git repo programs (castle-api, app)
and relative paths for user projects (code/central-context).
Add idempotent install.sh for bootstrapping infrastructure (Docker,
Caddy, MQTT, Postgres, Neo4j) with interactive service detection.
Remove components/ from repo (now in ~/.castle/code/), deinit
submodules, remove .gitmodules.