文档

应用 CLI 命令

打包、上传、更新和删除 Web 应用,并读写其键值存储及相关 webhook。

这里的每个命令都按 CLI 参考所述运行:全局标志、JSON 输出、退出代码、修订和重试。

应用

应用是一个已构建的静态目录,根目录为 index.html。打包器在 _screenrig/runtime.js 注入浏览器 SDK 并添加其脚本标签,因此应用无需构建步骤即可访问 window.screenrig,且无需添加依赖。目录中无任何内容在打包时构建或执行。

app pack#

将静态目录打包成确定性归档,无需上传。

app pack <directory> [--output FILE]
参数类型必填默认备注
<directory>路径是无构建的静态目录。需要根 index.html。
--output FILE路径否无内容还将归档写入此路径。未指定时,命令报告归档并保留在内存中。
screenrig app pack ./lobby-board --output ./lobby-board.tgz

信封报告 sha256、compressed_bytes、expanded_bytes、file_count、条目列表,以及 SDK 运行时是否被注入。app upload 打包目录本身,仅在想先检查归档时使用此命令。它在本地运行,无需登录。

一个包最多包含 5000 个文件,解压后 250 MiB,压缩后 100 MiB,单个文件最大 32 MiB,路径最多 16 层、255 字节。打包会排除以 . 开头的名称、node_modules/、bower_components/、jspm_packages/、vendor/、venv/、__pycache__/、CVS/、源码映射 *.map、密钥和凭据文件(*.pem, *.key, *.p12, *.pfx, *.crt, *.cer, id_rsa, id_dsa, id_ecdsa, id_ed25519, credentials.json, secrets.json)、编辑器交换和备份文件、Thumbs.db 以及 desktop.ini。目录根部的 .screenrigignore 文件可按 gitignore 风格逐行添加模式,但无法恢复内置排除项。符号链接、硬链接、稀疏文件、设备文件、重复路径(也按不区分大小写比较)、打包期间发生变化的文件,以及根部没有 index.html 的目录都会被拒绝,并指明路径:命令以退出码 2 结束,不会发送任何内容。

应用运行在阻止内联代码的内容安全策略下。打包会将内联样式和脚本块移入每个 HTML 文档旁的 _screenrig-inline-* 文件并链接。内联事件处理器如 onclick= 和 javascript: URL 无法移动;打包拒绝它们并标明文件和行号。

app types#

将 window.screenrig 的 TypeScript 类型写入目录。

app types [directory]
参数类型必填默认备注
[directory]路径否当前目录要写入 screenrig.d.ts 的目录。该目录必须已存在。
screenrig app types ./src

信封报告 path、bytes、sha256 和 written,当文件已包含当前类型时其值为 false。该文件与 app pack 和 app upload 注入的运行时一致,因此更新 CLI 后请再次运行该命令。已有的 screenrig.d.ts 会被整体替换;该路径上的目录或符号链接会被拒绝,命令以退出码 2 结束。它在本地运行,无需登录。TypeScript 说明了这些类型声明的内容。

app dev#

在本地播放器测试台中托管一个目录,以便在上传应用前试用。

app dev <directory> [--port PORT] [--open] [--no-reload] [--kv FILE | --kv-from APP_ID]
参数类型必填默认备注
<directory>路径是无构建的静态目录。需要根 index.html。
--port PORTinteger否18890测试环境监听的端口。运行时只在 18890 上信任测试环境,因此其他任何端口都会被拒绝。
--openboolean否关闭在浏览器中打开测试台。
--no-reloadboolean否关闭文件更改时保持页面不变。没有它,页面会在每次更改时重新加载。
--kv FILE路径否.screenrig-dev/kv.json保存本次运行键值存储的 JSON 文件。
--kv-from APP_IDstring否无只读地读取此已上传应用的键值存储,而不是读取文件。
screenrig app dev ./lobby-board --open

