import { EntryOwnerRef, ToolEntry, ToolRecord, ToolRegistryInterface, ToolType } from '@frontmcp/sdk'; import { ToolChangeEvent } from './tool.events'; import ProviderRegistry from '../provider/provider.registry'; import { RegistryAbstract, RegistryBuildMapResult } from '../regsitry'; import { ToolInstance } from './tool.instance'; import { ExportNameOptions } from "./tool.types"; export default class ToolRegistry extends RegistryAbstract implements ToolRegistryInterface { /** Who owns this registry (used for provenance). Optional. */ owner: EntryOwnerRef; /** Tools truly owned/constructed by THIS registry (with lineage applied) */ private localRows; /** Adopted tool rows from each child registry (references to the same instances) */ private adopted; /** Children registries that we track */ private children; private byQualifiedId; private byName; private byOwnerAndName; private byProviderAndName; private byOwner; private version; private emitter; constructor(providers: ProviderRegistry, list: ToolType[], owner: EntryOwnerRef); protected buildMap(list: ToolType[]): RegistryBuildMapResult; protected buildGraph(): void; protected initialize(): Promise; /** * Adopt tools from a child registry. Parent runs after children are ready. * We *reference* the child's tool instances; no duplicates are created. * * IMPORTANT: * - Child rows already include the child's own lineage (e.g., adapter:openapi). * - Here we only prepend the **parent's** owner, to avoid double-prefixing the child. */ adoptFromChild(child: ToolRegistry, _childOwner: EntryOwnerRef): void; getTools(includeHidden?: boolean): ToolEntry[]; getInlineTools(): ToolEntry[]; /** Internal snapshot of effective indexed rows (locals + adopted). */ private listAllIndexed; private reindex; /** List all instances (locals + adopted). */ listAllInstances(): readonly ToolInstance[]; /** List instances by owner path (e.g. "app:Portal/plugin:Okta") */ listByOwner(ownerPath: string): readonly ToolInstance[]; /** * Produce unique, MCP-valid exported names. * - Base (standardized) = metadata.name cased (snake/camel/kebab/dot) * - If conflicting: * - Locals keep bare base (unless >1 locals conflict → they get owner prefixes) * - Children with same base get prefixed by providerId (or owner path) */ exportResolvedNames(opts?: ExportNameOptions): Array<{ name: string; instance: ToolInstance; }>; /** Lookup by the exported (resolved) name. */ getExported(name: string, opts?: ExportNameOptions): ToolInstance | undefined; subscribe(opts: { immediate?: boolean; filter?: (i: ToolInstance) => boolean; }, cb: (evt: ToolChangeEvent) => void): () => void; private bump; /** Build an IndexedTool row */ private makeRow; /** Clone a child row and prepend lineage (with adjacent de-dup to avoid double prefixes). */ private relineage; /** Best-effort provider id used for prefixing (inspects class metadata if present). */ private providerIdOf; /** True if this registry (or adopted children) has any tools. */ hasAny(): boolean; }