@tencent-rtc/trtc-agent-skills 0.1.1 → 0.1.3

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.
@@ -70,10 +70,17 @@ In this mode:
70
70
  `conference.createAndJoinRoom()`, `conference.joinRoom()`,
71
71
  `conference.leaveRoom()`, `conference.endRoom()`, and `RoomEvent`
72
72
  listeners as appropriate for the customer's flow.
73
- 4. For UserSig, reuse the existing MCP / local-signing / backend-issued
74
- credential flow. Do not generate `src/utils/usersig.ts`, do not expose
75
- `SecretKey` in client code, and do not use `crypto-js`, `pako`,
76
- `HmacSHA256`, or `tls-sig-api-v2` to sign UserSig in browser code.
73
+ 4. For UserSig, branch on `usersig_source` from session (see
74
+ `skills/trtc-onboarding/reference/usersig-handling.md`):
75
+ - **`local-dev`**: copy bundled signing lib to `src/config/`; collect
76
+ SDKAppID + SecretKey into `basic-info-config.ts` only; login via
77
+ `getBasicInfo(userId)` — no UserSig input on the login page.
78
+ - **`console`**: UserID + SDKAppID + UserSig paste fields; no SecretKey, no
79
+ signing bundle.
80
+ - **`backend`**: API-fetched userSig; no SecretKey, no signing bundle.
81
+ Do not generate `src/utils/usersig.ts` or hand-roll signing with
82
+ `crypto-js`, `pako`, `HmacSHA256`, or `tls-sig-api-v2`. Production MUST
83
+ use `backend`.
77
84
  5. For button / toolbar / pre-action UI adjustment, use only the official
78
85
  customization APIs: `conference.setWidgetVisible()`,
79
86
  `conference.registerWidget()`, and `conference.onWill()`.
package/AGENTS.md CHANGED
@@ -82,10 +82,17 @@ In this mode:
82
82
  `conference.createAndJoinRoom()`, `conference.joinRoom()`,
83
83
  `conference.leaveRoom()`, `conference.endRoom()`, and `RoomEvent`
84
84
  listeners as appropriate for the customer's flow.
85
- 4. For UserSig, reuse the existing MCP / local-signing / backend-issued
86
- credential flow. Do not generate `src/utils/usersig.ts`, do not expose
87
- `SecretKey` in client code, and do not use `crypto-js`, `pako`,
88
- `HmacSHA256`, or `tls-sig-api-v2` to sign UserSig in browser code.
85
+ 4. For UserSig, branch on `usersig_source` from session (see
86
+ `skills/trtc-onboarding/reference/usersig-handling.md`):
87
+ - **`local-dev`**: copy bundled signing lib to `src/config/`; collect
88
+ SDKAppID + SecretKey into `basic-info-config.ts` only; login via
89
+ `getBasicInfo(userId)` — no UserSig input on the login page.
90
+ - **`console`**: UserID + SDKAppID + UserSig paste fields; no SecretKey, no
91
+ signing bundle.
92
+ - **`backend`**: API-fetched userSig; no SecretKey, no signing bundle.
93
+ Do not generate `src/utils/usersig.ts` or hand-roll signing with
94
+ `crypto-js`, `pako`, `HmacSHA256`, or `tls-sig-api-v2`. Production MUST
95
+ use `backend`.
89
96
  5. For button / toolbar / pre-action UI adjustment, use only the official
90
97
  customization APIs: `conference.setWidgetVisible()`,
91
98
  `conference.registerWidget()`, and `conference.onWill()`.
package/CLAUDE.md CHANGED
@@ -102,10 +102,17 @@ In this mode:
102
102
  `conference.createAndJoinRoom()`, `conference.joinRoom()`,
103
103
  `conference.leaveRoom()`, `conference.endRoom()`, and `RoomEvent`
104
104
  listeners as appropriate for the customer's flow.
105
- 4. For UserSig, reuse the existing MCP / local-signing / backend-issued
106
- credential flow. Do not generate `src/utils/usersig.ts`, do not expose
107
- `SecretKey` in client code, and do not use `crypto-js`, `pako`,
108
- `HmacSHA256`, or `tls-sig-api-v2` to sign UserSig in browser code.
105
+ 4. For UserSig, branch on `usersig_source` from session (see
106
+ `skills/trtc-onboarding/reference/usersig-handling.md`):
107
+ - **`local-dev`**: copy bundled signing lib to `src/config/`; collect
108
+ SDKAppID + SecretKey into `basic-info-config.ts` only; login via
109
+ `getBasicInfo(userId)` — no UserSig input on the login page.
110
+ - **`console`**: UserID + SDKAppID + UserSig paste fields; no SecretKey, no
111
+ signing bundle.
112
+ - **`backend`**: API-fetched userSig; no SecretKey, no signing bundle.
113
+ Do not generate `src/utils/usersig.ts` or hand-roll signing with
114
+ `crypto-js`, `pako`, `HmacSHA256`, or `tls-sig-api-v2`. Production MUST
115
+ use `backend`.
109
116
  5. For button / toolbar / pre-action UI adjustment, use only the official
110
117
  customization APIs: `conference.setWidgetVisible()`,
