T3 Code 非官方中文翻译不是官方产品,也不是 T3 Tools 官方文档。源提交 d2c25950b4d9英文原文GitHub 源文件
Skip to content

移动应用商店截图采集框架 ​

面向维护者。正在使用 T3 Code?请参阅用户文档。

截图采集框架在三个一次性的本地 T3 环境(environment)上运行真实的移动应用。它为每个环境创建隔离的基础目录和服务器,并创建内容确定的真实 Git 项目、预先灌入的编排投影(projection),以及已持久化的终端历史。应用通过正常的连接流程与每一台服务器配对,React Navigation 则会打开生产环境中的 Home、Thread、ThreadTerminal、ThreadReview 和 SettingsEnvironments 路由。

并没有专为截图另做一套界面来复刻应用 UI。EXPO_PUBLIC_SHOWCASE=1 只启用非渲染的配对与就绪协调器,关闭终端自动聚焦,使截图里不出现软键盘,并向真实的 Environments 界面提供内容确定的 T3 Connect 发现行。本地环境卡片始终来自真实配对的服务器。

采集默认矩阵 ​

在仓库根目录执行:

pnpm screenshots:mobile

该命令会:

  1. 创建三个临时的 T3 基础目录,并在各自可用的端口上为每个目录启动一台本地服务器。
  2. 创建 T3 Code、React 和 Linux 的 Git 仓库,带有可辨认的网站图标、功能分支,以及一份内容确定的 T3 Code 审查差异。
  3. 向每台服务器已完成迁移的 SQLite 数据库灌入轻松俏皮的对话线程(thread)、消息、活动和终端历史,再加入两项已持久化、等待发送的移动端发件箱(outbox)任务。
  4. 启动一台隔离的 Metro 服务器,构建所选的原生应用,并启动每一台设备。
  5. 把每个干净的应用安装与 Moonbase Terminal、Suspense Station 和 Kernel Cabin 配对。
  6. 针对每一个请求的场景,导航到真实的应用路由。
  7. 设置所请求的系统外观和配色,把状态栏整理一致,将截图转换为不含 alpha 的 24 位 RGB PNG,并在判定成功之前校验尺寸、宽高比、文件大小和截图数量。
  8. 在 artifacts/app-store/screenshots/ 下写出可以直接上传到 App Store Connect 或 Google Play Console 的商店用文件夹。

采集结束后,运行器启动的服务器、Metro、临时根目录和设备都会被清理。传入 --keep-running 可以把它们留下来检查;运行器会打印基础目录路径和服务器端口。

截图会等待真实的环境快照加载到位,并等待所请求的路由进入活动状态。两个平台都在模拟器或仿真器的应用容器里记录就绪状态。最后还有一段稳定等待,让原生终端和 Git 审查数据完成渲染。

一次完整采集会在构建之前,先用 Expo 的干净生产预构建(prebuild)重新生成所选的原生项目。第一次构建之后若要反复采集,请使用 --skip-build。

采集框架使用固定的 Metro 端口 8199。它和 Expo 通常的默认端口是分开的,但每一次检出都共用这个端口。就绪检查只确认端口已经打开,并不核对进程归谁所有。因此,不同工作树(worktree)里同时运行的截图采集框架可能互相冲突,或者连到错误的 Metro 进程上。

每台已配置的设备默认都是深色外观和 t3-code 配色,所以直接执行 pnpm screenshots:mobile 会生成 45 张深色 PNG。传入 --appearance light、--appearance dark 或 --appearance both 可以覆盖配置里的外观;both 会生成 90 张 PNG。

传入 --theme <id>(可以重复传入)或 --theme all,即可采集应用的其他配色:t3-code、t3-chat、grove、ocean、ember 和 iris。运行器把配色作为启动参数交给应用,应用会把它应用到两种配色方案;场景只有在所请求的配色已经生效之后,才会报告自己就绪——因此截图不可能还停在上一个主题。--theme all 会把这一次运行的数量乘以六;其中只有原生构建是共享的。

默认矩阵如下:

输出文件夹采集目标上传尺寸商店槽位
apple/iphone-6.9/dark/t3-code/一次性的 iPhone 17 Pro Max1320×2868App Store Connect iPhone 6.9 英寸
apple/iphone-6.5/dark/t3-code/一次性的 iPhone 14 Plus1284×2778App Store Connect iPhone 6.5 英寸
apple/iphone-duo-closed/dark/t3-code/iPhone Duo,折叠后的竖屏1398×2034App Store Connect iPhone Duo
apple/iphone-duo-open/dark/t3-code/iPhone Duo,展开后的横屏2853×2007App Store Connect iPhone Duo
apple/ipad-13/dark/t3-code/iPad Pro 13 英寸(M5)2752×2064App Store Connect iPad 13 英寸,横屏
google-play/phone/dark/t3-code/420 dpi 的 Pixel AVD1080×1920Google Play 手机,竖屏 9:16
google-play/tablet-7/dark/t3-code/宽度为 600dp 的 Pixel AVD1080×1920Google Play 7 英寸平板,竖屏 9:16
google-play/tablet-10/dark/t3-code/宽度为 800dp 的 Pixel AVD1440×2560Google Play 10 英寸平板,竖屏 9:16

每个目标都会采集对话线程、终端、审查、对话线程列表和环境;除了 iPad 和 Duo,每个目标还会采集智能体活动。每个配色文件夹里的五张或六张截图,满足所配置的 Apple 上限 1–10 张、Google 手机要求的 2–8 张,以及 Google 平板建议数量与槽位下限 4 张、上限 8 张。两个 Duo 文件夹各自包含五个场景,上传到同一个 iPhone Duo 槽位(一共十张图片)。它们省去智能体活动,以便留在这个共享上限之内。Duo 采集需要已安装、且支持 iPhone Duo 的 iOS 运行时,并且 PATH 上要有 agent-device,或者由 AGENT_DEVICE_PATH 指向它的可执行文件;它会在启动应用之前设置并核对模拟器的折叠姿态。

每种配色都有自己的叶子文件夹,因此同一个上传槽位不会混进不同主题,每个文件夹的截图数量也符合商店规定。

智能体活动场景展示的是用户离开应用之后看到的画面。应用会为四个预置的对话线程,预先放上中继(relay)将会发布的那同一条 Live Activity(iOS)或持续显示的 Live Update(Android)。在 iOS 上,运行器接着锁定模拟器,并用 simctl push 推送与之对应的批准提醒;在 Android 上,这条预先放上的更新本身带着该提醒,运行器会打开通知栏。锁定模拟器,以及回应通知权限提示,都要使用 AXe,因此在采集 iOS 之前请先安装它(brew tap cameroncooke/axe && brew install axe) or set AXE_PATH。iPad 会跳过这一场景,因为锁屏不会跟随应用自身的横屏旋转。

生成的目录树有意与商店的上传字段对齐:

artifacts/app-store/screenshots/
├── apple/
│   ├── iphone-6.9/dark/t3-code/{thread,terminal,review,threads,environments,agent-activity}.png
│   ├── iphone-6.5/dark/t3-code/{thread,terminal,review,threads,environments,agent-activity}.png
│   ├── iphone-duo-closed/dark/t3-code/{thread,terminal,review,threads,environments}.png
│   ├── iphone-duo-open/dark/t3-code/{thread,terminal,review,threads,environments}.png
│   └── ipad-13/dark/t3-code/{thread,terminal,review,threads,environments}.png
└── google-play/
    ├── phone/dark/t3-code/{thread,terminal,review,threads,environments,agent-activity}.png
    ├── tablet-7/dark/t3-code/{thread,terminal,review,threads,environments,agent-activity}.png
    └── tablet-10/dark/t3-code/{thread,terminal,review,threads,environments,agent-activity}.png

只采集浅色时,会把同一棵目录树写到 light/ 下;--appearance both 会写入两种外观各自的文件夹,并且每请求一种主题,就会在 t3-code/ 旁边再加一个同级文件夹。

编辑 mobile-showcase.config.ts,即可更改模拟器或 AVD 的名称、浅色与深色外观、默认配色、iOS 方向、场景、输出目录、采集延迟、Android ABI 或视口。可选配色的 id 来自 MOBILE_THEME_IDS,它位于 themePalettes.ts 中,因此采集框架和应用的外观设置不会彼此偏离。

在 GitHub Actions 中采集 ​

从 GitHub 的 Actions 标签页运行 Mobile Showcase Screenshots 工作流,在 all、ios、android 中选择一项,在 light、dark、both 中选择一项,并挑选一种配色(或选择 all,它会把每个作业的超时从 60 分钟提高到 300 分钟)。按默认选项触发时,会采集 t3-code 配色的两种外观,并且 iOS 与 Android 同时进行:iPhone 和 iPad 在 12 vCPU 的 Blacksmith macOS 运行器上采集,Android 手机、7 英寸平板和 10 英寸平板则在带有 KVM 加速 x86_64 仿真器的 16 vCPU Blacksmith Linux 运行器上采集。

