@ohos-cpf/3rdloop 0.0.1

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 (389) hide show
  1. package/README.md +425 -0
  2. package/bin/3rdloop.mjs +48 -0
  3. package/lib/cli.js +741 -0
  4. package/lib/config.js +318 -0
  5. package/lib/doctor.js +114 -0
  6. package/lib/exit-codes.js +31 -0
  7. package/lib/opencode.js +156 -0
  8. package/lib/orch.js +427 -0
  9. package/lib/queries.js +264 -0
  10. package/lib/runner.js +979 -0
  11. package/lib/step.js +326 -0
  12. package/lib/ui.js +223 -0
  13. package/lib/workflow.js +291 -0
  14. package/lib/workflows.js +132 -0
  15. package/package.json +50 -0
  16. package/vendor/Server/Agent/SkillSelector/README.md +344 -0
  17. package/vendor/Server/Agent/SkillSelector/core/Agent.js +207 -0
  18. package/vendor/Server/Agent/SkillSelector/index.js +14 -0
  19. package/vendor/Server/Agent/SkillSelector/llm/llmClient.js +313 -0
  20. package/vendor/Server/Agent/SkillSelector/llm/prompts.js +161 -0
  21. package/vendor/Server/Agent/SkillSelector/llm/reactSteps.js +144 -0
  22. package/vendor/Server/Agent/SkillSelector/matcher/fuzzyMatcher.js +433 -0
  23. package/vendor/Server/Agent/SkillSelector/scanner/skillScanner.js +382 -0
  24. package/vendor/Server/Agent/SkillSelector/types.js +63 -0
  25. package/vendor/Server/Agent/SkillSelector/utils/actionWords.js +60 -0
  26. package/vendor/Server/Brain/AnalysisStrategies.js +422 -0
  27. package/vendor/Server/Brain/Brain.js +686 -0
  28. package/vendor/Server/Brain/DecompositionStrategies.js +621 -0
  29. package/vendor/Server/Brain/PlanPersistence.js +196 -0
  30. package/vendor/Server/Brain/SkillExecutor.js +251 -0
  31. package/vendor/Server/Brain/index.js +11 -0
  32. package/vendor/Server/CLI/cli.js +243 -0
  33. package/vendor/Server/CLI/opencode/index.js +804 -0
  34. package/vendor/Server/CLI/opencode.js +5 -0
  35. package/vendor/Server/DbUse/MessageArchive.js +61 -0
  36. package/vendor/Server/DbUse/StorageManager.js +107 -0
  37. package/vendor/Server/DbUse/adapters/BaseAdapter.js +94 -0
  38. package/vendor/Server/DbUse/adapters/FileAdapter.js +138 -0
  39. package/vendor/Server/DbUse/adapters/JsonAdapter.js +138 -0
  40. package/vendor/Server/DbUse/adapters/JsonlAdapter.js +114 -0
  41. package/vendor/Server/DbUse/adapters/SqliteAdapter.js +157 -0
  42. package/vendor/Server/DbUse/index.js +160 -0
  43. package/vendor/Server/DbUse/stores/SessionStore.js +279 -0
  44. package/vendor/Server/DbUse/stores/TaskExecutionStore.js +133 -0
  45. package/vendor/Server/DbUse/stores/TaskRegistryStore.js +262 -0
  46. package/vendor/Server/DbUse/stores/TaskStepStore.js +279 -0
  47. package/vendor/Server/FlexRunner/FlexRunner.js +1759 -0
  48. package/vendor/Server/FlexRunner/index.js +12 -0
  49. package/vendor/Server/Knowledge/KnowledgeImporter.js +523 -0
  50. package/vendor/Server/Knowledge/KnowledgeManager.js +341 -0
  51. package/vendor/Server/Knowledge/index.js +33 -0
  52. package/vendor/Server/LoopEngine/LoopEngine.js +1133 -0
  53. package/vendor/Server/LoopEngine/index.js +11 -0
  54. package/vendor/Server/Orchestrator/Orchestrator.js +1425 -0
  55. package/vendor/Server/Orchestrator/StepNode.js +312 -0
  56. package/vendor/Server/Orchestrator/index.js +13 -0
  57. package/vendor/Server/Routes/controllers/BrainController.js +241 -0
  58. package/vendor/Server/Routes/controllers/FlexRunnerController.js +1125 -0
  59. package/vendor/Server/Routes/controllers/HealthController.js +44 -0
  60. package/vendor/Server/Routes/controllers/KnowledgeImportController.js +355 -0
  61. package/vendor/Server/Routes/controllers/LoopEngineController.js +788 -0
  62. package/vendor/Server/Routes/controllers/OrchestratorController.js +911 -0
  63. package/vendor/Server/Routes/controllers/StatsController.js +57 -0
  64. package/vendor/Server/Routes/controllers/StreamController.js +67 -0
  65. package/vendor/Server/Routes/library/logger.js +179 -0
  66. package/vendor/Server/Routes/library/zipArchive.js +172 -0
  67. package/vendor/Server/Routes/router/Router.js +204 -0
  68. package/vendor/Server/Routes/routes/brain.js +47 -0
  69. package/vendor/Server/Routes/routes/flexrunner.js +72 -0
  70. package/vendor/Server/Routes/routes/health.js +28 -0
  71. package/vendor/Server/Routes/routes/index.js +57 -0
  72. package/vendor/Server/Routes/routes/knowledge.js +55 -0
  73. package/vendor/Server/Routes/routes/loopengine.js +58 -0
  74. package/vendor/Server/Routes/routes/orchestrator.js +61 -0
  75. package/vendor/Server/Routes/routes/registry.js +98 -0
  76. package/vendor/Server/Routes/routes/stats.js +23 -0
  77. package/vendor/Server/Routes/routes/stream.js +30 -0
  78. package/vendor/Server/Routes/server.js +202 -0
  79. package/vendor/Server/Routes/sse/SseHub.js +308 -0
  80. package/vendor/Server/Skills/acceptance-check/SKILL.md +174 -0
  81. package/vendor/Server/Skills/acceptance-check/references/PHASE1_ARTIFACT_COLLECTION.md +52 -0
  82. package/vendor/Server/Skills/acceptance-check/references/PHASE2_CRITERIA_EVALUATION.md +77 -0
  83. package/vendor/Server/Skills/arkts-code-check/SKILL.md +314 -0
  84. package/vendor/Server/Skills/arkts-code-check/references/CODE_CHECK_GUIDE.md +160 -0
  85. package/vendor/Server/Skills/arkts-code-check/references/FILE_TYPE_GUIDE.md +29 -0
  86. package/vendor/Server/Skills/arkts-code-check/references/PHASE1_INFO_COLLECTION.md +222 -0
  87. package/vendor/Server/Skills/arkts-code-check/references/REPORT_TEMPLATE.md +220 -0
  88. package/vendor/Server/Skills/arkts-library-compile-validate/SKILL.md +329 -0
  89. package/vendor/Server/Skills/arkts-library-compile-validate/scripts/build.ps1 +93 -0
  90. package/vendor/Server/Skills/arkts-library-compile-validate/scripts/code-linter.cjs +433 -0
  91. package/vendor/Server/Skills/arkts-library-compile-validate/scripts/migrate.cjs +851 -0
  92. package/vendor/Server/Skills/arkts-library-compile-validate/scripts/ohpm-switch.cjs +789 -0
  93. package/vendor/Server/Skills/arkts-library-demo-code/SKILL.md +291 -0
  94. package/vendor/Server/Skills/arkts-library-demo-code/references/API_SIGNATURE_CHECKS.md +68 -0
  95. package/vendor/Server/Skills/arkts-library-demo-code/references/BUILD_VALIDATION.md +184 -0
  96. package/vendor/Server/Skills/arkts-library-demo-code/references/CODE_STANDARDS.md +337 -0
  97. package/vendor/Server/Skills/arkts-library-demo-code/references/EXAMPLES.md +400 -0
  98. package/vendor/Server/Skills/arkts-library-demo-code/references/SYSTEM_API_LOOKUP.md +99 -0
  99. package/vendor/Server/Skills/arkts-library-demo-code/references/TEMPLATE.md +544 -0
  100. package/vendor/Server/Skills/arkts-library-demo-code/scripts/build.ps1 +93 -0
  101. package/vendor/Server/Skills/arkts-library-demo-code/scripts/code-linter.cjs +433 -0
  102. package/vendor/Server/Skills/arkts-library-demo-code/scripts/migrate.cjs +851 -0
  103. package/vendor/Server/Skills/arkts-library-demo-code/scripts/ohpm-switch.cjs +789 -0
  104. package/vendor/Server/Skills/arkts-library-demo-coverage/SKILL.md +174 -0
  105. package/vendor/Server/Skills/arkts-library-demo-scenario/SKILL.md +321 -0
  106. package/vendor/Server/Skills/arkts-library-demo-scenario/references/EXAMPLES.md +100 -0
  107. package/vendor/Server/Skills/arkts-library-demo-scenario/references/TEMPLATE.md +185 -0
  108. package/vendor/Server/Skills/arkts-library-documentation-quality-check/SKILL.md +234 -0
  109. package/vendor/Server/Skills/arkts-library-documentation-quality-check/assets/REPORT_TEMPLATE.md +103 -0
  110. package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/CHECK_DIMENSIONS.md +89 -0
  111. package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/COMPLIANCE_CHECKLIST.md +62 -0
  112. package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/KB_QUERY_GUIDE.md +108 -0
  113. package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/MCP_TOOL_DISCOVERY.md +124 -0
  114. package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/REPORT_TEMPLATE.md +90 -0
  115. package/vendor/Server/Skills/arkts-library-documentation-quality-check/references/SCORING_FORMULA.md +57 -0
  116. package/vendor/Server/Skills/arkts-library-documentation-quality-check/scripts/validate-skill.cjs +259 -0
  117. package/vendor/Server/Skills/arkts-library-interface-spec/SKILL.md +97 -0
  118. package/vendor/Server/Skills/arkts-library-memory-leak-check/SKILL.md +392 -0
  119. package/vendor/Server/Skills/arkts-library-source-clone/SKILL.md +113 -0
  120. package/vendor/Server/Skills/arkts-library-stability-check/SKILL.md +313 -0
  121. package/vendor/Server/Skills/arkts-library-stability-check/assets/REPORT_TEMPLATE.md +154 -0
  122. package/vendor/Server/Skills/arkts-library-stability-check/references/CHECKLIST.md +166 -0
  123. package/vendor/Server/Skills/arkts-library-stability-check/references/CODE_EXAMPLES.md +309 -0
  124. package/vendor/Server/Skills/arkts-library-stability-check/references/SCORING_RULES.md +90 -0
  125. package/vendor/Server/Skills/arkts-library-stability-check/scripts/validate-skill.cjs +282 -0
  126. package/vendor/Server/Skills/arkts-library-test-coverage-check/SKILL.md +361 -0
  127. package/vendor/Server/Skills/arkts-library-test-coverage-check/assets/REPORT_TEMPLATE.md +146 -0
  128. package/vendor/Server/Skills/arkts-library-test-coverage-check/references/CHECKLIST.md +253 -0
  129. package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +115 -0
  130. package/vendor/Server/Skills/arkts-library-test-coverage-check/scripts/validate-skill.cjs +263 -0
  131. package/vendor/Server/Skills/arkts-library-xts-code/SKILL.md +455 -0
  132. package/vendor/Server/Skills/arkts-library-xts-code/assets/report-template.md +60 -0
  133. package/vendor/Server/Skills/arkts-library-xts-code/references/ACCESS_MODIFIER_PRECHECK.md +76 -0
  134. package/vendor/Server/Skills/arkts-library-xts-code/references/BUILD_VERIFICATION.md +200 -0
  135. package/vendor/Server/Skills/arkts-library-xts-code/references/CODE_STANDARDS.md +519 -0
  136. package/vendor/Server/Skills/arkts-library-xts-code/references/SUBAGENT_PROMPT_TEMPLATE.md +276 -0
  137. package/vendor/Server/Skills/arkts-library-xts-code/references/SYSTEM_API_LOOKUP.md +93 -0
  138. package/vendor/Server/Skills/arkts-library-xts-code/references/XTS_TEMPLATE.md +767 -0
  139. package/vendor/Server/Skills/arkts-library-xts-code/scripts/build.ps1 +93 -0
  140. package/vendor/Server/Skills/arkts-library-xts-code/scripts/code-linter.cjs +433 -0
  141. package/vendor/Server/Skills/arkts-library-xts-code/scripts/migrate.cjs +851 -0
  142. package/vendor/Server/Skills/arkts-library-xts-code/scripts/ohpm-switch.cjs +789 -0
  143. package/vendor/Server/Skills/arkts-library-xts-code/scripts/precheck-access-modifiers.cjs +221 -0
  144. package/vendor/Server/Skills/arkts-library-xts-code-fix/SKILL.md +229 -0
  145. package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +97 -0
  146. package/vendor/Server/Skills/arkts-library-xts-doc/SKILL.md +194 -0
  147. package/vendor/Server/Skills/arkts-library-xts-doc/references/EXAMPLES.md +576 -0
  148. package/vendor/Server/Skills/arkts-library-xts-doc/references/TEMPLATE.md +575 -0
  149. package/vendor/Server/Skills/arkts-library-xts-doc/references/TESTABILITY_GUIDE.md +182 -0
  150. package/vendor/Server/Skills/arkts-library-xts-execution/SKILL.md +491 -0
  151. package/vendor/Server/Skills/arkts-library-xts-execution/references/error-fixing-examples.md +217 -0
  152. package/vendor/Server/Skills/arkts-library-xts-execution/scripts/build.ps1 +93 -0
  153. package/vendor/Server/Skills/arkts-library-xts-execution/scripts/code-linter.cjs +433 -0
  154. package/vendor/Server/Skills/arkts-library-xts-execution/scripts/migrate.cjs +851 -0
  155. package/vendor/Server/Skills/arkts-library-xts-execution/scripts/ohpm-switch.cjs +789 -0
  156. package/vendor/Server/Skills/flutter-code-check/SKILL.md +299 -0
  157. package/vendor/Server/Skills/flutter-code-check/assets/OUTPUT_TEMPLATE.md +312 -0
  158. package/vendor/Server/Skills/flutter-code-check/references/CHECKLIST.md +190 -0
  159. package/vendor/Server/Skills/flutter-code-check/references/PLATFORMS.md +134 -0
  160. package/vendor/Server/Skills/flutter-code-check/scripts/validate-skill.cjs +259 -0
  161. package/vendor/Server/Skills/flutter-interface/README.md +75 -0
  162. package/vendor/Server/Skills/flutter-interface/SKILL.md +291 -0
  163. package/vendor/Server/Skills/flutter-interface/references/EXAMPLES.md +336 -0
  164. package/vendor/Server/Skills/flutter-interface/references/GIT_CLONE_GUIDE.md +190 -0
  165. package/vendor/Server/Skills/flutter-interface/references/SCRIPT_REFERENCE.md +258 -0
  166. package/vendor/Server/Skills/flutter-interface/references/TEMPLATE.md +254 -0
  167. package/vendor/Server/Skills/flutter-library-consistency-check/SKILL.md +518 -0
  168. package/vendor/Server/Skills/flutter-library-consistency-check/references/CHECKLIST.md +382 -0
  169. package/vendor/Server/Skills/flutter-library-consistency-check/references/FUNCTION_COMPARISON_GUIDE.md +342 -0
  170. package/vendor/Server/Skills/flutter-library-consistency-check/references/PLATFORM_LIMITATION_GUIDE.md +71 -0
  171. package/vendor/Server/Skills/flutter-library-documentation-quality-check/SKILL.md +519 -0
  172. package/vendor/Server/Skills/flutter-library-documentation-quality-check/references/CHECKLIST.md +407 -0
  173. package/vendor/Server/Skills/flutter-library-memory-leak-check/SKILL.md +653 -0
  174. package/vendor/Server/Skills/flutter-library-memory-leak-check/references/CHECKLIST.md +397 -0
  175. package/vendor/Server/Skills/flutter-library-stability-check/SKILL.md +745 -0
  176. package/vendor/Server/Skills/flutter-library-stability-check/references/CHECKLIST.md +721 -0
  177. package/vendor/Server/Skills/flutter-library-test-coverage-check/SKILL.md +414 -0
  178. package/vendor/Server/Skills/flutter-library-test-coverage-check/assets/REPORT_TEMPLATE.md +150 -0
  179. package/vendor/Server/Skills/flutter-library-test-coverage-check/references/CHECKLIST.md +304 -0
  180. package/vendor/Server/Skills/flutter-library-test-coverage-check/references/SCORING_RULES.md +265 -0
  181. package/vendor/Server/Skills/flutter-library-test-coverage-check/references/SCRIPT_USAGE.md +286 -0
  182. package/vendor/Server/Skills/knowledge-import/SKILL.md +383 -0
  183. package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +165 -0
  184. package/vendor/Server/Skills/knowledge-import/references/SKILL_LOCATOR_GUIDE.md +91 -0
  185. package/vendor/Server/Skills/knowledge-import/references/SKILL_OPTIMIZATION_GUIDE.md +127 -0
  186. package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +301 -0
  187. package/vendor/Server/Skills/ohos-lib-pr-push/assets/PR_ISSUE_TEMPLATE.md +105 -0
  188. package/vendor/Server/Skills/ohos-lib-pr-push/references/GITCODE_API.md +127 -0
  189. package/vendor/Server/Skills/ohos-lib-pr-push/scripts/gitcode-api.cjs +208 -0
  190. package/vendor/Server/Skills/rn-code-check/SKILL.md +321 -0
  191. package/vendor/Server/Skills/rn-code-check/references/API-GUIDE.md +235 -0
  192. package/vendor/Server/Skills/rn-code-check/references/CHECKLIST.md +189 -0
  193. package/vendor/Server/Skills/rn-code-check/references/REPORT-TEMPLATE.md +247 -0
  194. package/vendor/Server/Skills/rn-lib-add-example/SKILL.md +198 -0
  195. package/vendor/Server/Skills/rn-lib-add-example/references/APP_RENAME_GUIDE.md +40 -0
  196. package/vendor/Server/Skills/rn-lib-add-example/references/SHELL_ADAPTATION_CHECKLIST.md +78 -0
  197. package/vendor/Server/Skills/rn-lib-add-example/references/TEMPLATE_REPO_GUIDE.md +70 -0
  198. package/vendor/Server/Skills/rn-lib-add-example/references/VERIFICATION_GUIDE.md +47 -0
  199. package/vendor/Server/Skills/rn-lib-add-example/scripts/create-example.cjs +252 -0
  200. package/vendor/Server/Skills/rn-lib-update-doc/SKILL.md +176 -0
  201. package/vendor/Server/Skills/rn-lib-update-doc/config.json +5 -0
  202. package/vendor/Server/Skills/rn-lib-update-doc/references/changelog-template.md +35 -0
  203. package/vendor/Server/Skills/rn-lib-update-doc/references/format-diff.md +137 -0
  204. package/vendor/Server/Skills/rn-lib-update-doc/references/link-registry.json +33 -0
  205. package/vendor/Server/Skills/rn-lib-update-doc/references/model-0.4.2-overview.md +40 -0
  206. package/vendor/Server/Skills/rn-lib-update-doc/references/model-0.4.2.md +429 -0
  207. package/vendor/Server/Skills/rn-lib-update-doc/scripts/detect-readme-format.cjs +105 -0
  208. package/vendor/Server/Skills/rn-lib-update-doc/scripts/find-usage-doc.cjs +90 -0
  209. package/vendor/Server/Skills/rn-lib-update-doc/scripts/link-verify.cjs +213 -0
  210. package/vendor/Server/Skills/rn-lib-update-doc/scripts/normalize-changelog.cjs +73 -0
  211. package/vendor/Server/Skills/rn-lib-update-doc/scripts/normalize-package-meta.cjs +258 -0
  212. package/vendor/Server/Skills/rn-lib-update-doc/scripts/normalize-readme-links.cjs +341 -0
  213. package/vendor/Server/Skills/rn-lib-update-doc/scripts/resolve-usage-docs.cjs +67 -0
  214. package/vendor/Server/Skills/rn-library-consistency-check/SKILL.md +299 -0
  215. package/vendor/Server/Skills/rn-library-consistency-check/assets/REPORT_TEMPLATE.md +293 -0
  216. package/vendor/Server/Skills/rn-library-consistency-check/references/ARKTS_COMPONENT_CHECK_GUIDE.md +857 -0
  217. package/vendor/Server/Skills/rn-library-consistency-check/references/ARKTS_TURBOMODULE_CHECK_GUIDE.md +856 -0
  218. package/vendor/Server/Skills/rn-library-consistency-check/references/CHECKLIST.md +157 -0
  219. package/vendor/Server/Skills/rn-library-consistency-check/references/CPP_COMPONENT_CHECK_GUIDE.md +801 -0
  220. package/vendor/Server/Skills/rn-library-consistency-check/references/CPP_TURBOMODULE_CHECK_GUIDE.md +684 -0
  221. package/vendor/Server/Skills/rn-library-consistency-check/references/FUNCTION_COMPARISON_GUIDE.md +233 -0
  222. package/vendor/Server/Skills/rn-library-consistency-check/references/NATIVE_COMPONENT_IDENTIFICATION.md +1373 -0
  223. package/vendor/Server/Skills/rn-library-consistency-check/references/SCORING_STANDARD.md +220 -0
  224. package/vendor/Server/Skills/rn-library-consistency-check/scripts/validate-skill.py +245 -0
  225. package/vendor/Server/Skills/rn-library-documentation-quality-check/SKILL.md +263 -0
  226. package/vendor/Server/Skills/rn-library-documentation-quality-check/assets/MODEL.md +414 -0
  227. package/vendor/Server/Skills/rn-library-documentation-quality-check/assets/MODEL_en.md +413 -0
  228. package/vendor/Server/Skills/rn-library-documentation-quality-check/assets/REPORT_TEMPLATE.md +311 -0
  229. package/vendor/Server/Skills/rn-library-documentation-quality-check/references/CHECK_CHECKLIST.md +355 -0
  230. package/vendor/Server/Skills/rn-library-documentation-quality-check/references/CROSS_VALIDATION_GUIDE.md +115 -0
  231. package/vendor/Server/Skills/rn-library-documentation-quality-check/references/DOC_COLLECTION_GUIDE.md +139 -0
  232. package/vendor/Server/Skills/rn-library-documentation-quality-check/references/EXAMPLES.md +586 -0
  233. package/vendor/Server/Skills/rn-library-documentation-quality-check/references/GOTCHAS.md +57 -0
  234. package/vendor/Server/Skills/rn-library-documentation-quality-check/scripts/validate-skill.py +259 -0
  235. package/vendor/Server/Skills/rn-library-interface-analyzer/SKILL.md +301 -0
  236. package/vendor/Server/Skills/rn-library-interface-analyzer/assets/REPORT_TEMPLATE.md +148 -0
  237. package/vendor/Server/Skills/rn-library-interface-analyzer/references/DOC_ANNOTATION_GUIDE.md +118 -0
  238. package/vendor/Server/Skills/rn-library-interface-analyzer/references/SCRIPT_USAGE_GUIDE.md +168 -0
  239. package/vendor/Server/Skills/rn-library-interface-analyzer/references/URL_PARSING_RULES.md +176 -0
  240. package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +274 -0
  241. package/vendor/Server/Skills/rn-library-issue-generalizer/assets/case-template.md +45 -0
  242. package/vendor/Server/Skills/rn-library-issue-generalizer/assets/rule-template.md +25 -0
  243. package/vendor/Server/Skills/rn-library-issue-generalizer/references/PR_FETCH_GUIDE.md +61 -0
  244. package/vendor/Server/Skills/rn-library-issue-generalizer/references/RULE_TEMPLATE_GUIDE.md +165 -0
  245. package/vendor/Server/Skills/rn-library-issue-generalizer/scripts/fetch-pr-info.py +239 -0
  246. package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +263 -0
  247. package/vendor/Server/Skills/rn-library-known-issue-check/assets/REPORT_TEMPLATE.md +96 -0
  248. package/vendor/Server/Skills/rn-library-known-issue-check/references/COMPLIANCE_CHECKLIST.md +58 -0
  249. package/vendor/Server/Skills/rn-library-known-issue-check/references/INSPECTION_GUIDE.md +99 -0
  250. package/vendor/Server/Skills/rn-library-known-issue-check/references/PRESCREEN_GUIDE.md +64 -0
  251. package/vendor/Server/Skills/rn-library-known-issue-check/references/SOURCE_PREP_GUIDE.md +75 -0
  252. package/vendor/Server/Skills/rn-library-known-issue-check/scripts/validate-known-issue-report.py +164 -0
  253. package/vendor/Server/Skills/rn-library-memory-leak-check/SKILL.md +339 -0
  254. package/vendor/Server/Skills/rn-library-memory-leak-check/assets/REPORT_TEMPLATE.md +83 -0
  255. package/vendor/Server/Skills/rn-library-memory-leak-check/references/CHECKLIST.md +859 -0
  256. package/vendor/Server/Skills/rn-library-memory-leak-check/references/HARMONY_CODE_PATTERNS.md +122 -0
  257. package/vendor/Server/Skills/rn-library-memory-leak-check/scripts/scan_harmony_code.py +279 -0
  258. package/vendor/Server/Skills/rn-library-stability-check/SKILL.md +273 -0
  259. package/vendor/Server/Skills/rn-library-stability-check/assets/REPORT_TEMPLATE.md +129 -0
  260. package/vendor/Server/Skills/rn-library-stability-check/references/CHECKLIST.md +581 -0
  261. package/vendor/Server/Skills/rn-library-stability-check/references/SCORING_RULES.md +138 -0
  262. package/vendor/Server/Skills/rn-library-stability-check/scripts/scan-harmony-code.py +168 -0
  263. package/vendor/Server/Skills/rn-library-test-coverage-check/SKILL.md +506 -0
  264. package/vendor/Server/Skills/rn-library-test-coverage-check/references/CHECKLIST.md +280 -0
  265. package/vendor/Server/Skills/rn-library-test-coverage-check/references/DEMO_LOCATION.md +221 -0
  266. package/vendor/Server/Skills/rn-library-test-coverage-check/references/REPORT_TEMPLATE.md +209 -0
  267. package/vendor/Server/Skills/rn-library-test-coverage-check/references/SCRIPT_USAGE.md +325 -0
  268. package/vendor/Server/Skills/rn-ohos-xts-generator/SKILL.md +279 -0
  269. package/vendor/Server/Skills/rn-ohos-xts-generator/assets/TEST_FILE_TEMPLATES.md +404 -0
  270. package/vendor/Server/Skills/rn-ohos-xts-generator/references/BUILD_TROUBLESHOOTING.md +185 -0
  271. package/vendor/Server/Skills/rn-ohos-xts-generator/references/BUILD_WORKFLOW.md +265 -0
  272. package/vendor/Server/Skills/rn-ohos-xts-generator/references/COMMON_CONFIG.md +189 -0
  273. package/vendor/Server/Skills/rn-ohos-xts-generator/references/CONFIG_GUIDE.md +203 -0
  274. package/vendor/Server/Skills/rn-ohos-xts-generator/references/COVERAGE_ANALYZER.md +147 -0
  275. package/vendor/Server/Skills/rn-ohos-xts-generator/references/DESIGN_DOC_GUIDE.md +148 -0
  276. package/vendor/Server/Skills/rn-ohos-xts-generator/references/GENERATION_FLOW.md +165 -0
  277. package/vendor/Server/Skills/rn-ohos-xts-generator/references/GENERATION_STRATEGY.md +195 -0
  278. package/vendor/Server/Skills/rn-ohos-xts-generator/references/HARMONY_SCANNER.md +249 -0
  279. package/vendor/Server/Skills/rn-ohos-xts-generator/references/JEST_FRAMEWORK.md +235 -0
  280. package/vendor/Server/Skills/rn-ohos-xts-generator/references/PLATFORM_COMPAT.md +161 -0
  281. package/vendor/Server/Skills/rn-ohos-xts-generator/references/RN_TEST_PATTERNS.md +413 -0
  282. package/vendor/Server/Skills/rn-ohos-xts-generator/references/SOURCE_PARSER.md +235 -0
  283. package/vendor/Server/Skills/rn-ohos-xts-generator/references/TEST_CONVENTIONS.md +245 -0
  284. package/vendor/Server/Skills/rn-ohos-xts-generator/references/TROUBLESHOOTING.md +282 -0
  285. package/vendor/Server/Skills/rn-ohos-xts-generator/references/USAGE_GUIDE.md +251 -0
  286. package/vendor/Server/Skills/rnoh-cptf-api-test/SKILL.md +469 -0
  287. package/vendor/Server/Skills/rnoh-cptf-api-test/assets/CPTF_TEST_TEMPLATE.md +310 -0
  288. package/vendor/Server/Skills/rnoh-cptf-api-test/assets/DEMO_PAGE_TEMPLATE.md +303 -0
  289. package/vendor/Server/Skills/rnoh-cptf-api-test/references/CPTF_TEST_GENERATION_GUIDE.md +421 -0
  290. package/vendor/Server/Skills/rnoh-cptf-api-test/references/DEMO_GENERATION_GUIDE.md +358 -0
  291. package/vendor/Server/Skills/rnoh-cptf-api-test/references/QUALITY_CHECKLIST.md +114 -0
  292. package/vendor/Server/Skills/rnoh-cptf-api-test/references/SPEC_PARSING_GUIDE.md +274 -0
  293. package/vendor/Server/Skills/rnoh-cptf-api-test/scripts/validate-rnoh-cptf-api-test.sh +185 -0
  294. package/vendor/Server/Skills/rnoh-cptf-demo-test/SKILL.md +191 -0
  295. package/vendor/Server/Skills/rnoh-cptf-demo-test/assets/TEST_TEMPLATE.md +216 -0
  296. package/vendor/Server/Skills/rnoh-cptf-demo-test/references/CPTF_SETUP.md +107 -0
  297. package/vendor/Server/Skills/rnoh-cptf-demo-test/references/DEMO_ANALYSIS.md +120 -0
  298. package/vendor/Server/Skills/rnoh-cptf-demo-test/scripts/validate-rnoh-cptf-test.sh +108 -0
  299. package/vendor/Server/Skills/rnoh-cptf-test-run/SKILL.md +237 -0
  300. package/vendor/Server/Skills/rnoh-cptf-test-run/references/DEBUG_PLAYBOOK.md +261 -0
  301. package/vendor/Server/Skills/rnoh-cptf-test-run/scripts/validate-run-env.sh +112 -0
  302. package/vendor/Server/Skills/rnoh-lib-code-adapt/SKILL.md +498 -0
  303. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/adapt-checklist.md +270 -0
  304. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/api-migration-checklist.md +164 -0
  305. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/common-compile-errors.md +556 -0
  306. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/deveco-cli-tools.md +459 -0
  307. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/edge-cases.md +65 -0
  308. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/har-tgz-build.md +512 -0
  309. package/vendor/Server/Skills/rnoh-lib-code-adapt/references/version-compat-matrix.md +132 -0
  310. package/vendor/Server/Skills/rnoh-lib-code-adapt/scripts/auto-integrate.sh +424 -0
  311. package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +137 -0
  312. package/vendor/Server/Skills/rnoh-lib-demo-create/SKILL.md +306 -0
  313. package/vendor/Server/Skills/rnoh-lib-demo-create/assets/DEMO_PAGE_TEMPLATE.md +485 -0
  314. package/vendor/Server/Skills/rnoh-lib-demo-create/assets/INDEX_TEMPLATE.md +172 -0
  315. package/vendor/Server/Skills/rnoh-lib-demo-create/references/DEMO_CODE_RULES.md +422 -0
  316. package/vendor/Server/Skills/rnoh-lib-demo-create/references/QUALITY_CHECKLIST.md +95 -0
  317. package/vendor/Server/Skills/rnoh-lib-demo-create/references/SOURCE_EXPLORATION.md +169 -0
  318. package/vendor/Server/Skills/rnoh-lib-demo-doc/SKILL.md +554 -0
  319. package/vendor/Server/Skills/rnoh-lib-demo-doc/assets/DEMO_DOC_TEMPLATE.md +106 -0
  320. package/vendor/Server/Skills/rnoh-lib-demo-doc/references/COVERAGE_INCREMENTAL.md +216 -0
  321. package/vendor/Server/Skills/rnoh-lib-demo-doc/references/DEMO_DESIGN_RULES.md +413 -0
  322. package/vendor/Server/Skills/rnoh-lib-demo-doc/references/OUTPUT_FORMAT.md +269 -0
  323. package/vendor/Server/Skills/rnoh-lib-demo-doc/references/QUALITY_CHECKLIST.md +98 -0
  324. package/vendor/Server/Skills/rnoh-lib-func-test/SKILL.md +337 -0
  325. package/vendor/Server/Skills/rnoh-lib-rnt-search/SKILL.md +722 -0
  326. package/vendor/Server/Skills/rnoh-lib-rnt-search/assets/PORT_REPORT_TEMPLATE.md +219 -0
  327. package/vendor/Server/Skills/rnoh-lib-rnt-search/references/DEMO_PORTING_GUIDE.md +345 -0
  328. package/vendor/Server/Skills/rnoh-lib-rnt-search/references/PORT_VERIFICATION.md +269 -0
  329. package/vendor/Server/Skills/rnoh-lib-rnt-search/references/RNT_PROJECT_STRUCTURE.md +173 -0
  330. package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/analyze-demo-deps.cjs +267 -0
  331. package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/detect-rnoh-version.cjs +174 -0
  332. package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/find-rnt-demo.sh +111 -0
  333. package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/port-demo.sh +186 -0
  334. package/vendor/Server/Skills/rnoh-lib-rnt-search/scripts/read-lib-meta.cjs +150 -0
  335. package/vendor/Server/Skills/rnoh-lib-test-align/SKILL.md +296 -0
  336. package/vendor/Server/Skills/rnoh-lib-test-align/references/jest-troubleshooting.md +371 -0
  337. package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +212 -0
  338. package/vendor/Server/Skills/rnoh-lib-test-align/references/runtime-troubleshooting.md +345 -0
  339. package/vendor/Server/Skills/rnoh-lib-test-align/references/unit-test-template.md +223 -0
  340. package/vendor/Server/Skills/rnoh-lib-test-align/scripts/port-test-demo.sh +1053 -0
  341. package/vendor/Server/Skills/rnoh-lib-version-diff/SKILL.md +255 -0
  342. package/vendor/Server/Skills/rnoh-lib-version-diff/references/OHOS_ADAPTATION.md +77 -0
  343. package/vendor/Server/Skills/rnoh-lib-version-diff/references/OHOS_API_LOOKUP.md +224 -0
  344. package/vendor/Server/Skills/rnoh-lib-version-diff/references/script-reference.md +174 -0
  345. package/vendor/Server/Skills/rnoh-lib-version-diff/scripts/detect-upstream-version.js +967 -0
  346. package/vendor/Server/Skills/rnoh-lib-version-diff/scripts/generate-diff.js +1798 -0
  347. package/vendor/Server/Skills/rnoh-lib-version-diff/scripts/package.json +5 -0
  348. package/vendor/Server/Skills/rnoh-lib-version-diff/templates/report-template.md +137 -0
  349. package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +145 -0
  350. package/vendor/Server/Skills/skill-generator/SKILL.md +365 -0
  351. package/vendor/Server/Skills/skill-generator/assets/SKILL_TEMPLATE.md +183 -0
  352. package/vendor/Server/Skills/skill-generator/references/COMPLIANCE_CHECKLIST.md +82 -0
  353. package/vendor/Server/Skills/skill-generator/references/KB_QUERY_GUIDE.md +110 -0
  354. package/vendor/Server/Skills/skill-generator/references/MCP_TOOL_DISCOVERY.md +122 -0
  355. package/vendor/Server/Skills/skill-generator/references/SKILL_SPEC.md +121 -0
  356. package/vendor/Server/Skills/skill-generator/scripts/validate-skill.cjs +259 -0
  357. package/vendor/Server/Skills/task-analysis/SKILL.md +234 -0
  358. package/vendor/Server/Skills/task-analysis/assets/OUTPUT_EXAMPLES.md +160 -0
  359. package/vendor/Server/Skills/task-analysis/references/ACCEPTANCE_CRITERIA_GUIDE.md +190 -0
  360. package/vendor/Server/Skills/task-analysis/references/ANALYSIS_SCHEMA.md +224 -0
  361. package/vendor/Server/Skills/task-analysis/references/INTEGRATION_CONTEXT.md +162 -0
  362. package/vendor/Server/Skills/task-analysis/references/LESSONS_LEARNED.md +55 -0
  363. package/vendor/Server/Skills/task-analysis/references/REPLAN_CONTEXT_GUIDE.md +126 -0
  364. package/vendor/Server/Skills/task-analysis/scripts/validate-analysis-output.sh +256 -0
  365. package/vendor/Server/Skills/task-decomposition/SKILL.md +529 -0
  366. package/vendor/Server/Skills/task-decomposition/assets/OUTPUT_EXAMPLES.md +451 -0
  367. package/vendor/Server/Skills/task-decomposition/references/ACCEPTANCE_CRITERIA_GUIDE.md +179 -0
  368. package/vendor/Server/Skills/task-decomposition/references/DEPENDENCY_GRAPH_GUIDE.md +152 -0
  369. package/vendor/Server/Skills/task-decomposition/references/INTEGRATION_CONTEXT.md +175 -0
  370. package/vendor/Server/Skills/task-decomposition/references/REPLAN_CONTEXT_GUIDE.md +195 -0
  371. package/vendor/Server/Skills/task-decomposition/references/TASK_DECOMPOSITION_TEMPLATES.md +226 -0
  372. package/vendor/Server/Skills/task-decomposition/scripts/list-available-skills.cjs +263 -0
  373. package/vendor/Server/Skills/task-decomposition/scripts/skill-blacklist.json +29 -0
  374. package/vendor/Server/Skills/task-decomposition/scripts/validate-decomposition-output.cjs +376 -0
  375. package/vendor/Server/Skills/task-decomposition/scripts/validate-param-consistency.cjs +259 -0
  376. package/vendor/Server/Skills/task-decomposition/scripts/validate-specified-skills.cjs +216 -0
  377. package/vendor/Server/Skills/task-decomposition/scripts/validate-step-graph.cjs +425 -0
  378. package/vendor/Server/Skills/tpc-cpp-check/SKILL.md +427 -0
  379. package/vendor/Server/Skills/tpc-cpp-check/references/CHECKLIST.md +214 -0
  380. package/vendor/Server/Skills/tpc-cpp-check/references/HPKBUILD_GUIDE.md +235 -0
  381. package/vendor/Server/Skills/tpc-cpp-check/references/REPORT_TEMPLATE.md +250 -0
  382. package/vendor/Server/TestCheck/TestCheck.js +775 -0
  383. package/vendor/Server/TestCheck/index.js +11 -0
  384. package/vendor/Server/library/McpToolGuide.js +280 -0
  385. package/vendor/Server/library/StatsService.js +127 -0
  386. package/vendor/Server/library/cstTime.js +16 -0
  387. package/vendor/Server/package.json +17 -0
  388. package/vendor/VERSION +3 -0
  389. package/workflows/pr-check.mjs +106 -0