111
118
  `conference.registerWidget()`, and `conference.onWill()`.
@@ -64,10 +64,17 @@ In this mode:
64
64
  `conference.createAndJoinRoom()`, `conference.joinRoom()`,
65
65
  `conference.leaveRoom()`, `conference.endRoom()`, and `RoomEvent`
66
66
  listeners as appropriate for the customer's flow.
67
- 4. For UserSig, reuse the existing MCP / local-signing / backend-issued
68
- credential flow. Do not generate `src/utils/usersig.ts`, do not expose
69
- `SecretKey` in client code, and do not use `crypto-js`, `pako`,
70
- `HmacSHA256`, or `tls-sig-api-v2` to sign UserSig in browser code.
67
+ 4. For UserSig, branch on `usersig_source` from session (see
68
+ `skills/trtc-onboarding/reference/usersig-handling.md`):
69
+ - **`local-dev`**: copy bundled signing lib to `src/config/`; collect
70
+ SDKAppID + SecretKey into `basic-info-config.ts` only; login via
71
+ `getBasicInfo(userId)` — no UserSig input on the login page.
72
+ - **`console`**: UserID + SDKAppID + UserSig paste fields; no SecretKey, no
73
+ signing bundle.
74
+ - **`backend`**: API-fetched userSig; no SecretKey, no signing bundle.
75
+ Do not generate `src/utils/usersig.ts` or hand-roll signing with
76
+ `crypto-js`, `pako`, `HmacSHA256`, or `tls-sig-api-v2`. Production MUST
77
+ use `backend`.
71
78
  5. For button / toolbar / pre-action UI adjustment, use only the official
72
79
  customization APIs: `conference.setWidgetVisible()`,
73
80
  `conference.registerWidget()`, and `conference.onWill()`.
@@ -331,6 +331,14 @@ slices:
331
331
  description: 官方 RoomKit 集成模式下 conference 对象的完整 API 签名、枚举定义、调用时序和代码示例(ui_mode=official-roomkit 专用)
332
332
  status: active
333
333
 
334
+ - id: conference/integration-audit
335
+ name: Conference Web 集成审计
336
+ tags: [audit, checklist, meta, integration-review, roomkit, online-classroom]
337
+ platforms: [web]
338
+ file: slices/conference/web/integration-audit.md
339
+ description: 横切对照官方 Conference Web 接入流程的审计清单;Path B intent F 使用,不进 scenario 集成队列
340
+ status: active
341
+
334
342
  # ============================================================
335
343
  # Scenarios — 场景组合索引
336
344
  # ============================================================
@@ -236,12 +236,15 @@ slices:
236
236
  ```
237
237
  我帮你定位到「通用会议」场景。会议骨架(登录、会前预览、房间生命周期、成员列表、画面布局、设备控制、网络质量)会默认集成。
238
238
 
239
- 你的需求里我识别到要这些增强能力(已勾选):{命中的可选模块中文名}
239
+ 你的需求里我识别到要这些增强能力:{命中的可选模块中文名}
240
240
 
241
- 还要加别的吗?(可多选;如果都不需要,请选择「以上都不需要」)
241
+ 以上无误吗?
242
242
  ```
243
243
 
244
- 3. **AskUserQuestion**:对「可选模块」做一次多选(`multiSelect: true`),选项 label 用上面的中文名,**预勾选第 1 步命中的项**。一次超过 4 项时按"会中协作 / 视频效果 / 预约邀请"分组拆成多次问(遵守 4 选项上限)。**每组多选必须包含一个「以上都不需要」选项(value=`none`),放在选项列表末尾,作为用户显式拒绝该组所有能力的出口。选中`none`时,该组其他选项视为未勾选;同时选中`none`和其他选项时,以`none`为准(清空其他选择)。**
244
+ 3a. **确认优先(`target_features` 已明确时)**:若第 1 步命中的可选模块非空且映射清晰,用 `AskUserQuestion` 单次确认:(1) 确认,按此集成 直接写 `confirmed_plan`;(2) 需要调整 再走下方多选。不要把用户已在 prompt 里点名的能力再让用户选一遍。
245
+
246
+ 3b. **多选(仅当 `target_features` 为空/模糊,或用户选「需要调整」)**:对「可选模块」做 `multiSelect: true` 多选,预勾选第 1 步命中的项。一次超过 4 项时分组。每组末尾含「以上都不需要」(`none`)。
247
+
245
248
  4. **写 `confirmed_plan`**:`confirmed_plan = 必装骨架 + 用户最终选中的可选模块`(去重,保持上面声明的顺序)。这是 `init_slice_queue.py` 的唯一输入,后续 A2-Q1.5 业务决策、slice 循环、apply 都以它为准。
246
249
  5. **不要**把未选中的可选模块写进 `confirmed_plan`,也不要在生成代码时"顺手"加它们的按钮 / composable。
247
250
  6. `enhancement_level` 仅为兼容旧字段:全部可选模块都选 → `complete`,否则 → `minimal`。真正的范围以 `confirmed_plan` 为准。
