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

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.
Files changed (360) hide show
  1. package/.cursor/rules/main.mdc +12 -0
  2. package/AGENTS.md +14 -104
  3. package/CLAUDE.md +15 -127
  4. package/CODEBUDDY.md +32 -118
  5. package/README.md +7 -5
  6. package/README.zh.md +7 -5
  7. package/bin/cli.js +133 -41
  8. package/hooks/__pycache__/cursor-adapter.cpython-313.pyc +0 -0
  9. package/hooks/cursor-adapter.py +45 -18
  10. package/hooks/hooks-cursor.json +5 -18
  11. package/hooks/hooks.json +6 -31
  12. package/knowledge-base/conference/web/index.yaml +143 -0
  13. package/knowledge-base/platform-slice-template.md +1041 -133
  14. package/knowledge-base/products.yaml +76 -0
  15. package/knowledge-base/scenario-spec.md +1316 -115
  16. package/knowledge-base/scenarios/conference/base/general-conference.md +22 -2
  17. package/knowledge-base/scenarios/conference/base/webinar-conference.md +14 -0
  18. package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +19 -0
  19. package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +13 -0
  20. package/knowledge-base/scenarios/live/entertainment-live-room.md +12 -0
  21. package/knowledge-base/slice-spec.md +2377 -299
  22. package/knowledge-base/slices/conference/web/integration-audit.md +1 -1
  23. package/knowledge-base/slices/conference/web/login-auth.md +14 -1
  24. package/knowledge-base/tooling/aliases.yaml +92 -0
  25. package/knowledge-base/tooling/intent-signals.yaml +181 -0
  26. package/knowledge-base/tooling/symptom-keywords.yaml +21 -0
  27. package/package.json +1 -1
  28. package/skills/trtc/SKILL.md +202 -245
  29. package/skills/trtc/hooks/__pycache__/report_prompt.cpython-313.pyc +0 -0
  30. package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_read.py +12 -8
  31. package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_write.py +16 -12
  32. package/skills/{trtc-topic/guardrails → trtc/hooks}/stop_require_apply_evidence.py +22 -14
  33. package/skills/trtc/hooks/topic_phase_gate.py +161 -0
  34. package/skills/{trtc-topic → trtc}/runtime/README.md +2 -2
  35. package/skills/{trtc-onboarding/reference/reporting-protocol.md → trtc/runtime/REPORTING.md} +5 -5
  36. package/skills/{trtc-topic → trtc}/runtime/RUNTIME.md +5 -5
  37. package/skills/trtc/runtime/lib/__init__.py +0 -0
  38. package/skills/{trtc-topic → trtc}/runtime/package-lock.json +2 -2
  39. package/skills/{trtc-topic → trtc}/runtime/package.json +2 -2
  40. package/skills/{trtc-topic → trtc}/runtime/telemetry-bridge.mjs +1 -1
  41. package/skills/{trtc-topic/scripts → trtc/tools}/STATE-MACHINE-GUIDE.md +23 -23
  42. package/skills/trtc/tools/__init__.py +2 -0
  43. package/skills/trtc/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  44. package/skills/trtc/tools/__pycache__/query_classifier.cpython-313.pyc +0 -0
  45. package/skills/trtc/tools/__pycache__/reporting.cpython-313.pyc +0 -0
  46. package/skills/trtc/tools/__pycache__/search.cpython-313.pyc +0 -0
  47. package/skills/trtc/tools/__pycache__/session.cpython-313.pyc +0 -0
  48. package/skills/trtc/tools/apply.py +540 -0
  49. package/skills/trtc/tools/docs.py +712 -0
  50. package/skills/trtc/tools/docsbot.py +182 -0
  51. package/skills/trtc/tools/entry/render_ai_instructions.py +92 -0
  52. package/skills/trtc/tools/flow.py +1089 -0
  53. package/skills/{trtc-topic/scripts → trtc/tools}/init_slice_queue.py +5 -4
  54. package/skills/{trtc-topic/scripts → trtc/tools}/next_slice.py +5 -4
  55. package/skills/trtc/tools/query_classifier.py +301 -0
  56. package/skills/trtc/tools/reporting.py +447 -0
  57. package/skills/trtc/tools/search.py +817 -0
  58. package/skills/trtc/tools/session.py +1261 -0
  59. package/skills/trtc/tools/state_machine.py +690 -0
  60. package/skills/trtc-ai-service/README.md +195 -0
  61. package/skills/trtc-ai-service/README.zh-CN.md +193 -0
  62. package/skills/trtc-ai-service/SKILL.md +945 -0
  63. package/skills/trtc-ai-service/auto_adapters/README.md +40 -0
  64. package/skills/trtc-ai-service/auto_adapters/frontend-spa/README.md +27 -0
  65. package/skills/trtc-ai-service/auto_adapters/frontend-spa/angular/voice-agent.component.ts.tpl +131 -0
  66. package/skills/trtc-ai-service/auto_adapters/frontend-spa/manifest.yaml +57 -0
  67. package/skills/trtc-ai-service/auto_adapters/frontend-spa/react/VoiceAgent.tsx.tpl +142 -0
  68. package/skills/trtc-ai-service/auto_adapters/frontend-spa/vue/VoiceAgent.vue.tpl +121 -0
  69. package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-backend.md +45 -0
  70. package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-frontend.md +51 -0
  71. package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-rest-api.md +93 -0
  72. package/skills/trtc-ai-service/auto_adapters/java-backend/README.md +25 -0
  73. package/skills/trtc-ai-service/auto_adapters/java-backend/manifest.yaml +30 -0
  74. package/skills/trtc-ai-service/auto_adapters/java-backend/quarkus/VoiceAgentFilter.java.tpl +64 -0
  75. package/skills/trtc-ai-service/auto_adapters/java-backend/springboot/VoiceAgentFilter.java.tpl +91 -0
  76. package/skills/trtc-ai-service/auto_adapters/manifest.yaml +43 -0
  77. package/skills/trtc-ai-service/auto_adapters/node-backend/README.md +25 -0
  78. package/skills/trtc-ai-service/auto_adapters/node-backend/express.js.tpl +40 -0
  79. package/skills/trtc-ai-service/auto_adapters/node-backend/fastify.js.tpl +27 -0
  80. package/skills/trtc-ai-service/auto_adapters/node-backend/koa.js.tpl +31 -0
  81. package/skills/trtc-ai-service/auto_adapters/node-backend/manifest.yaml +47 -0
  82. package/skills/trtc-ai-service/auto_adapters/python-backend/README.md +22 -0
  83. package/skills/trtc-ai-service/auto_adapters/python-backend/django.py.tpl +32 -0
  84. package/skills/trtc-ai-service/auto_adapters/python-backend/fastapi.py.tpl +35 -0
  85. package/skills/trtc-ai-service/auto_adapters/python-backend/flask.py.tpl +31 -0
  86. package/skills/trtc-ai-service/auto_adapters/python-backend/manifest.yaml +45 -0
  87. package/skills/trtc-ai-service/capabilities/__init__.py +43 -0
  88. package/skills/trtc-ai-service/capabilities/conversation-core/.env.example +29 -0
  89. package/skills/trtc-ai-service/capabilities/conversation-core/INTEGRATION.md +134 -0
  90. package/skills/trtc-ai-service/capabilities/conversation-core/INTERFACE_ADAPT.md +111 -0
  91. package/skills/trtc-ai-service/capabilities/conversation-core/QUICK_START.md +62 -0
  92. package/skills/trtc-ai-service/capabilities/conversation-core/manifest.yaml +250 -0
  93. package/skills/trtc-ai-service/capabilities/conversation-core/requirements.txt +6 -0
  94. package/skills/trtc-ai-service/capabilities/conversation-core/src/__init__.py +10 -0
  95. package/skills/trtc-ai-service/capabilities/conversation-core/src/_capability_loader.py +218 -0
  96. package/skills/trtc-ai-service/capabilities/conversation-core/src/agent.py +231 -0
  97. package/skills/trtc-ai-service/capabilities/conversation-core/src/credentials.py +132 -0
  98. package/skills/trtc-ai-service/capabilities/conversation-core/src/health.py +355 -0
  99. package/skills/trtc-ai-service/capabilities/conversation-core/src/log_filter.py +76 -0
  100. package/skills/trtc-ai-service/capabilities/conversation-core/src/modality.py +109 -0
  101. package/skills/trtc-ai-service/capabilities/conversation-core/src/server.py +312 -0
  102. package/skills/trtc-ai-service/capabilities/conversation-core/src/trtc_client.py +315 -0
  103. package/skills/trtc-ai-service/capabilities/conversation-core/src/usersig.py +90 -0
  104. package/skills/trtc-ai-service/capabilities/conversation-core/tests/test_skeleton.py +216 -0
  105. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/README.md +48 -0
  106. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/app.js +415 -0
  107. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/index.html +68 -0
  108. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/styles.css +136 -0
  109. package/skills/trtc-ai-service/capabilities/digital-human/README.md +31 -0
  110. package/skills/trtc-ai-service/capabilities/digital-human/manifest.yaml +64 -0
  111. package/skills/trtc-ai-service/capabilities/digital-human/src/__init__.py +2 -0
  112. package/skills/trtc-ai-service/capabilities/digital-human/src/router.py +43 -0
  113. package/skills/trtc-ai-service/capabilities/human-handoff/INTERFACE_ADAPT.md +353 -0
  114. package/skills/trtc-ai-service/capabilities/human-handoff/README.md +44 -0
  115. package/skills/trtc-ai-service/capabilities/human-handoff/manifest.yaml +227 -0
  116. package/skills/trtc-ai-service/capabilities/human-handoff/src/__init__.py +2 -0
  117. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/__init__.py +9 -0
  118. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/default_rest.py +242 -0
  119. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/factory.py +89 -0
  120. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/local_queue.py +258 -0
  121. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/mock.py +132 -0
  122. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/__init__.py +25 -0
  123. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/intent_detector.py +75 -0
  124. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/models.py +163 -0
  125. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/service.py +192 -0
  126. package/skills/trtc-ai-service/capabilities/human-handoff/src/feedback_store.py +54 -0
  127. package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/__init__.py +4 -0
  128. package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/handoff_client.py +86 -0
  129. package/skills/trtc-ai-service/capabilities/human-handoff/src/queue.py +62 -0
  130. package/skills/trtc-ai-service/capabilities/human-handoff/src/router.py +201 -0
  131. package/skills/trtc-ai-service/capabilities/human-handoff/src/summary_link.py +77 -0
  132. package/skills/trtc-ai-service/capabilities/human-handoff/src/trigger.py +25 -0
  133. package/skills/trtc-ai-service/capabilities/knowledge-base/INTERFACE_ADAPT.md +297 -0
  134. package/skills/trtc-ai-service/capabilities/knowledge-base/README.md +51 -0
  135. package/skills/trtc-ai-service/capabilities/knowledge-base/data/faq.json +20 -0
  136. package/skills/trtc-ai-service/capabilities/knowledge-base/manifest.yaml +211 -0
  137. package/skills/trtc-ai-service/capabilities/knowledge-base/src/__init__.py +8 -0
  138. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/__init__.py +9 -0
  139. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/default_rest.py +209 -0
  140. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/factory.py +86 -0
  141. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/local_json.py +172 -0
  142. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/mock.py +91 -0
  143. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/__init__.py +12 -0
  144. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/models.py +77 -0
  145. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/scoring.py +73 -0
  146. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/service.py +78 -0
  147. package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/__init__.py +4 -0
  148. package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/kb_client.py +61 -0
  149. package/skills/trtc-ai-service/capabilities/knowledge-base/src/retriever.py +56 -0
  150. package/skills/trtc-ai-service/capabilities/knowledge-base/src/router.py +85 -0
  151. package/skills/trtc-ai-service/capabilities/session-summary/INTERFACE_ADAPT.md +99 -0
  152. package/skills/trtc-ai-service/capabilities/session-summary/README.md +47 -0
  153. package/skills/trtc-ai-service/capabilities/session-summary/data/test_session.json +18 -0
  154. package/skills/trtc-ai-service/capabilities/session-summary/manifest.yaml +165 -0
  155. package/skills/trtc-ai-service/capabilities/session-summary/src/__init__.py +2 -0
  156. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/__init__.py +5 -0
  157. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/base.py +31 -0
  158. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/default_rest.py +67 -0
  159. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/factory.py +51 -0
  160. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/local_json.py +42 -0
  161. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/mock.py +22 -0
  162. package/skills/trtc-ai-service/capabilities/session-summary/src/recorder.py +210 -0
  163. package/skills/trtc-ai-service/capabilities/session-summary/src/router.py +93 -0
  164. package/skills/trtc-ai-service/capabilities/session-summary/src/summarizer.py +163 -0
  165. package/skills/trtc-ai-service/capabilities/tool-calling/INTERFACE_ADAPT.md +158 -0
  166. package/skills/trtc-ai-service/capabilities/tool-calling/README.md +50 -0
  167. package/skills/trtc-ai-service/capabilities/tool-calling/data/tools.yaml +58 -0
  168. package/skills/trtc-ai-service/capabilities/tool-calling/examples/__init__.py +1 -0
  169. package/skills/trtc-ai-service/capabilities/tool-calling/examples/local_tools.py +101 -0
  170. package/skills/trtc-ai-service/capabilities/tool-calling/manifest.yaml +146 -0
  171. package/skills/trtc-ai-service/capabilities/tool-calling/src/__init__.py +8 -0
  172. package/skills/trtc-ai-service/capabilities/tool-calling/src/dispatcher.py +54 -0
  173. package/skills/trtc-ai-service/capabilities/tool-calling/src/registry.py +219 -0
  174. package/skills/trtc-ai-service/capabilities/tool-calling/src/router.py +50 -0
  175. package/skills/trtc-ai-service/references/business-contract-spec.md +263 -0
  176. package/skills/trtc-ai-service/scenarios/custom-builder/README.md +86 -0
  177. package/skills/trtc-ai-service/scenarios/custom-builder/output-templates/recipe.yaml.j2 +194 -0
  178. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q1-business-scenario.md +43 -0
  179. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q2-io-modality.md +57 -0
  180. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q3-ui-form.md +55 -0
  181. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q4-capabilities.md +78 -0
  182. package/skills/trtc-ai-service/scenarios/customer-service/README.md +114 -0
  183. package/skills/trtc-ai-service/scenarios/customer-service/recipe.yaml +154 -0
  184. package/skills/trtc-ai-service/scenarios/customer-service/sample-data/README.md +32 -0
  185. package/skills/trtc-ai-service/scenarios/customer-service/sample-data/faq-sample.json +37 -0
  186. package/skills/trtc-ai-service/scenarios/customer-service/system-prompt.template.md +94 -0
  187. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/app.js +347 -0
  188. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/index.html +125 -0
  189. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/styles.css +487 -0
  190. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/tokens.css +71 -0
  191. package/skills/trtc-ai-service/scenarios/customer-service/ui/design-system/DESIGN_GUIDELINES.md +370 -0
  192. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/README.md +68 -0
  193. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/app.js +1307 -0
  194. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/data.js +40 -0
  195. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/index.html +233 -0
  196. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/mock-shop.json +21 -0
  197. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/styles.css +603 -0
  198. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/tokens.css +71 -0
  199. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/agent-link.js +323 -0
  200. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/app.js +458 -0
  201. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/index.html +109 -0
  202. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/styles.css +489 -0
  203. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/tokens.css +59 -0
  204. package/skills/trtc-ai-service/scripts/add-capability.py +364 -0
  205. package/skills/trtc-ai-service/scripts/contract-adapt.py +334 -0
  206. package/skills/trtc-ai-service/scripts/detect-stack.py +40 -0
  207. package/skills/trtc-ai-service/scripts/lib/__init__.py +20 -0
  208. package/skills/trtc-ai-service/scripts/lib/adapter_codegen.py +509 -0
  209. package/skills/trtc-ai-service/scripts/lib/arbitrator.py +152 -0
  210. package/skills/trtc-ai-service/scripts/lib/contract_resolver.py +519 -0
  211. package/skills/trtc-ai-service/scripts/lib/credential_validators.py +253 -0
  212. package/skills/trtc-ai-service/scripts/lib/curl_parser.py +303 -0
  213. package/skills/trtc-ai-service/scripts/lib/degrader.py +140 -0
  214. package/skills/trtc-ai-service/scripts/lib/injector.py +347 -0
  215. package/skills/trtc-ai-service/scripts/lib/manifest_resolver.py +288 -0
  216. package/skills/trtc-ai-service/scripts/lib/openapi_parser.py +289 -0
  217. package/skills/trtc-ai-service/scripts/lib/stack_detector.py +159 -0
  218. package/skills/trtc-ai-service/scripts/lib/tokens_compile.py +204 -0
  219. package/skills/trtc-ai-service/scripts/post-install-patch.py +225 -0
  220. package/skills/trtc-ai-service/scripts/setup-credentials.py +393 -0
  221. package/skills/trtc-ai-service/scripts/verify-credentials.py +108 -0
  222. package/skills/trtc-ai-service/start.sh +111 -0
  223. package/skills/trtc-ai-service/tests/__init__.py +1 -0
  224. package/skills/trtc-ai-service/tests/test_arbitrator.py +64 -0
  225. package/skills/trtc-ai-service/tests/test_capability_overlay.py +85 -0
  226. package/skills/trtc-ai-service/tests/test_contract_resolver.py +190 -0
  227. package/skills/trtc-ai-service/tests/test_handoff_ports.py +195 -0
  228. package/skills/trtc-ai-service/tests/test_kb_ports.py +195 -0
  229. package/skills/trtc-ai-service/tests/test_manifest_resolver.py +95 -0
  230. package/skills/trtc-ai-service/tests/test_recipe_assembly.py +175 -0
  231. package/skills/trtc-ai-service/tests/test_stack_and_degrader.py +101 -0
  232. package/skills/trtc-ai-service/tests/test_verify_credentials.py +285 -0
  233. package/skills/trtc-ai-service/triggers.yaml +29 -0
  234. package/skills/trtc-conference/SKILL.md +324 -0
  235. package/skills/trtc-conference/flows/onboarding.md +205 -0
  236. package/skills/trtc-conference/flows/topic.md +474 -0
  237. package/skills/trtc-conference/flows/troubleshoot.md +85 -0
  238. package/skills/trtc-conference/hooks/pretooluse_require_business_decisions.py +213 -0
  239. package/skills/trtc-conference/playbooks/medical-quickstart.md +84 -0
  240. package/skills/trtc-conference/playbooks/official-roomkit.md +97 -0
  241. package/skills/trtc-conference/references/local-usersig/basic-info-config.ts +39 -0
  242. package/skills/trtc-conference/references/usersig-handling.md +134 -0
  243. package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
  244. package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
  245. package/skills/trtc-conference/tests/__pycache__/test_conference_onboarding_contract.cpython-313-pytest-9.0.2.pyc +0 -0
  246. package/skills/trtc-conference/tests/__pycache__/test_conference_topic_flow_contract.cpython-313-pytest-9.0.2.pyc +0 -0
  247. package/skills/trtc-conference/tests/test_conference_index_contract.py +43 -0
  248. package/skills/trtc-conference/tests/test_conference_onboarding_contract.py +103 -0
  249. package/skills/trtc-conference/tests/test_conference_template_contract.py +25 -0
  250. package/skills/trtc-conference/tests/test_conference_topic_flow_contract.py +132 -0
  251. package/skills/trtc-conference/tools/apply_checks.py +328 -0
  252. package/skills/trtc-conference/verify_lib/__init__.py +0 -0
  253. package/skills/{trtc-apply/guardrails/apply_lib → trtc-conference/verify_lib}/rule_parser.py +1 -1
  254. package/skills/trtc-docs/SKILL.md +91 -119
  255. package/.cursor/rules/ui-mode.mdc +0 -99
  256. package/ai-instructions/base.md +0 -13
  257. package/ai-instructions/ui-mode.md +0 -93
  258. package/knowledge-base/index.yaml +0 -462
  259. package/skills/trtc/room-builder/SKILL.md +0 -133
  260. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +0 -108
  261. package/skills/trtc/room-builder/tools/render_ai_instructions.py +0 -226
  262. package/skills/trtc-apply/SKILL.md +0 -97
  263. package/skills/trtc-onboarding/SKILL.md +0 -841
  264. package/skills/trtc-onboarding/reference/path-a1-demo.md +0 -103
  265. package/skills/trtc-onboarding/reference/path-a2-integrate.md +0 -737
  266. package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +0 -186
  267. package/skills/trtc-onboarding/reference/path-c-expand.md +0 -43
  268. package/skills/trtc-onboarding/reference/supported-matrix.md +0 -100
  269. package/skills/trtc-search/SKILL.md +0 -228
  270. package/skills/trtc-topic/SKILL.md +0 -622
  271. package/skills/trtc-topic/scripts/apply.py +0 -581
  272. package/skills/trtc-topic/scripts/lib/state_machine.py +0 -328
  273. package/skills/trtc-topic/tests/README.md +0 -70
  274. package/skills/trtc-topic/tests/conftest.py +0 -72
  275. package/skills/trtc-topic/tests/test_apply_cli.py +0 -480
  276. package/skills/trtc-topic/tests/test_end_to_end.py +0 -305
  277. package/skills/trtc-topic/tests/test_finalize_session.py +0 -51
  278. package/skills/trtc-topic/tests/test_gates.py +0 -316
  279. package/skills/trtc-topic/tests/test_session_resolver.py +0 -260
  280. package/skills/trtc-topic/tests/test_state_machine.py +0 -414
  281. package/skills/trtc-topic/tests/test_stop_require_apply.py +0 -99
  282. package/skills/trtc-topic/tests/test_topic_skill_invariants.py +0 -130
  283. /package/skills/{trtc-topic → trtc}/runtime/lib/platforms.py +0 -0
  284. /package/skills/{trtc-topic → trtc}/runtime/telemetry_collector.py +0 -0
  285. /package/skills/{trtc-onboarding/reference → trtc/runtime}/usersig-handling.md +0 -0
  286. /package/skills/{trtc-topic/scripts → trtc/tools}/finalize_session.py +0 -0
  287. /package/skills/{trtc-apply/guardrails/apply_lib → trtc-ai-service/capabilities/conversation-core/tests}/__init__.py +0 -0
  288. /package/skills/{trtc-topic → trtc-conference}/references/execution-units.yaml +0 -0
  289. /package/skills/{trtc/room-builder/templates/scenarios/medical-consultation/src/config → trtc-conference/references/local-usersig}/lib-generate-test-usersig-es.min.d.ts +0 -0
  290. /package/skills/{trtc/room-builder/templates/scenarios/medical-consultation/src/config → trtc-conference/references/local-usersig}/lib-generate-test-usersig-es.min.js +0 -0
  291. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/backend-contract.zh-CN.md +0 -0
  292. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/integration.zh-CN.md +0 -0
  293. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/theme.zh-CN.md +0 -0
  294. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/index.html +0 -0
  295. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/package.json +0 -0
  296. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/postcss.config.js +0 -0
  297. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/App.vue +0 -0
  298. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/ConsultationManagePanel.vue +0 -0
  299. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LanguageSwitch.vue +0 -0
  300. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LoadingSpinner.vue +0 -0
  301. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalAlert.vue +0 -0
  302. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalBusinessPanel.vue +0 -0
  303. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalButton.vue +0 -0
  304. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalConfirmDialog.vue +0 -0
  305. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalDataPanel.vue +0 -0
  306. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalRecordPanel.vue +0 -0
  307. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/PrescriptionPanel.vue +0 -0
  308. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/basic-info-config.ts +0 -0
  309. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/runtime-config.ts +0 -0
  310. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/env.d.ts +0 -0
  311. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +0 -0
  312. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +0 -0
  313. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +0 -0
  314. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +0 -0
  315. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +0 -0
  316. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +0 -0
  317. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/types.ts +0 -0
  318. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationChat.ts +0 -0
  319. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationDevices.ts +0 -0
  320. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationParticipants.ts +0 -0
  321. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationPermissions.ts +0 -0
  322. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/utils.ts +0 -0
  323. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/en-US/index.ts +0 -0
  324. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/index.ts +0 -0
  325. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/medicalTranslate.ts +0 -0
  326. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/state.ts +0 -0
  327. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/zh-CN/index.ts +0 -0
  328. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/main.ts +0 -0
  329. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/appointments.ts +0 -0
  330. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/users.ts +0 -0
  331. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/router/index.ts +0 -0
  332. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/index.ts +0 -0
  333. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/appointmentService.ts +0 -0
  334. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/authService.ts +0 -0
  335. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/launchContext.ts +0 -0
  336. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/userService.ts +0 -0
  337. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/appointmentService.ts +0 -0
  338. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/authService.ts +0 -0
  339. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/userService.ts +0 -0
  340. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/types.ts +0 -0
  341. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/shared/icons.ts +0 -0
  342. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/index.css +0 -0
  343. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/tailwind.css +0 -0
  344. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/theme.css +0 -0
  345. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/auth.ts +0 -0
  346. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/format.ts +0 -0
  347. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/navigation.ts +0 -0
  348. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/session.ts +0 -0
  349. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorConsultationView.vue +0 -0
  350. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorDashboardView.vue +0 -0
  351. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/LoginView.vue +0 -0
  352. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationFinishedView.vue +0 -0
  353. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationView.vue +0 -0
  354. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientSelectDoctorView.vue +0 -0
  355. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientWaitingView.vue +0 -0
  356. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.json +0 -0
  357. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.node.json +0 -0
  358. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/vite.config.ts +0 -0
  359. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation//346/216/245/345/205/245/350/257/264/346/230/216.md" +0 -0
  360. /package/skills/{trtc-topic/runtime/lib → trtc-conference/tools}/__init__.py +0 -0
