@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/mcp.js ADDED
@@ -0,0 +1,498 @@
1
+ /**
2
+ * mcp.js —— 3rdloop mcp:MCP Gateway 一键装配(install / uninstall / status)
3
+ *
4
+ * 背景:npm 包内 vendor/ 携带 MCP Gateway(vendor/MCP)、知识库检索引擎
5
+ * (vendor/Archive)、已知问题知识库种子(vendor/BadCase),但 AI CLI
6
+ * (opencode / deveco-code)需要在其**全局配置**里注册 mcp-gateway 才会在
7
+ * serve 启动时 spawn Gateway。本命令完成装配:
8
+ *
9
+ * 3rdloop mcp install [--cli opencode|deveco|all] [--force]
10
+ * ① 生成用户级 Gateway 配置 ~/.3lib/3rdloop/mcp/config.json
11
+ * - scriptsDir / enginePath → 包内(vendor,随包更新获得新脚本/引擎)
12
+ * - knowledgeBase.dataDir → ~/.3lib/3rdloop/kb-data(用户数据,跨版本不丢)
13
+ * ② 种子复制:kb-data(← vendor/Archive/data)、BadCase 副本
14
+ * (← vendor/BadCase,泛化 SKILL 的可写知识库)
15
+ * ③ 注册 mcp-gateway 到 ~/.config/opencode/opencode.json 与
16
+ * ~/.config/deveco/deveco.jsonc(保留其他字段,幂等可重跑)
17
+ *
18
+ * 3rdloop mcp uninstall [--cli ...] 仅移除注册条目(用户数据保留)
19
+ * 3rdloop mcp status 查看注册状态与路径
20
+ *
21
+ * 设计约束:
22
+ * - 仓库开发态(npm link,无 vendor/)自动回退仓库 MCP/、Archive/、BadCase/
23
+ * - 用户已有 ~/.3lib/3rdloop/mcp/config.json 时仅刷新路径字段,
24
+ * 保留 downstreamServers 等用户改动(--force 重置为包内默认)
25
+ * - deveco.jsonc 为 JSONC:容错解析(去注释重试),解析失败提示手动配置
26
+ */
27
+
28
+ import fs from 'node:fs';
29
+ import path from 'node:path';
30
+ import { fileURLToPath } from 'node:url';
31
+ import process from 'node:process';
32
+ import { resolveCliType } from './config.js';
33
+
34
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
35
+ export const CLI_ROOT = path.resolve(moduleDir, '..');
36
+
37
+ /** 注册到 AI CLI 全局配置的条目名(与既有生态约定一致) */
38
+ export const MCP_ENTRY_NAME = 'mcp-gateway';
39
+
40
+ /** AI CLI 全局配置文件位置(按平台) */
41
+ function aiCliConfigPaths() {
42
+ const home = process.env['HOME'] || process.env['USERPROFILE'] || '';
43
+ const configRoot = process.env['XDG_CONFIG_HOME'] || path.join(home, '.config');
44
+ return {
45
+ opencode: path.join(configRoot, 'opencode', 'opencode.json'),
46
+ 'deveco-code': path.join(configRoot, 'deveco', 'deveco.jsonc'),
47
+ };
48
+ }
49
+
50
+ // ─── 包内资产定位(vendor 优先,仓库开发态回退)────────────────────────
51
+
52
+ let _assetsCache = null;
53
+
54
+ /**
55
+ * 定位 MCP / Archive / BadCase 资产目录。
56
+ * @returns {{ mcpDir: string, archiveDir: string, badcaseDir: string, mode: 'vendor'|'repo' }}
57
+ * @throws {Error} vendor 与仓库路径均不存在
58
+ */
59
+ export function resolveAssets() {
60
+ if (_assetsCache) return _assetsCache;
61
+
62
+ const vendorDir = path.join(CLI_ROOT, 'vendor');
63
+ const repoRoot = path.resolve(CLI_ROOT, '..');
64
+
65
+ const tryDirs = [
66
+ { root: vendorDir, mode: 'vendor' },
67
+ { root: repoRoot, mode: 'repo' },
68
+ ];
69
+ for (const { root, mode } of tryDirs) {
70
+ const mcpDir = path.join(root, 'MCP');
71
+ if (fs.existsSync(path.join(mcpDir, 'src', 'index.js'))) {
72
+ _assetsCache = {
73
+ mcpDir,
74
+ archiveDir: path.join(root, 'Archive'),
75
+ badcaseDir: path.join(root, 'BadCase'),
76
+ mode,
77
+ };
78
+ return _assetsCache;
79
+ }
80
+ }
81
+ throw new Error(
82
+ `无法定位 MCP Gateway:期望 cli/vendor/MCP 或仓库 MCP/。` +
83
+ `npm 安装态请重装包(npm i -g @ohos-cpf/3rdloop),仓库态请在 cli/ 上一级执行`
84
+ );
85
+ }
86
+
87
+ // ─── 用户级路径 ────────────────────────────────────────────────────────
88
+
89
+ /**
90
+ * 用户级路径集合(kb 数据 / BadCase 副本 / Gateway 配置)。
91
+ * @param {string} user3libHome - ~/.3lib
92
+ */
93
+ export function userPaths(user3libHome) {
94
+ const loopHome = path.join(user3libHome, '3rdloop');
95
+ return {
96
+ loopHome,
97
+ mcpConfigDir: path.join(loopHome, 'mcp'),
98
+ mcpConfig: path.join(loopHome, 'mcp', 'config.json'),
99
+ kbDataDir: path.join(loopHome, 'kb-data'),
100
+ badcaseDir: path.join(loopHome, 'BadCase'),
101
+ };
102
+ }
103
+
104
+ // ─── 工具函数 ─────────────────────────────────────────────────────────
105
+
106
+ /** 递归复制目录(跳过 node_modules)。 */
107
+ function copyDir(src, dst) {
108
+ fs.mkdirSync(dst, { recursive: true });
109
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
110
+ if (entry.name === 'node_modules' || entry.name === '.git') continue;
111
+ const s = path.join(src, entry.name);
112
+ const d = path.join(dst, entry.name);
113
+ if (entry.isDirectory()) copyDir(s, d);
114
+ else fs.copyFileSync(s, d);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * 容错读取 JSON / JSONC 配置(带 // 与 /* 注释剥离重试)。
120
+ * @returns {{ ok: boolean, data: object|null, raw: string, error?: string }}
121
+ */
122
+ function readJsonc(file) {
123
+ let raw = '';
124
+ try {
125
+ raw = fs.readFileSync(file, 'utf8');
126
+ } catch (err) {
127
+ return { ok: false, data: null, raw: '', error: err.message };
128
+ }
129
+ try {
130
+ return { ok: true, data: JSON.parse(raw), raw };
131
+ } catch { /* 尝试剥注释 */ }
132
+ const stripped = raw
133
+ .replace(/\/\*[\s\S]*?\*\//g, '')
134
+ .replace(/(^|[^:"'\\])\/\/.*$/gm, '$1');
135
+ try {
136
+ return { ok: true, data: JSON.parse(stripped), raw };
137
+ } catch (err) {
138
+ return { ok: false, data: null, raw, error: `JSONC 解析失败: ${err.message}` };
139
+ }
140
+ }
141
+
142
+ /** 合并写入 AI CLI 全局配置的 mcp.mcp-gateway 条目(保留其他字段)。 */
143
+ function upsertMcpEntry(file, entry, { createIfMissing = true } = {}) {
144
+ const existed = fs.existsSync(file);
145
+ if (!existed && !createIfMissing) return { ok: true, skipped: true };
146
+
147
+ const parsed = existed ? readJsonc(file) : { ok: true, data: {} };
148
+ if (!parsed.ok) {
149
+ return { ok: false, error: `${file} ${parsed.error}(可手动编辑,或删除该文件后重跑 3rdloop mcp install)` };
150
+ }
151
+ const data = parsed.data || {};
152
+ if (!data.mcp || typeof data.mcp !== 'object') data.mcp = {};
153
+ data.mcp[MCP_ENTRY_NAME] = entry;
154
+
155
+ fs.mkdirSync(path.dirname(file), { recursive: true });
156
+ fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n');
157
+ return { ok: true, skipped: false, existed };
158
+ }
159
+
160
+ /** 从 AI CLI 全局配置移除 mcp.mcp-gateway 条目(文件不存在视为成功)。 */
161
+ function removeMcpEntry(file) {
162
+ if (!fs.existsSync(file)) return { ok: true, removed: false };
163
+ const parsed = readJsonc(file);
164
+ if (!parsed.ok) {
165
+ return { ok: false, error: `${file} ${parsed.error}(请手动删除其中的 "${MCP_ENTRY_NAME}" 条目)` };
166
+ }
167
+ const data = parsed.data || {};
168
+ let removed = false;
169
+ if (data.mcp && typeof data.mcp === 'object' && MCP_ENTRY_NAME in data.mcp) {
170
+ delete data.mcp[MCP_ENTRY_NAME];
171
+ removed = true;
172
+ fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n');
173
+ }
174
+ return { ok: true, removed };
175
+ }
176
+
177
+ /** 读取某 AI CLI 配置中 mcp-gateway 的注册状态。 */
178
+ function readMcpEntry(file) {
179
+ if (!fs.existsSync(file)) return { state: 'missing-file' };
180
+ const parsed = readJsonc(file);
181
+ if (!parsed.ok) return { state: 'parse-error', error: parsed.error };
182
+ const entry = parsed.data?.mcp?.[MCP_ENTRY_NAME];
183
+ if (!entry) return { state: 'missing-entry' };
184
+ return { state: 'registered', entry };
185
+ }
186
+
187
+ // ─── install ──────────────────────────────────────────────────────────
188
+
189
+ /**
190
+ * 生成/刷新用户级 Gateway 配置。
191
+ * 已存在时仅刷新 scriptsDir/enginePath/gateway/scripts 策略(保留 downstreamServers
192
+ * 与用户自定义 dataDir),force 时以包内 config 为模板重置。
193
+ */
194
+ function writeUserMcpConfig({ userMcpConfig, templateConfig, assets, kbDataDir, force }) {
195
+ const existed = fs.existsSync(userMcpConfig);
196
+ const current = existed ? readJsonc(userMcpConfig) : null;
197
+ if (existed && !current.ok) {
198
+ return { ok: false, error: `${userMcpConfig} ${current.error}(可 --force 覆盖或手动修复)` };
199
+ }
200
+
201
+ const tmplKb = templateConfig.knowledgeBase || {};
202
+ const curKb = (!force && existed && current.data?.knowledgeBase) || null;
203
+
204
+ let cfg;
205
+ if (curKb) {
206
+ // 刷新模式:以现有用户配置为基底
207
+ cfg = current.data;
208
+ cfg.scripts = { ...(templateConfig.scripts || {}), ...(cfg.scripts || {}) };
209
+ cfg.gateway = cfg.gateway || templateConfig.gateway;
210
+ } else {
211
+ // 首次 / --force:以包内模板为基底(深拷贝,含 scripts 策略/downstreamServers)
212
+ cfg = JSON.parse(JSON.stringify(templateConfig));
213
+ }
214
+ if (force) {
215
+ cfg.downstreamServers = templateConfig.downstreamServers || {};
216
+ cfg.gateway = templateConfig.gateway || cfg.gateway;
217
+ cfg.scripts = { ...(templateConfig.scripts || {}) };
218
+ }
219
+
220
+ // dataDir:仅当用户改过(≠ 模板默认相对值)才保留,否则统一指向用户 kb-data
221
+ const userSetDataDir = curKb && curKb.dataDir && curKb.dataDir !== tmplKb.dataDir
222
+ ? curKb.dataDir : null;
223
+ const finalDataDir = userSetDataDir || kbDataDir;
224
+
225
+ // 路径字段始终刷新为当前安装位置(包更新后路径不变,幂等无害)
226
+ cfg.scriptsDir = path.join(assets.mcpDir, 'scripts');
227
+ cfg.knowledgeBase = {
228
+ ...tmplKb,
229
+ ...(curKb || {}),
230
+ enabled: (curKb?.enabled) ?? tmplKb.enabled ?? true,
231
+ enginePath: path.join(assets.archiveDir, 'src', 'index.js'),
232
+ dataDir: finalDataDir,
233
+ };
234
+
235
+ fs.mkdirSync(path.dirname(userMcpConfig), { recursive: true });
236
+ fs.writeFileSync(userMcpConfig, JSON.stringify(cfg, null, 2) + '\n');
237
+ return { ok: true, existed, config: cfg };
238
+ }
239
+
240
+ /**
241
+ * 3rdloop mcp install 实现。
242
+ * @param {object} opts
243
+ * @param {string} opts.user3libHome - ~/.3lib
244
+ * @param {string[]} opts.rest - 命令参数(--cli / --force)
245
+ * @param {boolean} opts.jsonMode
246
+ * @returns {Promise<number>} 退出码
247
+ */
248
+ export async function mcpInstall({ user3libHome, rest = [], jsonMode = false }) {
249
+ const cliFilter = _parseCliFilter(rest); // 'all' | 'opencode' | 'deveco-code'
250
+ const force = rest.includes('--force');
251
+ const out = (data) => { if (jsonMode) process.stdout.write(JSON.stringify(data, null, 2) + '\n'); };
252
+ const log = (msg) => process.stderr.write(`${msg}\n`);
253
+
254
+ const assets = resolveAssets();
255
+ const up = userPaths(user3libHome);
256
+
257
+ // ① 包内模板 config(downstreamServers / gateway / 脚本策略)
258
+ const templateFile = path.join(assets.mcpDir, 'config.json');
259
+ if (!fs.existsSync(templateFile)) {
260
+ log(`错误: 未找到 Gateway 配置模板: ${templateFile}`);
261
+ return 1;
262
+ }
263
+ const templateConfig = JSON.parse(fs.readFileSync(templateFile, 'utf8'));
264
+
265
+ // ② 用户级 Gateway 配置
266
+ const writeResult = writeUserMcpConfig({
267
+ userMcpConfig: up.mcpConfig,
268
+ templateConfig,
269
+ assets,
270
+ kbDataDir: up.kbDataDir,
271
+ force,
272
+ });
273
+ if (!writeResult.ok) {
274
+ log(`错误: ${writeResult.error}`);
275
+ return 1;
276
+ }
277
+
278
+ // ③ 种子数据(目录已存在则跳过,保用户数据)
279
+ const seeds = [
280
+ { src: path.join(assets.archiveDir, 'data'), dst: up.kbDataDir, label: '知识库数据' },
281
+ { src: assets.badcaseDir, dst: up.badcaseDir, label: 'BadCase 已知问题知识库' },
282
+ ];
283
+ const seeded = [];
284
+ for (const { src, dst, label } of seeds) {
285
+ if (fs.existsSync(dst)) continue;
286
+ if (!fs.existsSync(src)) continue; // 仓库缺该资产时跳过(prepack 有警告)
287
+ copyDir(src, dst);
288
+ seeded.push({ label, dst });
289
+ }
290
+
291
+ // ④ 注册到 AI CLI 全局配置
292
+ const entry = {
293
+ command: ['node', path.join(assets.mcpDir, 'src', 'index.js'), '--config', up.mcpConfig],
294
+ enabled: true,
295
+ type: 'local',
296
+ };
297
+ const targets = cliFilter === 'all'
298
+ ? Object.keys(aiCliConfigPaths())
299
+ : [cliFilter];
300
+ const registered = [];
301
+ const failures = [];
302
+ for (const cliType of targets) {
303
+ const file = aiCliConfigPaths()[cliType];
304
+ const res = upsertMcpEntry(file, entry);
305
+ if (!res.ok) failures.push(res.error);
306
+ else registered.push({ cliType, file, existed: !!res.existed });
307
+ }
308
+ if (failures.length > 0) {
309
+ for (const f of failures) log(`错误: ${f}`);
310
+ return 1;
311
+ }
312
+
313
+ if (jsonMode) {
314
+ out({
315
+ ok: true,
316
+ mode: assets.mode,
317
+ userConfig: up.mcpConfig,
318
+ kbDataDir: up.kbDataDir,
319
+ badcaseDir: up.badcaseDir,
320
+ seeded,
321
+ registered,
322
+ });
323
+ } else {
324
+ log(`[3rdloop mcp] Gateway 来源: ${assets.mode === 'vendor' ? '包内 vendor/MCP' : '仓库 MCP/'}`);
325
+ log(`[3rdloop mcp] 用户配置: ${up.mcpConfig}${writeResult.existed && !force ? '(已存在,仅刷新路径)' : ''}`);
326
+ log(`[3rdloop mcp] 知识库数据目录: ${up.kbDataDir}`);
327
+ log(`[3rdloop mcp] BadCase 副本: ${up.badcaseDir}`);
328
+ for (const s of seeded) log(`[3rdloop mcp] 已种子复制 ${s.label} → ${s.dst}`);
329
+ for (const r of registered) {
330
+ log(`[3rdloop mcp] 已注册 ${MCP_ENTRY_NAME} → ${r.file}${r.existed ? '(覆盖旧条目)' : ''}`);
331
+ }
332
+ log(`[3rdloop mcp] 完成。重启 ${targets.join(' / ')} serve 后 AI 会话即可使用 MCP 工具`);
333
+ }
334
+ return 0;
335
+ }
336
+
337
+ // ─── uninstall / status ───────────────────────────────────────────────
338
+
339
+ export async function mcpUninstall({ rest = [], jsonMode = false }) {
340
+ const cliFilter = _parseCliFilter(rest);
341
+ const out = (data) => { if (jsonMode) process.stdout.write(JSON.stringify(data, null, 2) + '\n'); };
342
+ const log = (msg) => process.stderr.write(`${msg}\n`);
343
+
344
+ const targets = cliFilter === 'all' ? Object.keys(aiCliConfigPaths()) : [cliFilter];
345
+ const removed = [];
346
+ const failures = [];
347
+ for (const cliType of targets) {
348
+ const file = aiCliConfigPaths()[cliType];
349
+ const res = removeMcpEntry(file);
350
+ if (!res.ok) failures.push(res.error);
351
+ else if (res.removed) removed.push({ cliType, file });
352
+ }
353
+ if (failures.length > 0) {
354
+ for (const f of failures) log(`错误: ${f}`);
355
+ return 1;
356
+ }
357
+ if (jsonMode) out({ ok: true, removed });
358
+ else if (removed.length === 0) log('[3rdloop mcp] 未发现已注册的条目,无需卸载');
359
+ else for (const r of removed) log(`[3rdloop mcp] 已移除 ${MCP_ENTRY_NAME} → ${r.file}`);
360
+ log('[3rdloop mcp] 用户数据(kb-data / BadCase / config)已保留,可随时重新 install');
361
+ return 0;
362
+ }
363
+
364
+ export async function mcpStatus({ user3libHome, jsonMode = false }) {
365
+ const out = (data) => { if (jsonMode) process.stdout.write(JSON.stringify(data, null, 2) + '\n'); };
366
+ const log = (msg) => process.stderr.write(`${msg}\n`);
367
+
368
+ let assets;
369
+ try {
370
+ assets = resolveAssets();
371
+ } catch (err) {
372
+ if (jsonMode) out({ ok: false, error: err.message });
373
+ else log(`错误: ${err.message}`);
374
+ return 1;
375
+ }
376
+ const up = userPaths(user3libHome);
377
+
378
+ const registrations = {};
379
+ for (const [cliType, file] of Object.entries(aiCliConfigPaths())) {
380
+ const st = readMcpEntry(file);
381
+ registrations[cliType] = { file, state: st.state, entry: st.entry || null };
382
+ }
383
+
384
+ const result = {
385
+ ok: true,
386
+ mode: assets.mode,
387
+ gateway: path.join(assets.mcpDir, 'src', 'index.js'),
388
+ userConfig: up.mcpConfig,
389
+ userConfigExists: fs.existsSync(up.mcpConfig),
390
+ kbDataDir: up.kbDataDir,
391
+ kbDataSeeded: fs.existsSync(up.kbDataDir),
392
+ badcaseDir: up.badcaseDir,
393
+ badcaseSeeded: fs.existsSync(up.badcaseDir),
394
+ registrations,
395
+ };
396
+
397
+ if (jsonMode) {
398
+ out(result);
399
+ } else {
400
+ log(`Gateway 来源: ${assets.mode === 'vendor' ? '包内 vendor/MCP' : '仓库 MCP/'}(${result.gateway})`);
401
+ log(`用户配置: ${up.mcpConfig}${result.userConfigExists ? '' : '(未生成,先 3rdloop mcp install)'}`);
402
+ log(`知识库数据: ${up.kbDataDir}${result.kbDataSeeded ? '' : '(未初始化)'}`);
403
+ log(`BadCase 副本: ${up.badcaseDir}${result.badcaseSeeded ? '' : '(未初始化)'}`);
404
+ for (const [cliType, r] of Object.entries(registrations)) {
405
+ const icon = r.state === 'registered' ? '✓' : '✗';
406
+ const detail = r.state === 'registered'
407
+ ? `已注册 (${r.file})`
408
+ : r.state === 'missing-file' ? `未注册(配置文件不存在: ${r.file})`
409
+ : r.state === 'missing-entry' ? `未注册(${r.file} 无 ${MCP_ENTRY_NAME} 条目)`
410
+ : `解析失败: ${r.file}`;
411
+ log(`${icon} ${cliType}: ${detail}`);
412
+ }
413
+ const anyRegistered = Object.values(registrations).some(r => r.state === 'registered');
414
+ if (!anyRegistered) log('提示: 执行 3rdloop mcp install 完成装配');
415
+ }
416
+ return 0;
417
+ }
418
+
419
+ // ─── 命令入口 ─────────────────────────────────────────────────────────
420
+
421
+ /**
422
+ * 3rdloop mcp 命令入口(子命令分发)。
423
+ * @param {object} opts
424
+ * @param {string[]} opts.rest - flags.rest(含子命令与参数)
425
+ * @param {string} opts.user3libHome - ~/.3lib
426
+ * @param {boolean} opts.jsonMode
427
+ * @returns {Promise<number>} 退出码
428
+ */
429
+ export async function cmdMcp({ rest = [], user3libHome = '', jsonMode = false }) {
430
+ if (rest.includes('--help') || rest.includes('-h')) {
431
+ printMcpHelp();
432
+ return 0;
433
+ }
434
+
435
+ // 位置子命令 = 第一个非 flag 参数(--cli 的值跳过)
436
+ let subcommand = null;
437
+ for (let i = 0; i < rest.length; i++) {
438
+ if (rest[i] === '--cli') { i++; continue; }
439
+ if (rest[i].startsWith('--')) continue;
440
+ subcommand = rest[i];
441
+ break;
442
+ }
443
+
444
+ try {
445
+ if (subcommand === 'install') return await mcpInstall({ user3libHome, rest, jsonMode });
446
+ if (subcommand === 'uninstall') return await mcpUninstall({ rest, jsonMode });
447
+ if (subcommand === 'status') return await mcpStatus({ user3libHome, jsonMode });
448
+ if (subcommand === null && rest.length === 0) {
449
+ printMcpHelp();
450
+ return 0;
451
+ }
452
+ if (subcommand !== null) {
453
+ process.stderr.write(`未知子命令: ${subcommand}\n`);
454
+ } else {
455
+ process.stderr.write(`未知参数: ${rest.join(' ')}\n`);
456
+ }
457
+ printMcpHelp();
458
+ return 1;
459
+ } catch (err) {
460
+ process.stderr.write(`错误: ${err.message}\n`);
461
+ return 1;
462
+ }
463
+ }
464
+
465
+ // ─── 帮助 / 参数 ──────────────────────────────────────────────────────
466
+
467
+ function _parseCliFilter(rest) {
468
+ const idx = rest.indexOf('--cli');
469
+ const raw = idx !== -1 ? rest[idx + 1] : undefined;
470
+ if (!raw || raw === 'all') return 'all';
471
+ if (raw === 'opencode') return 'opencode';
472
+ if (raw === 'deveco' || raw === 'deveco-code') return 'deveco-code';
473
+ throw new Error(`非法 --cli 值: "${raw}"(可选: opencode | deveco | all)`);
474
+ }
475
+
476
+ export function printMcpHelp() {
477
+ process.stdout.write(`3rdloop mcp —— MCP Gateway 装配(npm 安装态必需,仓库开发态可选)
478
+
479
+ 用法:
480
+ 3rdloop mcp install [--cli opencode|deveco|all] [--force]
481
+ ① 生成用户级 Gateway 配置 ~/.3lib/3rdloop/mcp/config.json
482
+ (scriptsDir/enginePath 指向包内 vendor,kb 数据落在 ~/.3lib/3rdloop/kb-data)
483
+ ② 种子复制知识库数据(kb-data)与 BadCase 已知问题知识库到用户目录
484
+ ③ 注册 mcp-gateway 到 opencode / deveco 全局配置(幂等,可重跑)
485
+ --force 重置用户级配置为包内默认(downstreamServers 等)
486
+ 3rdloop mcp uninstall [--cli opencode|deveco|all]
487
+ 仅移除注册条目;用户数据(kb-data / BadCase / config)保留
488
+ 3rdloop mcp status
489
+ 查看注册状态、用户配置与数据目录
490
+
491
+ 说明:
492
+ - opencode/deveco serve 启动时会按全局配置自动 spawn MCP Gateway,
493
+ AI 会话即可调用 kb 搜索、覆盖率分析脚本等工具
494
+ - 安装/更新 npm 包后路径不变,注册条目持续有效;包更新后新脚本
495
+ 自动可用(scriptsDir 随包)
496
+ - 默认注册到 opencode 与 deveco 两处(--cli 可限定)
497
+ `);
498
+ }