@@ -0,0 +1,155 @@
1
+ ---
2
+ id: conference/integration-audit
3
+ name: Conference Web 集成审计
4
+ product: conference
5
+ platform: web
6
+ tags: [audit, checklist, meta, integration-review, roomkit, online-classroom]
7
+ platforms: [web]
8
+ related:
9
+ - conference/login-auth
10
+ - conference/prejoin-check
11
+ - conference/room-lifecycle
12
+ - conference/room-schedule
13
+ - conference/device-control
14
+ - conference/official-roomkit-api
15
+ related_scenario: general-conference
16
+ ---
17
+
18
+ # Conference Web 集成审计
19
+
20
+ > **Meta slice** — 横切对照清单,供 Path B intent F(集成审计)使用。
21
+ > **不要**加入 scenario 的 `slices` / `confirmed_plan`,**不要**走 topic 集成队列或 apply 门禁。
22
+
23
+ > 当用户问「检查业务流程遗漏」「对照官方接入流程」「在线课堂/会议流程是否正常」时使用本 slice。
24
+ > 输出形态:**固定 checklist + slice 引用**;**不要**输出 code review、优缺点列表或「改进建议」段落。
25
+
26
+ ## 如何使用
27
+
28
+ 1. 从 session 读取 `product` / `platform` / `ui_mode` / `scenario`(若有)。
29
+ 2. 仅 `(product, platform) == (conference, web)` 时走完整清单;其他组合说明当前 skill 集成 fix 仅覆盖 Conference Web,清单仍可作为对照参考。
30
+ 3. 按角色(学生 / 老师 / 通用)裁剪章节;用户未说明角色时输出「通用骨架 + 在线课堂附录」。
31
+ 4. 每项标注:**应有** / **常见遗漏** / **对应 slice**。
32
+ 5. 用户贴了代码时,只核对清单项是否 wired up,不做风格点评。
33
+
34
+ ---
35
+
36
+ ## 1. 通用骨架(所有 Conference Web 项目)
37
+
38
+ | # | 检查项 | 常见遗漏 | 参考 slice |
39
+ |---|--------|----------|------------|
40
+ | 1.1 | `conference.login()` / `useLoginState().login()` 先于任何 room/device/chat 调用 | 未登录直接 join | `conference/login-auth` |
41
+ | 1.2 | 登录参数含 `scene: 5001`(skill 生成代码) | 缺 scene | `conference/login-auth` |
42
+ | 1.3 | 登录成功后 `setSelfInfo({ userName, avatarUrl })` | 列表只显示 userId | `conference/login-auth` |
43
+ | 1.4 | UserSig:生产由后端签发;本地可用 config 自动签名(`local-dev`)或控制台粘贴(`console`) | userId 与 userSig 不匹配 | `conference/login-auth` |
44
+ | 1.5 | 监听 `LoginEvent.onLoginExpired` / `onKickedOffline` 并收口 | 只打日志 | `conference/login-auth` |
45
+ | 1.6 | 监听 `RoomEvent.USER_SIG_EXPIRED` / `KICKED_OUT` / `ROOM_DISMISS` | 被动退出 UI 假在线 | `conference/room-lifecycle` |
46
+ | 1.7 | 页面在 **HTTPS** 或 **localhost** 下调试 | 生产 HTTP 无媒体权限 | `conference/device-control` |
47
+ | 1.8 | iframe 嵌入时宿主页 `allow="camera; microphone; display-capture; fullscreen"` | iframe 内黑屏/无权限 | `conference/device-control` |
48
+ | 1.9 | 刷新/关页时 `leaveRoom()` 或等价清理 | 幽灵参会者 | `conference/room-lifecycle` |
49
+ | 1.10 | 房主 `endRoom()` vs 成员 `leaveRoom()` 分支正确 | 老师误用 leave 导致房间未结束 | `conference/room-lifecycle` |
50
+
51
+ ---
52
+
53
+ ## 2. 会前设备检测
54
+
55
+ | # | 检查项 | 常见遗漏 | 参考 slice |
56
+ |---|--------|----------|------------|
57
+ | 2.1 | 会前用 `startCameraTest` / `stopCameraTest`,**不用** `openLocalCamera` 做预检 | getUserMedia 与 SDK 双轨冲突 | `conference/prejoin-check` |
58
+ | 2.2 | 预检页设备开关用**本地 ref**,不读 `cameraStatus` / `microphoneStatus` | 预检与会中状态串线 | `conference/prejoin-check` |
59
+ | 2.3 | 入会前 `stopCameraTest()` 释放采集 | 进房后设备占用 | `conference/prejoin-check` |
60
+ | 2.4 | 轻量 `getUserMedia` 仅作**权限门禁**;完整预览走 Atomicx 测试 API | 两套检测职责重叠 | `conference/prejoin-check` |
61
+ | 2.5 | 进房后麦克风:先 `openLocalMicrophone()` + 默认 `muteMicrophone()`;摄像头:`open/closeLocalCamera` | 开麦延迟、关摄语义错误 | `conference/device-control` |
62
+
63
+ ---
64
+
65
+ ## 3. 房间生命周期
66
+
67
+ | # | 检查项 | 常见遗漏 | 参考 slice |
68
+ |---|--------|----------|------------|
69
+ | 3.1 | 即时会议:发起人 `createAndJoinRoom`,他人 `joinRoom` | roomId 来源混乱 | `conference/room-lifecycle` |
70
+ | 3.2 | 预约会议:`scheduleRoom` 成功后,到点仍须 `joinRoom`(预约≠已入会) | 预约后直接认为在会中 | `conference/room-schedule` |
71
+ | 3.3 | `joinRoom` 失败区分:未登录 / 房间不存在 / 密码错误 / 已结束 | 统一提示「进房失败」 | `conference/room-lifecycle` |
72
+ | 3.4 | 被动退出后清理 `currentRoom`、聊天、布局、widget 注册 | 再次入会残留上一场状态 | `conference/room-lifecycle` |
73
+ | 3.5 | `passive_exit_target`:被踢/解散后跳转大厅或登录(业务决策) | 停留在空白会中页 | `conference/room-lifecycle` |
74
+
75
+ ---
76
+
77
+ ## 4. 官方 RoomKit 模式(`ui_mode = official-roomkit`)
78
+
79
+ | # | 检查项 | 常见遗漏 | 参考 slice |
80
+ |---|--------|----------|------------|
81
+ | 4.1 | 根节点 `UIKitProvider` 包裹 `PreConferenceView` / `ConferenceMainView(H5)` | Provider 缺失 | `conference/official-roomkit-api` |
82
+ | 4.2 | `setWidgetVisible` / `registerWidget` / `onWill` 在 **login 之后、join 之前** | 按钮闪烁、拦截失效 | `conference/official-roomkit-api` |
83
+ | 4.3 | `createAndJoinRoom` / `joinRoom` 成功后立即 `setFeatureConfig({ shareLink })` | 分享链接 roomId 不对 | `conference/official-roomkit-api` |
84
+ | 4.4 | 收集 `registerWidget` / `onWill` 返回的 cleanup;在 `ROOM_LEAVE` 与 `ROOM_DISMISS` 都执行 | 重复注册、泄漏 | `conference/official-roomkit-api` |
85
+ | 4.5 | UI 显隐用 `setWidgetVisible`,**不用** CSS/DOM hack | 升级 SDK 即碎 | `conference/official-roomkit-api` |
86
+ | 4.6 | lockfile 中 `@tencentcloud/roomkit-web-vue3 >= 5.4.3` | 定制 API 不可用 | `conference/official-roomkit-api` |
87
+
88
+ ---
89
+
90
+ ## 5. 在线课堂角色附录
91
+
92
+ ### 学生链路
93
+
94
+ ```text
95
+ 登录 → setSelfInfo → 预约列表(room-schedule) → 会前检测(prejoin-check)
96
+ → joinRoom → 会中(默认禁麦策略)→ 主动 leaveRoom / 被动 ROOM_DISMISS
97
+ ```
98
+
99
+ | 常见遗漏 | 说明 |
100
+ |----------|------|
101
+ | 预约后直接进房未做设备检测 | 应用 prejoin-check 页或等价流程 |
102
+ | 被房主结束会议无提示 | 监听 `RoomEvent.ROOM_DISMISS` |
103
+ | 与「只 join 不 create」的 roomid_origin 不一致 | session 业务决策应对齐 |
104
+
105
+ ### 老师链路
106
+
107
+ ```text
108
+ 登录 → setSelfInfo → createAndJoinRoom → 会中开启 AI 字幕(ai-tools) / 录制(控制台+套餐)
109
+ → endRoom(非 leaveRoom)
110
+ ```
111
+
112
+ | 常见遗漏 | 说明 |
113
+ |----------|------|
114
+ | AI 字幕非房主也调 `startRealtimeTranscriber` | 仅房主应启动 |
115
+ | 结束会议用 `leaveRoom` 而非 `endRoom` | 其他成员仍留在已结束房间上下文 |
116
+ | 录制能力未在控制台开通 | 预制 UI 按钮灰显或启动失败 |
117
+
118
+ ---
119
+
120
+ ## 6. 高频运行时问题速查(审计时顺带提及)
121
+
122
+ | 现象 / 错误码 | 结论 | 下一步 |
123
+ |---------------|------|--------|
124
+ | **6206** / UserSig expired | 鉴权失败 | 后端刷新 UserSig;监听 `USER_SIG_EXPIRED` |
125
+ | **100211** take-seat not enabled | 非麦位房间内部 seat 同步 | Standard 会议通常**可忽略**;确认未调用上麦/连麦 API |
126
+ | **100006** only open to live room | 在 Standard 房间调了 Live 接口 | 检查 roomType;隐藏 Live 工具栏 widget |
127
+ | 双设备检测冲突 | 职责未分层 | 见 §2 |
128
+ | iframe 无画面 | 缺 allow 权限 | 见 §1.8 |
129
+ | 刷新后幽灵在线 | 未 beforeunload leave | 见 §1.9 |
130
+
131
+ ---
132
+
133
+ ## 7. 推荐输出模板(给 AI)
134
+
135
+ ```markdown
136
+ ## Conference Web 集成对照结果
137
+
138
+ **场景**:{scenario 或「通用会议」} · **UI 模式**:{official-roomkit | headless | 未知}
139
+
140
+ ### 已覆盖(对照官方流程)
141
+ - …
142
+
143
+ ### 可能遗漏(按优先级)
144
+ 1. … → 参考 `conference/xxx`
145
+ 2. …
146
+
147
+ ### 环境/权限门禁
148
+ - HTTPS / iframe / UserSig:…
149
+
150
+ ### 官方文档
151
+ - [Web RoomKit 快速接入](https://cloud.tencent.com/document/product/647/81962)
152
+ - [设备检测](https://cloud.tencent.com/document/product/647/126939)
153
+ ```
154
+
155
+ **禁止**使用的标题:Critical Review Checklist、改进建议、✅正确 vs ❌错误 对比表(作为主结构)。
@@ -14,7 +14,8 @@ business_decisions:
14
14
  tier: blocking