@@ -1,216 +1,1085 @@
1
1
  # 平台 Slice 模板
2
2
 
3
3
  > **本文件是平台实现 slice 的标准模板。**
4
- > 复制本文件到 `slices/{product}/{platform}/{ability}.md`,按 `<!-- 指引: ... -->` 批注填写内容,填完后删除所有批注。
4
+ > 复制本文件到 `slices/{product}/{platform}/{ability}.md`,按 `<!-- 指引: ... -->` 批注填写内容,**填完后删除所有批注**。
5
5
  >
6
- > **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 目前最完整的平台 slice,包含所有 section 的真实内容。
6
+ > **三步走**:
7
+ > 1. 复制本文件 → 把 `{占位符}` 全部替换为真实内容
8
+ > 2. 对照每个 section 批注里的 ✅ 正例 / ❌ 反例自查
9
+ > 3. 跑批注里给出的「验证命令」,通过后再提交
10
+ > 复制本文件到 `slices/{product}/{platform}/{ability}.md`,按 `<!-- 指引: ... -->` 批注填写内容,**填完后删除所有批注**。
11
+ >
12
+ > **三步走**:
13
+ > 1. 复制本文件 → 把 `{占位符}` 全部替换为真实内容
14
+ > 2. 对照每个 section 批注里的 ✅ 正例 / ❌ 反例自查
15
+ > 3. 跑批注里给出的「验证命令」,通过后再提交
16
+ >
17
+ > **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 目前最完整的平台 slice,包含所有 section 的真实内容。
18
+ > **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
19
+ > **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 目前最完整的平台 slice,包含所有 section 的真实内容。
20
+ > **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
7
21
 
