From bd973d97511cf7f86cb22c2ff0652ba4e7f56182 Mon Sep 17 00:00:00 2001 From: yi-ge Date: Tue, 13 Oct 2026 17:13:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=9D=E7=95=99=E6=AD=A3=E5=BC=8F?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=A0=BC=E5=BC=8F=E5=B9=B6=E9=9A=94=E7=A6=BB?= =?UTF-8?q?=E4=BD=9C=E8=80=85=E5=80=99=E9=80=89=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- SCHEMA_VERSION | 2 +- manifest.json | 4 +- package-lock.json | 4 +- package.json | 2 +- schemas/registry-entry.schema.json | 1754 +------- schemas/registry-entry.v4.3.schema.json | 5215 +++++++++++++++++++++++ scripts/application-authoring.test.mjs | 9 +- 8 files changed, 5234 insertions(+), 1762 deletions(-) create mode 100644 schemas/registry-entry.v4.3.schema.json diff --git a/README.md b/README.md index ed410e8..2b8a1aa 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ DesireCore 客户端启动时会克隆此仓库,并定期同步更新。用户 ```text . ├── README.md # 本文件 -├── SCHEMA_VERSION # 数据格式版本号(4.3.0兼容候选,尚未开放新工作台条目) +├── SCHEMA_VERSION # 正式数据格式仍为4.2.0;4.3候选另存独立Schema文件 ├── manifest.json # 仓库元数据(版本、统计、维护者) ├── package.json # Registry 校验入口 ├── schemas/ # legacy entry、仓库 manifest 与 catalog sidecar Schema @@ -70,6 +70,10 @@ English: Plugins are App products with host contributions, sharing the canonical ## 固定工作台应用(4.3兼容候选) +本PR只新增 `schemas/registry-entry.v4.3.schema.json` 和合成fixtures/validator,正式 `SCHEMA_VERSION`、manifest数据版本与 `schemas/registry-entry.schema.json` 原4.2字节保持。正式Schema SHA-256仍为 `ea63d6305ae17994e595aea009a131c41300d2b7fdb07ec83cc2c19c37b32038`;4.3候选为 `29ece0b6ae92d2b31d18bbb288b5ed33220dde125924082e1e38c20ace900200`。旧已发行客户端不会因为此Schema先行PR丢失原外部listing或其他类目。 + +发布顺序:先review候选Schema/fixtures → 主仓固定候选摘要并交付兼容reader(官方候选只允许原类目,可信非官方测试源可验新类型)→ 核心Agent/Market知识经各自PR合入再同步真实main bootstrap → 客户端能力实际发行并验证 → 单独PR将正式Schema激活4.3并开放新entries。每一步取实际提交/发行/目录回执,不把未合入commit固定成官方seed。若有4.3checkout先到新reader,只有版本/字节摘要完全匹配才读原类目;未知或被篡改Schema继续关闭,新作者条目仍等待正式准入。 + 4.3保留全部4.2旧分支,新增 `web-bundle` 与带 `appRelease` 的 `native-app`/`docker-app` 严格分支。网页包不冒充无执行声明artifact;宿主/容器服务应用使用 `install.method: release`,运行知识与依赖在固定清单中,不限定Node技术栈,也不自动执行说明文字。Docker显式声明固定imageRefs,每项是repository@sha256,复用原容器/执行/服务owner;没有真实身份adapter时保留Agent管理,不因为Schema合法声称直开。新分支声明来源无关releaseDigest、包内manifestPath/definitionPath与实际能力要求,source.sha256仍为下载归档原始字节摘要;descriptor在安装时按来源物化并单独核验。 正式目录未新增工作台条目。`fixtures/authoring/`只有合成的listing-only契约样本,example.test地址不是可获取的应用发行物,不表示上传、审核、运行或第二用户安装已完成。主仓内置seed保持旧受审提交;此候选先经外仓与客户端reader分别review,只有客户端真实app-authoring-v1/web-bundle等能力发行后才能开放新entries。最低版本字符串不能代替握手,旧客户端继续读取旧条目并忽略未知类型,不允许改交付类型绕过。 diff --git a/SCHEMA_VERSION b/SCHEMA_VERSION index 8089590..6aba2b2 100644 --- a/SCHEMA_VERSION +++ b/SCHEMA_VERSION @@ -1 +1 @@ -4.3.0 +4.2.0 diff --git a/manifest.json b/manifest.json index b5ca813..21aa3d6 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "id": "desirecore-registry-manifest", - "version": "4.3.0", + "version": "4.2.0", "name": "DesireCore Registry", "description": "DesireCore 官方注册表 — 应用、插件、MCP 服务、HTTP API 和第三方外部集成的统一目录", "maintainer": "DesireCore Team", @@ -15,7 +15,7 @@ "httpApis": 5, "externalIntegrations": 1 }, - "dataVersion": "4.3.0", + "dataVersion": "4.2.0", "catalogMetadata": { "version": "1.0.0", "schema": "schemas/catalog-metadata.v1.schema.json", diff --git a/package-lock.json b/package-lock.json index 18f24a2..fa9d5db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@desirecore/registry", - "version": "4.3.0", + "version": "4.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@desirecore/registry", - "version": "4.3.0", + "version": "4.2.0", "devDependencies": { "ajv": "8.20.0" }, diff --git a/package.json b/package.json index d7e79cf..6c23298 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@desirecore/registry", - "version": "4.3.0", + "version": "4.2.0", "private": true, "description": "Validated catalog data for the DesireCore Registry", "type": "module", diff --git a/schemas/registry-entry.schema.json b/schemas/registry-entry.schema.json index 3c68f10..e0b365a 100644 --- a/schemas/registry-entry.schema.json +++ b/schemas/registry-entry.schema.json @@ -1,8 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://github.com/desirecore/registry/schemas/registry-entry.schema.json", - "title": "DesireCore Registry Entry 4.3", - "description": "兼容保留4.2条目并新增固定应用release/web-bundle。候选Schema先审阅,客户端具备真实app-authoring-v1能力后才能开放条目。", + "title": "DesireCore Registry Entry 4.2", + "description": "严格区分应用/插件与服务/外部集成的 Registry 4.2 authored 契约。产品归属、部署方式、宿主贡献分别声明;声明不产生授权。此候选须在 Registry 外仓 review 后发布。", "oneOf": [ { "$ref": "#/definitions/dockerApp" @@ -21,15 +21,6 @@ }, { "$ref": "#/definitions/externalIntegration" - }, - { - "$ref": "#/definitions/webBundle" - }, - { - "$ref": "#/definitions/authoredNativeApp" - }, - { - "$ref": "#/definitions/authoredDockerApp" } ], "definitions": { @@ -3469,1747 +3460,6 @@ } } ] - }, - "appRelease": { - "type": "object", - "description": "Registry 指向固定应用 release 的兼容视图;来源归档摘要在 source.sha256,不能与 releaseDigest 交换。", - "required": [ - "schemaVersion", - "releaseDigest", - "manifestPath", - "definitionPath", - "requiredCapabilities" - ], - "properties": { - "schemaVersion": { - "const": 1, - "description": "固定 release 目录引用格式版本。" - }, - "releaseDigest": { - "type": "string", - "pattern": "^[a-f0-9]{64}$", - "description": "app-release-c14n-v1 规范材料身份;不是归档文件摘要。" - }, - "manifestPath": { - "type": "string", - "const": "app-release.json", - "description": "获取并核验的包内固定 release 清单。" - }, - "definitionPath": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.?(?:/|$))(?!.*[\\\\\\x00-\\x1f])[^?#]+$", - "description": "同一 release 文件清单中的作者定义路径;相对 POSIX 路径,禁止宿主路径、穿越和 URL。" - }, - "requiredCapabilities": { - "type": "array", - "minItems": 1, - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 120 - }, - "contains": { - "const": "app-authoring-v1" - }, - "description": "获取后需要重新握手的真实能力;最低客户端版本不能代替能力支持。" - }, - "imageRefs": { - "type": "array", - "minItems": 1, - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 2048, - "pattern": "^(?:localhost|[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+)(?::[1-9][0-9]{0,4})?/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*@sha256:[a-f0-9]{64}$", - "description": "显式DNS/IPv4或localhost注册表、可选端口和repository@sha256:小写64位摘要;不能用浮动tag、shell、凭据或宿主路径。" - }, - "description": "仅容器release从同一delivery映射的固定镜像依赖;不包含登录凭据,不假定本机Docker可用。" - } - }, - "additionalProperties": false - }, - "webBundle": { - "type": "object", - "description": "固定网页包:页面到包内文件的映射在同一release清单,不执行宿主程序、不派生内部服务。", - "required": [ - "id", - "name", - "type", - "version", - "author", - "description", - "tags", - "icon", - "iconLetter", - "platformSupport", - "category", - "fullDesc", - "shortDesc", - "install", - "source", - "requiredClientVersion", - "placementPolicy", - "stewardship", - "availability", - "license", - "redistribution", - "entrypoints", - "appRelease" - ], - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "name": { - "$ref": "#/definitions/nonEmptyString" - }, - "type": { - "const": "web-bundle", - "description": "与 release.delivery 一致的交付类别。" - }, - "version": { - "$ref": "#/definitions/version" - }, - "author": { - "$ref": "#/definitions/nonEmptyString" - }, - "description": { - "$ref": "#/definitions/nonEmptyString" - }, - "tags": { - "$ref": "#/definitions/tags" - }, - "icon": { - "$ref": "#/definitions/nonEmptyString" - }, - "iconLetter": { - "type": "string", - "minLength": 1, - "maxLength": 2 - }, - "platformSupport": { - "type": "array", - "minItems": 1, - "maxItems": 4, - "uniqueItems": true, - "items": { - "enum": [ - "macos", - "windows", - "linux", - "web" - ] - }, - "description": "来源release支持的平台;运行时仍需真实宿主能力。" - }, - "category": { - "type": "string", - "minLength": 1, - "pattern": "^[a-z0-9-]+$", - "description": "应用分类(slug 格式),可扩展任意分类" - }, - "fullDesc": { - "$ref": "#/definitions/nonEmptyString" - }, - "shortDesc": { - "$ref": "#/definitions/nonEmptyString" - }, - "githubUrl": { - "$ref": "#/definitions/httpsUrl" - }, - "requiredClientVersion": { - "$ref": "#/definitions/version" - }, - "install": { - "type": "object", - "required": [ - "method", - "requirements" - ], - "additionalProperties": false, - "description": "先获取固定 release 再由 Agent 沿既有发布/执行owner处理;不是自动安装DSL。", - "properties": { - "method": { - "const": "web-bundle", - "description": "固定应用材料的安装方式。" - }, - "requirements": { - "type": "object", - "required": [ - "docker", - "ports" - ], - "additionalProperties": false, - "description": "发布者声明的环境条件;未知资源数字省略,不是当前运行健康。", - "properties": { - "docker": { - "const": false, - "description": "此静态或宿主应用分支不安装Docker。" - }, - "ports": { - "type": "array", - "uniqueItems": true, - "maxItems": 0, - "items": { - "type": "integer", - "minimum": 1, - "maximum": 65535 - }, - "description": "声明服务端口要求;运行时地址必须由可信执行owner提供。" - }, - "minMemory": { - "type": "string", - "minLength": 1, - "description": "实际发布材料声明的内存条件;未知省略。" - }, - "minDisk": { - "type": "string", - "minLength": 1, - "description": "实际发布材料声明的磁盘条件;未知省略。" - } - } - }, - "configNeeded": { - "type": "array", - "items": { - "type": "string", - "minLength": 1 - }, - "description": "发布者说明的配置准备项,不包含凭据。" - } - } - }, - "placementPolicy": { - "type": "object", - "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", - "required": [ - "showInMyApps", - "allowNavPin", - "allowAgentBinding" - ], - "properties": { - "showInMyApps": { - "type": "boolean", - "description": "安装后是否允许出现在“我的应用”" - }, - "allowNavPin": { - "type": "boolean", - "description": "用户是否可将应用固定到主导航" - }, - "allowAgentBinding": { - "type": "boolean", - "description": "用户是否可将应用关联到 Agent 会话侧栏" - } - }, - "additionalProperties": false - }, - "source": { - "type": "object", - "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", - "required": [ - "kind", - "url", - "ref" - ], - "properties": { - "kind": { - "type": "string", - "enum": [ - "git", - "release", - "package", - "container" - ], - "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "权威上游地址;不得由客户端在安装请求中替换。" - }, - "ref": { - "type": "string", - "minLength": 1, - "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" - }, - "sha256": { - "type": "string", - "pattern": "^[a-fA-F0-9]{64}$", - "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" - }, - "path": { - "type": "string", - "minLength": 1, - "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" - }, - "upstreamRepo": { - "type": "string", - "format": "uri", - "description": "制品与源码不在同一地址时对应的上游源码仓库。" - } - }, - "additionalProperties": false - }, - "stewardship": { - "type": "string", - "enum": [ - "official", - "partner", - "community", - "pointer" - ], - "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" - }, - "availability": { - "type": "string", - "enum": [ - "listing-only", - "installable" - ], - "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" - }, - "license": { - "type": "string", - "minLength": 1, - "description": "覆盖实际制品的许可证标识。" - }, - "redistribution": { - "type": "string", - "enum": [ - "allowed", - "source-pointer-only", - "verify-package-terms" - ], - "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" - }, - "listingMaintainer": { - "type": "object", - "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "维护者的公开名称或组织名称。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "维护者的公开主页、项目主页或可验证身份页面。" - }, - "verified": { - "type": "boolean", - "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" - } - }, - "additionalProperties": false - }, - "upstreamMaintainer": { - "type": "object", - "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "维护者的公开名称或组织名称。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "维护者的公开主页、项目主页或可验证身份页面。" - }, - "verified": { - "type": "boolean", - "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" - } - }, - "additionalProperties": false - }, - "branding": { - "type": "object", - "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", - "required": [ - "relationship", - "nameUsage", - "logoStatus" - ], - "properties": { - "relationship": { - "type": "string", - "enum": [ - "official", - "partner", - "independent-listing" - ], - "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" - }, - "nameUsage": { - "type": "string", - "enum": [ - "owned", - "licensed", - "nominative" - ], - "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" - }, - "logoStatus": { - "type": "string", - "enum": [ - "not-used", - "license-covered", - "trademark-policy-allowed", - "permission-obtained" - ], - "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" - } - }, - "additionalProperties": false - }, - "compliance": { - "type": "object", - "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", - "required": [ - "licenseEvidencePath", - "reviewedRef", - "reviewedAt", - "reviewedBy", - "upstreamEndorsed" - ], - "properties": { - "licenseEvidencePath": { - "type": "string", - "minLength": 1, - "description": "在已审核源码或制品中定位许可证文本的相对路径。" - }, - "noticePath": { - "type": "string", - "minLength": 1, - "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" - }, - "reviewedRef": { - "type": "string", - "minLength": 1, - "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" - }, - "reviewedAt": { - "type": "string", - "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", - "description": "审核日期或 ISO 8601 时间戳。" - }, - "reviewedBy": { - "type": "string", - "minLength": 1, - "description": "可追溯的审核者或审核流程标识。" - }, - "upstreamEndorsed": { - "type": "boolean", - "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" - } - }, - "additionalProperties": false - }, - "productKind": { - "const": "application", - "description": "用户自建应用;不是平台声明插件。" - }, - "entrypoints": { - "type": "array", - "maxItems": 32, - "items": { - "oneOf": [ - { - "type": "object", - "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", - "required": [ - "id", - "name", - "kind", - "serviceRef" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "embedded-web", - "description": "隔离 Web 入口判别字段" - }, - "serviceRef": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "id", - "name", - "kind" - ], - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID。" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "交给 Agent 打开的入口显示名。" - }, - "kind": { - "const": "agent", - "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" - } - } - } - ], - "description": "应用的一个用户可见启动入口,按 kind 严格判别" - }, - "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" - }, - "appRelease": { - "$ref": "#/definitions/appRelease" - } - }, - "allOf": [ - { - "if": { - "properties": { - "availability": { - "const": "installable" - } - }, - "required": [ - "availability" - ] - }, - "then": { - "required": [ - "branding", - "compliance", - "listingMaintainer", - "upstreamMaintainer" - ] - } - } - ] - }, - "authoredNativeApp": { - "type": "object", - "description": "带运行说明的固定宿主应用:可信执行owner核验身份,目录不保存启动命令或当前端口。", - "required": [ - "id", - "name", - "type", - "version", - "author", - "description", - "tags", - "icon", - "iconLetter", - "platformSupport", - "category", - "fullDesc", - "shortDesc", - "install", - "source", - "requiredClientVersion", - "placementPolicy", - "stewardship", - "availability", - "license", - "redistribution", - "entrypoints", - "appRelease" - ], - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "name": { - "$ref": "#/definitions/nonEmptyString" - }, - "type": { - "const": "native-app", - "description": "与 release.delivery 一致的交付类别。" - }, - "version": { - "$ref": "#/definitions/version" - }, - "author": { - "$ref": "#/definitions/nonEmptyString" - }, - "description": { - "$ref": "#/definitions/nonEmptyString" - }, - "tags": { - "$ref": "#/definitions/tags" - }, - "icon": { - "$ref": "#/definitions/nonEmptyString" - }, - "iconLetter": { - "type": "string", - "minLength": 1, - "maxLength": 2 - }, - "platformSupport": { - "type": "array", - "minItems": 1, - "maxItems": 4, - "uniqueItems": true, - "items": { - "enum": [ - "macos", - "windows", - "linux", - "web" - ] - }, - "description": "来源release支持的平台;运行时仍需真实宿主能力。" - }, - "category": { - "type": "string", - "minLength": 1, - "pattern": "^[a-z0-9-]+$", - "description": "应用分类(slug 格式),可扩展任意分类" - }, - "fullDesc": { - "$ref": "#/definitions/nonEmptyString" - }, - "shortDesc": { - "$ref": "#/definitions/nonEmptyString" - }, - "githubUrl": { - "$ref": "#/definitions/httpsUrl" - }, - "requiredClientVersion": { - "$ref": "#/definitions/version" - }, - "install": { - "type": "object", - "required": [ - "method", - "requirements" - ], - "additionalProperties": false, - "description": "先获取固定 release 再由 Agent 沿既有发布/执行owner处理;不是自动安装DSL。", - "properties": { - "method": { - "const": "release", - "description": "固定应用材料的安装方式。" - }, - "requirements": { - "type": "object", - "required": [ - "docker", - "ports" - ], - "additionalProperties": false, - "description": "发布者声明的环境条件;未知资源数字省略,不是当前运行健康。", - "properties": { - "docker": { - "const": false, - "description": "此静态或宿主应用分支不安装Docker。" - }, - "ports": { - "type": "array", - "uniqueItems": true, - "maxItems": 32, - "items": { - "type": "integer", - "minimum": 1, - "maximum": 65535 - }, - "description": "声明服务端口要求;运行时地址必须由可信执行owner提供。" - }, - "minMemory": { - "type": "string", - "minLength": 1, - "description": "实际发布材料声明的内存条件;未知省略。" - }, - "minDisk": { - "type": "string", - "minLength": 1, - "description": "实际发布材料声明的磁盘条件;未知省略。" - }, - "node": { - "type": "string", - "minLength": 1, - "maxLength": 80, - "description": "明确依赖Node时的版本要求,不由交付类别猜测。" - }, - "envVars": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1 - }, - "description": "运行环境变量名称,不包含秘密值。" - } - } - }, - "configNeeded": { - "type": "array", - "items": { - "type": "string", - "minLength": 1 - }, - "description": "发布者说明的配置准备项,不包含凭据。" - } - } - }, - "placementPolicy": { - "type": "object", - "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", - "required": [ - "showInMyApps", - "allowNavPin", - "allowAgentBinding" - ], - "properties": { - "showInMyApps": { - "type": "boolean", - "description": "安装后是否允许出现在“我的应用”" - }, - "allowNavPin": { - "type": "boolean", - "description": "用户是否可将应用固定到主导航" - }, - "allowAgentBinding": { - "type": "boolean", - "description": "用户是否可将应用关联到 Agent 会话侧栏" - } - }, - "additionalProperties": false - }, - "source": { - "type": "object", - "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", - "required": [ - "kind", - "url", - "ref" - ], - "properties": { - "kind": { - "type": "string", - "enum": [ - "git", - "release", - "package", - "container" - ], - "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "权威上游地址;不得由客户端在安装请求中替换。" - }, - "ref": { - "type": "string", - "minLength": 1, - "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" - }, - "sha256": { - "type": "string", - "pattern": "^[a-fA-F0-9]{64}$", - "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" - }, - "path": { - "type": "string", - "minLength": 1, - "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" - }, - "upstreamRepo": { - "type": "string", - "format": "uri", - "description": "制品与源码不在同一地址时对应的上游源码仓库。" - } - }, - "additionalProperties": false - }, - "stewardship": { - "type": "string", - "enum": [ - "official", - "partner", - "community", - "pointer" - ], - "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" - }, - "availability": { - "type": "string", - "enum": [ - "listing-only", - "installable" - ], - "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" - }, - "license": { - "type": "string", - "minLength": 1, - "description": "覆盖实际制品的许可证标识。" - }, - "redistribution": { - "type": "string", - "enum": [ - "allowed", - "source-pointer-only", - "verify-package-terms" - ], - "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" - }, - "listingMaintainer": { - "type": "object", - "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "维护者的公开名称或组织名称。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "维护者的公开主页、项目主页或可验证身份页面。" - }, - "verified": { - "type": "boolean", - "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" - } - }, - "additionalProperties": false - }, - "upstreamMaintainer": { - "type": "object", - "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "维护者的公开名称或组织名称。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "维护者的公开主页、项目主页或可验证身份页面。" - }, - "verified": { - "type": "boolean", - "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" - } - }, - "additionalProperties": false - }, - "branding": { - "type": "object", - "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", - "required": [ - "relationship", - "nameUsage", - "logoStatus" - ], - "properties": { - "relationship": { - "type": "string", - "enum": [ - "official", - "partner", - "independent-listing" - ], - "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" - }, - "nameUsage": { - "type": "string", - "enum": [ - "owned", - "licensed", - "nominative" - ], - "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" - }, - "logoStatus": { - "type": "string", - "enum": [ - "not-used", - "license-covered", - "trademark-policy-allowed", - "permission-obtained" - ], - "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" - } - }, - "additionalProperties": false - }, - "compliance": { - "type": "object", - "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", - "required": [ - "licenseEvidencePath", - "reviewedRef", - "reviewedAt", - "reviewedBy", - "upstreamEndorsed" - ], - "properties": { - "licenseEvidencePath": { - "type": "string", - "minLength": 1, - "description": "在已审核源码或制品中定位许可证文本的相对路径。" - }, - "noticePath": { - "type": "string", - "minLength": 1, - "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" - }, - "reviewedRef": { - "type": "string", - "minLength": 1, - "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" - }, - "reviewedAt": { - "type": "string", - "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", - "description": "审核日期或 ISO 8601 时间戳。" - }, - "reviewedBy": { - "type": "string", - "minLength": 1, - "description": "可追溯的审核者或审核流程标识。" - }, - "upstreamEndorsed": { - "type": "boolean", - "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" - } - }, - "additionalProperties": false - }, - "productKind": { - "const": "application", - "description": "用户自建应用;不是平台声明插件。" - }, - "entrypoints": { - "type": "array", - "maxItems": 32, - "items": { - "oneOf": [ - { - "type": "object", - "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", - "required": [ - "id", - "name", - "kind", - "route" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "builtin", - "description": "内置页面入口判别字段" - }, - "route": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "pattern": "^/(?!/)", - "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", - "required": [ - "id", - "name", - "kind", - "serviceRef" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "embedded-web", - "description": "隔离 Web 入口判别字段" - }, - "serviceRef": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", - "required": [ - "id", - "name", - "kind", - "serviceRef" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "external", - "description": "外部浏览器入口判别字段" - }, - "serviceRef": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" - }, - "path": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "pattern": "^/(?!/)", - "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "id", - "name", - "kind" - ], - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID。" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "交给 Agent 打开的入口显示名。" - }, - "kind": { - "const": "agent", - "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" - } - } - } - ], - "description": "应用的一个用户可见启动入口,按 kind 严格判别" - }, - "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" - }, - "appRelease": { - "$ref": "#/definitions/appRelease" - } - }, - "allOf": [ - { - "if": { - "properties": { - "availability": { - "const": "installable" - } - }, - "required": [ - "availability" - ] - }, - "then": { - "required": [ - "branding", - "compliance", - "listingMaintainer", - "upstreamMaintainer" - ] - } - } - ] - }, - "authoredDockerApp": { - "type": "object", - "description": "固定容器镜像依赖的release应用:使用原Docker执行/服务owner,不新建容器管理器;缺真实身份adapter时不声称直开。", - "required": [ - "id", - "name", - "type", - "version", - "author", - "description", - "tags", - "icon", - "iconLetter", - "platformSupport", - "category", - "fullDesc", - "shortDesc", - "install", - "source", - "requiredClientVersion", - "placementPolicy", - "stewardship", - "availability", - "license", - "redistribution", - "entrypoints", - "appRelease" - ], - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "name": { - "$ref": "#/definitions/nonEmptyString" - }, - "type": { - "const": "docker-app", - "description": "与 release.delivery 一致的交付类别。" - }, - "version": { - "$ref": "#/definitions/version" - }, - "author": { - "$ref": "#/definitions/nonEmptyString" - }, - "description": { - "$ref": "#/definitions/nonEmptyString" - }, - "tags": { - "$ref": "#/definitions/tags" - }, - "icon": { - "$ref": "#/definitions/nonEmptyString" - }, - "iconLetter": { - "type": "string", - "minLength": 1, - "maxLength": 2 - }, - "platformSupport": { - "type": "array", - "minItems": 1, - "maxItems": 4, - "uniqueItems": true, - "items": { - "enum": [ - "macos", - "windows", - "linux", - "web" - ] - }, - "description": "来源release支持的平台;运行时仍需真实宿主能力。" - }, - "category": { - "type": "string", - "minLength": 1, - "pattern": "^[a-z0-9-]+$", - "description": "应用分类(slug 格式),可扩展任意分类" - }, - "fullDesc": { - "$ref": "#/definitions/nonEmptyString" - }, - "shortDesc": { - "$ref": "#/definitions/nonEmptyString" - }, - "githubUrl": { - "$ref": "#/definitions/httpsUrl" - }, - "requiredClientVersion": { - "$ref": "#/definitions/version" - }, - "install": { - "type": "object", - "required": [ - "method", - "requirements" - ], - "additionalProperties": false, - "description": "先获取固定 release 再由 Agent 沿既有发布/执行owner处理;不是自动安装DSL。", - "properties": { - "method": { - "const": "release", - "description": "固定应用材料的安装方式。" - }, - "requirements": { - "type": "object", - "required": [ - "docker", - "ports" - ], - "additionalProperties": false, - "description": "发布者声明的环境条件;未知资源数字省略,不是当前运行健康。", - "properties": { - "docker": { - "const": true, - "description": "此静态或宿主应用分支不安装Docker。" - }, - "ports": { - "type": "array", - "uniqueItems": true, - "maxItems": 32, - "items": { - "type": "integer", - "minimum": 1, - "maximum": 65535 - }, - "description": "声明服务端口要求;运行时地址必须由可信执行owner提供。" - }, - "minMemory": { - "type": "string", - "minLength": 1, - "description": "实际发布材料声明的内存条件;未知省略。" - }, - "minDisk": { - "type": "string", - "minLength": 1, - "description": "实际发布材料声明的磁盘条件;未知省略。" - }, - "node": { - "type": "string", - "minLength": 1, - "maxLength": 80, - "description": "明确依赖Node时的版本要求,不由交付类别猜测。" - }, - "envVars": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1 - }, - "description": "运行环境变量名称,不包含秘密值。" - } - } - }, - "configNeeded": { - "type": "array", - "items": { - "type": "string", - "minLength": 1 - }, - "description": "发布者说明的配置准备项,不包含凭据。" - } - } - }, - "placementPolicy": { - "type": "object", - "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", - "required": [ - "showInMyApps", - "allowNavPin", - "allowAgentBinding" - ], - "properties": { - "showInMyApps": { - "type": "boolean", - "description": "安装后是否允许出现在“我的应用”" - }, - "allowNavPin": { - "type": "boolean", - "description": "用户是否可将应用固定到主导航" - }, - "allowAgentBinding": { - "type": "boolean", - "description": "用户是否可将应用关联到 Agent 会话侧栏" - } - }, - "additionalProperties": false - }, - "source": { - "type": "object", - "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", - "required": [ - "kind", - "url", - "ref" - ], - "properties": { - "kind": { - "type": "string", - "enum": [ - "git", - "release", - "package", - "container" - ], - "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "权威上游地址;不得由客户端在安装请求中替换。" - }, - "ref": { - "type": "string", - "minLength": 1, - "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" - }, - "sha256": { - "type": "string", - "pattern": "^[a-fA-F0-9]{64}$", - "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" - }, - "path": { - "type": "string", - "minLength": 1, - "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" - }, - "upstreamRepo": { - "type": "string", - "format": "uri", - "description": "制品与源码不在同一地址时对应的上游源码仓库。" - } - }, - "additionalProperties": false - }, - "stewardship": { - "type": "string", - "enum": [ - "official", - "partner", - "community", - "pointer" - ], - "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" - }, - "availability": { - "type": "string", - "enum": [ - "listing-only", - "installable" - ], - "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" - }, - "license": { - "type": "string", - "minLength": 1, - "description": "覆盖实际制品的许可证标识。" - }, - "redistribution": { - "type": "string", - "enum": [ - "allowed", - "source-pointer-only", - "verify-package-terms" - ], - "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" - }, - "listingMaintainer": { - "type": "object", - "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "维护者的公开名称或组织名称。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "维护者的公开主页、项目主页或可验证身份页面。" - }, - "verified": { - "type": "boolean", - "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" - } - }, - "additionalProperties": false - }, - "upstreamMaintainer": { - "type": "object", - "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "维护者的公开名称或组织名称。" - }, - "url": { - "type": "string", - "format": "uri", - "description": "维护者的公开主页、项目主页或可验证身份页面。" - }, - "verified": { - "type": "boolean", - "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" - } - }, - "additionalProperties": false - }, - "branding": { - "type": "object", - "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", - "required": [ - "relationship", - "nameUsage", - "logoStatus" - ], - "properties": { - "relationship": { - "type": "string", - "enum": [ - "official", - "partner", - "independent-listing" - ], - "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" - }, - "nameUsage": { - "type": "string", - "enum": [ - "owned", - "licensed", - "nominative" - ], - "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" - }, - "logoStatus": { - "type": "string", - "enum": [ - "not-used", - "license-covered", - "trademark-policy-allowed", - "permission-obtained" - ], - "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" - } - }, - "additionalProperties": false - }, - "compliance": { - "type": "object", - "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", - "required": [ - "licenseEvidencePath", - "reviewedRef", - "reviewedAt", - "reviewedBy", - "upstreamEndorsed" - ], - "properties": { - "licenseEvidencePath": { - "type": "string", - "minLength": 1, - "description": "在已审核源码或制品中定位许可证文本的相对路径。" - }, - "noticePath": { - "type": "string", - "minLength": 1, - "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" - }, - "reviewedRef": { - "type": "string", - "minLength": 1, - "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" - }, - "reviewedAt": { - "type": "string", - "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", - "description": "审核日期或 ISO 8601 时间戳。" - }, - "reviewedBy": { - "type": "string", - "minLength": 1, - "description": "可追溯的审核者或审核流程标识。" - }, - "upstreamEndorsed": { - "type": "boolean", - "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" - } - }, - "additionalProperties": false - }, - "productKind": { - "const": "application", - "description": "用户自建应用;不是平台声明插件。" - }, - "entrypoints": { - "type": "array", - "maxItems": 32, - "items": { - "oneOf": [ - { - "type": "object", - "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", - "required": [ - "id", - "name", - "kind", - "route" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "builtin", - "description": "内置页面入口判别字段" - }, - "route": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "pattern": "^/(?!/)", - "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", - "required": [ - "id", - "name", - "kind", - "serviceRef" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "embedded-web", - "description": "隔离 Web 入口判别字段" - }, - "serviceRef": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", - "required": [ - "id", - "name", - "kind", - "serviceRef" - ], - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "入口显示名称" - }, - "kind": { - "const": "external", - "description": "外部浏览器入口判别字段" - }, - "serviceRef": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" - }, - "path": { - "type": "string", - "minLength": 1, - "maxLength": 512, - "pattern": "^/(?!/)", - "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "id", - "name", - "kind" - ], - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "minLength": 1, - "maxLength": 160, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", - "description": "应用内稳定入口 ID。" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 120, - "description": "交给 Agent 打开的入口显示名。" - }, - "kind": { - "const": "agent", - "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" - } - } - } - ], - "description": "应用的一个用户可见启动入口,按 kind 严格判别" - }, - "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" - }, - "appRelease": { - "$ref": "#/definitions/appRelease" - } - }, - "allOf": [ - { - "if": { - "properties": { - "availability": { - "const": "installable" - } - }, - "required": [ - "availability" - ] - }, - "then": { - "required": [ - "branding", - "compliance", - "listingMaintainer", - "upstreamMaintainer" - ] - } - }, - { - "properties": { - "appRelease": { - "required": [ - "imageRefs" - ] - } - } - } - ] } } } diff --git a/schemas/registry-entry.v4.3.schema.json b/schemas/registry-entry.v4.3.schema.json new file mode 100644 index 0000000..3c68f10 --- /dev/null +++ b/schemas/registry-entry.v4.3.schema.json @@ -0,0 +1,5215 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://github.com/desirecore/registry/schemas/registry-entry.schema.json", + "title": "DesireCore Registry Entry 4.3", + "description": "兼容保留4.2条目并新增固定应用release/web-bundle。候选Schema先审阅,客户端具备真实app-authoring-v1能力后才能开放条目。", + "oneOf": [ + { + "$ref": "#/definitions/dockerApp" + }, + { + "$ref": "#/definitions/nativeApp" + }, + { + "$ref": "#/definitions/artifact" + }, + { + "$ref": "#/definitions/mcp" + }, + { + "$ref": "#/definitions/httpApi" + }, + { + "$ref": "#/definitions/externalIntegration" + }, + { + "$ref": "#/definitions/webBundle" + }, + { + "$ref": "#/definitions/authoredNativeApp" + }, + { + "$ref": "#/definitions/authoredDockerApp" + } + ], + "definitions": { + "nativeApp": { + "type": "object", + "description": "宿主机原生应用:独立安装和运行,不通过 MCP 服务注册或 Docker 容器部署。", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "iconLetter", + "platformSupport", + "category", + "fullDesc", + "shortDesc", + "install", + "source", + "requiredClientVersion", + "placementPolicy", + "stewardship", + "availability", + "license", + "redistribution", + "listingMaintainer", + "upstreamMaintainer", + "branding", + "compliance", + "entrypoints" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "native-app" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "iconLetter": { + "type": "string", + "minLength": 1, + "maxLength": 2 + }, + "platformSupport": { + "$ref": "#/definitions/platformSupport" + }, + "category": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$", + "description": "应用分类(slug 格式),可扩展任意分类" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "githubUrl": { + "$ref": "#/definitions/httpsUrl" + }, + "requiredClientVersion": { + "$ref": "#/definitions/version" + }, + "install": { + "type": "object", + "required": [ + "method", + "requirements", + "configNeeded" + ], + "additionalProperties": false, + "properties": { + "method": { + "const": "native-node", + "description": "按审核后的 install.md 在宿主机安装固定 Node 制品;不自动启动应用或隧道。" + }, + "requirements": { + "type": "object", + "required": [ + "docker", + "node", + "minMemory", + "minDisk", + "ports" + ], + "additionalProperties": false, + "properties": { + "docker": { + "const": false + }, + "node": { + "type": "string", + "minLength": 1, + "maxLength": 80 + }, + "minMemory": { + "$ref": "#/definitions/nonEmptyString" + }, + "minDisk": { + "$ref": "#/definitions/nonEmptyString" + }, + "ports": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "uniqueItems": true, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "description": "安装默认使用的本机管理页面端口,不是对外公网端口或内部服务。" + } + } + }, + "configNeeded": { + "type": "array", + "items": { + "$ref": "#/definitions/nonEmptyString" + } + } + } + }, + "placementPolicy": { + "type": "object", + "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", + "required": [ + "showInMyApps", + "allowNavPin", + "allowAgentBinding" + ], + "properties": { + "showInMyApps": { + "type": "boolean", + "description": "安装后是否允许出现在“我的应用”" + }, + "allowNavPin": { + "type": "boolean", + "description": "用户是否可将应用固定到主导航" + }, + "allowAgentBinding": { + "type": "boolean", + "description": "用户是否可将应用关联到 Agent 会话侧栏" + } + }, + "additionalProperties": false + }, + "source": { + "type": "object", + "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", + "required": [ + "kind", + "url", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "git", + "release", + "package", + "container" + ], + "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "权威上游地址;不得由客户端在安装请求中替换。" + }, + "ref": { + "type": "string", + "minLength": 1, + "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$", + "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" + }, + "path": { + "type": "string", + "minLength": 1, + "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" + }, + "upstreamRepo": { + "type": "string", + "format": "uri", + "description": "制品与源码不在同一地址时对应的上游源码仓库。" + } + }, + "additionalProperties": false + }, + "stewardship": { + "type": "string", + "enum": [ + "official", + "partner", + "community", + "pointer" + ], + "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" + }, + "availability": { + "type": "string", + "enum": [ + "listing-only", + "installable" + ], + "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" + }, + "license": { + "type": "string", + "minLength": 1, + "description": "覆盖实际制品的许可证标识。" + }, + "redistribution": { + "type": "string", + "enum": [ + "allowed", + "source-pointer-only", + "verify-package-terms" + ], + "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" + }, + "listingMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "upstreamMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "branding": { + "type": "object", + "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "properties": { + "relationship": { + "type": "string", + "enum": [ + "official", + "partner", + "independent-listing" + ], + "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" + }, + "nameUsage": { + "type": "string", + "enum": [ + "owned", + "licensed", + "nominative" + ], + "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" + }, + "logoStatus": { + "type": "string", + "enum": [ + "not-used", + "license-covered", + "trademark-policy-allowed", + "permission-obtained" + ], + "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" + } + }, + "additionalProperties": false + }, + "compliance": { + "type": "object", + "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", + "required": [ + "licenseEvidencePath", + "reviewedRef", + "reviewedAt", + "reviewedBy", + "upstreamEndorsed" + ], + "properties": { + "licenseEvidencePath": { + "type": "string", + "minLength": 1, + "description": "在已审核源码或制品中定位许可证文本的相对路径。" + }, + "noticePath": { + "type": "string", + "minLength": 1, + "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" + }, + "reviewedRef": { + "type": "string", + "minLength": 1, + "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" + }, + "reviewedAt": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", + "description": "审核日期或 ISO 8601 时间戳。" + }, + "reviewedBy": { + "type": "string", + "minLength": 1, + "description": "可追溯的审核者或审核流程标识。" + }, + "upstreamEndorsed": { + "type": "boolean", + "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" + } + }, + "additionalProperties": false + }, + "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": "产品提供或消费宿主能力的关系契约;至少声明一项贡献或依赖。普通应用可仅消费,独立插件仍须提供实际贡献。" + }, + "entrypoints": { + "type": "array", + "maxItems": 32, + "items": { + "oneOf": [ + { + "type": "object", + "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", + "required": [ + "id", + "name", + "kind", + "route" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "builtin", + "description": "内置页面入口判别字段" + }, + "route": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "embedded-web", + "description": "隔离 Web 入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "external", + "description": "外部浏览器入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" + }, + "path": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "id", + "name", + "kind" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID。" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "交给 Agent 打开的入口显示名。" + }, + "kind": { + "const": "agent", + "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" + } + } + } + ], + "description": "应用的一个用户可见启动入口,按 kind 严格判别" + }, + "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" + } + }, + "allOf": [ + { + "if": { + "properties": { + "productKind": { + "const": "plugin" + } + }, + "required": [ + "productKind" + ] + }, + "then": { + "required": [ + "extension" + ], + "properties": { + "extension": { + "properties": { + "contributes": { + "minItems": 1 + } + } + } + } + }, + "else": { + "properties": { + "entrypoints": { + "minItems": 1 + } + } + } + } + ] + }, + "nativeMaintainer": { + "type": "object", + "required": [ + "name", + "url" + ], + "additionalProperties": false, + "properties": { + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "url": { + "$ref": "#/definitions/httpsUrl" + }, + "verified": { + "type": "boolean" + } + } + }, + "id": { + "type": "string", + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", + "description": "Stable entry identifier; must equal the containing directory name." + }, + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "version": { + "type": "string", + "pattern": "^[0-9]+(?:\\.[0-9]+){1,3}(?:[-+][0-9A-Za-z.-]+)?$", + "description": "Entry or client version in dotted numeric form." + }, + "httpsUrl": { + "type": "string", + "pattern": "^https://[^\\s]+$", + "description": "An HTTPS URL without embedded whitespace." + }, + "platformSupport": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "macos", + "windows", + "linux" + ] + }, + "description": "Desktop platforms on which the entry is relevant." + }, + "tags": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": "Human-readable discovery and search tags." + }, + "capabilities": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$" + } + }, + "environment": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "mcpInstall": { + "type": "object", + "required": [ + "method", + "command", + "args" + ], + "additionalProperties": false, + "properties": { + "method": { + "$ref": "#/definitions/nonEmptyString" + }, + "packageName": { + "$ref": "#/definitions/nonEmptyString" + }, + "command": { + "$ref": "#/definitions/nonEmptyString" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "postInstall": { + "type": "array", + "items": { + "$ref": "#/definitions/nonEmptyString" + } + }, + "env": { + "$ref": "#/definitions/environment" + } + } + }, + "connection": { + "type": "object", + "required": [ + "transport" + ], + "additionalProperties": false, + "properties": { + "transport": { + "type": "string", + "enum": [ + "stdio", + "streamable-http", + "sse" + ] + }, + "command": { + "$ref": "#/definitions/nonEmptyString" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "$ref": "#/definitions/nonEmptyString" + }, + "env": { + "$ref": "#/definitions/environment" + } + } + }, + "dockerApp": { + "type": "object", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "iconLetter", + "platformSupport", + "category", + "fullDesc", + "shortDesc", + "install", + "entrypoints" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "docker-app" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "iconLetter": { + "type": "string", + "minLength": 1, + "maxLength": 2 + }, + "platformSupport": { + "$ref": "#/definitions/platformSupport" + }, + "category": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$", + "description": "应用分类(slug 格式),可扩展任意分类" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "stars": { + "type": "integer", + "minimum": 0 + }, + "githubUrl": { + "$ref": "#/definitions/httpsUrl" + }, + "install": { + "type": "object", + "required": [ + "method", + "requirements", + "configNeeded" + ], + "additionalProperties": false, + "properties": { + "method": { + "type": "string", + "enum": [ + "docker", + "docker-compose" + ] + }, + "requirements": { + "type": "object", + "required": [ + "docker", + "minMemory", + "minDisk", + "ports" + ], + "additionalProperties": false, + "properties": { + "docker": { + "const": true + }, + "minMemory": { + "$ref": "#/definitions/nonEmptyString" + }, + "minDisk": { + "$ref": "#/definitions/nonEmptyString" + }, + "ports": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + } + } + }, + "configNeeded": { + "type": "array", + "items": { + "$ref": "#/definitions/nonEmptyString" + } + } + } + }, + "exposes": { + "type": "array", + "items": { + "type": "object", + "required": [ + "type", + "port", + "path", + "name" + ], + "additionalProperties": false, + "properties": { + "type": { + "const": "http-api" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "path": { + "type": "string", + "pattern": "^/" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + } + } + } + }, + "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": "产品提供或消费宿主能力的关系契约;至少声明一项贡献或依赖。普通应用可仅消费,独立插件仍须提供实际贡献。" + }, + "entrypoints": { + "type": "array", + "maxItems": 32, + "items": { + "oneOf": [ + { + "type": "object", + "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", + "required": [ + "id", + "name", + "kind", + "route" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "builtin", + "description": "内置页面入口判别字段" + }, + "route": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "embedded-web", + "description": "隔离 Web 入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "external", + "description": "外部浏览器入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" + }, + "path": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "id", + "name", + "kind" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID。" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "交给 Agent 打开的入口显示名。" + }, + "kind": { + "const": "agent", + "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" + } + } + } + ], + "description": "应用的一个用户可见启动入口,按 kind 严格判别" + }, + "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" + }, + "placementPolicy": { + "type": "object", + "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", + "required": [ + "showInMyApps", + "allowNavPin", + "allowAgentBinding" + ], + "properties": { + "showInMyApps": { + "type": "boolean", + "description": "安装后是否允许出现在“我的应用”" + }, + "allowNavPin": { + "type": "boolean", + "description": "用户是否可将应用固定到主导航" + }, + "allowAgentBinding": { + "type": "boolean", + "description": "用户是否可将应用关联到 Agent 会话侧栏" + } + }, + "additionalProperties": false + }, + "stewardship": { + "type": "string", + "enum": [ + "official", + "partner", + "community", + "pointer" + ], + "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" + }, + "availability": { + "type": "string", + "enum": [ + "listing-only", + "installable" + ], + "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" + }, + "license": { + "type": "string", + "minLength": 1, + "description": "覆盖实际制品的许可证标识。" + }, + "redistribution": { + "type": "string", + "enum": [ + "allowed", + "source-pointer-only", + "verify-package-terms" + ], + "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" + }, + "source": { + "type": "object", + "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", + "required": [ + "kind", + "url", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "git", + "release", + "package", + "container" + ], + "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "权威上游地址;不得由客户端在安装请求中替换。" + }, + "ref": { + "type": "string", + "minLength": 1, + "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$", + "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" + }, + "path": { + "type": "string", + "minLength": 1, + "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" + }, + "upstreamRepo": { + "type": "string", + "format": "uri", + "description": "制品与源码不在同一地址时对应的上游源码仓库。" + } + }, + "additionalProperties": false + }, + "listingMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "upstreamMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "branding": { + "type": "object", + "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "properties": { + "relationship": { + "type": "string", + "enum": [ + "official", + "partner", + "independent-listing" + ], + "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" + }, + "nameUsage": { + "type": "string", + "enum": [ + "owned", + "licensed", + "nominative" + ], + "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" + }, + "logoStatus": { + "type": "string", + "enum": [ + "not-used", + "license-covered", + "trademark-policy-allowed", + "permission-obtained" + ], + "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" + } + }, + "additionalProperties": false + }, + "compliance": { + "type": "object", + "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", + "required": [ + "licenseEvidencePath", + "reviewedRef", + "reviewedAt", + "reviewedBy", + "upstreamEndorsed" + ], + "properties": { + "licenseEvidencePath": { + "type": "string", + "minLength": 1, + "description": "在已审核源码或制品中定位许可证文本的相对路径。" + }, + "noticePath": { + "type": "string", + "minLength": 1, + "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" + }, + "reviewedRef": { + "type": "string", + "minLength": 1, + "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" + }, + "reviewedAt": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", + "description": "审核日期或 ISO 8601 时间戳。" + }, + "reviewedBy": { + "type": "string", + "minLength": 1, + "description": "可追溯的审核者或审核流程标识。" + }, + "upstreamEndorsed": { + "type": "boolean", + "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" + } + }, + "additionalProperties": false + } + }, + "allOf": [ + { + "if": { + "properties": { + "productKind": { + "const": "plugin" + } + }, + "required": [ + "productKind" + ] + }, + "then": { + "required": [ + "extension" + ], + "properties": { + "extension": { + "properties": { + "contributes": { + "minItems": 1 + } + } + } + } + }, + "else": { + "properties": { + "entrypoints": { + "minItems": 1 + } + } + } + } + ] + }, + "mcp": { + "type": "object", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "platformSupport", + "capabilities", + "connection" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "mcp" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "platformSupport": { + "$ref": "#/definitions/platformSupport" + }, + "capabilities": { + "$ref": "#/definitions/capabilities" + }, + "toolCount": { + "type": "integer", + "minimum": 0 + }, + "install": { + "$ref": "#/definitions/mcpInstall" + }, + "connection": { + "$ref": "#/definitions/connection" + }, + "sourceAppId": { + "$ref": "#/definitions/id" + }, + "sourceAppName": { + "$ref": "#/definitions/nonEmptyString" + } + } + }, + "httpApi": { + "type": "object", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "platformSupport", + "endpoint", + "capabilities" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "http-api" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "platformSupport": { + "$ref": "#/definitions/platformSupport" + }, + "endpoint": { + "type": "string", + "pattern": "^https?://[^\\s]+$" + }, + "capabilities": { + "$ref": "#/definitions/capabilities" + }, + "sourceAppId": { + "$ref": "#/definitions/id" + }, + "sourceAppName": { + "$ref": "#/definitions/nonEmptyString" + } + } + }, + "maintainer": { + "type": "object", + "required": [ + "name", + "url", + "verified" + ], + "additionalProperties": false, + "properties": { + "name": { + "allOf": [ + { + "$ref": "#/definitions/nonEmptyString" + } + ], + "description": "Human-readable maintainer identity." + }, + "url": { + "allOf": [ + { + "$ref": "#/definitions/httpsUrl" + } + ], + "description": "Public source used to verify the maintainer identity." + }, + "verified": { + "const": true, + "description": "The Registry maintainer verified this identity against the public source." + } + } + }, + "officialLink": { + "description": "A Kimi WebBridge upstream URL pinned by kind, hostname, path, and extension ID where applicable.", + "oneOf": [ + { + "type": "object", + "required": [ + "kind", + "label", + "url" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "product" + }, + "label": { + "$ref": "#/definitions/nonEmptyString" + }, + "url": { + "const": "https://www.kimi.ai/products/kimi-webbridge" + } + } + }, + { + "type": "object", + "required": [ + "kind", + "label", + "url" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "documentation" + }, + "label": { + "$ref": "#/definitions/nonEmptyString" + }, + "url": { + "const": "https://www.kimi.ai/help/kimi-webbridge/kimi-webbridge-introduction" + } + } + }, + { + "type": "object", + "required": [ + "kind", + "label", + "extensionId", + "url" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "chrome-web-store" + }, + "label": { + "$ref": "#/definitions/nonEmptyString" + }, + "extensionId": { + "const": "fldmhceldgbpfpkbgopacenieobmligc", + "description": "The audited Chrome Web Store extension identifier." + }, + "url": { + "const": "https://chromewebstore.google.com/detail/kimi-webbridge/fldmhceldgbpfpkbgopacenieobmligc" + } + } + }, + { + "type": "object", + "required": [ + "kind", + "label", + "extensionId", + "url" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "edge-add-ons" + }, + "label": { + "$ref": "#/definitions/nonEmptyString" + }, + "extensionId": { + "const": "bnlffdbcfnanfbknnlaflhlhkocccckg", + "description": "The audited Microsoft Edge Add-ons extension identifier." + }, + "url": { + "const": "https://microsoftedge.microsoft.com/addons/detail/kimi-webbridge/bnlffdbcfnanfbknnlaflhlhkocccckg" + } + } + }, + { + "type": "object", + "required": [ + "kind", + "label", + "url" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "privacy" + }, + "label": { + "$ref": "#/definitions/nonEmptyString" + }, + "url": { + "const": "https://www.kimi.ai/user/agreement/userPrivacy?version=v2" + } + } + }, + { + "type": "object", + "required": [ + "kind", + "label", + "url" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "terms" + }, + "label": { + "$ref": "#/definitions/nonEmptyString" + }, + "url": { + "const": "https://www.kimi.ai/user/agreement/modelUse?version=v2" + } + } + } + ] + }, + "browserExtensionComponent": { + "type": "object", + "required": [ + "kind", + "name", + "description", + "distribution", + "browsers" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "browser-extension" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "distribution": { + "const": "official-upstream-only", + "description": "DesireCore does not mirror or repackage this third-party component." + }, + "browsers": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "chrome", + "edge" + ] + }, + "allOf": [ + { + "contains": { + "const": "chrome" + } + }, + { + "contains": { + "const": "edge" + } + } + ] + } + } + }, + "localDaemonComponent": { + "type": "object", + "required": [ + "kind", + "name", + "description", + "distribution", + "platforms" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "local-daemon" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "distribution": { + "const": "official-upstream-only", + "description": "DesireCore does not mirror or repackage this third-party component." + }, + "platforms": { + "type": "array", + "minItems": 2, + "maxItems": 3, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "macos", + "windows", + "linux" + ] + }, + "allOf": [ + { + "contains": { + "const": "macos" + } + }, + { + "contains": { + "const": "windows" + } + } + ] + } + } + }, + "externalComponent": { + "description": "One strictly discriminated Kimi WebBridge physical component.", + "oneOf": [ + { + "$ref": "#/definitions/browserExtensionComponent" + }, + { + "$ref": "#/definitions/localDaemonComponent" + } + ] + }, + "artifactReview": { + "type": "object", + "required": [ + "component", + "platform", + "architecture", + "version", + "url", + "sha256", + "reviewedAt", + "reviewedBy" + ], + "additionalProperties": false, + "properties": { + "component": { + "const": "local-daemon" + }, + "platform": { + "type": "string", + "enum": [ + "macos", + "windows", + "linux" + ] + }, + "architecture": { + "type": "string", + "enum": [ + "x64", + "arm64" + ] + }, + "version": { + "$ref": "#/definitions/version" + }, + "url": { + "$ref": "#/definitions/httpsUrl" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + "reviewedAt": { + "type": "string", + "format": "date" + }, + "reviewedBy": { + "$ref": "#/definitions/nonEmptyString" + } + } + }, + "externalIntegration": { + "type": "object", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "category", + "shortDesc", + "fullDesc", + "tags", + "icon", + "platformSupport", + "requiredClientVersion", + "stewardship", + "availability", + "redistribution", + "branding", + "listingMaintainer", + "upstreamMaintainer", + "integration", + "officialLinks", + "components", + "permissions", + "profileRecommendation", + "dataBoundaries", + "admission", + "compliance" + ], + "additionalProperties": false, + "properties": { + "id": { + "const": "kimi-webbridge", + "description": "The only external-integration ID admitted by Registry Schema v4." + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "external-integration" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "category": { + "const": "tools" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "type": "string", + "enum": [ + "monitor", + "puzzle", + "globe" + ], + "description": "A neutral DesireCore icon name; upstream logos are not permitted in this listing type." + }, + "platformSupport": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "macos", + "windows" + ] + }, + "allOf": [ + { + "contains": { + "const": "macos" + } + }, + { + "contains": { + "const": "windows" + } + } + ], + "description": "The reviewed listing must support both macOS and Windows." + }, + "requiredClientVersion": { + "allOf": [ + { + "$ref": "#/definitions/version" + } + ], + "description": "Minimum DesireCore version that understands this strict listing-only entry." + }, + "stewardship": { + "const": "pointer" + }, + "availability": { + "const": "listing-only" + }, + "redistribution": { + "const": "source-pointer-only" + }, + "branding": { + "type": "object", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "additionalProperties": false, + "properties": { + "relationship": { + "const": "independent-listing" + }, + "nameUsage": { + "const": "nominative" + }, + "logoStatus": { + "const": "not-used" + } + } + }, + "listingMaintainer": { + "$ref": "#/definitions/maintainer" + }, + "upstreamMaintainer": { + "$ref": "#/definitions/maintainer" + }, + "integration": { + "type": "object", + "required": [ + "kind", + "adapterId", + "executionAvailability", + "installMode" + ], + "additionalProperties": false, + "properties": { + "kind": { + "const": "local-extension-bridge" + }, + "adapterId": { + "$ref": "#/definitions/id" + }, + "executionAvailability": { + "const": "blocked" + }, + "installMode": { + "const": "upstream-guided" + } + } + }, + "officialLinks": { + "type": "array", + "minItems": 6, + "maxItems": 6, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/officialLink" + }, + "description": "One reviewed official source for each required link kind." + }, + "components": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/externalComponent" + }, + "description": "The upstream browser extension and local daemon, neither redistributed by DesireCore." + }, + "permissions": { + "type": "object", + "required": [ + "browserExtension" + ], + "additionalProperties": false, + "properties": { + "browserExtension": { + "type": "object", + "required": [ + "apiPermissions", + "hostPermissions", + "riskLevel" + ], + "additionalProperties": false, + "properties": { + "apiPermissions": { + "type": "array", + "minItems": 7, + "maxItems": 7, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "tabs", + "activeTab", + "debugger", + "storage", + "alarms", + "tabGroups", + "windows" + ] + } + }, + "hostPermissions": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "const": "" + } + }, + "riskLevel": { + "const": "high" + } + } + } + } + }, + "profileRecommendation": { + "const": "dedicated-browser-profile" + }, + "dataBoundaries": { + "type": "object", + "required": [ + "webBridgeLocalExecution", + "desireCoreModelContext", + "modelProviderDisclosureRequired" + ], + "additionalProperties": false, + "properties": { + "webBridgeLocalExecution": { + "allOf": [ + { + "$ref": "#/definitions/nonEmptyString" + } + ], + "description": "A scoped statement of the upstream claim about the local WebBridge execution path." + }, + "desireCoreModelContext": { + "allOf": [ + { + "$ref": "#/definitions/nonEmptyString" + } + ], + "description": "A separate disclosure that content entering DesireCore context may be sent to the selected model provider." + }, + "modelProviderDisclosureRequired": { + "const": true + } + } + }, + "admission": { + "type": "object", + "required": [ + "status", + "code", + "reason", + "missingPrerequisites" + ], + "additionalProperties": false, + "properties": { + "status": { + "const": "blocked" + }, + "code": { + "const": "native-integration-not-admitted" + }, + "reason": { + "$ref": "#/definitions/nonEmptyString" + }, + "missingPrerequisites": { + "type": "array", + "minItems": 4, + "maxItems": 4, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "stable-auditable-protocol", + "integration-authorization", + "deterministic-command-receipts", + "user-interaction-pause-signal" + ] + } + } + } + }, + "compliance": { + "type": "object", + "required": [ + "reviewedAt", + "reviewedBy", + "upstreamEndorsed", + "relationshipDisclosure", + "artifactReviews" + ], + "additionalProperties": false, + "properties": { + "reviewedAt": { + "type": "string", + "format": "date" + }, + "reviewedBy": { + "$ref": "#/definitions/nonEmptyString" + }, + "upstreamEndorsed": { + "const": false + }, + "relationshipDisclosure": { + "const": "independent-listing-not-endorsed" + }, + "artifactReviews": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/artifactReview" + }, + "description": "Immutable upstream artifact audit facts; these records do not admit installation or redistribution." + } + } + } + } + }, + "artifact": { + "type": "object", + "description": "纯声明制品:由宿主读取受核验文件,不需要 Node、Docker、端口或虚假运行进程。安装仍走 Agent 材料/核验/唯一账本。", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "iconLetter", + "platformSupport", + "category", + "fullDesc", + "shortDesc", + "install", + "source", + "requiredClientVersion", + "placementPolicy", + "stewardship", + "availability", + "license", + "redistribution", + "listingMaintainer", + "upstreamMaintainer", + "branding", + "compliance", + "productKind", + "entrypoints", + "extension" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "artifact", + "description": "声明制品交付类别,与 productKind 正交。" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "iconLetter": { + "type": "string", + "minLength": 1, + "maxLength": 2 + }, + "platformSupport": { + "$ref": "#/definitions/platformSupport" + }, + "category": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$", + "description": "应用分类(slug 格式),可扩展任意分类" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "githubUrl": { + "$ref": "#/definitions/httpsUrl" + }, + "requiredClientVersion": { + "$ref": "#/definitions/version" + }, + "install": { + "type": "object", + "description": "应用安装配置:描述如何安装和部署此应用", + "required": [ + "method", + "requirements" + ], + "allOf": [ + { + "if": { + "properties": { + "method": { + "const": "native-node" + } + }, + "required": [ + "method" + ] + }, + "then": { + "properties": { + "requirements": { + "required": [ + "node" + ], + "properties": { + "docker": { + "const": false + } + } + } + } + } + }, + { + "if": { + "properties": { + "method": { + "const": "artifact" + } + }, + "required": [ + "method" + ] + }, + "then": { + "properties": { + "requirements": { + "properties": { + "docker": { + "const": false + }, + "ports": { + "maxItems": 0 + } + } + } + } + } + } + ], + "properties": { + "method": { + "const": "artifact", + "description": "按安装材料获取、核验和维护纯声明文件。" + }, + "requirements": { + "type": "object", + "description": "系统要求:安装前需满足的硬件和环境条件", + "required": [ + "docker", + "ports" + ], + "properties": { + "docker": { + "type": "boolean", + "description": "是否需要 Docker 环境" + }, + "minMemory": { + "type": "string", + "description": "发布者声明的内存要求或建议;未知时省略,不用通用默认值或当前运行用量填充。" + }, + "minDisk": { + "type": "string", + "description": "发布者声明的磁盘空间要求或建议;未知时省略,不代表实测占用。" + }, + "ports": { + "type": "array", + "description": "需要开放的端口号列表", + "items": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + }, + "node": { + "type": "string", + "minLength": 1, + "maxLength": 80, + "description": "宿主机 Node.js 版本要求;native-node 安装必填。" + }, + "envVars": { + "type": "array", + "description": "需要配置的环境变量名列表(如 API_KEY、DATABASE_URL)", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "configNeeded": { + "type": "array", + "items": { + "type": "string" + }, + "description": "安装前需准备的配置项(人类可读清单)" + } + }, + "additionalProperties": false + }, + "placementPolicy": { + "type": "object", + "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", + "required": [ + "showInMyApps", + "allowNavPin", + "allowAgentBinding" + ], + "properties": { + "showInMyApps": { + "type": "boolean", + "description": "安装后是否允许出现在“我的应用”" + }, + "allowNavPin": { + "type": "boolean", + "description": "用户是否可将应用固定到主导航" + }, + "allowAgentBinding": { + "type": "boolean", + "description": "用户是否可将应用关联到 Agent 会话侧栏" + } + }, + "additionalProperties": false + }, + "source": { + "type": "object", + "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", + "required": [ + "kind", + "url", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "git", + "release", + "package", + "container" + ], + "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "权威上游地址;不得由客户端在安装请求中替换。" + }, + "ref": { + "type": "string", + "minLength": 1, + "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$", + "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" + }, + "path": { + "type": "string", + "minLength": 1, + "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" + }, + "upstreamRepo": { + "type": "string", + "format": "uri", + "description": "制品与源码不在同一地址时对应的上游源码仓库。" + } + }, + "additionalProperties": false + }, + "stewardship": { + "type": "string", + "enum": [ + "official", + "partner", + "community", + "pointer" + ], + "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" + }, + "availability": { + "type": "string", + "enum": [ + "listing-only", + "installable" + ], + "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" + }, + "license": { + "type": "string", + "minLength": 1, + "description": "覆盖实际制品的许可证标识。" + }, + "redistribution": { + "type": "string", + "enum": [ + "allowed", + "source-pointer-only", + "verify-package-terms" + ], + "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" + }, + "listingMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "upstreamMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "branding": { + "type": "object", + "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "properties": { + "relationship": { + "type": "string", + "enum": [ + "official", + "partner", + "independent-listing" + ], + "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" + }, + "nameUsage": { + "type": "string", + "enum": [ + "owned", + "licensed", + "nominative" + ], + "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" + }, + "logoStatus": { + "type": "string", + "enum": [ + "not-used", + "license-covered", + "trademark-policy-allowed", + "permission-obtained" + ], + "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" + } + }, + "additionalProperties": false + }, + "compliance": { + "type": "object", + "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", + "required": [ + "licenseEvidencePath", + "reviewedRef", + "reviewedAt", + "reviewedBy", + "upstreamEndorsed" + ], + "properties": { + "licenseEvidencePath": { + "type": "string", + "minLength": 1, + "description": "在已审核源码或制品中定位许可证文本的相对路径。" + }, + "noticePath": { + "type": "string", + "minLength": 1, + "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" + }, + "reviewedRef": { + "type": "string", + "minLength": 1, + "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" + }, + "reviewedAt": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", + "description": "审核日期或 ISO 8601 时间戳。" + }, + "reviewedBy": { + "type": "string", + "minLength": 1, + "description": "可追溯的审核者或审核流程标识。" + }, + "upstreamEndorsed": { + "type": "boolean", + "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" + } + }, + "additionalProperties": false + }, + "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": { + "type": "object", + "required": [ + "kind" + ], + "properties": { + "kind": { + "const": "declarative", + "description": "只由宿主读取声明,不创建执行进程。" + } + }, + "additionalProperties": false + }, + "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": "产品提供或消费宿主能力的关系契约;至少声明一项贡献或依赖。普通应用可仅消费,独立插件仍须提供实际贡献。" + }, + "entrypoints": { + "type": "array", + "maxItems": 32, + "items": { + "oneOf": [ + { + "type": "object", + "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", + "required": [ + "id", + "name", + "kind", + "route" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "builtin", + "description": "内置页面入口判别字段" + }, + "route": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "embedded-web", + "description": "隔离 Web 入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "external", + "description": "外部浏览器入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" + }, + "path": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "id", + "name", + "kind" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID。" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "交给 Agent 打开的入口显示名。" + }, + "kind": { + "const": "agent", + "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" + } + } + } + ], + "description": "应用的一个用户可见启动入口,按 kind 严格判别" + }, + "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" + } + }, + "allOf": [ + { + "if": { + "properties": { + "productKind": { + "const": "plugin" + } + }, + "required": [ + "productKind" + ] + }, + "then": { + "required": [ + "extension" + ], + "properties": { + "extension": { + "properties": { + "contributes": { + "minItems": 1 + } + } + } + } + }, + "else": { + "properties": { + "entrypoints": { + "minItems": 1 + } + } + } + } + ] + }, + "appRelease": { + "type": "object", + "description": "Registry 指向固定应用 release 的兼容视图;来源归档摘要在 source.sha256,不能与 releaseDigest 交换。", + "required": [ + "schemaVersion", + "releaseDigest", + "manifestPath", + "definitionPath", + "requiredCapabilities" + ], + "properties": { + "schemaVersion": { + "const": 1, + "description": "固定 release 目录引用格式版本。" + }, + "releaseDigest": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "description": "app-release-c14n-v1 规范材料身份;不是归档文件摘要。" + }, + "manifestPath": { + "type": "string", + "const": "app-release.json", + "description": "获取并核验的包内固定 release 清单。" + }, + "definitionPath": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.?(?:/|$))(?!.*[\\\\\\x00-\\x1f])[^?#]+$", + "description": "同一 release 文件清单中的作者定义路径;相对 POSIX 路径,禁止宿主路径、穿越和 URL。" + }, + "requiredCapabilities": { + "type": "array", + "minItems": 1, + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 120 + }, + "contains": { + "const": "app-authoring-v1" + }, + "description": "获取后需要重新握手的真实能力;最低客户端版本不能代替能力支持。" + }, + "imageRefs": { + "type": "array", + "minItems": 1, + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 2048, + "pattern": "^(?:localhost|[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+)(?::[1-9][0-9]{0,4})?/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*@sha256:[a-f0-9]{64}$", + "description": "显式DNS/IPv4或localhost注册表、可选端口和repository@sha256:小写64位摘要;不能用浮动tag、shell、凭据或宿主路径。" + }, + "description": "仅容器release从同一delivery映射的固定镜像依赖;不包含登录凭据,不假定本机Docker可用。" + } + }, + "additionalProperties": false + }, + "webBundle": { + "type": "object", + "description": "固定网页包:页面到包内文件的映射在同一release清单,不执行宿主程序、不派生内部服务。", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "iconLetter", + "platformSupport", + "category", + "fullDesc", + "shortDesc", + "install", + "source", + "requiredClientVersion", + "placementPolicy", + "stewardship", + "availability", + "license", + "redistribution", + "entrypoints", + "appRelease" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "web-bundle", + "description": "与 release.delivery 一致的交付类别。" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "iconLetter": { + "type": "string", + "minLength": 1, + "maxLength": 2 + }, + "platformSupport": { + "type": "array", + "minItems": 1, + "maxItems": 4, + "uniqueItems": true, + "items": { + "enum": [ + "macos", + "windows", + "linux", + "web" + ] + }, + "description": "来源release支持的平台;运行时仍需真实宿主能力。" + }, + "category": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$", + "description": "应用分类(slug 格式),可扩展任意分类" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "githubUrl": { + "$ref": "#/definitions/httpsUrl" + }, + "requiredClientVersion": { + "$ref": "#/definitions/version" + }, + "install": { + "type": "object", + "required": [ + "method", + "requirements" + ], + "additionalProperties": false, + "description": "先获取固定 release 再由 Agent 沿既有发布/执行owner处理;不是自动安装DSL。", + "properties": { + "method": { + "const": "web-bundle", + "description": "固定应用材料的安装方式。" + }, + "requirements": { + "type": "object", + "required": [ + "docker", + "ports" + ], + "additionalProperties": false, + "description": "发布者声明的环境条件;未知资源数字省略,不是当前运行健康。", + "properties": { + "docker": { + "const": false, + "description": "此静态或宿主应用分支不安装Docker。" + }, + "ports": { + "type": "array", + "uniqueItems": true, + "maxItems": 0, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "description": "声明服务端口要求;运行时地址必须由可信执行owner提供。" + }, + "minMemory": { + "type": "string", + "minLength": 1, + "description": "实际发布材料声明的内存条件;未知省略。" + }, + "minDisk": { + "type": "string", + "minLength": 1, + "description": "实际发布材料声明的磁盘条件;未知省略。" + } + } + }, + "configNeeded": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "发布者说明的配置准备项,不包含凭据。" + } + } + }, + "placementPolicy": { + "type": "object", + "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", + "required": [ + "showInMyApps", + "allowNavPin", + "allowAgentBinding" + ], + "properties": { + "showInMyApps": { + "type": "boolean", + "description": "安装后是否允许出现在“我的应用”" + }, + "allowNavPin": { + "type": "boolean", + "description": "用户是否可将应用固定到主导航" + }, + "allowAgentBinding": { + "type": "boolean", + "description": "用户是否可将应用关联到 Agent 会话侧栏" + } + }, + "additionalProperties": false + }, + "source": { + "type": "object", + "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", + "required": [ + "kind", + "url", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "git", + "release", + "package", + "container" + ], + "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "权威上游地址;不得由客户端在安装请求中替换。" + }, + "ref": { + "type": "string", + "minLength": 1, + "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$", + "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" + }, + "path": { + "type": "string", + "minLength": 1, + "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" + }, + "upstreamRepo": { + "type": "string", + "format": "uri", + "description": "制品与源码不在同一地址时对应的上游源码仓库。" + } + }, + "additionalProperties": false + }, + "stewardship": { + "type": "string", + "enum": [ + "official", + "partner", + "community", + "pointer" + ], + "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" + }, + "availability": { + "type": "string", + "enum": [ + "listing-only", + "installable" + ], + "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" + }, + "license": { + "type": "string", + "minLength": 1, + "description": "覆盖实际制品的许可证标识。" + }, + "redistribution": { + "type": "string", + "enum": [ + "allowed", + "source-pointer-only", + "verify-package-terms" + ], + "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" + }, + "listingMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "upstreamMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "branding": { + "type": "object", + "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "properties": { + "relationship": { + "type": "string", + "enum": [ + "official", + "partner", + "independent-listing" + ], + "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" + }, + "nameUsage": { + "type": "string", + "enum": [ + "owned", + "licensed", + "nominative" + ], + "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" + }, + "logoStatus": { + "type": "string", + "enum": [ + "not-used", + "license-covered", + "trademark-policy-allowed", + "permission-obtained" + ], + "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" + } + }, + "additionalProperties": false + }, + "compliance": { + "type": "object", + "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", + "required": [ + "licenseEvidencePath", + "reviewedRef", + "reviewedAt", + "reviewedBy", + "upstreamEndorsed" + ], + "properties": { + "licenseEvidencePath": { + "type": "string", + "minLength": 1, + "description": "在已审核源码或制品中定位许可证文本的相对路径。" + }, + "noticePath": { + "type": "string", + "minLength": 1, + "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" + }, + "reviewedRef": { + "type": "string", + "minLength": 1, + "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" + }, + "reviewedAt": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", + "description": "审核日期或 ISO 8601 时间戳。" + }, + "reviewedBy": { + "type": "string", + "minLength": 1, + "description": "可追溯的审核者或审核流程标识。" + }, + "upstreamEndorsed": { + "type": "boolean", + "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" + } + }, + "additionalProperties": false + }, + "productKind": { + "const": "application", + "description": "用户自建应用;不是平台声明插件。" + }, + "entrypoints": { + "type": "array", + "maxItems": 32, + "items": { + "oneOf": [ + { + "type": "object", + "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "embedded-web", + "description": "隔离 Web 入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "id", + "name", + "kind" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID。" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "交给 Agent 打开的入口显示名。" + }, + "kind": { + "const": "agent", + "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" + } + } + } + ], + "description": "应用的一个用户可见启动入口,按 kind 严格判别" + }, + "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" + }, + "appRelease": { + "$ref": "#/definitions/appRelease" + } + }, + "allOf": [ + { + "if": { + "properties": { + "availability": { + "const": "installable" + } + }, + "required": [ + "availability" + ] + }, + "then": { + "required": [ + "branding", + "compliance", + "listingMaintainer", + "upstreamMaintainer" + ] + } + } + ] + }, + "authoredNativeApp": { + "type": "object", + "description": "带运行说明的固定宿主应用:可信执行owner核验身份,目录不保存启动命令或当前端口。", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "iconLetter", + "platformSupport", + "category", + "fullDesc", + "shortDesc", + "install", + "source", + "requiredClientVersion", + "placementPolicy", + "stewardship", + "availability", + "license", + "redistribution", + "entrypoints", + "appRelease" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "native-app", + "description": "与 release.delivery 一致的交付类别。" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "iconLetter": { + "type": "string", + "minLength": 1, + "maxLength": 2 + }, + "platformSupport": { + "type": "array", + "minItems": 1, + "maxItems": 4, + "uniqueItems": true, + "items": { + "enum": [ + "macos", + "windows", + "linux", + "web" + ] + }, + "description": "来源release支持的平台;运行时仍需真实宿主能力。" + }, + "category": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$", + "description": "应用分类(slug 格式),可扩展任意分类" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "githubUrl": { + "$ref": "#/definitions/httpsUrl" + }, + "requiredClientVersion": { + "$ref": "#/definitions/version" + }, + "install": { + "type": "object", + "required": [ + "method", + "requirements" + ], + "additionalProperties": false, + "description": "先获取固定 release 再由 Agent 沿既有发布/执行owner处理;不是自动安装DSL。", + "properties": { + "method": { + "const": "release", + "description": "固定应用材料的安装方式。" + }, + "requirements": { + "type": "object", + "required": [ + "docker", + "ports" + ], + "additionalProperties": false, + "description": "发布者声明的环境条件;未知资源数字省略,不是当前运行健康。", + "properties": { + "docker": { + "const": false, + "description": "此静态或宿主应用分支不安装Docker。" + }, + "ports": { + "type": "array", + "uniqueItems": true, + "maxItems": 32, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "description": "声明服务端口要求;运行时地址必须由可信执行owner提供。" + }, + "minMemory": { + "type": "string", + "minLength": 1, + "description": "实际发布材料声明的内存条件;未知省略。" + }, + "minDisk": { + "type": "string", + "minLength": 1, + "description": "实际发布材料声明的磁盘条件;未知省略。" + }, + "node": { + "type": "string", + "minLength": 1, + "maxLength": 80, + "description": "明确依赖Node时的版本要求,不由交付类别猜测。" + }, + "envVars": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + }, + "description": "运行环境变量名称,不包含秘密值。" + } + } + }, + "configNeeded": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "发布者说明的配置准备项,不包含凭据。" + } + } + }, + "placementPolicy": { + "type": "object", + "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", + "required": [ + "showInMyApps", + "allowNavPin", + "allowAgentBinding" + ], + "properties": { + "showInMyApps": { + "type": "boolean", + "description": "安装后是否允许出现在“我的应用”" + }, + "allowNavPin": { + "type": "boolean", + "description": "用户是否可将应用固定到主导航" + }, + "allowAgentBinding": { + "type": "boolean", + "description": "用户是否可将应用关联到 Agent 会话侧栏" + } + }, + "additionalProperties": false + }, + "source": { + "type": "object", + "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", + "required": [ + "kind", + "url", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "git", + "release", + "package", + "container" + ], + "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "权威上游地址;不得由客户端在安装请求中替换。" + }, + "ref": { + "type": "string", + "minLength": 1, + "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$", + "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" + }, + "path": { + "type": "string", + "minLength": 1, + "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" + }, + "upstreamRepo": { + "type": "string", + "format": "uri", + "description": "制品与源码不在同一地址时对应的上游源码仓库。" + } + }, + "additionalProperties": false + }, + "stewardship": { + "type": "string", + "enum": [ + "official", + "partner", + "community", + "pointer" + ], + "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" + }, + "availability": { + "type": "string", + "enum": [ + "listing-only", + "installable" + ], + "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" + }, + "license": { + "type": "string", + "minLength": 1, + "description": "覆盖实际制品的许可证标识。" + }, + "redistribution": { + "type": "string", + "enum": [ + "allowed", + "source-pointer-only", + "verify-package-terms" + ], + "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" + }, + "listingMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "upstreamMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "branding": { + "type": "object", + "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "properties": { + "relationship": { + "type": "string", + "enum": [ + "official", + "partner", + "independent-listing" + ], + "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" + }, + "nameUsage": { + "type": "string", + "enum": [ + "owned", + "licensed", + "nominative" + ], + "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" + }, + "logoStatus": { + "type": "string", + "enum": [ + "not-used", + "license-covered", + "trademark-policy-allowed", + "permission-obtained" + ], + "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" + } + }, + "additionalProperties": false + }, + "compliance": { + "type": "object", + "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", + "required": [ + "licenseEvidencePath", + "reviewedRef", + "reviewedAt", + "reviewedBy", + "upstreamEndorsed" + ], + "properties": { + "licenseEvidencePath": { + "type": "string", + "minLength": 1, + "description": "在已审核源码或制品中定位许可证文本的相对路径。" + }, + "noticePath": { + "type": "string", + "minLength": 1, + "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" + }, + "reviewedRef": { + "type": "string", + "minLength": 1, + "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" + }, + "reviewedAt": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", + "description": "审核日期或 ISO 8601 时间戳。" + }, + "reviewedBy": { + "type": "string", + "minLength": 1, + "description": "可追溯的审核者或审核流程标识。" + }, + "upstreamEndorsed": { + "type": "boolean", + "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" + } + }, + "additionalProperties": false + }, + "productKind": { + "const": "application", + "description": "用户自建应用;不是平台声明插件。" + }, + "entrypoints": { + "type": "array", + "maxItems": 32, + "items": { + "oneOf": [ + { + "type": "object", + "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", + "required": [ + "id", + "name", + "kind", + "route" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "builtin", + "description": "内置页面入口判别字段" + }, + "route": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "embedded-web", + "description": "隔离 Web 入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "external", + "description": "外部浏览器入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" + }, + "path": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "id", + "name", + "kind" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID。" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "交给 Agent 打开的入口显示名。" + }, + "kind": { + "const": "agent", + "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" + } + } + } + ], + "description": "应用的一个用户可见启动入口,按 kind 严格判别" + }, + "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" + }, + "appRelease": { + "$ref": "#/definitions/appRelease" + } + }, + "allOf": [ + { + "if": { + "properties": { + "availability": { + "const": "installable" + } + }, + "required": [ + "availability" + ] + }, + "then": { + "required": [ + "branding", + "compliance", + "listingMaintainer", + "upstreamMaintainer" + ] + } + } + ] + }, + "authoredDockerApp": { + "type": "object", + "description": "固定容器镜像依赖的release应用:使用原Docker执行/服务owner,不新建容器管理器;缺真实身份adapter时不声称直开。", + "required": [ + "id", + "name", + "type", + "version", + "author", + "description", + "tags", + "icon", + "iconLetter", + "platformSupport", + "category", + "fullDesc", + "shortDesc", + "install", + "source", + "requiredClientVersion", + "placementPolicy", + "stewardship", + "availability", + "license", + "redistribution", + "entrypoints", + "appRelease" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/id" + }, + "name": { + "$ref": "#/definitions/nonEmptyString" + }, + "type": { + "const": "docker-app", + "description": "与 release.delivery 一致的交付类别。" + }, + "version": { + "$ref": "#/definitions/version" + }, + "author": { + "$ref": "#/definitions/nonEmptyString" + }, + "description": { + "$ref": "#/definitions/nonEmptyString" + }, + "tags": { + "$ref": "#/definitions/tags" + }, + "icon": { + "$ref": "#/definitions/nonEmptyString" + }, + "iconLetter": { + "type": "string", + "minLength": 1, + "maxLength": 2 + }, + "platformSupport": { + "type": "array", + "minItems": 1, + "maxItems": 4, + "uniqueItems": true, + "items": { + "enum": [ + "macos", + "windows", + "linux", + "web" + ] + }, + "description": "来源release支持的平台;运行时仍需真实宿主能力。" + }, + "category": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z0-9-]+$", + "description": "应用分类(slug 格式),可扩展任意分类" + }, + "fullDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "shortDesc": { + "$ref": "#/definitions/nonEmptyString" + }, + "githubUrl": { + "$ref": "#/definitions/httpsUrl" + }, + "requiredClientVersion": { + "$ref": "#/definitions/version" + }, + "install": { + "type": "object", + "required": [ + "method", + "requirements" + ], + "additionalProperties": false, + "description": "先获取固定 release 再由 Agent 沿既有发布/执行owner处理;不是自动安装DSL。", + "properties": { + "method": { + "const": "release", + "description": "固定应用材料的安装方式。" + }, + "requirements": { + "type": "object", + "required": [ + "docker", + "ports" + ], + "additionalProperties": false, + "description": "发布者声明的环境条件;未知资源数字省略,不是当前运行健康。", + "properties": { + "docker": { + "const": true, + "description": "此静态或宿主应用分支不安装Docker。" + }, + "ports": { + "type": "array", + "uniqueItems": true, + "maxItems": 32, + "items": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "description": "声明服务端口要求;运行时地址必须由可信执行owner提供。" + }, + "minMemory": { + "type": "string", + "minLength": 1, + "description": "实际发布材料声明的内存条件;未知省略。" + }, + "minDisk": { + "type": "string", + "minLength": 1, + "description": "实际发布材料声明的磁盘条件;未知省略。" + }, + "node": { + "type": "string", + "minLength": 1, + "maxLength": 80, + "description": "明确依赖Node时的版本要求,不由交付类别猜测。" + }, + "envVars": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + }, + "description": "运行环境变量名称,不包含秘密值。" + } + } + }, + "configNeeded": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "发布者说明的配置准备项,不包含凭据。" + } + } + }, + "placementPolicy": { + "type": "object", + "description": "目录维护者声明的可放置范围;只限制能力,不能替用户自动固定或绑定", + "required": [ + "showInMyApps", + "allowNavPin", + "allowAgentBinding" + ], + "properties": { + "showInMyApps": { + "type": "boolean", + "description": "安装后是否允许出现在“我的应用”" + }, + "allowNavPin": { + "type": "boolean", + "description": "用户是否可将应用固定到主导航" + }, + "allowAgentBinding": { + "type": "boolean", + "description": "用户是否可将应用关联到 Agent 会话侧栏" + } + }, + "additionalProperties": false + }, + "source": { + "type": "object", + "description": "经过审核的上游来源指针;安装时必须进一步证明 ref 或制品摘要不可变。", + "required": [ + "kind", + "url", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "enum": [ + "git", + "release", + "package", + "container" + ], + "description": "上游来源类型:Git 仓库、Release 制品、包管理器制品或容器镜像。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "权威上游地址;不得由客户端在安装请求中替换。" + }, + "ref": { + "type": "string", + "minLength": 1, + "description": "审核版本引用;安装候选必须是完整 commit、制品版本或容器 digest。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-fA-F0-9]{64}$", + "description": "Release、package 或其他下载响应体的 SHA-256 摘要。" + }, + "path": { + "type": "string", + "minLength": 1, + "description": "单仓库目录中的相对路径;不得作为运行时任意本地路径使用。" + }, + "upstreamRepo": { + "type": "string", + "format": "uri", + "description": "制品与源码不在同一地址时对应的上游源码仓库。" + } + }, + "additionalProperties": false + }, + "stewardship": { + "type": "string", + "enum": [ + "official", + "partner", + "community", + "pointer" + ], + "description": "条目治理身份:official 仅能由受信 official catalog provider 注入;partner/community/pointer 分别表示合作方、社区维护或纯上游指针。" + }, + "availability": { + "type": "string", + "enum": [ + "listing-only", + "installable" + ], + "description": "目录可用性:listing-only 仅允许浏览上游;installable 才允许进入既有受治理获取流程,不表示已经安装或正在运行。" + }, + "license": { + "type": "string", + "minLength": 1, + "description": "覆盖实际制品的许可证标识。" + }, + "redistribution": { + "type": "string", + "enum": [ + "allowed", + "source-pointer-only", + "verify-package-terms" + ], + "description": "内容转交策略:allowed 可按许可证分发;source-pointer-only 只能从权威上游取得;verify-package-terms 表示条款尚未完成复核。" + }, + "listingMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "upstreamMaintainer": { + "type": "object", + "description": "目录策展者或上游维护者身份;两种角色必须分别存放,不能把 author 当成已验证维护者。", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "description": "维护者的公开名称或组织名称。" + }, + "url": { + "type": "string", + "format": "uri", + "description": "维护者的公开主页、项目主页或可验证身份页面。" + }, + "verified": { + "type": "boolean", + "description": "平台是否已验证该身份;不等同于许可证授权、内容审核或上游背书。" + } + }, + "additionalProperties": false + }, + "branding": { + "type": "object", + "description": "名称、Logo 和官方关系的展示依据;代码许可证不能自动授予商标或宣传素材权利。", + "required": [ + "relationship", + "nameUsage", + "logoStatus" + ], + "properties": { + "relationship": { + "type": "string", + "enum": [ + "official", + "partner", + "independent-listing" + ], + "description": "与上游的公开关系:官方、已确认合作,或独立事实索引。" + }, + "nameUsage": { + "type": "string", + "enum": [ + "owned", + "licensed", + "nominative" + ], + "description": "项目名称的使用依据:自有、已获许可,或识别上游所需的指称性使用。" + }, + "logoStatus": { + "type": "string", + "enum": [ + "not-used", + "license-covered", + "trademark-policy-allowed", + "permission-obtained" + ], + "description": "Logo 使用依据;未确认权利时必须为 not-used,并由客户端使用中性图标。" + } + }, + "additionalProperties": false + }, + "compliance": { + "type": "object", + "description": "绑定到本次不可变来源的合规审核记录;新版本必须重新审核,不能继承旧版本结论。", + "required": [ + "licenseEvidencePath", + "reviewedRef", + "reviewedAt", + "reviewedBy", + "upstreamEndorsed" + ], + "properties": { + "licenseEvidencePath": { + "type": "string", + "minLength": 1, + "description": "在已审核源码或制品中定位许可证文本的相对路径。" + }, + "noticePath": { + "type": "string", + "minLength": 1, + "description": "需要履行 NOTICE 或署名义务时,对应材料的相对路径。" + }, + "reviewedRef": { + "type": "string", + "minLength": 1, + "description": "实际完成许可证、品牌和供应链复核的不可变 ref,必须与获取来源一致。" + }, + "reviewedAt": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}(?:T.*)?$", + "description": "审核日期或 ISO 8601 时间戳。" + }, + "reviewedBy": { + "type": "string", + "minLength": 1, + "description": "可追溯的审核者或审核流程标识。" + }, + "upstreamEndorsed": { + "type": "boolean", + "description": "上游是否明确认可该条目;false 时必须显示非官方、未经背书声明。" + } + }, + "additionalProperties": false + }, + "productKind": { + "const": "application", + "description": "用户自建应用;不是平台声明插件。" + }, + "entrypoints": { + "type": "array", + "maxItems": 32, + "items": { + "oneOf": [ + { + "type": "object", + "description": "DesireCore 自带并随客户端发布的页面入口;第三方目录不得伪造此入口类型", + "required": [ + "id", + "name", + "kind", + "route" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "builtin", + "description": "内置页面入口判别字段" + }, + "route": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "客户端内置路由;必须是单斜杠开头的相对应用路由,不能是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由隔离 App Host 承载的 Web 应用入口,运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "embedded-web", + "description": "隔离 Web 入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID 或服务端生成的本机端口引用;不是 URL" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "description": "由系统浏览器打开的目录声明入口;运行时 URL 只可由服务端从 serviceRef 解析", + "required": [ + "id", + "name", + "kind", + "serviceRef" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "入口显示名称" + }, + "kind": { + "const": "external", + "description": "外部浏览器入口判别字段" + }, + "serviceRef": { + "type": "string", + "minLength": 1, + "maxLength": 240, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "Registry 服务 ID;不是 URL,解析结果还需 HTTPS 或本机 loopback 校验" + }, + "path": { + "type": "string", + "minLength": 1, + "maxLength": 512, + "pattern": "^/(?!/)", + "description": "可选服务内路径;解析层禁止凭据、反斜杠和目录穿越" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "id", + "name", + "kind" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1, + "maxLength": 160, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._:-]*$", + "description": "应用内稳定入口 ID。" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 120, + "description": "交给 Agent 打开的入口显示名。" + }, + "kind": { + "const": "agent", + "description": "读取实例维护资料后委派 Agent;无需服务端口或标准启动接口。" + } + } + } + ], + "description": "应用的一个用户可见启动入口,按 kind 严格判别" + }, + "description": "明确用户入口;plugin 允许空数组,普通应用至少一个入口。" + }, + "appRelease": { + "$ref": "#/definitions/appRelease" + } + }, + "allOf": [ + { + "if": { + "properties": { + "availability": { + "const": "installable" + } + }, + "required": [ + "availability" + ] + }, + "then": { + "required": [ + "branding", + "compliance", + "listingMaintainer", + "upstreamMaintainer" + ] + } + }, + { + "properties": { + "appRelease": { + "required": [ + "imageRefs" + ] + } + } + } + ] + } + } +} diff --git a/scripts/application-authoring.test.mjs b/scripts/application-authoring.test.mjs index f94dca4..99bd7ef 100644 --- a/scripts/application-authoring.test.mjs +++ b/scripts/application-authoring.test.mjs @@ -11,21 +11,24 @@ import { validateApplicationReleaseContract } from './catalog/application-releas const source = join(dirname(fileURLToPath(import.meta.url)),'..') const temporary = [] afterEach(() => { for (const root of temporary.splice(0)) rmSync(root,{recursive:true,force:true}) }) -const schema = JSON.parse(readFileSync(join(source,'schemas/registry-entry.schema.json'),'utf8')) +const schema = JSON.parse(readFileSync(join(source,'schemas/registry-entry.v4.3.schema.json'),'utf8')) const validate = new Ajv({allErrors:true,strict:true,strictTypes:false,strictRequired:false,validateFormats:false}).compile(schema) const load = id => JSON.parse(readFileSync(join(source,'fixtures/authoring/entries',id,'manifest.json'),'utf8')) -test('4.3只新增兼容与合成fixtures,正式目录仍无web-bundle或appRelease条目',() => { +test('4.3只新增候选文件和合成fixtures,正式4.2目录不提前激活新格式',() => { const root = JSON.parse(readFileSync(join(source,'manifest.json'),'utf8')) - assert.equal(root.version,'4.3.0') + assert.equal(root.version,'4.2.0') + assert.equal(readFileSync(join(source,'SCHEMA_VERSION'),'utf8').trim(),'4.2.0') assert.equal(root.stats.totalEntries,24) assert.equal(root.stats.webBundles,undefined) }) test('静态与带服务合成目录三文件保持App语义,两个validator同样通过',() => { const root = mkdtempSync(join(tmpdir(),'registry-authoring-'));temporary.push(root) cpSync(join(source,'schemas'),join(root,'schemas'),{recursive:true}) + cpSync(join(source,'schemas/registry-entry.v4.3.schema.json'),join(root,'schemas/registry-entry.schema.json')) cpSync(join(source,'fixtures/authoring/entries'),join(root,'entries'),{recursive:true}) const manifest = JSON.parse(readFileSync(join(source,'manifest.json'),'utf8')) + manifest.version='4.3.0';manifest.dataVersion='4.3.0' manifest.stats={totalEntries:3,dockerApps:1,nativeApps:1,webBundles:1,mcpServices:0,httpApis:0,externalIntegrations:0} writeFileSync(join(root,'manifest.json'),JSON.stringify(manifest));writeFileSync(join(root,'SCHEMA_VERSION'),'4.3.0\n') const report = validateRegistry(root)