15
15
  question: "您的项目当前处于哪个阶段?这决定鉴权凭证(UserSig)的生成方式。"
16
16
  options:
17
- - { label: "本地开发 / 调试 —— 控制台临时签发,几分钟即可跑通;有有效期、不能用于生产", value: "console" }
17
+ - { label: "本地开发 —— config 配置 SDKAppID+SecretKey,登录时按 UserID 自动签名(推荐,最快)", value: "local-dev" }
18
+ - { label: "本地开发 / 调试 —— 到控制台生成 UserSig,复制粘贴到登录页(不配置 SecretKey)", value: "console" }
18
19
  - { label: "生产环境(上线)—— 由您的后端接口签发,安全合规(推荐)", value: "backend" }
19
20
  - key: userid_strategy
20
21
  tier: blocking
@@ -57,39 +57,67 @@ platform: web
57
57
  | 1 | 标题 `<h1>加入会议</h1>` | 32px |
58
58
  | 2 | 输入框:用户 ID | 16px |
59
59
  | 3 | 输入框:会议 ID(placeholder: "输入会议 ID(创建时可留空)") | 16px |
60
- | 4 | 输入框:SDKAppID | 16px |
61
- | 5 | 输入框:UserSig | 16px |
62
- | 6 | 凭证说明区(见下方规范) | 24px |
63
- | 7 | 主按钮「创建并加入」 | 24px |
64
- | 8 | 分割提示行:1px 横线 + 居中「或」 | 16px |
65
- | 9 | 次级按钮「加入已有会议」(outline 样式) | |
60
+
61
+ **按 `usersig_source` 分支追加字段(二选一,勿混用):**
62
+
63
+ | `usersig_source` | 追加字段(顺序接在会议 ID 之后) |
64
+ |---|---|
65
+ | `local-dev` | 仅凭证说明区(见 §3.1 local-dev)— **无** SDKAppID / UserSig 输入框 |
66
+ | `console` | 输入框 SDKAppID → 输入框 UserSig → 凭证说明区(见 §3.1 console) |
67
+
68
+ | # | 元素 | 与下一项的间距 |
69
+ |---|---|---|
70
+ | … | 主按钮「创建并加入」 | 24px |
71
+ | … | 分割提示行 + 「或」 | 16px |
72
+ | … | 次级按钮「加入已有会议」 | — |
73
+
74
+ > **`local-dev`**:凭证在 `src/config/basic-info-config.ts`,登录调用 `getBasicInfo(userId)`。
75
+ > **`console`**:保留 SDKAppID + UserSig 平铺输入框,UserSig 从控制台粘贴(见 `usersig-handling.md` Path B)。
66
76
 