@@ -0,0 +1,851 @@
1
+ /**
2
+ * migrate.cjs — 鸿蒙历史工程手动迁移脚本(API 9 + API 10+)。
3
+ *
4
+ * 依据华为官方 Manual Migration 流程,原地修改工程文件,完成一体化迁移:
5
+ * 1. 删除工程级 build-profile.json5 的 compileSdkVersion(OpenHarmony 工程跳过)
6
+ * 2. [API 9] 迁移 compatibleSdkVersion/targetSdkVersion 到 product,强制 runtimeOS=HarmonyOS
7
+ * 3. [API 9] 清理各模块级 build-profile.json5 中 targets[].runtimeOS
8
+ * 4. 强制所有 product compatibleSdkVersion/targetSdkVersion(由参数指定)+ runtimeOS=HarmonyOS
9
+ * 5. 删除 hvigorw / hvigorw.bat / hvigor/hvigor-wrapper.js
10
+ * 6. hvigor/hvigor-config.json5:新增 modelVersion(由参数指定),删除 hvigorVersion + dependencies 中 @ohos/hvigor-ohos-plugin/rollup
11
+ * 7. 工程级 oh-package.json5:新增 modelVersion(由参数指定)
12
+ * 8. local.properties:删除 HarmonyOS SDK 配置(OpenHarmony 工程跳过)
13
+ *
14
+ * 用法:
15
+ * node migrate.cjs --source <工程根路径> [--compatible-api <N>] [--target-api <N>] [--openharmony]
16
+ *
17
+ * 参数说明:
18
+ * --compatible-api <N> 设备 API 版本(如 23),用于 compatibleSdkVersion。
19
+ * 不传则 = target-api(向后兼容)。
20
+ * --target-api <N> 已安装 SDK API 版本(如 24),用于 targetSdkVersion 和 modelVersion。
21
+ * 不传则自动探测已安装 SDK(探测失败默认 24)。
22
+ *
23
+ * 参考:
24
+ * https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V13/ide-integrated-project-migration-V13
25
+ */
26
+
27
+ const fs = require('fs');
28
+ const path = require('path');
29
+ const { execSync } = require('child_process');
30
+
31
+ // ── 常量 ────────────────────────────────────────────────────
32
+ const RUNTIME_OS = 'HarmonyOS';
33
+
34
+ // API → 平台版本映射表(来源:HarmonyOS 版本说明 overview-allversion)
35
+ const API_VERSION_MAP = {
36
+ 12: '5.0.0', 13: '5.0.1', 14: '5.0.2', 15: '5.0.3',
37
+ 16: '5.0.4', 17: '5.0.5', 18: '5.1.0', 19: '5.1.1',
38
+ 20: '6.0.0', 21: '6.0.1', 22: '6.0.2', 23: '6.1.0', 24: '6.1.1',
39
+ };
40
+
41
+ // 默认值,在 parseArgs() 后由 --compatible-api / --target-api 参数覆盖
42
+ let MODEL_VERSION = '6.1.1';
43
+ let COMPATIBLE_SDK_VERSION = '6.1.1(24)';
44
+ let TARGET_SDK_VERSION = '6.1.1(24)';
45
+
46
+ // ── SDK 版本自动探测 ────────────────────────────────────────
47
+
48
+ /**
49
+ * 自动探测已安装 SDK 的 API 版本。
50
+ * 通过 where.exe hdc 反推 DevEco 目录,读取 oh-uni-package.json。
51
+ * @returns {{api: number, version: string}|null}
52
+ */
53
+ function detectInstalledSdkApi() {
54
+ try {
55
+ const hdcPath = execSync('where.exe hdc', { encoding: 'utf-8' })
56
+ .trim().split(/\r?\n/)[0].trim();
57
+ const idx = hdcPath.indexOf('\\sdk');
58
+ if (idx <= 0) return null;
59
+ const devEcoDir = hdcPath.substring(0, idx);
60
+ const ohUniPath = path.join(devEcoDir, 'sdk', 'default',
61
+ 'openharmony', 'ets', 'oh-uni-package.json');
62
+ if (!fs.existsSync(ohUniPath)) return null;
63
+ const content = JSON.parse(fs.readFileSync(ohUniPath, 'utf-8'));
64
+ return { api: parseInt(content.apiVersion), version: content.version };
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+
70
+ // ── 参数解析 ────────────────────────────────────────────────
71
+
72
+ /**
73
+ * 解析 --key value 形式的命令行参数;--flag 形式的布尔参数值为 true。
74
+ * @returns {Record<string, string|true>}
75
+ */
76
+ function parseArgs() {
77
+ const args = process.argv.slice(2);
78
+ const parsed = {};
79
+ for (let i = 0; i < args.length; i++) {
80
+ if (args[i].startsWith('--')) {
81
+ const key = args[i].substring(2);
82
+ if (i + 1 < args.length && !args[i + 1].startsWith('--')) {
83
+ parsed[key] = args[i + 1];
84
+ i++;
85
+ } else {
86
+ parsed[key] = true;
87
+ }
88
+ }
89
+ }
90
+ return parsed;
91
+ }
92
+
93
+ // ── JSON5 文本操作工具 ──────────────────────────────────────
94
+
95
+ /**
96
+ * JSON5 兼容的文本操作工具集。所有方法均基于正则 + 文本替换,
97
+ * 不引入 json5 npm 依赖(与项目零原生依赖风格一致)。
98
+ *
99
+ * 设计约束:
100
+ * - 不破坏 JSON5 注释(// 或 /* *\/)
101
+ * - 处理尾逗号,避免遗留语法错误
102
+ * - 仅在明确锚点位置插入,不重排已有字段
103
+ */
104
+
105
+ /**
106
+ * 删除对象中的指定顶层字段(形如 `"field": value,` 或 `field: value,`)。
107
+ * 同时清理删除后遗留的多余逗号/空行。
108
+ * @param {string} content 原始文本
109
+ * @param {string} field 字段名
110
+ * @returns {string} 处理后的文本
111
+ */
112
+ function removeField(content, field) {
113
+ const escaped = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
114
+ // 匹配 "field": value, 或 field: value,(value 不含未转义的 , 或 })
115
+ // 允许键带引号或不带引号;值允许含字符串、数字、布尔、数组、嵌套对象之外的简单值
116
+ const patterns = [
117
+ // 带引号键,值含字符串/数字/布尔/null
118
+ new RegExp(`^[ \\t]*"${escaped}"\\s*:\\s*[^,}\\n]+,?[ \\t]*\\r?\\n`, 'gm'),
119
+ // 不带引号键
120
+ new RegExp(`^[ \\t]*${escaped}\\s*:\\s*[^,}\\n]+,?[ \\t]*\\r?\\n`, 'gm'),
121
+ ];
122
+ let result = content;
123
+ for (const p of patterns) {
124
+ result = result.replace(p, '');
125
+ }
126
+ return result;
127
+ }
128
+
129
+ /**
130
+ * 删除对象中指定字段(值可能含逗号,如嵌套对象/数组)。采用括号配对算法删除整段。
131
+ * 用于删除 dependencies 中的 `@ohos/hvigor-ohos-plugin` 等含特殊字符的键。
132
+ * @param {string} content 原始文本
133
+ * @param {string} field 字段名(原样匹配,需含引号则传入含引号形式)
134
+ * @returns {string}
135
+ */
136
+ function removeFieldWithBrackets(content, field) {
137
+ const escaped = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
138
+ const re = new RegExp(`^(\\s*)${escaped}\\s*:\\s*`, 'm');
139
+ const match = re.exec(content);
140
+ if (!match) return content;
141
+
142
+ const start = match.index + match[1].length;
143
+ const valueStart = match.index + match[0].length;
144
+ // 从值开始配对括号,找出字段结束位置
145
+ let depth = 0;
146
+ let inString = false;
147
+ let quoteChar = '';
148
+ let i = valueStart;
149
+ for (; i < content.length; i++) {
150
+ const ch = content[i];
151
+ if (inString) {
152
+ if (ch === '\\') { i++; continue; }
153
+ if (ch === quoteChar) inString = false;
154
+ continue;
155
+ }
156
+ if (ch === '"' || ch === "'") { inString = true; quoteChar = ch; continue; }
157
+ if (ch === '{' || ch === '[') { depth++; continue; }
158
+ if (ch === '}' || ch === ']') {
159
+ depth--;
160
+ if (depth < 0) break; // 越过本字段,遇到外层闭合
161
+ continue;
162
+ }
163
+ if (depth === 0 && ch === ',') { i++; break; }
164
+ if (depth === 0 && (ch === '\n' || ch === '}')) break;
165
+ }
166
+ // i 现在指向字段结束后的位置(逗号后或换行/闭合前)
167
+ // 回溯 start 之前找行首
168
+ let lineStart = start;
169
+ while (lineStart > 0 && content[lineStart - 1] !== '\n') lineStart--;
170
+ // 前进 i 到行尾
171
+ let lineEnd = i;
172
+ while (lineEnd < content.length && content[lineEnd] !== '\n') lineEnd++;
173
+ if (lineEnd < content.length) lineEnd++; // 含换行
174
+ return content.slice(0, lineStart) + content.slice(lineEnd);
175
+ }
176
+
177
+ /**
178
+ * 在指定父对象闭合 `}` 前插入新字段。
179
+ * @param {string} content 原始文本
180
+ * @param {string} parentAnchor 父对象的开始锚点(正则字符串,匹配父对象首行如 `"app"\s*:\s*\{`)
181
+ * @param {string} fieldText 要插入的字段文本(如 ` "modelVersion": "5.0.4",\n`)
182
+ * @returns {string}
183
+ */
184
+ function insertFieldBeforeClose(content, parentAnchor, fieldText) {
185
+ // 定位父对象开始
186
+ const startRe = new RegExp(parentAnchor);
187
+ const startMatch = startRe.exec(content);
188
+ if (!startMatch) return content;
189
+
190
+ // 从父对象开始处配对括号找闭合 }
191
+ let depth = 0;
192
+ let inString = false;
193
+ let quoteChar = '';
194
+ let closeIdx = -1;
195
+ for (let i = startMatch.index + startMatch[0].length - 1; i < content.length; i++) {
196
+ const ch = content[i];
197
+ if (inString) {
198
+ if (ch === '\\') { i++; continue; }
199
+ if (ch === quoteChar) inString = false;
200
+ continue;
201
+ }
202
+ if (ch === '"' || ch === "'") { inString = true; quoteChar = ch; continue; }
203
+ if (ch === '{' || ch === '[') { depth++; continue; }
204
+ if (ch === '}' || ch === ']') {
205
+ depth--;
206
+ if (depth === 0) { closeIdx = i; break; }
207
+ continue;
208
+ }
209
+ }
210
+ if (closeIdx === -1) return content;
211
+
212
+ // 找到闭合 } 前的最后一个非空字符位置,判断是否需要补逗号
213
+ let insertPos = closeIdx;
214
+ while (insertPos > 0 && /\s/.test(content[insertPos - 1])) insertPos--;
215
+ // 检查前一个非空字符是否为 { 或 ,(决定是否补逗号)
216
+ const prefix = content[insertPos - 1];
217
+ const needsComma = prefix !== '{' && prefix !== ',';
218
+
219
+ // 字段缩进 = 闭合 } 所在行缩进 + 一级缩进(2 空格)
220
+ const lineStart = (() => {
221
+ let p = closeIdx;
222
+ while (p > 0 && content[p - 1] !== '\n') p--;
223
+ return p;
224
+ })();
225
+ const closeIndent = content.slice(lineStart, closeIdx).match(/^\s*/)[0];
226
+ const fieldIndent = closeIndent + ' ';
227
+ // 插入内容不含末尾 \n:content.slice(insertPos) 已以 \n + closeIndent 开头
228
+ // fieldText 使用 trimStart() 去前导空白(保留尾部逗号)
229
+ const insertion = (needsComma ? ',' : '') + '\n' + fieldIndent + fieldText.trimStart();
230
+ return content.slice(0, insertPos) + insertion + content.slice(insertPos);
231
+ }
232
+
233
+ /**
234
+ * 提取字段的值(字符串/数字/布尔/null)。仅处理简单值,不处理嵌套。
235
+ * @param {string} content
236
+ * @param {string} field
237
+ * @returns {string|null} 值文本,未找到返回 null
238
+ */
239
+ function getFieldValue(content, field) {
240
+ const escaped = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
241
+ const patterns = [
242
+ new RegExp(`"${escaped}"\\s*:\\s*("([^"\\\\]|\\\\.)*"|\\d+|true|false|null)`),
243
+ new RegExp(`\\b${escaped}\\s*:\\s*("([^"\\\\]|\\\\.)*"|\\d+|true|false|null)`),
244
+ ];
245
+ for (const p of patterns) {
246
+ const m = p.exec(content);
247
+ if (m) return m[1];
248
+ }
249
+ return null;
250
+ }
251
+
252
+ /**
253
+ * 设置/覆盖字段的值(简单值)。若字段不存在则插入到指定锚点对象闭合前。
254
+ * @param {string} content
255
+ * @param {string} field 字段名(不带引号)
256
+ * @param {string} valueText 值文本(如 `"HarmonyOS"`、`"5.0.4"`、`16`)
257
+ * @param {string} parentAnchor 插入锚点(父对象开始正则)
258
+ * @param {string} indent 缩进
259
+ * @returns {string}
260
+ */
261
+ function setFieldValue(content, field, valueText, parentAnchor, indent) {
262
+ const escaped = field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
263
+ // 检测字段键是否已存在(带引号或不带引号)。依据存在性决定替换或插入,
264
+ // 而非"替换后文本是否变化"——因为值恰好与目标值相同时替换无变化,
265
+ // 若据此误判为不存在会重复插入同一字段。
266
+ const existsRe = new RegExp(`^[ \\t]*("?${escaped}"?\\s*:)`, 'gm');
267
+ const existsMatch = existsRe.exec(content);
268
+ if (existsMatch) {
269
+ // 已存在:仅替换该行值(保留引号键/无引号键原样)
270
+ const replaceRe = new RegExp(`(^[ \\t]*"?${escaped}"?\\s*:\\s*)[^,}\\n]+`, 'gm');
271
+ return content.replace(replaceRe, `$1${valueText}`);
272
+ }
273
+ // 不存在 → 插入到指定父对象闭合前
274
+ return insertFieldBeforeClose(content, parentAnchor, `${indent}"${field}": ${valueText},`);
275
+ }
276
+
277
+ // ── 工程检测 ────────────────────────────────────────────────
278
+
279
+ /**
280
+ * 读取文件文本,文件不存在返回 null。
281
+ * @param {string} filePath
282
+ * @returns {string|null}
283
+ */
284
+ function readFileSafe(filePath) {
285
+ try {
286
+ return fs.readFileSync(filePath, 'utf-8');
287
+ } catch {
288
+ return null;
289
+ }
290
+ }
291
+
292
+ /**
293
+ * 检测工程类型与 API 版本。
294
+ * @param {string} projectRoot
295
+ * @param {boolean} openHarmonyFlag
296
+ * @returns {{apiLevel: '9'|'10+', isOpenHarmony: boolean, hasLocalProperties: boolean}}
297
+ */
298
+ function detectProject(projectRoot, openHarmonyFlag) {
299
+ const bpPath = path.join(projectRoot, 'build-profile.json5');
300
+ const content = readFileSafe(bpPath) || '';
301
+ const localProps = readFileSafe(path.join(projectRoot, 'local.properties')) || '';
302
+
303
+ // OpenHarmony 检测
304
+ let isOpenHarmony = !!openHarmonyFlag;
305
+ if (!isOpenHarmony) {
306
+ // local.properties 中含 HarmonyOS SDK 配置 → 非 OpenHarmony
307
+ const hasHarmonySdk = /HarmonyOS\s+SDK/i.test(localProps);
308
+ isOpenHarmony = !hasHarmonySdk && localProps.length > 0 && !hasHarmonySdk;
309
+ // 若 local.properties 不存在或无 HarmonyOS SDK 配置,视为 OpenHarmony
310
+ // 但若用户未传 --openharmony 且文件无 SDK 配置,保守判定为 OpenHarmony
311
+ if (localProps.length === 0) isOpenHarmony = false; // 无文件不判定
312
+ else isOpenHarmony = !hasHarmonySdk;
313
+ }
314
+
315
+ // API 9 检测
316
+ const appCompat = getFieldValue(content, 'compatibleSdkVersion');
317
+ const appTarget = getFieldValue(content, 'targetSdkVersion');
318
+ const appCompile = getFieldValue(content, 'compileSdkVersion');
319
+ const productCompat = content.match(/"compatibleSdkVersion"\s*:\s*("([^"\\]|\\.)*"|\d+)/g);
320
+
321
+ let apiLevel = '10+';
322
+ // API 9 判定:app 顶层 compatibleSdkVersion 为 9,或 product 中无 compatibleSdkVersion
323
+ const isAppCompat9 =
324
+ (appCompat === '9') || (appCompat === '"9"') ||
325
+ (appCompile === '9') || (appCompile === '"9"');
326
+ if (isAppCompat9 || (!productCompat && appCompat)) {
327
+ apiLevel = '9';
328
+ }
329
+ // 若 compileSdkVersion >= 10 且 product 中已有 compatibleSdkVersion,视为 10+
330
+ if (appCompile && parseInt(String(appCompile).replace(/["']/g, ''), 10) >= 10) {
331
+ apiLevel = '10+';
332
+ }
333
+
334
+ return {
335
+ apiLevel,
336
+ isOpenHarmony,
337
+ hasLocalProperties: localProps.length > 0,
338
+ };
339
+ }
340
+
341
+ // ── 迁移步骤实现 ────────────────────────────────────────────
342
+
343
+ /**
344
+ * 收集所有模块级 build-profile.json5 路径。
345
+ * 模块定义在工程级 build-profile.json5 的 modules[] 中,但简单遍历子目录更稳健。
346
+ * @param {string} projectRoot
347
+ * @returns {string[]} 模块级 build-profile.json5 绝对路径列表
348
+ */
349
+ function findModuleBuildProfiles(projectRoot) {
350
+ const results = [];
351
+ const entries = fs.readdirSync(projectRoot, { withFileTypes: true });
352
+ for (const entry of entries) {
353
+ if (!entry.isDirectory()) continue;
354
+ if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;
355
+ const moduleBp = path.join(projectRoot, entry.name, 'build-profile.json5');
356
+ if (fs.existsSync(moduleBp)) {
357
+ results.push(moduleBp);
358
+ }
359
+ }
360
+ return results;
361
+ }
362
+
363
+ /**
364
+ * 步骤:[API 9] 迁移 app 顶层 compatibleSdkVersion/targetSdkVersion 到每个 product,
365
+ * 值改为参数指定的版本,并强制 runtimeOS="HarmonyOS"。
366
+ * @param {string} bpPath
367
+ * @returns {string[]} 操作日志列表
368
+ */
369
+ function migrateApi9BuildProfile(bpPath) {
370
+ const logs = [];
371
+ let content = fs.readFileSync(bpPath, 'utf-8');
372
+ const rel = path.basename(path.dirname(bpPath));
373
+
374
+ // 删除 app 顶层 compatibleSdkVersion 与 targetSdkVersion
375
+ const before = content;
376
+ content = removeField(content, 'compatibleSdkVersion');
377
+ content = removeField(content, 'targetSdkVersion');
378
+ if (content !== before) {
379
+ logs.push(` ✅ ${rel}/build-profile.json5: 删除 app 顶层 compatibleSdkVersion/targetSdkVersion`);
380
+ }
381
+
382
+ // 对每个 product 强制 compatibleSdkVersion/targetSdkVersion/runtimeOS
383
+ // 锚点:app.products 数组的每个 { 开始处
384
+ // 简化处理:定位 "products" 数组,在每个 `{` 后插入字段
385
+ // 采用逐 product 处理:用正则匹配 product 项的 `{ ... }` 段
386
+ const productsAnchor = /"app"\s*:\s*\{[\s\S]*?"products"\s*:\s*\[/;
387
+ const productsMatch = productsAnchor.exec(content);
388
+ if (!productsMatch) {
389
+ logs.push(` ⚠️ ${rel}/build-profile.json5: 未找到 app.products 数组,跳过 product 配置`);
390
+ return { content: before, logs };
391
+ }
392
+
393
+ // 找到 products 数组闭合 ]
394
+ const arrayStart = productsMatch.index + productsMatch[0].length - 1; // 指向 [
395
+ let depth = 0;
396
+ let inString = false;
397
+ let quoteChar = '';
398
+ let arrayEnd = -1;
399
+ for (let i = arrayStart; i < content.length; i++) {
400
+ const ch = content[i];
401
+ if (inString) {
402
+ if (ch === '\\') { i++; continue; }
403
+ if (ch === quoteChar) inString = false;
404
+ continue;
405
+ }
406
+ if (ch === '"' || ch === "'") { inString = true; quoteChar = ch; continue; }
407
+ if (ch === '[' || ch === '{') { depth++; continue; }
408
+ if (ch === ']' || ch === '}') {
409
+ depth--;
410
+ if (depth === 0 && content[i] === ']') { arrayEnd = i; break; }
411
+ continue;
412
+ }
413
+ }
414
+ if (arrayEnd === -1) {
415
+ logs.push(` ⚠️ ${rel}/build-profile.json5: products 数组闭合 ] 未找到`);
416
+ return { content: before, logs };
417
+ }
418
+
419
+ // 在 products 数组文本内,对每个 product 项强制字段
420
+ const beforeProducts = content.slice(0, arrayStart);
421
+ const productsText = content.slice(arrayStart, arrayEnd + 1);
422
+ const afterProducts = content.slice(arrayEnd + 1);
423
+
424
+ // 对 productsText 中的每个 product(以 { 开始的对象)强制设置字段
425
+ // 用 insertFieldBeforeClose 逐个处理:找到每个 product 的闭合 }
426
+ // 简化:直接在 products 文本中对 "name" 锚点的每个对象插入字段
427
+ let newProducts = productsText;
428
+ // 强制每个 product 的 compatibleSdkVersion/targetSdkVersion/runtimeOS
429
+ // 通过正则定位每个 product 对象的开始 {
430
+ const productObjs = [];
431
+ let pdepth = 0;
432
+ let pinString = false;
433
+ let pquote = '';
434
+ let pObjStart = -1;
435
+ for (let i = 0; i < newProducts.length; i++) {
436
+ const ch = newProducts[i];
437
+ if (pinString) {
438
+ if (ch === '\\') { i++; continue; }
439
+ if (ch === pquote) pinString = false;
440
+ continue;
441
+ }
442
+ if (ch === '"' || ch === "'") { pinString = true; pquote = ch; continue; }
443
+ if (ch === '{') {
444
+ if (pdepth === 0) pObjStart = i;
445
+ pdepth++;
446
+ continue;
447
+ }
448
+ if (ch === '}') {
449
+ pdepth--;
450
+ if (pdepth === 0) {
451
+ productObjs.push({ start: pObjStart, end: i });
452
+ }
453
+ continue;
454
+ }
455
+ }
456
+
457
+ // 从后往前处理(避免索引偏移)
458
+ let productCount = 0;
459
+ for (let idx = productObjs.length - 1; idx >= 0; idx--) {
460
+ const { start, end } = productObjs[idx];
461
+ const objText = newProducts.slice(start, end + 1);
462
+ let newObj = objText;
463
+ // 清理 product 内残留的 compileSdkVersion(HarmonyOS 新 SDK 中该字段非必须,
464
+ // 旧工程/AI 可能预置数字或字符串,导致同一对象出现重复键)
465
+ newObj = removeField(newObj, 'compileSdkVersion');
466
+ // 强制 compatibleSdkVersion
467
+ newObj = setFieldValue(newObj, 'compatibleSdkVersion', `"${COMPATIBLE_SDK_VERSION}"`, '^\\{', ' ');
468
+ // 强制 targetSdkVersion
469
+ newObj = setFieldValue(newObj, 'targetSdkVersion', `"${TARGET_SDK_VERSION}"`, '^\\{', ' ');
470
+ // 强制 runtimeOS
471
+ newObj = setFieldValue(newObj, 'runtimeOS', `"${RUNTIME_OS}"`, '^\\{', ' ');
472
+ newProducts = newProducts.slice(0, start) + newObj + newProducts.slice(end + 1);
473
+ productCount++;
474
+ }
475
+ logs.push(` ✅ ${rel}/build-profile.json5: ${productCount} 个 product 迁移 compatibleSdkVersion=${COMPATIBLE_SDK_VERSION} + runtimeOS=HarmonyOS`);
476
+
477
+ content = beforeProducts + newProducts + afterProducts;
478
+ return { content, logs };
479
+ }
480
+
481
+ /**
482
+ * 步骤:[API 9] 清理各模块级 build-profile.json5 中 targets[].runtimeOS。
483
+ * @param {string[]} moduleBpPaths
484
+ * @returns {string[]} 操作日志
485
+ */
486
+ function cleanModuleTargetsRuntimeOS(moduleBpPaths) {
487
+ const logs = [];
488
+ for (const bpPath of moduleBpPaths) {
489
+ const content = fs.readFileSync(bpPath, 'utf-8');
490
+ const rel = path.relative(path.dirname(path.dirname(bpPath)), bpPath);
491
+ // 删除 targets 内的 runtimeOS 字段
492
+ // 简化:直接在整个文件中删除 "runtimeOS" 字段(模块级文件中 runtimeOS 只应出现在 targets 内)
493
+ const before = content;
494
+ const after = removeField(content, 'runtimeOS');
495
+ if (before !== after) {
496
+ fs.writeFileSync(bpPath, after, 'utf-8');
497
+ logs.push(` ✅ ${rel}: 清理 targets[].runtimeOS`);
498
+ } else {
499
+ logs.push(` ⏭️ ${rel}: 无 runtimeOS 字段,跳过`);
500
+ }
501
+ }
502
+ return logs;
503
+ }
504
+
505
+ /**
506
+ * 步骤:删除工程级 compileSdkVersion。
507
+ * @param {string} bpPath
508
+ * @returns {string[]} 操作日志
509
+ */
510
+ function removeCompileSdkVersion(bpPath) {
511
+ const logs = [];
512
+ let content = fs.readFileSync(bpPath, 'utf-8');
513
+ const before = content;
514
+ content = removeField(content, 'compileSdkVersion');
515
+ if (content !== before) {
516
+ fs.writeFileSync(bpPath, content, 'utf-8');
517
+ logs.push(` ✅ ${path.basename(path.dirname(bpPath))}/build-profile.json5: 删除 compileSdkVersion`);
518
+ } else {
519
+ logs.push(` ⏭️ ${path.basename(path.dirname(bpPath))}/build-profile.json5: 无 compileSdkVersion,跳过`);
520
+ }
521
+ return logs;
522
+ }
523
+
524
+ /**
525
+ * 步骤:强制所有 product 的 compatibleSdkVersion/targetSdkVersion/runtimeOS。
526
+ * - compatibleSdkVersion = 参数指定的版本(满足 M.S.F(X) 规则的字符串)
527
+ * - targetSdkVersion = 参数指定的版本
528
+ * - runtimeOS = "HarmonyOS"
529
+ * 不论原值是数字、字符串、缺失还是其他,统一覆盖。
530
+ * @param {string} bpPath
531
+ * @returns {string[]} 操作日志
532
+ */
533
+ function forceProductSdkConfig(bpPath) {
534
+ const logs = [];
535
+ let content = fs.readFileSync(bpPath, 'utf-8');
536
+ const rel = `${path.basename(path.dirname(bpPath))}/build-profile.json5`;
537
+
538
+ // 定位 products 数组
539
+ const productsAnchor = /"app"\s*:\s*\{[\s\S]*?"products"\s*:\s*\[/;
540
+ const productsMatch = productsAnchor.exec(content);
541
+ if (!productsMatch) {
542
+ logs.push(` ⚠️ ${rel}: 未找到 app.products 数组,跳过 SDK 配置强制设置`);
543
+ return logs;
544
+ }
545
+
546
+ const arrayStart = productsMatch.index + productsMatch[0].length - 1;
547
+ let depth = 0;
548
+ let inString = false;
549
+ let quoteChar = '';
550
+ let arrayEnd = -1;
551
+ for (let i = arrayStart; i < content.length; i++) {
552
+ const ch = content[i];
553
+ if (inString) {
554
+ if (ch === '\\') { i++; continue; }
555
+ if (ch === quoteChar) inString = false;
556
+ continue;
557
+ }
558
+ if (ch === '"' || ch === "'") { inString = true; quoteChar = ch; continue; }
559
+ if (ch === '[' || ch === '{') { depth++; continue; }
560
+ if (ch === ']' || ch === '}') {
561
+ depth--;
562
+ if (depth === 0 && content[i] === ']') { arrayEnd = i; break; }
563
+ continue;
564
+ }
565
+ }
566
+ if (arrayEnd === -1) {
567
+ logs.push(` ⚠️ ${rel}: products 数组闭合 ] 未找到`);
568
+ return logs;
569
+ }
570
+
571
+ const beforeProducts = content.slice(0, arrayStart);
572
+ let productsText = content.slice(arrayStart, arrayEnd + 1);
573
+ const afterProducts = content.slice(arrayEnd + 1);
574
+
575
+ // 对每个 product 对象强制 compatibleSdkVersion/targetSdkVersion/runtimeOS
576
+ const productObjs = [];
577
+ let pdepth = 0;
578
+ let pinString = false;
579
+ let pquote = '';
580
+ let pObjStart = -1;
581
+ for (let i = 0; i < productsText.length; i++) {
582
+ const ch = productsText[i];
583
+ if (pinString) {
584
+ if (ch === '\\') { i++; continue; }
585
+ if (ch === pquote) pinString = false;
586
+ continue;
587
+ }
588
+ if (ch === '"' || ch === "'") { pinString = true; pquote = ch; continue; }
589
+ if (ch === '{') {
590
+ if (pdepth === 0) pObjStart = i;
591
+ pdepth++;
592
+ continue;
593
+ }
594
+ if (ch === '}') {
595
+ pdepth--;
596
+ if (pdepth === 0) productObjs.push({ start: pObjStart, end: i });
597
+ continue;
598
+ }
599
+ }
600
+
601
+ let count = 0;
602
+ for (let idx = productObjs.length - 1; idx >= 0; idx--) {
603
+ const { start, end } = productObjs[idx];
604
+ const objText = productsText.slice(start, end + 1);
605
+ let newObj = objText;
606
+ // 清理 product 内残留的 compileSdkVersion,避免同一对象出现数字+字符串重复键
607
+ newObj = removeField(newObj, 'compileSdkVersion');
608
+ newObj = setFieldValue(newObj, 'compatibleSdkVersion', `"${COMPATIBLE_SDK_VERSION}"`, '^\\{', ' ');
609
+ newObj = setFieldValue(newObj, 'targetSdkVersion', `"${TARGET_SDK_VERSION}"`, '^\\{', ' ');
610
+ newObj = setFieldValue(newObj, 'runtimeOS', `"${RUNTIME_OS}"`, '^\\{', ' ');
611
+ productsText = productsText.slice(0, start) + newObj + productsText.slice(end + 1);
612
+ count++;
613
+ }
614
+ content = beforeProducts + productsText + afterProducts;
615
+ fs.writeFileSync(bpPath, content, 'utf-8');
616
+ logs.push(` ✅ ${rel}: 强制 ${count} 个 product compatibleSdkVersion=${COMPATIBLE_SDK_VERSION}/targetSdkVersion=${TARGET_SDK_VERSION} + runtimeOS=${RUNTIME_OS}`);
617
+ return logs;
618
+ }
619
+
620
+ /**
621
+ * 步骤:删除 hvigor 相关文件。
622
+ * @param {string} projectRoot
623
+ * @returns {string[]} 操作日志
624
+ */
625
+ function removeHvigorFiles(projectRoot) {
626
+ const logs = [];
627
+ const targets = [
628
+ path.join(projectRoot, 'hvigorw'),
629
+ path.join(projectRoot, 'hvigorw.bat'),
630
+ path.join(projectRoot, 'hvigor', 'hvigor-wrapper.js'),
631
+ ];
632
+ for (const t of targets) {
633
+ const rel = path.relative(projectRoot, t);
634
+ if (fs.existsSync(t)) {
635
+ fs.rmSync(t, { force: true });
636
+ logs.push(` ✅ 删除 ${rel}`);
637
+ } else {
638
+ logs.push(` ⏭️ ${rel} 不存在,跳过`);
639
+ }
640
+ }
641
+ return logs;
642
+ }
643
+
644
+ /**
645
+ * 步骤:修改 hvigor/hvigor-config.json5。
646
+ * 新增 modelVersion(由参数指定);删除 hvigorVersion;删除 dependencies 中 @ohos/hvigor-ohos-plugin 与 rollup。
647
+ * @param {string} projectRoot
648
+ * @returns {string[]} 操作日志
649
+ */
650
+ function patchHvigorConfig(projectRoot) {
651
+ const logs = [];
652
+ const cfgPath = path.join(projectRoot, 'hvigor', 'hvigor-config.json5');
653
+ if (!fs.existsSync(cfgPath)) {
654
+ logs.push(` ⚠️ hvigor/hvigor-config.json5 不存在,跳过`);
655
+ return logs;
656
+ }
657
+ let content = fs.readFileSync(cfgPath, 'utf-8');
658
+ const before = content;
659
+
660
+ // 新增/覆盖 modelVersion
661
+ content = setFieldValue(content, 'modelVersion', `"${MODEL_VERSION}"`, '^\\{', '');
662
+ if (content !== before) {
663
+ logs.push(` ✅ hvigor/hvigor-config.json5: 新增/覆盖 modelVersion=${MODEL_VERSION}`);
664
+ }
665
+
666
+ // 删除 hvigorVersion
667
+ const beforeHv = content;
668
+ content = removeField(content, 'hvigorVersion');
669
+ if (content !== beforeHv) {
670
+ logs.push(` ✅ hvigor/hvigor-config.json5: 删除 hvigorVersion`);
671
+ } else {
672
+ logs.push(` ⏭️ hvigor/hvigor-config.json5: 无 hvigorVersion,跳过`);
673
+ }
674
+
675
+ // 删除 dependencies 中 @ohos/hvigor-ohos-plugin 与 rollup
676
+ const depKeys = ['"@ohos/hvigor-ohos-plugin"', "'@ohos/hvigor-ohos-plugin'", '"rollup"', "'rollup'"];
677
+ for (const key of depKeys) {
678
+ const beforeDep = content;
679
+ content = removeFieldWithBrackets(content, key);
680
+ if (content !== beforeDep) {
681
+ logs.push(` ✅ hvigor/hvigor-config.json5: 删除 dependencies.${key}`);
682
+ }
683
+ }
684
+
685
+ if (content !== before) {
686
+ fs.writeFileSync(cfgPath, content, 'utf-8');
687
+ }
688
+ return logs;
689
+ }
690
+
691
+ /**
692
+ * 步骤:工程级 oh-package.json5 新增 modelVersion(由参数指定)。
693
+ * @param {string} projectRoot
694
+ * @returns {string[]}
695
+ */
696
+ function patchOhPackage(projectRoot) {
697
+ const logs = [];
698
+ const pkgPath = path.join(projectRoot, 'oh-package.json5');
699
+ if (!fs.existsSync(pkgPath)) {
700
+ logs.push(` ⚠️ oh-package.json5 不存在,跳过`);
701
+ return logs;
702
+ }
703
+ let content = fs.readFileSync(pkgPath, 'utf-8');
704
+ const before = content;
705
+ content = setFieldValue(content, 'modelVersion', `"${MODEL_VERSION}"`, '^\\{', '');
706
+ if (content !== before) {
707
+ fs.writeFileSync(pkgPath, content, 'utf-8');
708
+ logs.push(` ✅ oh-package.json5: 新增/覆盖 modelVersion=${MODEL_VERSION}`);
709
+ } else {
710
+ logs.push(` ⏭️ oh-package.json5: modelVersion 已为 ${MODEL_VERSION},跳过`);
711
+ }
712
+ return logs;
713
+ }
714
+
715
+ /**
716
+ * 步骤:清理 local.properties 中 HarmonyOS SDK 配置行。
717
+ * @param {string} projectRoot
718
+ * @returns {string[]}
719
+ */
720
+ function cleanLocalProperties(projectRoot) {
721
+ const logs = [];
722
+ const lpPath = path.join(projectRoot, 'local.properties');
723
+ if (!fs.existsSync(lpPath)) {
724
+ logs.push(` ⏭️ local.properties 不存在,跳过`);
725
+ return logs;
726
+ }
727
+ const content = fs.readFileSync(lpPath, 'utf-8');
728
+ const lines = content.split(/\r?\n/);
729
+ // 删除含 HarmonyOS SDK 或 sdk.dir/harmonyos.sdk 等配置行
730
+ const filtered = lines.filter((line) => {
731
+ return !/HarmonyOS\s+SDK/i.test(line) &&
732
+ !/^sdk\.dir/i.test(line) &&
733
+ !/^harmonyos\.sdk/i.test(line);
734
+ });
735
+ if (filtered.length !== lines.length) {
736
+ fs.writeFileSync(lpPath, filtered.join('\n'), 'utf-8');
737
+ logs.push(` ✅ local.properties: 清理 ${lines.length - filtered.length} 行 HarmonyOS SDK 配置`);
738
+ } else {
739
+ logs.push(` ⏭️ local.properties: 无 HarmonyOS SDK 配置,跳过`);
740
+ }
741
+ return logs;
742
+ }
743
+
744
+ // ── 主流程 ──────────────────────────────────────────────────
745
+
746
+ /**
747
+ * 主迁移流程。
748
+ * @param {string} projectRoot
749
+ * @param {boolean} isOpenHarmony
750
+ * @param {'9'|'10+'} apiLevel
751
+ * @returns {string[]} 全部操作日志
752
+ */
753
+ function runMigration(projectRoot, isOpenHarmony, apiLevel) {
754
+ const allLogs = [];
755
+ const bpPath = path.join(projectRoot, 'build-profile.json5');
756
+
757
+ allLogs.push(`[migrate] 开始迁移工程: ${projectRoot}`);
758
+ allLogs.push(`[migrate] 检测: API ${apiLevel} 工程, ${isOpenHarmony ? 'OpenHarmony' : 'HarmonyOS'}`);
759
+
760
+ // [API 9] 迁移 build-profile.json5
761
+ if (apiLevel === '9') {
762
+ const { content, logs } = migrateApi9BuildProfile(bpPath);
763
+ allLogs.push(...logs);
764
+ fs.writeFileSync(bpPath, content, 'utf-8');
765
+
766
+ // 清理模块级 targets[].runtimeOS
767
+ const moduleBps = findModuleBuildProfiles(projectRoot);
768
+ allLogs.push(...cleanModuleTargetsRuntimeOS(moduleBps));
769
+ }
770
+
771
+ // [非 OpenHarmony] 删除工程级 compileSdkVersion
772
+ if (!isOpenHarmony) {
773
+ allLogs.push(...removeCompileSdkVersion(bpPath));
774
+ } else {
775
+ allLogs.push(` ⏭️ build-profile.json5: OpenHarmony 工程,跳过 compileSdkVersion 删除`);
776
+ }
777
+
778
+ // 强制所有 product 的 compatibleSdkVersion/targetSdkVersion + runtimeOS=HarmonyOS
779
+ allLogs.push(...forceProductSdkConfig(bpPath));
780
+
781
+ // 删除 hvigor 文件
782
+ allLogs.push(...removeHvigorFiles(projectRoot));
783
+
784
+ // 修改 hvigor-config.json5
785
+ allLogs.push(...patchHvigorConfig(projectRoot));
786
+
787
+ // 修改 oh-package.json5
788
+ allLogs.push(...patchOhPackage(projectRoot));
789
+
790
+ // [非 OpenHarmony] 清理 local.properties
791
+ if (!isOpenHarmony) {
792
+ allLogs.push(...cleanLocalProperties(projectRoot));
793
+ } else {
794
+ allLogs.push(` ⏭️ local.properties: OpenHarmony 工程,跳过 HarmonyOS SDK 清理`);
795
+ }
796
+
797
+ allLogs.push(`[migrate] SDK版本: compatibleSdkVersion=${COMPATIBLE_SDK_VERSION}, targetSdkVersion=${TARGET_SDK_VERSION}, runtimeOS=${RUNTIME_OS}`);
798
+ allLogs.push(`[migrate] 迁移完成。请在 DevEco Studio 中执行 Sync now 验证。`);
799
+ return allLogs;
800
+ }
801
+
802
+ // ── 入口 ────────────────────────────────────────────────────
803
+
804
+ const args = parseArgs();
805
+
806
+ // --- SDK 版本参数化 ---
807
+ // target-api: 优先用参数,否则自动探测已安装 SDK,探测失败默认 24
808
+ const sdkInfo = detectInstalledSdkApi();
809
+ const targetApi = args['target-api'] ? parseInt(String(args['target-api'])) : (sdkInfo ? sdkInfo.api : 24);
810
+ // compatible-api: 优先用参数,否则 = target-api(向后兼容)
811
+ const compatibleApi = args['compatible-api'] ? parseInt(String(args['compatible-api'])) : targetApi;
812
+
813
+ const _targetVer = API_VERSION_MAP[targetApi];
814
+ const _compatibleVer = API_VERSION_MAP[compatibleApi];
815
+ if (!_targetVer) {
816
+ console.error(`错误: 未知 target-api 版本 ${targetApi},API_VERSION_MAP 中无对应平台版本`);
817
+ process.exit(1);
818
+ }
819
+ if (!_compatibleVer) {
820
+ console.error(`错误: 未知 compatible-api 版本 ${compatibleApi},API_VERSION_MAP 中无对应平台版本`);
821
+ process.exit(1);
822
+ }
823
+ MODEL_VERSION = _targetVer;
824
+ COMPATIBLE_SDK_VERSION = `${_compatibleVer}(${compatibleApi})`;
825
+ TARGET_SDK_VERSION = `${_targetVer}(${targetApi})`;
826
+ // --- SDK 版本参数化结束 ---
827
+
828
+ if (!args.source || args.source === true) {
829
+ console.error('用法: node migrate.cjs --source <工程根路径> [--compatible-api <N>] [--target-api <N>] [--openharmony]');
830
+ process.exit(1);
831
+ }
832
+
833
+ const projectRoot = path.resolve(String(args.source));
834
+
835
+ if (!fs.existsSync(projectRoot) || !fs.statSync(projectRoot).isDirectory()) {
836
+ console.error(`错误: --source 路径不存在或非目录: ${projectRoot}`);
837
+ process.exit(1);
838
+ }
839
+
840
+ const bpPath = path.join(projectRoot, 'build-profile.json5');
841
+ if (!fs.existsSync(bpPath)) {
842
+ console.error(`错误: 未找到工程级 build-profile.json5: ${bpPath}`);
843
+ process.exit(1);
844
+ }
845
+
846
+ const { apiLevel, isOpenHarmony } = detectProject(projectRoot, args.openharmony === true);
847
+
848
+ const logs = runMigration(projectRoot, isOpenHarmony, apiLevel);
849
+ for (const line of logs) {
850
+ console.log(line);
851
+ }