Numable 创作文档同一份内容也在终端里:`numable docs <主题>`English

publish —— 从个人自用到上架

读者:做工具的用户,和替他干活的 AI。两者读同一份。

目标

把一个自己在用的包,变成商店里别人能装、能看懂、装完不会一脸问号的包,然后发出去。

发布这个动作不在 CLI 里:CLI 只负责把包检到能发的状态(check --profile publish 零 error),签名与上传由桌面 App(Mac / Windows)工作台的发布面板完成 —— 那里有你的登录身份和签名能力。

前置

  1. 包在 personal 档已经零 error(numable docs first-card 走完)。
  2. 桌面 App 里已登录 —— 未登录发布面板会直接提示「需登录后才能发布」。
  3. 包是你自己在工作区目录里创作的那份,不是从商店装下来的别人的包。

步骤 1 · 弄清两档差在哪

numable check 有两档。personal 档跳过九段闸,它们全是「不影响包能不能跑,只影响别人能不能用」的东西 —— 靠自觉的结果就是一条都不会做,所以只有闸能挡住。

段 publish 档多要求什么 不做的后果
G6 组件档位 每包 ≥3 个 .xwidget,其中必须有一张 22 档,以及一张 42 或 44 档 22 是桌面小组件的最小档,没有就上不了桌面;只有小组件的包在仪表盘上撑不起一屏
G11 / G11b 身份资产 包根有 logo.png,512×512 正方形,满幅、自己不烤圆角 缺图回落成首字母图标;自己烤了圆角,宿主还会再裁一次,两条弧对不齐,不透明底还会在四角漏出一圈底色
G19 商店门面 manifest.subtitle 必填且 ≤22 字;manifest.i18n["en-US"].title 与 .subtitle 必备 没有副标题,商店行只能长成「名字 + 版本号」;没有英文,英文用户看到的是一列中文
G24 添加组件入口(与 G19 同段) 添加组件入口是一个按钮(pickWidgets),不是在页面里手抄一份组件目录;别写「已添加」 手抄的目录与真组件目录两份真相,新增组件忘了改页面用户就永远加不到;加没加成功只有面板知道,包里那句「已添加」会撒谎
G20 组件标题英文 每个 .xwidget 的 i18n["en-US"].title 与 .sub 英文环境下仪表盘组件标题、组件面板、桌面小组件配置列表这几处显示中文
G21 包名宽度 每个语言门的 title 显示宽 ≤24(全角算 2、半角算 1),建议 ≤16;manifest.i18n 结构合法、category 用平台枚举 key 工具宫格瓦片标题恒两行,超出的部分不是不显示是被省略号吃掉,用户看到一个认不出的半截名字
G8 / G8b 内容双语 包里的文案表(.rcn 的 rc.i18n、.xpage / .af / .xform 顶层 i18n)zh-CN 与 en-US 两门 key 齐全;用户可见字段里的中文硬编码提出来做 key 英文环境下组件上露中文;缺 key 那一处直接渲出字面量
G23 首屏缓存 有详情页的包:页面消费的 .df 要有 data.get / data.set 三态缓存(有缓存先渲、后台校新、下拉穿透、失败不覆盖);带缓存的页面根节点要有 events.onRefresh;组件消费的那条 .df 缓存写回必须由入参开关控制且默认关;缓存里不许有凭证 首屏每次白等一轮网络;下拉刷新又命中缓存,刷了等于没刷;组件那边刷新意图就是「跳过缓存直取」,数据层再压一层缓存 = 整条刷新链空转
G25 凭证直达入口 声明了 required: true 凭证的包,page/ 里要有一处直达 numable://app/mine?section=credentials 的入口 用户装完看到一个空组件,不知道去哪里绑密钥;「先加组件再按组件上提示连接」是绕路,不算入口
G27 添加组件按钮版式 添加组件按钮用平台基准版式(高度、宽度、形态、颜色都不自定义) 加组件是平台动作,用户在任何一个包里都该一眼认出它;各包各画的结果是同一个按钮长出六种样子

除此之外,两档都跑的闸(结构、白名单闭合、DSL 静默失效、路由与凭证声明)一条不少。完整码表见 numable docs lint-codes。


步骤 2 · 跑全闸,逐条修

命令

numable check hn --profile publish

看到什么算对:目标是 0 error。刚从 personal 档过来时通常长这样:

静态闸 · 档位 publish(上线标准全闸)

── HN 榜首 (hn) ──
✗ [01M200QWNNX1RFPNTX5S7M8PGW] 只有 1 个组件,标准要求 ≥3
✗ [01M200QWNNX1RFPNTX5S7M8PGW] 没有 42/44 档组件(标准要求至少一个宽幅档)
! [01M200QWNNX1RFPNTX5S7M8PGW] 无 logo.png —— 会回落首字母图标
· [01M200QWNNX1RFPNTX5S7M8PGW] 1 组件 · layout[22] · 5KB · net[hn.algolia.com]

✗ check 完成: 2 error / 1 warn

逐条修的顺序建议:

  1. 补组件(G6)。别把同一个组件换个尺寸交差 —— 宽组件应该多回答一点东西(榜前几条、带趋势条),不是把小组件拉宽。补完每个组件都要重走一遍 run → render → 三态图。
  2. 出 logo(G11)。512×512,内容铺满整块画布,四角不要留白也不要自己做圆角。
  3. 补商店门面(G19 / G21)。subtitle 一句话说清「这个包给我什么」,≤22 字;title 短到一行能读完。英文不是把中文机翻一遍,是重写一句英文用户读得懂的。
  4. 补英文(G20 / G8)。每个 .xwidget 一组 title / sub;每张 .rcn 的 rc.i18n 两门齐平。做法见 numable docs localize。
  5. 首屏缓存(G23)、凭证入口(G25)、添加组件按钮(G24 / G27)—— 只有带详情页 / 带凭证 / 带添加组件入口的包才会碰到。