67
77
  ### 3.1 凭证说明区规范
68
78
 
69
- SDKAppID UserSig 输入框下方,以信息提示卡片形式展示(非折叠、非 tooltip):
79
+ 在凭证相关输入框下方(或 `local-dev` 时在会议 ID 下方),以信息提示卡片展示:
70
80
 
71
81
  - 容器:背景 `#F0F6FF`,圆角 8px,内边距 12px 16px
72
82
  - 图标:左侧 ℹ️ 信息图标,颜色 `#0D6BDE`
73
83
  - 文字:12px,颜色 `#444`,行高 1.6
74
84
 
75
- 内容(固定文案,不可省略):
85
+ **`local-dev` 文案:**
86
+
87
+ ```
88
+ 本地调试:在 src/config/basic-info-config.ts 填入 SDKAppID 和 SecretKey
89
+ (控制台 → 应用管理 → 应用信息):
90
+ • 国际站:https://console.trtc.io
91
+ • 国内站:https://console.cloud.tencent.com
92
+
93
+ 登录时只需输入 UserID —— userSig 会按 UserID 自动生成,两者必须匹配。
94
+ ⚠️ SecretKey 仅用于本地调试;生产环境请由服务端签发 UserSig。
95
+ ```
96
+
97
+ **`console` 文案(固定,不可省略):**
76
98
 