该命令在 http://play.screenrig.localhost:18890 提供测试台,并一直运行到你停止它。它像 app pack 那样注入运行时,并在你编辑时报告打包拒绝的内容,指明文件和行号。测试台会模拟功能、视口、屏幕名称、时区和参数、页面计时器、暂停、显示和离开、设备事件,以及串口、GPIO 线路、Bluetooth LE 外设和打印机。emit 和 log 行会打印在终端中。在本地开发介绍了这些控件。

app upload#

打包目录,发布为新应用版本,等待发布成功。

app upload <directory> [--name NAME] [--no-wait] [--poll-ms MS] [--timeout MS]
参数类型必填默认备注
<directory>路径是无构建的静态目录。
--name NAMEstring否自动生成的名称应用名称,去除首尾空白后 1 至 120 个字符,不含控制字符。
--no-waitboolean否关闭在发布操作完成前返回。发布前运行 operations wait,将版本固定到播放列表。
--poll-ms MSinteger否1000等待时操作轮询间隔。
--timeout MSinteger否120000等待的截止时间。它也限制每个底层请求。
screenrig app upload ./lobby-board --name "Lobby board"

读取三个字段:data.operation.state 是 succeeded,data.application.release_id 是 rel_ ID,一个 application 原语引脚,data.application.id 是 app_ ID,kv 命令使用。成功操作(非单独的发布 ID)表示发布可用。

每个 app upload 创建一个新应用和第一个不可变版本。发布同一应用的后续版本,使用 app update。播放列表保持提供已固定的版本,直到编辑该原始版本。

中断的存储传输会在其上传 URL 有效期间最多尝试 4 次。若仍然失败,请再次运行同一条命令以恢复同一次上传。

app update#

发布现有应用的新版本,保留身份、名称和应用 K/V。

app update <id> <directory> [--expect-rev REVISION] [--no-wait] [--poll-ms MS] [--timeout MS]
参数类型必填默认备注
<id>string是无app_ 应用 ID。
<directory>路径是无构建的静态目录。
--expect-rev REVISIONstring否无可选修订前提条件。省略则写入当前资源。提供的过期值为 revision_conflict:重新获取,重新应用,重试。
--no-waitboolean否关闭在发布操作完成前返回。发布前运行 operations wait,将版本固定到播放列表。
--poll-ms MSinteger否1000等待时操作轮询间隔。
--timeout MSinteger否120000等待的截止时间。它也限制每个底层请求。
screenrig app update app_01EXAMPLEAPP00000000000 ./lobby-board

名称保持不变;如需更改,请使用 app rename。等待 data.operation.state: "succeeded",然后使用 playlist replace-release 审查确切的页面、原语、新版本和受影响的屏幕。使用返回的影响令牌和可选的修订保护(如 播放列表工作流 中所述)进行应用。现有播放列表固定保持不变直到应用。遇到修订冲突时,重新读取应用后再决定是否重试;不要为了绕过冲突而创建替代应用。

app list#

列出项目的应用程序。

app list

无参数。

screenrig app list

app rename#

更改应用的显示名称。

app rename <id> --name NAME [--expect-rev REVISION]
参数类型必填默认备注
<id>string是无app_ 应用 ID。
--name NAMEstring是无新名称,去除首尾空白后 1 至 120 个字符,不含控制字符。
--expect-rev REVISIONstring否无可选修订前提条件。省略则写入当前资源。提供的过期值为 revision_conflict:重新获取,重新应用,重试。
screenrig app rename app_01EXAMPLEAPP00000000000 --name "Lobby welcome"

只会更改显示名称。应用 ID、其发布版本、键/值数据以及固定其发布版本的播放列表都保持不变,也无需上传目录。改为当前名称不会改变修订版本。名称可以重复;请通过 ID 指定应用。

app show#

读取一个应用。

app show <id>
参数类型必填默认备注
<id>string是无app_ 应用 ID。
screenrig app show app_01EXAMPLEAPP00000000000

