/** * --describe handler: prints the scope definition as JSON to stdout. * * Used by `np scope publish` to read the plugin's self-description. * Strips handler functions — outputs only schemas and metadata. */ import { getActionDefaults } from "./actions"; import { resolveAgentConfig, schemaWithAssetType, type ScopeDefinition, } from "./index"; export function handleDescribe(definition: ScopeDefinition): void { const actionSpecs: Record = {}; for (const [slug, action] of Object.entries(definition.actions)) { const defaults = getActionDefaults(slug); actionSpecs[slug] = { name: action.name ?? defaults.name, type: action.type ?? defaults.type, retryable: action.retryable ?? defaults.retryable, lifecycle: defaults.lifecycle, input: action.input, output: action.output, }; } const output = { name: definition.name, version: definition.version, description: definition.description, category: definition.category, provider: definition.provider, subCategory: definition.subCategory, // The declared assetType, surfaced both ways: as a top-level manifest key // for consumers that read it directly, and injected into the schema — the // np CLI registers the spec from this schema and defaults asset_type to // docker-image when the manifest omits it, silently overriding defineScope. assetType: definition.assetType ?? "docker-image", schema: schemaWithAssetType(definition), actions: actionSpecs, uiSchema: definition.uiSchema, // Routing config with defaults resolved from the name, so the CLI applies // exactly what the scope declares instead of re-deriving conventions. agent: resolveAgentConfig(definition), }; const cleaned = JSON.parse(JSON.stringify(output)); console.log(JSON.stringify(cleaned, null, 2)); }