每个作业即便采集失败也会上传自己的 PNG,因此不完整的运行仍然可以用来诊断。单独的校验步骤以采集成功为门槛:只有采集成功时,它才会在上传之前运行。如果采集失败,always() 的上传仍会把这些不完整的 PNG 发布出去,并且不会重新校验。请从该工作流运行的产物(Artifacts)区域下载 app-store-connect-screenshots 和 google-play-screenshots。产物保留 14 天。

该工作流使用与本地采集相同、已经签入仓库的设备和场景矩阵。本地 Apple Silicon 开发时,Android 默认仍是 ARM64;CI 会设置 T3_SHOWCASE_ANDROID_ABI=x86_64,使调试 APK 与那台加速仿真器一致。

快速迭代 ​

只采集一个场景或一台设备:

pnpm screenshots:mobile --device iphone-duo-closed --device iphone-duo-open
pnpm screenshots:mobile --device iphone-6.9 --scene thread
pnpm screenshots:mobile --platform android --scene review

覆盖配置中的外观,或两种都采集:

pnpm screenshots:mobile --appearance light
pnpm screenshots:mobile --appearance dark
pnpm screenshots:mobile --appearance both

采集其他配色:

pnpm screenshots:mobile --device iphone-6.9 --theme ocean
pnpm screenshots:mobile --device iphone-6.9 --theme ocean --theme ember
pnpm screenshots:mobile --device iphone-6.9 --theme all

复用原生构建,并保留一次性环境:

pnpm screenshots:mobile --device ipad-13 --skip-build --keep-running

默认让截图运行器在端口 8199 上启动 Metro。若要把 Metro 留在单独的终端里,请用同一套展示环境,并显式指定采集框架所用的端口来启动:

cd apps/mobile
APP_VARIANT=development EXPO_PUBLIC_SHOWCASE=1 pnpm exec expo start --dev-client --port 8199

然后在仓库根目录执行采集:

pnpm screenshots:mobile --skip-build --skip-metro --device iphone-6.9

pnpm --filter @t3tools/mobile showcase 会在 Expo 平常的端口上启动,因此与采集框架的 --skip-metro 模式不兼容。

列出矩阵和标志:

pnpm screenshots:mobile --list

只校验已有文件,不启动 Metro、服务器、模拟器或仿真器:

pnpm screenshots:mobile --validate-only
pnpm screenshots:mobile --platform ios --validate-only

自定义预置环境 ​

夹具时间戳按相对于采集开始的时刻生成,因此每条路由都显示稳定的相对时间标签,而服务器收到的仍是当前有效的数据。同一组内容确定的三个环境,同时供 iPhone、iPad、Android 手机和 Android 平板的采集使用;响应式上的差异完全来自生产应用的布局。

待处理(Pending)行使用的是生产环境的离线发件箱(outbox),并指向真实的 T3 Code 与 React 夹具项目。展示协调会在采集期间把这两条留在发件箱里,如同一项当前正打开、等待编辑的任务,因此重新连接这些预置环境时,无法在截图拍下之前把它们投递并移除。

Environments 这一场景把三个本地夹具的传输显示为 Tailscale 的 HTTPS 主机名、赫尔辛基 VPS 的主机名,以及 Tailnet 的 IPv4 地址。这种只改显示的替换让卡片保持远程优先,采集框架则继续用可靠的回环连接访问自己的临时服务器。

本地前提 ​

  • iOS:Xcode 命令行工具、已配置的模拟器运行时,以及已安装的 CocoaPods。
  • Android:解析 SDK 时先检查 ANDROID_HOME,再检查 ANDROID_SDK_ROOT,然后在 macOS 上默认使用 $HOME/Library/Android/sdk,在其他平台上默认使用 $HOME/Android/Sdk。解析到的 SDK 必须提供 adb 和 emulator,并且配置中的 AVD 必须已经存在。

上传尺寸以采集框架为准,不要改这些输出文件的尺寸。商店规则若有变化,请更新该目标的 storeAsset 规格。PNG 尺寸不对、带有 alpha、不是 8 位 RGB、超过配置的文件大小上限、违反 Google Play 的 9:16 形状或边界,或者一整套输出的数量低于商店要求的下限时,采集都会失败。

非官方译文 · 源提交 d2c25950b4d9 · 不代表 T3 Tools