77
99
  ```
78
100
  SDKAppID 和 UserSig 可从控制台获取:
79
101
  • 国际站:https://console.trtc.io
80
102
  • 国内站:https://console.cloud.tencent.com
81
103
 
82
- ⚠️ 测试 UserSig 24 小时后失效,生产环境请由服务端签发。
83
- 「服务端签发」链接指向:https://trtc.io/document/34385
104
+ 在「UserSig 生成&校验」中输入与登录页相同的 UserID 再生成 UserSig —— 两者必须匹配。
105
+ ⚠️ 测试 UserSig 约 24h 后失效;生产环境请由服务端签发。
106
+ 「服务端签发」:https://trtc.io/document/34385
84
107
  ```
85
108
 
86
109
  链接使用主色 `#0D6BDE`,hover 加下划线,`target="_blank"`。
87
110
 
88
111
  ### 3.2 输入框要求
89
112
 
90
- - 四个输入框(用户 ID、会议 ID、SDKAppID、UserSig)均为**平铺展示**,不使用折叠/展开/高级设置等隐藏形式。
91
- - 若通过 MCP 获取到 SDKAppID UserSig,可预填值但仍保持输入框可见可编辑。
92
- - UserSig 输入框使用 `type="password"` 遮罩显示。
113
+ **`local-dev`:**
114
+ - 仅用户 ID、会议 ID;SDKAppID / SecretKey 在 `basic-info-config.ts`。
115
+ - 禁止 UserSig 手填框。
116
+
117
+ **`console`:**
118
+ - 用户 ID、会议 ID、SDKAppID、UserSig 四个输入框均平铺展示。
119
+ - UserSig 使用 `type="password"`。
120
+ - 凭证说明必须强调 **控制台生成 UserSig 时 UserID 与登录页一致**。
93
121
 
94
122
  约束要点:
95
123
  - 卡片内每个表单元素**宽度 100%**(撑满卡片内边距宽度)。
@@ -82,12 +82,12 @@ camera-testing / microphone-testing / speaker-testing
82
82
 
83
83
  1. **把入会前完整检查流程与真实入会控制拆成两段主链路** —— 用户先完成会前自检,再进入房间主链路;会中如需局部检查,应由会中设备能力单独承接。
84
84
  2. **把用户选定的设备延续到会中** —— 会前选好的摄像头、麦克风和扬声器应直接复用于会中控制。
85
- 3. **在页面卸载或进入会议前停止测试** —— 避免会前测试与会中真实采集相互冲突。
85
+ 3. **在页面卸载、路由离开或进入会议前停止全部测试** —— 必须调用 `stopCameraTest()` 与 `stopSpeakerTest()`(若 SDK 暴露),避免会前测试与会中真实采集冲突,以及扬声器测试音贯穿整场会议。
86
86
  4. **把权限拒绝和设备缺失写成可执行提示** —— 告诉用户下一步该切浏览器权限、换设备,还是直接降级进入。
87
87
 
88
88
  ### ❌ NEVER
89
89
 
90
- 1. **不要把会前测试残留到会中流程里** —— 测试流和真实采集流应在入会时完成切换。
90
+ 1. **不要把会前测试残留到会中流程里** —— 测试流和真实采集流应在入会时完成切换;`startSpeakerTest` 后未 `stopSpeakerTest` 会导致测试音循环播放至会议结束。
91
91
  2. **不要只测试摄像头而忽略麦克风和扬声器** —— 用户真实会议体验依赖完整的音视频链路。
92
92
  3. **不要在测试失败时静默继续入会** —— 如果关键设备不可用,应给出明确风险提示或修复建议。
93
93
 
@@ -103,6 +103,7 @@ const {
103
103
  stopCameraTest,
104
104
  startMicrophoneTest,
105
105
  startSpeakerTest,
106
+ stopSpeakerTest,
106
107
  currentMicVolume,
107
108
  } = useDeviceState();
108
109
 
@@ -130,7 +131,8 @@ async function toggleCameraPreview(view: HTMLElement) {
130
131
  }
131
132
  }
132
133
 
133
- // 入会前停止测试释放设备资源
134
+ // 入会前停止测试释放设备资源(扬声器测试音必须停止,否则会贯穿整场会议)
135
+ await stopSpeakerTest?.();
134
136
  await stopCameraTest();