警告(!)不挡发布,但要逐条看过。有几条警告的含义是「现在能用,英文用户 / 小屏用户看到的不是你以为的样子」。

修完复验两层:

numable run hn
numable render hn --locales zh-CN,en-US

英文那一列渲出来还是中文,说明文案表没接上;组件上出现 ${@i18n.xxx} 字面量,说明那个 key 在这一门里缺了。

发布前 · 把上屏文案再读一遍

check 管的是能不能跑,管不了话说得好不好。发给别人用之前,把组件、页面、提醒里用户看得到的每一句按下面几条过一遍:


步骤 3 · 在 App 工作台里发布

CLI 不发布。到桌面 App(Mac / Windows)→ 工作台 → 找到这个包 → 发布。

面板上有三处要看:

项 说明
版本 默认勾「发布为 v(下一版)」。同一个 (id, version) 只能发一次,重传会被挡下。内容改了就让它 +1
分发区域 只读,由平台决定:第一次发布进海外(中国大陆以外);要进中国大陆,需要平台审核后设定;以后每一版沿用线上那一版的区域。在中国大陆暂不能发布工具,面板会提示「中国大陆暂不支持发布工具」
过闸 点发布后面板会先跑一遍静态闸,用的就是 --profile publish 那一份规则。有 error 直接挡下并逐条列出来,不会上传

上传成功后面板有两种结果:

发布是外发动作:包里每一个字节都会被签名分发到所有用户。发之前确认包里没有密钥、没有本机夹具、没有私人数据 —— .numable/ 目录天然不进包,凭证走 manifest.credentials 声明而不是写在文件里(见 numable docs credentials)。


步骤 4 · 发布之后

包怎么到用户手上

上传时包被封成一个签过名的 .xbundle。用户在商店里点安装 → 客户端下载 → 校验签名与文件哈希 → 解压落盘 → 本地渲染。数据始终是用户设备自己去取的,不经过服务端中转。

更新靠 version +1

App 比对商店里的版本号与已装的版本号,高了才提示更新。manifest.version 不 +1 就重发,等于没发:更新不会被发现,已装的用户永远停在旧版。发新版之前把改动在 run / render 两层都复验一遍 —— 用户装的是包的全部内容,不是你改的那几个文件。

你的源目录和已发布的那一版是两份

你工作区目录里的那份是源,它不会被已发布的版本覆盖,也不会出现在更新红点里(更新只认从商店装下来的包)。所以:

组件的文件名就是它的身份

用户仪表盘上的每个组件,记的是「哪个包 + 哪个 .xwidget 文件名」。新版本删掉或改名了某个 .xwidget,用户盘上引用它的组件会显示「组件已下线」,并在包更新时被清掉。所以组件文件名定下来就别改;要换一个组件,新增一个文件,旧的保留或确认可以让用户失去它再删。

扩大访问范围的版本不会自动装上

用户默认开着「自动更新工具」,但新版本如果比用户已装的版本多访问了网站(manifest.network)、多用了凭证(新的 credentials[].id,或同一个凭证要发往新的网站)、或多了后台任务,就不会静默更新:用户要点更新,在安装面板上看到「这个版本新增:…」逐个确认。只收窄、不扩大的版本会自动装上。所以扩大访问范围的改动,单独发一版,别和用户急着要的修复绑在一起。

版本历史与回退

工作台里包那一行的 ··· → 版本历史,列出这个包发过的每一版和它们的状态。被新版本替换、或你自己撤下的那一版,可以点 回退到此版:它会把那一版的内容作为一个新的版本号重新上线,替换现在线上的版本(应用只接受版本号变大,所以回退也是往前发一版,不是把号改回去)。被平台下架的版本不能回退,要走申诉。

发出去之后还能做什么

工作台里可以自助下架自己已发布的包;被下架或被举报时可以申诉。这些都在工作台的包列表上。


常见错

现象 原因 修法
面板点发布后立刻弹一串红色条目,没上传 静态闸有 error 照条目改;在终端跑 numable check <包> --profile publish 是同一份规则,改起来更快
提示版本被占用 没勾版本 +1,同一个 (id, version) 重传 勾上「发布为 v(下一版)」,或先手改 manifest.version
发了新版,用户那边没有更新提示 manifest.version 没 +1 改版本号再发一次
商店里包名显示成半截 + 省略号 标题超过宫格瓦片两行的容量(G21) 缩短 title,全名放 subtitle
英文环境下商店行 / 组件标题是中文 manifest.i18n["en-US"](G19)或 .xwidget 的 i18n["en-US"](G20)缺 补上;numable docs localize
图标四角有一圈白边 logo.png 自己烤了圆角、角部垫的是不透明底,宿主再裁一次就漏出来(G11b) 改满幅,用底板色把四角填平
装完是一个空组件,用户不知道要绑密钥 声明了 required 凭证但页面里没有直达入口(G25) 首页写编号步骤 + 一个直达按钮
提示该账号已被限制发布 账号在发布黑名单里 通过 App 内的意见反馈联系平台
提示「中国大陆暂不支持发布工具」 在中国大陆发布 暂不支持,在中国大陆以外发布
发了新版,用户那边迟迟没有自动更新 新版本比已装版本多了网站、凭证或后台任务,要用户逐个确认 预期行为;扩大访问范围的改动单独发版
发了新版,用户盘上某个组件显示「组件已下线」 删掉或改名了那个 .xwidget 别改组件文件名;要换组件就新增文件

下一步