soloforge 1.2.19 → 1.3.0

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 (719) hide show
  1. package/README.md +140 -3
  2. package/dist/adapters/claude_code/claude_md.d.ts +1 -2
  3. package/dist/adapters/claude_code/claude_md.d.ts.map +1 -1
  4. package/dist/adapters/claude_code/claude_md.js +47 -4
  5. package/dist/adapters/claude_code/claude_md.js.map +1 -1
  6. package/dist/adapters/claude_code/hooks.d.ts.map +1 -1
  7. package/dist/adapters/claude_code/hooks.js +2 -1
  8. package/dist/adapters/claude_code/hooks.js.map +1 -1
  9. package/dist/adapters/claude_code/server.js +4 -3
  10. package/dist/adapters/claude_code/server.js.map +1 -1
  11. package/dist/adapters/claude_code/tools.d.ts +255 -1
  12. package/dist/adapters/claude_code/tools.d.ts.map +1 -1
  13. package/dist/adapters/claude_code/tools.js +981 -7
  14. package/dist/adapters/claude_code/tools.js.map +1 -1
  15. package/dist/adapters/codex/codex_config.d.ts.map +1 -1
  16. package/dist/adapters/codex/codex_config.js +3 -2
  17. package/dist/adapters/codex/codex_config.js.map +1 -1
  18. package/dist/adapters/codex/codex_rules.d.ts.map +1 -1
  19. package/dist/adapters/codex/codex_rules.js +2 -1
  20. package/dist/adapters/codex/codex_rules.js.map +1 -1
  21. package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
  22. package/dist/adapters/shared/workflow_template.js +2 -1
  23. package/dist/adapters/shared/workflow_template.js.map +1 -1
  24. package/dist/adapters/trae/trae_config.d.ts +1 -6
  25. package/dist/adapters/trae/trae_config.d.ts.map +1 -1
  26. package/dist/adapters/trae/trae_config.js +3 -2
  27. package/dist/adapters/trae/trae_config.js.map +1 -1
  28. package/dist/adapters/trae/trae_rules.d.ts.map +1 -1
  29. package/dist/adapters/trae/trae_rules.js +2 -1
  30. package/dist/adapters/trae/trae_rules.js.map +1 -1
  31. package/dist/bin/config_commands.d.ts.map +1 -1
  32. package/dist/bin/config_commands.js +34 -33
  33. package/dist/bin/config_commands.js.map +1 -1
  34. package/dist/bin/soloforge.d.ts.map +1 -1
  35. package/dist/bin/soloforge.js +1110 -157
  36. package/dist/bin/soloforge.js.map +1 -1
  37. package/dist/engine/adapter_prompt_contract.d.ts +60 -0
  38. package/dist/engine/adapter_prompt_contract.d.ts.map +1 -0
  39. package/dist/engine/adapter_prompt_contract.js +163 -0
  40. package/dist/engine/adapter_prompt_contract.js.map +1 -0
  41. package/dist/engine/architecture_design_contract.d.ts +49 -0
  42. package/dist/engine/architecture_design_contract.d.ts.map +1 -0
  43. package/dist/engine/architecture_design_contract.js +169 -0
  44. package/dist/engine/architecture_design_contract.js.map +1 -0
  45. package/dist/engine/artifact_contract_registry.d.ts.map +1 -1
  46. package/dist/engine/artifact_contract_registry.js +7 -14
  47. package/dist/engine/artifact_contract_registry.js.map +1 -1
  48. package/dist/engine/{batch1_manifest.d.ts → asset_manifest.d.ts} +8 -8
  49. package/dist/engine/asset_manifest.d.ts.map +1 -0
  50. package/dist/engine/{batch1_manifest.js → asset_manifest.js} +52 -9
  51. package/dist/engine/asset_manifest.js.map +1 -0
  52. package/dist/engine/audit_pool.d.ts.map +1 -1
  53. package/dist/engine/audit_pool.js +6 -4
  54. package/dist/engine/audit_pool.js.map +1 -1
  55. package/dist/engine/audit_sampler.d.ts.map +1 -1
  56. package/dist/engine/audit_sampler.js +2 -1
  57. package/dist/engine/audit_sampler.js.map +1 -1
  58. package/dist/engine/audit_verifier.d.ts.map +1 -1
  59. package/dist/engine/audit_verifier.js +5 -4
  60. package/dist/engine/audit_verifier.js.map +1 -1
  61. package/dist/engine/brainstorm_contract.d.ts +46 -0
  62. package/dist/engine/brainstorm_contract.d.ts.map +1 -0
  63. package/dist/engine/brainstorm_contract.js +136 -0
  64. package/dist/engine/brainstorm_contract.js.map +1 -0
  65. package/dist/engine/capability_action_advisor.d.ts.map +1 -1
  66. package/dist/engine/capability_action_advisor.js +8 -7
  67. package/dist/engine/capability_action_advisor.js.map +1 -1
  68. package/dist/engine/capability_registry.d.ts.map +1 -1
  69. package/dist/engine/capability_registry.js +0 -7
  70. package/dist/engine/capability_registry.js.map +1 -1
  71. package/dist/engine/capability_state_store.d.ts.map +1 -1
  72. package/dist/engine/capability_state_store.js +7 -6
  73. package/dist/engine/capability_state_store.js.map +1 -1
  74. package/dist/engine/change_coordinator.d.ts.map +1 -1
  75. package/dist/engine/change_coordinator.js +4 -3
  76. package/dist/engine/change_coordinator.js.map +1 -1
  77. package/dist/engine/chinese_semantic_priority.d.ts +62 -0
  78. package/dist/engine/chinese_semantic_priority.d.ts.map +1 -0
  79. package/dist/engine/chinese_semantic_priority.js +153 -0
  80. package/dist/engine/chinese_semantic_priority.js.map +1 -0
  81. package/dist/engine/coding_readiness_gate.d.ts +46 -0
  82. package/dist/engine/coding_readiness_gate.d.ts.map +1 -0
  83. package/dist/engine/coding_readiness_gate.js +175 -0
  84. package/dist/engine/coding_readiness_gate.js.map +1 -0
  85. package/dist/engine/cognitive_anchor.d.ts.map +1 -1
  86. package/dist/engine/cognitive_anchor.js +7 -6
  87. package/dist/engine/cognitive_anchor.js.map +1 -1
  88. package/dist/engine/command_execution_contract.d.ts.map +1 -1
  89. package/dist/engine/command_execution_contract.js +13 -12
  90. package/dist/engine/command_execution_contract.js.map +1 -1
  91. package/dist/engine/confidence_scorer.d.ts.map +1 -1
  92. package/dist/engine/confidence_scorer.js +2 -1
  93. package/dist/engine/confidence_scorer.js.map +1 -1
  94. package/dist/engine/config_precedence_contract.d.ts.map +1 -1
  95. package/dist/engine/config_precedence_contract.js +9 -8
  96. package/dist/engine/config_precedence_contract.js.map +1 -1
  97. package/dist/engine/conflict_gate.d.ts.map +1 -1
  98. package/dist/engine/conflict_gate.js +4 -3
  99. package/dist/engine/conflict_gate.js.map +1 -1
  100. package/dist/engine/consumable_asset_registry.d.ts +4 -0
  101. package/dist/engine/consumable_asset_registry.d.ts.map +1 -1
  102. package/dist/engine/consumable_asset_registry.js +307 -0
  103. package/dist/engine/consumable_asset_registry.js.map +1 -1
  104. package/dist/engine/consumption_trace_store.d.ts +50 -0
  105. package/dist/engine/consumption_trace_store.d.ts.map +1 -0
  106. package/dist/engine/consumption_trace_store.js +84 -0
  107. package/dist/engine/consumption_trace_store.js.map +1 -0
  108. package/dist/engine/contract_guard.d.ts.map +1 -1
  109. package/dist/engine/contract_guard.js +7 -6
  110. package/dist/engine/contract_guard.js.map +1 -1
  111. package/dist/engine/contract_registry.d.ts +113 -0
  112. package/dist/engine/contract_registry.d.ts.map +1 -0
  113. package/dist/engine/contract_registry.js +1632 -0
  114. package/dist/engine/contract_registry.js.map +1 -0
  115. package/dist/engine/contract_state_store.d.ts +67 -0
  116. package/dist/engine/contract_state_store.d.ts.map +1 -0
  117. package/dist/engine/contract_state_store.js +167 -0
  118. package/dist/engine/contract_state_store.js.map +1 -0
  119. package/dist/engine/convention_detector.d.ts.map +1 -1
  120. package/dist/engine/convention_detector.js +4 -3
  121. package/dist/engine/convention_detector.js.map +1 -1
  122. package/dist/engine/core_engineering_principles.d.ts.map +1 -1
  123. package/dist/engine/core_engineering_principles.js +4 -14
  124. package/dist/engine/core_engineering_principles.js.map +1 -1
  125. package/dist/engine/core_experience_principle.d.ts +194 -0
  126. package/dist/engine/core_experience_principle.d.ts.map +1 -0
  127. package/dist/engine/core_experience_principle.js +349 -0
  128. package/dist/engine/core_experience_principle.js.map +1 -0
  129. package/dist/engine/debt_reporter.d.ts.map +1 -1
  130. package/dist/engine/debt_reporter.js +3 -2
  131. package/dist/engine/debt_reporter.js.map +1 -1
  132. package/dist/engine/debt_tracker.d.ts.map +1 -1
  133. package/dist/engine/debt_tracker.js +8 -7
  134. package/dist/engine/debt_tracker.js.map +1 -1
  135. package/dist/engine/debug_log.d.ts +4 -1
  136. package/dist/engine/debug_log.d.ts.map +1 -1
  137. package/dist/engine/debug_log.js +4 -6
  138. package/dist/engine/debug_log.js.map +1 -1
  139. package/dist/engine/debugger.d.ts.map +1 -1
  140. package/dist/engine/debugger.js +33 -3
  141. package/dist/engine/debugger.js.map +1 -1
  142. package/dist/engine/decision_contract.d.ts.map +1 -1
  143. package/dist/engine/decision_contract.js +4 -3
  144. package/dist/engine/decision_contract.js.map +1 -1
  145. package/dist/engine/degradation.d.ts +58 -0
  146. package/dist/engine/degradation.d.ts.map +1 -0
  147. package/dist/engine/degradation.js +74 -0
  148. package/dist/engine/degradation.js.map +1 -0
  149. package/dist/engine/delivery.d.ts.map +1 -1
  150. package/dist/engine/delivery.js +16 -15
  151. package/dist/engine/delivery.js.map +1 -1
  152. package/dist/engine/delivery_readiness.d.ts +70 -0
  153. package/dist/engine/delivery_readiness.d.ts.map +1 -0
  154. package/dist/engine/delivery_readiness.js +198 -0
  155. package/dist/engine/delivery_readiness.js.map +1 -0
  156. package/dist/engine/dependency_scanner.d.ts.map +1 -1
  157. package/dist/engine/dependency_scanner.js +6 -5
  158. package/dist/engine/dependency_scanner.js.map +1 -1
  159. package/dist/engine/deprecated_contract.d.ts +21 -0
  160. package/dist/engine/deprecated_contract.d.ts.map +1 -0
  161. package/dist/engine/deprecated_contract.js +14 -0
  162. package/dist/engine/deprecated_contract.js.map +1 -0
  163. package/dist/engine/detail_discipline.d.ts +40 -0
  164. package/dist/engine/detail_discipline.d.ts.map +1 -0
  165. package/dist/engine/detail_discipline.js +107 -0
  166. package/dist/engine/detail_discipline.js.map +1 -0
  167. package/dist/engine/developer_sovereignty.d.ts.map +1 -1
  168. package/dist/engine/developer_sovereignty.js +6 -5
  169. package/dist/engine/developer_sovereignty.js.map +1 -1
  170. package/dist/engine/diagnostic_registry.d.ts +64 -0
  171. package/dist/engine/diagnostic_registry.d.ts.map +1 -0
  172. package/dist/engine/diagnostic_registry.js +176 -0
  173. package/dist/engine/diagnostic_registry.js.map +1 -0
  174. package/dist/engine/diff_ownership.d.ts.map +1 -1
  175. package/dist/engine/diff_ownership.js +9 -8
  176. package/dist/engine/diff_ownership.js.map +1 -1
  177. package/dist/engine/diff_ownership_store.d.ts.map +1 -1
  178. package/dist/engine/diff_ownership_store.js +8 -7
  179. package/dist/engine/diff_ownership_store.js.map +1 -1
  180. package/dist/engine/documentation_governance.d.ts +55 -0
  181. package/dist/engine/documentation_governance.d.ts.map +1 -0
  182. package/dist/engine/documentation_governance.js +249 -0
  183. package/dist/engine/documentation_governance.js.map +1 -0
  184. package/dist/engine/dual_layer_mechanism_registry.d.ts +6 -4
  185. package/dist/engine/dual_layer_mechanism_registry.d.ts.map +1 -1
  186. package/dist/engine/dual_layer_mechanism_registry.js +731 -11
  187. package/dist/engine/dual_layer_mechanism_registry.js.map +1 -1
  188. package/dist/engine/enforcement_guard.d.ts +84 -0
  189. package/dist/engine/enforcement_guard.d.ts.map +1 -0
  190. package/dist/engine/enforcement_guard.js +319 -0
  191. package/dist/engine/enforcement_guard.js.map +1 -0
  192. package/dist/engine/escape_report.d.ts.map +1 -1
  193. package/dist/engine/escape_report.js +4 -3
  194. package/dist/engine/escape_report.js.map +1 -1
  195. package/dist/engine/evolution_regression_gate.d.ts +42 -0
  196. package/dist/engine/evolution_regression_gate.d.ts.map +1 -0
  197. package/dist/engine/evolution_regression_gate.js +159 -0
  198. package/dist/engine/evolution_regression_gate.js.map +1 -0
  199. package/dist/engine/existing_system_analysis.d.ts +37 -0
  200. package/dist/engine/existing_system_analysis.d.ts.map +1 -0
  201. package/dist/engine/existing_system_analysis.js +151 -0
  202. package/dist/engine/existing_system_analysis.js.map +1 -0
  203. package/dist/engine/exploration.d.ts.map +1 -1
  204. package/dist/engine/exploration.js +7 -6
  205. package/dist/engine/exploration.js.map +1 -1
  206. package/dist/engine/extension_contract.d.ts +50 -0
  207. package/dist/engine/extension_contract.d.ts.map +1 -0
  208. package/dist/engine/extension_contract.js +158 -0
  209. package/dist/engine/extension_contract.js.map +1 -0
  210. package/dist/engine/extension_platform_contracts.d.ts +712 -0
  211. package/dist/engine/extension_platform_contracts.d.ts.map +1 -0
  212. package/dist/engine/extension_platform_contracts.js +42 -0
  213. package/dist/engine/extension_platform_contracts.js.map +1 -0
  214. package/dist/engine/extension_scenario_registry.d.ts +30 -0
  215. package/dist/engine/extension_scenario_registry.d.ts.map +1 -0
  216. package/dist/engine/extension_scenario_registry.js +976 -0
  217. package/dist/engine/extension_scenario_registry.js.map +1 -0
  218. package/dist/engine/failure_classifier.d.ts.map +1 -1
  219. package/dist/engine/failure_classifier.js +9 -8
  220. package/dist/engine/failure_classifier.js.map +1 -1
  221. package/dist/engine/failure_report.d.ts +74 -0
  222. package/dist/engine/failure_report.d.ts.map +1 -0
  223. package/dist/engine/failure_report.js +143 -0
  224. package/dist/engine/failure_report.js.map +1 -0
  225. package/dist/engine/feasibility_checker.d.ts.map +1 -1
  226. package/dist/engine/feasibility_checker.js +5 -4
  227. package/dist/engine/feasibility_checker.js.map +1 -1
  228. package/dist/engine/first_principles.d.ts +35 -0
  229. package/dist/engine/first_principles.d.ts.map +1 -0
  230. package/dist/engine/first_principles.js +128 -0
  231. package/dist/engine/first_principles.js.map +1 -0
  232. package/dist/engine/{batch1_scenario_registry.d.ts → foundation_scenario_registry.d.ts} +15 -15
  233. package/dist/engine/foundation_scenario_registry.d.ts.map +1 -0
  234. package/dist/engine/{batch1_scenario_registry.js → foundation_scenario_registry.js} +22 -25
  235. package/dist/engine/foundation_scenario_registry.js.map +1 -0
  236. package/dist/engine/{batch1_scenario_runners.d.ts → foundation_scenario_runners.d.ts} +1 -1
  237. package/dist/engine/foundation_scenario_runners.d.ts.map +1 -0
  238. package/dist/engine/{batch1_scenario_runners.js → foundation_scenario_runners.js} +8 -7
  239. package/dist/engine/foundation_scenario_runners.js.map +1 -0
  240. package/dist/engine/git_deps.d.ts.map +1 -1
  241. package/dist/engine/git_deps.js +2 -1
  242. package/dist/engine/git_deps.js.map +1 -1
  243. package/dist/engine/governance_report.d.ts +9 -1
  244. package/dist/engine/governance_report.d.ts.map +1 -1
  245. package/dist/engine/governance_report.js +25 -10
  246. package/dist/engine/governance_report.js.map +1 -1
  247. package/dist/engine/impact_analyzer.d.ts.map +1 -1
  248. package/dist/engine/impact_analyzer.js +5 -4
  249. package/dist/engine/impact_analyzer.js.map +1 -1
  250. package/dist/engine/implementation_roadmap_registry.d.ts +1 -1
  251. package/dist/engine/implementation_roadmap_registry.d.ts.map +1 -1
  252. package/dist/engine/implementation_roadmap_registry.js +237 -92
  253. package/dist/engine/implementation_roadmap_registry.js.map +1 -1
  254. package/dist/engine/input_material_contract_registry.d.ts.map +1 -1
  255. package/dist/engine/input_material_contract_registry.js +4 -3
  256. package/dist/engine/input_material_contract_registry.js.map +1 -1
  257. package/dist/engine/instruction_contract.d.ts +68 -0
  258. package/dist/engine/instruction_contract.d.ts.map +1 -0
  259. package/dist/engine/instruction_contract.js +123 -0
  260. package/dist/engine/instruction_contract.js.map +1 -0
  261. package/dist/engine/intent_expander.d.ts.map +1 -1
  262. package/dist/engine/intent_expander.js +339 -1
  263. package/dist/engine/intent_expander.js.map +1 -1
  264. package/dist/engine/intent_router.d.ts +11 -2
  265. package/dist/engine/intent_router.d.ts.map +1 -1
  266. package/dist/engine/intent_router.js +121 -1
  267. package/dist/engine/intent_router.js.map +1 -1
  268. package/dist/engine/intent_signal_extractor.d.ts +3 -0
  269. package/dist/engine/intent_signal_extractor.d.ts.map +1 -1
  270. package/dist/engine/intent_signal_extractor.js +49 -0
  271. package/dist/engine/intent_signal_extractor.js.map +1 -1
  272. package/dist/engine/io_controller.d.ts.map +1 -1
  273. package/dist/engine/io_controller.js +8 -7
  274. package/dist/engine/io_controller.js.map +1 -1
  275. package/dist/engine/java_quality_guard.d.ts.map +1 -1
  276. package/dist/engine/java_quality_guard.js +5 -18
  277. package/dist/engine/java_quality_guard.js.map +1 -1
  278. package/dist/engine/job_manager.d.ts.map +1 -1
  279. package/dist/engine/job_manager.js +8 -7
  280. package/dist/engine/job_manager.js.map +1 -1
  281. package/dist/engine/knowledge_acceptance_registry.d.ts +35 -0
  282. package/dist/engine/knowledge_acceptance_registry.d.ts.map +1 -0
  283. package/dist/engine/knowledge_acceptance_registry.js +271 -0
  284. package/dist/engine/knowledge_acceptance_registry.js.map +1 -0
  285. package/dist/engine/knowledge_asset_audit.d.ts +65 -0
  286. package/dist/engine/knowledge_asset_audit.d.ts.map +1 -0
  287. package/dist/engine/knowledge_asset_audit.js +230 -0
  288. package/dist/engine/knowledge_asset_audit.js.map +1 -0
  289. package/dist/engine/knowledge_asset_consumer.d.ts +150 -0
  290. package/dist/engine/knowledge_asset_consumer.d.ts.map +1 -0
  291. package/dist/engine/knowledge_asset_consumer.js +279 -0
  292. package/dist/engine/knowledge_asset_consumer.js.map +1 -0
  293. package/dist/engine/knowledge_asset_generation_gate.d.ts +38 -0
  294. package/dist/engine/knowledge_asset_generation_gate.d.ts.map +1 -0
  295. package/dist/engine/knowledge_asset_generation_gate.js +131 -0
  296. package/dist/engine/knowledge_asset_generation_gate.js.map +1 -0
  297. package/dist/engine/knowledge_asset_migration.d.ts +117 -0
  298. package/dist/engine/knowledge_asset_migration.d.ts.map +1 -0
  299. package/dist/engine/knowledge_asset_migration.js +204 -0
  300. package/dist/engine/knowledge_asset_migration.js.map +1 -0
  301. package/dist/engine/knowledge_asset_schema.d.ts +97 -0
  302. package/dist/engine/knowledge_asset_schema.d.ts.map +1 -0
  303. package/dist/engine/knowledge_asset_schema.js +413 -0
  304. package/dist/engine/knowledge_asset_schema.js.map +1 -0
  305. package/dist/engine/knowledge_config_loader.d.ts.map +1 -1
  306. package/dist/engine/knowledge_config_loader.js +5 -4
  307. package/dist/engine/knowledge_config_loader.js.map +1 -1
  308. package/dist/engine/knowledge_consumption_snapshot.d.ts +91 -0
  309. package/dist/engine/knowledge_consumption_snapshot.d.ts.map +1 -0
  310. package/dist/engine/knowledge_consumption_snapshot.js +113 -0
  311. package/dist/engine/knowledge_consumption_snapshot.js.map +1 -0
  312. package/dist/engine/knowledge_evolution.d.ts +82 -0
  313. package/dist/engine/knowledge_evolution.d.ts.map +1 -0
  314. package/dist/engine/knowledge_evolution.js +272 -0
  315. package/dist/engine/knowledge_evolution.js.map +1 -0
  316. package/dist/engine/knowledge_lifecycle.d.ts +83 -0
  317. package/dist/engine/knowledge_lifecycle.d.ts.map +1 -0
  318. package/dist/engine/knowledge_lifecycle.js +247 -0
  319. package/dist/engine/knowledge_lifecycle.js.map +1 -0
  320. package/dist/engine/knowledge_manager.d.ts.map +1 -1
  321. package/dist/engine/knowledge_manager.js +9 -8
  322. package/dist/engine/knowledge_manager.js.map +1 -1
  323. package/dist/engine/knowledge_scenario_registry.d.ts +21 -0
  324. package/dist/engine/knowledge_scenario_registry.d.ts.map +1 -0
  325. package/dist/engine/knowledge_scenario_registry.js +337 -0
  326. package/dist/engine/knowledge_scenario_registry.js.map +1 -0
  327. package/dist/engine/knowledge_sovereignty.d.ts.map +1 -1
  328. package/dist/engine/knowledge_sovereignty.js +5 -4
  329. package/dist/engine/knowledge_sovereignty.js.map +1 -1
  330. package/dist/engine/knowledge_template_contracts.d.ts +244 -0
  331. package/dist/engine/knowledge_template_contracts.d.ts.map +1 -0
  332. package/dist/engine/knowledge_template_contracts.js +26 -0
  333. package/dist/engine/knowledge_template_contracts.js.map +1 -0
  334. package/dist/engine/language_policy.d.ts +78 -0
  335. package/dist/engine/language_policy.d.ts.map +1 -0
  336. package/dist/engine/language_policy.js +139 -0
  337. package/dist/engine/language_policy.js.map +1 -0
  338. package/dist/engine/language_policy_contract.d.ts +52 -0
  339. package/dist/engine/language_policy_contract.d.ts.map +1 -0
  340. package/dist/engine/language_policy_contract.js +78 -0
  341. package/dist/engine/language_policy_contract.js.map +1 -0
  342. package/dist/engine/llm_gateway.d.ts.map +1 -1
  343. package/dist/engine/llm_gateway.js +10 -9
  344. package/dist/engine/llm_gateway.js.map +1 -1
  345. package/dist/engine/local_docker_acceptance.d.ts +94 -0
  346. package/dist/engine/local_docker_acceptance.d.ts.map +1 -0
  347. package/dist/engine/local_docker_acceptance.js +312 -0
  348. package/dist/engine/local_docker_acceptance.js.map +1 -0
  349. package/dist/engine/logger.d.ts +64 -0
  350. package/dist/engine/logger.d.ts.map +1 -0
  351. package/dist/engine/logger.js +115 -0
  352. package/dist/engine/logger.js.map +1 -0
  353. package/dist/engine/main_path_integration_contract.d.ts.map +1 -1
  354. package/dist/engine/main_path_integration_contract.js +43 -42
  355. package/dist/engine/main_path_integration_contract.js.map +1 -1
  356. package/dist/engine/mechanism_contract_registry.d.ts.map +1 -1
  357. package/dist/engine/mechanism_contract_registry.js +448 -17
  358. package/dist/engine/mechanism_contract_registry.js.map +1 -1
  359. package/dist/engine/mechanism_family_registry.d.ts +48 -0
  360. package/dist/engine/mechanism_family_registry.d.ts.map +1 -0
  361. package/dist/engine/mechanism_family_registry.js +197 -0
  362. package/dist/engine/mechanism_family_registry.js.map +1 -0
  363. package/dist/engine/metric_governance.d.ts +51 -0
  364. package/dist/engine/metric_governance.d.ts.map +1 -0
  365. package/dist/engine/metric_governance.js +138 -0
  366. package/dist/engine/metric_governance.js.map +1 -0
  367. package/dist/engine/migration_guard.d.ts.map +1 -1
  368. package/dist/engine/migration_guard.js +6 -5
  369. package/dist/engine/migration_guard.js.map +1 -1
  370. package/dist/engine/mutation_audit.d.ts.map +1 -1
  371. package/dist/engine/mutation_audit.js +6 -5
  372. package/dist/engine/mutation_audit.js.map +1 -1
  373. package/dist/engine/observability.d.ts +11 -0
  374. package/dist/engine/observability.d.ts.map +1 -1
  375. package/dist/engine/observability.js +60 -8
  376. package/dist/engine/observability.js.map +1 -1
  377. package/dist/engine/onboarding.d.ts.map +1 -1
  378. package/dist/engine/onboarding.js +17 -16
  379. package/dist/engine/onboarding.js.map +1 -1
  380. package/dist/engine/plan_proposal_gate.d.ts +131 -0
  381. package/dist/engine/plan_proposal_gate.d.ts.map +1 -0
  382. package/dist/engine/plan_proposal_gate.js +340 -0
  383. package/dist/engine/plan_proposal_gate.js.map +1 -0
  384. package/dist/engine/platform_context.d.ts +44 -0
  385. package/dist/engine/platform_context.d.ts.map +1 -0
  386. package/dist/engine/platform_context.js +165 -0
  387. package/dist/engine/platform_context.js.map +1 -0
  388. package/dist/engine/policy_drift_detector.d.ts +20 -0
  389. package/dist/engine/policy_drift_detector.d.ts.map +1 -1
  390. package/dist/engine/policy_drift_detector.js +85 -5
  391. package/dist/engine/policy_drift_detector.js.map +1 -1
  392. package/dist/engine/regression_matrix.d.ts.map +1 -1
  393. package/dist/engine/regression_matrix.js +15 -14
  394. package/dist/engine/regression_matrix.js.map +1 -1
  395. package/dist/engine/release_compatibility.d.ts +62 -0
  396. package/dist/engine/release_compatibility.d.ts.map +1 -0
  397. package/dist/engine/release_compatibility.js +145 -0
  398. package/dist/engine/release_compatibility.js.map +1 -0
  399. package/dist/engine/release_gate.d.ts +29 -0
  400. package/dist/engine/release_gate.d.ts.map +1 -0
  401. package/dist/engine/release_gate.js +675 -0
  402. package/dist/engine/release_gate.js.map +1 -0
  403. package/dist/engine/release_gate_scenario_registry.d.ts +50 -0
  404. package/dist/engine/release_gate_scenario_registry.d.ts.map +1 -0
  405. package/dist/engine/release_gate_scenario_registry.js +514 -0
  406. package/dist/engine/release_gate_scenario_registry.js.map +1 -0
  407. package/dist/engine/release_readiness_gate.d.ts +36 -0
  408. package/dist/engine/release_readiness_gate.d.ts.map +1 -0
  409. package/dist/engine/release_readiness_gate.js +1050 -0
  410. package/dist/engine/release_readiness_gate.js.map +1 -0
  411. package/dist/engine/retention_policy.d.ts +46 -0
  412. package/dist/engine/retention_policy.d.ts.map +1 -0
  413. package/dist/engine/retention_policy.js +124 -0
  414. package/dist/engine/retention_policy.js.map +1 -0
  415. package/dist/engine/risk_sampler.d.ts.map +1 -1
  416. package/dist/engine/risk_sampler.js +4 -3
  417. package/dist/engine/risk_sampler.js.map +1 -1
  418. package/dist/engine/runtime_safety.d.ts.map +1 -1
  419. package/dist/engine/runtime_safety.js +18 -17
  420. package/dist/engine/runtime_safety.js.map +1 -1
  421. package/dist/engine/scaffolder.d.ts.map +1 -1
  422. package/dist/engine/scaffolder.js +4 -3
  423. package/dist/engine/scaffolder.js.map +1 -1
  424. package/dist/engine/scope_lease.d.ts.map +1 -1
  425. package/dist/engine/scope_lease.js +4 -3
  426. package/dist/engine/scope_lease.js.map +1 -1
  427. package/dist/engine/semantic_evidence.d.ts.map +1 -1
  428. package/dist/engine/semantic_evidence.js +4 -3
  429. package/dist/engine/semantic_evidence.js.map +1 -1
  430. package/dist/engine/state_fact_classifier.d.ts +47 -0
  431. package/dist/engine/state_fact_classifier.d.ts.map +1 -0
  432. package/dist/engine/state_fact_classifier.js +158 -0
  433. package/dist/engine/state_fact_classifier.js.map +1 -0
  434. package/dist/engine/state_update_bypass.d.ts +19 -0
  435. package/dist/engine/state_update_bypass.d.ts.map +1 -0
  436. package/dist/engine/state_update_bypass.js +17 -0
  437. package/dist/engine/state_update_bypass.js.map +1 -0
  438. package/dist/engine/task_context.d.ts +25 -3
  439. package/dist/engine/task_context.d.ts.map +1 -1
  440. package/dist/engine/task_context.js +132 -35
  441. package/dist/engine/task_context.js.map +1 -1
  442. package/dist/engine/task_planner.d.ts.map +1 -1
  443. package/dist/engine/task_planner.js +6 -5
  444. package/dist/engine/task_planner.js.map +1 -1
  445. package/dist/engine/team_awareness.d.ts.map +1 -1
  446. package/dist/engine/team_awareness.js +2 -1
  447. package/dist/engine/team_awareness.js.map +1 -1
  448. package/dist/engine/technology_decision.d.ts +38 -0
  449. package/dist/engine/technology_decision.d.ts.map +1 -0
  450. package/dist/engine/technology_decision.js +120 -0
  451. package/dist/engine/technology_decision.js.map +1 -0
  452. package/dist/engine/template_manifest_io.d.ts +47 -0
  453. package/dist/engine/template_manifest_io.d.ts.map +1 -0
  454. package/dist/engine/template_manifest_io.js +151 -0
  455. package/dist/engine/template_manifest_io.js.map +1 -0
  456. package/dist/engine/template_mechanism_auditor.d.ts.map +1 -1
  457. package/dist/engine/template_mechanism_auditor.js +5 -4
  458. package/dist/engine/template_mechanism_auditor.js.map +1 -1
  459. package/dist/engine/template_sync.d.ts +98 -0
  460. package/dist/engine/template_sync.d.ts.map +1 -0
  461. package/dist/engine/template_sync.js +355 -0
  462. package/dist/engine/template_sync.js.map +1 -0
  463. package/dist/engine/test_generator.d.ts.map +1 -1
  464. package/dist/engine/test_generator.js +5 -4
  465. package/dist/engine/test_generator.js.map +1 -1
  466. package/dist/engine/test_quality.d.ts.map +1 -1
  467. package/dist/engine/test_quality.js +5 -4
  468. package/dist/engine/test_quality.js.map +1 -1
  469. package/dist/engine/test_strategy.d.ts +58 -0
  470. package/dist/engine/test_strategy.d.ts.map +1 -0
  471. package/dist/engine/test_strategy.js +93 -0
  472. package/dist/engine/test_strategy.js.map +1 -0
  473. package/dist/engine/tool_invocation_contract_registry.d.ts.map +1 -1
  474. package/dist/engine/tool_invocation_contract_registry.js +43 -32
  475. package/dist/engine/tool_invocation_contract_registry.js.map +1 -1
  476. package/dist/engine/traceability.d.ts.map +1 -1
  477. package/dist/engine/traceability.js +6 -5
  478. package/dist/engine/traceability.js.map +1 -1
  479. package/dist/engine/user_feedback_contract.d.ts.map +1 -1
  480. package/dist/engine/user_feedback_contract.js +81 -19
  481. package/dist/engine/user_feedback_contract.js.map +1 -1
  482. package/dist/engine/user_promise.d.ts +67 -0
  483. package/dist/engine/user_promise.d.ts.map +1 -0
  484. package/dist/engine/user_promise.js +436 -0
  485. package/dist/engine/user_promise.js.map +1 -0
  486. package/dist/engine/verification_contract.d.ts +132 -0
  487. package/dist/engine/verification_contract.d.ts.map +1 -0
  488. package/dist/engine/verification_contract.js +296 -0
  489. package/dist/engine/verification_contract.js.map +1 -0
  490. package/dist/engine/verifier.d.ts +6 -10
  491. package/dist/engine/verifier.d.ts.map +1 -1
  492. package/dist/engine/verifier.js +149 -1
  493. package/dist/engine/verifier.js.map +1 -1
  494. package/dist/engine/workflow_contract_registry.d.ts.map +1 -1
  495. package/dist/engine/workflow_contract_registry.js +127 -10
  496. package/dist/engine/workflow_contract_registry.js.map +1 -1
  497. package/dist/engine/workflow_template_pack.d.ts +71 -0
  498. package/dist/engine/workflow_template_pack.d.ts.map +1 -0
  499. package/dist/engine/workflow_template_pack.js +246 -0
  500. package/dist/engine/workflow_template_pack.js.map +1 -0
  501. package/dist/engine/workspace_lease.d.ts +69 -0
  502. package/dist/engine/workspace_lease.d.ts.map +1 -0
  503. package/dist/engine/workspace_lease.js +153 -0
  504. package/dist/engine/workspace_lease.js.map +1 -0
  505. package/dist/engine/workspace_resumer.d.ts.map +1 -1
  506. package/dist/engine/workspace_resumer.js +9 -8
  507. package/dist/engine/workspace_resumer.js.map +1 -1
  508. package/dist/engine/zero_config_init.d.ts.map +1 -1
  509. package/dist/engine/zero_config_init.js +16 -15
  510. package/dist/engine/zero_config_init.js.map +1 -1
  511. package/dist/git/operations.d.ts.map +1 -1
  512. package/dist/git/operations.js +18 -17
  513. package/dist/git/operations.js.map +1 -1
  514. package/dist/index.js +10 -9
  515. package/dist/index.js.map +1 -1
  516. package/dist/knowledge/conflict_detector.d.ts.map +1 -1
  517. package/dist/knowledge/conflict_detector.js +2 -1
  518. package/dist/knowledge/conflict_detector.js.map +1 -1
  519. package/dist/knowledge/health_checker.d.ts.map +1 -1
  520. package/dist/knowledge/health_checker.js +5 -4
  521. package/dist/knowledge/health_checker.js.map +1 -1
  522. package/dist/knowledge/index_manager.js +4 -4
  523. package/dist/knowledge/index_manager.js.map +1 -1
  524. package/dist/knowledge/loader.d.ts.map +1 -1
  525. package/dist/knowledge/loader.js +20 -14
  526. package/dist/knowledge/loader.js.map +1 -1
  527. package/dist/knowledge/writer.d.ts.map +1 -1
  528. package/dist/knowledge/writer.js +7 -6
  529. package/dist/knowledge/writer.js.map +1 -1
  530. package/dist/types.d.ts +34 -2
  531. package/dist/types.d.ts.map +1 -1
  532. package/package.json +13 -4
  533. package/templates/knowledge/acceptance_templates/Bug/345/210/206/346/236/220/346/250/241/347/211/210.md +27 -3
  534. package/templates/knowledge/acceptance_templates/POC/347/273/223/350/256/272/346/250/241/347/211/210.md +27 -3
  535. package/templates/knowledge/acceptance_templates//345/211/215/347/253/257/351/241/265/351/235/242/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -3
  536. package/templates/knowledge/acceptance_templates//345/216/237/345/236/213/350/257/264/346/230/216/346/250/241/347/211/210.md +31 -3
  537. package/templates/knowledge/acceptance_templates//345/220/216/347/253/257API/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -3
  538. package/templates/knowledge/acceptance_templates//345/256/211/345/205/250/345/256/241/350/256/241/346/250/241/347/211/210.md +27 -3
  539. package/templates/knowledge/acceptance_templates//346/200/247/350/203/275/345/210/206/346/236/220/346/250/241/347/211/210.md +27 -3
  540. package/templates/knowledge/acceptance_templates//346/212/200/346/234/257/351/200/211/345/236/213/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -3
  541. package/templates/knowledge/acceptance_templates//346/216/245/345/217/243/345/257/271/346/216/245/346/226/271/346/241/210/346/250/241/347/211/210.md +26 -3
  542. package/templates/knowledge/acceptance_templates//346/216/245/345/217/243/350/256/276/350/256/241/346/250/241/347/211/210.md +27 -3
  543. package/templates/knowledge/acceptance_templates//346/225/205/351/232/234/345/244/215/347/233/230/346/250/241/347/211/210.md +28 -3
  544. package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/346/226/271/346/241/210/346/250/241/347/211/210.md +26 -3
  545. package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/351/252/214/346/224/266/346/270/205/345/215/225.md +31 -3
  546. package/templates/knowledge/acceptance_templates//346/236/266/346/236/204/350/256/276/350/256/241/346/250/241/347/211/210.md +27 -3
  547. package/templates/knowledge/acceptance_templates//346/265/213/350/257/225/350/256/241/345/210/222/346/250/241/347/211/210.md +27 -3
  548. package/templates/knowledge/acceptance_templates//350/257/246/347/273/206/350/256/276/350/256/241/346/250/241/347/211/210.md +26 -3
  549. package/templates/knowledge/acceptance_templates//350/277/201/347/247/273/350/257/204/344/274/260/346/250/241/347/211/210.md +27 -3
  550. package/templates/knowledge/acceptance_templates//351/200/232/347/224/250/350/264/250/351/207/217/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -3
  551. package/templates/knowledge/acceptance_templates//351/207/215/346/236/204/346/226/271/346/241/210/346/250/241/347/211/210.md +27 -3
  552. package/templates/knowledge/acceptance_templates//351/234/200/346/261/202/345/210/206/346/236/220/346/250/241/347/211/210.md +27 -3
  553. package/templates/knowledge/checklists//344/270/273/351/223/276/350/267/257/346/216/245/345/205/245/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -0
  554. package/templates/knowledge/checklists//344/274/232/350/257/235/346/201/242/345/244/215.md +30 -8
  555. package/templates/knowledge/checklists//345/267/245/344/275/234/346/265/201/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -0
  556. package/templates/knowledge/checklists//346/240/270/345/277/203/345/267/245/347/250/213/346/211/247/350/241/214/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -0
  557. package/templates/knowledge/checklists//347/237/245/350/257/206/346/263/250/345/205/245/351/252/214/346/224/266/346/270/205/345/215/225.md +30 -0
  558. package/templates/knowledge/checklists//351/232/220/347/247/201/345/256/241/346/237/245/346/270/205/345/215/225.md +29 -0
  559. package/templates/knowledge/checklists//351/252/214/350/257/201/351/252/214/346/224/266/346/270/205/345/215/225.md +29 -0
  560. package/templates/knowledge/domain//345/244/232/347/247/237/346/210/267.md +28 -3
  561. package/templates/knowledge/domain//345/256/241/350/256/241/346/227/245/345/277/227.md +27 -3
  562. package/templates/knowledge/domain//345/257/274/345/205/245/345/257/274/345/207/272/350/247/204/345/210/231.md +30 -3
  563. package/templates/knowledge/domain//345/267/245/344/275/234/346/265/201/345/274/225/346/223/216.md +32 -3
  564. package/templates/knowledge/domain//346/212/245/350/241/250/347/273/237/350/256/241.md +31 -3
  565. package/templates/knowledge/domain//346/224/257/344/273/230/350/247/204/345/210/231.md +31 -3
  566. package/templates/knowledge/domain//346/225/260/346/215/256/346/235/203/351/231/220.md +28 -3
  567. package/templates/knowledge/domain//351/200/232/347/224/250/346/234/272/346/242/260/346/235/241/346/254/276.md +30 -3
  568. package/templates/knowledge/domain//351/200/232/347/237/245/350/247/204/345/210/231.md +31 -3
  569. package/templates/knowledge/patterns/core/Diff/345/275/222/345/261/236/350/277/275/350/270/252.md +24 -7
  570. package/templates/knowledge/patterns/core/Java/350/264/250/351/207/217/351/227/250/347/246/201.md +25 -7
  571. package/templates/knowledge/patterns/core/LLM/351/242/204/347/256/227/347/275/221/345/205/263.md +24 -7
  572. package/templates/knowledge/patterns/core//344/273/273/345/212/241/344/270/212/344/270/213/346/226/207/347/224/237/345/221/275/345/221/250/346/234/237.md +24 -7
  573. package/templates/knowledge/patterns/core//344/273/273/345/212/241/347/256/241/347/220/206/345/231/250.md +25 -7
  574. package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/344/270/216/345/257/206/351/222/245/346/213/246/346/210/252.md +24 -7
  575. package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/347/247/237/347/272/246.md +25 -7
  576. package/templates/knowledge/patterns/core//345/206/262/347/252/201/351/227/250/347/246/201.md +24 -7
  577. package/templates/knowledge/patterns/core//345/206/263/347/255/226/347/275/221/345/205/263.md +26 -7
  578. package/templates/knowledge/patterns/core//345/217/230/345/274/202/345/256/241/350/256/241.md +25 -7
  579. package/templates/knowledge/patterns/core//345/233/236/345/275/222/347/237/251/351/230/265.md +24 -7
  580. package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/344/272/222/346/226/245/351/224/201.md +24 -7
  581. package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/345/224/244/351/206/222.md +24 -7
  582. package/templates/knowledge/patterns/core//345/271/266/345/217/221/351/224/201.md +26 -7
  583. package/templates/knowledge/patterns/core//345/274/200/345/217/221/350/200/205/345/256/252/346/263/225.md +26 -7
  584. package/templates/knowledge/patterns/core//346/225/217/346/204/237/344/277/241/346/201/257/346/211/253/346/217/217.md +24 -7
  585. package/templates/knowledge/patterns/core//346/262/273/347/220/206/350/277/220/350/241/214/346/227/266/345/276/252/347/216/257.md +25 -7
  586. package/templates/knowledge/patterns/core//346/265/201/345/274/217/345/277/203/350/267/263.md +25 -7
  587. package/templates/knowledge/patterns/core//347/237/245/350/257/206/344/270/273/346/235/203.md +25 -7
  588. package/templates/knowledge/patterns/core//350/257/255/344/271/211/350/257/201/346/215/256.md +24 -7
  589. package/templates/knowledge/patterns/core//350/277/220/350/241/214/345/256/211/345/205/250/345/214/205.md +25 -7
  590. package/templates/knowledge/patterns/core//351/233/266/351/205/215/347/275/256/345/210/235/345/247/213/345/214/226.md +24 -7
  591. package/templates/knowledge/patterns/core//351/252/214/350/257/201/345/221/275/344/273/244/347/224/237/346/210/220.md +24 -7
  592. package/templates/knowledge/procedures/Schema/345/217/230/346/233/264/346/265/201/346/260/264/347/272/277.md +29 -3
  593. package/templates/knowledge/procedures//344/270/273/351/223/276/350/267/257/346/216/245/345/205/245/351/252/214/350/257/201/346/265/201/347/250/213.md +33 -0
  594. package/templates/knowledge/procedures//344/273/243/347/240/201/351/227/250/347/246/201/346/265/201/347/250/213.md +30 -3
  595. package/templates/knowledge/procedures//344/273/273/345/212/241/346/213/206/350/247/243/346/265/201/347/250/213.md +30 -3
  596. package/templates/knowledge/procedures//345/212/237/350/203/275/345/274/200/345/217/221/346/265/201/347/250/213.md +30 -3
  597. package/templates/knowledge/procedures//345/221/275/344/273/244/346/211/247/350/241/214/346/265/201/347/250/213.md +34 -0
  598. package/templates/knowledge/procedures//345/256/211/345/205/250/345/212/240/345/233/272/346/265/201/346/260/264/347/272/277.md +30 -3
  599. package/templates/knowledge/procedures//345/267/245/345/205/267/350/260/203/347/224/250/346/265/201/347/250/213.md +34 -0
  600. package/templates/knowledge/procedures//346/200/247/350/203/275/346/265/201/346/260/264/347/272/277.md +30 -3
  601. package/templates/knowledge/procedures//346/204/217/345/233/276/350/267/257/347/224/261/346/265/201/347/250/213.md +34 -0
  602. package/templates/knowledge/procedures//346/216/245/345/217/243/351/233/206/346/210/220/346/265/201/346/260/264/347/272/277.md +30 -3
  603. package/templates/knowledge/procedures//346/225/260/346/215/256/345/272/223/350/277/201/347/247/273/346/265/201/347/250/213.md +29 -3
  604. package/templates/knowledge/procedures//346/234/254/345/234/260/346/265/217/350/247/210/345/231/250/351/252/214/346/224/266/345/267/245/344/275/234/346/265/201.md +99 -0
  605. package/templates/knowledge/procedures//346/236/266/346/236/204/350/256/276/350/256/241/345/267/245/344/275/234/346/265/201.md +95 -0
  606. package/templates/knowledge/procedures//346/236/266/346/236/204/350/256/276/350/256/241/346/265/201/347/250/213.md +30 -3
  607. package/templates/knowledge/procedures//346/246/202/345/277/265/351/252/214/350/257/201/346/265/201/346/260/264/347/272/277.md +30 -3
  608. package/templates/knowledge/procedures//346/265/213/350/257/225/344/274/230/345/205/210/347/274/226/347/240/201/345/267/245/344/275/234/346/265/201.md +91 -0
  609. package/templates/knowledge/procedures//346/272/220/347/240/201/345/216/237/345/236/213/344/272/244/344/273/230/346/265/201/347/250/213.md +30 -3
  610. package/templates/knowledge/procedures//347/216/260/346/234/211/347/263/273/347/273/237/345/267/256/350/267/235/345/210/206/346/236/220/345/267/245/344/275/234/346/265/201.md +97 -0
  611. package/templates/knowledge/procedures//347/237/245/350/257/206/347/273/264/346/212/244/346/265/201/346/260/264/347/272/277.md +30 -3
  612. package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +30 -3
  613. package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/347/250/213.md +30 -3
  614. package/templates/knowledge/procedures//347/274/226/347/240/201/345/211/215/346/276/204/346/270/205/346/265/201/347/250/213.md +33 -0
  615. package/templates/knowledge/procedures//347/274/272/351/231/267/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +30 -3
  616. package/templates/knowledge/procedures//350/207/252/344/270/273/351/200/211/345/236/213/346/265/201/347/250/213.md +30 -3
  617. package/templates/knowledge/procedures//350/257/246/347/273/206/350/256/276/350/256/241/346/265/201/347/250/213.md +30 -3
  618. package/templates/knowledge/procedures//350/260/203/350/257/225/346/216/222/346/237/245/346/265/201/347/250/213.md +30 -3
  619. package/templates/knowledge/procedures//350/277/201/347/247/273/346/265/201/346/260/264/347/272/277.md +30 -3
  620. package/templates/knowledge/procedures//351/203/250/347/275/262/345/217/221/345/270/203/346/265/201/347/250/213.md +30 -3
  621. package/templates/knowledge/procedures//351/207/215/346/236/204/346/265/201/346/260/264/347/272/277.md +30 -3
  622. package/templates/knowledge/procedures//351/233/206/346/210/220/351/252/214/350/257/201/346/265/201/347/250/213.md +30 -3
  623. package/templates/knowledge/procedures//351/234/200/346/261/202/346/276/204/346/270/205/346/265/201/347/250/213.md +30 -3
  624. package/templates/knowledge/procedures//351/252/214/346/224/266/346/265/213/350/257/225/350/247/204/345/210/222.md +30 -3
  625. package/templates/knowledge/procedures//351/252/214/350/257/201/350/256/241/345/210/222/346/265/201/347/250/213.md +30 -3
  626. package/templates/knowledge/review_rules//344/272/244/344/273/230/345/256/214/345/244/207/346/200/247/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  627. package/templates/knowledge/review_rules//345/256/211/345/205/250/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  628. package/templates/knowledge/review_rules//345/271/266/345/217/221/345/256/241/346/237/245/350/247/204/345/210/231.md +23 -3
  629. package/templates/knowledge/review_rules//346/200/247/350/203/275/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  630. package/templates/knowledge/review_rules//346/216/245/345/217/243/345/245/221/347/272/246/345/256/241/346/237/245/350/247/204/345/210/231.md +23 -3
  631. package/templates/knowledge/review_rules//346/236/266/346/236/204/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  632. package/templates/knowledge/review_rules//350/264/250/351/207/217/345/256/241/346/237/245/350/247/204/345/210/231.md +24 -3
  633. package/templates/knowledge/rules//344/272/247/347/211/251/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  634. package/templates/knowledge/rules//344/273/273/345/212/241/344/270/212/344/270/213/346/226/207/347/224/237/345/221/275/345/221/250/346/234/237/350/247/204/345/210/231.md +65 -0
  635. package/templates/knowledge/rules//345/221/275/344/273/244/346/211/247/350/241/214/350/247/204/345/210/231.md +36 -0
  636. package/templates/knowledge/rules//345/267/245/344/275/234/346/265/201/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  637. package/templates/knowledge/rules//345/267/245/344/275/234/346/265/201/346/250/241/346/235/277/345/214/205/350/247/204/345/210/231.md +38 -0
  638. package/templates/knowledge/rules//345/267/245/345/205/267/350/260/203/347/224/250/350/247/204/345/210/231.md +36 -0
  639. package/templates/knowledge/rules//346/204/217/345/233/276/350/267/257/347/224/261/350/247/204/345/210/231.md +36 -0
  640. package/templates/knowledge/rules//346/211/247/350/241/214/345/256/210/345/215/253/350/257/204/344/274/260/350/247/204/345/210/231.md +36 -0
  641. package/templates/knowledge/rules//346/211/251/345/261/225/347/224/237/345/221/275/345/221/250/346/234/237/350/247/204/345/210/231.md +38 -0
  642. package/templates/knowledge/rules//346/212/200/346/234/257/345/206/263/347/255/226/344/270/273/346/235/203/350/247/204/345/210/231.md +64 -0
  643. package/templates/knowledge/rules//346/225/217/346/204/237/344/277/241/346/201/257/345/244/204/347/220/206/350/247/204/345/210/231.md +36 -0
  644. package/templates/knowledge/rules//346/226/275/345/267/245/346/214/207/344/273/244/345/245/221/347/272/246/350/247/204/345/210/231.md +49 -0
  645. package/templates/knowledge/rules//346/240/270/345/277/203/344/275/223/351/252/214/345/216/237/345/210/231.md +50 -0
  646. package/templates/knowledge/rules//346/240/270/345/277/203/345/267/245/347/250/213/346/211/247/350/241/214/345/216/237/345/210/231.md +35 -0
  647. package/templates/knowledge/rules//346/263/250/345/206/214/350/241/250/345/237/272/347/241/200/350/256/276/346/226/275/350/247/204/345/210/231.md +36 -0
  648. package/templates/knowledge/rules//346/274/224/350/277/233/345/233/236/345/275/222/350/247/204/345/210/231.md +51 -0
  649. package/templates/knowledge/rules//346/274/224/350/277/233/345/233/236/345/275/222/351/227/250/346/216/247/350/247/204/345/210/231.md +74 -0
  650. package/templates/knowledge/rules//347/224/250/346/210/267/345/217/215/351/246/210/345/245/221/347/272/246/350/247/204/345/210/231.md +35 -0
  651. package/templates/knowledge/rules//347/237/245/350/257/206/346/263/250/345/205/245/350/276/271/347/225/214/350/247/204/345/210/231.md +36 -0
  652. package/templates/knowledge/rules//347/237/245/350/257/206/350/265/204/344/272/247/346/262/273/347/220/206/350/247/204/345/210/231.md +61 -0
  653. package/templates/knowledge/rules//347/254/254/344/270/200/346/200/247/345/216/237/347/220/206/346/216/250/347/220/206/350/247/204/345/210/231.md +73 -0
  654. package/templates/knowledge/rules//347/273/206/350/212/202/347/272/252/345/276/213/350/247/204/345/210/231.md +67 -0
  655. package/templates/knowledge/rules//350/204/221/346/232/264/344/270/216/346/226/271/346/241/210/346/216/242/347/264/242/350/247/204/345/210/231.md +66 -0
  656. package/templates/knowledge/rules//350/256/241/345/210/222/345/211/215/347/275/256/351/227/250/350/247/204/345/210/231.md +59 -0
  657. package/templates/knowledge/rules//350/267/250/345/271/263/345/217/260/350/267/257/345/276/204/345/256/211/345/205/250/350/247/204/345/210/231.md +38 -0
  658. package/templates/knowledge/rules//350/276/223/345/205/245/346/235/220/346/226/231/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  659. package/templates/knowledge/rules//351/205/215/347/275/256/344/274/230/345/205/210/347/272/247/350/247/204/345/210/231.md +35 -0
  660. package/templates/knowledge/rules//351/230/262/345/255/244/345/262/233/345/256/236/347/216/260/350/247/204/345/210/231.md +36 -0
  661. package/templates/knowledge/rules//351/233/266/351/205/215/347/275/256/345/210/235/345/247/213/345/214/226/350/247/204/345/210/231.md +36 -0
  662. package/templates/knowledge/rules//351/252/214/350/257/201/345/245/221/347/272/246/350/247/204/345/210/231.md +36 -0
  663. package/templates/knowledge/templates//345/256/241/346/237/245/346/221/230/350/246/201.md +26 -7
  664. package/templates/patterns/API/350/256/276/350/256/241/350/247/204/350/214/203.md +30 -3
  665. package/templates/patterns/Docker/351/203/250/347/275/262/350/247/204/350/214/203.md +29 -3
  666. package/templates/patterns/Git/346/223/215/344/275/234/350/247/204/350/214/203.md +33 -3
  667. package/templates/patterns/N/345/212/2401/346/237/245/350/257/242/350/247/204/350/214/203.md +31 -3
  668. package/templates/patterns/React/345/210/227/350/241/250/350/241/250/346/240/274/350/247/204/350/214/203.md +30 -3
  669. package/templates/patterns/React/346/216/245/345/217/243/351/233/206/346/210/220/350/247/204/350/214/203.md +31 -3
  670. package/templates/patterns/React/347/212/266/346/200/201/347/256/241/347/220/206/350/247/204/350/214/203.md +31 -3
  671. package/templates/patterns/React/347/273/204/344/273/266/350/247/204/350/214/203.md +30 -3
  672. package/templates/patterns/React/350/241/250/345/215/225/350/247/204/350/214/203.md +30 -3
  673. package/templates/patterns/React/350/267/257/347/224/261/350/247/204/350/214/203.md +31 -3
  674. package/templates/patterns/Schema/345/205/274/345/256/271/350/247/204/350/214/203.md +30 -3
  675. package/templates/patterns/Vue/347/212/266/346/200/201/347/256/241/347/220/206/350/247/204/350/214/203.md +29 -3
  676. package/templates/patterns/Vue/347/273/204/344/273/266/350/247/204/350/214/203.md +33 -3
  677. package/templates/patterns/Vue/350/267/257/347/224/261/350/247/204/350/214/203.md +28 -3
  678. package/templates/patterns//344/272/213/344/273/266/351/251/261/345/212/250/350/247/204/350/214/203.md +32 -3
  679. package/templates/patterns//344/272/213/345/212/241/346/250/241/345/274/217/350/247/204/350/214/203.md +31 -3
  680. package/templates/patterns//344/274/230/351/233/205/345/201/234/346/234/272/350/247/204/350/214/203.md +31 -3
  681. package/templates/patterns//345/205/250/346/240/210/346/265/201/347/250/213/344/277/256/345/244/215.md +30 -3
  682. package/templates/patterns//345/210/206/351/241/265/346/237/245/350/257/242/350/247/204/350/214/203.md +34 -3
  683. package/templates/patterns//345/211/215/347/253/257/346/200/247/350/203/275/350/247/204/350/214/203.md +32 -3
  684. package/templates/patterns//345/221/275/345/220/215/350/247/204/350/214/203.md +30 -3
  685. package/templates/patterns//345/233/275/351/231/205/345/214/226/350/247/204/350/214/203.md +31 -3
  686. package/templates/patterns//345/242/236/345/210/240/346/224/271/346/237/245/350/247/204/350/214/203.md +31 -3
  687. package/templates/patterns//345/244/226/351/203/250/344/276/235/350/265/226/350/247/204/350/214/203.md +31 -3
  688. package/templates/patterns//345/245/221/347/272/246/345/205/274/345/256/271/350/247/204/350/214/203.md +28 -3
  689. package/templates/patterns//345/256/232/346/227/266/344/273/273/345/212/241/350/247/204/350/214/203.md +32 -3
  690. package/templates/patterns//345/256/236/346/227/266/346/216/250/351/200/201/350/247/204/350/214/203.md +31 -3
  691. package/templates/patterns//345/267/245/347/250/213/347/272/252/345/276/213.md +30 -3
  692. package/templates/patterns//345/271/266/345/217/221/346/216/247/345/210/266/350/247/204/350/214/203.md +34 -3
  693. package/templates/patterns//345/274/202/346/255/245/345/257/274/345/207/272/350/247/204/350/214/203.md +31 -3
  694. package/templates/patterns//346/216/245/345/217/243/345/245/221/347/272/246/350/247/204/350/214/203.md +29 -3
  695. package/templates/patterns//346/220/234/347/264/242/346/250/241/345/274/217/350/247/204/350/214/203.md +33 -3
  696. package/templates/patterns//346/225/260/346/215/256/351/232/220/347/247/201/350/247/204/350/214/203.md +34 -3
  697. package/templates/patterns//346/226/207/344/273/266/344/270/212/344/274/240/350/247/204/350/214/203.md +30 -3
  698. package/templates/patterns//346/227/240/351/232/234/347/242/215/350/247/204/350/214/203.md +30 -3
  699. package/templates/patterns//346/227/245/345/277/227/350/247/204/350/214/203.md +31 -3
  700. package/templates/patterns//346/235/203/351/231/220/350/256/244/350/257/201/350/247/204/350/214/203.md +34 -3
  701. package/templates/patterns//346/236/266/346/236/204/347/272/242/347/272/277.md +28 -3
  702. package/templates/patterns//346/265/213/350/257/225/350/264/250/351/207/217/350/247/204/350/214/203.md +30 -3
  703. package/templates/patterns//347/206/224/346/226/255/351/231/215/347/272/247/350/247/204/350/214/203.md +32 -3
  704. package/templates/patterns//347/212/266/346/200/201/346/265/201/350/275/254/350/247/204/350/214/203.md +29 -3
  705. package/templates/patterns//347/272/246/346/235/237/345/256/236/347/216/260/350/247/204/350/214/203.md +32 -3
  706. package/templates/patterns//347/274/223/345/255/230/347/255/226/347/225/245/350/247/204/350/214/203.md +31 -3
  707. package/templates/patterns//347/274/226/347/240/201/350/264/250/351/207/217/350/247/204/350/214/203.md +30 -3
  708. package/templates/patterns//347/274/272/351/231/267/347/256/241/347/220/206/350/247/204/350/214/203.md +29 -3
  709. package/templates/patterns//350/260/203/350/257/225/346/226/271/346/263/225/350/256/272.md +30 -3
  710. package/templates/patterns//350/276/223/345/205/245/346/240/241/351/252/214/350/247/204/350/214/203.md +31 -3
  711. package/templates/patterns//351/224/231/350/257/257/345/244/204/347/220/206/350/247/204/350/214/203.md +31 -3
  712. package/templates/patterns//351/224/231/350/257/257/350/276/271/347/225/214/350/247/204/350/214/203.md +33 -3
  713. package/templates/patterns//351/242/206/345/237/237/351/251/261/345/212/250/350/256/276/350/256/241/350/247/204/350/214/203.md +30 -3
  714. package/dist/engine/batch1_manifest.d.ts.map +0 -1
  715. package/dist/engine/batch1_manifest.js.map +0 -1
  716. package/dist/engine/batch1_scenario_registry.d.ts.map +0 -1
  717. package/dist/engine/batch1_scenario_registry.js.map +0 -1
  718. package/dist/engine/batch1_scenario_runners.d.ts.map +0 -1
  719. package/dist/engine/batch1_scenario_runners.js.map +0 -1
