@ohos-cpf/3rdloop 0.0.8 → 0.0.10

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 (220) hide show
  1. package/README.md +43 -0
  2. package/lib/cli.js +38 -5
  3. package/lib/doctor.js +111 -10
  4. package/lib/knowledge.js +440 -0
  5. package/lib/mcp.js +498 -0
  6. package/package.json +6 -2
  7. package/vendor/Archive/data/.index/meta.json +7 -0
  8. package/vendor/Archive/data/.index/search.db +0 -0
  9. package/vendor/Archive/data/docs/experiences/arkts-check-tool-pitfalls-baseline-comparison.md +13 -0
  10. package/vendor/Archive/data/docs/experiences/arkts-deep-path-import-recognition.md +31 -0
  11. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-entry-file-case-mismatch.md +25 -0
  12. package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-import-trailing-slash.md +20 -0
  13. package/vendor/Archive/data/docs/experiences/arkts-library-source-files-may-be-ts.md +18 -0
  14. package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md +36 -0
  15. package/vendor/Archive/data/docs/experiences/arkts-xts-compile-error-clustering-fix.md +24 -0
  16. package/vendor/Archive/data/docs/experiences/arkts-xts-doc-expected-value-runtime-probe.md +35 -0
  17. package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md +33 -0
  18. package/vendor/Archive/data/docs/experiences/code-linter-chinese-comment-false-positive.md +16 -0
  19. package/vendor/Archive/data/docs/experiences/esobject-new-expression-variable-tracking.md +33 -0
  20. package/vendor/Archive/data/docs/experiences/filesystem-case-sensitivity-module-resolution.md +31 -0
  21. package/vendor/Archive/data/docs/experiences/gitcode-clone-redirect-warning-normal.md +13 -0
  22. package/vendor/Archive/data/docs/experiences/kn_msgvq1w585ec8319.md +77 -0
  23. package/vendor/Archive/data/docs/experiences/kn_msovnm6rd46de72c.md +98 -0
  24. package/vendor/Archive/data/docs/experiences/kn_mspt8vntfe708576.md +87 -0
  25. package/vendor/Archive/data/docs/experiences/kn_mspu1ei77adbbb48.md +133 -0
  26. package/vendor/Archive/data/docs/experiences/kn_mspubgak8d30bfce.md +128 -0
  27. package/vendor/Archive/data/docs/experiences/kn_mspug2de3cb1f7c3.md +115 -0
  28. package/vendor/Archive/data/docs/experiences/kn_skill_opt_001.md +38 -0
  29. package/vendor/Archive/data/docs/experiences/loop-artifacts-verification-evidence-triangle.md +19 -0
  30. package/vendor/Archive/data/docs/experiences/macos-bash-replace-build-ps1.md +19 -0
  31. package/vendor/Archive/data/docs/experiences/macos-bsd-diff-q-illegal-option.md +15 -0
  32. package/vendor/Archive/data/docs/experiences/migrate-cjs-compatible-api-version-map-limit.md +17 -0
  33. package/vendor/Archive/data/docs/experiences/mp3agic-arkts-library-behavior-quirks.md +21 -0
  34. package/vendor/Archive/data/docs/experiences/ohos-face-detection-scan-api-mapping.md +15 -0
  35. package/vendor/Archive/data/docs/experiences/pr-metadata-and-diff-integrity-verification.md +12 -0
  36. package/vendor/Archive/data/docs/experiences/rn-coverage-index-signature-pseudo-member-false-negative.md +32 -0
  37. package/vendor/Archive/data/docs/experiences/rn-memory-check-severity-calibration.md +21 -0
  38. package/vendor/Archive/data/docs/experiences/rn-platform-specific-api-exclusion-evidence.md +24 -0
  39. package/vendor/Archive/data/docs/experiences/rn-upstream-version-diff-pitfalls.md +17 -0
  40. package/vendor/Archive/data/docs/experiences/rn-version-gap-risk-rating-rules.md +13 -0
  41. package/vendor/Archive/data/docs/experiences/rn-view-lib-native-contract-diff-fabric-spec.md +16 -0
  42. package/vendor/Archive/data/docs/experiences/rnoh-adapter-package-version-field-semantics.md +18 -0
  43. package/vendor/Archive/data/docs/experiences/rnoh-arkts-sqlite-rows-array-format.md +18 -0
  44. package/vendor/Archive/data/docs/experiences/rnoh-dependency-residue-scan-strategy.md +18 -0
  45. package/vendor/Archive/data/docs/experiences/rnoh-example-local-lib-dep-use-tgz.md +53 -0
  46. package/vendor/Archive/data/docs/experiences/rnoh-example-prereserve-rntesterlist.md +17 -0
  47. package/vendor/Archive/data/docs/experiences/rnoh-example-template-compatiblesdkversion-upgrade.md +29 -0
  48. package/vendor/Archive/data/docs/experiences/rnoh-example-turbomodule-shell-adaptation-checklist.md +41 -0
  49. package/vendor/Archive/data/docs/experiences/rnoh-mcp-build-project-tool-risk.md +18 -0
  50. package/vendor/Archive/data/docs/experiences/rnoh-npm-devdependencies-version-precheck.md +29 -0
  51. package/vendor/Archive/data/docs/experiences/rnoh-repo-baseline-version-verification.md +13 -0
  52. package/vendor/Archive/data/docs/experiences/rnoh-repo-upstream-directory-mapping.md +18 -0
  53. package/vendor/Archive/data/docs/experiences/rnoh-stateless-library-zero-leak-verification.md +31 -0
  54. package/vendor/Archive/data/docs/experiences/rnoh-template-npmrc-credential-removal.md +15 -0
  55. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-codegen-wiring-verification.md +19 -0
  56. package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-cpp-methodmap-compatibility-check.md +20 -0
  57. package/vendor/Archive/data/docs/experiences/scenario-doc-vs-source-signature-diff-four-patterns.md +24 -0
  58. package/vendor/Archive/data/docs/experiences/static-analysis-grep-cross-validation.md +29 -0
  59. package/vendor/Archive/demo.js +489 -0
  60. package/vendor/Archive/index.js +43 -0
  61. package/vendor/Archive/package.json +16 -0
  62. package/vendor/Archive/src/constants.js +83 -0
  63. package/vendor/Archive/src/data/stopwords.txt +110 -0
  64. package/vendor/Archive/src/data/synonyms.json +25 -0
  65. package/vendor/Archive/src/data/terms.txt +59 -0
  66. package/vendor/Archive/src/db/sqlite-backend.js +312 -0
  67. package/vendor/Archive/src/db/sqlite-schema.js +64 -0
  68. package/vendor/Archive/src/engine.js +501 -0
  69. package/vendor/Archive/src/index/index-manager.js +203 -0
  70. package/vendor/Archive/src/index/index-state.js +94 -0
  71. package/vendor/Archive/src/index/search-text-builder.js +106 -0
  72. package/vendor/Archive/src/index.js +22 -0
  73. package/vendor/Archive/src/parser/api-identifiers.js +121 -0
  74. package/vendor/Archive/src/parser/api-suffixes.js +48 -0
  75. package/vendor/Archive/src/parser/heading-normalize.js +40 -0
  76. package/vendor/Archive/src/parser/markdown-splitter.js +215 -0
  77. package/vendor/Archive/src/search/catalog-routing.js +87 -0
  78. package/vendor/Archive/src/search/fts-search.js +289 -0
  79. package/vendor/Archive/src/search/query-normalizer.js +159 -0
  80. package/vendor/Archive/src/search/query-rewriter.js +72 -0
  81. package/vendor/Archive/src/search/search-engine.js +72 -0
  82. package/vendor/Archive/src/search/snippet.js +64 -0
  83. package/vendor/Archive/src/store/dir-store.js +103 -0
  84. package/vendor/Archive/src/store/doc-store.js +36 -0
  85. package/vendor/Archive/src/tokenizer/lexicon.js +151 -0
  86. package/vendor/Archive/src/tokenizer/tokenizer.js +167 -0
  87. package/vendor/Archive/src/types.js +86 -0
  88. package/vendor/Archive/src/utils/hash.js +16 -0
  89. package/vendor/Archive/src/utils/lock.js +73 -0
  90. package/vendor/Archive/src/utils/path-safety.js +96 -0
  91. package/vendor/Archive/src/utils/paths.js +39 -0
  92. package/vendor/BadCase/rn/INDEX.md +127 -0
  93. 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
  94. 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
  95. 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
  96. package/vendor/BadCase/rn/cases/KI-004-wechat/345/233/236/350/260/203/346/227/266/345/272/217.md +47 -0
  97. 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
  98. 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
  99. 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
  100. 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
  101. package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md +38 -0
  102. package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md +48 -0
  103. 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
  104. package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md +59 -0
  105. 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
  106. package/vendor/BadCase/rn/cases/KI-014-amap-geolocation/345/233/236/350/260/203/347/274/272/345/244/261.md +42 -0
  107. 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
  108. 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
  109. 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
  110. package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md +53 -0
  111. 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
  112. 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
  113. 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
  114. 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
  115. 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
  116. package/vendor/BadCase/rn/generalization-log.md +55 -0
  117. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.json +328 -0
  118. package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.md +382 -0
  119. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.json +1351 -0
  120. package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.md +1176 -0
  121. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.json +538 -0
  122. package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.md +1488 -0
  123. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.json +211 -0
  124. package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.md +35 -0
  125. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.json +2048 -0
  126. package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.md +3866 -0
  127. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.json +198 -0
  128. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.md +40 -0
  129. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.json +751 -0
  130. package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.md +883 -0
  131. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.json +1544 -0
  132. package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.md +2598 -0
  133. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.json +246 -0
  134. package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.md +554 -0
  135. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.json +211 -0
  136. package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.md +54 -0
  137. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.json +1626 -0
  138. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.md +2213 -0
  139. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.json +208 -0
  140. package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.md +77 -0
  141. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.json +377 -0
  142. package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.md +174 -0
  143. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.json +232 -0
  144. package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.md +194 -0
  145. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.json +198 -0
  146. package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.md +67 -0
  147. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.json +198 -0
  148. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.md +38 -0
  149. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.json +208 -0
  150. package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.md +34 -0
  151. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.json +222 -0
  152. package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.md +56 -0
  153. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.json +463 -0
  154. package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.md +383 -0
  155. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.json +464 -0
  156. package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.md +565 -0
  157. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.json +198 -0
  158. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.md +47 -0
  159. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.json +232 -0
  160. package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.md +422 -0
  161. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.json +295 -0
  162. package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.md +1038 -0
  163. 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
  164. 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
  165. 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
  166. 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
  167. 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
  168. 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
  169. 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
  170. 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
  171. 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
  172. 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
  173. 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
  174. 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
  175. 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
  176. 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
  177. 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
  178. 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
  179. 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
  180. 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
  181. 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
  182. package/vendor/MCP/README.md +490 -0
  183. package/vendor/MCP/config.json +29 -0
  184. package/vendor/MCP/package.json +23 -0
  185. package/vendor/MCP/scripts/analyze-demo-coverage.cjs +1203 -0
  186. package/vendor/MCP/scripts/analyze-xts-coverage.cjs +1245 -0
  187. package/vendor/MCP/scripts/deveco_docs.js +247 -0
  188. package/vendor/MCP/scripts/extract-interfaces.cjs +1487 -0
  189. package/vendor/MCP/scripts/flutter-analyze-demo-coverage.cjs +666 -0
  190. package/vendor/MCP/scripts/flutter-analyze-xts-coverage.cjs +684 -0
  191. package/vendor/MCP/scripts/flutter-extract-interfaces.cjs +1251 -0
  192. package/vendor/MCP/scripts/flutter-render-spec-doc.cjs +351 -0
  193. package/vendor/MCP/scripts/render-spec-doc.cjs +347 -0
  194. package/vendor/MCP/scripts/rn-analyze-demo-coverage.cjs +645 -0
  195. package/vendor/MCP/scripts/rn-analyze-test-coverage.cjs +614 -0
  196. package/vendor/MCP/scripts/rn-extract-interfaces.cjs +1462 -0
  197. package/vendor/MCP/scripts/rn-render-spec-doc.cjs +327 -0
  198. package/vendor/MCP/scripts/rn-scan-exports.cjs +1336 -0
  199. package/vendor/MCP/src/client/MCPClientPool.js +220 -0
  200. package/vendor/MCP/src/config/ConfigLoader.js +189 -0
  201. package/vendor/MCP/src/executor/ScriptExecutor.js +110 -0
  202. package/vendor/MCP/src/gateway/Gateway.js +451 -0
  203. package/vendor/MCP/src/index.js +87 -0
  204. package/vendor/MCP/src/library/KBToolProvider.js +229 -0
  205. package/vendor/MCP/src/library/logger.js +60 -0
  206. package/vendor/MCP/src/registry/ScriptRegistry.js +238 -0
  207. package/vendor/MCP/src/registry/ToolRegistry.js +111 -0
  208. package/vendor/MCP/src/types.js +115 -0
  209. package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +4 -2
  210. package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +3 -3
  211. package/vendor/Server/Skills/knowledge-import/SKILL.md +1 -1
  212. package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +12 -4
  213. package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +5 -4
  214. package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +2 -2
  215. package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +2 -2
  216. package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +1 -2
  217. package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +1 -1
  218. package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +1 -2
  219. package/vendor/Server/package.json +5 -1
  220. package/vendor/VERSION +3 -3
