refactor: Restructure ~/.castle/ as the instance directory

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.
This commit is contained in:
2026-03-09 22:03:37 -07:00
parent b7628c590b
commit 8be129259c
86 changed files with 1222 additions and 13989 deletions

View File

@@ -9,7 +9,7 @@ import tomllib
from dataclasses import dataclass
from pathlib import Path
from castle_core.config import STATIC_DIR
from castle_core.config import CONTENT_DIR
from castle_core.manifest import ProgramSpec
DEV_ACTIONS = ["build", "test", "lint", "type-check", "check"]
@@ -214,19 +214,19 @@ class ReactViteHandler(StackHandler):
for output_dir in outputs:
src_path = src / output_dir
if src_path.exists():
dest = STATIC_DIR / name
dest = CONTENT_DIR / name
if dest.exists():
shutil.rmtree(dest)
shutil.copytree(src_path, dest)
return ActionResult(
component=name, action="install", status="ok",
output=f"Built and deployed to {STATIC_DIR / name}",
output=f"Built and deployed to {CONTENT_DIR / name}",
)
async def uninstall(self, name: str, comp: ProgramSpec, root: Path) -> ActionResult:
"""Remove static assets from ~/.castle/static/{name}/."""
dest = STATIC_DIR / name
dest = CONTENT_DIR / name
if dest.exists():
shutil.rmtree(dest)
return ActionResult(