mirror of
https://git.openapi.site/https://github.com/desirecore/registry.git
synced 2026-10-21 04:53:23 +08:00
* 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>
518 lines
21 KiB
JSON
518 lines
21 KiB
JSON
{
|
||
"$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
|
||
}
|
||
}
|
||
}
|