/** * Site identity for the AstroAgent runtime — the ONLY place the framework reads * who this deployment is. Everything site-specific (name, url, model, agent user, * QA target) is derived here from site.config.json + astroagent.config.json, so * host.mjs and the agent modules stay site-agnostic. Brand *rules* live in the * per-site brand guide (brand/BRAND.md) and the `brand` skill, not here. */ import { readFileSync } from "node:fs"; import { dirname, resolve, join } from "node:path"; import { fileURLToPath } from "node:url"; const REPO = resolve(dirname(fileURLToPath(import.meta.url)), "..", ".."); const readJson = (p) => { try { return JSON.parse(readFileSync(join(REPO, p), "utf8")); } catch { return {}; } }; const sc = readJson("site.config.json"); const aa = readJson("astroagent.config.json"); const url = String(sc.url || aa.url || "https://example.com").replace(/\/+$/, ""); let host = url; try { host = new URL(url).host; } catch {} const agentUser = aa.ai?.agentUser || "astroagent"; export const site = { name: sc.name || "the site", url, host, model: aa.ai?.model || "claude-sonnet-4-6", tools: aa.ai?.tools || "Read Write Edit Glob Grep WebSearch", agentUser, home: `/var/lib/${agentUser}`, author: { name: sc.author?.name || sc.name || "the author", role: sc.author?.jobTitle || "", }, audience: sc.audience || "", qaEmail: `qa@${host}`, // Static route seed for the QA crawler (it also discovers via links + sitemap // + qa-routes.php). Site-derived; overridable via agents.settings.qa.routes. qaRoutes: aa.agents?.settings?.qa?.routes || [ "/", "/about", "/services", "/services/website-design", "/projects", "/blog", "/contact", "/changelog", "/resume", "/faq", ], // Per-project agent roster: which console agents run here + their settings. // Defaults to all four (back-compat) when astroagent.config.json omits it. agents: { enabled: aa.agents?.enabled || ["in-page-console", "project-builder", "web-designer", "qa"], settings: aa.agents?.settings || {}, }, };