// Non-executing organization view. Disabled/missing capabilities carry only a validated name. import { buildRegistry } from '../../organization/src/composition.mjs'; import { declaredSet, bad } from './manifest.mjs'; import { verifiedPlugin } from './pinned.mjs'; import { hasModule } from './loader.mjs'; export {pluginName} from "../../organization/src/vocabulary.mjs"; import {pluginName} from "../../organization/src/vocabulary.mjs"; export function organizationPlugins(dataRoot,settings = {}) { const names=new Set(Object.entries(settings).flatMap(([kind,v])=>(Array.isArray(v)?v:[v]).filter(name=>!hasModule(kind,name)))); const manifests=[],refused=[]; if(dataRoot!==null) for(const name of names){try {const m=verifiedPlugin(dataRoot,name).manifest; if(m.kinds.every(k=>(Array.isArray(settings[k])?settings[k]:[settings[k]]).includes(name)))manifests.push(m); }catch {refused.push(name);}} const registry=buildRegistry({plugins:manifests.map(declaredSet)}); return {registry,manifests,refused,roleTemplates:manifests.flatMap(m=>m.roleTemplates)}; } export function assertPluginCapabilities(role,view) { const check = (cap,registered) => { const name=pluginName(cap);if(!name)return; if(!view.manifests.some(m=>m.name===name))bad('plugin-disabled',name); if(!registered)bad('invalid-request'); }; for(const tool of role.tools ?? [])check(tool,view.registry.tools.includes(tool)); for(const action of [...(role.authority?.withinRole ?? []),...(role.authority?.crossRole ?? [])])check(action,view.registry.actions.includes(action)); const credentials=Array.isArray(role.credentials) ? role.credentials : Object.keys(role.credentials ?? {}).map(service=>({service})); for(const credential of credentials) { const {service,scopes}=credential;check(service,Object.hasOwn(view.registry.services,service)); if(pluginName(service) && scopes!==undefined && (!Array.isArray(scopes) || scopes.some(s=>!view.registry.services[service].scopes.includes(s))))bad('invalid-request'); } }