8
22
  ---
9
23
 
10
24
  ```yaml
11
25
  ---
12
- id: {product}/{ability} # [必填] index.yaml 中的 id 一致
26
+ id: {product}/{ability} # [必填] 与对应的 per-product platform index 中的 id 一致
13
27
  platform: {platform} # [必填] ios / android / web / flutter / electron
14
- api_docs: # [必填] 该平台对应的 API 参考文档链接,至少 1 条
28
+ api_docs: # [必填] 该平台对应的 API 参考文档链接,至少 1 条
29
+ api_docs: # [必填] 该平台对应的 API 参考文档链接,至少 1 条
15
30
  - title: {API 类名/模块名}
16
31
  url: https://...
17
32
  ---
18
33
  ```
19
34
 
20
35
  <!-- 指引: Frontmatter 字段说明:
21
- - id: index.yaml 中的 slice id 完全一致
36
+ - id: 与对应的 per-product platform index 中的 slice id 完全一致
22
37
  - platform: 当前平台标识
23
38
  - api_docs: 该功能在该平台的 API 参考文档链接(接口签名、参数类型、返回值等)。
24
39
  产品级概览已不再放文档链接,教程/指南类 URL 也不放在 api_docs 里。
25
40
 
26
- 必须精确到类/模块级的 URL(如 CoGuestStore 的 API 页面)
27
- 涉及多个类时可有多条(如 CoGuestStore + DeviceStore 各一条)
28
- 不要填 SDK 首页(AI 拿不到校验所需的签名信息)
29
- 不要填产品级教程页
41
+ 1️⃣ 你必须写什么
42
+ - id:与 index.yaml 中的 slice id **完全一致**(含连字符大小写)
43
+ - platform:当前平台标识(只能是 ios / android / web / flutter / electron 之一)
44
+ - api_docs:该功能在该平台的 API 参考文档链接(精确到类/模块,至少 1 条)
45
+
46
+ 2️⃣ 写作模板
47
+ api_docs:
48
+ - title: {本 slice 涉及的具体类名,如 CoGuestStore}
49
+ url: https://{平台 SDK 文档站}/.../{类名小写}/
50
+
51
+ 判定 url 是否合格:打开链接,**第一屏**就能看到本 slice 涉及的**具体类的方法签名**(参数名、参数类型、返回值)→ ✅ 合格
52
+
53
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
54
+ api_docs:
55
+ - title: CoGuestStore
56
+ url: https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/cogueststore/
57
+ - title: DeviceStore
58
+ url: https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/devicestore/
59
+ 为什么是正例:
60
+ - 链接路径含 /documentation/ → 是 API 参考站
61
+ - 路径末尾是具体类名 cogueststore → 精确到类
62
+ - slice 涉及两个 Store → 分别列出,不省略
63
+
64
+ 4️⃣ ❌ 反例
65
+ - title: TRTC iOS SDK
66
+ url: https://trtc.io/sdk ← SDK 首页:AI 拿不到类签名,生成不存在的 API
67
+ - title: 连麦集成指南
68
+ url: https://trtc.io/zh/document/74598 ← 教程页:API 名常被简化,AI 引用错误
69
+ - title: TODO
70
+ url: TODO ← 占位:永远不会被替换,半年后就是废 slice
71
+
72
+ 5️⃣ 必填项语义三件套
73
+ - 违反后果:链接非类级 → AI 生成不存在的 API 名 → 客户编译报错投诉
74
+ - 验证手段:python scripts/validate_api_docs.py {file}
75
+ 通过标准:每条 url 返回 200;url 含 /documentation/ 或 /api/;打开链接的页面 H1 必须包含 frontmatter 里的 title
76
+ - 绕过条件:该平台官方确实无 API 参考站(如某些早期 Electron 模块)→ 必须填头文件 GitHub 永久链接(含 commit hash),且在 PR 中说明
30
77
 
31
- 其余元数据(nametagsplatformsrelated)在产品级概览中维护,此处不重复。
78
+ 注:name / tags / platforms / related 在产品级概览中维护,此处不重复。
32
79
  -->
33
80
 
34
81
  # {名称} — {平台} 实现
35
82
 
36
83
  ## 前置条件 [必填]
37
84
 
38
- <!-- 指引: 通用依赖(SDK 安装、基础权限)已在 login-auth 平台 slice 中统一描述,此处不要重复。
39
- 本 section 只写两类内容:
85
+ <!-- 指引: 前置条件 [必填]
40
86
 
41
- 1. 增量依赖 — 本 slice 额外需要的库/权限(如美颜 SDK、蓝牙权限)。
42
- 如果没有额外依赖,写「无额外依赖」即可。
43
- 2. 前置状态 本功能依赖哪些 Store 已初始化/哪些操作已完成,引用对应 slice ID。
87
+ 1️⃣ 你必须写什么
88
+ 列出本 slice 代码运行前必须满足的状态,**用引用形式**指向其他 slice。
89
+ 通用依赖(SDK 安装、基础权限)已在 login-auth 中统一描述,**禁止重复**。
44
90
 
45
- 不要重复写 SDK 主包安装(如 pod 'AtomicXCore'、implementation 'com.tencent.liteav:...')
46
- 不要重复写基础权限声明(如 NSCameraUsageDescription、CAMERA permission),除非本 slice 需要额外权限
47
- 不要写通用开发环境搭建(如「安装 Xcode」「安装 Android Studio」)
48
- -->
91
+ section 只写两类内容:
92
+ - 增量依赖 slice 额外需要的库/权限(如美颜 SDK、蓝牙权限)
93
+ - 前置状态 本功能依赖哪些 Store 已初始化/操作已完成,引用对应 slice ID
94
+
95
+ 2️⃣ 写作模板
96
+ **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
97
+
98
+ **额外依赖**:{无 / 列出本 slice 独有依赖}
99
+
100
+ **前置状态**:
101
+ - `{Store/状态}.{属性} == {期望值}`(→ {产品}/{依赖 slice})
102
+ - {跨角色前置:如"主播端已开播"}
103
+
104
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
105
+ **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
106
+
107
+ **额外依赖**:无
49
108
 
50
- **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
109
+ **前置状态**:
110
+ - 已完成登录(→ live/login-auth),`LoginStore.shared.isLogin == true`
111
+ - 已加入房间且角色为观众(→ live/room-lifecycle),`RoomStore.shared.localUser.role == .audience`
112
+ - 主播端已开播且开启了"接受连麦申请"开关
113
+ 为什么是正例:
114
+ - 用 → slice-id 标注依赖,不重复说明怎么登录
115
+ - 给出可机械验证的状态条件(role == .audience)
116
+ - 包含跨角色前置(主播端配置)
51
117
 
52
- **额外依赖**:
53
- <!-- 如果有本 slice 独有的依赖,在此列出;没有则写「无」 -->
118
+ 4️⃣ ❌ 反例
119
+ 要先安装 SDK `pod 'TUIKit'`,然后调用 LoginStore.login(userId:userSig:) 登录,
120
+ 然后调用 RoomStore.joinRoom(roomId:) 加入房间,...
121
+ 为什么是反例:
122
+ - 重复了 base-setup / login-auth 的内容
123
+ - 这些内容会随版本变化,这里写一份等于埋雷
124
+ - 没用引用形式,信息易漂移
125
+ → 改为 → live/login-auth 引用
54
126
 
55
- **前置状态**:
56
- <!-- 列出必须满足的前置条件,引用 slice ID。例如:
57
- - `LoginStore.shared` 登录成功(→ live/login-auth)
58
- - 已进入直播间,持有有效 liveID(→ live/audience-watch)
127
+ 5️⃣ 必填项语义三件套
128
+ - 违反后果:重复其他 slice 内容 → 信息漂移(版本升级后这里没同步)→ AI 生成过时代码
129
+ - 验证手段:全文搜安装关键字应命中 0 次:
130
+ grep -E "pod install|pod 'AtomicXCore'|npm install|implementation 'com.tencent" {file}
131
+ - 绕过条件:本 slice 确实需要额外依赖(如美颜 SDK)→ 在「额外依赖」段列出
132
+ <!-- 指引: 前置条件 [必填]
133
+
134
+ 1️⃣ 你必须写什么
135
+ 列出本 slice 代码运行前必须满足的状态,**用引用形式**指向其他 slice。
136
+ 通用依赖(SDK 安装、基础权限)已在 login-auth 中统一描述,**禁止重复**。
137
+
138
+ 本 section 只写两类内容:
139
+ - 增量依赖 — 本 slice 额外需要的库/权限(如美颜 SDK、蓝牙权限)
140
+ - 前置状态 — 本功能依赖哪些 Store 已初始化/操作已完成,引用对应 slice ID
141
+
142
+ 2️⃣ 写作模板
143
+ **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
144
+
145
+ **额外依赖**:{无 / 列出本 slice 独有依赖}
146
+
147
+ **前置状态**:
148
+ - `{Store/状态}.{属性} == {期望值}`(→ {产品}/{依赖 slice})
149
+ - {跨角色前置:如"主播端已开播"}
150
+
151
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
152
+ **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
153
+
154
+ **额外依赖**:无
155
+
156
+ **前置状态**:
157
+ - 已完成登录(→ live/login-auth),`LoginStore.shared.isLogin == true`
158
+ - 已加入房间且角色为观众(→ live/room-lifecycle),`RoomStore.shared.localUser.role == .audience`
159
+ - 主播端已开播且开启了"接受连麦申请"开关
160
+ 为什么是正例:
161
+ - 用 → slice-id 标注依赖,不重复说明怎么登录
162
+ - 给出可机械验证的状态条件(role == .audience)
163
+ - 包含跨角色前置(主播端配置)
164
+
165
+ 4️⃣ ❌ 反例
166
+ 要先安装 SDK 包 `pod 'TUIKit'`,然后调用 LoginStore.login(userId:userSig:) 登录,
167
+ 然后调用 RoomStore.joinRoom(roomId:) 加入房间,...
168
+ 为什么是反例:
169
+ - 重复了 base-setup / login-auth 的内容
170
+ - 这些内容会随版本变化,这里写一份等于埋雷
171
+ - 没用引用形式,信息易漂移
172
+ → 改为 → live/login-auth 引用
173
+
174
+ 5️⃣ 必填项语义三件套
175
+ - 违反后果:重复其他 slice 内容 → 信息漂移(版本升级后这里没同步)→ AI 生成过时代码
176
+ - 验证手段:全文搜安装关键字应命中 0 次:
177
+ grep -E "pod install|pod 'AtomicXCore'|npm install|implementation 'com.tencent" {file}
178
+ - 绕过条件:本 slice 确实需要额外依赖(如美颜 SDK)→ 在「额外依赖」段列出
59
179
  -->
60
180
 
181
+ **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
182
+ **通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
183
+
184
+ **额外依赖**:
185
+ <!-- 如有本 slice 独有依赖,在此列出;没有则写「无」 -->
186
+ **额外依赖**:
187
+ <!-- 如有本 slice 独有依赖,在此列出;没有则写「无」 -->
188
+
189
+ **前置状态**:
190
+ <!-- 列出必须满足的前置条件,引用 slice ID -->
191
+ **前置状态**:
192
+ <!-- 列出必须满足的前置条件,引用 slice ID -->
193
+
61
194
  ## 代码示例 [必填]
62
195
 
