@ohos-cpf/3rdloop 0.0.7 → 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 (230) hide show
  1. package/README.md +44 -25
  2. package/lib/cli.js +54 -29
  3. package/lib/config-cmd.js +1 -1
  4. package/lib/config.js +32 -0
  5. package/lib/doctor.js +266 -48
  6. package/lib/mcp.js +498 -0
  7. package/lib/opencode.js +75 -29
  8. package/lib/orch.js +32 -10
  9. package/lib/runner.js +8 -5
  10. package/lib/serve.js +162 -149
  11. package/lib/step.js +15 -4
  12. package/lib/web.js +107 -265
  13. package/lib/workflow.js +18 -8
  14. package/package.json +6 -2
  15. package/vendor/Archive/data/.index/meta.json +7 -0
  16. package/vendor/Archive/data/.index/search.db +0 -0
  17. package/vendor/Archive/data/docs/experiences/arkts-check-tool-pitfalls-baseline-comparison.md +13 -0
  18. package/vendor/Archive/data/docs/experiences/arkts-deep-path-import-recognition.md +31 -0
  19. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-entry-file-case-mismatch.md +25 -0
  20. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-import-trailing-slash.md +20 -0
  21. package/vendor/Archive/data/docs/experiences/arkts-library-source-files-may-be-ts.md +18 -0
  22. package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md +36 -0
  23. package/vendor/Archive/data/docs/experiences/arkts-xts-compile-error-clustering-fix.md +24 -0
  24. package/vendor/Archive/data/docs/experiences/arkts-xts-doc-expected-value-runtime-probe.md +35 -0
  25. package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md +33 -0
  26. package/vendor/Archive/data/docs/experiences/code-linter-chinese-comment-false-positive.md +16 -0
  27. package/vendor/Archive/data/docs/experiences/esobject-new-expression-variable-tracking.md +33 -0
  28. package/vendor/Archive/data/docs/experiences/filesystem-case-sensitivity-module-resolution.md +31 -0
  29. package/vendor/Archive/data/docs/experiences/gitcode-clone-redirect-warning-normal.md +13 -0
  30. package/vendor/Archive/data/docs/experiences/kn_msgvq1w585ec8319.md +77 -0
  31. package/vendor/Archive/data/docs/experiences/kn_msovnm6rd46de72c.md +98 -0
  32. package/vendor/Archive/data/docs/experiences/kn_mspt8vntfe708576.md +87 -0
  33. package/vendor/Archive/data/docs/experiences/kn_mspu1ei77adbbb48.md +133 -0
  34. package/vendor/Archive/data/docs/experiences/kn_mspubgak8d30bfce.md +128 -0
  35. package/vendor/Archive/data/docs/experiences/kn_mspug2de3cb1f7c3.md +115 -0
  36. package/vendor/Archive/data/docs/experiences/kn_skill_opt_001.md +38 -0
  37. package/vendor/Archive/data/docs/experiences/loop-artifacts-verification-evidence-triangle.md +19 -0
  38. package/vendor/Archive/data/docs/experiences/macos-bash-replace-build-ps1.md +19 -0
  39. package/vendor/Archive/data/docs/experiences/macos-bsd-diff-q-illegal-option.md +15 -0
  40. package/vendor/Archive/data/docs/experiences/migrate-cjs-compatible-api-version-map-limit.md +17 -0
  41. package/vendor/Archive/data/docs/experiences/mp3agic-arkts-library-behavior-quirks.md +21 -0
  42. package/vendor/Archive/data/docs/experiences/ohos-face-detection-scan-api-mapping.md +15 -0
  43. package/vendor/Archive/data/docs/experiences/pr-metadata-and-diff-integrity-verification.md +12 -0
  44. package/vendor/Archive/data/docs/experiences/rn-coverage-index-signature-pseudo-member-false-negative.md +32 -0
  45. package/vendor/Archive/data/docs/experiences/rn-memory-check-severity-calibration.md +21 -0
  46. package/vendor/Archive/data/docs/experiences/rn-platform-specific-api-exclusion-evidence.md +24 -0
  47. package/vendor/Archive/data/docs/experiences/rn-upstream-version-diff-pitfalls.md +17 -0
  48. package/vendor/Archive/data/docs/experiences/rn-version-gap-risk-rating-rules.md +13 -0
  49. package/vendor/Archive/data/docs/experiences/rn-view-lib-native-contract-diff-fabric-spec.md +16 -0
  50. package/vendor/Archive/data/docs/experiences/rnoh-adapter-package-version-field-semantics.md +18 -0
  51. package/vendor/Archive/data/docs/experiences/rnoh-arkts-sqlite-rows-array-format.md +18 -0
  52. package/vendor/Archive/data/docs/experiences/rnoh-dependency-residue-scan-strategy.md +18 -0
  53. package/vendor/Archive/data/docs/experiences/rnoh-example-local-lib-dep-use-tgz.md +53 -0
  54. package/vendor/Archive/data/docs/experiences/rnoh-example-prereserve-rntesterlist.md +17 -0
  55. package/vendor/Archive/data/docs/experiences/rnoh-example-template-compatiblesdkversion-upgrade.md +29 -0
  56. package/vendor/Archive/data/docs/experiences/rnoh-example-turbomodule-shell-adaptation-checklist.md +41 -0
  57. package/vendor/Archive/data/docs/experiences/rnoh-mcp-build-project-tool-risk.md +18 -0
  58. package/vendor/Archive/data/docs/experiences/rnoh-npm-devdependencies-version-precheck.md +29 -0
  59. package/vendor/Archive/data/docs/experiences/rnoh-repo-baseline-version-verification.md +13 -0
  60. package/vendor/Archive/data/docs/experiences/rnoh-repo-upstream-directory-mapping.md +18 -0
  61. package/vendor/Archive/data/docs/experiences/rnoh-stateless-library-zero-leak-verification.md +31 -0
  62. package/vendor/Archive/data/docs/experiences/rnoh-template-npmrc-credential-removal.md +15 -0
  63. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-codegen-wiring-verification.md +19 -0
  64. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-cpp-methodmap-compatibility-check.md +20 -0
  65. package/vendor/Archive/data/docs/experiences/scenario-doc-vs-source-signature-diff-four-patterns.md +24 -0
  66. package/vendor/Archive/data/docs/experiences/static-analysis-grep-cross-validation.md +29 -0
  67. package/vendor/Archive/demo.js +489 -0
  68. package/vendor/Archive/index.js +43 -0
  69. package/vendor/Archive/package.json +16 -0
  70. package/vendor/Archive/src/constants.js +83 -0
  71. package/vendor/Archive/src/data/stopwords.txt +110 -0
  72. package/vendor/Archive/src/data/synonyms.json +25 -0
  73. package/vendor/Archive/src/data/terms.txt +59 -0
  74. package/vendor/Archive/src/db/sqlite-backend.js +312 -0
  75. package/vendor/Archive/src/db/sqlite-schema.js +64 -0
  76. package/vendor/Archive/src/engine.js +501 -0
  77. package/vendor/Archive/src/index/index-manager.js +203 -0
  78. package/vendor/Archive/src/index/index-state.js +94 -0
  79. package/vendor/Archive/src/index/search-text-builder.js +106 -0
  80. package/vendor/Archive/src/index.js +22 -0
  81. package/vendor/Archive/src/parser/api-identifiers.js +121 -0
  82. package/vendor/Archive/src/parser/api-suffixes.js +48 -0
  83. package/vendor/Archive/src/parser/heading-normalize.js +40 -0
  84. package/vendor/Archive/src/parser/markdown-splitter.js +215 -0
  85. package/vendor/Archive/src/search/catalog-routing.js +87 -0
  86. package/vendor/Archive/src/search/fts-search.js +289 -0
  87. package/vendor/Archive/src/search/query-normalizer.js +159 -0
  88. package/vendor/Archive/src/search/query-rewriter.js +72 -0
  89. package/vendor/Archive/src/search/search-engine.js +72 -0
  90. package/vendor/Archive/src/search/snippet.js +64 -0
  91. package/vendor/Archive/src/store/dir-store.js +103 -0
  92. package/vendor/Archive/src/store/doc-store.js +36 -0
  93. package/vendor/Archive/src/tokenizer/lexicon.js +151 -0
  94. package/vendor/Archive/src/tokenizer/tokenizer.js +167 -0
  95. package/vendor/Archive/src/types.js +86 -0
  96. package/vendor/Archive/src/utils/hash.js +16 -0
  97. package/vendor/Archive/src/utils/lock.js +73 -0
  98. package/vendor/Archive/src/utils/path-safety.js +96 -0
  99. package/vendor/Archive/src/utils/paths.js +39 -0
  100. package/vendor/BadCase/rn/INDEX.md +127 -0
  101. 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
  102. 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
  103. 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
  104. package/vendor/BadCase/rn/cases/KI-004-wechat/345/233/236/350/260/203/346/227/266/345/272/217.md +47 -0
  105. 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
  106. 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
  107. 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
  108. 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
  109. package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md +38 -0
  110. package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md +48 -0
  111. 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
  112. package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md +59 -0
  113. 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
  114. package/vendor/BadCase/rn/cases/KI-014-amap-geolocation/345/233/236/350/260/203/347/274/272/345/244/261.md +42 -0
  115. 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
  116. 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
  117. 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
  118. package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md +53 -0
  119. 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
  120. 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
  121. 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
  122. 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
  123. 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
  124. package/vendor/BadCase/rn/generalization-log.md +55 -0
  125. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.json +328 -0
  126. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.md +382 -0
  127. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.json +1351 -0
  128. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.md +1176 -0
  129. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.json +538 -0
  130. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.md +1488 -0
  131. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.json +211 -0
  132. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.md +35 -0
  133. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.json +2048 -0
  134. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.md +3866 -0
  135. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.json +198 -0
  136. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.md +40 -0
  137. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.json +751 -0
  138. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.md +883 -0
  139. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.json +1544 -0
  140. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.md +2598 -0
  141. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.json +246 -0
  142. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.md +554 -0
  143. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.json +211 -0
  144. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.md +54 -0
  145. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.json +1626 -0
  146. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.md +2213 -0
  147. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.json +208 -0
  148. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.md +77 -0
  149. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.json +377 -0
  150. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.md +174 -0
  151. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.json +232 -0
  152. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.md +194 -0
  153. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.json +198 -0
  154. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.md +67 -0
  155. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.json +198 -0
  156. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.md +38 -0
  157. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.json +208 -0
  158. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.md +34 -0
  159. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.json +222 -0
  160. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.md +56 -0
  161. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.json +463 -0
  162. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.md +383 -0
  163. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.json +464 -0
  164. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.md +565 -0
  165. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.json +198 -0
  166. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.md +47 -0
  167. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.json +232 -0
  168. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.md +422 -0
  169. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.json +295 -0
  170. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.md +1038 -0
  171. 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
  172. 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
  173. 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
  174. 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
  175. 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
  176. 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
  177. 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
  178. 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
  179. 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
  180. 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
  181. 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
  182. 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
  183. 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
  184. 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
  185. 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
  186. 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
  187. 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
  188. 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
  189. 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
  190. package/vendor/MCP/README.md +490 -0
  191. package/vendor/MCP/config.json +29 -0
  192. package/vendor/MCP/package.json +23 -0
  193. package/vendor/MCP/scripts/analyze-demo-coverage.cjs +1203 -0
  194. package/vendor/MCP/scripts/analyze-xts-coverage.cjs +1245 -0
  195. package/vendor/MCP/scripts/deveco_docs.js +247 -0
  196. package/vendor/MCP/scripts/extract-interfaces.cjs +1487 -0
  197. package/vendor/MCP/scripts/flutter-analyze-demo-coverage.cjs +666 -0
  198. package/vendor/MCP/scripts/flutter-analyze-xts-coverage.cjs +684 -0
  199. package/vendor/MCP/scripts/flutter-extract-interfaces.cjs +1251 -0
  200. package/vendor/MCP/scripts/flutter-render-spec-doc.cjs +351 -0
  201. package/vendor/MCP/scripts/render-spec-doc.cjs +347 -0
  202. package/vendor/MCP/scripts/rn-analyze-demo-coverage.cjs +645 -0
  203. package/vendor/MCP/scripts/rn-analyze-test-coverage.cjs +614 -0
  204. package/vendor/MCP/scripts/rn-extract-interfaces.cjs +1462 -0
  205. package/vendor/MCP/scripts/rn-render-spec-doc.cjs +327 -0
  206. package/vendor/MCP/scripts/rn-scan-exports.cjs +1336 -0
  207. package/vendor/MCP/src/client/MCPClientPool.js +220 -0
  208. package/vendor/MCP/src/config/ConfigLoader.js +189 -0
  209. package/vendor/MCP/src/executor/ScriptExecutor.js +110 -0
  210. package/vendor/MCP/src/gateway/Gateway.js +451 -0
  211. package/vendor/MCP/src/index.js +87 -0
  212. package/vendor/MCP/src/library/KBToolProvider.js +229 -0
  213. package/vendor/MCP/src/library/logger.js +60 -0
  214. package/vendor/MCP/src/registry/ScriptRegistry.js +238 -0
  215. package/vendor/MCP/src/registry/ToolRegistry.js +111 -0
  216. package/vendor/MCP/src/types.js +115 -0
  217. package/vendor/Server/CLI/cli.js +3 -3
  218. package/vendor/Server/Routes/server.js +3 -3
  219. package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +4 -2
  220. package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +3 -3
  221. package/vendor/Server/Skills/knowledge-import/SKILL.md +1 -1
  222. package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +12 -4
  223. package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +5 -4
  224. package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +2 -2
  225. package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +2 -2
  226. package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +1 -2
  227. package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +1 -1
  228. package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +1 -2
  229. package/vendor/Server/package.json +5 -1
  230. package/vendor/VERSION +3 -3