latest_ready_release 在首次发布达到就绪前不会出现。发布状态属于操作和发布版本,不属于应用。last_used_at 在屏幕首次播放该应用前不会出现。

app delete#

删除一个应用及其所有版本。

app delete <id> [--expect-rev REVISION]
参数类型必填默认备注
<id>string是无app_ 应用 ID。
--expect-rev REVISIONstring否无可选修订前提条件。省略则写入当前资源。提供的过期值为 revision_conflict:重新获取,重新应用,重试。
screenrig app delete app_01EXAMPLEAPP00000000000

无单独的发布删除。当屏幕显示应用的某个发布时,删除返回 application_in_use:请先给这些屏幕其他内容。删除不检查固定发布但未显示的播放列表,因此也需更新或删除这些播放列表。

应用键值

键值存储属于一个应用且支持二进制安全。每个命令使用--app-id和来自app upload的app_ID,绝不使用发布ID。每次写入仅使用一种值模式。

kv list#

列出为一个应用程序存储的密钥。

kv list --app-id ID
参数类型必填默认备注
--app-id IDstring是无app_ 应用 ID。
screenrig kv list --app-id app_01EXAMPLEAPP00000000000

kv get#

读取一个密钥。

kv get --app-id ID <key>
参数类型必填默认备注
--app-id IDstring是无app_ 应用 ID。
<key>string是无要读取的键。
screenrig kv get --app-id app_01EXAMPLEAPP00000000000 menu

响应在 data.value_base64 中携带值(包括 JSON 值):先解码,只有 data.content_type 表明是 JSON 时才按 JSON 解析。kv list 不包含值。

kv set#

从 JSON、文件或 base64 字节写入一个密钥。

kv set --app-id ID <key> --json-value JSON [--expect-rev REVISION]
kv set --app-id ID <key> --file FILE [--content-type TYPE] [--expect-rev REVISION]
kv set --app-id ID <key> --value-base64 BASE64 [--content-type TYPE] [--expect-rev REVISION]
参数类型必填默认备注
--app-id IDstring是无app_ 应用 ID。
<key>string是无要写入的键。
--json-value JSONstring单一模式无一个 JSON 值,发送前规范化,始终存储为 application/json。也接受显式的 application/json 内容类型。
--file FILE路径单一模式无从文件读取值的字节,最大 1 MiB,或用 - 从 stdin 读取。默认值为 application/octet-stream。
--value-base64 BASE64string单一模式无规范填充的标准 base64,无空白,最多 1,398,104 字符;允许空值。默认值为 application/octet-stream。
--content-type TYPEstring否字节的 application/octet-stream一到 127 个字符。
--expect-rev REVISIONstring否无仅当存储条目仍处于此版本时写入。
screenrig kv set --app-id app_01EXAMPLEAPP00000000000 menu --json-value '{"soup":"lentil"}'

kv delete#

删除一个键。

kv delete --app-id ID <key> [--expect-rev REVISION]
参数类型必填默认备注
--app-id IDstring是无app_ 应用 ID。
<key>string是无要删除的键。
--expect-rev REVISIONstring否无可选修订前提条件。省略则写入当前资源。提供的过期值为 revision_conflict:重新获取,重新应用,重试。
screenrig kv delete --app-id app_01EXAMPLEAPP00000000000 menu

键值webhook

键值 webhook 是一个 URL,写入一个应用的一个键,因此任何外部系统,如 销售点、电子表格脚本或定时任务,都可通过一次 HTTP POST 向屏幕推送数据。订阅 kv.onChange 的应用会在运行该应用的每个屏幕上几秒内更新。每个应用最多有 20 个 webhook。

