feat(api): content.load_npc + content-root resolver

This commit is contained in:
2026-07-10 12:08:50 -05:00
parent 55a2ae6f19
commit 69729f7673
2 changed files with 55 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ scenes into play.
"""
import json
import os
from pathlib import Path
@@ -48,3 +49,30 @@ def unresolved_refs(origin: dict, world: dict[str, set[str]]) -> list[str]:
if npc_id not in world["npcs"]:
missing.append(f"npc:{npc_id}")
return missing
def _content_root() -> Path:
"""Locate the authored content root. Honours CONTENT_ROOT, else walks up
from this file for a dir containing world/ — repo-root/content in a local
checkout, /app/content when bundled into the Docker image. Mirrors
canon_log._schema_dir().
"""
env = os.environ.get("CONTENT_ROOT")
if env:
return Path(env)
here = Path(__file__).resolve()
for parent in here.parents:
candidate = parent / "content"
if (candidate / "world").is_dir():
return candidate
raise RuntimeError("content root not found")
def load_npc(npc_id: str) -> dict | None:
"""Load one NPC's authored file (persona + knowledge + capabilities), or
None if no file resolves. Server-only fields never travel to the client."""
path = _content_root() / "world" / "npcs" / f"{npc_id}.json"
if not path.is_file():
return None
with open(path) as f:
return json.load(f)