diff --git a/docs/reference/plugins.md b/docs/reference/plugins.md index ebb2d9d..503252d 100644 --- a/docs/reference/plugins.md +++ b/docs/reference/plugins.md @@ -11,7 +11,7 @@ publish npm tooling, grant setup permissions, or deploy resources. | --- | --- | | Claude Code | Native manifest in the canonical bundle; strict validation and isolated seven-skill discovery gated with CLI `2.1.296`. | | GitHub Copilot CLI | Portable manifest; isolated marketplace install and seven-skill discovery gated with CLI `1.0.98`. App discovery additionally needs verification in the user's actual profile. | -| Codex and Cursor | Their documentation supports the portable Agent Plugins package. Catalogs target the same bundle; native loaders have not been verified here. | +| Codex (OpenAI) and Cursor | Their documentation supports the portable Agent Plugins package. Codex presentation metadata lives under `extensions["com.openai"]` in [plugin.json](../../plugins/sql-apps/plugin.json), and [.agents/plugins/marketplace.json](../../.agents/plugins/marketplace.json) is the repo marketplace. Native loaders have not been verified here. | | Gemini CLI | Native extension manifest inside the same bundle; documented local-directory installation, but loader behavior has not been verified here. | | Other assistants | Use the provider-neutral project guides. This is not a claim of native plugin integration. | diff --git a/plugins/sql-apps/plugin.json b/plugins/sql-apps/plugin.json index 9d4f429..0729135 100644 --- a/plugins/sql-apps/plugin.json +++ b/plugins/sql-apps/plugin.json @@ -7,5 +7,17 @@ "homepage": "https://github.com/microsoft/sql-apps", "repository": "https://github.com/microsoft/sql-apps", "license": "MIT", - "keywords": ["azure-sql", "data-api-builder", "local-development", "application-foundation"] + "keywords": ["azure-sql", "data-api-builder", "local-development", "application-foundation"], + "extensions": { + "com.openai": { + "interface": { + "displayName": "SQL Apps", + "shortDescription": "Build an Azure SQL and Data API Builder application", + "developerName": "Microsoft SQL team (mssql)", + "category": "Coding", + "capabilities": ["Read", "Write"], + "websiteURL": "https://github.com/microsoft/sql-apps" + } + } + } } diff --git a/scripts/check-plugin.mjs b/scripts/check-plugin.mjs index f5977d2..e63a466 100644 --- a/scripts/check-plugin.mjs +++ b/scripts/check-plugin.mjs @@ -14,9 +14,11 @@ export async function checkPlugin() { assert.equal(manifest.name, 'sql-apps'); assert.equal(manifest.version, '0.2.3'); assert.ok(manifest.description?.length); - const allowed = new Set(['$schema', 'name', 'version', 'description', 'author', 'homepage', 'repository', 'license', 'keywords']); + const allowed = new Set(['$schema', 'name', 'version', 'description', 'author', 'homepage', 'repository', 'license', 'keywords', 'extensions']); assert.ok(Object.keys(manifest).every(key => allowed.has(key)), 'Manifest uses only Agent Plugins 1.0 metadata fields'); - const { $schema, ...metadata } = manifest; + assert.deepEqual(Object.keys(manifest.extensions ?? {}), ['com.openai'], 'Only OpenAI presentation metadata is namespaced'); + assert.ok(manifest.extensions['com.openai'].interface?.displayName, 'Codex presentation metadata is declared'); + const { $schema, extensions, ...metadata } = manifest; assert.deepEqual(JSON.parse(await readFile(join(plugin, '.claude-plugin', 'plugin.json'), 'utf8')), metadata, 'Claude metadata matches the portable manifest without portable schema fields'); const gemini = JSON.parse(await readFile(join(plugin, 'gemini-extension.json'), 'utf8')); diff --git a/tests/plugin.test.ts b/tests/plugin.test.ts index e1a14c4..3597485 100644 --- a/tests/plugin.test.ts +++ b/tests/plugin.test.ts @@ -29,9 +29,18 @@ test('SQL Apps identity is consistent across packages, platform manifests and ma const repository = 'https://github.com/microsoft/sql-apps'; const portable = JSON.parse(await readFile('plugins/sql-apps/plugin.json', 'utf8')); const native = JSON.parse(await readFile('plugins/sql-apps/.claude-plugin/plugin.json', 'utf8')); - const { $schema, ...metadata } = portable; + const { $schema, extensions, ...metadata } = portable; assert.equal($schema, 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json'); assert.deepEqual(native, metadata, 'Native Claude metadata must match the portable package'); + assert.deepEqual(Object.keys(extensions), ['com.openai'], 'Only OpenAI presentation metadata is namespaced'); + assert.deepEqual(extensions['com.openai'].interface, { + displayName: 'SQL Apps', + shortDescription: 'Build an Azure SQL and Data API Builder application', + developerName: 'Microsoft SQL team (mssql)', + category: 'Coding', + capabilities: ['Read', 'Write'], + websiteURL: repository, + }); for (const path of ['plugins/sql-apps/plugin.json', 'plugins/sql-apps/.claude-plugin/plugin.json']) { const manifest = JSON.parse(await readFile(path, 'utf8')); assert.equal(manifest.name, 'sql-apps', path);