@ohos-cpf/3rdloop 0.0.8 → 0.0.9

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 (219) hide show
  1. package/README.md +25 -0
  2. package/lib/cli.js +22 -5
  3. package/lib/doctor.js +111 -10
  4. package/lib/mcp.js +498 -0
  5. package/package.json +6 -2
  6. package/vendor/Archive/data/.index/meta.json +7 -0
  7. package/vendor/Archive/data/.index/search.db +0 -0
  8. package/vendor/Archive/data/docs/experiences/arkts-check-tool-pitfalls-baseline-comparison.md +13 -0
  9. package/vendor/Archive/data/docs/experiences/arkts-deep-path-import-recognition.md +31 -0
  10. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-entry-file-case-mismatch.md +25 -0
  11. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-import-trailing-slash.md +20 -0
  12. package/vendor/Archive/data/docs/experiences/arkts-library-source-files-may-be-ts.md +18 -0
  13. package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md +36 -0
  14. package/vendor/Archive/data/docs/experiences/arkts-xts-compile-error-clustering-fix.md +24 -0
  15. package/vendor/Archive/data/docs/experiences/arkts-xts-doc-expected-value-runtime-probe.md +35 -0
  16. package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md +33 -0
  17. package/vendor/Archive/data/docs/experiences/code-linter-chinese-comment-false-positive.md +16 -0
  18. package/vendor/Archive/data/docs/experiences/esobject-new-expression-variable-tracking.md +33 -0
  19. package/vendor/Archive/data/docs/experiences/filesystem-case-sensitivity-module-resolution.md +31 -0
  20. package/vendor/Archive/data/docs/experiences/gitcode-clone-redirect-warning-normal.md +13 -0
  21. package/vendor/Archive/data/docs/experiences/kn_msgvq1w585ec8319.md +77 -0
  22. package/vendor/Archive/data/docs/experiences/kn_msovnm6rd46de72c.md +98 -0
  23. package/vendor/Archive/data/docs/experiences/kn_mspt8vntfe708576.md +87 -0
  24. package/vendor/Archive/data/docs/experiences/kn_mspu1ei77adbbb48.md +133 -0
  25. package/vendor/Archive/data/docs/experiences/kn_mspubgak8d30bfce.md +128 -0
  26. package/vendor/Archive/data/docs/experiences/kn_mspug2de3cb1f7c3.md +115 -0
  27. package/vendor/Archive/data/docs/experiences/kn_skill_opt_001.md +38 -0
  28. package/vendor/Archive/data/docs/experiences/loop-artifacts-verification-evidence-triangle.md +19 -0
  29. package/vendor/Archive/data/docs/experiences/macos-bash-replace-build-ps1.md +19 -0
  30. package/vendor/Archive/data/docs/experiences/macos-bsd-diff-q-illegal-option.md +15 -0
  31. package/vendor/Archive/data/docs/experiences/migrate-cjs-compatible-api-version-map-limit.md +17 -0
  32. package/vendor/Archive/data/docs/experiences/mp3agic-arkts-library-behavior-quirks.md +21 -0
  33. package/vendor/Archive/data/docs/experiences/ohos-face-detection-scan-api-mapping.md +15 -0
  34. package/vendor/Archive/data/docs/experiences/pr-metadata-and-diff-integrity-verification.md +12 -0
  35. package/vendor/Archive/data/docs/experiences/rn-coverage-index-signature-pseudo-member-false-negative.md +32 -0
  36. package/vendor/Archive/data/docs/experiences/rn-memory-check-severity-calibration.md +21 -0
  37. package/vendor/Archive/data/docs/experiences/rn-platform-specific-api-exclusion-evidence.md +24 -0
  38. package/vendor/Archive/data/docs/experiences/rn-upstream-version-diff-pitfalls.md +17 -0
  39. package/vendor/Archive/data/docs/experiences/rn-version-gap-risk-rating-rules.md +13 -0
  40. package/vendor/Archive/data/docs/experiences/rn-view-lib-native-contract-diff-fabric-spec.md +16 -0
  41. package/vendor/Archive/data/docs/experiences/rnoh-adapter-package-version-field-semantics.md +18 -0
  42. package/vendor/Archive/data/docs/experiences/rnoh-arkts-sqlite-rows-array-format.md +18 -0
  43. package/vendor/Archive/data/docs/experiences/rnoh-dependency-residue-scan-strategy.md +18 -0
  44. package/vendor/Archive/data/docs/experiences/rnoh-example-local-lib-dep-use-tgz.md +53 -0
  45. package/vendor/Archive/data/docs/experiences/rnoh-example-prereserve-rntesterlist.md +17 -0
  46. package/vendor/Archive/data/docs/experiences/rnoh-example-template-compatiblesdkversion-upgrade.md +29 -0
  47. package/vendor/Archive/data/docs/experiences/rnoh-example-turbomodule-shell-adaptation-checklist.md +41 -0
  48. package/vendor/Archive/data/docs/experiences/rnoh-mcp-build-project-tool-risk.md +18 -0
  49. package/vendor/Archive/data/docs/experiences/rnoh-npm-devdependencies-version-precheck.md +29 -0
  50. package/vendor/Archive/data/docs/experiences/rnoh-repo-baseline-version-verification.md +13 -0
  51. package/vendor/Archive/data/docs/experiences/rnoh-repo-upstream-directory-mapping.md +18 -0
  52. package/vendor/Archive/data/docs/experiences/rnoh-stateless-library-zero-leak-verification.md +31 -0
  53. package/vendor/Archive/data/docs/experiences/rnoh-template-npmrc-credential-removal.md +15 -0
  54. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-codegen-wiring-verification.md +19 -0
  55. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-cpp-methodmap-compatibility-check.md +20 -0
  56. package/vendor/Archive/data/docs/experiences/scenario-doc-vs-source-signature-diff-four-patterns.md +24 -0
  57. package/vendor/Archive/data/docs/experiences/static-analysis-grep-cross-validation.md +29 -0
  58. package/vendor/Archive/demo.js +489 -0
  59. package/vendor/Archive/index.js +43 -0
  60. package/vendor/Archive/package.json +16 -0
  61. package/vendor/Archive/src/constants.js +83 -0
  62. package/vendor/Archive/src/data/stopwords.txt +110 -0
  63. package/vendor/Archive/src/data/synonyms.json +25 -0
  64. package/vendor/Archive/src/data/terms.txt +59 -0
  65. package/vendor/Archive/src/db/sqlite-backend.js +312 -0
  66. package/vendor/Archive/src/db/sqlite-schema.js +64 -0
  67. package/vendor/Archive/src/engine.js +501 -0
  68. package/vendor/Archive/src/index/index-manager.js +203 -0
  69. package/vendor/Archive/src/index/index-state.js +94 -0
  70. package/vendor/Archive/src/index/search-text-builder.js +106 -0
  71. package/vendor/Archive/src/index.js +22 -0
  72. package/vendor/Archive/src/parser/api-identifiers.js +121 -0
  73. package/vendor/Archive/src/parser/api-suffixes.js +48 -0
  74. package/vendor/Archive/src/parser/heading-normalize.js +40 -0
  75. package/vendor/Archive/src/parser/markdown-splitter.js +215 -0
  76. package/vendor/Archive/src/search/catalog-routing.js +87 -0
  77. package/vendor/Archive/src/search/fts-search.js +289 -0
  78. package/vendor/Archive/src/search/query-normalizer.js +159 -0
  79. package/vendor/Archive/src/search/query-rewriter.js +72 -0
  80. package/vendor/Archive/src/search/search-engine.js +72 -0
  81. package/vendor/Archive/src/search/snippet.js +64 -0
  82. package/vendor/Archive/src/store/dir-store.js +103 -0
  83. package/vendor/Archive/src/store/doc-store.js +36 -0
  84. package/vendor/Archive/src/tokenizer/lexicon.js +151 -0
  85. package/vendor/Archive/src/tokenizer/tokenizer.js +167 -0
  86. package/vendor/Archive/src/types.js +86 -0
  87. package/vendor/Archive/src/utils/hash.js +16 -0
  88. package/vendor/Archive/src/utils/lock.js +73 -0
  89. package/vendor/Archive/src/utils/path-safety.js +96 -0
  90. package/vendor/Archive/src/utils/paths.js +39 -0
  91. package/vendor/BadCase/rn/INDEX.md +127 -0
  92. package/vendor/BadCase/rn/cases/KI-001-webview/350/247/206/351/242/221/346/227/240/346/263/225/346/250/252/345/261/217.md +52 -0
  93. package/vendor/BadCase/rn/cases/KI-002-fastImage/347/203/255/346/233/264/346/226/260/345/233/276/347/211/207/345/244/261/350/264/245.md +37 -0
  94. package/vendor/BadCase/rn/cases/KI-003-wechat/347/274/251/347/225/245/345/233/276/346/234/254/345/234/260/345/233/276/347/211/207.md +62 -0
  95. package/vendor/BadCase/rn/cases/KI-004-wechat/345/233/236/350/260/203/346/227/266/345/272/217.md +47 -0
  96. package/vendor/BadCase/rn/cases/KI-005-geolocation/345/257/274/345/205/245/350/267/257/345/276/204/345/220/216/347/274/200.md +31 -0
  97. package/vendor/BadCase/rn/cases/KI-006-SmartRefreshLayout/346/231/272/350/203/275/346/214/207/351/222/210/345/264/251/346/272/203.md +55 -0
  98. package/vendor/BadCase/rn/cases/KI-007-orientation-locker/344/274/240/346/204/237/345/231/250/345/210/235/345/247/213/345/214/226.md +58 -0
  99. package/vendor/BadCase/rn/cases/KI-008-orientation-locker/344/274/240/346/204/237/345/231/250/345/274/225/347/224/250/350/256/241/346/225/260.md +47 -0
  100. package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md +38 -0
  101. package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md +48 -0
  102. package/vendor/BadCase/rn/cases/KI-011-spring-scrollview/346/211/213/345/212/277/351/207/215/345/244/215/347/273/221/345/256/232.md +49 -0
  103. package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md +59 -0
  104. package/vendor/BadCase/rn/cases/KI-013-webview/346/267/261/350/211/262/346/250/241/345/274/217/350/203/214/346/231/257/350/211/262.md +37 -0
  105. package/vendor/BadCase/rn/cases/KI-014-amap-geolocation/345/233/236/350/260/203/347/274/272/345/244/261.md +42 -0
  106. package/vendor/BadCase/rn/cases/KI-015-reanimated/350/277/220/350/241/214/346/227/266/346/236/220/346/236/204/345/264/251/346/272/203.md +54 -0
  107. package/vendor/BadCase/rn/cases/KI-016-fs/346/226/207/344/273/266/350/257/273/345/217/226/347/274/226/347/240/201.md +58 -0
  108. package/vendor/BadCase/rn/cases/KI-017-blob-util/345/217/202/346/225/260/347/274/226/347/240/201/351/224/231/350/257/257.md +39 -0
  109. package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md +53 -0
  110. package/vendor/BadCase/rn/cases/KI-019-code-push/351/207/215/345/220/257/351/200/273/350/276/221/345/244/261/346/225/210.md +79 -0
  111. package/vendor/BadCase/rn/cases/KI-020-netinfo/346/225/217/346/204/237/344/277/241/346/201/257/346/263/204/351/234/262.md +60 -0
  112. package/vendor/BadCase/rn/cases/KI-021-video/346/234/254/345/234/260/350/247/206/351/242/221/346/222/255/346/224/276/345/274/202/345/270/270.md +79 -0
  113. package/vendor/BadCase/rn/cases/KI-022-audio-recorder-player/346/236/232/344/270/276/347/274/272/345/244/261.md +38 -0
  114. package/vendor/BadCase/rn/cases/KI-023-svg/346/270/220/345/217/230/347/273/247/346/211/277/345/244/261/346/225/210.md +62 -0
  115. package/vendor/BadCase/rn/generalization-log.md +55 -0
  116. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.json +328 -0
  117. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.md +382 -0
  118. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.json +1351 -0
  119. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.md +1176 -0
  120. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.json +538 -0
  121. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.md +1488 -0
  122. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.json +211 -0
  123. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.md +35 -0
  124. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.json +2048 -0
  125. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.md +3866 -0
  126. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.json +198 -0
  127. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.md +40 -0
  128. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.json +751 -0
  129. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.md +883 -0
  130. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.json +1544 -0
  131. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.md +2598 -0
  132. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.json +246 -0
  133. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.md +554 -0
  134. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.json +211 -0
  135. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.md +54 -0
  136. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.json +1626 -0
  137. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.md +2213 -0
  138. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.json +208 -0
  139. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.md +77 -0
  140. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.json +377 -0
  141. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.md +174 -0
  142. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.json +232 -0
  143. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.md +194 -0
  144. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.json +198 -0
  145. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.md +67 -0
  146. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.json +198 -0
  147. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.md +38 -0
  148. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.json +208 -0
  149. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.md +34 -0
  150. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.json +222 -0
  151. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.md +56 -0
  152. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.json +463 -0
  153. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.md +383 -0
  154. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.json +464 -0
  155. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.md +565 -0
  156. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.json +198 -0
  157. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.md +47 -0
  158. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.json +232 -0
  159. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.md +422 -0
  160. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.json +295 -0
  161. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.md +1038 -0
  162. package/vendor/BadCase/rn/rules/R-01-/345/205/250/345/261/217/347/252/227/345/217/243/347/212/266/346/200/201/347/256/241/347/220/206/345/256/214/346/225/264/346/200/247.md +20 -0
  163. package/vendor/BadCase/rn/rules/R-02-/350/265/204/346/272/220URI/345/275/242/346/200/201/345/210/206/346/224/257/350/246/206/347/233/226.md +21 -0
  164. package/vendor/BadCase/rn/rules/R-03-/351/231/204/345/261/236/346/223/215/344/275/234/345/244/261/350/264/245/351/230/273/346/226/255/344/270/273/346/265/201/347/250/213.md +20 -0
  165. package/vendor/BadCase/rn/rules/R-04-/345/274/202/346/255/245/345/233/236/350/260/203/346/263/250/345/206/214/346/227/266/345/272/217.md +20 -0
  166. package/vendor/BadCase/rn/rules/R-05-/346/250/241/345/235/227/345/257/274/345/205/245/350/267/257/345/276/204/350/247/204/350/214/203.md +19 -0
  167. package/vendor/BadCase/rn/rules/R-06-/344/274/240/346/204/237/345/231/250/347/241/254/344/273/266/346/235/203/351/231/220/346/214/211/351/234/200/350/216/267/345/217/226.md +21 -0
  168. package/vendor/BadCase/rn/rules/R-07-/346/231/272/350/203/275/346/214/207/351/222/210/347/224/237/345/221/275/345/221/250/346/234/237/347/256/241/347/220/206.md +20 -0
  169. package/vendor/BadCase/rn/rules/R-08-/346/211/213/345/212/277/344/272/213/344/273/266/346/263/250/345/206/214/344/270/216/345/206/262/347/252/201/345/244/204/347/220/206.md +22 -0
  170. package/vendor/BadCase/rn/rules/R-09-/346/250/252/347/253/226/345/261/217/345/244/232/345/275/242/346/200/201/345/270/203/345/261/200/351/200/202/351/205/215.md +20 -0
  171. package/vendor/BadCase/rn/rules/R-10-/346/267/261/350/211/262/346/250/241/345/274/217/344/270/273/351/242/230/351/242/234/350/211/262/351/200/202/351/205/215.md +19 -0
  172. package/vendor/BadCase/rn/rules/R-11-/346/216/245/345/217/243/345/233/236/350/260/203/345/256/236/347/216/260/345/256/214/346/225/264/346/200/247.md +20 -0
  173. package/vendor/BadCase/rn/rules/R-12-/345/216/237/347/224/237/350/277/220/350/241/214/346/227/266/350/265/204/346/272/220/346/236/220/346/236/204/346/227/266/345/272/217.md +20 -0
  174. package/vendor/BadCase/rn/rules/R-13-/346/226/207/344/273/266/346/225/260/346/215/256/347/274/226/347/240/201/344/270/216/346/240/274/345/274/217/345/205/274/345/256/271.md +21 -0
  175. package/vendor/BadCase/rn/rules/R-14-/345/212/250/347/224/273/345/210/235/345/247/213/345/214/226/346/227/266/345/272/217/344/270/216/347/212/266/346/200/201/345/220/214/346/255/245.md +20 -0
  176. package/vendor/BadCase/rn/rules/R-15-/347/212/266/346/200/201/346/214/201/344/271/205/345/214/226/344/270/216/351/207/215/345/220/257/351/200/273/350/276/221/344/270/200/350/207/264/346/200/247.md +20 -0
  177. package/vendor/BadCase/rn/rules/R-16-/346/225/217/346/204/237/344/277/241/346/201/257/346/227/245/345/277/227/346/263/204/351/234/262.md +19 -0
  178. package/vendor/BadCase/rn/rules/R-17-/345/252/222/344/275/223/350/265/204/346/272/220/347/224/237/345/221/275/345/221/250/346/234/237/344/270/216/351/224/231/350/257/257/345/244/204/347/220/206.md +21 -0
  179. package/vendor/BadCase/rn/rules/R-18-/350/203/275/345/212/233/346/236/232/344/270/276/351/205/215/347/275/256/345/256/214/346/225/264/346/200/247.md +19 -0
  180. package/vendor/BadCase/rn/rules/R-19-/345/233/276/345/275/242/346/270/262/346/237/223/345/261/236/346/200/247/347/273/247/346/211/277/344/270/216/351/207/215/347/275/256.md +19 -0
  181. package/vendor/MCP/README.md +490 -0
  182. package/vendor/MCP/config.json +29 -0
  183. package/vendor/MCP/package.json +23 -0
  184. package/vendor/MCP/scripts/analyze-demo-coverage.cjs +1203 -0
  185. package/vendor/MCP/scripts/analyze-xts-coverage.cjs +1245 -0
  186. package/vendor/MCP/scripts/deveco_docs.js +247 -0
  187. package/vendor/MCP/scripts/extract-interfaces.cjs +1487 -0
  188. package/vendor/MCP/scripts/flutter-analyze-demo-coverage.cjs +666 -0
  189. package/vendor/MCP/scripts/flutter-analyze-xts-coverage.cjs +684 -0
  190. package/vendor/MCP/scripts/flutter-extract-interfaces.cjs +1251 -0
  191. package/vendor/MCP/scripts/flutter-render-spec-doc.cjs +351 -0
  192. package/vendor/MCP/scripts/render-spec-doc.cjs +347 -0
  193. package/vendor/MCP/scripts/rn-analyze-demo-coverage.cjs +645 -0
  194. package/vendor/MCP/scripts/rn-analyze-test-coverage.cjs +614 -0
  195. package/vendor/MCP/scripts/rn-extract-interfaces.cjs +1462 -0
  196. package/vendor/MCP/scripts/rn-render-spec-doc.cjs +327 -0
  197. package/vendor/MCP/scripts/rn-scan-exports.cjs +1336 -0
  198. package/vendor/MCP/src/client/MCPClientPool.js +220 -0
  199. package/vendor/MCP/src/config/ConfigLoader.js +189 -0
  200. package/vendor/MCP/src/executor/ScriptExecutor.js +110 -0
  201. package/vendor/MCP/src/gateway/Gateway.js +451 -0
  202. package/vendor/MCP/src/index.js +87 -0
  203. package/vendor/MCP/src/library/KBToolProvider.js +229 -0
  204. package/vendor/MCP/src/library/logger.js +60 -0
  205. package/vendor/MCP/src/registry/ScriptRegistry.js +238 -0
  206. package/vendor/MCP/src/registry/ToolRegistry.js +111 -0
  207. package/vendor/MCP/src/types.js +115 -0
  208. package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +4 -2
  209. package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +3 -3
  210. package/vendor/Server/Skills/knowledge-import/SKILL.md +1 -1
  211. package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +12 -4
  212. package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +5 -4
  213. package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +2 -2
  214. package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +2 -2
  215. package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +1 -2
  216. package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +1 -1
  217. package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +1 -2
  218. package/vendor/Server/package.json +5 -1
  219. package/vendor/VERSION +3 -3
