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

@@ -12,9 +12,9 @@ from castle_core.registry import DeployedComponent, NodeConfig, NodeRegistry
@pytest.fixture(autouse=True)
def _isolate_static_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
"""Use a temp dir for STATIC_DIR so tests don't depend on real ~/.castle."""
monkeypatch.setattr(caddyfile_mod, "STATIC_DIR", tmp_path / "static")
def _isolate_content_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
"""Use a temp dir for CONTENT_DIR so tests don't depend on real ~/.castle."""
monkeypatch.setattr(caddyfile_mod, "CONTENT_DIR", tmp_path / "content")
def _make_registry(

View File

@@ -49,11 +49,11 @@ class TestUnitFromDeployed:
deployed = DeployedComponent(
runner="python",
run_cmd=["/home/user/.local/bin/uv", "run", "test-svc"],
env={"TEST_SVC_DATA_DIR": "/data/castle/test-svc"},
env={"TEST_SVC_DATA_DIR": "/home/user/.castle/data/test-svc"},
description="Test service",
)
unit = generate_unit_from_deployed("test-svc", deployed)
assert "Environment=TEST_SVC_DATA_DIR=/data/castle/test-svc" in unit
assert "Environment=TEST_SVC_DATA_DIR=/home/user/.castle/data/test-svc" in unit
def test_contains_restart_policy(self) -> None:
"""Unit file has restart configuration."""
@@ -82,14 +82,14 @@ class TestUnitFromDeployed:
deployed = DeployedComponent(
runner="python",
run_cmd=["/home/user/.local/bin/uv", "run", "my-svc"],
env={"MY_SVC_PORT": "9001", "MY_SVC_DATA_DIR": "/data/castle/my-svc"},
env={"MY_SVC_PORT": "9001", "MY_SVC_DATA_DIR": "/home/user/.castle/data/my-svc"},
description="My service",
)
unit = generate_unit_from_deployed("my-svc", deployed)
assert "Description=Castle: My service" in unit
assert "ExecStart=/home/user/.local/bin/uv run my-svc" in unit
assert "Environment=MY_SVC_PORT=9001" in unit
assert "Environment=MY_SVC_DATA_DIR=/data/castle/my-svc" in unit
assert "Environment=MY_SVC_DATA_DIR=/home/user/.castle/data/my-svc" in unit
assert "WorkingDirectory" not in unit
assert "Restart=on-failure" in unit
@@ -111,7 +111,7 @@ class TestUnitFromDeployed:
deployed = DeployedComponent(
runner="python",
run_cmd=["/home/user/.local/bin/uv", "run", "my-svc"],
env={"DATA_DIR": "/data/castle/my-svc"},
env={"DATA_DIR": "/home/user/.castle/data/my-svc"},
description="Test",
)
unit = generate_unit_from_deployed("my-svc", deployed)