UNPKG

@blundergoat/goat-flow

Version:

AI coding agent harness and local dashboard for Claude Code, OpenAI Codex, Google Antigravity, and GitHub Copilot - setup audits, guardrails, structured skills, deny hooks, and persistent learning loops.

134 lines 4.94 kB
/** * Manifest-backed agent registry. * * `workflow/manifest.json` is the single writable authority for framework * support metadata. This module exposes the typed runtime facade consumed by * detection, prompts, and dashboard surfaces. */ import { loadManifest } from "../manifest/manifest.js"; import { KNOWN_AGENT_IDS, } from "../types.js"; /** Re-export the canonical runtime authority for agent identity. */ export { KNOWN_AGENT_IDS } from "../types.js"; /** Trim the trailing slash from a directory path. */ function trimDir(path) { if (!path) return null; return path.replace(/\/$/, ""); } /** Check whether a value is an agent ID. */ function isAgentId(value) { return KNOWN_AGENT_IDS.includes(value); } /** Convert manifest deny config into the runtime shape. */ function toDenyMechanism(deny) { if (deny.type === "settings-deny") { return { type: "settings-deny", path: deny.path }; } if (deny.type === "deny-script") { return { type: "deny-script", path: deny.path }; } return { type: "both", settingsPath: deny.settings_path, scriptPath: deny.script_path, }; } /** Require a manifest directory field to be present and non-empty. */ function requireDir(id, field, path) { const trimmed = trimDir(path); if (!trimmed) { throw new Error(`workflow/manifest.json agent "${id}" is missing ${field}`); } return trimmed; } /** Require a manifest capability string to be present and non-empty. */ function requireCapabilityString(id, field, value) { const trimmed = value?.trim(); if (!trimmed) { throw new Error(`workflow/manifest.json agent "${id}" is missing capabilities.${field}`); } return trimmed; } /** Convert a manifest agent entry into the runtime profile. */ function toRuntimeProfile(id, agent) { const capabilities = agent.capabilities; return { id, name: agent.name, instructionFile: agent.instruction_file, terminalBinary: requireCapabilityString(id, "terminal_binary", capabilities.terminal_binary), setupSurfaces: [...capabilities.setup_surfaces], promptInvocationStyle: capabilities.prompt_invocation_style, skillSource: capabilities.skill_source, supportsPostTurnHook: agent.hook_events?.post_turn != null, settingsFile: agent.settings ?? null, hookConfigFile: agent.hook_config_file ?? agent.settings ?? null, skillsDir: requireDir(id, "skills_dir", agent.skills_dir), hooksDir: trimDir(agent.hooks_dir), denyMechanism: agent.deny_mechanism ? toDenyMechanism(agent.deny_mechanism) : null, denyHookFile: agent.deny_hook ?? null, localPattern: agent.local_pattern, hookEvents: agent.hook_events ? { preTool: agent.hook_events.pre_tool, postTurn: agent.hook_events.post_turn ?? null, } : null, }; } /** * Return the manifest-backed runtime profile for one agent id. * Throws when the manifest omits a supported runtime id because callers rely on a complete registry. * * @param id - supported agent id to resolve * @returns runtime profile derived from workflow/manifest.json */ export function getAgentProfile(id) { const agents = loadManifest().agents; const manifestAgent = agents[id]; if (!manifestAgent) { throw new Error(`workflow/manifest.json is missing agent "${id}"`); } return toRuntimeProfile(id, manifestAgent); } /** Return manifest-backed agent entries that match the supported runtime ids. */ function getKnownManifestAgents(agents) { return Object.entries(agents).filter((entry) => isKnownAgentId(entry[0], agents)); } /** * Return the manifest-backed runtime profile record keyed by agent id. * * @returns all supported runtime profiles as an id-keyed map */ export function getAgentProfileMap() { const agents = loadManifest().agents; return Object.fromEntries(getKnownManifestAgents(agents).map(([id, agent]) => [ id, toRuntimeProfile(id, agent), ])); } /** * Return all known manifest-backed runtime profiles in canonical order. * * @returns supported runtime profiles in manifest order */ export function getAgentProfiles() { const agents = loadManifest().agents; return getKnownManifestAgents(agents).map(([id, agent]) => toRuntimeProfile(id, agent)); } /** * Return the manifest-backed supported agent ids. * * @returns supported agent ids in manifest order */ export function getKnownAgentIds() { const agents = loadManifest().agents; return getKnownManifestAgents(agents).map(([id]) => id); } /** Type guard for manifest-backed agent ids. */ function isKnownAgentId(value, agents = loadManifest().agents) { return (isAgentId(value) && Object.prototype.hasOwnProperty.call(agents, value)); } //# sourceMappingURL=registry.js.map