可移植红线
卡是要在别人机器上活的东西。三类内容绝不入卡:
| 禁入 | 为什么 | 正确归宿 |
|---|---|---|
| 密钥值(API key、token、密码) | 泄漏;且别人的 key 本来就该是别人的 | 卡只声明密钥 id(requires.secrets),值走本机密钥库 |
本机绝对路径(/…、~…、C:\…) | 在别人机器上是死路径,还泄露你的目录结构 | 机器特定资产归插件的本机设置;卡内资源用卡内相对路径 |
| 机器特定配置(端点地址、端口、浏览器 profile 目录) | 「这台机器怎么配」不是卡的知识 | runtime.endpoints 只声明需要什么,值落本机设置 |
导出时的自动剥离
导出 .channekcard 时,系统会自动剥掉已知的机器特定字段,并在导出向导里逐项告知剥了什么:
voice.profiles.*.modelPath(已弃用的本机模型路径);- 音色档里任何绝对路径值——递归扫描,藏在几层嵌套下的也剥;
publish.profileDir(浏览器登录态目录);config段里的绝对路径值。
同时,导出会把 layout.preset 就地展开:一张 layout 只写 preset 引用的卡,目录结构其实活在导出这台机器的 preset 提供者里——别人机器上未必有同名 preset。展开后卡自带 contentDir / sections / artifacts / cardAssets / detect,跨机器、跨版本都成立。
注意
自动剥离是兜底,不是许可。剥离只认识已知的字段形状,你塞进自定义 metadata 深处的路径它可能够不着;而且被剥掉的字段说明你的卡在本机与分发版之间行为不一致——从一开始就不写,才是干净的做法。
schema 层的前置拦截
一部分红线在写卡时就会被 schema 拒绝,不用等到导出:
- 卡内资源引用(
cardAssets库路径、meta.icon、bundle.demo.path等)必须是遏制在卡根内的相对路径——绝对路径、盘符、含..的逃根段直接校验失败; runtime.endpoints里出现值键(url/port/apiKey/token/headers等)直接校验失败;meta.homepage/repository等外链只放行http(s)——javascript:/file:/data:都是可执行或本机 scheme,一律拒。
自查清单
发布前把这几条过一遍:
- 全卡搜一遍你的用户名、家目录片段、内网地址——出现即违规;
- 提示词与文档(它们 会原样打包)里有没有写死本机信息;
requires是否用「能力 + 插件」表达依赖,而不是描述你机器的现状;- 导出向导报告的
stripped列表——理想状态是空,每一条都说明有字段该挪去插件设置。