package/lib/serve.js CHANGED
@@ -1,22 +1,28 @@
1
1
  /**
2
- * serve.js —— 3rdloop serve 启动 Server HTTP 后端
2
+ * serve.js —— 3rdloop serve:一条命令同时启动 Server HTTP 后端 + Web 前端
3
3
  *
4
- * 定位:为前端展示启动现成 Server 后端(复用 Server/Routes/server.js
5
- * createServer,不新增任何 daemon/调度逻辑)。CLI 其余命令仍为嵌入式,不受影响。
4
+ * 定位:serve Web 前端绑定启动(原独立 `3rdloop web` 命令已合并至此):
5
+ * - 后端:复用 Server/Routes/server.js 的 createServer(默认 3000,不新增任何 daemon/调度逻辑)
6
+ * - 前端:进程内启动 Web 服务(lib/web.js:静态托管 + /api 反代 + 扩展挂载,默认 8080)
6
7
  *
7
8
  * 行为:
8
- * - 默认仅启动 HTTP 后端(--port / 3LIB_SERVER_PORT / 3000
9
- * - -w/--web 可选:再拉起 Web/server.js 静态前端(反向代理 /api/* 到后端)
10
- * - 复用 CLI 的环境装配(cli.js 已统一执行 .env 链 + stdout 保护),
11
- * 与 run/submit 等命令保持一致;json 模式下本模块自行纯化 stdout
9
+ * - 默认同时启动后端与 Web 前端(--port / 3LIB_SERVER_PORT、--web-port / 3LIB_WEB_PORT
10
+ * - 复用 CLI 的环境装配(cli.js 已统一执行 .env 链 + stdout 保护),与 run/submit 等命令一致
11
+ * - 扩展管理子命令:install-ext / list-ext / remove-ext(不启动服务)
12
12
  * - 端口冲突 / 启动失败给出明确错误,不静默
13
13
  */
