UNPKG

@extenshi/mcp

Version:

Extenshi MCP server — bring the extension catalog (search, security, market research) and pre-publish scanning into your AI tools

111 lines • 6.44 kB
/** * Extension templates — the "what kind of extension is this?" taxonomy. * * A template is not a folder of files to copy. It is a small set of claims * about the extension's shape: which manifest components it cannot work * without, which permissions those components force, and which files the * scaffold has to write so the manifest does not point at something that isn't * there. Everything downstream — the picker in the manifest generator, the * locked checkboxes, the scaffolded file set, and (next phase) the MCP tool * that hands this catalog to a developer's own agent — reads THIS module. * * It lives in shared-types rather than in dojo because the readers span * packages: the website, catalog-bff (answering a developer's own agent), and * the published `@extenshi/mcp` package, whose tool tells an agent what kinds of * extension exist and what each costs in permissions. All three must give the * same answer. * * SELF-CONTAINED ON PURPOSE — no imports, so it can be copied verbatim into * `@extenshi/mcp`, which cannot depend on unpublished workspace packages (same * constraint and same solution as welcome-agent-brief.ts). * * SINGLE SOURCE, TWO COPIES, byte-identical: * shared-types/extension-templates.ts ← canonical * tools/extenshi-mcp/src/extension-templates.ts ← copy, pinned by a test * Edit the canonical file and copy it over; the sync test in the MCP package * fails on any divergence inside the monorepo and skips in the npm tarball. * * Templates COMBINE. A side panel with a content script is one extension with * two capabilities, not a fifth template — the picker is multi-select and every * helper here takes a list and unions the result. That is why requirements are * expressed as components + permissions rather than as whole manifests. */ export declare const EXTENSION_TEMPLATE_IDS: readonly ["popup", "sidepanel", "content", "overlay"]; export type ExtensionTemplateId = (typeof EXTENSION_TEMPLATE_IDS)[number]; /** * The template applied when a project has never picked one. * * `popup` is deliberately the same shape the scaffold produced before templates * existed, so an old project regenerates byte-for-byte what it did yesterday. */ export declare const DEFAULT_EXTENSION_TEMPLATE: ExtensionTemplateId; /** * Manifest components a template can require. * * These are the things the UI can lock: a side-panel extension whose * `side_panel` key is turned off is not a side-panel extension, it is a broken * one. Each maps to a group of fields in the manifest draft. */ export declare const EXTENSION_TEMPLATE_COMPONENTS: readonly ["action", "sidePanel", "contentScript"]; export type ExtensionTemplateComponent = (typeof EXTENSION_TEMPLATE_COMPONENTS)[number]; /** Where scaffolded source goes, so the manifest and the file writer agree. */ export declare const EXTENSION_TEMPLATE_SOURCE_DIR = "src"; /** * The background service worker every template gets, template or not. * * It is not part of any one template because it carries the integration the * whole product is built around: `setUninstallURL` must be registered at * startup, and a template that skipped the background script would silently * ship an extension that can never report why someone uninstalled it. */ export declare const EXTENSION_BACKGROUND_PATH = "src/background.js"; export interface ExtensionTemplate { id: ExtensionTemplateId; label: string; /** One line on the picker card: what this kind of extension is for. */ summary: string; /** Components locked on while this template is selected. */ requires: readonly ExtensionTemplateComponent[]; /** * Permissions the manifest cannot drop while this template is selected. * * Chromium vocabulary. Firefox reaches the same capability through a * different manifest key and needs no permission for it (`sidebar_action` * instead of `sidePanel` + `side_panel`), so a per-browser manifest builder * is expected to translate rather than to emit these verbatim. */ requiredPermissions: readonly string[]; /** Pre-ticked because the template usually needs them — always removable. */ recommendedPermissions: readonly string[]; /** Repo-relative file the required component points at. */ entry: string; /** Every file the scaffold writes for this template, `entry` included. */ emits: readonly string[]; /** Seed match patterns, for the templates whose component is a content script. */ defaultMatches?: readonly string[]; } export declare const EXTENSION_TEMPLATE_CATALOG: readonly ExtensionTemplate[]; export declare function isExtensionTemplateId(value: unknown): value is ExtensionTemplateId; export declare function getExtensionTemplate(id: ExtensionTemplateId): ExtensionTemplate; /** * Clean a persisted or client-supplied list into templates we know. * * Saved tool state is free-form JSON written by whatever build was live at the * time, so an unknown id is expected rather than exceptional: it is dropped, * not thrown on. Order follows the catalog so two projects that picked the same * set produce the same manifest, and duplicates collapse. */ export declare function normalizeExtensionTemplates(value: unknown): ExtensionTemplateId[]; /** The selection to build with: what was picked, or the default when nothing was. */ export declare function effectiveExtensionTemplates(value: unknown): ExtensionTemplateId[]; /** Permissions the selection forces into the manifest (locked in the UI). */ export declare function extensionTemplateRequiredPermissions(ids: readonly ExtensionTemplateId[]): string[]; /** Permissions ticked when a template is picked, minus the ones already forced. */ export declare function extensionTemplateRecommendedPermissions(ids: readonly ExtensionTemplateId[]): string[]; /** Components the selection locks on. */ export declare function extensionTemplateComponents(ids: readonly ExtensionTemplateId[]): ExtensionTemplateComponent[]; /** Templates whose component is a content script, in catalog order. */ export declare function extensionTemplatesWithContentScripts(ids: readonly ExtensionTemplateId[]): ExtensionTemplate[]; /** Every file the scaffold writes for a selection, background script included. */ export declare function extensionTemplateFiles(ids: readonly ExtensionTemplateId[]): string[]; //# sourceMappingURL=extension-templates.d.ts.map