63
- <!-- 指引: section 是平台 slice 的核心交付物。详细标准见 slice-spec.md 第四节「代码示例标准」。
64
- 定位是「零件」— 单个功能的完整实现。多个零件如何组装成完整场景,由 scenario 的平台实现文件负责。
65
-
66
- 最低标准(必须全部满足):
67
- 1. 可编译:完整 import、完整类/函数闭包,严禁用 `...` 省略任何逻辑分支
68
- 2. 可运行:补充业务参数后可直接跑通;业务参数用 `{TODO: 填入 xxx}` 占位
69
- 3. 有日志锚点:关键路径(成功/失败/事件到达)必须有日志,供「验证矩阵」运行时使用
70
- 日志统一带模块前缀(如 `[CoGuest]`)
71
- 4. 有错误处理:每个 .failure / catch / error 分支都必须有面向用户的处理(errorMessage / alert),
72
- 不允许只 print 了事
73
- 5. 多角色分开写:主播端 / 观众端 必须拆成独立的代码块,不要耦合
74
- 6. 可组合性:前置依赖通过注释声明(`// 前置:登录完成(→ live/login-auth)`),不硬编码其他 slice 的调用
75
-
76
- 组织方式:按用户操作流程,用 MARK / region / 注释分隔各步骤(初始化 → 核心操作 → 事件监听 → 错误处理 → 清理)
77
-
78
- 不要写伪代码或用省略号 (...) 跳过逻辑
79
- ❌ 不要混入其他 slice 的职责代码
80
- 不要把多个功能耦合在一个类里
81
- ❌ 不要省略错误处理 — 每个失败分支都必须有处理
196
+ <!-- 指引: 代码示例 [必填]
197
+
198
+ 1️⃣ 你必须写什么
199
+ 能让 AI 直接学习并产出**可编译、可运行**的代码块。
200
+ 代码示例 = 这份 slice 给 AI 的"训练数据",每个细节都会被复制放大。
201
+
202
+ 定位是「零件」— 单个功能的完整实现。多个零件如何组装成完整场景,由 scenario 的平台实现文件负责。
203
+ <!-- 指引: 代码示例 [必填]
204
+
205
+ 1️⃣ 你必须写什么
206
+ 能让 AI 直接学习并产出**可编译、可运行**的代码块。
207
+ 代码示例 = 这份 slice 给 AI 的"训练数据",每个细节都会被复制放大。
208
+
209
+ 定位是「零件」— 单个功能的完整实现。多个零件如何组装成完整场景,由 scenario 的平台实现文件负责。
210
+
211
+ 2️⃣ 6 条最低标准(必须全部满足)
212
+
213
+ | 维度 | 最低标准 |
214
+ |------|---------|
215
+ | 可编译 | 含完整 import、完整类/函数闭包,**严禁** ... 省略任何逻辑分支 |
216
+ | 可运行 | 补充业务参数后可直接跑通;业务参数用 {TODO: 填入 xxx} 占位 |
217
+ | 有日志锚点 | 关键路径必须有 print/console.log/Log.d,带模块前缀如 [CoGuest] |
218
+ | 有错误处理 | 每个 .failure / catch / error 分支必须有面向用户的处理(UI 可见的 errorMessage / alert),不允许只 print |
219
+ | 多角色分开写 | 主播端 / 观众端必须拆成独立代码块,不耦合 |
220
+ | 可组合性 | 前置依赖通过注释声明 // 前置:登录完成(→ live/login-auth),不硬编码其他 slice 调用 |
221
+
222
+ 组织方式:按用户操作流程,用 MARK / region / 注释分隔各步骤(初始化 → 核心操作 → 事件监听 → 错误处理 → 清理)
223
+
224
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
225
+ ```swift
226
+ // 前置:登录完成(→ chat/login-auth)
227
+ // 前置:已加入房间(→ live/room-lifecycle)
228
+
229
+ import TencentImSDKPlugin
230
+ import Combine
231
+
232
+ class CoGuestApplyViewModel: ObservableObject {
233
+ @Published var errorMessage: String? // ← UI 必需,展示给用户
234
+ private var cancellables = Set<AnyCancellable>()
235
+
236
+ func applyForSeat() {
237
+ print("[CoGuest] 开始发起连麦申请") // ← 日志锚点
238
+
239
+ CoGuestStore.shared.applyForSeat(timeout: 30)
240
+ .sink { [weak self] completion in // ← [weak self] 必需
241
+ if case .failure(let error) = completion {
242
+ print("[CoGuest] 申请失败: \(error)")
243
+ self?.errorMessage = "连麦申请失败,请重试" // ← 用户可见
244
+ }
245
+ } receiveValue: { [weak self] _ in
246
+ print("[CoGuest] 申请已发送")
247
+ self?.errorMessage = nil
248
+ }
249
+ .store(in: &cancellables)
250
+ }
251
+ }
252
+ ```
253
+ 为什么是正例:
254
+ - 顶部 // 前置 注释声明依赖 slice,不耦合调用
255
+ - import 完整,可直接编译
256
+ - 业务参数(timeout)用真实值不是 xxx
257
+ - 关键路径有 print 锚点,带 [CoGuest] 模块前缀
258
+ - 每个 failure 分支都设置 errorMessage(UI 可见),不是只 print
259
+ - [weak self] 防循环引用
260
+
261
+ 4️⃣ ❌ 反例
262
+ 反例 1:用 ... 省略
263
+ func applyForSeat() {
264
+ CoGuestStore.shared.applyForSeat(...) { result in
265
+ // 处理结果
266
+ ...
267
+ }
268
+ }
269
+ → "..." 跳过了失败处理,AI 学到这个模式后到处省略
270
+
271
+ 反例 2:仅 print 错误
272
+ .sink { completion in
273
+ if case .failure(let error) = completion {
274
+ print("error: \(error)") // ← 用户看不到!
275
+ }
276
+ }
277
+ → 客户线上故障时用户只看到无反应
278
+
279
+ 反例 3:省略 import
280
+ class XXX {
281
+ var cancellables = Set<AnyCancellable>()
282
+ // ↑ 没 import Combine,代码贴出来不能编译
283
+ }
284
+
285
+ 反例 4:业务参数瞎编
286
+ applyForSeat(seatIndex: 1, timeout: 60, reason: "我想连麦")
287
+ → "我想连麦" 应该用 {TODO: 填入业务申请理由} 占位
288
+
289
+ 反例 5:多角色塞一个类里
290
+ class CoGuestManager {
291
+ func audienceApply() { ... }
292
+ func hostApprove() { ... }
293
+ }
294
+ → 主播观众职责混合,AI 生成时随机抽方法
295
+
296
+ 5️⃣ 必填项语义三件套
297
+ - 违反后果:含 ... / 仅 print 错误 / 省略 import → AI 学坏 → 跨 slice 蔓延错误模式 → slice 不可合并,**已合并的批量回退**(2025-03 真实事故,2 周返工)
298
+ - 验证手段:
299
+ # 1. 抽取代码块编译
300
+ python scripts/extract_code.py {file} | xcodebuild build ...
301
+ # 2. 静态扫描
302
+ grep -E "\\.\\.\\.|//\\s*处理结果|//\\s*TODO[^:]" {file} # 必须命中 0 次
303
+ grep -E "errorMessage|alert|toast" {file} # 每个 .failure 块至少 1 处
304
+ - 绕过条件:无。"先占位以后补"的代码示例 = 永远不会补的代码示例
305
+ 2️⃣ 6 条最低标准(必须全部满足)
306
+
307
+ | 维度 | 最低标准 |
308
+ |------|---------|
309
+ | 可编译 | 含完整 import、完整类/函数闭包,**严禁** ... 省略任何逻辑分支 |
310
+ | 可运行 | 补充业务参数后可直接跑通;业务参数用 {TODO: 填入 xxx} 占位 |
311
+ | 有日志锚点 | 关键路径必须有 print/console.log/Log.d,带模块前缀如 [CoGuest] |
312
+ | 有错误处理 | 每个 .failure / catch / error 分支必须有面向用户的处理(UI 可见的 errorMessage / alert),不允许只 print |
313
+ | 多角色分开写 | 主播端 / 观众端必须拆成独立代码块,不耦合 |
314
+ | 可组合性 | 前置依赖通过注释声明 // 前置:登录完成(→ live/login-auth),不硬编码其他 slice 调用 |
315
+
316
+ 组织方式:按用户操作流程,用 MARK / region / 注释分隔各步骤(初始化 → 核心操作 → 事件监听 → 错误处理 → 清理)
317
+
318
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
319
+ ```swift
320
+ // 前置:登录完成(→ chat/login-auth)
321
+ // 前置:已加入房间(→ live/room-lifecycle)
322
+
323
+ import TencentImSDKPlugin
324
+ import Combine
325
+
326
+ class CoGuestApplyViewModel: ObservableObject {
327
+ @Published var errorMessage: String? // ← UI 必需,展示给用户
328
+ private var cancellables = Set<AnyCancellable>()
329
+
330
+ func applyForSeat() {
331
+ print("[CoGuest] 开始发起连麦申请") // ← 日志锚点
332
+
333
+ CoGuestStore.shared.applyForSeat(timeout: 30)
334
+ .sink { [weak self] completion in // ← [weak self] 必需
335
+ if case .failure(let error) = completion {
336
+ print("[CoGuest] 申请失败: \(error)")
337
+ self?.errorMessage = "连麦申请失败,请重试" // ← 用户可见
338
+ }
339
+ } receiveValue: { [weak self] _ in
340
+ print("[CoGuest] 申请已发送")
341
+ self?.errorMessage = nil
342
+ }
343
+ .store(in: &cancellables)
344
+ }
345
+ }
346
+ ```
347
+ 为什么是正例:
348
+ - 顶部 // 前置 注释声明依赖 slice,不耦合调用
349
+ - import 完整,可直接编译
350
+ - 业务参数(timeout)用真实值不是 xxx
351
+ - 关键路径有 print 锚点,带 [CoGuest] 模块前缀
352
+ - 每个 failure 分支都设置 errorMessage(UI 可见),不是只 print
353
+ - [weak self] 防循环引用
354
+
355
+ 4️⃣ ❌ 反例
356
+ 反例 1:用 ... 省略
357
+ func applyForSeat() {
358
+ CoGuestStore.shared.applyForSeat(...) { result in
359
+ // 处理结果
360
+ ...
361
+ }
362
+ }
363
+ → "..." 跳过了失败处理,AI 学到这个模式后到处省略
364
+
365
+ 反例 2:仅 print 错误
366
+ .sink { completion in
367
+ if case .failure(let error) = completion {
368
+ print("error: \(error)") // ← 用户看不到!
369
+ }
370
+ }
371
+ → 客户线上故障时用户只看到无反应
372
+
373
+ 反例 3:省略 import
374
+ class XXX {
375
+ var cancellables = Set<AnyCancellable>()
376
+ // ↑ 没 import Combine,代码贴出来不能编译
377
+ }
378
+
379
+ 反例 4:业务参数瞎编
380
+ applyForSeat(seatIndex: 1, timeout: 60, reason: "我想连麦")
381
+ → "我想连麦" 应该用 {TODO: 填入业务申请理由} 占位
382
+
383
+ 反例 5:多角色塞一个类里
384
+ class CoGuestManager {
385
+ func audienceApply() { ... }
386
+ func hostApprove() { ... }
387
+ }
388
+ → 主播观众职责混合,AI 生成时随机抽方法
389
+
390
+ 5️⃣ 必填项语义三件套
391
+ - 违反后果:含 ... / 仅 print 错误 / 省略 import → AI 学坏 → 跨 slice 蔓延错误模式 → slice 不可合并,**已合并的批量回退**(2025-03 真实事故,2 周返工)
392
+ - 验证手段:
393
+ # 1. 抽取代码块编译
394
+ python scripts/extract_code.py {file} | xcodebuild build ...
395
+ # 2. 静态扫描
396
+ grep -E "\\.\\.\\.|//\\s*处理结果|//\\s*TODO[^:]" {file} # 必须命中 0 次
397
+ grep -E "errorMessage|alert|toast" {file} # 每个 .failure 块至少 1 处
398
+ - 绕过条件:无。"先占位以后补"的代码示例 = 永远不会补的代码示例
82
399
  -->
83
400
 
84
- ## 调用时序 [条件必填:多角色异步交互 或 回调嵌套 ≥3 层]
401
+ ## 调用时序 [条件必填:多角色异步交互 或 回调嵌套 ≥3 层]
402
+ ## 调用时序 [条件必填:多角色异步交互 或 回调嵌套 ≥3 层]
85
403
 
86
- <!-- 指引: 【条件必填】— 触发条件任一满足即必须画:
87
- — 多角色交互(主播/观众/服务端三方时序不容易从单段代码看出)
88
- — 异步回调链路特别深(3 层以上嵌套回调)
89
- — 有隐含的时序依赖不写出来容易踩坑(如「必须先订阅再操作」)
404
+ <!-- 指引: 调用时序 [条件必填]
90
405
 