@@ -0,0 +1,440 @@
1
+ /**
2
+ * knowledge.js —— 3rdloop knowledge:本地知识打包回收(export)与合入(import)
3
+ *
4
+ * 背景:知识沉淀产物散落在用户数据目录(npm 安装态各机器独立),需要一条
5
+ * 人工中转通道实现"用户 → 维护者 → 仓库/其他用户"的知识回流:
6
+ *
7
+ * 用户侧(export,零依赖、离线可用):
8
+ * 3rdloop knowledge export [--output <file>] [--since <date>] [--note <text>]
9
+ * 打包 ~/.3lib/3rdloop/kb-data/docs 新增文档 + BadCase 新规则/案例 +
10
+ * db/Knowledge 索引清单 → zip(含 manifest.json:来源/时间/清单/统计)
11
+ * 默认输出 ./3rdloop-knowledge-<日期>-<主机名>.zip
12
+ *
13
+ * 维护者侧(import,收到 zip 后一键预检 + 合入):
14
+ * 3rdloop knowledge import <zip> [--dry-run] [--allow-overwrite]
15
+ * 解包校验 manifest → 逐文件落位(docs → kb-data/docs、BadCase → BadCase、
16
+ * 索引清单仅汇总展示不入库)→ 重建由 kb 引擎首次检索时自动完成
17
+ * --dry-run 只预览将发生的变更,不写任何文件
18
+ *
19
+ * 设计约束:
20
+ * - export 零网络:纯本地打包,绝不静默上传(隐私合规)
21
+ * - 不打 .index/(kb 检索引擎的派生产物,import 后自动重建)
22
+ * - BadCase 冲突默认跳过(--allow-overwrite 覆盖);docs 同名默认跳过
23
+ * - 索引(db/Knowledge/index.json)只作为"待人工评估清单"随包携带,
24
+ * 不自动导入(指针含本机绝对路径,对他机无意义)
25
+ */
26
+
27
+ import fs from 'node:fs';
28
+ import path from 'node:path';
29
+ import os from 'node:os';
30
+ import zlib from 'node:zlib';
31
+ import process from 'node:process';
32
+
33
+ // ─── 用户路径 ─────────────────────────────────────────────────────────
34
+
35
+ /**
36
+ * 知识相关用户目录。
37
+ * @param {string} user3libHome - ~/.3lib
38
+ * @param {string} [dataDir] - CLI 解析的数据目录(kb-data/BadCase 固定在 loopHome,
39
+ * 仅 Knowledge 索引跟随 dataDir——npm 安装态两者相同,仓库开发态 dataDir 可能被覆盖)
40
+ */
41
+ export function knowledgePaths(user3libHome, dataDir = '') {
42
+ const loopHome = path.join(user3libHome, '3rdloop');
43
+ return {
44
+ loopHome,
45
+ kbDocsDir: path.join(loopHome, 'kb-data', 'docs'),
46
+ badcaseDir: path.join(loopHome, 'BadCase'),
47
+ knowledgeIndex: dataDir
48
+ ? path.join(dataDir, 'Knowledge', 'index.json')
49
+ : path.join(loopHome, 'db', 'Knowledge', 'index.json'),
50
+ };
51
+ }
52
+
53
+ // ─── zip 读写(STORE 打包,纯 Node 无第三方依赖)──────────────────────
54
+ // zip 结构说明:为避免实现 zip 目录遍历/central directory 全套规范,
55
+ // 本实现采用"单成员 zip"约定:一个 zip 只含一个被 deflate 压缩的
56
+ // JSON 载荷文件 payload.json(STORE/DEFLATE 单文件 zip 是稳定子集)。
57
+ // payload 内部再携带多文件内容(Base64),兼顾格式标准与实现简洁。
58
+
59
+ const PAYLOAD_NAME = 'payload.json';
60
+
61
+ /** 单文件 DEFLATE zip 写入(无第三方依赖)。 */
62
+ function writeSingleFileZip(filePath, content) {
63
+ const data = Buffer.from(content, 'utf8');
64
+ const compressed = zlib.deflateRawSync(data, { level: 9 });
65
+
66
+ // Local file header
67
+ const local = Buffer.alloc(30);
68
+ local.writeUInt32LE(0x04034b50, 0); // signature
69
+ local.writeUInt16LE(20, 4); // version needed
70
+ local.writeUInt16LE(0, 6); // flags
71
+ local.writeUInt16LE(8, 8); // method: deflate
72
+ local.writeUInt16LE(0, 10); // mod time
73
+ local.writeUInt16LE(0x2d21, 12); // mod date(任意合法值)
74
+ local.writeUInt32LE(crc32(data), 14); // crc32
75
+ local.writeUInt32LE(compressed.length, 18);
76
+ local.writeUInt32LE(data.length, 22);
77
+ local.writeUInt16LE(PAYLOAD_NAME.length, 26);
78
+ local.writeUInt16LE(0, 28); // extra len
79
+
80
+ // Central directory
81
+ const central = Buffer.alloc(46);
82
+ central.writeUInt32LE(0x02014b50, 0);
83
+ central.writeUInt16LE(20, 4); // version made by
84
+ central.writeUInt16LE(20, 6); // version needed
85
+ central.writeUInt16LE(0, 8); // flags
86
+ central.writeUInt16LE(8, 10); // method
87
+ central.writeUInt16LE(0, 12); // time
88
+ central.writeUInt16LE(0x2d21, 14); // date
89
+ central.writeUInt32LE(crc32(data), 16);
90
+ central.writeUInt32LE(compressed.length, 20);
91
+ central.writeUInt32LE(data.length, 24);
92
+ central.writeUInt16LE(PAYLOAD_NAME.length, 28);
93
+ // 其余字段 0(comment/extra/disk/attrs/offset 均为 0)
94
+
95
+ const nameBuf = Buffer.from(PAYLOAD_NAME, 'utf8');
96
+ // central directory 大小含文件名(header 46 + name),起始偏移 = local(30) + name + data
97
+ const centralSize = central.length + nameBuf.length;
98
+ const centralOffset = local.length + nameBuf.length + compressed.length;
99
+ const eocd = Buffer.alloc(22);
100
+ eocd.writeUInt32LE(0x06054b50, 0);
101
+ eocd.writeUInt16LE(1, 8); // entries
102
+ eocd.writeUInt16LE(1, 10);
103
+ eocd.writeUInt32LE(centralSize, 12); // central directory 总大小(含文件名)
104
+ eocd.writeUInt32LE(centralOffset, 16); // central directory 起始偏移
105
+
106
+ fs.writeFileSync(filePath, Buffer.concat([local, nameBuf, compressed, central, nameBuf, eocd]));
107
+ }
108
+
109
+ /** 读取单成员 zip(自动识别 STORE/DEFLATE)。 */
110
+ function readSingleFileZip(filePath) {
111
+ const buf = fs.readFileSync(filePath);
112
+ // 找 EOCD
113
+ let eocd = -1;
114
+ for (let i = buf.length - 22; i >= 0; i--) {
115
+ if (buf.readUInt32LE(i) === 0x06054b50) { eocd = i; break; }
116
+ }
117
+ if (eocd < 0) throw new Error('非法 zip:未找到 EOCD');
118
+ const entryCount = buf.readUInt16LE(eocd + 10);
119
+ if (entryCount !== 1) throw new Error(`非法载荷 zip:期望单成员,实际 ${entryCount} 个`);
120
+
121
+ // Local header
122
+ if (buf.readUInt32LE(0) !== 0x04034b50) throw new Error('非法 zip:缺少 local header');
123
+ const method = buf.readUInt16LE(8);
124
+ const compSize = buf.readUInt32LE(18);
125
+ const nameLen = buf.readUInt16LE(26);
126
+ const extraLen = buf.readUInt16LE(28);
127
+ const dataStart = 30 + nameLen + extraLen;
128
+ const compressed = buf.subarray(dataStart, dataStart + compSize);
129
+
130
+ const data = method === 8 ? zlib.inflateRawSync(compressed) : compressed;
131
+ return data.toString('utf8');
132
+ }
133
+
134
+ /** crc32(IEEE 802.3,zip 标准)。 */
135
+ function crc32(buf) {
136
+ let c;
137
+ const table = crc32._table || (crc32._table = (() => {
138
+ const t = new Uint32Array(256);
139
+ for (let n = 0; n < 256; n++) {
140
+ c = n;
141
+ for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
142
+ t[n] = c >>> 0;
143
+ }
144
+ return t;
145
+ })());
146
+ let crc = 0xffffffff;
147
+ for (let i = 0; i < buf.length; i++) {
148
+ crc = table[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
149
+ }
150
+ return (crc ^ 0xffffffff) >>> 0;
151
+ }
152
+
153
+ // ─── export ───────────────────────────────────────────────────────────
154
+
155
+ /**
156
+ * 递归收集目录下文件相对路径(排除 .index/.DS_Store/node_modules)。
157
+ */
158
+ function walkFiles(root, rel = '', out = []) {
159
+ if (!fs.existsSync(root)) return out;
160
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
161
+ if (entry.name === '.index' || entry.name === '.DS_Store' || entry.name === 'node_modules') continue;
162
+ const relPath = rel ? `${rel}/${entry.name}` : entry.name;
163
+ if (entry.isDirectory()) walkFiles(path.join(root, entry.name), relPath, out);
164
+ else out.push(relPath);
165
+ }
166
+ return out;
167
+ }
168
+
169
+ /**
170
+ * 3rdloop knowledge export 实现。
171
+ * @param {object} opts
172
+ * @param {string} opts.user3libHome
173
+ * @param {string[]} opts.rest - 命令参数(--output/--since/--note)
174
+ * @param {boolean} opts.jsonMode
175
+ * @returns {Promise<number>} 退出码
176
+ */
177
+ export async function knowledgeExport({ user3libHome, dataDir = '', rest = [], jsonMode = false }) {
178
+ const out = (data) => { if (jsonMode) process.stdout.write(JSON.stringify(data, null, 2) + '\n'); };
179
+ const log = (msg) => process.stderr.write(`${msg}\n`);
180
+
181
+ const output = _flagValue(rest, '--output');
182
+ const since = _flagValue(rest, '--since'); // ISO 日期:仅收该日期后新增的文件(按 mtime)
183
+ const note = _flagValue(rest, '--note') || '';
184
+ const sinceMs = since ? Date.parse(since) : null;
185
+ if (since && Number.isNaN(sinceMs)) {
186
+ log(`错误: 非法 --since 日期: ${since}(示例: 2026-09-01)`);
187
+ return 1;
188
+ }
189
+
190
+ const up = knowledgePaths(user3libHome, dataDir);
191
+
192
+ // ── 收集三类知识 ──
193
+ const docsFiles = walkFiles(up.kbDocsDir);
194
+ const badcaseFiles = walkFiles(up.badcaseDir);
195
+ const knowledgeIndex = fs.existsSync(up.knowledgeIndex)
196
+ ? JSON.parse(fs.readFileSync(up.knowledgeIndex, 'utf8'))
197
+ : [];
198
+
199
+ const sinceFilter = (absPath) => sinceMs == null || fs.statSync(absPath).mtimeMs >= sinceMs;
200
+
201
+ // docs:结构化知识文档(export 全量,包小;--since 可裁剪)
202
+ const docs = {};
203
+ let docsSkipped = 0;
204
+ for (const rel of docsFiles) {
205
+ const abs = path.join(up.kbDocsDir, rel);
206
+ if (!sinceFilter(abs)) { docsSkipped++; continue; }
207
+ docs[rel] = fs.readFileSync(abs, 'utf8');
208
+ }
209
+
210
+ // BadCase:规则/案例/日志(排除种子自带内容:仅收 INDEX 之外的新增 + 用户改动,
211
+ // 简化策略 = 全量携带,import 端与种子比对去重)
212
+ const badcase = {};
213
+ let badcaseSkipped = 0;
214
+ for (const rel of badcaseFiles) {
215
+ const abs = path.join(up.badcaseDir, rel);
216
+ if (!sinceFilter(abs)) { badcaseSkipped++; continue; }
217
+ badcase[rel] = fs.readFileSync(abs, 'utf8');
218
+ }
219
+
220
+ if (Object.keys(docs).length === 0 && Object.keys(badcase).length === 0 && knowledgeIndex.length === 0) {
221
+ log('未发现可导出的知识(kb-data/docs、BadCase 均为空)。');
222
+ log('提示: 知识在任务执行后由 knowledge-import SKILL 沉淀,先跑几个任务再看。');
223
+ return 0;
224
+ }
225
+
226
+ // ── 载荷与 manifest ──
227
+ const manifest = {
228
+ format: '3rdloop-knowledge/1',
229
+ exportedAt: new Date().toISOString(),
230
+ host: os.hostname(),
231
+ platform: process.platform,
232
+ note,
233
+ since: since || null,
234
+ stats: {
235
+ docs: Object.keys(docs).length,
236
+ badcase: Object.keys(badcase).length,
237
+ knowledgeIndexEntries: knowledgeIndex.length,
238
+ },
239
+ };
240
+ const payload = JSON.stringify({ manifest, docs, badcase, knowledgeIndex }, null, 2);
241
+
242
+ // 默认文件名:./3rdloop-knowledge-<YYYYMMDD>-<hostname>.zip
243
+ const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
244
+ const defaultName = `3rdloop-knowledge-${date}-${os.hostname().split('.')[0]}.zip`;
245
+ const target = output
246
+ ? path.resolve(output)
247
+ : path.join(process.cwd(), defaultName);
248
+
249
+ writeSingleFileZip(target, payload);
250
+
251
+ if (jsonMode) {
252
+ out({ ok: true, file: target, ...manifest.stats, docsSkippedBySince: docsSkipped });
253
+ } else {
254
+ log(`[3rdloop knowledge] 知识包已生成: ${target}`);
255
+ log(` 结构化知识文档: ${manifest.stats.docs} 篇${docsSkipped ? `(--since 裁剪 ${docsSkipped} 篇)` : ''}`);
256
+ log(` BadCase 规则/案例: ${manifest.stats.badcase} 个文件`);
257
+ log(` 知识索引条目: ${manifest.stats.knowledgeIndexEntries} 条(仅作人工评估清单)`);
258
+ if (note) log(` 备注: ${note}`);
259
+ log(` 大小: ${(fs.statSync(target).size / 1024).toFixed(1)} KB`);
260
+ log(`请将 zip 发送给维护者(微信/邮件均可);内容由你本机知识文件打包而成,可先解压自查。`);
261
+ }
262
+ return 0;
263
+ }
264
+
265
+ // ─── import ───────────────────────────────────────────────────────────
266
+
267
+ /**
268
+ * 3rdloop knowledge import 实现(维护者侧:收 zip → 校验 → 落位)。
269
+ * @param {object} opts
270
+ * @param {string} opts.user3libHome
271
+ * @param {string[]} opts.rest - <zip> --dry-run --allow-overwrite
272
+ * @param {boolean} opts.jsonMode
273
+ */
274
+ export async function knowledgeImport({ user3libHome, dataDir = '', rest = [], jsonMode = false }) {
275
+ const out = (data) => { if (jsonMode) process.stdout.write(JSON.stringify(data, null, 2) + '\n'); };
276
+ const log = (msg) => process.stderr.write(`${msg}\n`);
277
+
278
+ const dryRun = rest.includes('--dry-run');
279
+ const allowOverwrite = rest.includes('--allow-overwrite');
280
+ const zipPath = rest.find(a => !a.startsWith('--'));
281
+ if (!zipPath) {
282
+ log('缺少 zip 路径。用法: 3rdloop knowledge import <zip> [--dry-run] [--allow-overwrite]');
283
+ return 1;
284
+ }
285
+ const absZip = path.resolve(zipPath);
286
+ if (!fs.existsSync(absZip)) {
287
+ log(`错误: 文件不存在: ${absZip}`);
288
+ return 1;
289
+ }
290
+
291
+ // ── 解包 ──
292
+ let payload;
293
+ try {
294
+ payload = JSON.parse(readSingleFileZip(absZip));
295
+ } catch (err) {
296
+ log(`错误: 解析知识包失败: ${err.message}`);
297
+ return 1;
298
+ }
299
+ const { manifest, docs, badcase, knowledgeIndex } = payload;
300
+ if (!manifest || manifest.format !== '3rdloop-knowledge/1') {
301
+ log(`错误: 未知知识包格式: ${manifest?.format || '(缺失 manifest)'}`);
302
+ return 1;
303
+ }
304
+
305
+ const up = knowledgePaths(user3libHome, dataDir);
306
+
307
+ // ── 预演:统计冲突 ──
308
+ const plan = { docsAdd: [], docsSkip: [], badcaseAdd: [], badcaseSkip: [] };
309
+ for (const rel of Object.keys(docs || {})) {
310
+ (fs.existsSync(path.join(up.kbDocsDir, rel)) ? plan.docsSkip : plan.docsAdd).push(rel);
311
+ }
312
+ for (const rel of Object.keys(badcase || {})) {
313
+ (fs.existsSync(path.join(up.badcaseDir, rel)) ? plan.badcaseSkip : plan.badcaseAdd).push(rel);
314
+ }
315
+
316
+ if (dryRun) {
317
+ if (jsonMode) out({ ok: true, dryRun: true, manifest, plan });
318
+ else {
319
+ log(`[3rdloop knowledge] 预演(不写入任何文件)`);
320
+ log(` 知识包: ${absZip}`);
321
+ log(` 导出时间: ${manifest.exportedAt} 来源: ${manifest.host}(${manifest.platform})`);
322
+ if (manifest.note) log(` 备注: ${manifest.note}`);
323
+ log(` 将新增 docs: ${plan.docsAdd.length} 篇${plan.docsAdd.length ? `(如 ${plan.docsAdd.slice(0, 3).join(', ')}${plan.docsAdd.length > 3 ? ' ...' : ''})` : ''}`);
324
+ log(` 将新增 BadCase: ${plan.badcaseAdd.length} 个${plan.badcaseAdd.length ? `(如 ${plan.badcaseAdd.slice(0, 3).join(', ')}${plan.badcaseAdd.length > 3 ? ' ...' : ''})` : ''}`);
325
+ log(` 跳过同名冲突: docs ${plan.docsSkip.length} / BadCase ${plan.badcaseSkip.length}(--allow-overwrite 可覆盖)`);
326
+ log(` 知识索引条目: ${(knowledgeIndex || []).length} 条(仅展示,不入库)`);
327
+ }
328
+ return 0;
329
+ }
330
+
331
+ // ── 落位 ──
332
+ let added = 0, skipped = 0;
333
+ for (const rel of Object.keys(docs || {})) {
334
+ const target = path.join(up.kbDocsDir, rel);
335
+ if (fs.existsSync(target) && !allowOverwrite) { skipped++; continue; }
336
+ fs.mkdirSync(path.dirname(target), { recursive: true });
337
+ fs.writeFileSync(target, docs[rel]);
338
+ added++;
339
+ }
340
+ for (const rel of Object.keys(badcase || {})) {
341
+ const target = path.join(up.badcaseDir, rel);
342
+ if (fs.existsSync(target) && !allowOverwrite) { skipped++; continue; }
343
+ fs.mkdirSync(path.dirname(target), { recursive: true });
344
+ fs.writeFileSync(target, badcase[rel]);
345
+ added++;
346
+ }
347
+
348
+ // 知识索引:打印摘要供人工评估(不入库:含他机绝对路径指针)
349
+ if (knowledgeIndex && knowledgeIndex.length > 0 && !jsonMode) {
350
+ log(`[3rdloop knowledge] 携带知识索引 ${knowledgeIndex.length} 条(未入库;含导出者机器的本地路径,仅供参考)`);
351
+ }
352
+
353
+ if (jsonMode) {
354
+ out({ ok: true, added, skipped, plan });
355
+ } else {
356
+ log(`[3rdloop knowledge] 导入完成: 新增 ${added} 个文件${skipped ? `,跳过同名冲突 ${skipped} 个` : ''}`);
357
+ log(` docs → ${up.kbDocsDir}`);
358
+ log(` BadCase → ${up.badcaseDir}`);
359
+ log(` 检索索引将在下次 kb_search 时自动重建(.index/ 为派生产物)`);
360
+ }
361
+ return 0;
362
+ }
363
+
364
+ // ─── 帮助 / 入口 ──────────────────────────────────────────────────────
365
+
366
+ function _flagValue(rest, name) {
367
+ const idx = rest.indexOf(name);
368
+ return idx !== -1 ? rest[idx + 1] : undefined;
369
+ }
370
+
371
+ export function printKnowledgeHelp() {
372
+ process.stdout.write(`3rdloop knowledge —— 本地知识打包回收 / 合入(人工中转通道)
373
+
374
+ 用法(用户侧:打包发给维护者):
375
+ 3rdloop knowledge export [选项]
376
+ 打包 ~/.3lib/3rdloop/ 下的知识产物为 zip:
377
+ - kb-data/docs/ 结构化知识文档(knowledge-import SKILL 的沉淀)
378
+ - BadCase/ 已知问题规则/案例(泛化 SKILL 的沉淀)
379
+ - db/Knowledge/ 索引清单(仅作人工评估参考,不入库)
380
+ 选项:
381
+ --output <file> 输出路径(默认 ./3rdloop-knowledge-<日期>-<主机名>.zip)
382
+ --since <date> 仅打包该日期后新增的文件(示例: 2026-09-01)
383
+ --note <text> 备注(写入 manifest,如 "mp3agic 检视批次")
384
+ --json 结构化输出
385
+
386
+ 用法(维护者侧:收到 zip 后合入):
387
+ 3rdloop knowledge import <zip> [--dry-run] [--allow-overwrite]
388
+ --dry-run 仅预览将发生的变更,不写入
389
+ --allow-overwrite 覆盖同名文件(默认跳过)
390
+ 解包后 docs → ~/.3lib/3rdloop/kb-data/docs、BadCase → ~/.3lib/3rdloop/BadCase
391
+
392
+ 说明:
393
+ - export 纯本地打包,不上传任何数据;可先解压自查内容再发送
394
+ - 不含检索索引(.index/),导入后首次检索自动重建
395
+ - 维护者审核后可把精选内容合入仓库 Archive/data 与 BadCase/,随版本分发
396
+ `);
397
+ }
398
+
399
+ /**
400
+ * 3rdloop knowledge 命令入口。
401
+ * @param {object} opts
402
+ * @param {string[]} opts.rest
403
+ * @param {string} opts.user3libHome
404
+ * @param {boolean} opts.jsonMode
405
+ * @returns {Promise<number>}
406
+ */
407
+ export async function cmdKnowledge({ rest = [], user3libHome = '', dataDir = '', jsonMode = false }) {
408
+ if (rest.includes('--help') || rest.includes('-h')) {
409
+ printKnowledgeHelp();
410
+ return 0;
411
+ }
412
+ // 定位位置子命令(第一个非 flag 参数),并从参数中剥离子命令词
413
+ let subIdx = -1;
414
+ for (let i = 0; i < rest.length; i++) {
415
+ if (rest[i].startsWith('--')) {
416
+ // flag 值(如 --note 后面的文本)不是子命令,跳过
417
+ if (_hasValue(rest[i]) && rest[i + 1] !== undefined && !rest[i + 1].startsWith('--')) i++;
418
+ continue;
419
+ }
420
+ subIdx = i;
421
+ break;
422
+ }
423
+ const args = subIdx === -1 ? [] : [...rest.slice(0, subIdx), ...rest.slice(subIdx + 1)];
424
+
425
+ if (subIdx === -1) {
426
+ printKnowledgeHelp();
427
+ return rest.length === 0 ? 0 : 1;
428
+ }
429
+ const sub = rest[subIdx];
430
+ if (sub === 'export') return knowledgeExport({ user3libHome, dataDir, rest: args, jsonMode });
431
+ if (sub === 'import') return knowledgeImport({ user3libHome, dataDir, rest: args, jsonMode });
432
+ process.stderr.write(`未知子命令: ${sub}\n`);
433
+ printKnowledgeHelp();
434
+ return 1;
435
+ }
436
+
437
+ /** 该 flag 是否携带值(--output/--since/--note)。 */
438
+ function _hasValue(flag) {
439
+ return flag === '--output' || flag === '--since' || flag === '--note';
440
+ }