135
137
  ```
136
138
 
@@ -163,6 +165,7 @@ onMounted(async () => {
163
165
  });
164
166
 
165
167
  onUnmounted(async () => {
168
+ await stopSpeakerTest?.();
166
169
  await stopCameraTest();
167
170
  });
168
171
 
@@ -239,8 +242,8 @@ export function useConferenceDevice() {
239
242
 
240
243
  1. **在预览容器准备好后再调用 `startCameraTest()`** — 否则本地预览无法正常渲染。
241
244
  **Verify**: 检查是否为 `view` 传入真实 DOM 节点。
242
- 2. **在页面离开或流程结束时停止测试**否则设备资源会残留占用。
243
- **Verify**: 检查是否存在 `stopCameraTest()` 或等价清理逻辑。
245
+ 2. **在页面离开或流程结束时停止全部测试**必须配对 `stopCameraTest()` 与 `stopSpeakerTest()`(入会按钮点击、路由离开、`onUnmounted` 三处至少覆盖入会路径)。
246
+ **Verify**: 搜索 `stopCameraTest` 与 `stopSpeakerTest`(或 SDK 等价 API)。
244
247
 
245
248
  #### MUST NOT(生成时绝不能出现)
246
249
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tencent-rtc/trtc-agent-skills",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Installer for the TRTC Agent Skills suite (Chat, Call, RTC Engine, Live, Conference) + knowledge base, with one-command MCP setup for Claude Code / Cursor / CodeBuddy / Codex.",
5
5
  "bin": {
6
6
  "trtc-agent-skills": "bin/cli.js"
@@ -143,15 +143,16 @@ Route to `../trtc-onboarding/SKILL.md` when ANY of these are true:
143
143
  - User asks for specific API details ("what are the parameters for applyForSeat?") → `docs` skill (follows slice-first fallback chain)
144
144
  - User asks a fact / decision question (pricing, quotas, product comparison, migration) → `docs` skill (reads llms.txt directly)
145
145
 
146
- **Review-request handling (hard rule — triage, do NOT refuse):** When the user uses review / audit / cross-check / validate / 帮我看看 / 是否正确 / check my X wording, do NOT perform a code-style review AND do NOT refuse outright. Instead **triage to the underlying intent** and route accordingly. The authoritative A/B/C/D/E triage logic (including the Decline template for option E) lives in `../trtc-onboarding/reference/path-b-troubleshoot.md` → **B-Q0**. On a review-worded turn, route to onboarding Path B so it can run B-Q0; for quick lookup from the root:
146
+ **Review-request handling (hard rule — triage, do NOT refuse):** When the user uses review / audit / cross-check / validate / 帮我看看 / 是否正确 / check my X wording, do NOT perform a code-style review AND do NOT refuse outright. Instead **triage to the underlying intent** and route accordingly. The authoritative A/B/C/D/E/F triage logic (including the Decline template for option E) lives in `../trtc-onboarding/reference/path-b-troubleshoot.md` → **B-Q0**. On a review-worded turn, route to onboarding Path B so it can run B-Q0; for quick lookup from the root:
147
147
 
148
- - A. Symptom with pasted code ("doesn't work", crash, black screen, login fails) → onboarding Path B → B-Q1 symptom tree
148
+ - A. Runtime symptom ("doesn't work", crash, black screen, login fails, 进房失败) → onboarding Path B → B-Q1 symptom tree (Conference Web menu when applicable)
149
149
  - B/C/D. Error code / official pattern / API comparison → `docs` skill (slice-first fallback chain)
150
+ - F. Integration audit (检查遗漏 / 业务流程 / 对照官方 / 在线课堂流程) → Path B → **B-Audit** (`conference/integration-audit` slice)
150
151
  - E. Pure style/quality review with no concrete question → Decline (apply is internal quality gate, not user-facing review)
151
152
 
152
- See B-Q0 in path-b-troubleshoot.md for signals, option E decline template, and the full self-check list. If the intent is ambiguous, B-Q0 will ask ONE triage question. Never just say "I don't do code review" and stop — land the user on A–D if any signal is there.
153
+ See B-Q0 in path-b-troubleshoot.md for signals, option E decline template, and the full self-check list. If the intent is ambiguous, B-Q0 will ask ONE triage question. Never just say "I don't do code review" and stop — land the user on A–F if any signal is there.
153
154
 
154
- **Answer-shape constraint (applies on every turn):** even when routing to A–D, your reply MUST NOT take review shapes — no "Critical Review Checklist", no "✅ Correct pattern vs ❌ Incorrect pattern" contrast as the main structure, no "Improvements you should make" list, no "Fixed version of your code" as a finished artifact. These shapes, produced after a review-worded request, constitute review behaviour even without the words "apply skill" / "verify" / "review your code". Use documentation / factual-lookup shapes instead (cite slice X, quote official pattern, link the error-code doc).
155
+ **Answer-shape constraint (applies on every turn):** even when routing to A–F, your reply MUST NOT take review shapes — no "Critical Review Checklist", no "✅ Correct pattern vs ❌ Incorrect pattern" contrast as the main structure, no "Improvements you should make" list, no "Fixed version of your code" as a finished artifact. These shapes, produced after a review-worded request, constitute review behaviour even without the words "apply skill" / "verify" / "review your code". Use documentation / factual-lookup shapes instead (cite slice X, quote official pattern, link the error-code doc). Intent **F** (integration audit) may use the `conference/integration-audit` checklist shape.
155
156
 
156
157
  **The key distinction:** "I want to ADD/BUILD/IMPLEMENT X" → onboarding Path A2. "I want to UNDERSTAND/LEARN about X" → `docs` skill.
157
158
 
@@ -316,8 +317,8 @@ These rules are checked on **every turn**. If anything above conflicts with a ru
316
317
  **NEVER call any other MCP tool**, regardless of prefix
317
318
  (`mcp__tencentcloud-sdk-mcp__` / `mcp__tencent-rtc__` or any other). This
318
319
  explicitly includes:
319
- - `get_usersig` — the skill does NOT generate UserSig; the user obtains a test
320
- UserSig from the TRTC console (see `../trtc-onboarding/reference/usersig-handling.md`)
320
+ - `get_usersig` — use bundled local signing per
321
+ `../trtc-onboarding/reference/usersig-handling.md` (medical-template config pattern)
321
322
  - `get_callkit_api`, `get_faq`, `get_native_*`, `get_web_*`,
322
323
  `present_framework_choice` — these doc tools bypass the skill's knowledge
323
324
  base; answer from slices / llms.txt via `../trtc-docs/SKILL.md` instead
@@ -57,12 +57,7 @@ RoomKit** 时,走官方 RoomKit 集成模式。
57
57
  4. 房间号 `roomId` 必须来自业务系统或由业务系统保证唯一;在线问诊、1v1 客服等
58
58
  双方不确定谁先建房的场景,可统一用业务单据号作为 `roomId` 并调用
59
59
  `conference.createAndJoinRoom()`。
60
- 5. UserSig 处理必须复用 `skills/trtc-onboarding/reference/usersig-handling.md`
61
- 的规则:生成占位符 `userSig` + 引导用户去 TRTC 控制台获取测试 UserSig 填入
62
- (skill 不自动签发),正式环境由业务后端签发;前端只保留
63
- `SDKAppID / userId / userSig` 输入项或占位。
64
- 不要生成 `src/utils/usersig.ts`,不要在前端依赖 `SecretKey`,不要用 `crypto-js`、
65
- `pako`、`HmacSHA256` 或 `tls-sig-api-v2` 在浏览器端签名。
60
+ 5. UserSig:`usersig-handling.md` 三路径 — `local-dev`(bundled lib)、`console`(控制台粘贴,保留)、`backend`(生产)。
66
61
  6. 按钮、工具栏、内置按钮点击前拦截只使用官方界面微调 API:
67
62
  `conference.setWidgetVisible()` 隐藏/恢复内置按钮,
68
63
  `conference.registerWidget()` 添加自定义业务按钮或侧边面板,
@@ -83,9 +78,9 @@ RoomKit** 时,走官方 RoomKit 集成模式。
83
78
  `ui-*` class 数量规则。
84
79
  - 不要手写一套替代 RoomKit 主界面的会议 SFC;官方组件承担会议主界面,业务侧只
85
80
  负责外层路由、登录、房间号、事件监听和官方 UI 微调 API。
86
- - 不要生成前端 UserSig 签名器,尤其不要生成 `src/utils/usersig.ts`、不要把
87
- `SecretKey` 放进 `src/config.ts`、不要新增 `crypto-js` / `pako` / `tls-sig-api-v2`
88
- 这类仅用于浏览器端签名的依赖。
81
+ - 本地开发可使用 bundled signing lib(`src/config/basic-info-config.ts` + `lib-generate-test-usersig-es.min.js`),
82
+ 与医疗模板同源;生产环境禁止把 SecretKey 放进客户端。
83
+ - 不要手写 `src/utils/usersig.ts`,不要新增 `crypto-js` / `pako` / `tls-sig-api-v2`。
89
84
  - 不要用 CSS 选择器或 DOM hack 修改 RoomKit 内部按钮显隐、点击前权限和工具栏
90
85
  扩展;这些需求必须使用 `setWidgetVisible()`、`registerWidget()`、`onWill()`。
91
86
  - 不要在进房前写死 `setFeatureConfig({ shareLink })`;分享链接依赖最终 `roomId`,
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Local development credentials — Conference Web integration.
3
+ *
4
+ * ⚠️ SDKSECRETKEY is for local debugging ONLY. Do NOT ship to production.
5
+ * Production UserSig MUST be issued by your backend.
6
+ *
7
+ * Source bundle (copy all 3 files into the target project's src/config/):
8
+ * skills/trtc/room-builder/assets/local-usersig/
9
+ * Same signing lib as the medical-consultation template config.
10
+ */
11
+ import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min';
12
+
13
+ export const SDKAPPID = 0;
14
+ export const SDKSECRETKEY = '';
15
+ export const EXPIRETIME = 604800;
16
+
17
+ export function assertBasicInfoConfigured() {
18
+ if (!Number(SDKAPPID) || !String(SDKSECRETKEY).trim()) {
19
+ throw new Error(
20
+ '请先在 src/config/basic-info-config.ts 中配置 SDKAPPID 和 SDKSECRETKEY'
21
+ );
22
+ }
23
+ }
24
+
25
+ /** Generate login params for the given userId. userSig always matches userId. */
26
+ export function getBasicInfo(userId: string) {
27
+ assertBasicInfoConfigured();
28
+ const generator = new LibGenerateTestUserSig(
29
+ SDKAPPID,
30
+ SDKSECRETKEY,
31
+ EXPIRETIME
32
+ );
33
+ return {
34
+ sdkAppId: SDKAPPID,
35
+ userId,
36
+ userSig: generator.genTestUserSig(userId),
37
+ scene: 5001 as const,
38
+ };
39
+ }
@@ -0,0 +1,4 @@
1
+ export default class LibGenerateTestUserSig {
2
+ constructor(sdkAppId: number, secretKey: string, expireTime: number);
3
+ genTestUserSig(userId: string): string;
4
+ }