91
- 如果代码示例已经足够清晰(单角色、同步或浅回调),可以跳过此 section 并整段删除。
406
+ 1️⃣ 触发条件(任一满足即必须画)
407
+ - 多角色交互(主播/观众/服务端三方时序不容易从单段代码看出)
408
+ - 异步回调链路特别深(3 层以上嵌套回调)
409
+ - 状态机分支 ≥3 个
410
+
411
+ 不满足 → **整段删除**,不要留空。
412
+
413
+ 2️⃣ 写作模板(ASCII 时序图)
414
+ ```
415
+ {角色 A} {SDK / 中介} {角色 B}
416
+ │ │ │
417
+ ├─ {操作} ──→ │ │
418
+ │ ├─ {事件} ──→ │
419
+ │ │ ├─ {响应}
420
+ │ ←─ {回调} ─────┤
421
+ ```
422
+
423
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
424
+ ```
425
+ 观众端 SDK 主播端
426
+ │ │
427
+ ├─ applyForSeat ──→ │
428
+ │ │
429
+ │ ←─ onApplication ─┤
430
+ │ │
431
+ │ ←─ approve ──────┤
432
+ │ │
433
+ ├─ {打开摄像头/麦克风} │
434
+ │ │
435
+ ```
436
+ 为什么是正例:
437
+ - 三列对应三方角色(观众/SDK/主播),清晰
438
+ - 每条箭头标注具体方法名/事件名,可对应到代码
439
+ - 顺序贴近真实业务时序
440
+
441
+ 4️⃣ ❌ 反例
442
+ 观众发起申请,主播收到后处理,然后通知观众。
443
+ → 不是图,只是一句散文,无法体现并行/异步
444
+
445
+ 或者画图但没标方法名:
446
+ 观众 → 服务器 → 主播
447
+ → 无法对应代码,AI 拿不到信息
448
+
449
+ 5️⃣ 必填项语义三件套
450
+ - 违反后果:多角色交互无时序图 → AI 生成代码角色行为错位 → 上线后双方互相听不到
451
+ - 验证手段:人工 review,触发条件命中即必有;时序图覆盖所有角色和关键事件
452
+ - 绕过条件:不满足触发条件 → 可省(整段删除)
453
+ <!-- 指引: 调用时序 [条件必填]
454
+
455
+ 1️⃣ 触发条件(任一满足即必须画)
456
+ - 多角色交互(主播/观众/服务端三方时序不容易从单段代码看出)
457
+ - 异步回调链路特别深(3 层以上嵌套回调)
458
+ - 状态机分支 ≥3 个
459
+
460
+ 不满足 → **整段删除**,不要留空。
461
+
462
+ 2️⃣ 写作模板(ASCII 时序图)
463
+ ```
464
+ {角色 A} {SDK / 中介} {角色 B}
465
+ │ │ │
466
+ ├─ {操作} ──→ │ │
467
+ │ ├─ {事件} ──→ │
468
+ │ │ ├─ {响应}
469
+ │ ←─ {回调} ─────┤
470
+ ```
92
471
 