14
14
 
15
- import { spawn, execSync } from 'node:child_process';
16
15
  import fs from 'node:fs';
17
16
  import path from 'node:path';
18
17
  import { fileURLToPath } from 'node:url';
19
18
  import process from 'node:process';
19
+ import {
20
+ startWebServer,
21
+ resolveUserExtRoot,
22
+ webExtInstall,
23
+ webExtList,
24
+ webExtRemove,
25
+ } from './web.js';
20
26
 
21
27
  const moduleDir = path.dirname(fileURLToPath(import.meta.url));
22
28
  export const CLI_ROOT = path.resolve(moduleDir, '..');
@@ -49,60 +55,112 @@ async function _importServerModule() {
49
55
  return import(url.href);
50
56
  }
51
57
 
52
- /** Web 静态前端目录(开发期仓库 Web/;发布期 vendor/Web 预留)。 */
53
- function resolveWebDir() {
54
- const candidates = [
55
- path.resolve(CLI_ROOT, '..', 'Web'),
56
- path.join(CLI_ROOT, 'vendor', 'Web'),
57
- ];
58
- for (const dir of candidates) {
59
- if (fs.existsSync(path.join(dir, 'server.js')) && fs.existsSync(path.join(dir, 'public'))) {
60
- return dir;
61
- }
62
- }
63
- return null;
64
- }
65
-
66
58
  /**
67
- * 解析 flags.rest 中 serve 专用参数(不依赖 cli.js 的 parseGlobalFlags
68
- * 因为 -w/--web 会被它归入 rest)。
69
- * @returns {{ web: boolean, port?: number, webPort?: number }}
59
+ * 解析 serve 专用参数(不依赖 cli.js 的 parseGlobalFlags,全局 flags 已被其消费)。
60
+ * Web 前端随 serve 默认启动,原 -w/--web 仅作兼容接受(不再有独立语义)。
61
+ * @returns {{ port?: number, webPort?: number, webRoot: string, extRoots: string[], extNames: string[], noExt: boolean, open: boolean, positionals: string[] }}
70
62
  */
