tirtc-device-builder 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ import {
12
12
  import { homedir } from "node:os";
13
13
  import { dirname, join, resolve } from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
+ import { runEsp32Setup } from "./setup-esp32.js";
15
16
 
16
17
  const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
17
18
  const PACKAGE = JSON.parse(
@@ -35,6 +36,7 @@ function printHelp() {
35
36
  Usage:
36
37
  tirtc-device-builder list
37
38
  tirtc-device-builder install <platform> [--skills-dir <path>] [--force]
39
+ tirtc-device-builder setup <platform> [setup options]
38
40
  tirtc-device-builder doctor <platform> [doctor options]
39
41
  tirtc-device-builder --version
40
42
 
@@ -43,11 +45,14 @@ Platforms:
43
45
 
44
46
  Examples:
45
47
  npx tirtc-device-builder install esp32
48
+ npx tirtc-device-builder setup esp32
49
+ npx tirtc-device-builder setup esp32 --install
46
50
  npx tirtc-device-builder install esp32 --skills-dir /absolute/path/skills
47
51
  npx tirtc-device-builder doctor esp32 --project /absolute/path/project
48
52
 
49
53
  Install defaults to ${"$"}{CODEX_HOME:-~/.codex}/skills. Existing skills are
50
- preserved unless --force is explicitly supplied.`);
54
+ preserved unless --force is explicitly supplied. Setup checks are read-only;
55
+ setup --install installs missing user-space components without running sudo.`);
51
56
  }
52
57
 
53
58
  function fail(message) {
@@ -187,7 +192,7 @@ function main(args) {
187
192
  }
188
193
 
189
194
  const [command, identifier, ...rest] = args;
190
- if (command !== "install" && command !== "doctor") {
195
+ if (command !== "install" && command !== "doctor" && command !== "setup") {
191
196
  return fail(`unknown command: ${command}; run with --help`);
192
197
  }
193
198
  if (!identifier) {
@@ -201,6 +206,18 @@ function main(args) {
201
206
  if (command === "doctor") {
202
207
  return runDoctor(platform, rest);
203
208
  }
209
+ if (command === "setup") {
210
+ if (platform.name !== "esp32") {
211
+ return fail(`setup is not available for platform: ${platform.name}`);
212
+ }
213
+ return runEsp32Setup(rest, {
214
+ cliPath: fileURLToPath(import.meta.url),
215
+ defaultSkillsDir: defaultSkillsDir(),
216
+ packageRoot: PACKAGE_ROOT,
217
+ packageVersion: PACKAGE.version,
218
+ platform,
219
+ });
220
+ }
204
221
 
205
222
  try {
206
223
  const options = parseInstallOptions(rest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirtc-device-builder",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Install and run TiRTC device-development skills for Codex.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -45,6 +45,7 @@
45
45
  "registry": "https://registry.npmjs.org/"
46
46
  },
47
47
  "scripts": {
48
+ "pack:esp32-kit": "node scripts/pack-esp32-kit.js",
48
49
  "test": "npm run test:node && npm run test:python && npm run validate && npm run validate:tarball && npm run test:package",
49
50
  "test:node": "node --test test/*.test.js",
50
51
  "test:python": "python3 -m unittest discover -s skills/tirtc-esp32-builder/scripts -p 'test_*.py'",
@@ -9,17 +9,20 @@ Turn board evidence into an evidence-backed ESP-IDF project. Treat the Hardware
9
9
 
10
10
  ## Start
11
11
 
12
- 1. Locate the ThingConnect root containing `device-sim/` using the explicit input, `TIRTC_THING_CONNECT_ROOT`, or workspace discovery. Read its applicable `AGENTS.md` and preserve its public protocol contracts.
13
- 2. Read [environment.md](references/environment.md) and run `python3 <skill-dir>/scripts/doctor.py --expected-idf 5.5 --target esp32s3`. Add `--require-workspace` when generation or repository reference documents are needed; a self-contained generated project can instead resolve its bundled SDK through `--project`. Resolve every required failure before claiming build readiness. Installation, cloning, or shell-profile changes require an explicit destination and the applicable authorization.
14
- 3. Read [workflow.md](references/workflow.md). Select the registered-board, new-board intake, or existing-project branch. The branch is selected when every supplied artifact has been accounted for and the exact board revision is known or explicitly unresolved.
15
- 4. Read [hardware-ir.md](references/hardware-ir.md) when a Hardware IR must be created or updated. Record a source and verification level for every hardware fact that affects a requested feature.
16
- 5. Run `python3 <skill-dir>/scripts/hardware_ir.py validate <hardware-ir.json>` and then `assess --strict`. Generation may proceed for a requested feature only when it is `READY_TO_PORT` or `HIL_VERIFIED`; otherwise report the exact missing evidence and continue with safe discovery or scaffolding only.
12
+ 1. Read [environment.md](references/environment.md). For a first-time setup or a request to check/install prerequisites, prefer `npx tirtc-device-builder@latest setup esp32`. Run its `--install` mode only when the user explicitly authorizes installation at the displayed destinations. The installer may create user-space files but never grants permission for `sudo` or persistent shell-profile edits.
13
+ 2. Locate the versioned ESP32 Device Kit root containing `device-sim/` using the explicit input, `TIRTC_THING_CONNECT_ROOT`, the managed setup configuration, or workspace discovery. Treat its manifest and packaged protocol documents as the generation facts. If the user explicitly supplies a full ThingConnect source workspace, also read its applicable `AGENTS.md`.
14
+ 3. Run the Doctor through the managed environment helper when one exists; otherwise run `python3 <skill-dir>/scripts/doctor.py --expected-idf 5.5 --target esp32s3`. Add `--require-workspace` when generation or repository reference documents are needed; a self-contained generated project can instead resolve its bundled SDK through `--project`. Resolve every required failure before claiming build readiness.
15
+ 4. Read [workflow.md](references/workflow.md). Select the registered-board, new-board intake, or existing-project branch. The branch is selected when every supplied artifact has been accounted for and the exact board revision is known or explicitly unresolved.
16
+ 5. Read [hardware-ir.md](references/hardware-ir.md) when a Hardware IR must be created or updated. New intake uses schema v2; schema v1 remains readable for existing H.264 projects. Record a source and verification level for every hardware fact that affects a requested feature.
17
+ 6. Run `python3 <skill-dir>/scripts/hardware_ir.py validate <hardware-ir.json>` and then `assess --strict`. Generation may proceed for a requested feature only when it is `READY_TO_PORT` or `HIL_VERIFIED`; otherwise report the exact missing evidence and continue with safe discovery or scaffolding only.
17
18
 
18
19
  ## Build the project
19
20
 
20
- Run `<thing-connect-root>/device-sim/scripts/create_esp32_project.py` for the current ESP32-S3 H5/AI starter. Keep ThingConnect onboarding, H5, AI, TiRTC lifecycle, callback, stream, and generation behavior in the existing deep modules. Put board-specific camera, microphone, encoder, codec, amplifier, GPIO, DMA, and task behavior behind the `starter_media` seam or a board media adapter owned by it.
21
+ Run `<device-kit-root>/device-sim/scripts/create_esp32_project.py` for the current ESP32-S3 H5/AI starter. Keep ThingConnect onboarding, H5, AI, TiRTC lifecycle, callback, stream, and generation behavior in the existing deep modules. Put board-specific camera, microphone, encoder, codec, amplifier, GPIO, DMA, and task behavior behind the `starter_media` seam or a board media adapter owned by it.
21
22
 
22
- Before changing media code, read [capability-rules.md](references/capability-rules.md) and the repository documents it routes to. A camera sensor alone does not establish H5 video support; the complete H.264 Annex-B and key-frame path must be evidenced. Choose half duplex for AI when the supplied hardware and BSP do not establish a usable full-duplex/AEC path.
23
+ Before changing media code, read [capability-rules.md](references/capability-rules.md) and [porting-risks.md](references/porting-risks.md), then read the repository documents they route to. A camera sensor alone does not establish H5 video support; validate the user-selected MJPEG, H.264, or H.265 profile end to end. Choose half duplex for AI when the supplied hardware and BSP do not establish a usable full-duplex/AEC path.
24
+
25
+ Keep the Skill board-agnostic. The prompt supplies product intent and artifact locations; Hardware IR stores evidence; the generated board adapter owns concrete sensors, codecs, pins, clocks, slots, DMA, and task allocation. Never add one board's values to Skill defaults to make an assessment pass.
23
26
 
24
27
  Run focused tests before ESP-IDF build. Resolve the TiRTC SDK target and `manifest/build-contract.env` against the generated `sdkconfig`; a mismatched precompiled SDK is a blocked build, not a code-generation problem.
25
28
 
@@ -27,7 +30,7 @@ Run focused tests before ESP-IDF build. Resolve the TiRTC SDK target and `manife
27
30
 
28
31
  Flash only when the user requested hardware mutation and the exact serial port and chip have been resolved. When more than one candidate device exists, obtain the target choice before writing. Keep credentials outside generated files and redact device keys, Wi-Fi passwords, MQTT/WHIP tokens, and user media from logs and reports.
29
32
 
30
- Read [reporting.md](references/reporting.md) before end-to-end verification. Report every acceptance level as `PASS`, `FAIL`, or `SKIP`, with commands and evidence. A build-only result is not H5 or AI completion; missing hardware, browser, account, service, or network evidence remains an explicit `SKIP` or blocker.
33
+ Read [reporting.md](references/reporting.md) before end-to-end verification. Report every acceptance level as `PASS`, `FAIL`, or `SKIP`, with commands and evidence. Bind HIL observations to the exact firmware SHA-256 with `assess --artifact-sha256`; an older artifact cannot verify a newer build. A build-only result is not H5 or AI completion; missing hardware, browser, account, service, or network evidence remains an explicit `SKIP` or blocker.
31
34
 
32
35
  ## Finish
33
36
 
@@ -1,38 +1,46 @@
1
1
  # TiRTC ESP32 Builder 使用说明
2
2
 
3
+ ## 一键准备
4
+
5
+ ```bash
6
+ npx tirtc-device-builder@latest setup esp32
7
+ npx tirtc-device-builder@latest setup esp32 --install
8
+ ```
9
+
10
+ 第一条命令只检查;第二条命令自动安装用户目录内缺失的 Skill、带校验的 ESP32 Device Kit、ESP-IDF 5.5.4 和 ESP32-S3 工具链,最后复跑 Doctor。它不执行 `sudo`,也不修改 shell 配置。安装完成后新开 Codex 会话即可调用 Skill。
11
+
3
12
  安装后可在 Codex 中显式调用:
4
13
 
5
14
  ```text
6
15
  $tirtc-esp32-builder
7
16
 
8
- 在“厂商 + 完整开发板型号 + PCB 版本”上实现:
9
- - H5 实时视频和声音
10
- - H5 按住说话
11
- - AI 双向对讲
17
+ 开发板:<厂商、完整型号、PCB 版本>
18
+ 资料与实物对应:<是/否/未知>
12
19
 
13
20
  资料:
14
- - 产品页或资料链接:...
15
- - 原理图:/absolute/path/board-schematic.pdf
16
- - BSP 或示例工程:/absolute/path/vendor-bsp
17
- - ThingConnect:/absolute/path/tirtc-server-example/thing-connect
18
- - 输出目录:/absolute/path/my-tirtc-device
21
+ - <原理图、BSP/厂商示例、数据手册和产品页;一行一个>
22
+
23
+ 目标:<H5 实时音视频、H5 对讲、AI 双向语音等>
24
+ 视频:<MJPEG/H264/H265/根据证据选择>
25
+ Wi-Fi 与设备绑定:<指定方案/根据 BSP 和平台合同选择>
26
+ 工程:<输出目录或现有工程的绝对路径>
19
27
 
20
- 先完成能力分析;具备条件后生成并编译。只有我明确指定串口时才烧录。
28
+ 先运行 Doctor,再生成 Hardware IR v2。达到 READY_TO_PORT 后完成板级适配和编译,输出 TIRTC_PORTING_REPORT.md。
29
+ 本轮不访问串口、不烧录、不擦除 NVS,也不把凭证写入源码或报告。
21
30
  ```
22
31
 
23
- ## ThingConnect 工作区
32
+ 可直接复制的版本见[开发板接入提示词](assets/developer-intake-prompt.md)。SoftAP 只是可选方案;没有 AP 配网时,Skill 会根据 BSP 和产品要求评估其他可重配路径。生产 SSID 和密码不能进入源码或报告。
24
33
 
25
- 这个 Skill 不复制 ThingConnect 源码和 TiRTC 静态库。首次使用可以准备公开仓库:
34
+ ## ESP32 Device Kit
26
35
 
27
- ```bash
28
- git clone https://github.com/tangeai/tirtc-server-example.git \
29
- /absolute/path/tirtc-server-example
36
+ 一键安装会下载固定版本的最小资源包并校验 SHA-256,不需要克隆 ThingConnect 服务端仓库。安装路径由下面的文件记录:
30
37
 
31
- export TIRTC_THING_CONNECT_ROOT=\
32
- /absolute/path/tirtc-server-example/thing-connect
38
+ ```bash
39
+ source ~/.tirtc-device-builder/env.sh
40
+ printf '%s\n' "$TIRTC_THING_CONNECT_ROOT"
33
41
  ```
34
42
 
35
- 也可以在调用 Skill 时直接给出 ThingConnect 绝对路径,不需要设置持久环境变量。
43
+ 已有完整 ThingConnect 工作区仍可通过 `--thing-connect-root` 显式复用,主要用于维护模板或协议时的开发场景。
36
44
 
37
45
  ## 常见输入方式
38
46
 
@@ -45,7 +53,7 @@ $tirtc-esp32-builder 分析 <厂商> <型号> <硬件版本>,目标是 H5 实
45
53
  提供本地资料:
46
54
 
47
55
  ```text
48
- $tirtc-esp32-builder 使用原理图 /path/board.pdf、BSP /path/vendor-project 和 ThingConnect /path/tirtc-server-example/thing-connect,为该板生成 TiRTC H5/AI ESP-IDF 工程并编译。
56
+ $tirtc-esp32-builder 使用原理图 /path/board.pdf、BSP /path/vendor-project 和一键安装的 Device Kit,为该板生成 TiRTC H5/AI ESP-IDF 工程并编译。
49
57
  ```
50
58
 
51
59
  完整实机流程:
@@ -64,7 +72,7 @@ $tirtc-esp32-builder 使用 /path/hardware-ir.json 生成工程,编译后烧
64
72
  python3 <skill-dir>/scripts/doctor.py \
65
73
  --expected-idf 5.5 \
66
74
  --target esp32s3 \
67
- --thing-connect-root /absolute/path/tirtc-server-example/thing-connect \
75
+ --thing-connect-root ~/.tirtc-device-builder/kits/esp32s3/1.0.0 \
68
76
  --require-workspace
69
77
  ```
70
78
 
@@ -87,8 +95,8 @@ python3 <skill-dir>/scripts/hardware_ir.py validate /tmp/hardware-ir.json
87
95
  python3 <skill-dir>/scripts/hardware_ir.py assess --strict /tmp/hardware-ir.json
88
96
  ```
89
97
 
90
- `BLOCKED` 表示资料已确认硬件不满足;`NEEDS_CONFIRMATION` 表示仍有未知项或只有单一来源;`READY_TO_PORT` 表示可以生成并实现板级适配;`HIL_VERIFIED` 表示端到端实机验收通过。
98
+ `init` 默认创建 schema v2;v1 仅用于兼容已有 H.264 IR。`BLOCKED` 表示资料已确认硬件/合同/资源或凭证策略不满足;`NEEDS_CONFIRMATION` 表示仍有未知项或只有单一来源;`READY_TO_PORT` 表示可以生成并实现板级适配;`HIL_VERIFIED` 还要求 `--artifact-sha256` 匹配该固件的 L5/L6 运行证据。
91
99
 
92
100
  ## 当前边界
93
101
 
94
- ThingConnect 仓库提供 ESP32-S3 H5/AI 模板和生成器,但默认媒体适配器不包含特定开发板的摄像头、麦克风、H.264 编码和扬声器驱动。模板生成和编译成功只证明工程与协议骨架可用,不代表 Web 已经出图或 AI 音频已经通过实机验收。
102
+ ThingConnect 仓库提供 ESP32-S3 H5/AI 模板和生成器,但默认媒体适配器不包含特定开发板的摄像头、麦克风、选定视频路径、Wi-Fi 凭证方法和扬声器驱动。模板生成和编译成功只证明工程与协议骨架可用,不代表 Web 已经出图或 AI 音频已经通过实机验收。
@@ -0,0 +1,50 @@
1
+ # TiRTC ESP32 开发板接入提示词
2
+
3
+ 不用先把所有硬件参数查齐。你只要说明是哪块板、资料放在哪里、想实现什么,以及工程输出到哪里。其余内容由 Skill 从原理图、BSP、Device Kit 和数据手册中提取;确实不知道的地方写“未知”。
4
+
5
+ ## 精简模板
6
+
7
+ ```text
8
+ $tirtc-esp32-builder
9
+
10
+ 请为下面这块开发板完成 ThingConnect TiRTC ESP32 接入。
11
+
12
+ 开发板:
13
+ - 厂商、完整型号、PCB/硬件版本:<填写>
14
+ - 资料与手中实物是否对应:<是/否/未知>
15
+
16
+ 资料:
17
+ - <原理图、BSP/厂商示例、数据手册、产品页等本地绝对路径或固定链接;一行一个>
18
+
19
+ 目标:
20
+ - <例如:H5 实时视频和声音、H5 语音对讲、AI 双向语音对讲>
21
+ - 视频选择:<MJPEG/H264/H265/根据合同和硬件证据选择>
22
+ - 双工或 AEC 的硬要求:<无,初版可半双工/必须全双工或 AEC/未知>
23
+
24
+ 接入方式:
25
+ - Wi-Fi:<选择一种,或写“根据 BSP 选择”>
26
+ - 设备绑定:<选择一种,或写“根据平台合同选择”>
27
+
28
+ 工程:
29
+ - 输出目录或现有工程:<绝对路径>
30
+
31
+ 执行要求:
32
+ 1. 先运行 Device Kit Doctor,读完全部资料,再生成 Hardware IR v2。没有证据的器件、GPIO 和媒体能力保持未知。
33
+ 2. 资料不足时,列出矛盾、缺失项和最小补充动作;达到 READY_TO_PORT 后再生成板级 adapter、编译并记录 BIN/ELF SHA-256。
34
+ 3. 移植前核对媒体合同、板级资源、内存预算、配网和绑定状态。具体板卡参数只写入该板的 Hardware IR 和 adapter。
35
+ 4. 输出 TIRTC_PORTING_REPORT.md,并把编译结果与 L2-L7 实机验收分开记录。
36
+ 5. 本轮不访问串口、不烧录、不擦除 NVS。Wi-Fi 密码、设备密钥、token、私钥和用户音视频也不能写入工程或报告。
37
+ ```
38
+
39
+ ## 只有已知时才补充
40
+
41
+ 这些信息如果手头已有,也可以附上;没有就交给 Skill 查资料:
42
+
43
+ - 主控/模组完整型号、Flash 和 PSRAM 容量及总线模式;
44
+ - BSP 的 commit、tag 或 release,以及已验证的摄像头、录音和播放示例;
45
+ - H5/AI 媒体合同链接、选定 profile、stream ID 和帧或 access unit 边界;
46
+ - 凭证保存与重配方式、已有绑定处理和独立清除入口;
47
+ - 已知资料矛盾、实机 PID、串口日志或已知良好固件 SHA-256;
48
+ - 非默认 ESP-IDF、TiRTC SDK、Device Kit、服务发现地址或 HTTP/HTTPS 分阶段要求。
49
+
50
+ 直接把它们追加在提示词末尾即可,不必逐项填表。
@@ -0,0 +1,122 @@
1
+ {
2
+ "schema_version": 2,
3
+ "board": {
4
+ "id": "example_esp32s3_media_board",
5
+ "vendor": "Example Vendor",
6
+ "model": "ESP32-S3 Media Board",
7
+ "hardware_revision": "unspecified"
8
+ },
9
+ "sources": [
10
+ {
11
+ "id": "board-materials",
12
+ "kind": "user-supplied-materials",
13
+ "location": "user-supplied://board-materials",
14
+ "revision": "unspecified"
15
+ }
16
+ ],
17
+ "soc": {
18
+ "target": "esp32s3",
19
+ "module": "ESP32-S3-WROOM-1-N16R8",
20
+ "flash_mb": 16,
21
+ "psram_mb": 8,
22
+ "source_refs": [
23
+ "board-materials"
24
+ ]
25
+ },
26
+ "toolchain": {
27
+ "framework": "esp-idf",
28
+ "framework_version": "5.5.x",
29
+ "verification": "extracted",
30
+ "tirtc": {
31
+ "platform": "espressif-esp32s3",
32
+ "version": "2.3.0",
33
+ "sdk_path": "device-sim/sdk/espressif-esp32s3/2.3.0",
34
+ "build_contract": "manifest/build-contract.env"
35
+ },
36
+ "source_refs": [
37
+ "board-materials"
38
+ ]
39
+ },
40
+ "camera": {
41
+ "present": null,
42
+ "sensor": null,
43
+ "interface": null,
44
+ "selected_video_profile": null,
45
+ "video_profiles": [],
46
+ "source_refs": [
47
+ "board-materials"
48
+ ]
49
+ },
50
+ "audio_input": {
51
+ "present": null,
52
+ "interface": null,
53
+ "codecs": [],
54
+ "source_refs": [
55
+ "board-materials"
56
+ ]
57
+ },
58
+ "audio_output": {
59
+ "present": null,
60
+ "interface": null,
61
+ "codecs": [],
62
+ "source_refs": [
63
+ "board-materials"
64
+ ]
65
+ },
66
+ "hardware_resources": {
67
+ "i2c": {
68
+ "used": null,
69
+ "driver_family": null,
70
+ "single_driver_family": null,
71
+ "verification": "extracted"
72
+ },
73
+ "i2s": {
74
+ "used": null,
75
+ "controller_and_gpio_ownership_resolved": null,
76
+ "verification": "extracted"
77
+ },
78
+ "audio_channel_mapping": {
79
+ "required": null,
80
+ "resolved": null,
81
+ "verification": "extracted"
82
+ },
83
+ "camera_realtime": {
84
+ "pipeline_safe": null,
85
+ "verification": "extracted"
86
+ },
87
+ "memory": {
88
+ "startup_and_media_budgeted": null,
89
+ "verification": "extracted"
90
+ },
91
+ "source_refs": [
92
+ "board-materials"
93
+ ]
94
+ },
95
+ "onboarding": {
96
+ "wifi_credentials": {
97
+ "selected_method": null,
98
+ "methods": [],
99
+ "credentials_committed_to_source": null,
100
+ "reprovisioning_defined": null
101
+ },
102
+ "device_binding": {
103
+ "selected_method": null,
104
+ "methods": [],
105
+ "credentials_committed_to_source": null,
106
+ "stored_credential_state_handled": null,
107
+ "clear_binding_control": null
108
+ },
109
+ "source_refs": [
110
+ "board-materials"
111
+ ]
112
+ },
113
+ "runtime_evidence": [],
114
+ "features": {
115
+ "requested": [
116
+ "h5_live_audio",
117
+ "h5_live_video",
118
+ "h5_talkback",
119
+ "ai_talk"
120
+ ]
121
+ }
122
+ }
@@ -5,6 +5,9 @@
5
5
  - Board ID: `{{BOARD_ID}}`
6
6
  - Model/revision: `{{BOARD_MODEL_REVISION}}`
7
7
  - Requested features: `{{REQUESTED_FEATURES}}`
8
+ - Selected media profile: `{{SELECTED_MEDIA_PROFILE}}`
9
+ - Selected Wi-Fi credential method: `{{SELECTED_WIFI_METHOD}}`
10
+ - Selected device-binding method: `{{SELECTED_BINDING_METHOD}}`
8
11
  - Output project: `{{PROJECT_PATH}}`
9
12
 
10
13
  ## Locked inputs
@@ -46,6 +49,18 @@
46
49
  - Firmware SHA-256: `{{FIRMWARE_SHA256}}`
47
50
  - Flash command/result: `{{FLASH_RESULT}}`
48
51
 
52
+ ## Artifact-bound runtime evidence
53
+
54
+ | Artifact SHA-256 | Acceptance levels | Observations | Current/superseded |
55
+ |---|---|---|---|
56
+ | | | | |
57
+
58
+ ## Runtime metrics
59
+
60
+ - Wi-Fi BSSID/channel/RSSI and roaming: `{{WIFI_RUNTIME_METRICS}}`
61
+ - Media tx/rx/drop/error and queue watermarks: `{{MEDIA_RUNTIME_METRICS}}`
62
+ - Camera overflow, internal heap/largest block, PSRAM: `{{RESOURCE_RUNTIME_METRICS}}`
63
+
49
64
  ## Remaining work and risks
50
65
 
51
66
  `{{REMAINING_WORK}}`
@@ -1,32 +1,57 @@
1
1
  # Capability rules
2
2
 
3
- Run `hardware_ir.py assess --strict` before generation. The script applies the minimum current starter contract; use this reference when explaining or extending the result.
3
+ Run `hardware_ir.py assess --strict` before generation. Hardware IR v2 validates the selected product contract rather than assuming one video codec or provisioning method. Schema v1 remains readable for existing H.264 projects.
4
4
 
5
5
  ## Current starter contract
6
6
 
7
7
  | Feature | Required hardware/media path |
8
8
  |---|---|
9
- | `h5_live_audio` | Microphone path that produces G.711 A-law, 8 kHz, mono for stream 10 |
10
- | `h5_live_video` | Camera plus H.264 Annex-B access units, SPS/PPS and IDR, and key-frame request control for stream 11 |
11
- | `h5_talkback` | G.711 A-law, 8 kHz downlink decode and speaker path for stream 14 |
12
- | `ai_talk` | A-law 8 kHz microphone and speaker paths for AI stream 1, started only after `start_session` succeeds |
9
+ | `h5_live_audio` | Microphone path producing G.711 A-law, 8 kHz, mono for stream 10; audio controller/channel ownership and memory budget resolved |
10
+ | `h5_live_video` | Camera plus the selected MJPEG, H.264, or H.265 profile for stream 11; refresh/key-frame control, realtime pipeline, and memory budget resolved |
11
+ | `h5_talkback` | G.711 A-law, 8 kHz downlink decode and speaker path for stream 14; audio controller/GPIO ownership and memory budget resolved |
12
+ | `ai_talk` | A-law 8 kHz microphone and speaker paths for AI stream 1, started only after `start_session`; audio ownership/channel mapping and memory budget resolved |
13
13
 
14
- The complete media path must be at least `corroborated` to become `READY_TO_PORT`. A path with unknown facts is `NEEDS_CONFIRMATION`; a confirmed missing or incompatible resource is `BLOCKED`. Only an end-to-end board run becomes `HIL_VERIFIED`.
14
+ The complete media path must be at least `corroborated` to become `READY_TO_PORT`. A path with unknown facts is `NEEDS_CONFIRMATION`; a confirmed missing or incompatible resource is `BLOCKED`.
15
15
 
16
- ## Non-negotiable checks
16
+ ## Selected video profiles
17
+
18
+ Hardware IR v2 stores one or more `camera.video_profiles` and exactly one selected profile for H5 video:
19
+
20
+ | Codec | Required output contract |
21
+ |---|---|
22
+ | `mjpeg` | `jpeg_complete_frames`: one complete JPEG per send; each frame independently refreshable |
23
+ | `h264` | `h264_annex_b_access_units`: Annex-B access units with SPS/PPS and IDR request behavior |
24
+ | `h265` | `h265_annex_b_access_units`: Annex-B access units with parameter-set and refresh behavior defined by the coordinated H5 contract |
25
+
26
+ Available but unselected profiles do not satisfy or block the selected contract. Stream IDs and codec support must come from the applicable ThingConnect/H5 contract, not this table alone.
27
+
28
+ ## Project gates
29
+
30
+ Schema v2 also requires:
31
+
32
+ - one evidenced I2C driver family when I2C is used;
33
+ - a selected Wi-Fi credential method that is available, reprovisionable, and keeps credentials outside source control;
34
+ - one evidenced binding method—verification code, factory-bound identity, development credentials, or documented custom flow—plus stored-binding behavior and reset control;
35
+ - feature-specific I2S/GPIO ownership, channel/TDM mapping, realtime camera policy, and startup/media memory budget.
36
+
37
+ SoftAP is one Wi-Fi option, not a universal requirement. BLE, SmartConfig, factory NVS, development configuration, or a documented custom method can satisfy intake when the selected path is evidenced. Committed plaintext credentials are always `BLOCKED`.
38
+
39
+ ## Non-negotiable runtime checks
17
40
 
18
41
  - Match the TiRTC precompiled SDK platform to the ESP-IDF target and its `manifest/build-contract.env` to the generated configuration.
19
- - Keep H5 stream IDs and formats stable unless the user explicitly authorizes a coordinated public contract change across the server and all consumers.
20
- - Start AI media only after the successful `start_session` response, and stop/flush media before disconnecting the session.
21
- - Copy SDK callback payloads into bounded queues before returning. Perform decoding, playback, HTTP, and lifecycle changes outside SDK callbacks.
42
+ - Keep H5 stream IDs and formats stable unless the user explicitly authorizes a coordinated contract change across the server and consumers.
43
+ - Start AI media only after the successful `start_session` response; stop and flush media before disconnecting.
44
+ - Copy SDK callback payloads into bounded queues before returning. Perform decoding, playback, HTTP, and lifecycle changes outside callbacks.
22
45
  - Use monotonic timestamps and session generation to reject stale frames and delayed callbacks.
46
+ - Record runtime evidence with the exact BIN/ELF SHA-256. Use `assess --artifact-sha256 <sha>`; documentation verification alone never becomes v2 `HIL_VERIFIED`.
23
47
 
24
48
  ## Typical blocked cases
25
49
 
26
- - A camera outputs JPEG but no evidenced H.264 encoder produces Annex-B access units.
27
- - The board has a microphone but no encoder path for the required A-law sample rate.
28
- - The board has a codec but its playback pins, clock, amplifier enable, or BSP driver remain unknown.
29
- - A generic ESP32-S3 module is named without the carrier board that defines camera/audio wiring.
30
- - The available TiRTC archive targets another chip, ESP-IDF ABI, or FreeRTOS configuration.
50
+ - The selected MJPEG/H.264/H.265 profile lacks its required output or refresh semantics.
51
+ - Audio hardware exists, but the A-law path, physical channel/TDM slot, clock, amplifier, or resource ownership is unresolved.
52
+ - Third-party components introduce both legacy and new ESP-IDF I2C drivers.
53
+ - A generic ESP32-S3 module is named without the carrier board wiring and hardware revision.
54
+ - Wi-Fi credentials are embedded in tracked source, or no available/reprovisionable credential path is selected.
55
+ - The TiRTC archive targets another chip, ESP-IDF ABI, or FreeRTOS configuration.
31
56
 
32
- When a blocked case would require changing the H5 contract, replacing hardware, or obtaining a new TiRTC SDK build, report those alternatives instead of silently changing the project.
57
+ When a blocked case requires changing a public contract, replacing hardware, obtaining a new SDK, or choosing a provisioning policy, report alternatives instead of silently changing the project.
@@ -1,5 +1,26 @@
1
1
  # ESP-IDF environment
2
2
 
3
+ ## Managed one-command setup
4
+
5
+ Prefer the packaged setup entrypoint for a new machine:
6
+
7
+ ```bash
8
+ npx tirtc-device-builder@latest setup esp32
9
+ npx tirtc-device-builder@latest setup esp32 --install
10
+ ```
11
+
12
+ The first command is read-only. The second command is explicit authorization to install missing user-space components at the printed destinations. Its default root is `~/.tirtc-device-builder`; it downloads and verifies the pinned ESP32 Device Kit, installs the Skill, clones or reuses ESP-IDF 5.5.4, runs Espressif's `install.sh esp32s3`, writes `config.json` and `env.sh`, and reruns the Doctor inside the activated environment.
13
+
14
+ The automatic branch never runs `sudo` or modifies a persistent shell profile. When system dependencies are missing, report its exact blocker and let the user perform the displayed system action. Existing incomplete directories are preserved as blockers. Rerunning the same command resumes completed stages.
15
+
16
+ When `<setup-root>/env.sh` exists, use it only as an activation prefix for the current command:
17
+
18
+ ```bash
19
+ bash -lc '. "<setup-root>/env.sh" && python3 "<skill-dir>/scripts/doctor.py" --expected-idf 5.5 --target esp32s3 --require-workspace'
20
+ ```
21
+
22
+ The helper contains paths, not device or network credentials. Read `<setup-root>/config.json` when exact managed paths are needed; the environment helper does not authorize unrelated downloads, shell-profile changes, flashing, or credential writes.
23
+
3
24
  Run the doctor before generation, build, flash, or monitor:
4
25
 
5
26
  ```bash
@@ -11,18 +32,18 @@ python3 <skill-dir>/scripts/doctor.py \
11
32
 
12
33
  Add `--project <generated-project>` after generation so the doctor can compare `sdkconfig` or `sdkconfig.defaults` with the TiRTC SDK build contract. Use `--json` when the result will be included in another report.
13
34
 
14
- ## ThingConnect workspace
35
+ ## ESP32 Device Kit
15
36
 
16
- This distributable skill does not bundle the ThingConnect source tree or TiRTC static library. Resolve the public ThingConnect workspace in this order:
37
+ The automatic setup downloads a versioned minimal Kit instead of cloning the ThingConnect server repository. Resolve the generation root in this order:
17
38
 
18
39
  1. an explicit `--thing-connect-root <path>`;
19
40
  2. `TIRTC_THING_CONNECT_ROOT`;
20
41
  3. an ancestor of the project or current directory containing `device-sim/scripts/create_esp32_project.py`;
21
42
  4. an ancestor whose `thing-connect/` child contains that generator.
22
43
 
23
- The public source is `https://github.com/tangeai/tirtc-server-example`. Clone it only into an explicit destination. The root accepted by the doctor may be either the repository root or its `thing-connect/` child.
44
+ The default managed root is `<setup-root>/kits/esp32s3/<kit-version>`. The public ThingConnect workspace remains an optional legacy/development input; the doctor accepts either a Device Kit root, a repository root, or its `thing-connect/` child.
24
45
 
25
- SDK resolution is independent after generation: an explicit `--sdk-dir` wins, followed by `<project>/third_party/tirtc`, then the SDK packaged in the resolved ThingConnect workspace. The generated project path therefore remains diagnosable after it is moved away from the source repository.
46
+ SDK resolution is independent after generation: an explicit `--sdk-dir` wins, followed by `<project>/third_party/tirtc`, then the SDK packaged in the resolved Device Kit or legacy workspace. The generated project remains diagnosable after it is moved away from the Kit.
26
47
 
27
48
  ## Required checks
28
49