Files
registry/schemas/catalog-metadata.v1.schema.json
Yige 3828aa6800 feat(registry): 插件与应用关系契约4.2 / plugin and application contract (#10)
* feat(registry): 增加插件贡献与应用依赖的4.2契约

* fix(registry): preserve legacy App manifests for published clients

---------

Co-authored-by: yi-ge <6657330+yi-ge@users.noreply.github.com>
2026-10-07 19:08:18 -07:00

518 lines
21 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/desirecore/registry/schemas/catalog-metadata.v1.schema.json",
"title": "DesireCore Registry catalog metadata v1 sidecar",
"description": "CatalogItemV1 的 Registry 来源事实子集。受信 catalogSourceId、catalog provenance 和 official 身份由客户端同步器注入,禁止写入本文档。",
"type": "object",
"required": ["schemaVersion", "identity", "presentation", "release", "timestamps", "provenance", "governance", "compatibility", "spec"],
"properties": {
"$schema": { "const": "../../schemas/catalog-metadata.v1.schema.json" },
"schemaVersion": { "const": 1 },
"identity": {
"type": "object",
"required": ["kind", "id"],
"properties": {
"kind": { "enum": ["app", "service"], "description": "canonical 条目类型;Registry mcp/http-api 都归一为 service。" },
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "description": "来源内条目 ID;受信来源 ID 不属于 sidecar。" }
},
"additionalProperties": false
},
"presentation": {
"type": "object",
"required": ["defaultLocale", "i18n", "tags"],
"properties": {
"defaultLocale": { "type": "string", "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$" },
"i18n": {
"type": "object",
"minProperties": 1,
"propertyNames": { "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$" },
"additionalProperties": { "$ref": "#/$defs/localeText" }
},
"tags": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 120 }, "uniqueItems": true }
},
"additionalProperties": false
},
"release": { "$ref": "#/$defs/release" },
"timestamps": {
"type": "object",
"required": ["catalogUpdatedAt", "releasePublishedAt", "reviewedAt", "upstreamObservedAt"],
"properties": {
"catalogUpdatedAt": { "$ref": "#/$defs/timestamp" },
"releasePublishedAt": { "$ref": "#/$defs/timestamp" },
"reviewedAt": { "$ref": "#/$defs/timestamp" },
"upstreamObservedAt": { "$ref": "#/$defs/timestamp" }
},
"additionalProperties": false,
"description": "目录修改、内容发布、审核和上游观察时间彼此独立;syncedAt 不属于上游元数据。"
},
"provenance": {
"type": "object",
"properties": { "content": { "$ref": "#/$defs/contentSource" } },
"additionalProperties": false,
"description": "只声明内容来源。Catalog 仓库来源由同步器根据受信 repo 上下文注入。"
},
"governance": {
"type": "object",
"required": ["availability", "license", "redistribution"],
"properties": {
"availability": { "enum": ["listing-only", "installable"] },
"stewardship": { "enum": ["partner", "community", "pointer"], "description": "正文不得自报 official;受信官方身份只能由同步器注入。" },
"license": { "$ref": "#/$defs/license" },
"redistribution": { "enum": ["allowed", "source-pointer-only", "verify-package-terms"] },
"listingMaintainer": { "$ref": "#/$defs/maintainer" },
"upstreamMaintainer": { "$ref": "#/$defs/maintainer" },
"branding": { "$ref": "#/$defs/branding" },
"compliance": { "$ref": "#/$defs/compliance" }
},
"additionalProperties": false
},
"compatibility": {
"type": "object",
"required": ["platforms"],
"properties": {
"platforms": { "$ref": "#/$defs/platforms" },
"requiredClientVersion": {
"type": "string",
"pattern": "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
}
},
"additionalProperties": false
},
"spec": { "oneOf": [{ "$ref": "#/$defs/appSpec" }, { "$ref": "#/$defs/serviceSpec" }] }
},
"additionalProperties": false,
"$defs": {
"localeText": {
"type": "object",
"required": ["name", "summary"],
"properties": {
"name": { "type": "string", "minLength": 1 },
"summary": { "type": "string", "minLength": 1 },
"description": { "type": "string", "minLength": 1 }
},
"additionalProperties": false
},
"release": {
"oneOf": [
{
"type": "object",
"required": ["state"],
"properties": { "state": { "const": "unknown" } },
"additionalProperties": false
},
{
"type": "object",
"required": ["state", "version", "versionScheme"],
"properties": {
"state": { "const": "known" },
"version": { "type": "string", "minLength": 1, "maxLength": 160 },
"versionScheme": { "enum": ["semver", "calver", "opaque"] }
},
"additionalProperties": false
}
]
},
"timestamp": {
"oneOf": [
{
"type": "object",
"required": ["state"],
"properties": { "state": { "const": "unknown" } },
"additionalProperties": false
},
{
"type": "object",
"required": ["state", "value", "precision"],
"properties": {
"state": { "const": "known" },
"value": { "type": "string" },
"precision": { "enum": ["day", "second"] }
},
"additionalProperties": false
}
]
},
"contentSource": {
"type": "object",
"required": ["kind", "url"],
"properties": {
"kind": { "enum": ["git", "web", "zip", "release", "package", "container"] },
"url": { "type": "string", "format": "uri" },
"ref": { "type": "string", "minLength": 1, "maxLength": 500 },
"sha256": { "type": "string", "pattern": "^[a-fA-F0-9]{64}$" },
"path": { "type": "string", "minLength": 1 }
},
"additionalProperties": false
},
"license": {
"oneOf": [
{
"type": "object",
"required": ["state"],
"properties": { "state": { "const": "unknown" } },
"additionalProperties": false
},
{
"type": "object",
"required": ["state", "value"],
"properties": {
"state": { "const": "known" },
"value": { "type": "string", "minLength": 1, "maxLength": 240 },
"evidencePath": { "type": "string", "minLength": 1 }
},
"additionalProperties": false
}
]
},
"maintainer": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "minLength": 1 },
"url": { "type": "string", "format": "uri" },
"verified": { "type": "boolean", "description": "身份是否已验证;不代表许可证授权或官方身份。" }
},
"additionalProperties": false
},
"branding": {
"type": "object",
"required": ["relationship", "nameUsage", "logoStatus"],
"properties": {
"relationship": { "enum": ["partner", "independent-listing"], "description": "sidecar 不接受 official 自报。" },
"nameUsage": { "enum": ["owned", "licensed", "nominative"] },
"logoStatus": { "enum": ["not-used", "license-covered", "trademark-policy-allowed", "permission-obtained"] }
},
"additionalProperties": false
},
"compliance": {
"type": "object",
"required": ["licenseEvidencePath", "reviewedRef", "reviewedAt", "reviewedBy", "upstreamEndorsed"],
"properties": {
"licenseEvidencePath": { "type": "string", "minLength": 1 },
"noticePath": { "type": "string", "minLength": 1 },
"reviewedRef": { "type": "string", "minLength": 1 },
"reviewedAt": { "type": "string" },
"reviewedBy": { "type": "string", "minLength": 1 },
"upstreamEndorsed": { "type": "boolean" }
},
"additionalProperties": false
},
"platforms": {
"oneOf": [
{
"type": "object",
"required": ["state", "values"],
"properties": {
"state": { "const": "known" },
"values": {
"type": "array",
"items": { "enum": ["macos", "windows", "linux", "web", "ios", "android"] },
"minItems": 1,
"uniqueItems": true
}
},
"additionalProperties": false
},
{
"type": "object",
"required": ["state"],
"properties": { "state": { "enum": ["all", "unknown"] } },
"additionalProperties": false
}
]
},
"placementPolicy": {
"type": "object",
"required": ["showInMyApps", "allowNavPin", "allowAgentBinding"],
"properties": {
"showInMyApps": { "type": "boolean" },
"allowNavPin": { "type": "boolean" },
"allowAgentBinding": { "type": "boolean" }
},
"additionalProperties": false
},
"appSpec": {
"type": "object",
"required": ["kind"],
"properties": {
"kind": { "const": "app" },
"productKind": {
"type": "string",
"enum": [
"application",
"plugin"
],
"description": "主要产品归属;应用提供独立业务,插件增加宿主能力。旧定义缺失时由受信适配层归一为 application。"
},
"extension": {
"type": "object",
"required": [
"apiVersion",
"hosts",
"runtime",
"contributes"
],
"additionalProperties": false,
"properties": {
"apiVersion": {
"const": "1.0.0",
"description": "宿主扩展协议版本;当前支持 1.0.0。"
},
"hosts": {
"type": "array",
"minItems": 1,
"maxItems": 2,
"uniqueItems": true,
"items": {
"type": "string",
"enum": [
"agent-service",
"desktop-host"
]
},
"description": "执行宿主;未实现的宿主只作声明并显示不兼容,客户端展示面在 UI 定义中另行声明。"
},
"runtime": {
"oneOf": [
{
"type": "object",
"required": [
"kind"
],
"properties": {
"kind": {
"const": "declarative",
"description": "仅由宿主读取声明,不创建执行进程。"
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"kind",
"protocol",
"descriptorRef"
],
"properties": {
"kind": {
"const": "service",
"description": "既有服务 owner 管理的协议连接;贡献调用继续走原授权和审批。"
},
"protocol": {
"type": "string",
"enum": [
"mcp",
"http"
],
"description": "服务通信协议,不代表连接已经建立。"
},
"descriptorRef": {
"type": "object",
"required": [
"path",
"sha256"
],
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"minLength": 1,
"maxLength": 512,
"pattern": "^(?!/)(?!.*\\\\)(?!.*:)(?!.*\\u0000)(?!.*(?:^|/)(?:\\.|\\.\\.)(?:/|$))(?!.*//)[^/]+(?:/[^/]+)*$",
"description": "固定在核验制品根下的规范 POSIX 相对文件路径;拒绝绝对路径、反斜杠、盘符、空段、点段及 NUL。解析时仍须核验 realpath containment。"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "固定文件字节的 SHA-256;消费前核验,编辑须提交新安装修订。"
}
},
"description": "安装制品根下内容固定的材料引用;相对路径和摘要必须共同匹配。"
}
},
"additionalProperties": false
}
],
"description": "贡献执行承载;descriptor 只定位受核验材料,不能直接把任意 endpoint 当运行事实。"
},
"contributes": {
"type": "array",
"maxItems": 64,
"items": {
"type": "object",
"required": [
"id",
"point",
"contractVersion",
"definitionRef"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$",
"description": "产品内稳定贡献 ID;与来源、产品及精确安装实例共同定位运行绑定。"
},
"point": {
"type": "string",
"enum": [
"document.parsers",
"session.panels",
"session.widgets",
"session.actions",
"tools",
"skills"
],
"description": "具有实际宿主消费者的贡献点;未知贡献点不得接入。"
},
"contractVersion": {
"const": 1,
"description": "该贡献点的消费契约版本;不兼容版本不激活。"
},
"definitionRef": {
"type": "object",
"required": [
"path",
"sha256"
],
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"minLength": 1,
"maxLength": 512,
"pattern": "^(?!/)(?!.*\\\\)(?!.*:)(?!.*\\u0000)(?!.*(?:^|/)(?:\\.|\\.\\.)(?:/|$))(?!.*//)[^/]+(?:/[^/]+)*$",
"description": "固定在核验制品根下的规范 POSIX 相对文件路径;拒绝绝对路径、反斜杠、盘符、空段、点段及 NUL。解析时仍须核验 realpath containment。"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "固定文件字节的 SHA-256;消费前核验,编辑须提交新安装修订。"
}
},
"description": "安装制品根下内容固定的材料引用;相对路径和摘要必须共同匹配。"
}
},
"description": "包内贡献定义引用;业务层补充贡献 ID 唯一性及内容摘要核验。"
},
"description": "本产品提供的宿主贡献;仅消费能力的普通应用允许空数组,独立插件必须至少一项。每项定义从安装材料读取并核验。"
},
"configurationSchemaRef": {
"type": "object",
"required": [
"path",
"sha256"
],
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"minLength": 1,
"maxLength": 512,
"pattern": "^(?!/)(?!.*\\\\)(?!.*:)(?!.*\\u0000)(?!.*(?:^|/)(?:\\.|\\.\\.)(?:/|$))(?!.*//)[^/]+(?:/[^/]+)*$",
"description": "固定在核验制品根下的规范 POSIX 相对文件路径;拒绝绝对路径、反斜杠、盘符、空段、点段及 NUL。解析时仍须核验 realpath containment。"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "固定文件字节的 SHA-256;消费前核验,编辑须提交新安装修订。"
}
},
"description": "安装制品根下内容固定的材料引用;相对路径和摘要必须共同匹配。"
},
"requires": {
"type": "array",
"maxItems": 64,
"items": {
"type": "object",
"required": [
"sourceId",
"appId",
"contributionId",
"contractVersion",
"optional"
],
"additionalProperties": false,
"properties": {
"sourceId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$",
"description": "直接依赖的受信产品来源,禁止按同名产品猜测。"
},
"appId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$",
"description": "所依赖的应用或插件产品 ID;静态定义不携带安装实例 ID。"
},
"contributionId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$",
"description": "消费方需要的具体贡献 ID。"
},
"contractVersion": {
"const": 1,
"description": "消费方支持的贡献契约版本。"
},
"optional": {
"type": "boolean",
"description": "true 为可选增强;false 缺失时阻断受影响功能,不自动安装或卸载。"
},
"versionRange": {
"type": "string",
"minLength": 1,
"maxLength": 120,
"description": "可选发布版本 semver 范围,由满足性检查器校验。"
}
},
"description": "直接能力依赖;运行时须显式解析兼容的精确安装实例,不建设递归依赖求解器。"
},
"description": "本产品消费的必需或可选直接能力依赖;不产生使用授权。"
}
},
"not": {
"properties": {
"contributes": {
"maxItems": 0
},
"requires": {
"maxItems": 0
}
}
},
"description": "产品提供或消费宿主能力的关系契约;至少声明一项贡献或依赖。普通应用可仅消费,独立插件仍须提供实际贡献。"
},
"category": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
"entrypointKinds": {
"type": "array",
"items": { "enum": ["builtin", "embedded-web", "external", "agent"] },
"uniqueItems": true
},
"placementPolicy": { "$ref": "#/$defs/placementPolicy" }
},
"allOf": [{"if":{"properties":{"productKind":{"const":"plugin"}},"required":["productKind"]},"then":{"required":["extension"],"properties":{"extension":{"properties":{"contributes":{"minItems":1}}}}}}],
"additionalProperties": false
},
"serviceSpec": {
"type": "object",
"required": ["kind", "protocol"],
"properties": {
"kind": { "const": "service" },
"protocol": { "enum": ["mcp", "http"] },
"authType": { "enum": ["none", "bearer", "header", "query", "oauth", "unknown"] },
"capabilities": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 160 }, "uniqueItems": true },
"toolCount": { "type": "integer", "minimum": 0 }
},
"additionalProperties": false
}
}
}