@tencent-rtc/trtc-agent-skills 0.1.0 → 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.
- package/.cursor/rules/ui-mode.mdc +99 -0
- package/AGENTS.md +111 -0
- package/CLAUDE.md +133 -0
- package/CODEBUDDY.md +131 -0
- package/README.md +28 -42
- package/README.zh.md +24 -42
- package/ai-instructions/base.md +13 -0
- package/ai-instructions/ui-mode.md +93 -0
- package/bin/cli.js +428 -13
- package/hooks/cursor-adapter.py +315 -0
- package/hooks/hooks-cursor.json +39 -0
- package/hooks/hooks.json +67 -0
- package/knowledge-base/index.yaml +8 -0
- package/knowledge-base/scenarios/conference/base/general-conference.md +6 -3
- package/knowledge-base/slices/conference/web/integration-audit.md +155 -0
- package/knowledge-base/slices/conference/web/login-auth.md +2 -1
- package/knowledge-base/slices/conference/web/official-roomkit-login-ui.md +41 -13
- package/knowledge-base/slices/conference/web/prejoin-check.md +8 -5
- package/package.json +7 -1
- package/skills/trtc/SKILL.md +7 -6
- package/skills/trtc/room-builder/SKILL.md +4 -9
- package/skills/trtc/room-builder/assets/local-usersig/basic-info-config.ts +39 -0
- package/skills/trtc/room-builder/assets/local-usersig/lib-generate-test-usersig-es.min.d.ts +4 -0
- package/skills/trtc/room-builder/assets/local-usersig/lib-generate-test-usersig-es.min.js +2 -0
- package/skills/trtc-onboarding/SKILL.md +35 -33
- package/skills/trtc-onboarding/reference/path-a2-integrate.md +101 -57
- package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +139 -68
- package/skills/trtc-onboarding/reference/reporting-protocol.md +2 -0
- package/skills/trtc-onboarding/reference/usersig-handling.md +98 -104
- package/skills/trtc-search/SKILL.md +7 -0
- package/skills/trtc-topic/SKILL.md +26 -42
- package/skills/trtc-apply/guardrails/apply_lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/trtc-apply/guardrails/apply_lib/__pycache__/rule_parser.cpython-313.pyc +0 -0
- package/skills/trtc-topic/guardrails/__pycache__/gate_slice_read.cpython-313.pyc +0 -0
- package/skills/trtc-topic/guardrails/__pycache__/gate_slice_write.cpython-313.pyc +0 -0
- package/skills/trtc-topic/guardrails/__pycache__/stop_require_apply_evidence.cpython-313.pyc +0 -0
- package/skills/trtc-topic/scripts/__pycache__/apply.cpython-313.pyc +0 -0
- package/skills/trtc-topic/scripts/lib/__pycache__/state_machine.cpython-313.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.3.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.3.pyc +0 -0
|
@@ -108,39 +108,40 @@ Before showing any menu, check `scenario` already in `${CLAUDE_PROJECT_DIR}/.trt
|
|
|
108
108
|
|
|
109
109
|
| Inferred `scenario` | Confidence signal (from user's first message) | Action |
|
|
110
110
|
|---|---|---|
|
|
111
|
-
| `general-conference` |
|
|
112
|
-
| `1v1-video-consultation` |
|
|
113
|
-
| `general-conference` AND `1v1-video-consultation` both inferred (rare
|
|
114
|
-
| Neither inferred (`scenario = null`)
|
|
111
|
+
| `general-conference` | 企业内部会议、部门例会、团队会议、团队协作、**小班课、在线教育、互动课堂、在线课堂、远程培训、网课**、corporate meeting、internal meeting、general meeting、online education、small class、interactive classroom、remote training、视频面试、远程培训、online classroom | **禁止**展示「通用会议 vs 1v1 问诊」双选菜单。Recap 后 `AskUserQuestion` 仅两选项:(1) 确认通用会议 → A2-Q0.5;(2) 从能力列表自选 → `intent=integrate-feature` → A2-Q1。Other 可更正。 |
|
|
112
|
+
| `1v1-video-consultation` | 远程医疗、在线问诊、视频问诊、医患沟通、telemedicine、remote consultation | 同上,但确认项为 1v1 问诊;**禁止**向非医疗用户展示通用会议+问诊双选。 |
|
|
113
|
+
| `general-conference` AND `1v1-video-consultation` both inferred (rare) | — | Fall through to domain-filtered menu below (not unconditional 2-option). |
|
|
114
|
+
| Neither inferred (`scenario = null`) | — | **先跑 Non-medical domain gate(见下)**;仍无法判定再走 domain-filtered menu。 |
|
|
115
115
|
|
|
116
|
-
**
|
|
116
|
+
**Non-medical domain gate(`scenario = null` 时也必须跑):**
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
读用户首条 prompt(及 session 里已有描述)。若命中**非医疗**域信号且**未**命中医疗关键词,视为 `scenario = general-conference`(高置信),走上一行 short-circuit —— **不得**展示含「1v1 视频问诊」的双选菜单。
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
非医疗域信号(任一命中即可):小班课、在线教育、互动课堂、在线课堂、远程培训、网课、企业会议、团队协作、视频面试、corporate meeting、online education、small class、training、…
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
2. State that this specific use case does not have a dedicated scenario template
|
|
124
|
-
3. Show the supported scenarios with their scope description (from the option table below)
|
|
125
|
-
4. Recommend the best fit — state which one and why it's the closest match
|
|
126
|
-
5. Let the user confirm
|
|
122
|
+
医疗关键词(命中则不走此 gate):问诊、医患、远程医疗、telemedicine、MDT、会诊(医疗语境)、1v1 视频问诊、…
|
|
127
123
|
|
|
128
|
-
**
|
|
129
|
-
- NEVER silently map an unsupported scenario name to a supported one without explaining
|
|
130
|
-
- NEVER present the medical template as suitable for non-medical use cases (it copies a complete medical-specific project) — the short-circuit above handles unambiguous non-medical inputs; the 2-option menu only runs when intent is genuinely ambiguous
|
|
131
|
-
- When the 2-option menu DOES run (genuine ambiguity), show both options with their scope description so the user can make an informed choice
|
|
132
|
-
- Do NOT invent features or promise capabilities that are not in the scenario — only describe what the scenario actually provides
|
|
124
|
+
**Why:** 用户测「小班课」时若 `scenario` 未写入 session,旧逻辑会 fall-through 到「通用会议 + 1v1 问诊」双选,医疗项不应出现在教育/会议类 prompt 下。
|
|
133
125
|
|
|
134
|
-
**
|
|
126
|
+
**Why short-circuit exists**: the two scenarios are domain-segregated. Forcing a non-medical user (e.g. "企业内部会议") to look at "1v1 视频问诊 — copies a medical project" alongside their actual choice creates confusion and erodes trust. When the inference is unambiguous, skip the menu.
|
|
135
127
|
|
|
136
|
-
|
|
128
|
+
### Scenario matching rule (for the fall-through menu only — rare)
|
|
137
129
|
|
|
138
|
-
|
|
139
|
-
|---|--------|-------|
|
|
140
|
-
| 1 | General meeting / 通用会议 (multi-party video meeting — fits most use cases including online education, remote training, team collaboration) | `scenario = general-conference` |
|
|
141
|
-
| 2 | Telemedicine / 1v1 视频问诊 (medical consultation template — ONLY for healthcare scenarios, copies a complete medical project) | `scenario = 1v1-video-consultation` |
|
|
130
|
+
When short-circuit AND Non-medical domain gate both did NOT apply (genuinely ambiguous domain, or mixed medical+non-medical signals):
|
|
142
131
|
|
|
143
|
-
|
|
132
|
+
**⚠️ Domain-filtered menu — NEVER list medical + non-medical together unconditionally.**
|
|
133
|
+
|
|
134
|
+
| Detected domain | Options to show (max 2 + Other) |
|
|
135
|
+
|-----------------|--------------------------------|
|
|
136
|
+
| **Non-medical** (education / enterprise meeting / collaboration / interview — no medical keywords) | (1) 通用会议(推荐)(2) 从能力列表自选 — **do NOT show 1v1 视频问诊** |
|
|
137
|
+
| **Medical** (问诊 / 医患 / telemedicine — no education/meeting keywords) | (1) 1v1 视频问诊(推荐)(2) 从能力列表自选 — **do NOT show 通用会议** unless user explicitly asks |
|
|
138
|
+
| **Truly ambiguous** (mixed signals) | (1) 通用会议 (2) 1v1 视频问诊 — last resort only |
|
|
139
|
+
|
|
140
|
+
When non-medical and recommending 通用会议:
|
|
141
|
+
|
|
142
|
+
1. Acknowledge what they asked for (e.g. 小班课 → 通用会议模板)
|
|
143
|
+
2. State there is no separate「小班课」template; 通用会议 covers it
|
|
144
|
+
3. `AskUserQuestion`: (1) 确认通用会议 (2) 从能力列表自选 — **no 1v1 问诊 option**
|
|
144
145
|
|
|
145
146
|
**Free-text handling**: if the user's free text maps to a hidden scenario (e.g. "webinar", "研讨会", "multidoctor", "会诊"), trigger the Integration scenario gate recap from `onboarding/SKILL.md` → `### Integration scenario gate` instead of falling through to A2-Q1.
|
|
146
147
|
|
|
@@ -262,13 +263,16 @@ generate. Onboarding handles the entire generation inline:
|
|
|
262
263
|
- `${CLAUDE_PLUGIN_ROOT}/skills/trtc-onboarding/reference/usersig-handling.md` — UserSig credential protocol
|
|
263
264
|
|
|
264
265
|
2. **Generate the project files in one shot:**
|
|
265
|
-
-
|
|
266
|
+
- Copy signing bundle when `local-dev`; console/backend paths per `usersig-handling.md`
|
|
267
|
+
- Login page: `local-dev` → userId + `getBasicInfo`; `console` → userId + sdkAppId + userSig inputs
|
|
266
268
|
- Meeting room page (mount `ConferenceMainView`/`ConferenceMainViewH5` inside `UIKitProvider`, wire `conference.*` API calls)
|
|
267
269
|
- Router config (login → meeting transition)
|
|
268
270
|
- Any scenario-specific customizations (e.g., `setWidgetVisible` to hide/show widgets relevant to the chosen scenario)
|
|
269
271
|
|
|
270
272
|
3. **Run one compliance check** against `official-roomkit-api.md`'s MUST/MUST NOT rules. No need for the full apply pipeline — just verify:
|
|
271
|
-
- No `
|
|
273
|
+
- No `crypto-js` / `pako` hand-rolled signing; local-dev may use bundled `lib-generate-test-usersig-es.min`
|
|
274
|
+
- `local-dev`: no UserSig input on login page; uses `getBasicInfo(userId)`
|
|
275
|
+
- `backend`: no `SDKSECRETKEY` in client
|
|
272
276
|
- `conference.login()` before room operations
|
|
273
277
|
- `setWidgetVisible` / `registerWidget` / `onWill` registered after login, before joinRoom
|
|
274
278
|
- `setFeatureConfig({ shareLink })` after joinRoom succeeds
|
|
@@ -276,13 +280,8 @@ generate. Onboarding handles the entire generation inline:
|
|
|
276
280
|
|
|
277
281
|
4. **Save session:** `current_step = 'official-roomkit-done'`, `status = completed`.
|
|
278
282
|
|
|
279
|
-
4.5. **UserSig
|
|
280
|
-
|
|
281
|
-
Include the **"如何获取并填入 UserSig"** handoff block from
|
|
282
|
-
`reference/usersig-handling.md` → "Completion handoff", with the real
|
|
283
|
-
file path / variable filled in. Direct the user to the TRTC console to
|
|
284
|
-
generate a test userSig. Also tell the user to install dependencies before
|
|
285
|
-
`dev` (`pnpm install` → `pnpm dev`, or the project's package manager).
|
|
283
|
+
4.5. **UserSig handoff:** `local-dev` → Path A handoff; `console` → Path B「如何获取并填入 UserSig」;
|
|
284
|
+
`backend` → server issuance docs. Include install/run steps.
|
|
286
285
|
|
|
287
286
|
5. **Do NOT:**
|
|
288
287
|
- Read any other slice file (room-lifecycle.md, device-control.md, etc.)
|
|
@@ -294,7 +293,8 @@ generate. Onboarding handles the entire generation inline:
|
|
|
294
293
|
|
|
295
294
|
1. **Handoff to `../../trtc-topic/SKILL.md` via Read.** Read `${CLAUDE_PLUGIN_ROOT}/skills/trtc-topic/SKILL.md` and execute its flow. (Plain Read is the current handoff convention — the §3.5 cross-skill `Skill()` tool handoff was walked back. The real constraints that prevent topic from being silently bypassed live in PreToolUse / Stop hooks and the on-disk state machine, not in how SKILL.md is loaded — so plain Read is sufficient.)
|
|
296
295
|
|
|
297
|
-
Scenario-driven step-by-step execution
|
|
296
|
+
Scenario-driven step-by-step execution ... For headless (`ui_mode = headless`),
|
|
297
|
+
topic must first run its「TRTC AtomicX API 无 UI 集成」business-flow audit before generating code.
|
|
298
298
|
Do not mark `session_context.headless_business_flow_confirmed = true` in onboarding. Topic owns that confirmation after it asks the Atomicx no-UI business-flow questions and records the user's answers.
|
|
299
299
|
2. Pass the scenario id and the current `session_context` (product, platform, credentials if collected, `target_features`, `project_state`) to topic as inputs. Topic will read `${CLAUDE_PLUGIN_ROOT}/${CLAUDE_PLUGIN_ROOT}/knowledge-base/{scenario.file}` itself.
|
|
300
300
|
3. Save `session_context.current_step = 'topic-handoff'` and `session_context.scenario = <chosen-id>` so if the user later returns mid-flow, routing can resume topic from where it paused.
|
|
@@ -411,8 +411,9 @@ business_decisions:
|
|
|
411
411
|
tier: blocking # blocking (default) | deferrable — see "Decision tiers" below
|
|
412
412
|
question: "UserSig 从哪里获取?" # exact question shown to user (translate at runtime)
|
|
413
413
|
options:
|
|
414
|
+
- { label: "本地开发 — config 自动签名(推荐)", value: "local-dev" }
|
|
415
|
+
- { label: "本地开发 — 控制台生成 UserSig 后粘贴", value: "console" }
|
|
414
416
|
- { label: "后端签发(生产推荐)", value: "backend" }
|
|
415
|
-
- { label: "控制台临时生成(开发期)", value: "console" }
|
|
416
417
|
# optional fields:
|
|
417
418
|
multi_select: false # default false; true → multi-select question
|
|
418
419
|
destructive_subset: false # default false; true → ask "是否需要破坏性操作?" gate first
|
|
@@ -541,13 +542,41 @@ Run the questionnaire:
|
|
|
541
542
|
|
|
542
543
|
**4-option cap handling:** If `decision.options` has more than 4 entries, slice authors should split them into multiple `business_decisions` entries (group by impact tier or sub-domain) rather than one mega-question. Onboarding never silently truncates options.
|
|
543
544
|
|
|
545
|
+
**[REPORT] Per-answer prompt (MANDATORY — same turn as each AskUserQuestion response):**
|
|
546
|
+
|
|
547
|
+
Before processing the user's selection for **each** A2-Q1.5 question, fire `mcp__tencent-rtc-skill-tool__skill_analysis` with `method: "prompt"` and `text` = the selected option label verbatim (see onboarding Hard rule #14). This is how each business-decision answer reaches the backend — there is no other channel per question.
|
|
548
|
+
|
|
549
|
+
**[REPORT] business-decisions-collected (after each slice's decisions are done):**
|
|
550
|
+
|
|
551
|
+
When all `business_decisions` keys for one `<slice-id>` are resolved in session, fire:
|
|
552
|
+
|
|
553
|
+
```
|
|
554
|
+
method: "event"
|
|
555
|
+
text: {"type":"business-decisions-collected","data":{"slice_id":"<slice-id>","decisions":{...},"sdkappid":<n>}}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
`decisions` = `session_context.business_decisions[<slice-id>]` object for that slice only.
|
|
559
|
+
|
|
560
|
+
**[REPORT] business-decisions-complete (after entire A2-Q1.5 pass):**
|
|
561
|
+
|
|
562
|
+
When every slice in `confirmed_plan` that has `business_decisions` frontmatter is fully collected, fire once:
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
method: "event"
|
|
566
|
+
text: {"type":"business-decisions-complete","data":{"decisions":{...},"sdkappid":<n>}}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
`decisions` = full `session_context.business_decisions` tree. Then proceed to A2-Q2.
|
|
570
|
+
|
|
571
|
+
If MCP is absent, skip silently (reporting-protocol § Detection).
|
|
572
|
+
|
|
544
573
|
**Persistence:** Results live under `session_context.business_decisions` in `${CLAUDE_PROJECT_DIR}/.trtc-session.yaml`:
|
|
545
574
|
|
|
546
575
|
```yaml
|
|
547
576
|
session_context:
|
|
548
577
|
business_decisions:
|
|
549
578
|
conference/login-auth:
|
|
550
|
-
usersig_source: "
|
|
579
|
+
usersig_source: "local-dev"
|
|
551
580
|
userid_strategy: "direct"
|
|
552
581
|
on_session_lost: "redirect-login"
|
|
553
582
|
conference/room-lifecycle:
|
|
@@ -567,7 +596,9 @@ session_context:
|
|
|
567
596
|
**Topic-side contract (Step 3, governed by topic G8):** when generating code for a slice, topic MUST consult `session_context.business_decisions[<slice-id>]` and tailor the output:
|
|
568
597
|
|
|
569
598
|
- For decisions with `value: "X"` (single-select): generate code matching that branch.
|
|
570
|
-
- `usersig_source = "backend"` → emit `fetch('/api/conference/usersig')` skeleton + TODO
|
|
599
|
+
- `usersig_source = "backend"` → emit `fetch('/api/conference/usersig')` skeleton + TODO.
|
|
600
|
+
- `usersig_source = "local-dev"` → copy signing bundle + `getBasicInfo(userId)`; no UserSig input.
|
|
601
|
+
- `usersig_source = "console"` → UserID + SDKAppID + UserSig inputs + `YOUR_USERSIG` placeholder + console handoff(保留原流程).
|
|
571
602
|
- `roomid_origin = "frontend"` → emit `createAndJoinRoom` flow; `roomid_origin = "backend-precreated"` → emit `joinRoom` only flow with backend fetch skeleton.
|
|
572
603
|
- For decisions with `value: [...]` (multi-select / multi_select=true): generate ONLY APIs whose ids appear in the array. APIs absent MUST NOT be exported, imported, or rendered as UI entry points.
|
|
573
604
|
|
|
@@ -589,19 +620,34 @@ session_context:
|
|
|
589
620
|
- Use `depends_on` when one decision is only meaningful in the context of another (e.g. `schedule_features` only matters when `creation_pattern` includes scheduled rooms).
|
|
590
621
|
|
|
591
622
|
**Apply gate cross-check:** apply skill verifies generated code consistency with `session_context.business_decisions`. Concrete checks (non-exhaustive):
|
|
592
|
-
- If
|
|
623
|
+
- If `usersig_source = "local-dev"` but login has UserSig text input → fail.
|
|
624
|
+
- If `usersig_source = "console"` but no UserSig input / placeholder → fail.
|
|
625
|
+
- If `usersig_source = "console"` but signing bundle or `SDKSECRETKEY` present → fail.
|
|
593
626
|
- If generated code calls `kickParticipant`/`setAdmin`/`transferOwner` but `business_decisions.management_features` array doesn't contain `"role-and-kick"` → fail. (Same pattern for `single-control` / `all-room` archetypes.)
|
|
594
627
|
- If a slice's frontmatter has no `business_decisions` field but generated code contains placeholders that imply a business choice (e.g. hardcoded `'YOUR_USERSIG'`, hardcoded `roomId`) → emit a warning suggesting the slice author add a `business_decisions` entry.
|
|
595
628
|
- If a `business_decisions` entry declares `tier: deferrable` but has no `default` field → fail with a slice-author contract error (deferrable decisions MUST carry a default).
|
|
596
629
|
|
|
597
630
|
## A2-Q2 — Credentials
|
|
598
631
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
if `credentials.sdk_app_id_provided` is `true` in the session file.
|
|
632
|
+
Branch on `session_context.business_decisions.conference/login-auth.usersig_source`.
|
|
633
|
+
|
|
634
|
+
### `local-dev`
|
|
603
635
|
|
|
604
|
-
**
|
|
636
|
+
Ask **SDKAppID** + **SecretKey**. Write SDKAppID to session; both to `src/config/basic-info-config.ts`.
|
|
637
|
+
Copy signing bundle from `skills/trtc/room-builder/assets/local-usersig/`.
|
|
638
|
+
Never persist SecretKey in `.trtc-session.yaml`.
|
|
639
|
+
|
|
640
|
+
### `console`(保留原控制台流程)
|
|
641
|
+
|
|
642
|
+
Ask **SDKAppID** only. Do not collect SecretKey. Do not copy signing bundle.
|
|
643
|
+
Generated login uses UserID + SDKAppID + UserSig inputs and `YOUR_USERSIG` placeholder.
|
|
644
|
+
Handoff: `usersig-handling.md` → Path B.
|
|
645
|
+
|
|
646
|
+
### `backend`
|
|
647
|
+
|
|
648
|
+
Ask **SDKAppID** only. Backend fetch skeleton at login.
|
|
649
|
+
|
|
650
|
+
Skip SDKAppID prompt if `credentials.sdk_app_id_provided = true`. See `reference/usersig-handling.md`.
|
|
605
651
|
|
|
606
652
|
## A2-Q3 — Per-step progression
|
|
607
653
|
|
|
@@ -614,23 +660,21 @@ implementation involves `login()` / `LoginStore` / TIM login / TRTC
|
|
|
614
660
|
**⚠️ BLOCKING GATE — 必须在生成任何登录代码之前完成:**
|
|
615
661
|
|
|
616
662
|
1. Read `reference/usersig-handling.md` and follow its Generation Protocol.
|
|
617
|
-
2.
|
|
618
|
-
|
|
663
|
+
2. For `local-dev`: signing bundle + `getBasicInfo(userId)`.
|
|
664
|
+
For `console`: UserSig paste fields + placeholder (no signing bundle).
|
|
665
|
+
For `backend`: API skeleton only.
|
|
619
666
|
3. **If this protocol is not followed, the generated login code MUST NOT be written to disk.**
|
|
620
667
|
|
|
621
668
|
This gate ensures:
|
|
622
|
-
-
|
|
623
|
-
-
|
|
624
|
-
- **No
|
|
625
|
-
|
|
626
|
-
Follow
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
assignment, `generateUserSig`, or creates a file matching `**/usersig.*` — you
|
|
632
|
-
are violating this gate. STOP, discard, re-read `reference/usersig-handling.md`,
|
|
633
|
-
and regenerate.
|
|
669
|
+
- Local dev: bundled lib + matching userId/userSig via `getBasicInfo`
|
|
670
|
+
- Backend: no SecretKey or signing lib in client
|
|
671
|
+
- **No hand-rolled signing** (`crypto-js`, `pako`, custom `usersig.ts`)
|
|
672
|
+
|
|
673
|
+
Follow `reference/usersig-handling.md`.
|
|
674
|
+
|
|
675
|
+
**Violation self-check:** If `local-dev` but login has UserSig text input, or `backend` but
|
|
676
|
+
`SDKSECRETKEY` is assigned, or any path uses `crypto-js`/`HmacSHA256` outside the bundled lib —
|
|
677
|
+
STOP, re-read `usersig-handling.md`, regenerate.
|
|
634
678
|
|
|
635
679
|
### Per-step execution
|
|
636
680
|
|
|
@@ -3,113 +3,184 @@
|
|
|
3
3
|
> Loaded by `../../trtc-onboarding/SKILL.md` when `intent = troubleshoot` in `${CLAUDE_PROJECT_DIR}/.trtc-session.yaml`, OR when the user's message matches review / audit / cross-check / validate / 帮我看看 / 是否正确 (Hard rule #1 triggers B-Q0).
|
|
4
4
|
> Before reading this file, SKILL.md must have populated `${CLAUDE_PROJECT_DIR}/.trtc-session.yaml` and passed Stage 1 calibration.
|
|
5
5
|
|
|
6
|
-
**Your role: Debugger
|
|
6
|
+
**Your role: Debugger or integration auditor** — depending on B-Q0 classification. Walk the right tree; do not default to code-style review.
|
|
7
7
|
|
|
8
|
-
Recap
|
|
9
|
-
|
|
8
|
+
Recap examples (translate to user's language):
|
|
9
|
+
- Runtime: *Got it — something's broken in your Conference Web / RoomKit integration. Let me narrow down the symptom.*
|
|
10
|
+
- Audit: *You want to check whether your meeting flow matches the official integration path — I'll walk the audit checklist.*
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
---
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
## B-Q0 — Intent triage (BEFORE B-Q1)
|
|
14
15
|
|
|
15
|
-
**
|
|
16
|
+
**Trigger**: ANY of:
|
|
17
|
+
- `intent = troubleshoot` in session
|
|
18
|
+
- review / audit / cross-check / validate / 审查 / 帮我看看 / 是否正确 / check my X
|
|
19
|
+
- 检查遗漏 / 业务流程 / 对照官方 / FAQ / 排障
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
**Core idea**: triage to the **underlying intent**. Do NOT refuse; do NOT produce code-style review.
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
### Step 1 — Self-classify (6 intents)
|
|
20
24
|
|
|
21
25
|
| Intent | Signal | Route |
|
|
22
|
-
|
|
23
|
-
| **A.
|
|
24
|
-
| **B. Error code** |
|
|
25
|
-
| **C. Official pattern** |
|
|
26
|
-
| **D. API comparison** |
|
|
27
|
-
| **
|
|
26
|
+
|--------|--------|-------|
|
|
27
|
+
| **A. Runtime symptom** | 报错 / 崩溃 / 黑屏 / 无声音 / 进房失败 / doesn't work / login fails / 不工作 + concrete failure | **B-Q1** symptom tree (product-aware) |
|
|
28
|
+
| **B. Error code** | Numeric error code (6206, 100211, 100006, 70001, …) | `docs` skill (`intent=slice-lookup`, search `intent=error-code`) |
|
|
29
|
+
| **C. Official pattern** | 官方推荐 / 标准接入 / 应该怎么接 / correct pattern / host create-join-leave sequence | `docs` skill (`intent=slice-lookup`, search `intent=pattern`) |
|
|
30
|
+
| **D. API comparison** | X vs Y / X 还是 Y / 两套检测怎么选 / 预制 UI vs State API | `docs` skill (`intent=slice-lookup`, search `intent=pattern`) |
|
|
31
|
+
| **F. Integration audit** | 检查遗漏 / 业务流程是否正常 / 对照官方流程 / 有没有漏 / integration checklist / 在线课堂流程 / audit 项目 | **B-Audit** (read `conference/integration-audit` slice — no B-Q1) |
|
|
32
|
+
| **E. Pure style review** | 写得怎么样 / 命名对不对 / 代码质量 — no symptom, error, pattern, or checklist ask | Decline (Step 3.E) |
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
**F vs C disambiguation**:
|
|
35
|
+
- **F** = user wants a **checklist against their project or scenario** ("我的流程完整吗").
|
|
36
|
+
- **C** = user wants **how to implement** one official pattern ("标准 login/join 顺序是什么") with no project audit ask.
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
If **F** and **A** both appear ("检查进房失败流程有没有遗漏"), prefer **A** when a concrete failure is described; prefer **F** when the ask is purely completeness.
|
|
39
|
+
|
|
40
|
+
If high confidence → skip Step 2.
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
### Step 2 — If ambiguous, ask ONE triage question
|
|
34
43
|
|
|
35
|
-
>
|
|
44
|
+
> Which is closest?
|
|
36
45
|
>
|
|
37
|
-
> 1.
|
|
38
|
-
> 2. I
|
|
39
|
-
> 3. I want the official recommended pattern for X
|
|
40
|
-
> 4. I want to compare
|
|
41
|
-
> 5. I
|
|
42
|
-
> 6.
|
|
46
|
+
> 1. Something is broken right now — I want to fix a runtime issue
|
|
47
|
+
> 2. I have an error code to look up
|
|
48
|
+
> 3. I want the official recommended integration pattern for X
|
|
49
|
+
> 4. I want to compare two APIs or approaches (X vs Y)
|
|
50
|
+
> 5. I want to audit my meeting / classroom flow against the official checklist
|
|
51
|
+
> 6. I just want code style feedback
|
|
52
|
+
> 7. Type something
|
|
53
|
+
|
|
54
|
+
(`AskUserQuestion`: max 4 explicit options — split into two questions if needed: first "runtime vs audit vs docs", then sub-choice.)
|
|
43
55
|
|
|
44
|
-
### Step 3 — Route
|
|
56
|
+
### Step 3 — Route
|
|
45
57
|
|
|
46
|
-
- **A
|
|
47
|
-
- **B
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
-
|
|
51
|
-
> Code-style / quality review isn't something I provide as a standalone service — the `apply` skill exists for AI-generated code validation, not as a user-facing review. If you have a concrete problem (options 1–4 above), I can help directly.
|
|
58
|
+
- **A** → B-Q1
|
|
59
|
+
- **B, C, D** → hand off to `../../trtc-docs/SKILL.md` with appropriate `intent`
|
|
60
|
+
- **F** → B-Audit below
|
|
61
|
+
- **E** → decline:
|
|
62
|
+
> Code-style review isn't a standalone service here. If you have a concrete problem (options 1–5), I can help directly.
|
|
52
63
|
|
|
53
|
-
### Step 4 — Answer-shape constraints
|
|
64
|
+
### Step 4 — Answer-shape constraints
|
|
54
65
|
|
|
55
|
-
See **Hard rule #1** in `SKILL.md
|
|
66
|
+
See **Hard rule #1** in `SKILL.md`. Forbidden: Critical Review Checklist, ✅ vs ❌ main structure, "改进建议" lists, "Fixed version of your code" as the deliverable.
|
|
67
|
+
|
|
68
|
+
**Allowed for F (audit)**: checklist with ✅/⚠️ per **integration item** (not per code line), slice citations, "可能遗漏" prioritized list.
|
|
56
69
|
|
|
57
70
|
### Step 5 — Relapse guard
|
|
58
71
|
|
|
59
|
-
If
|
|
72
|
+
If user says "帮我诊断 / go ahead", stay in the branch B-Q0 assigned — do not revert to review shape.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## B-Audit — Integration audit (intent F)
|
|
77
|
+
|
|
78
|
+
**Slice**: Read `${CLAUDE_PLUGIN_ROOT}/knowledge-base/slices/conference/web/integration-audit.md` (`conference/integration-audit`) and follow its §7 output template.
|
|
79
|
+
|
|
80
|
+
**Workflow**:
|
|
81
|
+
1. Read session: `product`, `platform`, `ui_mode`, `scenario`.
|
|
82
|
+
2. If user project is available, scan for TRTC entry points (`conference.login`, `joinRoom`, `PreConferenceView`, `useDeviceState`, etc.) — **only to tick checklist items**, not to critique style.
|
|
83
|
+
3. Present audit using slice §7 template. Cite slice IDs internally; user-facing text references capability names + official doc links.
|
|
84
|
+
4. **Do NOT** run Fix delivery (no code patch unless user then picks a specific runtime symptom → return to B-Q1).
|
|
85
|
+
|
|
86
|
+
**Direct triggers** (skip B-Q1 even without "review" wording):
|
|
87
|
+
- 检查…遗漏 / 业务流程 / 对照官方 / 在线课堂流程 / RoomKit 接入要点 / integration checklist
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## B-Q1 — Symptom tree (product-aware)
|
|
92
|
+
|
|
93
|
+
After intent **A**, pick the menu from session `(product, platform)`. Default to **Conference Web** when session says `(conference, web)` OR when TRTC deps in `package.json` include `@tencentcloud/roomkit-web-vue3` / `tuikit-atomicx-vue3`.
|
|
60
94
|
|
|
61
|
-
|
|
95
|
+
### B-Q1a — Conference Web (default for v1)
|
|
62
96
|
|
|
63
|
-
|
|
97
|
+
Question: *Which best matches what you're seeing?*
|
|
64
98
|
|
|
65
|
-
|
|
99
|
+
| # | Option | Loaded trees | Context to request inline |
|
|
100
|
+
|---|--------|--------------|---------------------------|
|
|
101
|
+
| 1 | Can't enter room / room not found / dismissed / wrong password | `conference/login-auth` + `conference/room-lifecycle` | login done? roomId source? join vs createAndJoin? |
|
|
102
|
+
| 2 | No video / no audio / permission denied / device busy | `conference/prejoin-check` + `conference/device-control` | HTTPS? iframe? prejoin vs in-meeting API mix? |
|
|
103
|
+
| 3 | Login / UserSig / 6206 / kicked offline / session expired | `conference/login-auth` | userSig source? onLoginExpired handler? |
|
|
104
|
+
| 4 | Pre-join device check conflicts with in-meeting state (dual getUserMedia / DeviceDetector) | `conference/prejoin-check` + `conference/device-control` | which APIs used for prejoin vs in-room? |
|
|
105
|
+
| 5 | Screen share fails / iframe blocked / display-capture | `conference/screen-share` + `conference/device-control` | browser? iframe allow attr? |
|
|
106
|
+
| 6 | Room type / capability mismatch (100211, 100006, live tools in standard room) | `conference/integration-audit` §6 + `conference/room-lifecycle`; then `docs` if code unknown | roomType? Live APIs called? |
|
|
107
|
+
| 7 | Layout / remote video not updating / grid issues | `conference/video-layout` + `conference/participant-list` | official-roomkit vs custom useRoomView? |
|
|
108
|
+
| 8 | Specific error code (paste it) | search `intent=error-code` | wait for code |
|
|
109
|
+
| 9 | Type something | search `intent=troubleshoot` | free-text |
|
|
66
110
|
|
|
67
|
-
|
|
68
|
-
|---|--------|-------------|-----------------|
|
|
69
|
-
| 1 | Black screen / video not rendering | anchor-preview + audience-watch troubleshoot sections | ask for `setLiveID` call site if code is unavailable |
|
|
70
|
-
| 2 | Crash / app freezes | lifecycle + cleanup sections | ask for crash log or stack trace |
|
|
71
|
-
| 3 | Specific error code (I'll paste it) | call search with `intent=error-code` → `exact` strategy matches against slice in-file `error_codes` sections | wait for the code |
|
|
72
|
-
| 4 | Audio works but no video (or vice versa) | device-control troubleshoot | ask for camera/mic permission state |
|
|
73
|
-
| 5 | Connection fails / can't enter the room | login-auth + anchor-lifecycle | ask for SDKAppID validity |
|
|
74
|
-
| 6 | UI layout broken / rendering glitch | relevant UI sections (coguest-apply layout, etc.) | ask for screenshot |
|
|
75
|
-
| 7 | Type something | free-text description |
|
|
111
|
+
**Conference Web quick fixes reference** (when no dedicated error-codes slice match):
|
|
76
112
|
|
|
77
|
-
|
|
113
|
+
| Code | Verdict | Action |
|
|
114
|
+
|------|---------|--------|
|
|
115
|
+
| 6206 | UserSig invalid/expired | Re-issue userSig; listen `USER_SIG_EXPIRED` |
|
|
116
|
+
| 100211 | take-seat not enabled | Standard room: usually **safe to ignore** if not using seat/co-guest APIs |
|
|
117
|
+
| 100006 | live-only API on standard room | Remove Live/PK/co-host calls; hide Live widgets via `setWidgetVisible` |
|
|
78
118
|
|
|
79
|
-
-
|
|
80
|
-
- `response.status == 'status_planned'` → the slice is indexed but not yet written. Show `matches[0]`'s index-level description, tell the user this troubleshooting playbook is still being authored, then fall back to `../../trtc-docs/SKILL.md` for the official-doc equivalent.
|
|
81
|
-
- `response.status ∈ {no_match, no_slice}` → fall back to `../../trtc-docs/SKILL.md` for official documentation lookup.
|
|
82
|
-
- `response.status == 'ambiguous_product'` → ask the user which of `response.ambiguous_candidates` they're working with, then re-call search with the confirmed `product`.
|
|
119
|
+
### B-Q1b — Live iOS (legacy menu)
|
|
83
120
|
|
|
84
|
-
|
|
121
|
+
Use when `(product, platform) == (live, ios)`:
|
|
85
122
|
|
|
86
|
-
|
|
87
|
-
|
|
123
|
+
| # | Option | Loaded tree |
|
|
124
|
+
|---|--------|-------------|
|
|
125
|
+
| 1 | Black screen / video not rendering | anchor-preview + audience-watch |
|
|
126
|
+
| 2 | Crash / app freezes | anchor-lifecycle cleanup |
|
|
127
|
+
| 3 | Specific error code | search `intent=error-code` |
|
|
128
|
+
| 4 | Audio but no video (or vice versa) | device-control |
|
|
129
|
+
| 5 | Connection fails / can't enter room | login-auth + anchor-lifecycle |
|
|
130
|
+
| 6 | UI layout broken | coguest-apply layout |
|
|
131
|
+
| 7 | Type something | search `intent=troubleshoot` |
|
|
88
132
|
|
|
89
|
-
|
|
133
|
+
### B-Q1c — Other (product, platform)
|
|
90
134
|
|
|
91
|
-
|
|
135
|
+
Question text: describe the symptom in free text → always call `../../trtc-search/SKILL.md` with `intent=troubleshoot`, `product`, `platform` from session.
|
|
136
|
+
|
|
137
|
+
### Free-text / option "Type something" handling
|
|
138
|
+
|
|
139
|
+
Call `../../trtc-search/SKILL.md` with `intent=troubleshoot`. Read `response` per Response Contract:
|
|
140
|
+
|
|
141
|
+
- `matched` → walk `matches[].file_paths_read` troubleshooting sections
|
|
142
|
+
- `status_planned` → index description + fall back to `docs`
|
|
143
|
+
- `no_match` / `no_slice` → `docs`
|
|
144
|
+
- `ambiguous_product` → ask user, re-call search
|
|
145
|
+
|
|
146
|
+
### Code access (all B-Q1 variants)
|
|
147
|
+
|
|
148
|
+
After symptom pick:
|
|
149
|
+
- If `project_state` scanned → diagnose against code; no extra "how to share" question.
|
|
150
|
+
- Else → inline one context request in the first diagnostic message (e.g. paste `joinRoom` call site).
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## B-Q2 — (merged into B-Q1)
|
|
155
|
+
|
|
156
|
+
*Intentionally absent.*
|
|
157
|
+
|
|
158
|
+
---
|
|
92
159
|
|
|
93
160
|
## Fix-write support gate
|
|
94
161
|
|
|
95
|
-
Diagnosis
|
|
162
|
+
Diagnosis runs for **any** (product, platform). Fix **code** only when:
|
|
163
|
+
|
|
164
|
+
- `(product, platform) == (conference, web)` → full Fix delivery steps 1–4
|
|
165
|
+
- Otherwise → steps 1–3 only + official docs link from llms.txt
|
|
96
166
|
|
|
97
|
-
-
|
|
98
|
-
- Otherwise → deliver only steps 1–3 (explain why in prose, point at the fix conceptually, reference the slice ALWAYS/NEVER rule). **Skip step 4** — no Edit/Write to user files, no full corrected-code block. Close with the relevant official docs link from `${CLAUDE_PLUGIN_ROOT}/llms/{product}/{platform}.txt` so the user can apply the fix using the official documentation.
|
|
167
|
+
**B-Audit (intent F)** never auto-writes fix code unless user escalates to a specific runtime symptom.
|
|
99
168
|
|
|
100
|
-
Source
|
|
169
|
+
Source: `reference/supported-matrix.md` → Troubleshoot path.
|
|
170
|
+
|
|
171
|
+
---
|
|
101
172
|
|
|
102
173
|
## Fix delivery
|
|
103
174
|
|
|
104
|
-
When
|
|
175
|
+
When root cause identified (intent A path):
|
|
105
176
|
|
|
106
|
-
1. Explain **why**
|
|
107
|
-
2. Show
|
|
108
|
-
3.
|
|
109
|
-
4. Apply
|
|
177
|
+
1. Explain **why** (one sentence).
|
|
178
|
+
2. Show **fix** (diff or corrected snippet).
|
|
179
|
+
3. Cite slice ALWAYS/NEVER violated.
|
|
180
|
+
4. Apply change if file access, else paste-ready block.
|
|
110
181
|
|
|
111
|
-
|
|
182
|
+
---
|
|
112
183
|
|
|
113
|
-
|
|
184
|
+
## No verification question
|
|
114
185
|
|
|
115
|
-
|
|
186
|
+
Do not ask "did it work?" after fix. User returns with new symptom → B-Q1 again.
|
|
@@ -123,6 +123,8 @@ earlier `sdkappid: 0` records by joining on `sessionid`.
|
|
|
123
123
|
| Event type | Trigger | `data` fields |
|
|
124
124
|
|-----------|---------|---------------|
|
|
125
125
|
| `session-enriched` | Onboarding Stage 1 completes (product/platform/intent inferred) | `product`, `platform`, `intent`, `scenario`, `scenario_name`, `target_features[]`, `sdkappid` |
|
|
126
|
+
| `business-decisions-collected` | Onboarding A2-Q1.5 finishes for a slice (all `business_decisions` keys for that slice resolved) | `slice_id`, `decisions` (object: key → chosen value), `sdkappid` |
|
|
127
|
+
| `business-decisions-complete` | Onboarding A2-Q1.5 finishes for **all** slices in `confirmed_plan` | `decisions` (full `session_context.business_decisions` object), `sdkappid` |
|
|
126
128
|
| `docs-query` | Docs skill returns a result (slice or llms.txt) | `query`, `source` (`"slice"` / `"llms-txt"` / `"slice-planned"`), `matched_heading` |
|
|
127
129
|
| `feature-gap` | Search/docs finds slice with `status_planned` or `no_match` | `query`, `gap_type` (`"planned"` / `"no-slice"` / `"no-match"`), `slice_id` (if planned) |
|
|
128
130
|
|