@@ -0,0 +1,422 @@
1
+ # PR #121: feat:增加video横竖屏切换功能
2
+
3
+ - **状态**: merged
4
+ - **作者**: chenbaodi123
5
+ - **创建时间**: 2026-08-02T16:51:36+08:00
6
+ - **分支**: master → master
7
+ - **变更文件数**: 2
8
+
9
+ ## PR 描述
10
+
11
+ ## 一、变更类型(单选,仅勾选一项)
12
+ - [x] feat(新增功能,对应 Changelog Added)
13
+ - [ ] fix(修复 Bug,对应 Changelog Fixed)
14
+ - [ ] docs(文档变更,对应 Changelog Documentation)
15
+ - [ ] refactor(代码重构,对应 Changelog Changed)
16
+ - [ ] perf(性能优化,对应 Changelog Performance)
17
+ - [ ] test(测试相关,不进入 Changelog)
18
+ - [ ] chore(构建/工具链/依赖,不进入 Changelog)
19
+ - [ ] deprecated(标记弃用,对应 Changelog Deprecated)
20
+ - [ ] removed(移除功能,对应 Changelog Removed)
21
+ - [ ] security(安全修复,对应 Changelog Security)
22
+
23
+ ## 二、变更内容
24
+ ### 简要描述
25
+ 增加video横竖屏切换功能
26
+
27
+ ### 破坏性变更说明
28
+ 无破坏性变更
29
+
30
+
31
+ ## 三、测试步骤
32
+ 1.连接网络,使用demo测试
33
+ 2.demo加载成功以后,点击全屏
34
+ 3.然后旋转手机,video会自动横竖屏切换
35
+
36
+ demo:
37
+ ```
38
+ /**
39
+ * @format
40
+ */
41
+
42
+ /**
43
+ * @format
44
+ */
45
+
46
+ import { AppRegistry } from 'react-native';
47
+ import React, { useEffect } from 'react';
48
+ import { name as appName } from './app.json';
49
+ import Orientation from 'react-native-orientation';
50
+
51
+ import { WebView } from "react-native-webview";
52
+
53
+ export default function WebViewDemo() {
54
+ const handleWebMessage = (e) => {
55
+ try {
56
+ const data = JSON.parse(e.nativeEvent.data);
57
+ if (data.type === 'WEB_FULLSCREEN') {
58
+ if (data.isFullScreen) {
59
+ // 进入视频全屏:解锁,允许自动横竖屏
60
+ // Orientation.unlockAllOrientations();
61
+ } else {
62
+ // 退出全屏:重新锁定竖屏
63
+ // Orientation.lockToPortrait();
64
+ }
65
+ }
66
+ } catch (err) { }
67
+ };
68
+
69
+
70
+ return (
71
+ <WebView
72
+ source={{ uri: "https://reyee.ruijie.com.cn/s2b2c/#/casePush/newVideoCommonPlay?userFlag=5d55e70ee071a533b06770291f388eb0_33187&accessKey=mini_profile__native_app_c0db3bad-5c06-4788-8e9e-8df39fc404ea&appVersion=9.4.0&hideShareAndSwiper=false&canShare=false&isTabWebView=false&accountId=18959589245&mId=350845&publisherId=266440&visitorId=18959589245&type=video&route=videoCommonPlay&isHideDescription=true&objClass=video&continent=&tz=-480&imControl=true&lang=zh&barHeight=37.84615384615385&platform=harmony" }}
73
+ domStorageEnabled={true}
74
+ javaScriptEnabled={true}
75
+ allowFileAccess={false}
76
+ allowsFullscreenVideo={true}
77
+ // injectedJavaScript={injectFullScreenScript}
78
+ onMessage={handleWebMessage}
79
+ />
80
+ );
81
+ }
82
+
83
+
84
+ export const Root = () => {
85
+ // 空依赖数组 = 组件初始化挂载后执行一次,完全等价 componentDidMount
86
+ useEffect(() => {
87
+ Orientation.lockToPortrait();
88
+ // SplashScreen.hide();
89
+ }, []);
90
+ return <WebViewDemo />;
91
+ };
92
+
93
+ AppRegistry.registerComponent(appName, () => Root);
94
+
95
+ ```
96
+
97
+ ## 四、测试情况
98
+ 横屏状态UI显示正常
99
+ 不涉及
100
+
101
+ ## 五、合入前自检
102
+ - [x] 不涉及非兼容性变更;若涉及,已通过相应评审。
103
+ - [x] 不涉及性能或已进行性能测试且无性能劣化。
104
+ - [x] 符合对应的编码规范。
105
+ - [x] 无敏感信息泄露,如密码、密钥等。
106
+ - [x] 不涉及文档更新,或已更新了文档。
107
+ - [x] 针对可测试性要求,已增加必要的自测用例、合理的日志记录或Trace信息。
108
+ - [x] 不存在非法的文件引入,包括图片和代码等
109
+
110
+ ## 变更文件
111
+
112
+ | 文件 | 变更 | +行 | -行 |
113
+ |------|------|-----|-----|
114
+ | `harmony/rn_webview/src/main/ets/Magic.ets` | ? | +1 | -0 |
115
+ | `harmony/rn_webview/src/main/ets/RNCWebView.ets` | ? | +198 | -7 |
116
+
117
+ ## Diff
118
+
119
+ ### `harmony/rn_webview/src/main/ets/Magic.ets`
120
+
121
+ ```diff
122
+ @@ -89,6 +89,7 @@ export interface WebViewProps extends ViewRawProps {
123
+ renderMode: "SYNC_RENDER" | "ASYNC_RENDER",
124
+ mediaCapturePermissionGrantType?: 'prompt' | 'grant' | 'deny' | 'grantIfSameHostElsePrompt' | 'grantIfSameHostElseDeny'
125
+ menuItems?: Array<MenuItem> | undefined;
126
+ + allowsFullscreenVideo?: boolean;
127
+ }
128
+
129
+ export interface MenuItem {
130
+
131
+ ```
132
+
133
+ ### `harmony/rn_webview/src/main/ets/RNCWebView.ets`
134
+
135
+ ```diff
136
+ @@ -53,6 +53,7 @@ import { abilityAccessCtrl, bundleManager, Permissions } from '@kit.AbilityKit';
137
+ import { WebViewTurboModule, ShouldStartParams, ShouldOverrideCallbackState } from './WebViewTurboModule';
138
+ import { AnyThreadRNInstance, WorkerTaskRunnable } from '@rnoh/react-native-openharmony/src/main/ets/RNOH';
139
+ import buffer from '@ohos.buffer';
140
+ +import { window } from '@kit.ArkUI';
141
+
142
+ export const TAG = "WebView"
143
+
144
+ @@ -106,6 +107,7 @@ export struct RNCWebView {
145
+ @State webviewWidth: number = ZERO
146
+ @State webviewHeight: number = ZERO
147
+ @State isRefreshing: boolean = false
148
+ + @State isFullScreen: boolean = false
149
+ @State mode: MixedMode = MixedMode.All;
150
+ private unregisterDescriptorChangesListener?: () => void = undefined
151
+ private cleanupCommandCallback?: () => void = undefined
152
+ @@ -119,10 +121,15 @@ export struct RNCWebView {
153
+ private debounceTimer: number = -1
154
+ static readonly DEBOUNCE_TIME: number = 100
155
+ private isFirstDebounce: boolean = true
156
+ + private initialOrientation: window.Orientation = window.Orientation.PORTRAIT
157
+ + private isOrientationSaved: boolean = false
158
+ + private cachedWindow: window.Window | null = null
159
+ + private allowsFullscreenVideo: boolean = false
160
+
161
+ aboutToAppear() {
162
+ try {
163
+ this.initVariable()
164
+ + this.saveInitialOrientation()
165
+ this.getBundleName()
166
+ this.url = this.source.uri as string;
167
+ this.onDescriptorWrapperChange(this.descriptorWrapper)
168
+ @@ -159,6 +166,20 @@ export struct RNCWebView {
169
+ }
170
+
171
+ aboutToDisappear() {
172
+ + // 恢复初始屏幕方向和沉浸式状态,防止全屏状态下组件销毁后状态残留
173
+ + // 无论是否在全屏状态,都尝试恢复窗口状态(handleFullScreenEnter 异步操作可能在组件销毁后才完成)
174
+ + if (this.cachedWindow) {
175
+ + try {
176
+ + this.cachedWindow.setPreferredOrientation(this.initialOrientation);
177
+ + this.cachedWindow.setWindowLayoutFullScreen(false);
178
+ + this.cachedWindow.setWindowSystemBarEnable(['status', 'navigation']);
179
+ + Logger.debug(TAG, '[WebViewFullScreen] Restored window state in aboutToDisappear');
180
+ + } catch (error) {
181
+ + Logger.error(TAG, `[WebViewFullScreen] Failed to restore in aboutToDisappear: ${error.code}`);
182
+ + }
183
+ + }
184
+ + this.isFullScreen = false;
185
+ + this.cachedWindow = null;
186
+ this.getUIContext().getFocusController().clearFocus()
187
+ this.cleanupCommandCallback?.()
188
+ this.unregisterDescriptorChangesListener?.()
189
+ @@ -532,6 +553,151 @@ export struct RNCWebView {
190
+ await atManager.requestPermissionsFromUser(this.ctx.uiAbilityContext, permissionList);
191
+ }
192
+
193
+ + private async getWindow(): Promise<window.Window | null> {
194
+ + try {
195
+ + const win = await window.getLastWindow(getContext(this));
196
+ + if (win) {
197
+ + this.cachedWindow = win;
198
+ + }
199
+ + return win;
200
+ + } catch (error) {
201
+ + console.error(TAG, `[WebViewFullScreenTest] getWindow Errorcode: ${error.code}`);
202
+ + return null;
203
+ + }
204
+ + }
205
+ +
206
+ + private async saveInitialOrientation() {
207
+ + const win = await this.getWindow();
208
+ + if (win) {
209
+ + try {
210
+ + const orientation = win.getPreferredOrientation();
211
+ + this.initialOrientation = orientation;
212
+ + this.isOrientationSaved = true;
213
+ + console.debug(TAG, `[WebViewFullScreenTest] Saved initial orientation: ${orientation}`);
214
+ + } catch (error) {
215
+ + console.error(TAG, `[WebViewFullScreenTest] saveInitialOrientation Errorcode: ${error.code}`);
216
+ + }
217
+ + }
218
+ + }
219
+ +
220
+ + private async setOrientation(orientation: window.Orientation): Promise<boolean> {
221
+ + const win = await this.getWindow();
222
+ + if (win) {
223
+ + try {
224
+ + await win.setPreferredOrientation(orientation);
225
+ + console.debug(TAG, `[WebViewFullScreenTest] Set orientation to: ${orientation}`);
226
+ + return true;
227
+ + } catch (error) {
228
+ + console.error(TAG, `[WebViewFullScreenTest] setOrientation Errorcode: ${error.code}`);
229
+ + return false;
230
+ + }
231
+ + }
232
+ + return false;
233
+ + }
234
+ +
235
+ + // 处理全屏进入(带状态保护和异步串行)
236
+ + private async handleFullScreenEnter() {
237
+ + if (this.isFullScreen) {
238
+ + Logger.debug(TAG, '[WebViewFullScreen] Already in full screen, skipping');
239
+ + return;
240
+ + }
241
+ + if (!this.isOrientationSaved) {
242
+ + Logger.warn(TAG, '[WebViewFullScreen] Initial orientation not saved yet, skipping full screen enter');
243
+ + return;
244
+ + }
245
+ + try {
246
+ + // 阶段1:设置方向
247
+ + const orientationResult = await this.setOrientation(window.Orientation.AUTO_ROTATION);
248
+ + if (!orientationResult) {
249
+ + Logger.error(TAG, '[WebViewFullScreen] Failed to set orientation, aborting full screen enter');
250
+ + return;
251
+ + }
252
+ + // 阶段2:设置沉浸式模式
253
+ + const immersiveResult = await this.enterImmersiveMode();
254
+ + if (!immersiveResult) {
255
+ + Logger.error(TAG, '[WebViewFullScreen] Failed to enter immersive mode, rolling back');
256
+ + // 回滚沉浸式模式(即使部分失败也要尝试恢复)
257
+ + await this.exitImmersiveMode();
258
+ + // 回滚方向设置
259
+ + await this.setOrientation(this.initialOrientation);
260
+ + return;
261
+ + }
262
+ + // 阶段3:所有操作成功,设置状态
263
+ + this.isFullScreen = true;
264
+ + } catch (error) {
265
+ + Logger.error(TAG, `[WebViewFullScreen] Enter full screen failed: ${error}`);
266
+ + // 异常时回滚所有操作
267
+ + await this.exitImmersiveMode();
268
+ + await this.setOrientation(this.initialOrientation);
269
+ + }
270
+ + }
271
+ +
272
+ + // 处理全屏退出(带状态保护和异步串行)
273
+ + private async handleFullScreenExit() {
274
+ + if (!this.isFullScreen) {
275
+ + Logger.debug(TAG, '[WebViewFullScreen] Not in full screen, skipping');
276
+ + return;
277
+ + }
278
+ + try {
279
+ + // 阶段1:恢复方向
280
+ + const orientationResult = await this.setOrientation(this.initialOrientation);
281
+ + if (!orientationResult) {
282
+ + Logger.error(TAG, '[WebViewFullScreen] Failed to restore orientation, keeping full screen state');
283
+ + return;
284
+ + }
285
+ + // 方向已恢复,清除 isFullScreen 让 UI 恢复原始布局
286
+ + this.isFullScreen = false;
287
+ + // 阶段2:退出沉浸式模式
288
+ + const immersiveResult = await this.exitImmersiveMode();
289
+ + if (!immersiveResult) {
290
+ + Logger.error(TAG, '[WebViewFullScreen] Failed to exit immersive mode after restoring orientation');
291
+ + // 沉浸式模式退出失败,但方向已恢复,isFullScreen 已清除,避免重复触发循环
292
+ + }
293
+ + } catch (error) {
294
+ + Logger.error(TAG, `[WebViewFullScreen] Exit full screen failed: ${error}`);
295
+ + // 异常时也应清除状态,避免卡死
296
+ + this.isFullScreen = false;
297
+ + }
298
+ + }
299
+ +
300
+ + // 进入沉浸式全屏模式(隐藏系统栏)
301
+ + private async enterImmersiveMode(): Promise<boolean> {
302
+ + const win = await this.getWindow();
303
+ + if (win) {
304
+ + try {
305
+ + // 设置窗口为全屏布局模式,内容延伸到系统栏下方
306
+ + await win.setWindowLayoutFullScreen(true);
307
+ + // 隐藏系统导航栏和状态栏
308
+ + await win.setWindowSystemBarEnable([]);
309
+ + Logger.debug(TAG, '[WebViewFullScreen] Entered immersive mode');
310
+ + return true;
311
+ + } catch (error) {
312
+ + console.error(TAG, `[WebViewFullScreen] enterImmersiveMode Errorcode: ${error.code}`);
313
+ + return false;
314
+ + }
315
+ + }
316
+ + return false;
317
+ + }
318
+ +
319
+ + // 退出沉浸式全屏模式(恢复系统栏)
320
+ + private async exitImmersiveMode(): Promise<boolean> {
321
+ + const win = await this.getWindow();
322
+ + if (win) {
323
+ + try {
324
+ + // 关闭全屏布局模式
325
+ + await win.setWindowLayoutFullScreen(false);
326
+ + // 恢复显示系统导航栏和状态栏(默认显示所有系统栏)
327
+ + await win.setWindowSystemBarEnable(['status', 'navigation']);
328
+ + Logger.debug(TAG, '[WebViewFullScreen] Exited immersive mode');
329
+ + return true;
330
+ + } catch (error) {
331
+ + console.error(TAG, `[WebViewFullScreen] exitImmersiveMode Errorcode: ${error.code}`);
332
+ + return false;
333
+ + }
334
+ + }
335
+ + return false;
336
+ + }
337
+ +
338
+ build() {
339
+ Stack() {
340
+ if ( deviceInfo.sdkApiVersion >= 20) {
341
+ @@ -584,8 +750,8 @@ export struct RNCWebView {
342
+ }
343
+ }
344
+ })
345
+ - .width(this.webviewWidth)
346
+ - .height(this.webviewHeight)
347
+ + .width(this.isFullScreen ? "100%" : this.webviewWidth)
348
+ + .height(this.isFullScreen ? "100%" : this.webviewHeight)
349
+ .fileAccess(this.allowFileAccess)
350
+ .constraintSize({ minHeight: MINHEIGHT })
351
+ .overScrollMode(this.overScrollMode)
352
+ @@ -629,6 +795,18 @@ export struct RNCWebView {
353
+ .onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
354
+ .onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
355
+ .onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
356
+ + .onFullScreenEnter(async () => {
357
+ + Logger.debug(TAG, '[WebViewFullScreen] onFullScreenEnter called');
358
+ + if (this.allowsFullscreenVideo) {
359
+ + await this.handleFullScreenEnter();
360
+ + } else {
361
+ + Logger.debug(TAG, '[WebViewFullScreen] Fullscreen video disabled by allowsFullscreenVideo');
362
+ + }
363
+ + })
364
+ + .onFullScreenExit(async () => {
365
+ + Logger.debug(TAG, '[WebViewFullScreen] onFullScreenExit called');
366
+ + await this.handleFullScreenExit();
367
+ + })
368
+ .editMenuOptions({
369
+ onCreateMenu: this.onCreateMenu.bind(this),
370
+ onMenuItemClick: this.onMenuItemClick.bind(this),
371
+ @@ -684,8 +862,8 @@ export struct RNCWebView {
372
+ }
373
+ })
374
+
375
+ - .width(this.webviewWidth)
376
+ - .height(this.webviewHeight)
377
+ + .width(this.isFullScreen ? "100%" : this.webviewWidth)
378
+ + .height(this.isFullScreen ? "100%" : this.webviewHeight)
379
+ .fileAccess(this.allowFileAccess)
380
+ .constraintSize({ minHeight: MINHEIGHT })
381
+ .overScrollMode(this.overScrollMode)
382
+ @@ -728,15 +906,27 @@ export struct RNCWebView {
383
+ .onRenderExited((event: OnRenderExitedEvent) => this.webViewBaseOperate?.onRenderExited(event))
384
+ .onLoadIntercept((event: OnLoadInterceptEvent) => this.onLoadIntercept(event))
385
+ .onTitleReceive((event: OnTitleReceiveEvent) => this.webViewBaseOperate?.onTitleReceive(event))
386
+ + .onFullScreenEnter(async () => {
387
+ + Logger.debug(TAG, '[WebViewFullScreen] onFullScreenEnter called');
388
+ + if (this.allowsFullscreenVideo) {
389
+ + await this.handleFullScreenEnter();
390
+ + } else {
391
+ + Logger.debug(TAG, '[WebViewFullScreen] Fullscreen video disabled by allowsFullscreenVideo');
392
+ + }
393
+ + })
394
+ + .onFullScreenExit(async () => {
395
+ + Logger.debug(TAG, '[WebViewFullScreen] onFullScreenExit called');
396
+ + await this.handleFullScreenExit();
397
+ + })
398
+ .editMenuOptions({
399
+ onCreateMenu: this.onCreateMenu.bind(this),
400
+ onMenuItemClick: this.onMenuItemClick.bind(this),
401
+ })
402
+ }
403
+ }
404
+ - .width(this.webviewWidth)
405
+ - .height(this.webviewHeight)
406
+ - .position({
407
+ + .width(this.isFullScreen ? "100%" : this.webviewWidth)
408
+ + .height(this.isFullScreen ? "100%" : this.webviewHeight)
409
+ + .position(this.isFullScreen ? undefined : {
410
+ x: this.descriptorWrapper.layoutMetrics.frame.origin.x,
411
+ y: this.descriptorWrapper.layoutMetrics.frame.origin.y
412
+ })
413
+ @@ -843,6 +1033,7 @@ export struct RNCWebView {
414
+
415
+ const renderModeStr = this.descriptorWrapper.rawProps.renderMode || "SYNC_RENDER"
416
+ this.renderMode = (renderModeStr === "ASYNC_RENDER") ? RenderMode.ASYNC_RENDER : RenderMode.SYNC_RENDER
417
+ + this.allowsFullscreenVideo = this.descriptorWrapper.rawProps.allowsFullscreenVideo ?? false;
418
+
419
+ }
420
+
421
+
422
+ ```