93
- 格式:用 ``` 包裹的 ASCII 文本流程图。
472
+ 3️⃣ 正例(摘自 live/ios/coguest-apply)
473
+ ```
474
+ 观众端 SDK 主播端
475
+ │ │
476
+ ├─ applyForSeat ──→ │
477
+ │ │
478
+ │ ←─ onApplication ─┤
479
+ │ │
480
+ │ ←─ approve ──────┤
481
+ │ │
482
+ ├─ {打开摄像头/麦克风} │
483
+ │ │
484
+ ```
485
+ 为什么是正例:
486
+ - 三列对应三方角色(观众/SDK/主播),清晰
487
+ - 每条箭头标注具体方法名/事件名,可对应到代码
488
+ - 顺序贴近真实业务时序
489
+
490
+ 4️⃣ ❌ 反例
491
+ 观众发起申请,主播收到后处理,然后通知观众。
492
+ → 不是图,只是一句散文,无法体现并行/异步
493
+
494
+ 或者画图但没标方法名:
495
+ 观众 → 服务器 → 主播
496
+ → 无法对应代码,AI 拿不到信息
497
+
498
+ 5️⃣ 必填项语义三件套
499
+ - 违反后果:多角色交互无时序图 → AI 生成代码角色行为错位 → 上线后双方互相听不到
500
+ - 验证手段:人工 review,触发条件命中即必有;时序图覆盖所有角色和关键事件
501
+ - 绕过条件:不满足触发条件 → 可省(整段删除)
94
502
  -->
95
503
 
96
- ## 平台特有注意事项 [必填:至少 1 条]
504
+ ## 平台特有注意事项 [必填:至少 1 条]
505
+ ## 平台特有注意事项 [必填:至少 1 条]
506
+
507
+ <!-- 指引: 平台特有注意事项 [必填,至少 1 条]
508
+
509
+ 1️⃣ 你必须写什么
510
+ 仅在该平台才会踩的坑。每条标准:**该平台独有 + 不写出来研发会踩**。
511
+ 跨平台通用的注意事项 → 上移到产品级概览的 ALWAYS/NEVER。
512
+
513
+ 2️⃣ 写作模板
514
+ ### {编号}. {一句话标题}
515
+ **现象**:{开发者会遇到什么具体表现}
516
+ **原因**:{为什么会这样,SDK / 平台机制层面}
517
+ **必须做**:{具体动作,可机械执行}
518
+
519
+ 3️⃣ ✅ 正例(iOS)
520
+ ### 1. AnyCancellable 必须存为实例属性
521
+ **现象**:.sink 闭包永远不触发,日志没有任何输出
522
+ **原因**:局部变量 cancellable 出作用域后被释放,Combine 自动解除订阅
523
+ **必须做**:声明 `private var cancellables = Set<AnyCancellable>()` 实例属性,
524
+ 所有 sink 后接 `.store(in: &cancellables)`
525
+
526
+ ### 2. sink 闭包必须显式 [weak self]
527
+ **现象**:VC dismiss 后 ViewModel 不释放,Memory Graph 显示循环引用
528
+ **原因**:sink 闭包对 self 强引用,publisher 又被 self 持有
529
+ **必须做**:所有 .sink { } 闭包第一行加 [weak self]
530
+
531
+ ### 3. 首次申请麦克风权限的弹窗在异步线程触发会被忽略
532
+ **现象**:点击连麦按钮后,系统不弹权限对话框,SDK 直接返回权限拒绝
533
+ **原因**:iOS 权限弹窗必须在主线程触发,异步线程调用静默失败
534
+ **必须做**:`DispatchQueue.main.async { applyForSeat() }`
535
+
536
+ 为什么这些是正例:
537
+ - 每条都是 iOS 独有(Android/Web 无 Combine、无 [weak self]、权限机制不同)
538
+ - 三段式结构(现象/原因/必须做)清晰,新人能快速 get
539
+ - "必须做" 是具体动作,不是"注意一下"
97
540
 
98
- <!-- 指引: 本 section 是平台 slice 区别于产品级概览的核心价值所在。
99
- 只写该平台独有的坑,产品级概览的通用最佳实践不要重复。
541
+ 4️⃣ 反例
542
+ ### 1. 注意内存管理
543
+ 内存管理很重要,要避免泄漏。
544
+ → "注意""很重要" = 软词;"内存管理"跨平台都有 → 不是平台特有
100
545
 
101
- 每条注意事项的格式:
102
- ### {编号}. {一句话标题}
103
- 先说现象/问题(开发者会遇到什么)
104
- — 再说原因(为什么会这样)
546
+ ### 2. iOS 上需要权限
547
+ iOS 应用要在 Info.plist 声明权限。
548
+ 这是基础常识,不写也不会踩;且 base-setup 已覆盖
105
549
 
106
- 什么内容该写在这里:
107
- - 该平台的类型陷阱(如 iOS 的 Int32 vs Int、Android 的 Int vs Long)
108
- - 该平台的生命周期问题(如 Android Activity 重建、iOS 后台挂起)
109
- - 该平台的内存/线程问题(如 iOS [weak self]、Android 主线程更新 UI)
110
- - 该平台的权限行为差异(如 iOS 崩溃 vs Android 返回错误码)
111
- - 该平台特有的错误码或异常行为
550
+ ### 3. 异步代码要小心
551
+ 处理异步代码时要注意时序问题。
552
+ 全是模糊形容词,无具体动作
112
553
 
113
- 什么内容不该写:
114
- 跨平台通用的业务逻辑(如「先登录再操作」→ 产品级概览已覆盖)
115
- API 用法说明(→ 代码示例已覆盖)
116
- 通用排障流程(→ 产品级概览已覆盖)
554
+ 5️⃣ 必填项语义三件套
555
+ - 违反后果:平台特有坑没写 → AI 生成代码在该平台报错 / 行为异常 / 内存泄漏
556
+ - 验证手段:每条必须含"必须做:{具体动作}";描述的现象其他平台不会出现;不出现"注意""小心""很重要"等软词
557
+ - 绕过条件:无(每个平台 slice 都至少要有 1 条)
558
+ <!-- 指引: 平台特有注意事项 [必填,至少 1 条]
117
559
 
118
- 质量标准:每条都应该是「不写出来,研发大概率会踩坑」的内容。
119
- 如果一条注意事项对于有经验的该平台开发者来说是常识,就不用写。
560
+ 1️⃣ 你必须写什么
561
+ 仅在该平台才会踩的坑。每条标准:**该平台独有 + 不写出来研发会踩**。
562
+ 跨平台通用的注意事项 → 上移到产品级概览的 ALWAYS/NEVER。
563
+
564
+ 2️⃣ 写作模板
565
+ ### {编号}. {一句话标题}
566
+ **现象**:{开发者会遇到什么具体表现}
567
+ **原因**:{为什么会这样,SDK / 平台机制层面}
568
+ **必须做**:{具体动作,可机械执行}
569
+
570
+ 3️⃣ ✅ 正例(iOS)
571
+ ### 1. AnyCancellable 必须存为实例属性
572
+ **现象**:.sink 闭包永远不触发,日志没有任何输出
573
+ **原因**:局部变量 cancellable 出作用域后被释放,Combine 自动解除订阅
574
+ **必须做**:声明 `private var cancellables = Set<AnyCancellable>()` 实例属性,
575
+ 所有 sink 后接 `.store(in: &cancellables)`
576
+
577
+ ### 2. sink 闭包必须显式 [weak self]
578
+ **现象**:VC dismiss 后 ViewModel 不释放,Memory Graph 显示循环引用
579
+ **原因**:sink 闭包对 self 强引用,publisher 又被 self 持有
580
+ **必须做**:所有 .sink { } 闭包第一行加 [weak self]
581
+
582
+ ### 3. 首次申请麦克风权限的弹窗在异步线程触发会被忽略
583
+ **现象**:点击连麦按钮后,系统不弹权限对话框,SDK 直接返回权限拒绝
584
+ **原因**:iOS 权限弹窗必须在主线程触发,异步线程调用静默失败
585
+ **必须做**:`DispatchQueue.main.async { applyForSeat() }`
586
+
587
+ 为什么这些是正例:
588
+ - 每条都是 iOS 独有(Android/Web 无 Combine、无 [weak self]、权限机制不同)
589
+ - 三段式结构(现象/原因/必须做)清晰,新人能快速 get
590
+ - "必须做" 是具体动作,不是"注意一下"
591
+
592
+ 4️⃣ ❌ 反例
593
+ ### 1. 注意内存管理
594
+ 内存管理很重要,要避免泄漏。
595
+ → "注意""很重要" = 软词;"内存管理"跨平台都有 → 不是平台特有
596
+
597
+ ### 2. iOS 上需要权限
598
+ iOS 应用要在 Info.plist 声明权限。
599
+ → 这是基础常识,不写也不会踩;且 base-setup 已覆盖
600
+
601
+ ### 3. 异步代码要小心
602
+ 处理异步代码时要注意时序问题。
603
+ → 全是模糊形容词,无具体动作
604
+
605
+ 5️⃣ 必填项语义三件套
606
+ - 违反后果:平台特有坑没写 → AI 生成代码在该平台报错 / 行为异常 / 内存泄漏
607
+ - 验证手段:每条必须含"必须做:{具体动作}";描述的现象其他平台不会出现;不出现"注意""小心""很重要"等软词
608
+ - 绕过条件:无(每个平台 slice 都至少要有 1 条)
120
609
  -->
121
610
 
122
611
  ## 代码生成约束 [必填]
123
612
 
124
- <!-- 指引: section 供 AI 在生成/验证代码时使用,是给机器读的硬性规则。
125
- 与「平台特有注意事项」互补:
126
- 注意事项 = 给人读的经验提醒
127
- 代码生成约束 = 给 AI 读的可检查规则
128
-
129
- 所有规则必须基于实际 SDK 行为,不允许凭经验推测。
130
- ⚠️ 核心要求:每条 MUST / MUST NOT 使用 **prose + backtick** 格式:
131
- N. **<动作> `符号`** <违反后果>。
132
- **Verify**: 检查是否存在 `符号`。
133
- backtick 里的符号 = apply 唯一会 grep 的东西;规则文字其他词 apply 不验。
134
- 完整原则与红旗词表见 slice-spec.md 第四节「MUST 规则的维度对齐原则」。
613
+ <!-- 指引: 代码生成约束 [必填]
614
+
615
+ section 是给 AI 读的硬性规则,与「平台特有注意事项」互补:
616
+ - 注意事项 = 给人读的经验提醒(描述性)
617
+ - 代码生成约束 = 给 AI 读的可机械验证规则(结构化)
618
+
619
+ ⚠️ 核心原则
620
+ **MUST 的语义 = 它的 backtick 符号能验的语义。**
621
+ 规则文字承诺得比 backtick 多 → 维度溢出 → AI 写对了 grep 不到,写错了也 grep 不到 → verifier 反向变成攻击面。
622
+
623
+ 完整原则与红旗词表见 slice-spec.mdMUST 规则的维度对齐原则」,但你**不需要先读它**——按下方批注的模板和正反例即可。
624
+ <!-- 指引: 代码生成约束 [必填]
625
+
626
+ 本 section 是给 AI 读的硬性规则,与「平台特有注意事项」互补:
627
+ - 注意事项 = 给人读的经验提醒(描述性)
628
+ - 代码生成约束 = 给 AI 读的可机械验证规则(结构化)
629
+
630
+ ⚠️ 核心原则
631
+ **MUST 的语义 = 它的 backtick 符号能验的语义。**
632
+ 规则文字承诺得比 backtick 多 → 维度溢出 → AI 写对了 grep 不到,写错了也 grep 不到 → verifier 反向变成攻击面。
633
+
634
+ 完整原则与红旗词表见 slice-spec.md「MUST 规则的维度对齐原则」,但你**不需要先读它**——按下方批注的模板和正反例即可。
135
635
  -->
136
636
 
137
637
  ### 编译必要条件 [必填]
138
638
 
139
- <!-- 指引: slice 代码能编译通过的最小条件。
140
- 只写增量条件(通用条件见 login-auth slice)。
141
- 必须导入的模块/包(精确到包名)
142
- 本 slice 额外需要的 SDK 版本要求(如果高于基础要求)
143
- — 本 slice 额外需要的权限声明或配置
639
+ <!-- 指引: 编译必要条件 [必填]
640
+
641
+ 1️⃣ 你必须写什么
642
+ 本 slice 代码能编译通过的最小条件。**只写增量条件**(通用条件见 login-auth)。
643
+
644
+ 2️⃣ 写作模板
645
+ - **必须导入** `{包名 1}` / `{包名 2}` —— SDK 类型不可用则编译失败。
646
+ - **最低 SDK 版本**:`{version}`(若高于 base-setup 中的版本)
647
+ - **必须的权限声明**:
648
+ - {平台}: {key/permission} —— {用途}
649
+
650
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
651
+ - **必须导入** `import TencentImSDKPlugin` 与 `import Combine`
652
+ - **最低 iOS 版本**:`13.0`(Combine 最低要求)
653
+ - **必须的权限声明**:
654
+ - Info.plist `NSMicrophoneUsageDescription` —— 连麦需要麦克风
655
+ - Info.plist `NSCameraUsageDescription` —— 连麦需要摄像头
656
+
657
+ 4️⃣ ❌ 反例
658
+ - 需要导入相关的包。
659
+ - 最低版本参见官方文档。
660
+ - 注意申请权限。
661
+ → 模糊、不可机械验证、"参见官方文档" = 等于没写
144
662
 
145
- 如果没有增量条件,写「同 login-auth,无额外要求」
663
+ 5️⃣ 必填项语义三件套
664
+ - 违反后果:编译条件不明 → AI 生成代码编译失败 → 客户接入第一步就卡住
665
+ - 验证手段:每条都有 backtick 包裹的具体包名/版本号/权限 key
666
+ - 绕过条件:同 login-auth,无额外要求 → 写"同 login-auth,无额外要求"
667
+ <!-- 指引: 编译必要条件 [必填]
668
+
669
+ 1️⃣ 你必须写什么
670
+ 本 slice 代码能编译通过的最小条件。**只写增量条件**(通用条件见 login-auth)。
671
+
672
+ 2️⃣ 写作模板
673
+ - **必须导入** `{包名 1}` / `{包名 2}` —— SDK 类型不可用则编译失败。
674
+ - **最低 SDK 版本**:`{version}`(若高于 base-setup 中的版本)
675
+ - **必须的权限声明**:
676
+ - {平台}: {key/permission} —— {用途}
677
+
678
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
679
+ - **必须导入** `import TencentImSDKPlugin` 与 `import Combine`
680
+ - **最低 iOS 版本**:`13.0`(Combine 最低要求)
681
+ - **必须的权限声明**:
682
+ - Info.plist `NSMicrophoneUsageDescription` —— 连麦需要麦克风
683
+ - Info.plist `NSCameraUsageDescription` —— 连麦需要摄像头
684
+
685
+ 4️⃣ ❌ 反例
686
+ - 需要导入相关的包。
687
+ - 最低版本参见官方文档。
688
+ - 注意申请权限。
689
+ → 模糊、不可机械验证、"参见官方文档" = 等于没写
690
+
691
+ 5️⃣ 必填项语义三件套
692
+ - 违反后果:编译条件不明 → AI 生成代码编译失败 → 客户接入第一步就卡住
693
+ - 验证手段:每条都有 backtick 包裹的具体包名/版本号/权限 key
694
+ - 绕过条件:同 login-auth,无额外要求 → 写"同 login-auth,无额外要求"
146
695
  -->
147
696
 
148
697
  ### 生成规则 [必填]
149
698
 
150
- #### MUST(生成时必须包含)
699
+ #### MUST(生成时必须包含)
700
+
701
+ <!-- 指引: MUST [必填,至少 3 条]
702
+
703
+ 1️⃣ 你必须写什么
704
+ AI 生成代码时**机械验证**的硬约束,**只写 apply 能用 grep 验的规则**。
705
+
706
+ 2️⃣ 写作模板
707
+ 1. **必须 {强动词} `{可 grep 的符号}`** —— {不这样做的具体后果}。
708
+ **Verify**: 检查 `{符号}` 出现 ≥1 次。
709
+
710
+ 2. **必须 {强动词} `{符号 A}` 与 `{符号 B}`** —— {后果}。
711
+ **Verify**: 检查 `{符号 A}` 与 `{符号 B}` 各出现 ≥1 次。
712
+
713
+ 3. **必须在 {场景} 时调用 `{符号}`** —— {后果}。
714
+ **Verify**: 检查 `{符号}` 出现 ≥1 次。
715
+
716
+ ⚠️ 「在 X 时调用 Y」中的 X 语义 apply **不验**,只验 Y 出现。
717
+ 这是有意的——调用时机属于软规则,放到「调用时序」section 引导 AI。
718
+
719
+ 3️⃣ ✅ 正例(摘自 chat/ios/multi-instance)
720
+ 1. **必须导入 `import TencentImSDKPlugin`** —— 否则 SDK 类型不可用,编译报错。
721
+ **Verify**: 检查 `import TencentImSDKPlugin` 出现 ≥1 次。
722
+
723
+ 2. **必须注册互踢监听 `addSimpleMsgListener`** —— 不注册则用户被踢后无感知。
724
+ **Verify**: 检查 `addSimpleMsgListener` 出现 ≥1 次。
725
+
726
+ 3. **必须在 `onKickedOffline` 回调里展示 UI 反馈 `errorMessage`** ——
727
+ 仅 print 不算,用户看不到。
728
+ **Verify**: 检查 `onKickedOffline` 与 `errorMessage` 各出现 ≥1 次。
729
+
730
+ 为什么是正例:
731
+ - 每条用强动词("必须导入""必须注册"),不用"应该""建议"
732
+ - backtick 内是**精确的可 grep 字符串**(类名/方法名)
733
+ - 规则文字承诺的范围 ≤ Verify 能验的范围(无维度溢出)
734
+ - 每条都有"违反后果"
735
+
736
+ 4️⃣ ❌ 反例(及红旗词诊断)
737
+ 1. **应该正确处理互踢回调** —— 否则用户体验不好。
738
+ **Verify**: 检查互踢逻辑是否完整。
739
+ ↑ 软词"应该" + 模糊动词"处理" + Verify 不可机械化
740
+
741
+ 2. **必须调用 `login()` 或 `loginWithSig()`** —— 没登录无法用 SDK。
742
+ **Verify**: 检查 `login` 出现。
743
+ ↑ "或" = 红旗词;只 grep 一个 ≠ 验了选择
744
+
745
+ 3. **必须按业务场景选择互踢策略** —— 业务决定。
746
+ **Verify**: 检查策略配置是否合理。
747
+ ↑ "按业务""合理" = 不可机械验证,应下沉到「最佳实践」软规则
151
748
 
152
- <!-- 指引: 每条格式:
749
+ 🚩 红旗词表(出现任一即重写)
750
+ - 「或 / 任一」 → 拆两条 MUST 各管一个分支
751
+ - 「等价 / 或类似」 → 显式枚举所有可接受写法
752
+ - 「按业务 / 根据场景」 → 完全移出 MUST,移到「代码示例」按场景给完整 demo
753
+ - 「留给 / 负责」 → 移到「集成检查点」,作为 AI 读但 apply 不验的引导
754
+ - 「多 backtick 但 Verify 只提一个」 → 拆原子规则;调用顺序写到「调用时序」
153
755
 
154
- N. **<动作> `符号`** — <违反后果>。
155
- **Verify**: 检查是否存在 `符号`。
756
+ ✍️ 自查三问(写完每条 MUST 之前问自己)
757
+ 1. backtick 里的符号是不是 verify 唯一会做的事?规则文字其他词能不能删?
758
+ 2. 如果 AI 写**等价但不同写法**的代码,verify 会不会误杀?误杀 = 规则太死。
759
+ 3. 如果 AI 写**只满足 backtick 字符串但语义错**的代码,verify 会不会放过?放过 = 规则太松。
156
760
 
157
- 重要原则(详细规则见 slice-spec.md 第四节「MUST 规则的维度对齐原则」):
158
- backtick 里的符号 = apply 唯一会 grep 的东西
159
- 规则文字描述的判断 / 选择 / 等价 / 条件分支,apply 全部不验
160
- backtick 的规则可以接受,apply 解析为「全部都要出现」(all-of)
761
+ 5️⃣ 必填项语义三件套
762
+ - 违反后果:MUST 含红旗词 apply 误杀正确代码 + 训练 AI 凑字符串 → slice 不可合并(2024-12 真实事故:room-lifecycle 写"调 A 或 B",apply 验过却生成错误混合代码)
763
+ - 验证手段:python scripts/check_must_rules.py {file}
764
+ 通过标准:红旗词命中 0 次;每条 MUST 都有 Verify;Verify 内有 backtick
765
+ - 绕过条件:**无**。MUST 是硬约束区,不接受任何豁免。需要"或/按业务"语义 → 拆原子规则,或下沉到「最佳实践」软规则区
766
+ #### MUST(生成时必须包含)
161
767
 
162
- ⚠️ 红旗词:以下写法说明 MUST 写错了,要么拆分要么下沉到软规则区
163
- — 「或 / 任一」、「等价 / 或类似」、「按业务 / 根据场景」
164
- — 「留给 / 负责」、「多 backtick 但 Verify 只提一个」
768
+ <!-- 指引: MUST [必填,至少 3 条]
165
769
 
166
- 示例(复制修改):
167
- 1. **必须导入 `useRoomState`** 否则状态与 UI 无法收口。
168
- **Verify**: 检查是否存在 `useRoomState`。
770
+ 1️⃣ 你必须写什么
771
+ AI 生成代码时**机械验证**的硬约束,**只写 apply 能用 grep 验的规则**。
169
772
 
170
- 2. **必须从 `tuikit-atomicx-vue3/room` 导入** — 错包的同名 hook 不会跑通。
171
- **Verify**: 检查是否存在 `tuikit-atomicx-vue3/room` `useRoomState`
172
- 同时出现在同一 import 语句。
773
+ 2️⃣ 写作模板
774
+ 1. **必须 {强动词} `{可 grep 的符号}`** —— {不这样做的具体后果}。
775
+ **Verify**: 检查 `{符号}` 出现 ≥1 次。
173
776
 
174
- 只写本 slice 独有的规则。跨 slice 通用规则如果在多个 slice 中反复出现,
175
- 考虑提到产品级概览或 base-setup 中。
777
+ 2. **必须 {强动词} `{符号 A}` `{符号 B}`** —— {后果}。
778
+ **Verify**: 检查 `{符号 A}` 与 `{符号 B}` 各出现 ≥1 次。
779
+
780
+ 3. **必须在 {场景} 时调用 `{符号}`** —— {后果}。
781
+ **Verify**: 检查 `{符号}` 出现 ≥1 次。
782
+
783
+ ⚠️ 「在 X 时调用 Y」中的 X 语义 apply **不验**,只验 Y 出现。
784
+ 这是有意的——调用时机属于软规则,放到「调用时序」section 引导 AI。
785
+
786
+ 3️⃣ ✅ 正例(摘自 chat/ios/multi-instance)
787
+ 1. **必须导入 `import TencentImSDKPlugin`** —— 否则 SDK 类型不可用,编译报错。
788
+ **Verify**: 检查 `import TencentImSDKPlugin` 出现 ≥1 次。
789
+
790
+ 2. **必须注册互踢监听 `addSimpleMsgListener`** —— 不注册则用户被踢后无感知。
791
+ **Verify**: 检查 `addSimpleMsgListener` 出现 ≥1 次。
792
+
793
+ 3. **必须在 `onKickedOffline` 回调里展示 UI 反馈 `errorMessage`** ——
794
+ 仅 print 不算,用户看不到。
795
+ **Verify**: 检查 `onKickedOffline` 与 `errorMessage` 各出现 ≥1 次。
796
+
797
+ 为什么是正例:
798
+ - 每条用强动词("必须导入""必须注册"),不用"应该""建议"
799
+ - backtick 内是**精确的可 grep 字符串**(类名/方法名)
800
+ - 规则文字承诺的范围 ≤ Verify 能验的范围(无维度溢出)
801
+ - 每条都有"违反后果"
802
+
803
+ 4️⃣ ❌ 反例(及红旗词诊断)
804
+ 1. **应该正确处理互踢回调** —— 否则用户体验不好。
805
+ **Verify**: 检查互踢逻辑是否完整。
806
+ ↑ 软词"应该" + 模糊动词"处理" + Verify 不可机械化
807
+
808
+ 2. **必须调用 `login()` 或 `loginWithSig()`** —— 没登录无法用 SDK。
809
+ **Verify**: 检查 `login` 出现。
810
+ ↑ "或" = 红旗词;只 grep 一个 ≠ 验了选择
811
+
812
+ 3. **必须按业务场景选择互踢策略** —— 业务决定。
813
+ **Verify**: 检查策略配置是否合理。
814
+ ↑ "按业务""合理" = 不可机械验证,应下沉到「最佳实践」软规则
815
+
816
+ 🚩 红旗词表(出现任一即重写)
817
+ - 「或 / 任一」 → 拆两条 MUST 各管一个分支
818
+ - 「等价 / 或类似」 → 显式枚举所有可接受写法
819
+ - 「按业务 / 根据场景」 → 完全移出 MUST,移到「代码示例」按场景给完整 demo
820
+ - 「留给 / 负责」 → 移到「集成检查点」,作为 AI 读但 apply 不验的引导
821
+ - 「多 backtick 但 Verify 只提一个」 → 拆原子规则;调用顺序写到「调用时序」
822
+
823
+ ✍️ 自查三问(写完每条 MUST 之前问自己)
824
+ 1. backtick 里的符号是不是 verify 唯一会做的事?规则文字其他词能不能删?
825
+ 2. 如果 AI 写**等价但不同写法**的代码,verify 会不会误杀?误杀 = 规则太死。
826
+ 3. 如果 AI 写**只满足 backtick 字符串但语义错**的代码,verify 会不会放过?放过 = 规则太松。
827
+
828
+ 5️⃣ 必填项语义三件套
829
+ - 违反后果:MUST 含红旗词 → apply 误杀正确代码 + 训练 AI 凑字符串 → slice 不可合并(2024-12 真实事故:room-lifecycle 写"调 A 或 B",apply 验过却生成错误混合代码)
830
+ - 验证手段:python scripts/check_must_rules.py {file}
831
+ 通过标准:红旗词命中 0 次;每条 MUST 都有 Verify;Verify 内有 backtick
832
+ - 绕过条件:**无**。MUST 是硬约束区,不接受任何豁免。需要"或/按业务"语义 → 拆原子规则,或下沉到「最佳实践」软规则区
176
833
  -->
177
834
 
178
- #### MUST NOT(生成时绝不能出现)
835
+ #### MUST NOT(生成时绝不能出现)
836
+
837
+ <!-- 指引: MUST NOT [必填,至少 2 条]
838
+
839
+ 1️⃣ 你必须写什么
840
+ 列出**绝不允许出现**的代码模式。重点写「看起来能跑但逻辑错误」的写法 —— 编译器抓不到,只有了解业务语义才能避免。
841
+
842
+ 2️⃣ 写作模板
843
+ 1. **不要 {动作} `{符号}`** —— {违反后果}。
844
+ **Verify**: 检查 `{符号}` 出现 0 次(或在特定上下文中出现 0 次)。
845
+
846
+ 3️⃣ ✅ 正例
847
+ 1. **不要在 `onKickedOffline` 回调里调用 `login()`** —— 自动重登形成两端死循环互踢,
848
+ 最终两端都登不上。
849
+ **Verify**: 在 `onKickedOffline` 函数体内,`login` 出现 0 次。
850
+
851
+ 2. **不要在客户端代码里硬编码 `SecretKey`** —— 密钥泄露后可签发任意 UserSig。
852
+ **Verify**: 全文 `SecretKey` 出现 0 次。
853
+
854
+ 3. **不要把 `leaveRoom()` 当成解散会议** —— 房主离开后房间仍在,其他成员卡死。
855
+ **Verify**: 房主代码路径中,房主收口必须用 `endRoom`,不能用 `leaveRoom`。
856
+
857
+ 4. **不要用 `try?` 吞掉 `loginWithSig` 的错误** —— 静默失败导致后续 API 全失败但无日志可查。
858
+ **Verify**: `try?\\s+.*loginWithSig` 出现 0 次(grep -E)。
859
+
860
+ 为什么是正例:
861
+ - 每条精确到"哪个上下文里不能出现哪个符号"
862
+ - Verify 是 0 次匹配,机械可验
863
+
864
+ 4️⃣ ❌ 反例
865
+ 1. 不要写不安全的代码。
866
+ 2. 避免循环引用。
867
+ 3. 不要忽略错误。
868
+ → 全部模糊,无 backtick,无 Verify,grep 不到
869
+
870
+ 5️⃣ 必填项语义三件套
871
+ - 违反后果:MUST NOT 缺失或模糊 → AI 生成代码引入安全/性能/稳定性问题
872
+ - 验证手段:同 MUST,跑 python scripts/check_must_rules.py
873
+ - 绕过条件:无
874
+ #### MUST NOT(生成时绝不能出现)
875
+
876
+ <!-- 指引: MUST NOT [必填,至少 2 条]
877
+
878
+ 1️⃣ 你必须写什么
879
+ 列出**绝不允许出现**的代码模式。重点写「看起来能跑但逻辑错误」的写法 —— 编译器抓不到,只有了解业务语义才能避免。
179
880
 
180
- <!-- 指引: 同上格式,每条 = 一个禁现的具体符号或符号组合。
181
- 重点写「看起来能跑但逻辑错误」的写法 这类问题编译器抓不到,只有了解业务语义才能避免。
881
+ 2️⃣ 写作模板
882
+ 1. **不要 {动作} `{符号}`** —— {违反后果}。
883
+ **Verify**: 检查 `{符号}` 出现 0 次(或在特定上下文中出现 0 次)。
182
884
 
183
- 示例:
184
- 1. **不要把 `leaveRoom()` 当成解散会议** — 会导致房主离开后房间仍在。
185
- **Verify**: 检查 `leaveRoom` 不与房主路径并列出现,房主收口必须用 `endRoom`。
885
+ 3️⃣ ✅ 正例
886
+ 1. **不要在 `onKickedOffline` 回调里调用 `login()`** —— 自动重登形成两端死循环互踢,
887
+ 最终两端都登不上。
888
+ **Verify**: 在 `onKickedOffline` 函数体内,`login` 出现 0 次。
186
889
 
187
- 注:MUST NOT Verify 同样依赖 backtick 符号 + apply 的「all-of」grep;
188
- 避免用「不应该 / 不要」+ 抽象描述这种 grep 无法验证的写法。
890
+ 2. **不要在客户端代码里硬编码 `SecretKey`** —— 密钥泄露后可签发任意 UserSig。
891
+ **Verify**: 全文 `SecretKey` 出现 0 次。
892
+
893
+ 3. **不要把 `leaveRoom()` 当成解散会议** —— 房主离开后房间仍在,其他成员卡死。
894
+ **Verify**: 房主代码路径中,房主收口必须用 `endRoom`,不能用 `leaveRoom`。
895
+
896
+ 4. **不要用 `try?` 吞掉 `loginWithSig` 的错误** —— 静默失败导致后续 API 全失败但无日志可查。
897
+ **Verify**: `try?\\s+.*loginWithSig` 出现 0 次(grep -E)。
898
+
899
+ 为什么是正例:
900
+ - 每条精确到"哪个上下文里不能出现哪个符号"
901
+ - Verify 是 0 次匹配,机械可验
902
+
903
+ 4️⃣ ❌ 反例
904
+ 1. 不要写不安全的代码。
905
+ 2. 避免循环引用。
906
+ 3. 不要忽略错误。
907
+ → 全部模糊,无 backtick,无 Verify,grep 不到
908
+
909
+ 5️⃣ 必填项语义三件套
910
+ - 违反后果:MUST NOT 缺失或模糊 → AI 生成代码引入安全/性能/稳定性问题
911
+ - 验证手段:同 MUST,跑 python scripts/check_must_rules.py
912
+ - 绕过条件:无
189
913
  -->
190
914
 
191
915
  ### 集成检查点 [必填]
192
916
 
193
- <!-- 指引: 假设目标是已有项目(不是从零开始的 demo),列出集成时需要确认的事项:
194
- — 是否与项目中已有的 SDK 初始化冲突
195
- 是否需要合并到已有的生命周期方法中(而非新建)
196
- 是否依赖其他 slice 的前置状态(引用具体 slice ID)
197
- 对已有代码的侵入性(新增文件 vs 修改已有文件)
917
+ <!-- 指引: 集成检查点 [必填,至少 3 条]
918
+
919
+ 1️⃣ 你必须写什么
920
+ 假设目标是已有项目(不是从零开始的 demo),列出集成时需要确认的事项。
921
+ section 是软规则区(apply 不验),AI 阅读后自行判断。
922
+
923
+ 2️⃣ 写作模板
924
+ - 是否与项目已有 SDK 初始化冲突?(检查 `{初始化函数}` 是否已在别处调用)
925
+ - 是否依赖其他 slice 的前置状态?(本 slice 依赖 → `{slice-id}`)
926
+ - 对已有代码的侵入性:`{新增 X 个文件 / 修改 Y 个文件}`
927
+ - {本 slice 特有的集成关注点}
928
+
929
+ 3️⃣ ✅ 正例
930
+ - 是否与项目已有 SDK 初始化冲突?检查项目中 `V2TIMManager.sharedInstance().initSDK()`
931
+ 是否已被调用,若是则不要重复调用
932
+ - 是否依赖其他 slice?依赖 `chat/login-auth` 完成登录,依赖 `live/room-lifecycle` 已进房
933
+ - 对已有代码的侵入性:新增 1 个 ViewModel 文件,无需修改现有代码
934
+ - 是否在已有的 RoomEvent 监听基础上叠加?如已注册 `onUserSigExpired` 监听,本 slice 注册的是不同事件,可叠加;若已注册 `onKickedOffline`,需合并而非新增
935
+
936
+ 4️⃣ ❌ 反例
937
+ - 集成时注意一下 SDK 冲突。
938
+ - 看看有没有依赖。
939
+ - 影响应该不大。
940
+ → "注意一下""看看""应该不大" = 软词,无可操作信息
941
+
942
+ 5️⃣ 必填项语义三件套
943
+ - 违反后果:不写检查点 → 集成时与已有代码冲突(双重初始化、状态污染)→ 客户报"按文档接但跑不起来"
944
+ - 验证手段:必须有 ≥3 条;每条引用具体函数/slice/文件数
945
+ - 绕过条件:无
946
+ <!-- 指引: 集成检查点 [必填,至少 3 条]
947
+
948
+ 1️⃣ 你必须写什么
949
+ 假设目标是已有项目(不是从零开始的 demo),列出集成时需要确认的事项。
950
+ 本 section 是软规则区(apply 不验),AI 阅读后自行判断。
951
+
952
+ 2️⃣ 写作模板
953
+ - 是否与项目已有 SDK 初始化冲突?(检查 `{初始化函数}` 是否已在别处调用)
954
+ - 是否依赖其他 slice 的前置状态?(本 slice 依赖 → `{slice-id}`)
955
+ - 对已有代码的侵入性:`{新增 X 个文件 / 修改 Y 个文件}`
956
+ - {本 slice 特有的集成关注点}
957
+
958
+ 3️⃣ ✅ 正例
959
+ - 是否与项目已有 SDK 初始化冲突?检查项目中 `V2TIMManager.sharedInstance().initSDK()`
960
+ 是否已被调用,若是则不要重复调用
961
+ - 是否依赖其他 slice?依赖 `chat/login-auth` 完成登录,依赖 `live/room-lifecycle` 已进房
962
+ - 对已有代码的侵入性:新增 1 个 ViewModel 文件,无需修改现有代码
963
+ - 是否在已有的 RoomEvent 监听基础上叠加?如已注册 `onUserSigExpired` 监听,本 slice 注册的是不同事件,可叠加;若已注册 `onKickedOffline`,需合并而非新增
964
+
965
+ 4️⃣ ❌ 反例
966
+ - 集成时注意一下 SDK 冲突。
967
+ - 看看有没有依赖。
968
+ - 影响应该不大。
969
+ → "注意一下""看看""应该不大" = 软词,无可操作信息
970
+
971
+ 5️⃣ 必填项语义三件套
972
+ - 违反后果:不写检查点 → 集成时与已有代码冲突(双重初始化、状态污染)→ 客户报"按文档接但跑不起来"
973
+ - 验证手段:必须有 ≥3 条;每条引用具体函数/slice/文件数
974
+ - 绕过条件:无
198
975
  -->
199
976
 
200
977
  ## 验证矩阵 [必填]
201
978
 
202
- <!-- 指引: 平台 slice 的统一验收出口。AI 生成代码后或人工 review 时,自上而下跑一遍就能完成验收。
979
+ <!-- 指引: 验证矩阵 [必填]
980
+
981
+ 1️⃣ 你必须写什么
982
+ 平台 slice 末尾的**统一验收出口**。AI 生成代码后或人工 review 时,自上而下跑一遍即可完成验收。
983
+ 这是 SuperPowers「验证门」机制在 slice 层的落地——**禁止在没跑过验证矩阵的情况下声称完成**。
984
+
985
+ 2️⃣ 4 个层级
986
+ - 1. 编译级:能编译、依赖齐全(CI / AI 自动)
987
+ - 2. 静态规则级:纯静态扫描 / grep 可查(CI / AI 自动)
988
+ - 3. 运行时级:跑起来通过日志锚点可观察(AI 半自动 / 人工)
989
+ - 4. 业务行为级:人眼看 UI / 硬件状态(人工)
990
+
991
+ 要求(不可省):
992
+ - 每条「代码生成约束」MUST/MUST NOT 都要在矩阵中有对应行(层级 1 或 2)
993
+ - 至少 1 条层级 3 的检查,证明代码真能跑
994
+ - 至少 1 条层级 4 的检查,证明业务语义正确
995
+
996
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
203
997
 
204
- 4 个层级:
205
- — 1. 编译级:能编译、依赖齐全(CI / AI 自动)
206
- 2. 静态规则级:纯静态扫描 / grep 可查(CI / AI 自动)
207
- 3. 运行时级:跑起来通过日志锚点可观察(AI 半自动 / 人工)
208
- 4. 业务行为级:人眼看 UI / 硬件状态(人工)
998
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
999
+ |------|--------|----------|---------|
1000
+ | 1. 编译级 | 模块导入齐全 | xcodebuild build -scheme Demo | exit code 0 |
1001
+ | 1. 编译级 | iOS 最低版本 ≥ 13.0 | 查 Podfile/project.pbxproj | IPHONEOS_DEPLOYMENT_TARGET = 13.0 |
1002
+ | 2. 静态规则级 | 所有 sink 都 [weak self] | grep -E "sink\\s*\\{\\s*\\[weak self\\]" | 匹配数 == sink 总数 |
1003
+ | 2. 静态规则级 | AnyCancellable 是实例属性 | grep "var cancellables: Set<AnyCancellable>" | 至少 1 处 |
1004
+ | 2. 静态规则级 | 每个 .failure 有 errorMessage | grep -B 5 "case .failure" \| grep errorMessage | 无裸 print |
1005
+ | 3. 运行时级 | 申请发送成功 | 观众点申请 → 查日志 | [CoGuest] 申请已发送 |
1006
+ | 3. 运行时级 | 主播收到事件 | 主播端查日志 | onGuestApplicationReceived |
1007
+ | 3. 运行时级 | 超时 UI 反馈 | 主播不响应,等 30s | UI 展示"申请超时" |
1008
+ | 4. 业务行为级 | 通过前设备未开 | 点申请但未同意 | 摄像头指示灯不亮 |
1009
+ | 4. 业务行为级 | 断开后设备关闭 | 连麦中主动断开 | 摄像头指示灯熄灭 |
1010
+
1011
+ 为什么是正例:
1012
+ - 4 层各有 ≥2 行,覆盖完整
1013
+ - 「检查项」都对应代码生成约束的 MUST/MUST NOT
1014
+ - 「验证手段」都是可执行命令或具体操作
1015
+ - 「预期结果」精确到字符串/状态/数值
209
1016
 
210
- 要求:
211
- — 每条「代码生成约束」的 MUST / MUST NOT 都要在矩阵中有对应行(层级 1 或 2)
212
- 至少 1 条层级 3 的检查,证明代码真能跑
213
- — 至少 1 条层级 4 的检查,证明业务语义正确(通常是 ALWAYS / NEVER 的运行时体现)
1017
+ 4️⃣ ❌ 反例
1018
+
1019
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
1020
+ |------|--------|----------|---------|
1021
+ | 1 | 能编译 | 编译看看 | 没报错 |
1022
+ | 2 | 代码规范 | 看一下代码 | 没问题 |
1023
+
1024
+ → "看看""没问题" = 不可机械验证;层级 3、4 缺失;无对应 MUST
1025
+
1026
+ 5️⃣ 必填项语义三件套
1027
+ - 违反后果:验证矩阵不全 → AI/人工无法系统性自验 → "应该没问题"上线 → 线上事故
1028
+ - 验证手段:python scripts/check_verify_matrix.py {file}
1029
+ 通过标准:4 层各 ≥1 行;每条 MUST/MUST NOT 都能在层级 1 或 2 找到对应行;至少 1 条层级 3、1 条层级 4
1030
+ - 绕过条件:无
1031
+ <!-- 指引: 验证矩阵 [必填]
1032
+
1033
+ 1️⃣ 你必须写什么
1034
+ 平台 slice 末尾的**统一验收出口**。AI 生成代码后或人工 review 时,自上而下跑一遍即可完成验收。
1035
+ 这是 SuperPowers「验证门」机制在 slice 层的落地——**禁止在没跑过验证矩阵的情况下声称完成**。
1036
+
1037
+ 2️⃣ 4 个层级
1038
+ - 1. 编译级:能编译、依赖齐全(CI / AI 自动)
1039
+ - 2. 静态规则级:纯静态扫描 / grep 可查(CI / AI 自动)
1040
+ - 3. 运行时级:跑起来通过日志锚点可观察(AI 半自动 / 人工)
1041
+ - 4. 业务行为级:人眼看 UI / 硬件状态(人工)
1042
+
1043
+ 要求(不可省):
1044
+ - 每条「代码生成约束」MUST/MUST NOT 都要在矩阵中有对应行(层级 1 或 2)
1045
+ - 至少 1 条层级 3 的检查,证明代码真能跑
1046
+ - 至少 1 条层级 4 的检查,证明业务语义正确
1047
+
1048
+ 3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
1049
+
1050
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
1051
+ |------|--------|----------|---------|
1052
+ | 1. 编译级 | 模块导入齐全 | xcodebuild build -scheme Demo | exit code 0 |
1053
+ | 1. 编译级 | iOS 最低版本 ≥ 13.0 | 查 Podfile/project.pbxproj | IPHONEOS_DEPLOYMENT_TARGET = 13.0 |
1054
+ | 2. 静态规则级 | 所有 sink 都 [weak self] | grep -E "sink\\s*\\{\\s*\\[weak self\\]" | 匹配数 == sink 总数 |
1055
+ | 2. 静态规则级 | AnyCancellable 是实例属性 | grep "var cancellables: Set<AnyCancellable>" | 至少 1 处 |
1056
+ | 2. 静态规则级 | 每个 .failure 有 errorMessage | grep -B 5 "case .failure" \| grep errorMessage | 无裸 print |
1057
+ | 3. 运行时级 | 申请发送成功 | 观众点申请 → 查日志 | [CoGuest] 申请已发送 |
1058
+ | 3. 运行时级 | 主播收到事件 | 主播端查日志 | onGuestApplicationReceived |
1059
+ | 3. 运行时级 | 超时 UI 反馈 | 主播不响应,等 30s | UI 展示"申请超时" |
1060
+ | 4. 业务行为级 | 通过前设备未开 | 点申请但未同意 | 摄像头指示灯不亮 |
1061
+ | 4. 业务行为级 | 断开后设备关闭 | 连麦中主动断开 | 摄像头指示灯熄灭 |
1062
+
1063
+ 为什么是正例:
1064
+ - 4 层各有 ≥2 行,覆盖完整
1065
+ - 「检查项」都对应代码生成约束的 MUST/MUST NOT
1066
+ - 「验证手段」都是可执行命令或具体操作
1067
+ - 「预期结果」精确到字符串/状态/数值
1068
+
1069
+ 4️⃣ ❌ 反例
1070
+
1071
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
1072
+ |------|--------|----------|---------|
1073
+ | 1 | 能编译 | 编译看看 | 没报错 |
1074
+ | 2 | 代码规范 | 看一下代码 | 没问题 |
1075
+
1076
+ → "看看""没问题" = 不可机械验证;层级 3、4 缺失;无对应 MUST
1077
+
1078
+ 5️⃣ 必填项语义三件套
1079
+ - 违反后果:验证矩阵不全 → AI/人工无法系统性自验 → "应该没问题"上线 → 线上事故
1080
+ - 验证手段:python scripts/check_verify_matrix.py {file}
1081
+ 通过标准:4 层各 ≥1 行;每条 MUST/MUST NOT 都能在层级 1 或 2 找到对应行;至少 1 条层级 3、1 条层级 4
1082
+ - 绕过条件:无
214
1083
  -->
215
1084
 
216
1085
  | 层级 | 检查项 | 验证手段 | 预期结果 |
@@ -224,10 +1093,49 @@ api_docs: # [必填] 该平台对应的 API 参考文档链
224
1093
 
225
1094
  ---
226
1095
 
227
- ## DoD 自查(提交前删除此 section
1096
+ ## DoD 自查(提交前删除此 section)
1097
+
1098
+ <!-- 指引: 提交前对照 slice-spec.md 第五节「平台实现文件 DoD」逐条打勾。
1099
+ **任何一项未满足 = 未完成,不允许提 PR**。
1100
+
1101
+ ⚠️ 仅打勾不跑命令 = 视为未验证。每条标了"验证命令"的项,必须在 PR 描述粘贴命令输出。
1102
+
1103
+ 最关键的 5 个一票否决项:
1104
+ - [ ] api_docs 链接精确到类/模块级
1105
+ 验证:python scripts/validate_api_docs.py {file}
1106
+ - [ ] 代码示例无 ... 省略,每个 .failure 有 errorMessage
1107
+ 验证:grep -E "\\.\\.\\." {file} 命中 0 次
1108
+ - [ ] 代码生成约束 MUST 不含红旗词
1109
+ 验证:python scripts/check_must_rules.py {file}
1110
+ - [ ] 验证矩阵 4 层齐全,覆盖所有 MUST/MUST NOT
1111
+ 验证:python scripts/check_verify_matrix.py {file}
1112
+ - [ ] 平台特有注意事项 ≥ 1 条,每条含"必须做:"
1113
+ -->
1114
+ ## DoD 自查(提交前删除此 section)
1115
+
1116
+ <!-- 指引: 提交前对照 slice-spec.md 第五节「平台实现文件 DoD」逐条打勾。
1117
+ **任何一项未满足 = 未完成,不允许提 PR**。
1118
+
1119
+ ⚠️ 仅打勾不跑命令 = 视为未验证。每条标了"验证命令"的项,必须在 PR 描述粘贴命令输出。
1120
+
1121
+ 最关键的 5 个一票否决项:
1122
+ - [ ] api_docs 链接精确到类/模块级
1123
+ 验证:python scripts/validate_api_docs.py {file}
1124
+ - [ ] 代码示例无 ... 省略,每个 .failure 有 errorMessage
1125
+ 验证:grep -E "\\.\\.\\." {file} 命中 0 次
1126
+ - [ ] 代码生成约束 MUST 不含红旗词
1127
+ 验证:python scripts/check_must_rules.py {file}
1128
+ - [ ] 验证矩阵 4 层齐全,覆盖所有 MUST/MUST NOT
1129
+ 验证:python scripts/check_verify_matrix.py {file}
1130
+ - [ ] 平台特有注意事项 ≥ 1 条,每条含"必须做:"
1131
+ -->
228
1132
 
229
- 提交前对照 `slice-spec.md` 第五节「平台实现文件 DoD」逐条打勾。任何一项不满足 = 未完成。
1133
+ 提交前对照 `slice-spec.md` 第五节「平台实现文件 DoD」逐条打勾。任何一项未满足 = 未完成。
1134
+ 提交前对照 `slice-spec.md` 第五节「平台实现文件 DoD」逐条打勾。任何一项未满足 = 未完成。
230
1135
 
231
1136
  ---
232
1137
 
233
- > **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 这是目前最完整的平台 slice 实现,包含所有 section 的真实内容。
1138
+ > **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 这是目前最完整的平台 slice 实现,包含所有 section 的真实内容。
1139
+ > **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
1140
+ > **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 这是目前最完整的平台 slice 实现,包含所有 section 的真实内容。
1141
+ > **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。