71
63
  function _parseServeArgs(rest = []) {
72
- const args = { web: false };
64
+ const args = { webRoot: '', extRoots: [], extNames: [], noExt: false, open: false, positionals: [] };
65
+ const parsePort = (raw, name) => {
66
+ const n = parseInt(raw, 10);
67
+ if (!Number.isFinite(n) || n <= 0 || n > 65535) {
68
+ throw new Error(`非法端口: "${raw}"(${name})`);
69
+ }
70
+ return n;
71
+ };
73
72
  for (let i = 0; i < rest.length; i++) {
74
73
  const arg = rest[i];
75
- if (arg === '-w' || arg === '--web') args.web = true;
76
- else if (arg === '--port' || arg === '--web-port') {
77
- const key = arg === '--port' ? 'port' : 'webPort';
78
- const n = parseInt(rest[i + 1], 10);
79
- if (Number.isFinite(n) && n > 0) args[key] = n;
80
- i++; // 跳过值
74
+
75
+ if (arg === '-w' || arg === '--web') {
76
+ // 兼容旧参数:Web 前端现已默认启动,提示后忽略
77
+ process.stderr.write('[3rdloop serve] 提示: -w/--web 已无需指定,Web 前端随 serve 默认启动\n');
78
+ } else if (arg === '--port') {
79
+ args.port = parsePort(rest[++i], '--port');
80
+ } else if (arg === '--web-port') {
81
+ args.webPort = parsePort(rest[++i], '--web-port');
82
+ } else if (arg === '--web-root') {
83
+ args.webRoot = rest[++i] || '';
84
+ } else if (arg === '--ext-root') {
85
+ const raw = rest[++i];
86
+ if (raw) args.extRoots.push(raw);
87
+ } else if (arg === '--ext') {
88
+ // 白名单:逗号分隔 + 可重复指定(--ext tag --ext issue 等效 --ext tag,issue)
89
+ const raw = rest[++i];
90
+ if (raw) {
91
+ for (const n of raw.split(',')) {
92
+ const t = n.trim();
93
+ if (t) args.extNames.push(t);
94
+ }
95
+ }
96
+ } else if (arg === '--no-ext') {
97
+ args.noExt = true;
98
+ } else if (arg === '--open') {
99
+ args.open = true;
100
+ } else if (arg.startsWith('--')) {
101
+ throw new Error(`未知选项: ${arg}(查看帮助: 3rdloop serve --help)`);
102
+ } else {
103
+ args.positionals.push(arg);
81
104
  }
82
105
  }
83
106
  return args;
84
107
  }
85
108
 
109
+ /** --json 模式的 stdout 输出函数(非 json 模式为 no-op)。 */
110
+ function _jsonOut(jsonMode) {
111
+ return (data) => {
112
+ if (jsonMode) process.stdout.write(JSON.stringify(data, null, 2) + '\n');
113
+ };
114
+ }
115
+
86
116
  /**
87
- * 3rdloop serve 命令实现。
117
+ * 3rdloop serve 命令实现:同时启动 Server HTTP 后端 + Web 前端。
88
118
  * @param {object} opts
89
- * @param {string[]} opts.rest - flags.rest(含 serve 专用参数)
119
+ * @param {string[]} opts.rest - flags.rest(含 serve 专用参数与扩展管理子命令)
90
120
  * @param {boolean} opts.jsonMode
91
121
  * @param {string} [opts.dataDir] - CLI 解析后的数据目录(--data-dir / 3LIB_DATA_DIR / 默认)
92
- * @returns {Promise<number>} 退出码(serve 为长驻命令,仅 --help/启动失败正常返回)
122
+ * @param {string} [opts.user3libHome] - 用户 3lib 主目录(~/.3lib,扩展根解析用)
123
+ * @returns {Promise<number>} 退出码(serve 为长驻命令,仅 --help/子命令/启动失败正常返回)
93
124
  */
94
- export async function cmdServe({ rest = [], jsonMode = false, dataDir = '' }) {
125
+ export async function cmdServe({ rest = [], jsonMode = false, dataDir = '', user3libHome = '' }) {
95
126
  // --help / -h:打印用法
96
127
  if (rest.includes('--help') || rest.includes('-h')) {
97
128
  _printServeHelp();
98
129
  return 0;
99
130
  }
100
131
 
101
- const args = _parseServeArgs(rest);
132
+ let args;
133
+ try {
134
+ args = _parseServeArgs(rest);
135
+ } catch (err) {
136
+ process.stderr.write(`${err.message}\n`);
137
+ _printServeHelp();
138
+ return 1;
139
+ }
140
+
141
+ const userExtRoot = resolveUserExtRoot(user3libHome);
142
+
143
+ // ── 扩展管理子命令(不启动服务) ──
144
+ const [sub, subArg] = args.positionals;
145
+ if (sub === 'install-ext') {
146
+ return webExtInstall(subArg, { userExtRoot, jsonMode, out: _jsonOut(jsonMode) });
147
+ }
148
+ if (sub === 'list-ext') {
149
+ return webExtList({ userExtRoot, jsonMode, out: _jsonOut(jsonMode) });
150
+ }
151
+ if (sub === 'remove-ext') {
152
+ return webExtRemove(subArg, { userExtRoot, jsonMode, out: _jsonOut(jsonMode) });
153
+ }
154
+ if (sub !== undefined) {
155
+ process.stderr.write(`未知子命令: ${sub}\n`);
156
+ _printServeHelp();
157
+ return 1;
158
+ }
159
+
102
160
  const serverPort = args.port ?? _envInt('3LIB_SERVER_PORT', 3000);
103
161
  const webPort = args.webPort ?? _envInt('3LIB_WEB_PORT', 8080);
104
162
 
105
- if (args.web && serverPort === webPort) {
163
+ if (serverPort === webPort) {
106
164
  process.stderr.write(`3rdloop serve: 后端端口与 Web 端口相同 (${serverPort}),请用 --web-port 指定不同端口\n`);
107
165
  return 1;
108
166
  }
@@ -118,106 +176,77 @@ export async function cmdServe({ rest = [], jsonMode = false, dataDir = '' }) {
118
176
 
119
177
  const serverModule = await _importServerModule();
120
178
 
121
- // json 模式下纯化 stdout:Server 内部 console.log/info 重定向到 stderr
122
- let restoreStdout = null;
123
- if (jsonMode) {
124
- restoreStdout = _redirectStdoutLogs();
125
- }
126
-
127
- let webChild = null;
128
-
129
- // 优雅退出:清理 Web 子进程(Windows taskkill 树)后退出
130
- const cleanup = () => {
131
- if (webChild && webChild.pid != null) {
132
- try {
133
- if (process.platform === 'win32') {
134
- execSync(`taskkill /pid ${webChild.pid} /T /F`, { stdio: 'ignore' });
135
- } else {
136
- webChild.kill('SIGTERM');
137
- }
138
- } catch { /* 进程可能已退出 */ }
139
- webChild = null;
140
- }
141
- };
179
+ // ── 优雅退出 ──
180
+ // 必须在 createServer 之前注册:Server 内部也注册了 SIGINT/SIGTERM 处理器
181
+ // (退出码 0),先注册者先执行,保证 CLI 约定的 130/143 退出码语义。
182
+ let webServer = null;
142
183
  let shuttingDown = false;
143
184
  const onSignal = (sig) => {
144
185
  if (shuttingDown) return;
145
186
  shuttingDown = true;
146
- cleanup();
187
+ try {
188
+ // 立即停止 Web 服务并断开存量连接(含 SSE 反代长连接)
189
+ webServer?.close();
190
+ webServer?.closeAllConnections?.();
191
+ } catch { /* 尽力而为 */ }
147
192
  process.exit(sig === 'SIGINT' ? 130 : 143);
148
193
  };
149
194
  process.once('SIGINT', () => onSignal('SIGINT'));
150
195
  process.once('SIGTERM', () => onSignal('SIGTERM'));
151
196
 
197
+ // json 模式下静默 Web 启动横幅(stdout 只放结构化启动信息)
198
+ const log = jsonMode ? () => {} : (msg) => process.stderr.write(`${msg}\n`);
199
+
152
200
  try {
153
- // cliType 由环境决定(shell > .env > 默认 opencode),与 CLI 嵌入式一致;
201
+ // 1) Web 前端先监听(后端反代指向本进程后端端口;
202
+ // Web 端口冲突时在后端启动前快速失败)
203
+ webServer = await startWebServer({
204
+ port: webPort,
205
+ backend: `http://127.0.0.1:${serverPort}`,
206
+ webRootFlag: args.webRoot,
207
+ extRootFlags: args.extRoots,
208
+ userExtRoot,
209
+ noExt: args.noExt,
210
+ extNames: args.extNames,
211
+ dataDir,
212
+ open: args.open,
213
+ log,
214
+ tag: '3rdloop serve',
215
+ });
216
+
217
+ // 2) Server HTTP 后端
218
+ // cliType 由环境决定(shell > .env > 默认 deveco-code),与 CLI 嵌入式一致;
154
219
  // dataDir 已通过 3LIB_DATA_DIR env 注入(见上),Server 内部所有默认
155
220
  // createStorage() 均落到用户数据目录;skillDir 沿用包内 vendor 默认
156
221
  // (npm 更新自动获得新 SKILL,不与 CLI 的 3LIB_SKILL_DIR 联动)
157
- const server = await serverModule.createServer({ port: serverPort });
222
+ await serverModule.createServer({ port: serverPort });
158
223
 
159
224
  if (jsonMode) {
160
225
  process.stdout.write(JSON.stringify({
161
226
  ok: true,
162
227
  type: 'server',
163
228
  pid: process.pid,
164
- port: serverPort,
165
- url: `http://127.0.0.1:${serverPort}`,
166
- web: args.web ? { port: webPort, url: `http://localhost:${webPort}` } : null,
229
+ backend: { port: serverPort, url: `http://127.0.0.1:${serverPort}` },
230
+ web: { port: webPort, url: `http://localhost:${webPort}` },
167
231
  }, null, 2) + '\n');
168
232
  } else {
169
- process.stderr.write(`[3rdloop serve] Server HTTP 后端已启动: http://127.0.0.1:${serverPort}\n`);
233
+ process.stderr.write(`[3rdloop serve] Server 后端已启动: http://127.0.0.1:${serverPort}\n`);
170
234
  process.stderr.write(`[3rdloop serve] 通过 Ctrl+C 停止\n`);
171
235
  }
172
236
 
173
- // ── 可选启动 Web 前端(默认不拉起,保持聚焦后端) ──
174
- if (args.web) {
175
- await _startWebFrontend(webPort, serverPort, jsonMode, (child) => { webChild = child; });
176
- }
177
-
178
237
  // 长驻:保持进程存活直到收到信号
179
238
  await new Promise(() => {});
180
239
  return 0;
181
240
  } catch (err) {
182
- process.stderr.write(`3rdloop serve 启动失败: ${err.message}\n`);
241
+ try {
242
+ webServer?.close();
243
+ webServer?.closeAllConnections?.();
244
+ } catch { /* 尽力而为 */ }
245
+ const reason = err?.code === 'EADDRINUSE'
246
+ ? `端口 ${err.port ?? '?'} 已被占用,可用 --port / --web-port 指定其他端口`
247
+ : err.message;
248
+ process.stderr.write(`3rdloop serve 启动失败: ${reason}\n`);
183
249
  return 1;
184
- } finally {
185
- restoreStdout?.();
186
- }
187
- }
188
-
189
- /** 启动 Web 静态前端(反向代理 /api/* → 后端)。 */
190
- async function _startWebFrontend(webPort, serverPort, jsonMode, onChild) {
191
- try {
192
- if (await _isPortOpen(webPort)) {
193
- process.stderr.write(`[3rdloop serve] Web 端口 ${webPort} 已被占用,跳过拉起前端(可直接访问该地址)\n`);
194
- return;
195
- }
196
- } catch { /* 探测失败不阻断 */ }
197
-
198
- const webDir = resolveWebDir();
199
- if (!webDir) {
200
- process.stderr.write('[3rdloop serve] 未找到 Web/ 前端目录,跳过拉起前端\n');
201
- return;
202
- }
203
-
204
- const child = spawn(process.execPath, [
205
- path.join(webDir, 'server.js'),
206
- '--port', String(webPort),
207
- '--backend', `http://127.0.0.1:${serverPort}`,
208
- ], {
209
- stdio: ['ignore', 'pipe', 'pipe'],
210
- shell: false,
211
- detached: false,
212
- });
213
- child.stdout?.on('data', (d) => process.stderr.write(`[web] ${d}`));
214
- child.stderr?.on('data', (d) => process.stderr.write(`[web] ${d}`));
215
- child.on('error', (err) => {
216
- process.stderr.write(`[3rdloop serve] 拉起 Web 前端失败: ${err.message}\n`);
217
- });
218
- onChild(child);
219
- if (!jsonMode) {
220
- process.stderr.write(`[3rdloop serve] Web 前端已启动: http://localhost:${webPort}\n`);
221
250
  }
222
251
  }
223
252
 
@@ -227,54 +256,38 @@ function _envInt(name, def) {
227
256
  return Number.isFinite(n) && n > 0 ? n : def;
228
257
  }
229
258
 
230
- /** 探测端口是否有响应(尽力而为,不阻断)。 */
231
- function _isPortOpen(port, timeoutMs = 1500) {
232
- return new Promise((resolve) => {
233
- const controller = new AbortController();
234
- const timer = setTimeout(() => controller.abort(), timeoutMs);
235
- fetch(`http://127.0.0.1:${port}/`, { signal: controller.signal })
236
- .then(() => resolve(true))
237
- .catch(() => resolve(false))
238
- .finally(() => clearTimeout(timer));
239
- });
240
- }
241
-
242
- /** json 模式下把 Server 内部 console.log/info 重定向到 stderr,返回恢复函数。 */
243
- function _redirectStdoutLogs() {
244
- const safeStringify = (a) => {
245
- try { return JSON.stringify(a); } catch { return String(a); }
246
- };
247
- const toStderr = (args) => {
248
- process.stderr.write(args.map((a) => (typeof a === 'string' ? a : safeStringify(a))).join(' ') + '\n');
249
- };
250
- const origLog = console.log;
251
- const origInfo = console.info;
252
- console.log = (...args) => toStderr(args);
253
- console.info = (...args) => toStderr(args);
254
- return () => {
255
- console.log = origLog;
256
- console.info = origInfo;
257
- };
258
- }
259
-
260
259
  function _printServeHelp() {
261
- process.stdout.write(`3rdloop serve —— 启动 Server HTTP 后端(供前端展示)
260
+ process.stdout.write(`3rdloop serve —— 同时启动 Server HTTP 后端 + Web 前端
262
261
 
263
262
  用法:
264
- 3rdloop serve [--port N] [-w|--web] [--web-port N]
263
+ 3rdloop serve [选项] 启动后端(默认 3000)+ Web 前端(默认 8080)
264
+ 3rdloop serve install-ext <dir> 安装扩展到 ~/.3lib/3rdloop/web-ext/
265
+ 3rdloop serve list-ext 列出可用扩展(含来源与挂载点)
266
+ 3rdloop serve remove-ext <name> 移除已安装扩展
265
267
 
266
268
  选项:
267
- --port N 后端端口(默认 3000,可用 3LIB_SERVER_PORT 覆盖)
268
- -w, --web 同时拉起 Web 前端(默认 8080,可用 --web-port / 3LIB_WEB_PORT 覆盖)
269
- --web-port N Web 前端端口
270
- --json 输出结构化启动信息到 stdout(进度/日志走 stderr)
271
- -h, --help 本帮助
269
+ --port <N> 后端端口(默认 3000,可用 3LIB_SERVER_PORT 覆盖)
270
+ --web-port <N> Web 前端端口(默认 8080,可用 3LIB_WEB_PORT 覆盖)
271
+ --web-root <dir> 核心前端资产目录覆盖(默认: 仓库 Web/public,发布包为内置 cli/web)
272
+ --ext-root <dir> 追加扩展根目录(可多次指定;目录下每个子目录是一个扩展)
273
+ --ext <name,...> 白名单:仅挂载指定扩展(逗号分隔,可重复指定;未发现的名字打警告)
274
+ --no-ext 禁用全部扩展(纯核心工作台模式;优先于 --ext)
275
+ --open 启动后自动打开浏览器
276
+ --json 输出结构化启动信息到 stdout(进度/日志走 stderr)
277
+ -h, --help 本帮助
272
278
 
273
279
  说明:
274
- 默认只启动 Server HTTP 后端(http://127.0.0.1:3000),供 Web 前端 / 脚本反向代理调用。
280
+ Web 前端随 serve 默认启动(原 "3rdloop web" 命令已合并到 serve):
281
+ 静态托管核心工作台 + /api/*、/stream* 反代到后端 + 扩展挂载。
275
282
  CLI 的 run/submit/wait 等命令保持嵌入式模式,不经此后端。
276
- 退出: Ctrl+C / SIGTERM 优雅停止(Windows 下会清理 Web 子进程树)。
283
+ 退出: Ctrl+C / SIGTERM 优雅停止(退出码 130/143)。
284
+
285
+ 环境变量:
286
+ 3LIB_SERVER_PORT 后端端口(等效 --port)
287
+ 3LIB_WEB_PORT Web 前端端口(等效 --web-port)
288
+ 3LIB_WEB_ROOT 核心前端资产目录(等效 --web-root)
289
+ 3LIB_WEB_EXT_ROOT 用户扩展根目录(默认 ~/.3lib/3rdloop/web-ext)
277
290
  `);
278
291
  }
279
292
 
280
- export default cmdServe;
293
+ export default cmdServe;
package/lib/step.js CHANGED
@@ -94,11 +94,22 @@ async function cmdStepRun({ flags, rest, dataDir, skillDir, jsonMode, quiet, ver
94
94
 
95
95
  const specifiedSkill = _stringFlag(flags, 'specified-skill');
96
96
 
97
- // 挂载 opencode 生命周期(复用 runner 语义)
97
+ // ── 环境预检(引擎执行前快速失败:凭据/目录类问题直接退出码 1) ──
98
+ {
99
+ const { precheckEnv, reportPrecheckFailures } = await import('./doctor.js');
100
+ const pre = await precheckEnv({ projectRoot, dataDir, skillDir });
101
+ if (!pre.ok) {
102
+ if (jsonMode) out({ ok: false, error: '环境预检未通过', taskId, failures: pre.failures });
103
+ else reportPrecheckFailures(pre.failures);
104
+ return EXIT.ERROR;
105
+ }
106
+ }
107
+
108
+ // 挂载 AI CLI serve 生命周期(复用 runner 语义,类型由 CLI_TYPE 决定)
98
109
  const r = await _runner();
99
- const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, cliType: 'opencode', verbose });
100
- const { OpencodeManager } = await import('./opencode.js');
101
- const oc = new OpencodeManager({ projectRoot });
110
+ const ctx = r.createRunContext({ projectRoot, dataDir, skillDir, verbose });
111
+ const { CliServeManager } = await import('./opencode.js');
112
+ const oc = new CliServeManager({ projectRoot, cliType: ctx.cliType });
102
113
  const ocHealth = await oc.ensureRunning();
103
114
  if (!ocHealth.ok) {
104
115
  if (jsonMode) out({ ok: false, error: ocHealth.message, taskId });