发送方使用 webhook 的密钥 srkw_… 进行认证,形式为 Authorization: Bearer <secret>,或使用 HTTP Basic,以 webhook ID 作为用户名、密钥作为密码;URL 或查询字符串中的密钥一律不接受。最大 1 MiB 的原始正文成为键的值,Content-Type 为其内容类型。每次投递不计入智能体请求上限,像 kv set 一样计入存储,会提升修订版本,并返回键的新元数据,从不返回它的值。可选的 Idempotency-Key 标头会对发送方的重试去重 24 小时。一个 webhook 每分钟最多接受 120 次投递,缺少或错误的密钥以及未知的 webhook 会返回 401。从其他系统推送数据提供 curl 示例。

秘密仅由 kv webhook create 和 kv webhook rotate-secret 显示。URL 非秘密。创建、轮换和删除 webhook 会在项目事件日志中追加 kv_webhook.created、kv_webhook.secret_rotated 和 kv_webhook.deleted,每次 POST 像任何写入一样追加 kv.updated。

问题代码退出含义
kv_webhook_limit_reached5应用或卡片已达到 20 个 webhook 上限。未创建新项。请先删除一个。
not_found4应用不属于此项目,或无此 ID 的 webhook。
card_not_found4此项目中没有该卡片。

kv webhook create#

创建一个写入应用某个键的 webhook,或使用 --card 写入卡片的数据文档,并一次性获取其 URL 和密钥。

kv webhook create <key> --app-id ID [--description TEXT]
kv webhook create --card CARD_ID [--description TEXT] [--map FILE|-] [--key-template TEMPLATE] [--signing]
                  [--verify VENDOR [--verify-secret-file FILE|-] [--verify-header NAME] [--verify-encoding hex|base64]
                   [--verify-timestamp-header NAME] [--verify-tolerance SECONDS]] [--handshake VENDOR]
参数类型必填默认备注
<key>string配合 --app-id无每个请求写入的键,长度为 1 至 256 个字符:首字符为字母或数字,后续为字母、数字、.、_、:、/ 或 -。该键可以尚不存在。卡片 webhook 没有键。
--app-id IDstring二选一无app_ 应用 ID。在 --app-id 和 --card 中恰好给出一个。
--card CARD_IDstring二选一无crd_ 卡片 ID:该 webhook 写入卡片的数据文档。参见卡片 webhook。
--description TEXTstring否无向它发送内容的系统,最多 200 字节。不得包含凭证。
--map FILE路径否无根据提交的正文构建文档的映射:从文件读取的、最大 64 KiB 的 JSON 对象,或用 - 从 stdin 读取。省略时,提交的对象就是文档。
--key-template TEMPLATEstring否无在由 {screen.field.NAME} 令牌填充而成的键下写入按键存储的文档,例如 room-{screen.field.room}。
--signingboolean否关闭还要求每次请求都带 ScreenRig-Signature,并仅显示一次签名密钥。不能与 --verify 同时使用。
--verify VENDORstring否无接受带有该服务商自己签名的请求,无需 webhook 的 srkw_ 密钥,该密钥仍可并行使用:github、stripe、shopify、slack、linear、vercel、asana 或 generic_hmac。
--verify-secret-file FILE路径配合 --verify无从文件读取服务商的密钥,或用 - 从 stdin 读取(不能作为参数):即 GitHub、Stripe、Shopify、Slack、Linear 或 Vercel 显示的密钥,或 generic_hmac 发送方的密钥。asana 不需要密钥,由其握手送达。只有一个选项可以读取 stdin。
--verify-header NAMEstring配合 generic_hmac无携带签名的请求头,1 到 100 个字母、数字、- 或 _。
--verify-encoding ENCODINGstring否hex配合 generic_hmac:签名的写法,hex 或 base64;可以以 sha256= 开头。
--verify-timestamp-header NAMEstring否无配合 generic_hmac:携带 Unix 时间的请求头,单位为秒,或为 13 位数字的毫秒。此时被签名的文本是时间戳、一个点和正文。
--verify-tolerance SECONDSinteger否300配合 --verify-timestamp-header:时间戳与服务器时钟的最大偏差,1 到 86400。
--handshake VENDORstring否无响应 microsoft_graph、monday、trello 或 azure_event_grid 的设置质询。Slack 和 Asana 通过 --verify 响应各自的质询。
screenrig kv webhook create menu --app-id app_01EXAMPLEAPP00000000000 --description "Point of sale menu feed"
screenrig kv webhook create --card crd_01EXAMPLEBOARD0000000000 --map alert-map.json --description "CMS alerts"

