/** * Shared, format-agnostic helpers used by the plugin format adapters. * * Kept deliberately free of any runtime dependency on `../manifest.js` (it only * imports *types* from there) so the adapter registry can be wired without a * module cycle: `manifest.ts → formats/index.ts → formats/.ts → * shared.ts`, with the back-reference to manifest types erased at compile time. */ import type { PluginCanvasExtension, PluginHooksConfig } from "../manifest.js"; import type { AuthoredHook, WorkspaceLayout } from "./types.js"; /** Raw manifest shape accepted by the `plugin.json`-style formats (agents/claude/copilot). */ export interface RawManifest { name?: string; version?: string; description?: string; author?: string | { name?: string; }; /** Optional capability-dir override(s): a path (or list of paths) relative to the plugin root, e.g. `"skills": "./skills/"`. */ skills?: unknown; commands?: unknown; agents?: unknown; themes?: unknown; hooks?: PluginHooksConfig | { hooks?: PluginHooksConfig; }; /** Inline server map, or a path (Claude Code form, e.g. `"./.mcp.json"`) relative to the plugin root. */ mcpServers?: Record | string; /** Native-only. */ providers?: unknown; /** * Copilot: canvas-extension directory (a path, or list of paths, relative to * the plugin root — e.g. `"extensions": "extensions"`). The Agent Plugins spec * gives the same key a second, unrelated meaning: a map of vendor metadata * namespaces (`{ "com.github.copilot": { logo } }`). Both readings are handled * — see {@link detectCanvasExtensions} — and the map form is preserved * verbatim through `unknownFields`. */ extensions?: unknown; /** Copilot: LSP config path or inline definitions. Parsed for preservation only. */ lspServers?: unknown; /** Any key the adapter does not model. */ [key: string]: unknown; } /** Manifest keys not modelled here, preserved verbatim so a re-emit cannot drop them. */ export declare function unknownManifestFields(raw: RawManifest): Record | undefined; /** * Vendor content namespace directory. The Agent Plugins layout both vendors are * converging on keeps portable capabilities at the plugin root (`skills/`) and * puts vendor-specific ones under a reverse-DNS directory, so Copilot's agents * and canvas extensions ship as `com.github.copilot//`. * `github/awesome-copilot` publishes its whole catalog this way. */ export declare const COPILOT_CONTENT_DIR = "com.github.copilot"; /** * Canvas extensions a plugin ships (see `docs/canvas-extensions-design.md` §4.3). * * Discovery keys off `/extension.mjs` and nothing else, exactly as * `core/canvas/discovery.ts` does for the workspace and user search roots — the * entry file is the whole contract, so a plugin's canvases are found by the same * rule as everyone else's. * * A plugin whose *root* carries `extension.mjs` is itself one canvas extension, * which is how a single-canvas repository is laid out; its id is the plugin id, * since there is no directory name below the root to take one from. */ export declare function detectCanvasExtensions(root: string, pluginId: string, override: unknown): PluginCanvasExtension[] | undefined; /** Which unsupported surfaces are present under `root`. */ export declare function detectUnsupportedSurfaces(root: string): string[] | undefined; export declare function readJson(file: string): T | null; export declare function dirIfExists(root: string, name: string): string | undefined; /** * Resolve a capability directory: an explicit manifest override — a path (or * list of paths, first existing wins) relative to the plugin root, e.g. * `"skills": "./skills/"` — beats the conventional directory. */ export declare function resolveCapabilityDir(root: string, override: unknown, conventional: string): string | undefined; /** Coerce an author field (string or `{ name }`) to a plain string. */ export declare function parseAuthor(author: RawManifest["author"]): string | undefined; /** Accept either `{ hooks: {...} }` or a bare event map, falling back to `hooks/hooks.json`. */ export declare function normalizeHooks(raw: RawManifest["hooks"], root: string): PluginHooksConfig | undefined; /** * Resolve inline `mcpServers`, a manifest-supplied file path, or a `.mcp.json` * file at `root`. * * `raw` may be: * - a string path (Claude Code form: `"mcpServers": "./.mcp.json"`), resolved * relative to the plugin root and read as a server file; * - an inline server map (returned as-is); * - undefined, falling back to `/`. * * Server files use `{ mcpServers }` (Claude/native) or `{ servers }` (Code/Copilot); * both keys are accepted. */ export declare function normalizeMcp(raw: Record | string | undefined, root: string, mcpFileName?: string): Record | undefined; /** A markdown capability file: frontmatter block + body. */ export declare function emitMarkdown(fields: Record, body: string): string; /** Pretty-print a JSON manifest with a trailing newline (matches repo convention). */ export declare function emitJson(value: unknown): string; /** Convert authored hooks into the on-disk `hooks.json` event-map shape shared by all formats. */ export declare function authoredHooksToConfig(hooks: AuthoredHook[]): Record; /** Slug-safe filename component (no path separators, conservative charset). */ export declare function slug(name: string): string; /** * Render a comma-separated tool allowlist (Claude Code convention, e.g. * "read, SearchCodebase") as a YAML flow sequence (`['read', 'SearchCodebase']`) for formats whose * frontmatter takes tools as a list (Copilot custom agents / prompt files). */ export declare function toolsYamlList(tools: string | undefined): string | undefined; /** * The workspace layout shared by the `.agents/` and `.claude/` conventions: * `/skills//SKILL.md`, `/agents/.md`, * `/commands/.md`. Copilot's differs and lives in its adapter. */ export declare function claudeStyleWorkspace(root: string): WorkspaceLayout; /** The manifest keys the adapters model, as a sorted list. Input to the drift check (§2.2). */ export declare function modelledManifestKeys(): string[]; /** * Surfaces we know about and deliberately do not load, as the **relative paths** * they actually occupy rather than their display labels. * * The distinction bit once already: the labels are written for humans * (`"monitors/"`), the vendor reference writes the real path * (`monitors/monitors.json`), and a drift check comparing the two reported a * known surface as a new finding. */ export declare function knownUnsupportedSurfaces(): string[]; //# sourceMappingURL=shared.d.ts.map