关于 build-and-deploy
用于打包 Even Hub G2 应用的 Skill,涵盖 app.json 校验、构建、生成 .ehpk 文件、验证及提交开发者门户。
主要功能
- 01校验 app.json 字段与权限
- 02执行构建和打包命令
- 03验证 .ehpk 输出文件
- 04说明 WebView 的 CORS 要求
- 05排查打包错误
适用场景
- 01打包前检查应用元数据
- 02构建并准备 Even Hub 应用
- 03诊断输出文件缺失或无效
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ even-realities/ everything-evenhub --skill build-and-deploy安装后在 Claude Code 中输入/build-and-deploy确认已加载。
详细介绍
你正在为分发打包 Even Hub G2 应用。请仔细按照以下步骤操作,并在继续之前验证每个阶段。
打包工作流
按顺序执行以下步骤:
步骤 1 — 验证 app.json
- 在项目根目录中找到
app.json。 - 读取文件,并根据下方的字段参考验证每个字段。
- 如果有字段缺失、类型错误或不符合验证规则,请报告确切错误并修正(如果修正会更改
package_id或name等有实际意义的值,请先征得用户确认)。 - 确认
app.json有效后再继续。
步骤 2 — 构建
在项目根目录运行构建命令:
npm run build
检查构建是否成功(退出代码为 0),以及输出文件夹(通常为 dist/)是否存在且不为空。
步骤 3 — 打包为 .ehpk
运行打包命令,将 <name> 替换为应用名称:
npx evenhub pack app.json dist -o <name>.ehpk
使用 app.json 中 name 字段的值(转换为小写,并将空格替换为连字符)作为 <name>。例如,如果 name 为 "Weather Now",则使用 weather-now.ehpk。
步骤 4 — 验证输出
确认已创建 .ehpk 文件:
ls -lh <name>.ehpk
如果文件不存在,请检查打包命令的错误输出,并参阅下方的故障排除表。
步骤 5 — 分发
将 .ehpk 文件提交至 Even Hub 开发者门户,以供审核和发布。
app.json 字段参考
除非另有说明,否则所有字段均为必填项。运行 evenhub pack 前,请验证每个字段。
| 字段 | 类型 | 必填 | 验证规则 |
|---|---|---|---|
package_id | string | 是 | 反向域名格式(例如 com.example.myapp)。仅允许小写字母和数字——不得包含连字符、大写字母或下划线。至少包含 2 个以点分隔的片段。每个片段必须以小写字母开头,且只能包含小写字母或数字。 |
edition | string | 是 | 必须恰好为 "202601"。 |
name | string | 是 | 最多 20 个字符。 |
version | string | 是 | Semver 格式 x.y.z——由点分隔的 3 个数字部分(例如 "1.0.0")。不得带 v 前缀或预发布后缀。 |
min_app_version | string | 是 | 所需的 Even Hub 应用最低版本。例如 "2.0.0"。 |
min_sdk_version | string | 是 | 所需的最低 SDK 版本。须与构建时使用的 SDK 版本一致(当前为 "0.0.12")。 |
entrypoint | string | 是 | 相对于构建输出文件夹的入口 HTML/JS 文件路径。运行 npm run build 后,该文件必须存在于构建输出中。 |
permissions | array | 是 | 权限对象数组(参阅“权限参考”)。可以为空 []。不得使用键值映射。 |
supported_languages | array | 是 | 受支持语言集中的 BCP 47 语言代码数组。有效值:en、de、fr、es、it、zh、ja、ko。 |
有效 app.json 最简示例
{
"package_id": "com.example.weatherapp",
"edition": "202601",
"name": "Weather Now",
"version": "1.0.0",
"min_app_version": "2.0.0",
"min_sdk_version": "0.0.12",
"entrypoint": "index.html",
"permissions": [],
"supported_languages": ["en"]
}
权限参考
permissions 必须是对象数组。每个对象包含:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 下方列出的有效权限名称之一。 |
desc | string | 是 | 易于理解的描述,长度为 1–300 个字符。 |
whitelist | string[] | 仅适用于 network | 允许访问的 URL 列表。name 为 "network" 时必填。 |
有效权限名称
network— 出站网络访问(需要whitelist)location— 设备 GPS/位置信息g2-microphone— G2 眼镜上的麦克风phone-microphone— 配对手机上的麦克风album— 访问相册camera— 访问相机
示例
"permissions": [
{
"name": "network",
"desc": "Fetches weather data from the API.",
"whitelist": ["https://api.weather.com"]
},
{
"name": "g2-microphone",
"desc": "Enables voice commands for hands-free control."
}
]
常见错误
请勿使用键值映射格式:
// WRONG
"permissions": { "network": ["example.com"] }
// CORRECT
"permissions": [{ "name": "network", "desc": "...", "whitelist": ["example.com"] }]
WebView 中的 CORS
Even App 会在真实的浏览器引擎中运行你的插件(Android 上使用 Chromium,iOS 上使用 WKWebView)。CORS 会完整生效。app.json 中的网络白名单是 Even 级别的权限检查,不会绕过 CORS。你需要同时满足以下两项:
- 在
app.json的permissions.network.whitelist中将域名加入白名单,并且 - 远程 API 返回正确的 CORS 标头(
Access-Control-Allow-Origin等)。
如果你调用的 API 不发送 CORS 标头,即使域名已加入白名单,fetch() 仍会因网络错误而失败。
| 场景 | 解决方法 |
|---|---|
| API 有 CORS 标头 | 只需将域名加入 app.json 白名单即可正常使用 |
| API 没有 CORS 标头 | 使用你自己的后端、Cloudflare Worker 代理(免费套餐),或寻找启用了 CORS 的镜像 |
| 开发服务器(localhost)因 CORS 被拦截 | 在 vite.config.ts 中添加 Vite 代理,见下文 |
Vite 开发代理
使用 Vite 代理,避免本地开发期间出现 CORS 问题:
// vite.config.ts
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/api/, ''),
},
},
},
})
此代理仅在开发环境中有效。对于生产环境的 .ehpk,WebView 会直接发送请求,因此你的 API 必须提供 CORS 标头,或者你必须通过自己的代理进行路由。
免费 CORS 代理服务不可靠
corsproxy.io、allorigins.win 和 api.codetabs.com 等公共代理可能会宕机、返回 403,或在没有警告的情况下超时。如果你的应用依赖不支持 CORS 的第三方 API,请部署自己的 Cloudflare Worker(免费套餐,设置约需 5 分钟),或寻找原生提供 CORS 标头的镜像。
evenhub pack 选项
npx evenhub pack <app.json> <build-folder> [options]
| 选项 | 说明 |
|---|---|
-o <file> / --output <file> | 输出文件名。若未指定,默认为 out.ehpk。 |
--no-ignore | 将点文件和其他通常会被忽略的文件包含在包中。 |
-c / --check | 打包前检查 package_id 在 Even Hub 商店中是否可用。 |
故障排除
| 错误 | 解决方法 |
|---|---|
Invalid package id | 使用小写的反向域名格式,至少包含 2 个以点分隔的部分。不能有连字符、大写字母或下划线,且各部分不能以数字开头。例如:com.example.myapp。 |
name: must be 20 characters or fewer | 将 app.json 中的 name 值缩短至 20 个字符以内。 |
version: must be in x.y.z format | 使用由三部分组成的数字语义化版本字符串,例如 "1.0.0"。不要使用 "1.0"、"v1.0.0" 或预发布标签。 |
min_app_version: expected string, received undefined | 必须提供 min_app_version。将其添加到 app.json 中(例如 "2.0.0")。 |
min_sdk_version: expected string, received undefined | 必须提供 min_sdk_version。将其添加到 app.json 中(例如 "0.0.12")。 |
permissions: each permission must be an object with name and desc keys | permissions 必须是一个对象数组,且每个对象都包含 name 和 desc。请参阅上方的权限参考。 |
supported_languages: invalid language | 仅使用受支持的小写 ISO 代码:en、de、fr、es、it、zh、ja、ko。 |
Entrypoint file not found | 运行 npm run build 后,确保 app.json 中的 entrypoint 指向构建输出文件夹中存在的文件。 |
Project folder not found | 构建输出文件夹不存在。先运行 npm run build,然后重试 evenhub pack。 |
分发
验证 .ehpk 文件后,将其提交至 Even Hub 开发者门户进行审核和发布。门户会验证该包、运行兼容性检查,并在审核通过后向 Even Hub G2 用户提供此应用。
任务
$ARGUMENTS