--map、--key-template、--signing、--verify(连同其选项)和 --handshake 仅适用于卡片 webhook。

信封就是该 webhook:data.id(kvw_…)、data.key(卡片则为 data.card_id)、data.url(https://api.screenrig.ai/api/applications/<app_id>/kv-webhooks/<id>/write,卡片则为 https://api.screenrig.ai/api/cards/<card_id>/kv-webhooks/<id>/write)和 data.secret(srkw_…)。签名的卡片 webhook 还包含 data.signing_secret(whsec_…)。请立即把 URL 和密钥填入发送系统,之后没有任何命令会再次显示它们。创建被中断或结果不明时,请在 24 小时内再次运行相同的命令:它会重用已保存的幂等键,服务器返回同一个 webhook 和同样的密钥,而不会再创建一个。

kv webhook list#

列出应用或卡片的 webhook,最早的在前。

kv webhook list (--app-id ID | --card CARD_ID)
参数类型必填默认备注
--app-id IDstring二选一无app_ 应用 ID。在 --app-id 和 --card 中恰好给出一个。
--card CARD_IDstring二选一无crd_ 卡片 ID。
screenrig kv webhook list --app-id app_01EXAMPLEAPP00000000000
screenrig kv webhook list --card crd_01EXAMPLEBOARD0000000000

每个项目都有 id、key、description、url、created_at,写入后还有 last_used_at。卡片 webhook 的项目用 card_id 代替 key,另有 mapping(提交的对象即文档时为 null)、enabled、signing,以及已设置时的 key_template、verify 和 handshake。列表从不包含密钥。

kv webhook delete#

删除 Webhook。其 URL 立即停止工作,键或卡片的文档保持其值。

kv webhook delete <webhook_id> (--app-id ID | --card CARD_ID)
参数类型必填默认备注
<webhook_id>string是无kvw_ Webhook ID。
--app-id IDstring二选一无app_ 应用 ID。在 --app-id 和 --card 中恰好给出一个。
--card CARD_IDstring二选一无crd_ 卡片 ID。
screenrig kv webhook delete kvw_01EXAMPLEWEBHOOK00000 --app-id app_01EXAMPLEAPP00000000000
screenrig kv webhook delete kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000

kv webhook rotate-secret#

替换Webhook密钥并仅接收一次新密钥。

kv webhook rotate-secret <webhook_id> (--app-id ID | --card CARD_ID) [--signing]
参数类型必填默认备注
<webhook_id>string是无kvw_ Webhook ID。
--app-id IDstring二选一无app_ 应用 ID。在 --app-id 和 --card 中恰好给出一个。
--card CARD_IDstring二选一无crd_ 卡片 ID。
--signingboolean否关闭配合 --card:替换签名密钥,而不是 webhook 密钥。
screenrig kv webhook rotate-secret kvw_01EXAMPLEWEBHOOK00000 --app-id app_01EXAMPLEAPP00000000000
screenrig kv webhook rotate-secret kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000 --signing

信封在 data.secret 中携带新密钥。旧密钥立即失效,因此请把新密钥填入发送系统。使用 --signing 时,信封改为在 data.signing_secret 中携带新的签名密钥,webhook 的 srkw_ 密钥保持不变。轮换被中断或结果不明时,请再次运行相同的命令:它会重用已保存的幂等键,服务器返回已完成的那次轮换,而不会再轮换一次。

其他命令组