/** * Plugin contribution shape — the manifest entry a plugin author writes to * declare that they want to be mounted at a given extension point. * * Mount points are open-ended strings the host page declares * (`vibe.detailTab`, `agent.detailTab`, `target.detailTab`, * `dashboard.widget`, …). Adding a new mount point does NOT require an * SDK release: the host page consumes the matching contributions and * interprets `meta` however it needs. */ export type PluginRuntime = 'iframe' | 'in-process'; export interface PluginCapabilities { /** * REST path prefixes the plugin is allowed to hit via the iframe token. * Globs (`*`) are honoured by `request-security` on the agent. * * Example: `["/api/profiles/*\/my-plugin/*"]` */ restPaths: string[]; /** WebSocket topics this plugin subscribes to via the host relay. */ wsTopics: string[]; /** * Host RPC methods the plugin may call (e.g. `navigate`, `toast`, * `storage.get`). The host enforces this allow-list before invocation; * mismatches return a structured error rather than executing. */ rpcMethods: string[]; } export interface ContributionGate { /** Vibe-level feature catalog id (`isFeatureEnabled(feature)`). */ feature?: string; /** Platform-level GrowthBook flag (`isPlatformTabEnabled(flag)`). */ platformFlag?: string; /** Hide the contribution when no agent is attached to the surface. */ requiresAgent?: boolean; } export interface PluginContribution { /** Open-ended mount point id. The host page knows how to read it. */ mountPoint: string; /** Unique within (pluginKey, mountPoint). */ id: string; title: string; /** Lucide icon name. Host resolves to a component; SDK stays icon-set agnostic. */ icon?: string; /** Lower = earlier in the strip / grid. */ order?: number; /** * Which runtimes this contribution supports. The host picks the first * entry that matches its preference and is available; warns and skips * the contribution when nothing matches. */ runtimes: PluginRuntime[]; capabilities: PluginCapabilities; gate?: ContributionGate; /** Mount-point-specific extras (e.g. `defaultSize` for dashboard widgets). */ meta?: Record; } export interface PluginManifest { /** Globally unique. Convention: npm-package-style (`vibe-plugin-ui-git`). */ id: string; /** Human-readable. */ name?: string; /** CalVer version of the plugin package itself. */ version?: string; description?: string; contributions: PluginContribution[]; } /** * `defineUiPlugin` is a typed identity helper — it lets the plugin author * declare the manifest + render function once and have the resulting * object accepted by both adapters without `as const` ceremony. * * The `render` thunk runs *inside* the chosen adapter, after the host * handshake has populated `VibeHostContext`. The hooks in `./react` are * what consumers actually use; this signature is intentionally untyped * for React to keep the protocol module DOM-free. */ export interface UiPluginDefinition { manifest: PluginManifest; render: () => TRender; } export declare function defineUiPlugin(plugin: UiPluginDefinition): UiPluginDefinition; //# sourceMappingURL=contribution.d.ts.map