@@ -16,10 +16,11 @@ import { cmdConfigResolve, cmdConfigExplain, cmdConfigConfirm, cmdConfigUnset, l
16
16
  import { resolveCurrentProjectConfigReports, validateConfigPrecedence, } from "../engine/config_precedence_contract.js";
17
17
  import { isReadForbidden } from "../engine/privacy_secret_contract.js";
18
18
  import { routeIntent } from "../engine/intent_router.js";
19
- import { debugLog } from "../engine/debug_log.js";
19
+ import { debugLog, debug, userInfo, userWarn, userError, internalWarn, jsonSafeError, initLoggerFromEnv } from "../engine/logger.js";
20
20
  const command = process.argv[2];
21
21
  const args = process.argv.slice(3);
22
22
  async function main() {
23
+ initLoggerFromEnv();
23
24
  switch (command) {
24
25
  case "init":
25
26
  if (args.includes("--auto")) {
@@ -60,7 +61,31 @@ async function main() {
60
61
  await cmdAuditTemplateMechanisms();
61
62
  break;
62
63
  case "validate-batch1":
63
- await cmdValidateBatch1();
64
+ userWarn("⚠️ validate-batch1 是历史施工命令,不代表正式发布通过。请使用 validate-release。");
65
+ await cmdValidateFoundation();
66
+ break;
67
+ case "validate-batch3":
68
+ userWarn("⚠️ validate-batch3 是历史施工命令,不代表正式发布通过。请使用 validate-release。");
69
+ await cmdValidateKnowledge();
70
+ break;
71
+ case "validate-batch5":
72
+ userWarn("⚠️ validate-batch5 是历史施工命令,不代表正式发布通过。请使用 validate-release。");
73
+ await cmdValidateReleaseGate();
74
+ break;
75
+ case "validate-release":
76
+ await cmdValidateReleaseGate();
77
+ break;
78
+ case "sync-templates":
79
+ await cmdSyncTemplates();
80
+ break;
81
+ case "sync-adapters":
82
+ await cmdSyncAdapters();
83
+ break;
84
+ case "migrate":
85
+ await cmdMigrate();
86
+ break;
87
+ case "validate-new-issue":
88
+ await cmdValidateNewIssue();
64
89
  break;
65
90
  case "generate-trae":
66
91
  await cmdGenerateTrae();
@@ -89,20 +114,23 @@ async function main() {
89
114
  await cmdConfigUnset();
90
115
  break;
91
116
  default:
92
- console.log("用法: soloforge config <resolve|explain|confirm|unset> [options]");
93
- console.log("");
94
- console.log(" resolve 解析配置字段优先级(只读,显示所有候选来源)");
95
- console.log(" explain 解释指定字段的来源和优先级(只读,中文输出)");
96
- console.log(" confirm 确认配置字段值(写入 config + evidence)");
97
- console.log(" unset 移除指定字段的确认配置和 evidence");
117
+ userInfo("用法: soloforge config <resolve|explain|confirm|unset> [options]");
118
+ userInfo("");
119
+ userInfo(" resolve 解析配置字段优先级(只读,显示所有候选来源)");
120
+ userInfo(" explain 解释指定字段的来源和优先级(只读,中文输出)");
121
+ userInfo(" confirm 确认配置字段值(写入 config + evidence)");
122
+ userInfo(" unset 移除指定字段的确认配置和 evidence");
98
123
  }
99
124
  break;
100
125
  }
101
126
  case "status":
102
127
  await cmdStatus();
103
128
  break;
129
+ case "cleanup":
130
+ await cmdCleanup();
131
+ break;
104
132
  default:
105
- console.log(`SoloForge CLI
133
+ userInfo(`SoloForge CLI
106
134
 
107
135
  用法: soloforge <命令>
108
136
 
@@ -121,17 +149,25 @@ async function main() {
121
149
  validate 验证项目配置和知识文件(config.yaml 可选,缺失时自动推断)
122
150
  validate-mechanisms 验证双层机制承载模型完整性(模板层 + 机制层)
123
151
  audit-template-mechanisms 扫描模板与机制注册表交叉校验(--json 输出完整报告,--changed-only 仅检查变更文件)
152
+ validate-release 验证发布门禁(契约、场景矩阵、消费 trace、双层机制、回归基线)
153
+ validate-batch1 [历史] 仅基础契约验证,不代表正式发布通过
154
+ validate-batch3 [历史] 仅知识模板验证,不代表正式发布通过
155
+ validate-batch5 [历史] 仅发布门禁验证,不代表正式发布通过
156
+ sync-templates 同步模板到项目(默认 dry-run,--apply 需 --confirm)
157
+ sync-adapters 同步适配器 Prompt(默认 dry-run,--apply 需 --confirm)
158
+ migrate 迁移项目 .soloforge/(默认 dry-run,--apply 需确认)
124
159
  version 显示 SoloForge 版本信息
125
160
  config resolve 解析配置字段优先级(只读)
126
161
  config explain 解释配置字段来源(只读,中文)
127
162
  config confirm <field> <value> 确认配置字段(写入 config + evidence)
128
163
  config unset <field> 移除确认配置
129
164
  status 显示当前项目的 SoloForge 状态
165
+ cleanup 清理过期任务和 evidence(默认 dry-run,--apply 执行实际清理)
130
166
  `);
131
167
  }
132
168
  }
133
169
  async function cmdInitAuto() {
134
- console.error("[soloForge] CLI: 执行 cmdInitAuto");
170
+ debug("CLI", "执行 cmdInitAuto");
135
171
  const dryRun = args.includes("--dry-run");
136
172
  const projectPathArg = getArgValue("--project-path");
137
173
  const projectPath = projectPathArg ? path.resolve(projectPathArg) : process.cwd();
@@ -142,50 +178,50 @@ async function cmdInitAuto() {
142
178
  // 层 3: 字段级 evidence
143
179
  const evidence = generateConfigEvidence(fp, draft, "auto");
144
180
  // 展示探测结果 + evidence
145
- console.log("\nSoloForge 自动配置探测结果:");
146
- console.log("=".repeat(50));
181
+ userInfo("\nSoloForge 自动配置探测结果:");
182
+ userInfo("=".repeat(50));
147
183
  for (const [key, field] of Object.entries(evidence.fields)) {
148
184
  const icon = field.confidence === "high" ? "✅" : field.confidence === "medium" ? "⚠️" : "❓";
149
185
  const valStr = typeof field.value === "object" ? JSON.stringify(field.value) : String(field.value);
150
- console.log(` ${icon} ${key}: ${valStr} (${field.confidence}, ${field.confidence_source})`);
151
- console.log(` 证据: ${field.evidence.join(", ")}`);
186
+ userInfo(` ${icon} ${key}: ${valStr} (${field.confidence}, ${field.confidence_source})`);
187
+ userInfo(` 证据: ${field.evidence.join(", ")}`);
152
188
  }
153
- console.log("=".repeat(50));
154
- console.log(`综合置信度: ${draft.confidence}`);
189
+ userInfo("=".repeat(50));
190
+ userInfo(`综合置信度: ${draft.confidence}`);
155
191
  if (draft.advisory_notes.length > 0) {
156
- console.log("建议:");
192
+ userInfo("建议:");
157
193
  for (const note of draft.advisory_notes) {
158
- console.log(` - ${note}`);
194
+ userInfo(` - ${note}`);
159
195
  }
160
196
  }
161
197
  // Schema 校验 (advisory)
162
198
  const validation = validateConfigDraft(draft);
163
199
  if (validation.warnings.length > 0) {
164
- console.log("\nschema 建议:");
200
+ userInfo("\nschema 建议:");
165
201
  for (const w of validation.warnings) {
166
- console.log(` ⚠️ ${w}`);
202
+ userInfo(` ⚠️ ${w}`);
167
203
  }
168
204
  }
169
205
  if (!validation.valid) {
170
- console.log("\nschema 错误:");
206
+ userInfo("\nschema 错误:");
171
207
  for (const e of validation.errors) {
172
- console.log(` ❌ ${e}`);
208
+ userInfo(` ❌ ${e}`);
173
209
  }
174
- console.log("\n配置校验失败,请手动运行 `soloforge init --interactive`。");
210
+ userInfo("\n配置校验失败,请手动运行 `soloforge init --interactive`。");
175
211
  return;
176
212
  }
177
213
  if (dryRun) {
178
- console.log("\n[dry-run] 不写入文件。使用不带 --dry-run 的命令执行写入。");
214
+ userInfo("\n[dry-run] 不写入文件。使用不带 --dry-run 的命令执行写入。");
179
215
  return;
180
216
  }
181
217
  // 写入门禁: 所有必要字段必须 high confidence + detected/user_declared/confirmed
182
218
  const gate = canAutoWrite(evidence);
183
219
  if (!gate.allowed) {
184
- console.log(`\n⚠️ 存在低/中置信度配置项,拒绝写入:`);
220
+ userInfo(`\n⚠️ 存在低/中置信度配置项,拒绝写入:`);
185
221
  for (const f of gate.blockedFields) {
186
- console.log(` - ${f}`);
222
+ userInfo(` - ${f}`);
187
223
  }
188
- console.log("请使用 `soloforge init --interactive` 或 `soloforge init --blueprint \"...\"` 生成配置。");
224
+ userInfo("请使用 `soloforge init --interactive` 或 `soloforge init --blueprint \"...\"` 生成配置。");
189
225
  return;
190
226
  }
191
227
  // 写入配置 + evidence
@@ -245,9 +281,9 @@ function writeConfigWithEvidence(projectPath, draft, evidence) {
245
281
  fss.writeFileSync(evidencePath, JSON.stringify(existing, null, 2), "utf-8");
246
282
  }
247
283
  catch (e) {
248
- console.error(`[soloForge] 更新 evidence 文件失败: ${e instanceof Error ? e.message : String(e)}`);
284
+ internalWarn("CLI", `更新 evidence 文件失败: ${e instanceof Error ? e.message : String(e)}`);
249
285
  }
250
- console.log(`\n✅ .soloforge/config.yaml + config.evidence.json created`);
286
+ userInfo(`\n✅ .soloforge/config.yaml + config.evidence.json created`);
251
287
  }
252
288
  function hashConfigValue(str) {
253
289
  return crypto.createHash("sha256").update(str).digest("hex").slice(0, 16);
@@ -261,18 +297,18 @@ function mapLegacySource(source) {
261
297
  }
262
298
  }
263
299
  async function cmdInitBlueprint() {
264
- console.error("[soloForge] CLI: 执行 cmdInitBlueprint");
300
+ debug("CLI", "执行 cmdInitBlueprint");
265
301
  const blueprintText = getArgValue("--blueprint");
266
302
  if (!blueprintText) {
267
- console.error("❌ --blueprint 需要提供描述文本,例如: soloforge init --blueprint \"Spring Boot + React 的 B2B 内部管理系统\"");
303
+ userError("❌ --blueprint 需要提供描述文本,例如: soloforge init --blueprint \"Spring Boot + React 的 B2B 内部管理系统\"");
268
304
  return;
269
305
  }
270
306
  const projectPathArg = getArgValue("--project-path");
271
307
  const projectPath = projectPathArg ? path.resolve(projectPathArg) : process.cwd();
272
308
  const parsed = parseBlueprint(blueprintText);
273
309
  if (!parsed.parsed) {
274
- console.log("⚠️ 无法从蓝图文本解析技术栈,请使用 --interactive。");
275
- console.log("支持的框架关键词: Spring Boot, Go, Rust, Gradle, React, Vue, Angular, Next.js, Nuxt");
310
+ userInfo("⚠️ 无法从蓝图文本解析技术栈,请使用 --interactive。");
311
+ userInfo("支持的框架关键词: Spring Boot, Go, Rust, Gradle, React, Vue, Angular, Next.js, Nuxt");
276
312
  return;
277
313
  }
278
314
  // 从解析的蓝图构建草稿
@@ -335,7 +371,7 @@ function blueprintFrontendCommands(framework) {
335
371
  }
336
372
  }
337
373
  async function cmdInit() {
338
- console.error("[soloForge] CLI: 执行 cmdInit");
374
+ debug("CLI", "执行 cmdInit");
339
375
  const interactive = args.includes("--interactive");
340
376
  const adapter = getArgValue("--adapter") || "claude-code";
341
377
  const projectPathArg = getArgValue("--project-path");
@@ -368,7 +404,7 @@ async function cmdInit() {
368
404
  writeConfigWithEvidence(projectPath, config.draft, config.evidence);
369
405
  }
370
406
  else if (!process.stdin.isTTY) {
371
- console.log("⚠️ interactive requires TTY. 请使用 --auto 或 --blueprint。");
407
+ userInfo("⚠️ interactive requires TTY. 请使用 --auto 或 --blueprint。");
372
408
  }
373
409
  }
374
410
  // 生成 .mcp.json(SoloForge + Playwright)
@@ -389,7 +425,7 @@ async function cmdInit() {
389
425
  },
390
426
  };
391
427
  fss.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
392
- console.log("✅ .mcp.json 已创建(soloforge + playwright)");
428
+ userInfo("✅ .mcp.json 已创建(soloforge + playwright)");
393
429
  }
394
430
  // 生成 hooks
395
431
  await cmdGenerateHooks(projectPath);
@@ -399,7 +435,7 @@ async function cmdInit() {
399
435
  // 生成 Trae IDE 配置
400
436
  if (adapter === "trae" || adapter === "all") {
401
437
  await cmdGenerateTraeInner(projectPath);
402
- console.log("💡 提示: 使用项目级 .trae/ 配置需在 Trae 中开启 beta flag");
438
+ userInfo("💡 提示: 使用项目级 .trae/ 配置需在 Trae 中开启 beta flag");
403
439
  }
404
440
  // 生成 Codex App 配置
405
441
  if (adapter === "codex" || adapter === "all") {
@@ -410,7 +446,7 @@ async function cmdInit() {
410
446
  await copyKnowledgeTemplates(projectPath);
411
447
  // 确保 .gitignore 包含必要条目
412
448
  ensureGitignore(projectPath);
413
- console.log(`\n✅ SoloForge 初始化完成 (适配器: ${adapter})。${adapter === "trae" ? "请打开 Trae IDE 开始使用。" :
449
+ userInfo(`\n✅ SoloForge 初始化完成 (适配器: ${adapter})。${adapter === "trae" ? "请打开 Trae IDE 开始使用。" :
414
450
  adapter === "codex" ? "请打开 Codex App 开始使用。" :
415
451
  adapter === "all" ? "可在 Claude Code、Trae IDE 或 Codex App 中使用。" :
416
452
  "请打开 Claude Code 开始使用。"}`);
@@ -428,7 +464,7 @@ async function copyGlobalPatterns(projectPath) {
428
464
  fss.copyFileSync(src, dest);
429
465
  }
430
466
  }
431
- console.log(`✅ ${files.length} 个默认模板已复制到 ~/.soloforge/patterns/`);
467
+ userInfo(`✅ ${files.length} 个默认模板已复制到 ~/.soloforge/patterns/`);
432
468
  }
433
469
  }
434
470
  async function copyKnowledgeTemplates(projectPath) {
@@ -453,7 +489,7 @@ async function copyKnowledgeTemplates(projectPath) {
453
489
  }
454
490
  }
455
491
  if (copiedCount > 0) {
456
- console.log(`✅ ${copiedCount} 个知识模板已复制到 .soloforge/knowledge/`);
492
+ userInfo(`✅ ${copiedCount} 个知识模板已复制到 .soloforge/knowledge/`);
457
493
  }
458
494
  }
459
495
  }
@@ -468,7 +504,7 @@ async function generateAdapterConfigs(projectPath, adapter) {
468
504
  },
469
505
  };
470
506
  fss.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2), "utf-8");
471
- console.log("✅ .mcp.json 已创建(soloforge + playwright)");
507
+ userInfo("✅ .mcp.json 已创建(soloforge + playwright)");
472
508
  }
473
509
  await cmdGenerateHooks(projectPath);
474
510
  await cmdGenerateClaudeMdInner(projectPath);
@@ -486,7 +522,7 @@ function ensureGitignore(projectPath) {
486
522
  if (missing.length > 0) {
487
523
  const addition = (content.endsWith("\n") ? "" : "\n") + missing.join("\n") + "\n";
488
524
  fss.appendFileSync(gitignorePath, addition, "utf-8");
489
- console.log(`✅ .gitignore 已更新: ${missing.join(", ")}`);
525
+ userInfo(`✅ .gitignore 已更新: ${missing.join(", ")}`);
490
526
  }
491
527
  }
492
528
  async function cmdGenerateHooks(projectPath) {
@@ -507,7 +543,7 @@ async function cmdGenerateHooks(projectPath) {
507
543
  // 仅 merge hooks 字段,保留用户的 permissions/env 等设置
508
544
  existing.hooks = hooksConfig.hooks;
509
545
  fss.writeFileSync(settingsPath, JSON.stringify(existing, null, 2), "utf-8");
510
- console.log("✅ .claude/settings.json 已更新 hooks 配置");
546
+ userInfo("✅ .claude/settings.json 已更新 hooks 配置");
511
547
  }
512
548
  async function cmdGenerateClaudeMd() {
513
549
  await cmdGenerateClaudeMdInner(process.cwd());
@@ -524,16 +560,16 @@ async function cmdGenerateCodexInner(projectPath) {
524
560
  fss.mkdirSync(codexDir, { recursive: true });
525
561
  const tomlContent = generateCodexMcpConfig(projectPath);
526
562
  fss.writeFileSync(path.join(codexDir, "config.toml"), tomlContent, "utf-8");
527
- console.log("✅ .codex/config.toml 已创建");
563
+ userInfo("✅ .codex/config.toml 已创建");
528
564
  // 生成 .codex/hooks.json
529
565
  const hooksContent = generateCodexHooksConfig();
530
566
  fss.writeFileSync(path.join(codexDir, "hooks.json"), hooksContent, "utf-8");
531
- console.log("✅ .codex/hooks.json 已创建");
567
+ userInfo("✅ .codex/hooks.json 已创建");
532
568
  // 生成 AGENTS.md
533
569
  const { config } = await resolveProjectConfig(projectPath);
534
570
  const agentsContent = generateCodexAgentsMd(config);
535
571
  fss.writeFileSync(path.join(projectPath, "AGENTS.md"), agentsContent, "utf-8");
536
- console.log("✅ AGENTS.md 已创建");
572
+ userInfo("✅ AGENTS.md 已创建");
537
573
  }
538
574
  async function cmdGenerateTraeInner(projectPath) {
539
575
  // 生成 .trae/mcp.json
@@ -542,20 +578,20 @@ async function cmdGenerateTraeInner(projectPath) {
542
578
  const traeMcpPath = path.join(traeDir, "mcp.json");
543
579
  const traeMcpConfig = generateTraeMcpConfig(projectPath);
544
580
  fss.writeFileSync(traeMcpPath, JSON.stringify(traeMcpConfig, null, 2), "utf-8");
545
- console.log("✅ .trae/mcp.json created");
581
+ userInfo("✅ .trae/mcp.json created");
546
582
  // 生成 .trae/rules/project_rules.md
547
583
  const rulesDir = path.join(traeDir, "rules");
548
584
  fss.mkdirSync(rulesDir, { recursive: true });
549
585
  const { config } = await resolveProjectConfig(projectPath);
550
586
  const rulesContent = generateTraeRules(config);
551
587
  fss.writeFileSync(path.join(rulesDir, "project_rules.md"), rulesContent, "utf-8");
552
- console.log("✅ .trae/rules/project_rules.md created");
588
+ userInfo("✅ .trae/rules/project_rules.md created");
553
589
  }
554
590
  async function cmdGenerateClaudeMdInner(projectPath) {
555
591
  const { config } = await resolveProjectConfig(projectPath);
556
592
  const content = generateClaudeMd(config);
557
593
  fss.writeFileSync(path.join(projectPath, "CLAUDE.md"), content, "utf-8");
558
- console.log("✅ CLAUDE.md created");
594
+ userInfo("✅ CLAUDE.md created");
559
595
  }
560
596
  async function cmdCheckWrite() {
561
597
  debugLog("CLI: 执行 cmdCheckWrite");
@@ -624,12 +660,12 @@ async function cmdCheckWrite() {
624
660
  process.exit(0);
625
661
  }
626
662
  if (result.severity === "warning") {
627
- console.error(JSON.stringify(result));
663
+ jsonSafeError(JSON.stringify(result));
628
664
  }
629
665
  process.exit(0); // 允许
630
666
  }
631
667
  catch (e) {
632
- console.error(`SoloForge 写入检查错误: ${e instanceof Error ? e.message : String(e)}`);
668
+ userError(`SoloForge 写入检查错误: ${e instanceof Error ? e.message : String(e)}`);
633
669
  process.exit(1);
634
670
  }
635
671
  }
@@ -639,16 +675,20 @@ function resolveProjectPath() {
639
675
  try {
640
676
  const stat = fss.statSync(envPath);
641
677
  if (!stat.isDirectory()) {
642
- console.error(`⚠️ SOLOFORGE_PROJECT (${envPath}) 不是目录,回退到 cwd`);
678
+ userWarn(`⚠️ SOLOFORGE_PROJECT (${envPath}) 不是目录,回退到 cwd`);
643
679
  return process.cwd();
644
680
  }
645
681
  return envPath;
646
682
  }
647
683
  catch {
648
- console.error(`⚠️ SOLOFORGE_PROJECT (${envPath}) 路径不存在,回退到 cwd`);
684
+ userWarn(`⚠️ SOLOFORGE_PROJECT (${envPath}) 路径不存在,回退到 cwd`);
649
685
  return process.cwd();
650
686
  }
651
687
  }
688
+ const projectPathArg = getArgValue("--project-path");
689
+ if (projectPathArg) {
690
+ return path.resolve(projectPathArg);
691
+ }
652
692
  return process.cwd();
653
693
  }
654
694
  async function cmdPostBash() {
@@ -699,12 +739,12 @@ async function cmdPrePrompt() {
699
739
  }
700
740
  }
701
741
  catch (e) {
702
- console.error("[soloForge] pre-prompt hook 错误:", e);
742
+ internalWarn("CLI", "pre-prompt hook 错误:", e);
703
743
  }
704
744
  process.exit(0);
705
745
  }
706
746
  async function checkEvidenceWarnings(projectPath) {
707
- console.error("[soloForge] CLI: 执行 checkEvidenceWarnings — " + projectPath);
747
+ debug("CLI", "执行 checkEvidenceWarnings —", projectPath);
708
748
  const warnings = [];
709
749
  const configPath = path.join(projectPath, ".soloforge", "config.yaml");
710
750
  const evidencePath = path.join(projectPath, ".soloforge", "config.evidence.json");
@@ -773,16 +813,16 @@ function getConfigFieldValue(config, key) {
773
813
  return obj;
774
814
  }
775
815
  async function cmdValidate() {
776
- console.error("[soloForge] CLI: 执行 cmdValidate");
777
- const projectPath = process.cwd();
816
+ debug("CLI", "执行 cmdValidate");
817
+ const projectPath = resolveProjectPath();
778
818
  try {
779
819
  const { config, source } = await resolveProjectConfig(projectPath);
780
820
  if (source === "inferred") {
781
- console.log("ℹ️ 未找到 .soloforge/config.yaml — 使用自动推断的配置。");
782
- console.log(" 运行 'soloforge init --auto' 可持久化。");
821
+ userInfo("ℹ️ 未找到 .soloforge/config.yaml — 使用自动推断的配置。");
822
+ userInfo(" 运行 'soloforge init --auto' 可持久化。");
783
823
  }
784
824
  else {
785
- console.log("✅ config.yaml 有效");
825
+ userInfo("✅ config.yaml 有效");
786
826
  }
787
827
  // 使用共享函数验证配置优先级
788
828
  let hasHardFail = false;
@@ -793,42 +833,121 @@ async function cmdValidate() {
793
833
  const advisory = findings.filter(f => f.severity === "advisory");
794
834
  if (hardFails.length > 0) {
795
835
  hasHardFail = true;
796
- console.log(`❌ 配置优先级: ${hardFails.length} hard_fail`);
836
+ userInfo(`❌ 配置优先级: ${hardFails.length} hard_fail`);
797
837
  for (const f of hardFails) {
798
- console.log(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
838
+ userInfo(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
799
839
  }
800
840
  }
801
841
  if (advisory.length > 0) {
802
- console.log(`⚠️ 配置优先级: ${advisory.length} advisory`);
842
+ userInfo(`⚠️ 配置优先级: ${advisory.length} advisory`);
803
843
  for (const f of advisory) {
804
- console.log(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
844
+ userInfo(` - [${f.rule}] ${f.field_path ?? "N/A"}: ${f.message}`);
805
845
  }
806
846
  }
807
847
  if (hardFails.length === 0 && advisory.length === 0) {
808
- console.log("✅ 配置优先级验证通过");
848
+ userInfo("✅ 配置优先级验证通过");
809
849
  }
810
850
  }
811
851
  catch { }
812
852
  // Evidence 检查
813
853
  const evidenceWarnings = await checkEvidenceWarnings(projectPath);
814
854
  for (const w of evidenceWarnings) {
815
- console.log(`⚠️ evidence: ${w}`);
855
+ userInfo(`⚠️ evidence: ${w}`);
816
856
  }
817
857
  // 检查知识文件
818
858
  const knowledgeDir = getProjectKnowledgeDir(config);
819
859
  if (fss.existsSync(knowledgeDir)) {
820
860
  const { KnowledgeIndexManager } = await import("../knowledge/index_manager.js");
821
- const index = new KnowledgeIndexManager(config);
822
- await index.build();
823
- const entries = index.getAllEntries();
824
- console.log(`✅ ${entries.project.length} 条项目知识已索引`);
825
- const issues = await index.checkHealth();
826
- if (issues.length > 0) {
827
- console.log(`⚠️ ${issues.length} 个健康问题:`);
828
- for (const { entry, issue } of issues) {
829
- console.log(` - ${entry.name}: ${issue}`);
861
+ const index = new KnowledgeIndexManager(config, { watch: false });
862
+ try {
863
+ await index.build();
864
+ const entries = index.getAllEntries();
865
+ userInfo(`✅ ${entries.project.length} 条项目知识已索引`);
866
+ const issues = await index.checkHealth();
867
+ if (issues.length > 0) {
868
+ userInfo(`⚠️ ${issues.length} 个健康问题:`);
869
+ for (const { entry, issue } of issues) {
870
+ userInfo(` - ${entry.name}: ${issue}`);
871
+ }
830
872
  }
831
873
  }
874
+ finally {
875
+ await index.close();
876
+ }
877
+ }
878
+ // 扩展清单校验 (problem-39: validateExtensionManifest)
879
+ try {
880
+ const { validateExtensionManifest } = await import("../engine/extension_contract.js");
881
+ const extResult = validateExtensionManifest({ extension_id: "soloforge-cli-validate", name: "SoloForge CLI 验证", version: "1.0.0", provider: "soloforge", extension_type: "workflow", contract_ids: [], capability_ids: [], permissions: ["read_project"], entrypoints: [], outputs: [], default_state: "disabled", compatibility: { min_soloforge_version: "1.0.0" } }, { extension_id: "soloforge-cli-validate", claimed_capabilities: [], claimed_enforcement: "advisory", third_party: false });
882
+ if (extResult.violations.length > 0) {
883
+ userInfo(" ✗ 扩展清单校验失败:");
884
+ for (const v of extResult.violations)
885
+ userInfo(` - ${v}`);
886
+ hasHardFail = true;
887
+ }
888
+ else {
889
+ userInfo(" ✓ 扩展清单校验通过");
890
+ }
891
+ }
892
+ catch (e) {
893
+ userInfo(` ⚠ 扩展清单校验异常: ${e instanceof Error ? e.message : String(e)}`);
894
+ }
895
+ // 平台兼容性检查 (problem-40: normalizePathRef via generatePlatformReport)
896
+ try {
897
+ const { generatePlatformReport } = await import("../engine/platform_context.js");
898
+ const platform = {
899
+ os: process.platform,
900
+ arch: process.arch,
901
+ shell: (process.env.SHELL?.includes("zsh") ? "zsh" : process.env.SHELL?.includes("fish") ? "fish" : "bash"),
902
+ path_case_sensitive: process.platform !== "darwin" && process.platform !== "win32",
903
+ path_separator: process.platform === "win32" ? "\\" : "/",
904
+ line_ending: process.platform === "win32" ? "crlf" : "lf",
905
+ supports_symlink: process.platform !== "win32",
906
+ workspace_realpath: projectPath,
907
+ };
908
+ const platformReport = generatePlatformReport(platform, ["package.json", "tsconfig.json"], process.cwd());
909
+ if (platformReport.platform_compatibility_status === "blocked") {
910
+ userInfo(` ✗ 平台兼容性阻断: ${platformReport.issues_found.join(", ")}`);
911
+ hasHardFail = true;
912
+ }
913
+ else {
914
+ userInfo(` ✓ 平台兼容性检查: ${platformReport.platform_compatibility_status}`);
915
+ }
916
+ }
917
+ catch (e) {
918
+ userInfo(` ⚠ 平台兼容性检查异常: ${e instanceof Error ? e.message : String(e)}`);
919
+ }
920
+ // README 命令漂移检测 (problem-30: detectReadmeDrift via validateUserPromise)
921
+ try {
922
+ const { validateUserPromise, getCliCommandContracts } = await import("../engine/user_promise.js");
923
+ const { extractReadmeCommands } = await import("../engine/knowledge_scenario_registry.js");
924
+ const fs = await import("node:fs");
925
+ const pathMod = await import("node:path");
926
+ const readmePath = pathMod.join(projectPath, "README.md");
927
+ if (fs.existsSync(readmePath)) {
928
+ const readmeContent = fs.readFileSync(readmePath, "utf-8");
929
+ const readmeCommands = extractReadmeCommands(readmeContent);
930
+ const promiseResult = validateUserPromise(readmeCommands, getCliCommandContracts());
931
+ const hardFails = promiseResult.findings.filter(f => f.severity === "hard_fail");
932
+ const warnings = promiseResult.findings.filter(f => f.severity === "warning");
933
+ if (hardFails.length > 0) {
934
+ userInfo(" ✗ README 命令漂移:");
935
+ for (const hf of hardFails)
936
+ userInfo(` - ${hf.message_zh}`);
937
+ hasHardFail = true;
938
+ }
939
+ else if (warnings.length > 0) {
940
+ userInfo(" ⚠ README 命令漂移警告:");
941
+ for (const w of warnings)
942
+ userInfo(` - ${w.message_zh}`);
943
+ }
944
+ else {
945
+ userInfo(" ✓ README 命令一致性检查通过");
946
+ }
947
+ }
948
+ }
949
+ catch (e) {
950
+ userInfo(` ⚠ README 命令漂移检测异常: ${e instanceof Error ? e.message : String(e)}`);
832
951
  }
833
952
  // 双层机制验证 (仅限 SoloForge 自身源码目录)
834
953
  if (fss.existsSync(path.join(projectPath, "src", "engine", "dual_layer_mechanism_registry.ts"))) {
@@ -837,29 +956,78 @@ async function cmdValidate() {
837
956
  const dlHard = dlFindings.filter((f) => f.severity === "hard_fail");
838
957
  const dlAdvisory = dlFindings.filter((f) => f.severity === "advisory");
839
958
  if (dlHard.length > 0) {
840
- console.log(`❌ 双层机制验证: ${dlHard.length} hard_fail`);
959
+ userInfo(`❌ 双层机制验证: ${dlHard.length} hard_fail`);
841
960
  for (const f of dlHard) {
842
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
961
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
843
962
  }
844
- console.error(`❌ validate 失败: 双层机制存在 ${dlHard.length} hard_fail`);
963
+ userError(`❌ validate 失败: 双层机制存在 ${dlHard.length} hard_fail`);
845
964
  process.exit(1);
846
965
  }
847
966
  else {
848
- console.log(`✅ 双层机制验证: ${dlAdvisory.length} advisory, 0 hard_fail`);
967
+ userInfo(`✅ 双层机制验证: ${dlAdvisory.length} advisory, 0 hard_fail`);
968
+ }
969
+ // problem-34: 测试策略覆盖验证 — 从 contract_registry 真实元数据构建
970
+ try {
971
+ const { validateTestStrategy } = await import("../engine/test_strategy.js");
972
+ const { getAllContracts } = await import("../engine/contract_registry.js");
973
+ const enforcedContracts = getAllContracts().filter((c) => c.state === "enforced");
974
+ let tsHardFail = false;
975
+ let tsChecked = 0;
976
+ let tsPending = 0;
977
+ for (const c of enforcedContracts) {
978
+ const hasTests = c.test_files && c.test_files.length > 0;
979
+ const hasLifecycle = c.lifecycle_test_files && c.lifecycle_test_files.length > 0;
980
+ if (!hasTests) {
981
+ // enforced 契约无测试文件元数据 → hard_fail,不得用 required_test_types:[] 掩盖
982
+ userInfo(`❌ 测试策略: ${c.contract_id} — enforced 契约缺少 test_files 元数据,无法验证覆盖`);
983
+ tsHardFail = true;
984
+ tsPending++;
985
+ continue;
986
+ }
987
+ const coverage = {
988
+ contract_id: c.contract_id,
989
+ required_test_types: ["unit"],
990
+ coverage_status: hasLifecycle ? "satisfied" : "partial",
991
+ satisfied_types: ["unit"],
992
+ missing_types: hasLifecycle ? [] : ["lifecycle"],
993
+ test_files: c.test_files || [],
994
+ has_lifecycle_test: hasLifecycle,
995
+ has_must_fail_case: false,
996
+ };
997
+ const tsErrors = validateTestStrategy(c.contract_id, true, coverage);
998
+ tsChecked++;
999
+ for (const e of tsErrors) {
1000
+ if (e.severity === "hard_fail") {
1001
+ tsHardFail = true;
1002
+ userInfo(`❌ 测试策略: ${c.contract_id} — ${e.error}`);
1003
+ }
1004
+ }
1005
+ }
1006
+ if (tsHardFail) {
1007
+ userError(`❌ 测试策略覆盖验证失败: ${tsChecked} 个已检查, ${tsPending} 个元数据缺失`);
1008
+ hasHardFail = true;
1009
+ }
1010
+ else {
1011
+ userInfo(`✅ 测试策略覆盖: 已检查 ${tsChecked} 个 enforced 契约`);
1012
+ }
1013
+ }
1014
+ catch (e) {
1015
+ userError(`❌ 测试策略验证异常: ${e.message}`);
1016
+ hasHardFail = true;
849
1017
  }
850
1018
  } // 双层机制检查结束
851
1019
  if (hasHardFail) {
852
- console.error("❌ validate 失败: 配置优先级存在 hard_fail");
1020
+ userError("❌ validate 失败: 配置优先级存在 hard_fail");
853
1021
  process.exit(1);
854
1022
  }
855
1023
  }
856
1024
  catch (e) {
857
- console.error(`❌ 验证失败: ${e.message}`);
1025
+ userError(`❌ 验证失败: ${e.message}`);
858
1026
  process.exit(1);
859
1027
  }
860
1028
  }
861
1029
  async function cmdValidateMechanisms() {
862
- console.error("[soloForge] CLI: 执行 cmdValidateMechanisms");
1030
+ debug("CLI", "执行 cmdValidateMechanisms");
863
1031
  // 从编译后的二进制位置推导根目录: dist/bin/soloforge.js -> 项目根
864
1032
  const soloforgeRoot = path.resolve(import.meta.dirname, "..", "..");
865
1033
  const projectPath = fss.existsSync(path.join(soloforgeRoot, "src", "engine"))
@@ -871,47 +1039,68 @@ async function cmdValidateMechanisms() {
871
1039
  const hardFails = findings.filter((f) => f.severity === "hard_fail");
872
1040
  const advisory = findings.filter((f) => f.severity === "advisory");
873
1041
  if (findings.length === 0) {
874
- console.log("✅ 所有双层机制映射验证通过,无发现。");
1042
+ userInfo("✅ 所有双层机制映射验证通过,无发现。");
875
1043
  process.exit(0);
876
1044
  return;
877
1045
  }
878
1046
  if (advisory.length > 0) {
879
- console.log(`⚠️ advisory findings (${advisory.length}):`);
1047
+ userInfo(`⚠️ advisory findings (${advisory.length}):`);
880
1048
  for (const f of advisory) {
881
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1049
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
882
1050
  }
883
1051
  }
884
1052
  if (hardFails.length > 0) {
885
- console.log(`❌ hard_fail findings (${hardFails.length}):`);
1053
+ userInfo(`❌ hard_fail findings (${hardFails.length}):`);
886
1054
  for (const f of hardFails) {
887
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1055
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1056
+ }
1057
+ userInfo(`\n❌ 双层机制验证失败: ${hardFails.length} hard_fail`);
1058
+ process.exit(1);
1059
+ }
1060
+ userInfo(`\n✅ 双层机制验证通过,${advisory.length} advisory findings`);
1061
+ // problem-15: 机制族实现一致性验证
1062
+ try {
1063
+ const { validateMechanismFamilies } = await import("../engine/mechanism_family_registry.js");
1064
+ const familyFindings = validateMechanismFamilies();
1065
+ const familyHardFails = familyFindings.filter((f) => f.severity === "hard_fail");
1066
+ if (familyHardFails.length > 0) {
1067
+ userInfo(`\n❌ 机制族验证失败 (${familyHardFails.length} hard_fail):`);
1068
+ for (const f of familyHardFails)
1069
+ userInfo(` - ${f.mechanism_id}: ${f.message_zh}`);
1070
+ process.exit(1);
1071
+ }
1072
+ else if (familyFindings.length > 0) {
1073
+ userInfo(`\n📊 机制族验证: ${familyFindings.length} advisory`);
888
1074
  }
889
- console.log(`\n❌ 双层机制验证失败: ${hardFails.length} hard_fail`);
1075
+ }
1076
+ catch (e) {
1077
+ userError(`❌ 机制族验证异常: ${e.message}`);
890
1078
  process.exit(1);
891
1079
  }
892
- console.log(`\n✅ 双层机制验证通过,${advisory.length} advisory findings`);
893
1080
  // 审计摘要
894
1081
  try {
895
1082
  const { auditTemplateMechanisms } = await import("../engine/template_mechanism_auditor.js");
896
1083
  const audit = auditTemplateMechanisms(projectPath);
897
1084
  if (audit.hard_fail_count > 0) {
898
- console.log(`\n⚠️ 模板审计摘要: ${audit.hard_fail_count} hard_fail, ${audit.unmapped_template_assets.length} unmapped`);
1085
+ userInfo(`\n模板审计摘要: ${audit.hard_fail_count} hard_fail, ${audit.unmapped_template_assets.length} unmapped`);
1086
+ process.exit(1);
899
1087
  }
900
1088
  else {
901
- console.log(`\n📊 模板审计: ${audit.total_template_files} 文件, ${audit.unmapped_template_assets.length} unmapped, ${audit.advisory_count} advisory`);
1089
+ userInfo(`\n📊 模板审计: ${audit.total_template_files} 文件, ${audit.unmapped_template_assets.length} unmapped, ${audit.advisory_count} advisory`);
902
1090
  }
903
1091
  }
904
- catch {
905
- // 审计仅为建议,不阻断
1092
+ catch (e) {
1093
+ userError(`❌ 模板审计异常: ${e.message}`);
1094
+ process.exit(1);
906
1095
  }
907
1096
  }
908
1097
  catch (e) {
909
- console.error(`❌ validate-mechanisms 失败: ${e.message}`);
1098
+ userError(`❌ validate-mechanisms 失败: ${e.message}`);
910
1099
  process.exit(1);
911
1100
  }
912
1101
  }
913
1102
  async function cmdAuditTemplateMechanisms() {
914
- console.error("[soloForge] CLI: 执行 cmdAuditTemplateMechanisms");
1103
+ debug("CLI", "执行 cmdAuditTemplateMechanisms");
915
1104
  const asJson = args.includes("--json");
916
1105
  const changedOnly = args.includes("--changed-only");
917
1106
  // 从编译后的二进制位置推导根目录
@@ -923,108 +1112,627 @@ async function cmdAuditTemplateMechanisms() {
923
1112
  const { auditTemplateMechanisms } = await import("../engine/template_mechanism_auditor.js");
924
1113
  const report = auditTemplateMechanisms(projectPath);
925
1114
  if (asJson) {
926
- console.log(JSON.stringify(report, null, 2));
1115
+ userInfo(JSON.stringify(report, null, 2));
927
1116
  if (report.hard_fail_count > 0) {
928
1117
  process.exit(1);
929
1118
  }
930
1119
  return;
931
1120
  }
932
1121
  // 人类可读输出
933
- console.log(`模板-机制审计报告 (${report.generated_at})`);
934
- console.log(` 模板文件: ${report.total_template_files}`);
935
- console.log(` 注册资产: ${report.total_registered_assets}`);
936
- console.log(` 机制总数: ${report.total_mechanisms}`);
937
- console.log("");
1122
+ userInfo(`模板-机制审计报告 (${report.generated_at})`);
1123
+ userInfo(` 模板文件: ${report.total_template_files}`);
1124
+ userInfo(` 注册资产: ${report.total_registered_assets}`);
1125
+ userInfo(` 机制总数: ${report.total_mechanisms}`);
1126
+ userInfo("");
938
1127
  if (report.unmapped_template_assets.length > 0) {
939
- console.log(`⚠️ 未注册模板 (${report.unmapped_template_assets.length}):`);
1128
+ userInfo(`⚠️ 未注册模板 (${report.unmapped_template_assets.length}):`);
940
1129
  for (const u of report.unmapped_template_assets) {
941
- console.log(` - ${u.path}`);
1130
+ userInfo(` - ${u.path}`);
942
1131
  }
943
1132
  }
944
1133
  if (report.unconsumed_template_assets.length > 0) {
945
- console.log(`⚠️ 未消费资产 (${report.unconsumed_template_assets.length}):`);
1134
+ userInfo(`⚠️ 未消费资产 (${report.unconsumed_template_assets.length}):`);
946
1135
  for (const u of report.unconsumed_template_assets) {
947
- console.log(` - ${u.path} (mode=${u.consumption_mode})`);
1136
+ userInfo(` - ${u.path} (mode=${u.consumption_mode})`);
948
1137
  }
949
1138
  }
950
1139
  if (report.code_only_mechanisms.length > 0) {
951
- console.log(`⚠️ 仅代码机制 (无模板层):`);
1140
+ userInfo(`⚠️ 仅代码机制 (无模板层):`);
952
1141
  for (const m of report.code_only_mechanisms) {
953
- console.log(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
1142
+ userInfo(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
954
1143
  }
955
1144
  }
956
1145
  if (report.template_only_mechanisms.length > 0) {
957
- console.log(`⚠️ 仅模板机制 (无代码层):`);
1146
+ userInfo(`⚠️ 仅模板机制 (无代码层):`);
958
1147
  for (const m of report.template_only_mechanisms) {
959
- console.log(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
1148
+ userInfo(` - ${m.mechanism_id} (${m.priority}, ${m.status})`);
960
1149
  }
961
1150
  }
962
1151
  if (report.required_assets_without_enforcer.length > 0) {
963
- console.log(`❌ Required 资产无 enforcer (${report.required_assets_without_enforcer.length}):`);
1152
+ userInfo(`❌ Required 资产无 enforcer (${report.required_assets_without_enforcer.length}):`);
964
1153
  for (const r of report.required_assets_without_enforcer) {
965
- console.log(` - ${r.path} (mechanism=${r.owner_mechanism_id})`);
1154
+ userInfo(` - ${r.path} (mechanism=${r.owner_mechanism_id})`);
966
1155
  }
967
1156
  }
968
1157
  if (report.overpromised_adapter_rules.length > 0) {
969
- console.log(`❌ 适配器过度承诺 (${report.overpromised_adapter_rules.length}):`);
1158
+ userInfo(`❌ 适配器过度承诺 (${report.overpromised_adapter_rules.length}):`);
970
1159
  for (const o of report.overpromised_adapter_rules) {
971
- console.log(` - ${o.source_file}: ${o.promised_mechanism_id} (${o.promise_keywords.join(",")})`);
1160
+ userInfo(` - ${o.source_file}: ${o.promised_mechanism_id} (${o.promise_keywords.join(",")})`);
972
1161
  }
973
1162
  }
974
1163
  if (report.deprecated_assets_injected.length > 0) {
975
- console.log(`⚠️ Deprecated 资产仍被注入:`);
1164
+ userInfo(`⚠️ Deprecated 资产仍被注入:`);
976
1165
  for (const d of report.deprecated_assets_injected) {
977
- console.log(` - ${d.path}`);
1166
+ userInfo(` - ${d.path}`);
978
1167
  }
979
1168
  }
980
1169
  if (report.template_mechanism_drift.length > 0) {
981
1170
  const driftHard = report.template_mechanism_drift.filter((f) => f.severity === "hard_fail");
982
1171
  const driftAdvisory = report.template_mechanism_drift.filter((f) => f.severity === "advisory");
983
1172
  if (driftAdvisory.length > 0) {
984
- console.log(`⚠️ 漂移 advisory (${driftAdvisory.length}):`);
1173
+ userInfo(`⚠️ 漂移 advisory (${driftAdvisory.length}):`);
985
1174
  for (const f of driftAdvisory) {
986
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1175
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
987
1176
  }
988
1177
  }
989
1178
  if (driftHard.length > 0) {
990
- console.log(`❌ 漂移 hard_fail (${driftHard.length}):`);
1179
+ userInfo(`❌ 漂移 hard_fail (${driftHard.length}):`);
991
1180
  for (const f of driftHard) {
992
- console.log(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
1181
+ userInfo(` - [${f.finding_type}] ${f.mechanism_id}: ${f.message}`);
993
1182
  }
994
1183
  }
995
1184
  }
996
- console.log("");
1185
+ userInfo("");
997
1186
  if (report.hard_fail_count > 0) {
998
- console.log(`❌ 审计失败: ${report.hard_fail_count} hard_fail, ${report.advisory_count} advisory`);
999
- process.exit(1);
1187
+ userInfo(`❌ 审计失败: ${report.hard_fail_count} hard_fail, ${report.advisory_count} advisory`);
1000
1188
  }
1001
1189
  else {
1002
- console.log(`✅ 审计通过: 0 hard_fail, ${report.advisory_count} advisory`);
1190
+ userInfo(`✅ 审计通过: 0 hard_fail, ${report.advisory_count} advisory`);
1191
+ }
1192
+ // problem-57: 知识资产 schema 审计
1193
+ try {
1194
+ const { auditKnowledgeAssets, parseAssetFile } = await import("../engine/knowledge_asset_audit.js");
1195
+ const knowledgeDirs = [
1196
+ path.join(projectPath, "templates", "knowledge", "procedures"),
1197
+ path.join(projectPath, "templates", "knowledge", "rules"),
1198
+ path.join(projectPath, "templates", "knowledge", "checklists"),
1199
+ path.join(projectPath, "templates", "knowledge", "acceptance_templates"),
1200
+ path.join(projectPath, "templates", "knowledge", "review_rules"),
1201
+ path.join(projectPath, "templates", "knowledge", "workflow_templates"),
1202
+ ];
1203
+ const assets = [];
1204
+ for (const dir of knowledgeDirs) {
1205
+ if (!fss.existsSync(dir))
1206
+ continue;
1207
+ for (const entry of fss.readdirSync(dir).filter((f) => f.endsWith(".md"))) {
1208
+ const fp = path.join(dir, entry);
1209
+ const content = fss.readFileSync(fp, "utf-8");
1210
+ assets.push(parseAssetFile(fp, content));
1211
+ }
1212
+ }
1213
+ if (assets.length > 0) {
1214
+ const kaReport = auditKnowledgeAssets(assets);
1215
+ userInfo("");
1216
+ userInfo("知识资产审计:");
1217
+ userInfo(` 资产数: ${kaReport.total_assets}`);
1218
+ userInfo(` 通过: ${kaReport.passed ? "✓" : "✗"}`);
1219
+ userInfo(` hard_fail: ${kaReport.hard_fail_count}, warning: ${kaReport.warning_count}`);
1220
+ for (const f of kaReport.findings) {
1221
+ const icon = f.severity === "hard_fail" ? "❌" : "⚠️";
1222
+ userInfo(` ${icon} ${f.asset_id ?? f.file_path}: ${f.detail} (${f.kind})`);
1223
+ }
1224
+ if (kaReport.hard_fail_count > 0) {
1225
+ userInfo(`❌ 知识资产审计有 ${kaReport.hard_fail_count} hard_fail`);
1226
+ process.exit(1);
1227
+ }
1228
+ }
1229
+ }
1230
+ catch (e) {
1231
+ userError(`❌ 知识资产审计异常: ${e.message}`);
1232
+ process.exit(1);
1233
+ }
1234
+ if (report.hard_fail_count > 0) {
1235
+ process.exit(1);
1003
1236
  }
1004
1237
  }
1005
1238
  catch (e) {
1006
- console.error(`❌ audit-template-mechanisms 失败: ${e.message}`);
1239
+ userError(`❌ audit-template-mechanisms 失败: ${e.message}`);
1240
+ process.exit(1);
1241
+ }
1242
+ }
1243
+ async function cmdValidateKnowledge() {
1244
+ debug("CLI", "执行 cmdValidateKnowledge");
1245
+ const { validateContractRegistry } = await import("../engine/contract_registry.js");
1246
+ const { listProblemsByBatch } = await import("../engine/implementation_roadmap_registry.js");
1247
+ const { runAllKnowledgeScenarios, extractReadmeCommands } = await import("../engine/knowledge_scenario_registry.js");
1248
+ const { listKnowledgeIssueDetailAcceptances, validateKnowledgeIssueDetailAcceptance, } = await import("../engine/knowledge_acceptance_registry.js");
1249
+ const isJson = args.includes("--json");
1250
+ const cwd = process.cwd();
1251
+ const fs = await import("node:fs");
1252
+ const pathModule = await import("node:path");
1253
+ // 收集项目文件集合
1254
+ const existingFiles = new Set();
1255
+ function walkDir(dir, prefix) {
1256
+ try {
1257
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
1258
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
1259
+ if (entry.isDirectory()) {
1260
+ walkDir(pathModule.join(dir, entry.name), rel);
1261
+ }
1262
+ else {
1263
+ existingFiles.add(rel);
1264
+ }
1265
+ }
1266
+ }
1267
+ catch { /* 忽略不存在目录 */ }
1268
+ }
1269
+ walkDir(pathModule.join(cwd, "src"), "src");
1270
+ walkDir(pathModule.join(cwd, "tests"), "tests");
1271
+ // 验证契约注册表
1272
+ const contractFindings = validateContractRegistry(existingFiles);
1273
+ const hardFails = contractFindings.filter((f) => f.severity === "hard_fail");
1274
+ // 验证 知识模板问题状态
1275
+ const knowledgeProblems = listProblemsByBatch("batch-3");
1276
+ const allImplemented = knowledgeProblems.every((p) => p.status === "implemented_verified");
1277
+ // 读取真实 README 并提取命令
1278
+ let readmeCommands;
1279
+ try {
1280
+ const readmeContent = fs.readFileSync(pathModule.join(cwd, "README.md"), "utf-8");
1281
+ readmeCommands = extractReadmeCommands(readmeContent);
1282
+ }
1283
+ catch { /* README 不存在时跳过 */ }
1284
+ // 运行真实场景矩阵
1285
+ const scenarioResults = runAllKnowledgeScenarios(readmeCommands);
1286
+ const scenariosPass = scenarioResults.every((s) => s.status === "PASS");
1287
+ // 验证 IssueDetailAcceptance 注册表
1288
+ const acceptances = listKnowledgeIssueDetailAcceptances();
1289
+ const acceptanceFindings = acceptances.flatMap((a) => validateKnowledgeIssueDetailAcceptance(a));
1290
+ const acceptanceHardFails = acceptanceFindings.filter((f) => f.severity === "hard_fail");
1291
+ const result = {
1292
+ knowledge_problems: knowledgeProblems.length,
1293
+ all_implemented_verified: allImplemented,
1294
+ contract_hard_fails: hardFails.length,
1295
+ issue_acceptances: acceptances.length,
1296
+ acceptance_hard_fails: acceptanceHardFails.length,
1297
+ scenarios_pass: scenariosPass,
1298
+ scenario_results: scenarioResults.map((s) => ({
1299
+ scenario_id: s.scenario_id,
1300
+ scenario_name: s.scenario_name,
1301
+ status: s.status,
1302
+ evidence: s.evidence,
1303
+ failures: s.failures.length,
1304
+ })),
1305
+ };
1306
+ if (isJson) {
1307
+ userInfo(JSON.stringify(result, null, 2));
1308
+ }
1309
+ else {
1310
+ userInfo("═══ Batch 3 验证 ═══");
1311
+ userInfo(` 问题数: ${knowledgeProblems.length}`);
1312
+ userInfo(` 全部 implemented_verified: ${allImplemented ? "✓" : "✗"}`);
1313
+ userInfo(` 契约 hard_fail: ${hardFails.length}`);
1314
+ for (const f of hardFails) {
1315
+ userInfo(` ✗ ${f.contract_id}: ${f.message_zh}`);
1316
+ }
1317
+ userInfo(` IssueDetailAcceptance: ${acceptances.length} 条, hard_fail: ${acceptanceHardFails.length}`);
1318
+ for (const f of acceptanceHardFails) {
1319
+ userInfo(` ✗ ${f.issue_id}: ${f.message_zh}`);
1320
+ }
1321
+ userInfo(` 场景矩阵:`);
1322
+ for (const s of scenarioResults) {
1323
+ const icon = s.status === "PASS" ? "✓" : "✗";
1324
+ userInfo(` ${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
1325
+ for (const ev of s.evidence) {
1326
+ userInfo(` ✓ ${ev}`);
1327
+ }
1328
+ for (const fl of s.failures) {
1329
+ userInfo(` ✗ ${fl}`);
1330
+ }
1331
+ }
1332
+ const overallPass = allImplemented && hardFails.length === 0 && scenariosPass && acceptanceHardFails.length === 0;
1333
+ userInfo(overallPass ? "\n✅ Batch 3 验证通过" : "\n❌ Batch 3 验证失败");
1334
+ }
1335
+ const overallPass = allImplemented && hardFails.length === 0 && scenariosPass && acceptanceHardFails.length === 0;
1336
+ process.exit(overallPass ? 0 : 1);
1337
+ }
1338
+ async function cmdSyncTemplates() {
1339
+ debug("CLI", "执行 cmdSyncTemplates");
1340
+ const apply = args.includes("--apply");
1341
+ const confirm = args.includes("--confirm");
1342
+ const isJson = args.includes("--json");
1343
+ const { executeSync, validateSyncSafety, computeTemplateAssetVersions } = await import("../engine/template_sync.js");
1344
+ const { validateWorkflowTemplatePack, createWorkflowTemplatePackContract, createWorkflowTemplateEntry, createTemplateConsumptionEvidence, } = await import("../engine/workflow_template_pack.js");
1345
+ const { buildTemplateManifestFromSource, computeFileHashes, loadProjectManifest, saveProjectManifest, writeFileSyncRecursive, sha256Hex, hashFile, } = await import("../engine/template_manifest_io.js");
1346
+ const projectPath = process.cwd();
1347
+ const packageRoot = path.resolve(import.meta.dirname, "..", "..");
1348
+ const sourceDir = args.find((a) => a.startsWith("--source="))?.slice("--source=".length) ?? path.join(packageRoot, "templates");
1349
+ // 读取当前包版本
1350
+ let packageVersion = "0.0.0";
1351
+ try {
1352
+ const pkgJson = JSON.parse(fss.readFileSync(path.join(packageRoot, "package.json"), "utf-8"));
1353
+ packageVersion = pkgJson.version;
1354
+ }
1355
+ catch { /* 回退 */ }
1356
+ // 构建源清单(真实模板文件)
1357
+ const sourceManifest = buildTemplateManifestFromSource(sourceDir, packageVersion);
1358
+ // 加载已安装清单
1359
+ const installedManifest = loadProjectManifest(projectPath) ?? [];
1360
+ // 计算哈希(Map key 用相对路径,与 computeTemplateAssetVersions 查找键一致)
1361
+ const sourceHashes = new Map();
1362
+ for (const e of sourceManifest) {
1363
+ const h = hashFile(path.join(packageRoot, e.source_path));
1364
+ if (h !== null)
1365
+ sourceHashes.set(e.source_path, h);
1366
+ }
1367
+ const baseManifest = installedManifest.length > 0 ? installedManifest : sourceManifest;
1368
+ const currentHashes = new Map();
1369
+ for (const e of baseManifest) {
1370
+ const h = hashFile(path.join(projectPath, e.target_path));
1371
+ if (h !== null)
1372
+ currentHashes.set(e.target_path, h);
1373
+ }
1374
+ // 计算差异(首次安装用 sourceManifest 作为基准,全部为 missing)
1375
+ const assets = computeTemplateAssetVersions(baseManifest, currentHashes, sourceHashes);
1376
+ // problem-53: 工作流模板包完整性校验 — 用真实 manifest 数据构建 pack
1377
+ const wfPackEntries = sourceManifest
1378
+ .filter(e => e.asset_kind === "workflow_template")
1379
+ .map(e => createWorkflowTemplateEntry("architecture_design", e.target_path));
1380
+ const wfConsumptionEvidences = assets
1381
+ .filter(a => wfPackEntries.some(w => w.template_path === a.target_path))
1382
+ .map(a => createTemplateConsumptionEvidence(a.target_path));
1383
+ if (wfPackEntries.length > 0) {
1384
+ const wfPack = createWorkflowTemplatePackContract({
1385
+ workflows: wfPackEntries,
1386
+ mechanism_consumption_map: sourceManifest
1387
+ .filter(e => e.asset_kind === "workflow_template")
1388
+ .map(e => ({ template_path: e.target_path, consumed_mechanism_id: `mc-${e.asset_id}`, consumption_type: "route_trigger", evidence_required: true })),
1389
+ });
1390
+ const wfResult = validateWorkflowTemplatePack(wfPack, wfConsumptionEvidences);
1391
+ if (!wfResult.valid && !isJson) {
1392
+ userInfo(` ⚠ 工作流模板包校验: ${wfResult.violations.length} 个违规`);
1393
+ for (const v of wfResult.violations)
1394
+ userInfo(` - ${v}`);
1395
+ }
1396
+ if (!wfResult.valid && apply) {
1397
+ // 校验失败阻断 apply
1398
+ internalWarn("CLI", `工作流模板包校验失败,apply 已阻断。违规: ${wfResult.violations.join("; ")}`);
1399
+ process.exit(1);
1400
+ }
1401
+ }
1402
+ const safeCheck = validateSyncSafety(assets);
1403
+ const syncResult = executeSync({ dry_run: !apply, apply, confirm, project_path: projectPath, source_path: sourceDir }, assets, sourceManifest);
1404
+ // apply 模式:真实文件复制
1405
+ if (apply && confirm && syncResult.success && syncResult.backup_path) {
1406
+ const backupDir = syncResult.backup_path;
1407
+ fss.mkdirSync(backupDir, { recursive: true });
1408
+ const assetMap = new Map(assets.map((a) => [a.asset_id, a]));
1409
+ const updatedManifest = [...sourceManifest];
1410
+ for (const assetId of [...syncResult.report.added, ...syncResult.report.updated]) {
1411
+ const asset = assetMap.get(assetId);
1412
+ if (!asset)
1413
+ continue;
1414
+ const srcAbs = path.join(packageRoot, asset.source_path);
1415
+ const tgtAbs = path.join(projectPath, asset.target_path);
1416
+ // 备份已有文件
1417
+ if (fss.existsSync(tgtAbs)) {
1418
+ const backupFile = path.join(backupDir, path.basename(tgtAbs));
1419
+ fss.copyFileSync(tgtAbs, backupFile);
1420
+ }
1421
+ // 复制源文件到目标
1422
+ writeFileSyncRecursive(tgtAbs, fss.readFileSync(srcAbs));
1423
+ // 更新清单中的 installed_hash
1424
+ const idx = updatedManifest.findIndex((e) => e.asset_id === assetId);
1425
+ if (idx >= 0) {
1426
+ updatedManifest[idx] = {
1427
+ ...updatedManifest[idx],
1428
+ installed_hash: asset.source_hash,
1429
+ installed_at: new Date().toISOString(),
1430
+ };
1431
+ }
1432
+ }
1433
+ // 持久化清单
1434
+ saveProjectManifest(projectPath, updatedManifest);
1435
+ }
1436
+ if (isJson) {
1437
+ userInfo(JSON.stringify({
1438
+ command: "sync-templates",
1439
+ mode: apply ? "apply" : "dry_run",
1440
+ total_assets: assets.length,
1441
+ safe: safeCheck.safe,
1442
+ result: syncResult.success,
1443
+ dry_run: syncResult.dry_run,
1444
+ report: syncResult.report,
1445
+ }, null, 2));
1446
+ }
1447
+ else {
1448
+ userInfo(apply ? "模板同步: apply 模式" : "模板同步: dry-run 模式(不写入文件)");
1449
+ userInfo(` 资产总数: ${assets.length}`);
1450
+ userInfo(` 安全检查: ${safeCheck.safe ? "✓" : "✗"}`);
1451
+ userInfo(` 结果: ${syncResult.success ? "成功" : "失败"}`);
1452
+ userInfo(` 新增: ${syncResult.report.added.length}`);
1453
+ userInfo(` 更新: ${syncResult.report.updated.length}`);
1454
+ userInfo(` 跳过(用户修改): ${syncResult.report.skipped_user_modified.length}`);
1455
+ userInfo(` 废弃: ${syncResult.report.deprecated.length}`);
1456
+ if (!apply)
1457
+ userInfo(" 使用 --apply --confirm 应用同步");
1458
+ }
1459
+ if (!syncResult.success)
1460
+ process.exit(1);
1461
+ }
1462
+ async function cmdSyncAdapters() {
1463
+ debug("CLI", "执行 cmdSyncAdapters");
1464
+ const apply = args.includes("--apply");
1465
+ const confirm = args.includes("--confirm");
1466
+ const isJson = args.includes("--json");
1467
+ const { syncAdapterPrompts, validateAdapterPrompt, REQUIRED_ADAPTER_SECTIONS, } = await import("../engine/adapter_prompt_contract.js");
1468
+ const { writeFileSyncRecursive, sha256Hex, hashFile, } = await import("../engine/template_manifest_io.js");
1469
+ const projectPath = process.cwd();
1470
+ // 加载项目配置(回退到默认)
1471
+ let config;
1472
+ try {
1473
+ const resolved = await resolveProjectConfig(projectPath);
1474
+ config = resolved.config;
1475
+ }
1476
+ catch {
1477
+ config = {
1478
+ name: "default", tech_stack: { backend: { lang: "", framework: "", version: "" }, frontend: { lang: "", framework: "", version: "" } },
1479
+ product_profile: "general", repos: [], build_commands: { backend: {}, frontend: {} }, scope: { backend: [], frontend: [] },
1480
+ };
1481
+ }
1482
+ // 适配器生成器
1483
+ const { generateClaudeMd } = await import("../adapters/claude_code/claude_md.js");
1484
+ const { generateCodexAgentsMd } = await import("../adapters/codex/codex_rules.js");
1485
+ const { generateTraeRules } = await import("../adapters/trae/trae_rules.js");
1486
+ const sections = [...REQUIRED_ADAPTER_SECTIONS];
1487
+ // 适配器 installed hash 记录文件
1488
+ const ADAPTER_HASH_FILE = ".soloforge/adapter_hashes.json";
1489
+ // 加载已安装的适配器 hash 记录
1490
+ let installedAdapterHashes = {};
1491
+ try {
1492
+ const hashContent = fss.readFileSync(path.join(projectPath, ADAPTER_HASH_FILE), "utf-8");
1493
+ installedAdapterHashes = JSON.parse(hashContent);
1494
+ }
1495
+ catch { /* 首次无记录 */ }
1496
+ const adapterContracts = [
1497
+ {
1498
+ adapter_id: "claude-code", host_type: "claude_code",
1499
+ prompt_path: "CLAUDE.md",
1500
+ generated_from_contract_version: "1",
1501
+ required_sections: sections,
1502
+ forbidden_claims: [],
1503
+ sync_required: true,
1504
+ next_allowed_tools: ["sf_classify", "sf_expand", "sf_verify", "sf_learn", "sf_deliver", "sf_review"],
1505
+ },
1506
+ {
1507
+ adapter_id: "codex", host_type: "codex",
1508
+ prompt_path: "AGENTS.md",
1509
+ generated_from_contract_version: "1",
1510
+ required_sections: sections,
1511
+ forbidden_claims: [],
1512
+ sync_required: true,
1513
+ next_allowed_tools: ["sf_classify", "sf_expand", "sf_verify", "sf_learn"],
1514
+ },
1515
+ {
1516
+ adapter_id: "trae", host_type: "cursor",
1517
+ prompt_path: ".trae/rules/project_rules.md",
1518
+ generated_from_contract_version: "1",
1519
+ required_sections: sections,
1520
+ forbidden_claims: [],
1521
+ sync_required: true,
1522
+ next_allowed_tools: ["sf_classify", "sf_expand", "sf_verify", "sf_learn"],
1523
+ },
1524
+ ];
1525
+ // 验证所有适配器
1526
+ const validations = syncAdapterPrompts(adapterContracts, { dry_run: !apply, apply, confirm });
1527
+ // 适配器内容生成
1528
+ const generators = {
1529
+ "claude-code": () => generateClaudeMd(config),
1530
+ "codex": () => generateCodexAgentsMd(config),
1531
+ "trae": () => generateTraeRules(config),
1532
+ };
1533
+ // apply 模式:写入合规的适配器文件
1534
+ const writtenFiles = [];
1535
+ const skippedFiles = [];
1536
+ if (apply && confirm) {
1537
+ const updatedHashes = { ...installedAdapterHashes };
1538
+ for (const contract of adapterContracts) {
1539
+ const validation = validations.find((v) => v.adapter_id === contract.adapter_id);
1540
+ if (!validation?.compliant) {
1541
+ skippedFiles.push(`${contract.adapter_id}: 不合规,跳过`);
1542
+ continue;
1543
+ }
1544
+ const targetPath = path.join(projectPath, contract.prompt_path);
1545
+ const generator = generators[contract.adapter_id];
1546
+ if (!generator)
1547
+ continue;
1548
+ const content = generator();
1549
+ const generatedHash = sha256Hex(content);
1550
+ // 用户修改检测:文件存在且 hash 与已安装 hash 不一致
1551
+ if (fss.existsSync(targetPath)) {
1552
+ const diskHash = hashFile(targetPath);
1553
+ const installedHash = installedAdapterHashes[contract.adapter_id];
1554
+ if (diskHash && installedHash && diskHash !== installedHash) {
1555
+ // 文件被用户修改,不得覆盖
1556
+ skippedFiles.push(`${contract.adapter_id}: 用户已修改,跳过`);
1557
+ continue;
1558
+ }
1559
+ }
1560
+ // 首次安装或内容有变化:写入
1561
+ writeFileSyncRecursive(targetPath, content);
1562
+ writtenFiles.push(contract.prompt_path);
1563
+ updatedHashes[contract.adapter_id] = generatedHash;
1564
+ }
1565
+ // 持久化 hash 记录
1566
+ writeFileSyncRecursive(path.join(projectPath, ADAPTER_HASH_FILE), JSON.stringify(updatedHashes, null, 2));
1567
+ }
1568
+ if (isJson) {
1569
+ userInfo(JSON.stringify({
1570
+ command: "sync-adapters",
1571
+ mode: apply ? "apply" : "dry_run",
1572
+ adapter_count: adapterContracts.length,
1573
+ validations,
1574
+ written: writtenFiles,
1575
+ skipped: skippedFiles,
1576
+ }, null, 2));
1577
+ }
1578
+ else {
1579
+ userInfo(apply ? "适配器同步: apply 模式" : "适配器同步: dry-run 模式(不写入文件)");
1580
+ userInfo(` 适配器数量: ${adapterContracts.length}`);
1581
+ for (const v of validations) {
1582
+ const icon = v.compliant ? "✓" : "✗";
1583
+ userInfo(` ${icon} ${v.adapter_id}: ${v.compliant ? "合规" : "不合规"}`);
1584
+ for (const f of v.findings) {
1585
+ if (f.severity !== "info")
1586
+ userInfo(` ${f.severity === "critical" ? "✗" : "⚠"} ${f.message_zh}`);
1587
+ }
1588
+ }
1589
+ if (writtenFiles.length > 0) {
1590
+ userInfo(` 已写入: ${writtenFiles.join(", ")}`);
1591
+ }
1592
+ if (skippedFiles.length > 0) {
1593
+ userInfo(` 已跳过: ${skippedFiles.join("; ")}`);
1594
+ }
1595
+ if (!apply)
1596
+ userInfo(" 使用 --apply --confirm 应用同步");
1597
+ }
1598
+ }
1599
+ async function cmdMigrate() {
1600
+ debug("CLI", "执行 cmdMigrate");
1601
+ const apply = args.includes("--apply");
1602
+ const confirm = args.includes("--confirm");
1603
+ const isJson = args.includes("--json");
1604
+ const { createMigrationPlan, getCurrentCompatibility, validateMigrationSafety, generateVersionFile } = await import("../engine/release_compatibility.js");
1605
+ const { loadProjectVersion, saveProjectVersion, writeFileSyncRecursive } = await import("../engine/template_manifest_io.js");
1606
+ const projectPath = process.cwd();
1607
+ const compat = getCurrentCompatibility();
1608
+ const toVersion = compat.package_version;
1609
+ // 读取项目已安装版本,不存在视为首次
1610
+ const installed = loadProjectVersion(projectPath);
1611
+ const fromVersion = installed?.soloforge_package_version ?? "0.0.0";
1612
+ // 版本相同,无需迁移
1613
+ if (fromVersion === toVersion) {
1614
+ if (isJson) {
1615
+ userInfo(JSON.stringify({
1616
+ command: "migrate",
1617
+ mode: "noop",
1618
+ success: true,
1619
+ dry_run: !apply,
1620
+ safe: true,
1621
+ message: `已是最新版本 ${toVersion}`,
1622
+ from_version: fromVersion,
1623
+ to_version: toVersion,
1624
+ }, null, 2));
1625
+ }
1626
+ else {
1627
+ userInfo(`项目迁移: 已是最新版本 ${toVersion}`);
1628
+ userInfo(` 当前版本: ${fromVersion}`);
1629
+ }
1630
+ return;
1631
+ }
1632
+ // 先生成真实迁移计划
1633
+ const plan = createMigrationPlan({ dry_run: !apply, apply, confirm, project_path: projectPath, from_version: fromVersion, to_version: toVersion }, compat);
1634
+ // 基于真实 plan 做安全检查
1635
+ const safetyCheck = validateMigrationSafety(plan.plan, apply, !!confirm);
1636
+ // apply --confirm 模式且安全通过时:创建备份 + 写入 version.json
1637
+ if (apply && confirm && plan.success && safetyCheck.safe && plan.backup_path) {
1638
+ const backupDir = path.join(projectPath, plan.backup_path);
1639
+ fss.mkdirSync(backupDir, { recursive: true });
1640
+ // 备份已有 version.json
1641
+ const versionPath = path.join(projectPath, ".soloforge/version.json");
1642
+ if (fss.existsSync(versionPath)) {
1643
+ fss.copyFileSync(versionPath, path.join(backupDir, "version.json"));
1644
+ }
1645
+ // 写入新版本文件
1646
+ const versionContent = generateVersionFile(toVersion, compat.contract_registry_version);
1647
+ // 合并 created_at(首次用新时间,升级保留原时间)
1648
+ if (installed?.created_at) {
1649
+ versionContent.created_at = installed.created_at;
1650
+ }
1651
+ saveProjectVersion(projectPath, versionContent);
1652
+ }
1653
+ const success = plan.success && safetyCheck.safe;
1654
+ if (isJson) {
1655
+ userInfo(JSON.stringify({
1656
+ command: "migrate",
1657
+ mode: apply ? "apply" : "dry_run",
1658
+ success,
1659
+ dry_run: plan.dry_run,
1660
+ safe: safetyCheck.safe,
1661
+ from_version: fromVersion,
1662
+ to_version: toVersion,
1663
+ plan: plan.plan,
1664
+ backup_path: plan.backup_path,
1665
+ }, null, 2));
1666
+ }
1667
+ else {
1668
+ userInfo(apply ? "项目迁移: apply 模式" : "项目迁移: dry-run 模式(不写入文件)");
1669
+ userInfo(` 结果: ${success ? "成功" : "失败"}`);
1670
+ userInfo(` 从版本: ${fromVersion}`);
1671
+ userInfo(` 到版本: ${toVersion}`);
1672
+ userInfo(` 安全检查: ${safetyCheck.safe ? "✓" : "✗"}`);
1673
+ userInfo(` 需迁移: ${plan.plan.required_migrations.length}`);
1674
+ userInfo(` 自动应用: ${plan.plan.auto_applicable.length}`);
1675
+ userInfo(` 需人工: ${plan.plan.requires_human.length}`);
1676
+ if (!apply)
1677
+ userInfo(" 使用 --apply --confirm 执行迁移");
1678
+ }
1679
+ if (!success)
1007
1680
  process.exit(1);
1681
+ }
1682
+ async function cmdValidateReleaseGate() {
1683
+ const isJson = args.includes("--json");
1684
+ debug("CLI", "执行 cmdValidateReleaseGate");
1685
+ const { runReleaseReadinessGate } = await import("../engine/release_readiness_gate.js");
1686
+ const result = await runReleaseReadinessGate(process.cwd());
1687
+ if (isJson) {
1688
+ userInfo(JSON.stringify({
1689
+ passed: result.passed,
1690
+ hard_fail_count: result.hard_fail_count,
1691
+ hard_fails: result.hard_fails,
1692
+ phases: result.phases,
1693
+ }, null, 2));
1694
+ }
1695
+ else {
1696
+ userInfo("══════════════════════════════════════════════════════════════");
1697
+ userInfo(`发布结论: ${result.passed ? "PASS" : "FAIL"}`);
1698
+ userInfo(`hard_fail 数量: ${result.hard_fail_count}`);
1699
+ userInfo("══════════════════════════════════════════════════════════════");
1700
+ userInfo();
1701
+ for (const p of result.phases) {
1702
+ userInfo(` ${p.hard_fail_count === 0 ? "[PASS]" : "[FAIL]"} ${p.name} — ${p.hard_fail_count} hard_fail`);
1703
+ }
1704
+ if (result.hard_fails.length > 0) {
1705
+ userInfo();
1706
+ userInfo("━━━ hard_fail 明细 ━━━");
1707
+ for (let i = 0; i < result.hard_fails.length; i++) {
1708
+ const hf = result.hard_fails[i];
1709
+ userInfo(`[${i + 1}] ${hf.code}: ${hf.message}`);
1710
+ userInfo(` 涉及: ${hf.files.join(", ")}`);
1711
+ userInfo(` 下一步: ${hf.nextStep}`);
1712
+ }
1713
+ }
1008
1714
  }
1715
+ if (!result.passed)
1716
+ process.exit(1);
1009
1717
  }
1010
- async function cmdValidateBatch1() {
1011
- console.error("[soloForge] CLI: 执行 cmdValidateBatch1");
1718
+ async function cmdValidateFoundation() {
1719
+ debug("CLI", "执行 cmdValidateFoundation");
1012
1720
  const { validateMechanismLayerMaps, listMechanismLayerMaps } = await import("../engine/dual_layer_mechanism_registry.js");
1013
1721
  const { auditTemplateMechanisms } = await import("../engine/template_mechanism_auditor.js");
1014
- const { validateBatch1Scenarios, validateBatch1ProblemMatrix } = await import("../engine/batch1_scenario_registry.js");
1722
+ const { validateFoundationScenarios, validateFoundationProblemMatrix } = await import("../engine/foundation_scenario_registry.js");
1015
1723
  const cwd = process.cwd();
1016
1724
  const maps = listMechanismLayerMaps();
1017
1725
  const mechFindings = validateMechanismLayerMaps(maps, cwd);
1018
1726
  const mechanismsPass = mechFindings.filter((f) => f.severity === "hard_fail").length === 0;
1019
1727
  const auditReport = auditTemplateMechanisms(cwd);
1020
1728
  const auditPass = auditReport.hard_fail_count === 0;
1021
- const scenarioResults = await validateBatch1Scenarios(mechanismsPass, auditPass, true);
1729
+ const scenarioResults = await validateFoundationScenarios(mechanismsPass, auditPass, true);
1022
1730
  const allPass = scenarioResults.every((s) => s.status === "PASS");
1023
1731
  const isJson = process.argv.includes("--json");
1024
1732
  if (isJson) {
1025
- const problemMatrix = validateBatch1ProblemMatrix(cwd);
1733
+ const problemMatrix = validateFoundationProblemMatrix(cwd);
1026
1734
  const problemAllPass = problemMatrix.every((p) => Object.values(p.dimensions).every((d) => d.status === "PASS"));
1027
- console.log(JSON.stringify({
1735
+ userInfo(JSON.stringify({
1028
1736
  mechanisms_pass: mechanismsPass,
1029
1737
  audit_pass: auditPass,
1030
1738
  all_pass: allPass && problemAllPass,
@@ -1036,71 +1744,173 @@ async function cmdValidateBatch1() {
1036
1744
  else {
1037
1745
  for (const s of scenarioResults) {
1038
1746
  const icon = s.status === "PASS" ? "✓" : "✗";
1039
- console.log(`${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
1747
+ userInfo(`${icon} ${s.scenario_id}: ${s.scenario_name} — ${s.status}`);
1040
1748
  for (const r of s.rules) {
1041
1749
  const ri = r.status === "PASS" ? " ✓" : " ✗";
1042
- console.log(`${ri} ${r.rule}: ${r.evidence}`);
1750
+ userInfo(`${ri} ${r.rule}: ${r.evidence}`);
1043
1751
  }
1044
1752
  }
1045
- console.log(allPass ? "\n所有场景通过" : "\n部分场景失败");
1753
+ userInfo(allPass ? "\n所有场景通过" : "\n部分场景失败");
1046
1754
  }
1047
1755
  process.exit(allPass ? 0 : 1);
1048
1756
  }
1757
+ /**
1758
+ * 新增问题/issue 演进门控 — problem-54 真实消费入口。
1759
+ * 用法: soloforge validate-new-issue --title="问题标题" --batch=2 [--json]
1760
+ */
1761
+ async function cmdValidateNewIssue() {
1762
+ debug("CLI", "执行 cmdValidateNewIssue");
1763
+ const title = getArgValue("--title") ?? "";
1764
+ const batchStr = getArgValue("--batch");
1765
+ const batch = batchStr ? parseInt(batchStr, 10) : 0;
1766
+ const isJson = args.includes("--json");
1767
+ if (!title) {
1768
+ userError("❌ 错误: --title 必须提供");
1769
+ process.exit(1);
1770
+ }
1771
+ const { performEvolutionGate, checkDuplicateIssue, createNewIssueRegressionGate, } = await import("../engine/evolution_regression_gate.js");
1772
+ // 从 implementation_roadmap_registry 加载真实已有问题
1773
+ const { listAllProblems } = await import("../engine/implementation_roadmap_registry.js");
1774
+ const allProblems = listAllProblems();
1775
+ // 精确重复检测: label 精确匹配(不子串),title 语义包含,id 精确匹配
1776
+ const lower = title.toLowerCase();
1777
+ const matchedProblemMap = new Map();
1778
+ for (const p of allProblems) {
1779
+ let matched = false;
1780
+ // id 精确匹配
1781
+ if (p.id.toLowerCase() === lower)
1782
+ matched = true;
1783
+ // label 精确匹配
1784
+ if (p.label.toLowerCase() === lower)
1785
+ matched = true;
1786
+ // label 前缀匹配: "问题四十一" 匹配 "问题四十一(Brainstorm)"
1787
+ if (p.label.toLowerCase().startsWith(lower + "("))
1788
+ matched = true;
1789
+ // 完整 title 的包含匹配(title 是长描述,子串匹配合理)
1790
+ if (lower.length >= 2 && p.title.toLowerCase().includes(lower))
1791
+ matched = true;
1792
+ // 输入包含完整 title(输入更长时)
1793
+ if (lower.length >= 4 && p.title.length >= 4 && lower.includes(p.title.toLowerCase()))
1794
+ matched = true;
1795
+ if (matched) {
1796
+ matchedProblemMap.set(p.id, { id: p.id, label: p.label, title: p.title });
1797
+ }
1798
+ }
1799
+ const deduplicatedIds = [...matchedProblemMap.keys()];
1800
+ const matchedDetails = [...matchedProblemMap.values()];
1801
+ // 稳定 slug: 基于标题哈希而非 Date.now
1802
+ const titleSlug = title
1803
+ .toLowerCase()
1804
+ .replace(/[^a-z0-9一-鿿]+/g, "-")
1805
+ .replace(/^-|-$/g, "")
1806
+ .slice(0, 40);
1807
+ const hashSuffix = crypto.createHash("sha256").update(title).digest("hex").slice(0, 8);
1808
+ const candidateId = `problem-new-${titleSlug}-${hashSuffix}`;
1809
+ const gate = createNewIssueRegressionGate({
1810
+ issue_candidate_id: candidateId,
1811
+ candidate_title: title,
1812
+ });
1813
+ // 重复检测 — 写入去重后的 ID 列表
1814
+ gate.duplicate_check.possible_duplicates = deduplicatedIds;
1815
+ // 演进门控
1816
+ const result = performEvolutionGate(gate);
1817
+ const output = {
1818
+ title,
1819
+ batch,
1820
+ candidate_id: candidateId,
1821
+ existing_issues_checked: allProblems.length,
1822
+ duplicate_detected: gate.duplicate_check.possible_duplicates.length > 0,
1823
+ duplicates: [...new Set(gate.duplicate_check.possible_duplicates)],
1824
+ matched_duplicate_details: matchedDetails,
1825
+ gate_status: result.gate_status,
1826
+ can_proceed: result.allowed,
1827
+ reasons: result.reasons,
1828
+ };
1829
+ if (isJson) {
1830
+ userInfo(JSON.stringify(output, null, 2));
1831
+ }
1832
+ else {
1833
+ userInfo(`问题演进门控: ${output.gate_status}`);
1834
+ userInfo(` 已检查 ${allProblems.length} 个既有问题`);
1835
+ if (output.duplicate_detected) {
1836
+ userInfo(` ⚠ 重复检测: 发现 ${output.duplicates.join(", ")}`);
1837
+ for (const d of matchedDetails) {
1838
+ userInfo(` - ${d.id}: ${d.label} — ${d.title}`);
1839
+ }
1840
+ }
1841
+ if (result.reasons.length > 0) {
1842
+ userInfo(` 原因:`);
1843
+ for (const r of result.reasons)
1844
+ userInfo(` - ${r}`);
1845
+ }
1846
+ if (output.can_proceed) {
1847
+ userInfo(` ✓ 可继续: 问题新增已通过演进门控 (候选ID: ${candidateId})`);
1848
+ }
1849
+ }
1850
+ if (!output.can_proceed) {
1851
+ process.exit(1);
1852
+ }
1853
+ }
1049
1854
  async function cmdStatus() {
1050
- console.error("[soloForge] CLI: 执行 cmdStatus");
1051
- const projectPath = process.cwd();
1052
- console.log(`SoloForge 状态: ${projectPath}`);
1855
+ debug("CLI", "执行 cmdStatus");
1856
+ const projectPath = resolveProjectPath();
1857
+ userInfo(`SoloForge 状态: ${projectPath}`);
1053
1858
  const { config, source } = await resolveProjectConfig(projectPath);
1054
- console.log(` 配置来源: ${source === "config_file" ? "config.yaml" : "自动推断"}`);
1055
- console.log(` 产品: ${config.product_profile}`);
1056
- console.log(` 后端: ${config.tech_stack.backend.framework || "未配置"}`);
1057
- console.log(` 前端: ${config.tech_stack.frontend.framework || "未配置"}`);
1859
+ userInfo(` 配置来源: ${source === "config_file" ? "config.yaml" : "自动推断"}`);
1860
+ userInfo(` 产品: ${config.product_profile}`);
1861
+ userInfo(` 后端: ${config.tech_stack.backend.framework || "未配置"}`);
1862
+ userInfo(` 前端: ${config.tech_stack.frontend.framework || "未配置"}`);
1058
1863
  // 逐字段配置优先级状态
1059
1864
  try {
1060
1865
  const { resolutions, entries } = await resolveCurrentProjectConfigReports(projectPath);
1061
1866
  if (resolutions.length > 0) {
1062
- console.log("");
1063
- console.log(" 字段解析状态:");
1867
+ userInfo("");
1868
+ userInfo(" 字段解析状态:");
1064
1869
  for (const r of resolutions) {
1065
1870
  const stale = r.stale_warning ? " ⚠️ stale" : "";
1066
1871
  const conflict = r.conflict_report ? " ⚠️ conflict" : "";
1067
- console.log(` ${r.field_path}: ${JSON.stringify(r.resolved_value)} (${r.source}${stale}${conflict})`);
1872
+ userInfo(` ${r.field_path}: ${JSON.stringify(r.resolved_value)} (${r.source}${stale}${conflict})`);
1068
1873
  }
1069
1874
  }
1070
1875
  const schemaPath = path.join(projectPath, ".soloforge", "config.evidence.json");
1071
1876
  if (fss.existsSync(schemaPath)) {
1072
1877
  try {
1073
1878
  const raw = JSON.parse(fss.readFileSync(schemaPath, "utf-8"));
1074
- console.log(` evidence: schema_version=${raw.schema_version ?? 1}, ${entries.length} 条`);
1879
+ userInfo(` evidence: schema_version=${raw.schema_version ?? 1}, ${entries.length} 条`);
1075
1880
  }
1076
1881
  catch {
1077
- console.log(" evidence: 无法解析");
1882
+ userInfo(" evidence: 无法解析");
1078
1883
  }
1079
1884
  }
1080
1885
  else if (source === "config_file") {
1081
- console.log(" evidence: ⚠️ config.evidence.json 缺失");
1886
+ userInfo(" evidence: ⚠️ config.evidence.json 缺失");
1082
1887
  }
1083
1888
  }
1084
1889
  catch { }
1085
1890
  // Evidence 警告
1086
1891
  const evidenceWarnings = await checkEvidenceWarnings(projectPath);
1087
1892
  for (const w of evidenceWarnings) {
1088
- console.log(` ⚠️ evidence: ${w}`);
1893
+ userInfo(` ⚠️ evidence: ${w}`);
1089
1894
  }
1090
1895
  const knowledgeDir = getProjectKnowledgeDir(config);
1091
1896
  if (fss.existsSync(knowledgeDir)) {
1092
1897
  const { KnowledgeIndexManager } = await import("../knowledge/index_manager.js");
1093
- const index = new KnowledgeIndexManager(config);
1094
- await index.build();
1095
- const entries = index.getAllEntries();
1096
- console.log(` 知识: ${entries.global.length} 全局 + ${entries.project.length} 项目`);
1898
+ const index = new KnowledgeIndexManager(config, { watch: false });
1899
+ try {
1900
+ await index.build();
1901
+ const entries = index.getAllEntries();
1902
+ userInfo(` 知识: ${entries.global.length} 全局 + ${entries.project.length} 项目`);
1903
+ }
1904
+ finally {
1905
+ await index.close();
1906
+ }
1097
1907
  }
1098
1908
  else {
1099
- console.log(" 知识: 未初始化");
1909
+ userInfo(" 知识: 未初始化");
1100
1910
  }
1101
1911
  }
1102
1912
  async function interactiveConfig(projectPath) {
1103
- console.error("[soloForge] CLI: 执行 interactiveConfig");
1913
+ debug("CLI", "执行 interactiveConfig");
1104
1914
  if (!process.stdin.isTTY)
1105
1915
  return undefined;
1106
1916
  const readline = await import("node:readline");
@@ -1146,22 +1956,165 @@ async function interactiveConfig(projectPath) {
1146
1956
  return { draft, evidence };
1147
1957
  }
1148
1958
  function cmdVersion() {
1149
- console.error("[soloForge] CLI: 执行 cmdVersion");
1959
+ debug("CLI", "执行 cmdVersion");
1150
1960
  // dist/bin/soloforge.js → dist/package.json (local) 或 package.json (global npm)
1151
1961
  const pkgPath = path.resolve(import.meta.dirname, "..", "package.json");
1152
1962
  try {
1153
1963
  const pkg = JSON.parse(fss.readFileSync(pkgPath, "utf-8"));
1154
- console.log("SoloForge v" + pkg.version);
1964
+ userInfo("SoloForge v" + pkg.version);
1155
1965
  }
1156
1966
  catch {
1157
1967
  // 回退: 从 dist 同级目录查找
1158
1968
  const altPath = path.resolve(import.meta.dirname, "..", "..", "package.json");
1159
1969
  const pkg = JSON.parse(fss.readFileSync(altPath, "utf-8"));
1160
- console.log("SoloForge v" + pkg.version);
1970
+ userInfo("SoloForge v" + pkg.version);
1971
+ }
1972
+ }
1973
+ async function cmdCleanup() {
1974
+ debug("CLI", "执行 cmdCleanup");
1975
+ const dryRun = !args.includes("--apply");
1976
+ const projectPath = process.cwd();
1977
+ const stateDir = path.join(projectPath, ".soloforge", "state");
1978
+ let hasError = false;
1979
+ userInfo(`SoloForge 清理: ${projectPath}`);
1980
+ userInfo(` 模式: ${dryRun ? "dry-run(仅评估)" : "⚠️ 实际清理"}`);
1981
+ // 收集所有 evidence 引用来源:task-*.json 中的 evidence 文件名 / evidence id
1982
+ const referencedEvidenceIds = new Set();
1983
+ // 扫描 task context 文件中的 evidence 引用
1984
+ if (fss.existsSync(stateDir)) {
1985
+ for (const f of fss.readdirSync(stateDir).filter((f) => f.startsWith("task-") && f.endsWith(".json"))) {
1986
+ try {
1987
+ const content = fss.readFileSync(path.join(stateDir, f), "utf-8");
1988
+ const ctx = JSON.parse(content);
1989
+ // 从 verification_evidence 收集引用
1990
+ if (ctx.verification_evidence && typeof ctx.verification_evidence === "object") {
1991
+ for (const [key, val] of Object.entries(ctx.verification_evidence)) {
1992
+ if (typeof val === "string")
1993
+ referencedEvidenceIds.add(val);
1994
+ referencedEvidenceIds.add(key);
1995
+ }
1996
+ }
1997
+ // 从 artifacts 的 evidence_refs 收集
1998
+ if (Array.isArray(ctx.output_artifacts)) {
1999
+ for (const art of ctx.output_artifacts) {
2000
+ if (art.evidence_refs && Array.isArray(art.evidence_refs)) {
2001
+ for (const ref of art.evidence_refs)
2002
+ referencedEvidenceIds.add(ref);
2003
+ }
2004
+ if (art.artifact_id)
2005
+ referencedEvidenceIds.add(art.artifact_id);
2006
+ }
2007
+ }
2008
+ // 从 delivery_report 收集
2009
+ if (ctx.delivery_report && typeof ctx.delivery_report === "object") {
2010
+ const dr = ctx.delivery_report;
2011
+ if (dr.evidence_refs && Array.isArray(dr.evidence_refs)) {
2012
+ for (const ref of dr.evidence_refs)
2013
+ referencedEvidenceIds.add(ref);
2014
+ }
2015
+ }
2016
+ // 从 governance_report 收集
2017
+ if (ctx.governance_report && typeof ctx.governance_report === "string") {
2018
+ referencedEvidenceIds.add(ctx.governance_report);
2019
+ }
2020
+ }
2021
+ catch {
2022
+ // 跳过不可解析文件
2023
+ }
2024
+ }
2025
+ }
2026
+ // 1. TaskContext 清理(使用 retention_policy)
2027
+ if (fss.existsSync(stateDir)) {
2028
+ try {
2029
+ const { TaskContextManager } = await import("../engine/task_context.js");
2030
+ const mgr = new TaskContextManager(stateDir);
2031
+ const result = await mgr.cleanup(dryRun);
2032
+ userInfo("");
2033
+ userInfo(" TaskContext 清理:");
2034
+ userInfo(` 已清理: ${result.removed} 条`);
2035
+ userInfo(` 受保护(被引用不可删除): ${result.protected} 条`);
2036
+ userInfo(` 禁止内容检出: ${result.forbidden_content_hits.length > 0 ? result.forbidden_content_hits.join("; ") : "无"}`);
2037
+ userInfo(` dry_run: ${result.dry_run}`);
2038
+ if (result.forbidden_content_hits.length > 0) {
2039
+ userError(` ❌ TaskContext 包含禁止内容,清理中止`);
2040
+ hasError = true;
2041
+ }
2042
+ }
2043
+ catch (e) {
2044
+ userError(` ❌ TaskContext 清理失败: ${e.message}`);
2045
+ process.exit(1);
2046
+ }
2047
+ }
2048
+ else {
2049
+ userInfo(" TaskContext: 状态目录不存在,跳过");
2050
+ }
2051
+ // 2. Evidence 文件清理(真实引用扫描)
2052
+ const evidenceDir = path.join(projectPath, ".soloforge");
2053
+ if (fss.existsSync(evidenceDir)) {
2054
+ try {
2055
+ const { evaluateCleanup, checkForbiddenContent } = await import("../engine/retention_policy.js");
2056
+ const evidenceFiles = fss.readdirSync(evidenceDir)
2057
+ .filter((f) => f.endsWith(".json") && !f.startsWith("config."))
2058
+ .map((f) => {
2059
+ const fp = path.join(evidenceDir, f);
2060
+ const stat = fss.statSync(fp);
2061
+ const ageDays = Math.max(0, (Date.now() - stat.mtimeMs) / (24 * 60 * 60 * 1000));
2062
+ const content = fss.readFileSync(fp, "utf-8");
2063
+ const forbiddenHits = checkForbiddenContent("evidence", content);
2064
+ // 真实引用检查: evidence 文件名或内容中的 id 出现在引用集合中
2065
+ const isReferenced = referencedEvidenceIds.has(f) || referencedEvidenceIds.has(f.replace(/\.json$/, ""));
2066
+ return { name: f, age_days: ageDays, is_referenced: isReferenced, forbidden: forbiddenHits };
2067
+ });
2068
+ const records = evidenceFiles.map(e => ({ id: e.name, age_days: e.age_days, is_referenced: e.is_referenced }));
2069
+ const result = evaluateCleanup("evidence", records, dryRun);
2070
+ userInfo("");
2071
+ userInfo(" Evidence 清理:");
2072
+ userInfo(` 总文件: ${result.total_records}`);
2073
+ userInfo(` 可清理: ${result.eligible_for_cleanup}`);
2074
+ userInfo(` 受保护: ${result.protected_records}`);
2075
+ userInfo(` dry_run: ${result.dry_run}`);
2076
+ if (result.cleanup_candidates.length > 0) {
2077
+ userInfo(` 清理候选: ${result.cleanup_candidates.join(", ")}`);
2078
+ }
2079
+ const forbiddenFiles = evidenceFiles.filter(e => e.forbidden.length > 0);
2080
+ if (forbiddenFiles.length > 0) {
2081
+ userInfo(" ❌ 禁止内容检出:");
2082
+ for (const f of forbiddenFiles) {
2083
+ userInfo(` ${f.name}: ${f.forbidden.join(", ")}`);
2084
+ }
2085
+ hasError = true;
2086
+ }
2087
+ }
2088
+ catch (e) {
2089
+ userError(` ❌ Evidence 清理失败: ${e.message}`);
2090
+ process.exit(1);
2091
+ }
2092
+ }
2093
+ // 3. 列出所有保留策略
2094
+ try {
2095
+ const { listRetentionPolicies } = await import("../engine/retention_policy.js");
2096
+ const policies = listRetentionPolicies();
2097
+ userInfo("");
2098
+ userInfo(" 保留策略:");
2099
+ for (const p of policies) {
2100
+ userInfo(` ${p.policy_id}: ${p.record_type}, 最大 ${p.max_age_days} 天 / ${p.max_count} 条, dry_run_default=${p.dry_run_default}`);
2101
+ }
1161
2102
  }
2103
+ catch (e) {
2104
+ userError(` ❌ 保留策略加载失败: ${e.message}`);
2105
+ process.exit(1);
2106
+ }
2107
+ if (hasError)
2108
+ process.exit(1);
1162
2109
  }
1163
- main().catch((e) => { console.error(e); process.exit(1); });
2110
+ main().catch((e) => { internalWarn("CLI", "启动失败:", e); process.exit(1); });
1164
2111
  function getArgValue(flag) {
2112
+ // 支持 --flag=value 格式
2113
+ const eqPrefix = flag + "=";
2114
+ const eqIdx = args.findIndex((a) => a.startsWith(eqPrefix));
2115
+ if (eqIdx !== -1) {
2116
+ return args[eqIdx].slice(eqPrefix.length) || undefined;
2117
+ }
1165
2118
  const idx = args.indexOf(flag);
1166
2119
  if (idx === -1 || idx + 1 >= args.length)
1167
2120
  return undefined;