ccjk 15.28.2 → 15.29.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 (436) hide show
  1. package/README.md +5 -4
  2. package/dist/chunks/agent-teams.mjs +145 -0
  3. package/dist/chunks/agent.mjs +1439 -0
  4. package/dist/chunks/agents.mjs +3783 -0
  5. package/dist/chunks/api-cli.mjs +135 -0
  6. package/dist/chunks/api-config-selector.mjs +159 -0
  7. package/dist/chunks/api-providers.mjs +144 -0
  8. package/dist/chunks/api.mjs +115 -0
  9. package/dist/chunks/auto-bootstrap.mjs +358 -0
  10. package/dist/chunks/auto-fixer.mjs +95 -0
  11. package/dist/chunks/auto-updater.mjs +507 -0
  12. package/dist/chunks/banner.mjs +173 -0
  13. package/dist/chunks/bash.mjs +187 -0
  14. package/dist/chunks/boost.mjs +474 -0
  15. package/dist/chunks/brain-config.mjs +75 -0
  16. package/dist/chunks/brain-status.mjs +89 -0
  17. package/dist/chunks/ccjk-agents.mjs +416 -0
  18. package/dist/chunks/ccjk-all.mjs +1046 -0
  19. package/dist/chunks/ccjk-config.mjs +445 -0
  20. package/dist/chunks/ccjk-hooks.mjs +1074 -0
  21. package/dist/chunks/ccjk-mcp.mjs +763 -0
  22. package/dist/chunks/ccjk-setup.mjs +765 -0
  23. package/dist/chunks/ccjk-skills.mjs +518 -0
  24. package/dist/chunks/ccr.mjs +109 -0
  25. package/dist/chunks/ccu.mjs +40 -0
  26. package/dist/chunks/check-updates.mjs +117 -0
  27. package/dist/chunks/claude-code-incremental-manager.mjs +761 -0
  28. package/dist/chunks/claude-config.mjs +606 -0
  29. package/dist/chunks/claude-config2.mjs +62 -0
  30. package/dist/chunks/claude-wrapper.mjs +85 -0
  31. package/dist/chunks/clavue-config.mjs +1454 -0
  32. package/dist/chunks/cleanup-migration.mjs +20 -0
  33. package/dist/chunks/cli-hook.mjs +4096 -0
  34. package/dist/chunks/cloud-sync.mjs +29 -0
  35. package/dist/chunks/code-type-resolver.mjs +880 -0
  36. package/dist/chunks/codex-config-switch.mjs +452 -0
  37. package/dist/chunks/codex-provider-manager.mjs +238 -0
  38. package/dist/chunks/codex-uninstaller.mjs +404 -0
  39. package/dist/chunks/codex.mjs +2141 -0
  40. package/dist/chunks/commands.mjs +108 -0
  41. package/dist/chunks/commands2.mjs +421 -0
  42. package/dist/chunks/commit.mjs +140 -0
  43. package/dist/chunks/completion.mjs +517 -0
  44. package/dist/chunks/config-consolidator.mjs +172 -0
  45. package/dist/chunks/config-switch.mjs +334 -0
  46. package/dist/chunks/config.mjs +558 -0
  47. package/dist/chunks/config2.mjs +484 -0
  48. package/dist/chunks/config3.mjs +486 -0
  49. package/dist/chunks/constants.mjs +323 -0
  50. package/dist/chunks/context-opt.mjs +444 -0
  51. package/dist/chunks/context.mjs +974 -0
  52. package/dist/chunks/dashboard.mjs +481 -0
  53. package/dist/chunks/doctor.mjs +1301 -0
  54. package/dist/chunks/eval.mjs +502 -0
  55. package/dist/chunks/evolution.mjs +322 -0
  56. package/dist/chunks/features.mjs +715 -0
  57. package/dist/chunks/fish.mjs +181 -0
  58. package/dist/chunks/fs-operations.mjs +180 -0
  59. package/dist/chunks/health-alerts.mjs +830 -0
  60. package/dist/chunks/help.mjs +341 -0
  61. package/dist/chunks/hook-installer.mjs +48 -0
  62. package/dist/chunks/impact.mjs +651 -0
  63. package/dist/chunks/index.mjs +23 -0
  64. package/dist/chunks/index10.mjs +19 -0
  65. package/dist/chunks/index11.mjs +1171 -0
  66. package/dist/chunks/index12.mjs +218 -0
  67. package/dist/chunks/index13.mjs +679 -0
  68. package/dist/chunks/index14.mjs +1009 -0
  69. package/dist/chunks/index15.mjs +194 -0
  70. package/dist/chunks/index2.mjs +7637 -0
  71. package/dist/chunks/index3.mjs +171 -0
  72. package/dist/chunks/index4.mjs +26 -0
  73. package/dist/chunks/index5.mjs +19 -0
  74. package/dist/chunks/index6.mjs +19092 -0
  75. package/dist/chunks/index7.mjs +616 -0
  76. package/dist/chunks/index8.mjs +1602 -0
  77. package/dist/chunks/index9.mjs +5384 -0
  78. package/dist/chunks/init.mjs +1911 -0
  79. package/dist/chunks/installer.mjs +757 -0
  80. package/dist/chunks/installer2.mjs +103 -0
  81. package/dist/chunks/interview.mjs +2927 -0
  82. package/dist/chunks/json-config.mjs +60 -0
  83. package/dist/chunks/linux.mjs +3863 -0
  84. package/dist/chunks/macos.mjs +69 -0
  85. package/dist/chunks/main.mjs +635 -0
  86. package/dist/chunks/manager.mjs +1048 -0
  87. package/dist/chunks/marketplace.mjs +265 -0
  88. package/dist/chunks/mcp-cli.mjs +205 -0
  89. package/dist/chunks/mcp-performance.mjs +187 -0
  90. package/dist/chunks/mcp.mjs +667 -0
  91. package/dist/chunks/memory-check.mjs +2973 -0
  92. package/dist/chunks/memory-paths.mjs +259 -0
  93. package/dist/chunks/memory-sync.mjs +209 -0
  94. package/dist/chunks/memory.mjs +354 -0
  95. package/dist/chunks/metrics-display.mjs +153 -0
  96. package/dist/chunks/monitor.mjs +1856 -0
  97. package/dist/chunks/notification.mjs +1864 -0
  98. package/dist/chunks/onboarding.mjs +386 -0
  99. package/dist/chunks/package.mjs +3 -0
  100. package/dist/chunks/paradigm.mjs +74 -0
  101. package/dist/chunks/permission-manager.mjs +250 -0
  102. package/dist/chunks/permissions.mjs +265 -0
  103. package/dist/chunks/persistence-manager.mjs +801 -0
  104. package/dist/chunks/persistence.mjs +707 -0
  105. package/dist/chunks/platform.mjs +395 -0
  106. package/dist/chunks/plugin.mjs +1936 -0
  107. package/dist/chunks/powershell.mjs +213 -0
  108. package/dist/chunks/prompts.mjs +244 -0
  109. package/dist/chunks/providers.mjs +263 -0
  110. package/dist/chunks/quick-actions.mjs +335 -0
  111. package/dist/chunks/quick-provider.mjs +755 -0
  112. package/dist/chunks/quick-setup.mjs +421 -0
  113. package/dist/chunks/remote.mjs +497 -0
  114. package/dist/chunks/research.mjs +1904 -0
  115. package/dist/chunks/rollback.mjs +38 -0
  116. package/dist/chunks/session-manager.mjs +1371 -0
  117. package/dist/chunks/session.mjs +878 -0
  118. package/dist/chunks/sessions.mjs +106 -0
  119. package/dist/chunks/silent-updater.mjs +396 -0
  120. package/dist/chunks/simple-config.mjs +122 -0
  121. package/dist/chunks/skill.mjs +117 -0
  122. package/dist/chunks/skill2.mjs +9052 -0
  123. package/dist/chunks/skills-sync.mjs +1343 -0
  124. package/dist/chunks/skills.mjs +577 -0
  125. package/dist/chunks/slash-commands.mjs +208 -0
  126. package/dist/chunks/smart-guide.mjs +247 -0
  127. package/dist/chunks/snapshot.mjs +58 -0
  128. package/dist/chunks/startup.mjs +487 -0
  129. package/dist/chunks/stats.mjs +191 -0
  130. package/dist/chunks/status.mjs +471 -0
  131. package/dist/chunks/team.mjs +63 -0
  132. package/dist/chunks/thinking.mjs +626 -0
  133. package/dist/chunks/trace.mjs +57 -0
  134. package/dist/chunks/uninstall.mjs +852 -0
  135. package/dist/chunks/update.mjs +174 -0
  136. package/dist/chunks/upgrade-manager.mjs +204 -0
  137. package/dist/chunks/upgrade.mjs +133 -0
  138. package/dist/chunks/version-checker.mjs +891 -0
  139. package/dist/chunks/vim.mjs +903 -0
  140. package/dist/chunks/windows.mjs +14 -0
  141. package/dist/chunks/workflows.mjs +633 -0
  142. package/dist/chunks/wsl.mjs +129 -0
  143. package/dist/chunks/zero-config.mjs +871 -0
  144. package/dist/chunks/zsh.mjs +182 -0
  145. package/dist/cli.d.mts +1 -0
  146. package/dist/cli.d.ts +1 -0
  147. package/dist/cli.js +11 -2
  148. package/dist/cli.js.map +1 -1
  149. package/dist/cli.mjs +2684 -0
  150. package/dist/commands/edit.js +1 -2
  151. package/dist/commands/edit.js.map +1 -1
  152. package/dist/commands/grok.js +35 -0
  153. package/dist/commands/grok.js.map +1 -0
  154. package/dist/commands/init.js +183 -110
  155. package/dist/commands/init.js.map +1 -1
  156. package/dist/commands/migrate.js +6 -8
  157. package/dist/commands/migrate.js.map +1 -1
  158. package/dist/commands/profile.js +10 -28
  159. package/dist/commands/profile.js.map +1 -1
  160. package/dist/commands/quick.js +28 -25
  161. package/dist/commands/quick.js.map +1 -1
  162. package/dist/core/codex-config.js +11 -29
  163. package/dist/core/codex-config.js.map +1 -1
  164. package/dist/core/grok-config.js +110 -0
  165. package/dist/core/grok-config.js.map +1 -0
  166. package/dist/core/perms.js +96 -86
  167. package/dist/core/perms.js.map +1 -1
  168. package/dist/core/profiles.js +13 -57
  169. package/dist/core/profiles.js.map +1 -1
  170. package/dist/core/providers.js +58 -49
  171. package/dist/core/providers.js.map +1 -1
  172. package/dist/core/quick-parse.js +1 -7
  173. package/dist/core/quick-parse.js.map +1 -1
  174. package/dist/core/tools.js +24 -0
  175. package/dist/core/tools.js.map +1 -1
  176. package/dist/i18n/locales/en/agent-teams.json +18 -0
  177. package/dist/i18n/locales/en/agentBrowser.json +80 -0
  178. package/dist/i18n/locales/en/agents.json +135 -0
  179. package/dist/i18n/locales/en/api.json +63 -0
  180. package/dist/i18n/locales/en/ccjk-agents.json +33 -0
  181. package/dist/i18n/locales/en/ccjk-all.json +23 -0
  182. package/dist/i18n/locales/en/ccjk-skills.json +22 -0
  183. package/dist/i18n/locales/en/ccjk.json +276 -0
  184. package/dist/i18n/locales/en/ccr.json +65 -0
  185. package/dist/i18n/locales/en/claude-md.json +73 -0
  186. package/dist/i18n/locales/en/cli.json +148 -0
  187. package/dist/i18n/locales/en/cloud-setup.json +31 -0
  188. package/dist/i18n/locales/en/cloud-sync.json +147 -0
  189. package/dist/i18n/locales/en/cloud.json +40 -0
  190. package/dist/i18n/locales/en/cloudPlugins.json +118 -0
  191. package/dist/i18n/locales/en/codex.json +184 -0
  192. package/dist/i18n/locales/en/cometix.json +29 -0
  193. package/dist/i18n/locales/en/common.json +68 -0
  194. package/dist/i18n/locales/en/config.json +108 -0
  195. package/dist/i18n/locales/en/configuration.json +236 -0
  196. package/dist/i18n/locales/en/context.json +85 -0
  197. package/dist/i18n/locales/en/dashboard.json +78 -0
  198. package/dist/i18n/locales/en/errors.json +26 -0
  199. package/dist/i18n/locales/en/evolution.json +54 -0
  200. package/dist/i18n/locales/en/hooks.json +74 -0
  201. package/dist/i18n/locales/en/hooksSync.json +133 -0
  202. package/dist/i18n/locales/en/installation.json +83 -0
  203. package/dist/i18n/locales/en/interview.json +104 -0
  204. package/dist/i18n/locales/en/language.json +19 -0
  205. package/dist/i18n/locales/en/lsp.json +78 -0
  206. package/dist/i18n/locales/en/marketplace.json +116 -0
  207. package/dist/i18n/locales/en/mcp.json +180 -0
  208. package/dist/i18n/locales/en/memory.json +23 -0
  209. package/dist/i18n/locales/en/menu.json +299 -0
  210. package/dist/i18n/locales/en/multi-config.json +79 -0
  211. package/dist/i18n/locales/en/notification.json +307 -0
  212. package/dist/i18n/locales/en/permissions.json +95 -0
  213. package/dist/i18n/locales/en/persistence.json +127 -0
  214. package/dist/i18n/locales/en/plugins.json +146 -0
  215. package/dist/i18n/locales/en/quick-actions.json +78 -0
  216. package/dist/i18n/locales/en/registry.json +54 -0
  217. package/dist/i18n/locales/en/remote.json +93 -0
  218. package/dist/i18n/locales/en/sandbox.json +44 -0
  219. package/dist/i18n/locales/en/setup.json +44 -0
  220. package/dist/i18n/locales/en/shencha.json +14 -0
  221. package/dist/i18n/locales/en/skills.json +100 -0
  222. package/dist/i18n/locales/en/skillsSync.json +74 -0
  223. package/dist/i18n/locales/en/smartGuide.json +49 -0
  224. package/dist/i18n/locales/en/stats.json +20 -0
  225. package/dist/i18n/locales/en/subagent.json +69 -0
  226. package/dist/i18n/locales/en/superpowers.json +117 -0
  227. package/dist/i18n/locales/en/team.json +7 -0
  228. package/dist/i18n/locales/en/thinking.json +65 -0
  229. package/dist/i18n/locales/en/tools.json +42 -0
  230. package/dist/i18n/locales/en/uninstall.json +56 -0
  231. package/dist/i18n/locales/en/updater.json +29 -0
  232. package/dist/i18n/locales/en/vim.json +169 -0
  233. package/dist/i18n/locales/en/workflow.json +55 -0
  234. package/dist/i18n/locales/en/workspace.json +108 -0
  235. package/dist/i18n/locales/zh-CN/agent-teams.json +18 -0
  236. package/dist/i18n/locales/zh-CN/agentBrowser.json +80 -0
  237. package/dist/i18n/locales/zh-CN/agents.json +135 -0
  238. package/dist/i18n/locales/zh-CN/api.json +63 -0
  239. package/dist/i18n/locales/zh-CN/ccjk-agents.json +33 -0
  240. package/dist/i18n/locales/zh-CN/ccjk-all.json +23 -0
  241. package/dist/i18n/locales/zh-CN/ccjk-skills.json +22 -0
  242. package/dist/i18n/locales/zh-CN/ccjk.json +276 -0
  243. package/dist/i18n/locales/zh-CN/ccr.json +65 -0
  244. package/dist/i18n/locales/zh-CN/claude-md.json +73 -0
  245. package/dist/i18n/locales/zh-CN/cli.json +148 -0
  246. package/dist/i18n/locales/zh-CN/cloud-setup.json +31 -0
  247. package/dist/i18n/locales/zh-CN/cloud-sync.json +147 -0
  248. package/dist/i18n/locales/zh-CN/cloud.json +40 -0
  249. package/dist/i18n/locales/zh-CN/cloudPlugins.json +118 -0
  250. package/dist/i18n/locales/zh-CN/codex.json +184 -0
  251. package/dist/i18n/locales/zh-CN/cometix.json +29 -0
  252. package/dist/i18n/locales/zh-CN/common.json +68 -0
  253. package/dist/i18n/locales/zh-CN/config.json +108 -0
  254. package/dist/i18n/locales/zh-CN/configuration.json +234 -0
  255. package/dist/i18n/locales/zh-CN/context.json +85 -0
  256. package/dist/i18n/locales/zh-CN/dashboard.json +78 -0
  257. package/dist/i18n/locales/zh-CN/errors.json +26 -0
  258. package/dist/i18n/locales/zh-CN/evolution.json +54 -0
  259. package/dist/i18n/locales/zh-CN/hooks.json +74 -0
  260. package/dist/i18n/locales/zh-CN/hooksSync.json +133 -0
  261. package/dist/i18n/locales/zh-CN/installation.json +83 -0
  262. package/dist/i18n/locales/zh-CN/interview.json +104 -0
  263. package/dist/i18n/locales/zh-CN/language.json +19 -0
  264. package/dist/i18n/locales/zh-CN/lsp.json +78 -0
  265. package/dist/i18n/locales/zh-CN/marketplace.json +116 -0
  266. package/dist/i18n/locales/zh-CN/mcp.json +180 -0
  267. package/dist/i18n/locales/zh-CN/memory.json +23 -0
  268. package/dist/i18n/locales/zh-CN/menu.json +299 -0
  269. package/dist/i18n/locales/zh-CN/multi-config.json +79 -0
  270. package/dist/i18n/locales/zh-CN/notification.json +307 -0
  271. package/dist/i18n/locales/zh-CN/permissions.json +95 -0
  272. package/dist/i18n/locales/zh-CN/persistence.json +127 -0
  273. package/dist/i18n/locales/zh-CN/plugins.json +146 -0
  274. package/dist/i18n/locales/zh-CN/quick-actions.json +78 -0
  275. package/dist/i18n/locales/zh-CN/registry.json +54 -0
  276. package/dist/i18n/locales/zh-CN/remote.json +93 -0
  277. package/dist/i18n/locales/zh-CN/sandbox.json +44 -0
  278. package/dist/i18n/locales/zh-CN/setup.json +44 -0
  279. package/dist/i18n/locales/zh-CN/shencha.json +14 -0
  280. package/dist/i18n/locales/zh-CN/skills.json +100 -0
  281. package/dist/i18n/locales/zh-CN/skillsSync.json +74 -0
  282. package/dist/i18n/locales/zh-CN/smartGuide.json +49 -0
  283. package/dist/i18n/locales/zh-CN/stats.json +20 -0
  284. package/dist/i18n/locales/zh-CN/subagent.json +69 -0
  285. package/dist/i18n/locales/zh-CN/superpowers.json +117 -0
  286. package/dist/i18n/locales/zh-CN/team.json +7 -0
  287. package/dist/i18n/locales/zh-CN/thinking.json +65 -0
  288. package/dist/i18n/locales/zh-CN/tools.json +42 -0
  289. package/dist/i18n/locales/zh-CN/uninstall.json +56 -0
  290. package/dist/i18n/locales/zh-CN/updater.json +29 -0
  291. package/dist/i18n/locales/zh-CN/vim.json +169 -0
  292. package/dist/i18n/locales/zh-CN/workflow.json +55 -0
  293. package/dist/i18n/locales/zh-CN/workspace.json +108 -0
  294. package/dist/index.d.mts +5658 -0
  295. package/dist/index.d.ts +5658 -0
  296. package/dist/index.mjs +3732 -0
  297. package/dist/shared/ccjk.5bEolFrk.mjs +254 -0
  298. package/dist/shared/ccjk.8oaxX4iR.mjs +90 -0
  299. package/dist/shared/ccjk.B2U7DsPy.mjs +31 -0
  300. package/dist/shared/ccjk.B2f-cwUP.mjs +468 -0
  301. package/dist/shared/ccjk.BAGoDD49.mjs +36 -0
  302. package/dist/shared/ccjk.BBtCGd_g.mjs +899 -0
  303. package/dist/shared/ccjk.BFQ7yr5S.mjs +16 -0
  304. package/dist/shared/ccjk.BLsIiTqO.mjs +449 -0
  305. package/dist/shared/ccjk.BXv8aYs1.mjs +170 -0
  306. package/dist/shared/ccjk.BnsY5WxD.mjs +171 -0
  307. package/dist/shared/ccjk.BoApaI4j.mjs +28 -0
  308. package/dist/shared/ccjk.Bq8TqZG_.mjs +189 -0
  309. package/dist/shared/ccjk.BtrioX1Z.mjs +25 -0
  310. package/dist/shared/ccjk.Bx_rmYfN.mjs +69 -0
  311. package/dist/shared/ccjk.BzPbSEP2.mjs +115 -0
  312. package/dist/shared/ccjk.C0WLUnFV.mjs +293 -0
  313. package/dist/shared/ccjk.C1hANZTu.mjs +19 -0
  314. package/dist/shared/ccjk.C2jHOZVP.mjs +52 -0
  315. package/dist/shared/ccjk.CNhnT6uQ.mjs +636 -0
  316. package/dist/shared/ccjk.COweQ1RR.mjs +5 -0
  317. package/dist/shared/ccjk.CfKKcvWy.mjs +126 -0
  318. package/dist/shared/ccjk.Cjgrln_h.mjs +297 -0
  319. package/dist/shared/ccjk.CoCHVXl3.mjs +3951 -0
  320. package/dist/shared/ccjk.CwGZSTAK.mjs +319 -0
  321. package/dist/shared/ccjk.CxpGa6MC.mjs +2724 -0
  322. package/dist/shared/ccjk.D-magaEx.mjs +763 -0
  323. package/dist/shared/ccjk.D0g2ABGg.mjs +171 -0
  324. package/dist/shared/ccjk.D6ycHbak.mjs +270 -0
  325. package/dist/shared/ccjk.D75wivnp.mjs +142 -0
  326. package/dist/shared/ccjk.DDL-4C-k.mjs +100 -0
  327. package/dist/shared/ccjk.DFRPtmK_.mjs +75 -0
  328. package/dist/shared/ccjk.DMV3x5Sd.mjs +299 -0
  329. package/dist/shared/ccjk.DZ2LLOa-.mjs +2195 -0
  330. package/dist/shared/ccjk.DbigonEQ.mjs +698 -0
  331. package/dist/shared/ccjk.DcMvE7lf.mjs +618 -0
  332. package/dist/shared/ccjk.DeWpAShp.mjs +1828 -0
  333. package/dist/shared/ccjk.DhJ1kyDR.mjs +30 -0
  334. package/dist/shared/ccjk.DlTXS9rP.mjs +224 -0
  335. package/dist/shared/ccjk.DopKzo3z.mjs +305 -0
  336. package/dist/shared/ccjk.DsZsc4LR.mjs +1280 -0
  337. package/dist/shared/ccjk.DuzJZlgj.mjs +418 -0
  338. package/dist/shared/ccjk.Dxgd2vjc.mjs +444 -0
  339. package/dist/shared/ccjk.J8YiPsOw.mjs +259 -0
  340. package/dist/shared/ccjk.KfSWcGlE.mjs +38 -0
  341. package/dist/shared/ccjk.L7yC58_i.mjs +225 -0
  342. package/dist/shared/ccjk.MwtjAULc.mjs +1447 -0
  343. package/dist/shared/ccjk.OJKHVSOb.mjs +2005 -0
  344. package/dist/shared/ccjk.OTnevPNE.mjs +225 -0
  345. package/dist/shared/ccjk.RyizuzOI.mjs +21 -0
  346. package/dist/shared/ccjk.T_cX87dY.mjs +15 -0
  347. package/dist/shared/ccjk.bQ7Dh1g4.mjs +249 -0
  348. package/dist/shared/ccjk.gDEDGD_t.mjs +38 -0
  349. package/dist/shared/ccjk.hoqrwWdN.mjs +333 -0
  350. package/dist/shared/ccjk.i_vn-9C3.mjs +317 -0
  351. package/dist/shared/ccjk.lG3ccFjm.mjs +885 -0
  352. package/dist/shared/ccjk.wLJHO0Af.mjs +244 -0
  353. package/dist/shared/ccjk.y-a_1vK4.mjs +5127 -0
  354. package/dist/templates/agents/README.md +78 -0
  355. package/dist/templates/agents/fullstack-developer.json +70 -0
  356. package/dist/templates/agents/go-expert.json +69 -0
  357. package/dist/templates/agents/index.json +64 -0
  358. package/dist/templates/agents/python-expert.json +69 -0
  359. package/dist/templates/agents/react-specialist.json +69 -0
  360. package/dist/templates/agents/testing-automation-expert.json +70 -0
  361. package/dist/templates/agents/typescript-architect.json +69 -0
  362. package/dist/templates/claude-code/common/settings.json +109 -0
  363. package/dist/templates/common/error-prevention.md +267 -0
  364. package/dist/templates/common/karpathy-baseline.md +83 -0
  365. package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +381 -0
  366. package/dist/templates/common/output-styles/zh-CN/codex-rigor-mode.md +114 -0
  367. package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +265 -0
  368. package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +539 -0
  369. package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +369 -0
  370. package/dist/templates/common/output-styles/zh-CN/linus-mode.md +135 -0
  371. package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +221 -0
  372. package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +628 -0
  373. package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +628 -0
  374. package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +187 -0
  375. package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +191 -0
  376. package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +249 -0
  377. package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +277 -0
  378. package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +29 -0
  379. package/dist/templates/common/workflow/essential/en/agents/init-architect.md +115 -0
  380. package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +91 -0
  381. package/dist/templates/common/workflow/essential/en/feat.md +92 -0
  382. package/dist/templates/common/workflow/essential/en/goal.md +147 -0
  383. package/dist/templates/common/workflow/essential/en/init-project.md +53 -0
  384. package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +29 -0
  385. package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +115 -0
  386. package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +91 -0
  387. package/dist/templates/common/workflow/essential/zh-CN/feat.md +315 -0
  388. package/dist/templates/common/workflow/essential/zh-CN/goal.md +146 -0
  389. package/dist/templates/common/workflow/essential/zh-CN/init-project.md +53 -0
  390. package/dist/templates/common/workflow/git/en/git-cleanBranches.md +102 -0
  391. package/dist/templates/common/workflow/git/en/git-commit.md +205 -0
  392. package/dist/templates/common/workflow/git/en/git-rollback.md +90 -0
  393. package/dist/templates/common/workflow/git/en/git-worktree.md +276 -0
  394. package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +102 -0
  395. package/dist/templates/common/workflow/git/zh-CN/git-commit.md +205 -0
  396. package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +90 -0
  397. package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +276 -0
  398. package/dist/templates/common/workflow/interview/en/interview.md +67 -0
  399. package/dist/templates/common/workflow/interview/zh-CN/interview.md +67 -0
  400. package/dist/templates/common/workflow/linearMethod/en/linear-method.md +651 -0
  401. package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +752 -0
  402. package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +516 -0
  403. package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +812 -0
  404. package/dist/templates/common/workflow/sixStep/en/workflow.md +83 -0
  405. package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +359 -0
  406. package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +364 -0
  407. package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +366 -0
  408. package/dist/templates/hooks/README.md +212 -0
  409. package/dist/templates/hooks/git-workflow-hooks.md +551 -0
  410. package/dist/templates/hooks/post-test/coverage.json +21 -0
  411. package/dist/templates/hooks/post-test/summary.json +21 -0
  412. package/dist/templates/hooks/post-test-coverage.md +434 -0
  413. package/dist/templates/hooks/pre-commit/eslint.json +22 -0
  414. package/dist/templates/hooks/pre-commit/prettier.json +22 -0
  415. package/dist/templates/hooks/pre-commit-black.md +274 -0
  416. package/dist/templates/hooks/pre-commit-eslint.md +153 -0
  417. package/dist/templates/hooks/pre-commit-gofmt.md +284 -0
  418. package/dist/templates/hooks/pre-commit-prettier.md +212 -0
  419. package/dist/templates/hooks/pre-commit-type-check.md +377 -0
  420. package/dist/templates/skills/ccjk-init.md +154 -0
  421. package/dist/templates/skills/ccjk-mcp-setup.md +205 -0
  422. package/dist/templates/skills/ccjk-troubleshoot.md +228 -0
  423. package/dist/templates/skills/django-patterns.md +1016 -0
  424. package/dist/templates/skills/git-workflow.md +748 -0
  425. package/dist/templates/skills/go-idioms.md +963 -0
  426. package/dist/templates/skills/index.json +132 -0
  427. package/dist/templates/skills/nextjs-optimization.md +694 -0
  428. package/dist/templates/skills/python-pep8.md +852 -0
  429. package/dist/templates/skills/react-patterns.md +686 -0
  430. package/dist/templates/skills/rust-patterns.md +1057 -0
  431. package/dist/templates/skills/security-best-practices.md +1413 -0
  432. package/dist/templates/skills/testing-best-practices.md +1315 -0
  433. package/dist/templates/skills/ts-best-practices.md +354 -0
  434. package/package.json +12 -13
  435. package/dist/core/codex-auth.js +0 -63
  436. package/dist/core/codex-auth.js.map +0 -1
@@ -0,0 +1,1171 @@
1
+ import { execSync } from 'node:child_process';
2
+ import * as path from 'node:path';
3
+ import * as process from 'node:process';
4
+ import * as fs from 'node:fs';
5
+
6
+ function getFixCommits(options) {
7
+ const { since, until, limit = 100, cwd = process.cwd() } = options;
8
+ let gitCmd = 'git log --pretty=format:"%H|%h|%s|%an|%ai" --name-only';
9
+ if (since) {
10
+ gitCmd += ` ${since}..${until || "HEAD"}`;
11
+ }
12
+ gitCmd += ` -n ${limit}`;
13
+ try {
14
+ const output = execSync(gitCmd, { cwd, encoding: "utf-8" });
15
+ return parseGitLog(output);
16
+ } catch {
17
+ return [];
18
+ }
19
+ }
20
+ function parseGitLog(output) {
21
+ const commits = [];
22
+ const entries = output.trim().split("\n\n");
23
+ for (const entry of entries) {
24
+ const lines = entry.split("\n");
25
+ if (lines.length === 0)
26
+ continue;
27
+ const [firstLine, ...fileLines] = lines;
28
+ const parts = firstLine.split("|");
29
+ if (parts.length < 5)
30
+ continue;
31
+ const [hash, shortHash, message, author, date] = parts;
32
+ const files = fileLines.filter((f) => f.trim());
33
+ if (isFixCommit(message)) {
34
+ commits.push({
35
+ hash,
36
+ shortHash,
37
+ message,
38
+ author,
39
+ date,
40
+ files
41
+ });
42
+ }
43
+ }
44
+ return commits;
45
+ }
46
+ function isFixCommit(message) {
47
+ const fixPatterns = [
48
+ /^fix[(:]/i,
49
+ /^bugfix[(:]/i,
50
+ /^hotfix[(:]/i,
51
+ /\bfix\b/i,
52
+ /\bbug\b/i,
53
+ /\brepair\b/i,
54
+ /\bresolve\b/i,
55
+ /\bcorrect\b/i,
56
+ /修复/,
57
+ /修正/,
58
+ /解决/,
59
+ /bug/i
60
+ ];
61
+ return fixPatterns.some((p) => p.test(message));
62
+ }
63
+ function analyzeFixCommit(commit, cwd = process.cwd()) {
64
+ const diff = getCommitDiff(commit.hash, cwd);
65
+ const bugType = detectBugType(commit.message, diff);
66
+ const severity = detectSeverity(commit.message, diff, commit.files);
67
+ const rootCause = extractRootCause(commit.message, diff);
68
+ const solution = extractSolution(diff);
69
+ const preventionSuggestions = generatePreventionSuggestions(bugType);
70
+ return {
71
+ commit,
72
+ bugType,
73
+ severity,
74
+ rootCause,
75
+ solution,
76
+ preventionSuggestions,
77
+ relatedPostmortems: []
78
+ };
79
+ }
80
+ function getCommitDiff(hash, cwd) {
81
+ try {
82
+ return execSync(`git show ${hash} --pretty="" --patch`, {
83
+ cwd,
84
+ encoding: "utf-8",
85
+ maxBuffer: 1024 * 1024 * 10
86
+ // 10MB
87
+ });
88
+ } catch {
89
+ return "";
90
+ }
91
+ }
92
+ function detectBugType(message, diff) {
93
+ const content = `${message}
94
+ ${diff}`.toLowerCase();
95
+ const patterns = [
96
+ {
97
+ category: "type-safety",
98
+ patterns: [
99
+ /null|undefined|cannot read|typeerror/,
100
+ /类型|空值|未定义/,
101
+ /optional chaining|\?\./,
102
+ /strict.*null|null.*check/
103
+ ]
104
+ },
105
+ {
106
+ category: "error-handling",
107
+ patterns: [
108
+ /try.*catch|exception|throw|error.*handling/,
109
+ /unhandled.*rejection|promise.*reject/,
110
+ /异常|错误处理|捕获/
111
+ ]
112
+ },
113
+ {
114
+ category: "performance",
115
+ patterns: [
116
+ /performance|slow|timeout|memory|leak/,
117
+ /optimize|optimization|cache/,
118
+ /性能|优化|缓存|内存/
119
+ ]
120
+ },
121
+ {
122
+ category: "security",
123
+ patterns: [
124
+ /security|xss|csrf|injection|auth/,
125
+ /vulnerability|exploit|sanitize/,
126
+ /安全|漏洞|注入|认证/
127
+ ]
128
+ },
129
+ {
130
+ category: "race-condition",
131
+ patterns: [
132
+ /race.*condition|concurrent|async.*await/,
133
+ /deadlock|mutex|lock/,
134
+ /竞态|并发|死锁/
135
+ ]
136
+ },
137
+ {
138
+ category: "logic-error",
139
+ patterns: [
140
+ /logic|incorrect|wrong.*result/,
141
+ /逻辑|错误结果|计算错误/
142
+ ]
143
+ },
144
+ {
145
+ category: "api-misuse",
146
+ patterns: [
147
+ /api.*usage|incorrect.*call|wrong.*parameter/,
148
+ /接口|调用错误|参数错误/
149
+ ]
150
+ },
151
+ {
152
+ category: "configuration",
153
+ patterns: [
154
+ /config|setting|environment|env/,
155
+ /配置|环境|设置/
156
+ ]
157
+ },
158
+ {
159
+ category: "dependency",
160
+ patterns: [
161
+ /dependency|package|version|upgrade/,
162
+ /依赖|版本|升级/
163
+ ]
164
+ }
165
+ ];
166
+ for (const { category, patterns: categoryPatterns } of patterns) {
167
+ if (categoryPatterns.some((p) => p.test(content))) {
168
+ return category;
169
+ }
170
+ }
171
+ return "other";
172
+ }
173
+ function detectSeverity(message, diff, files) {
174
+ const content = `${message}
175
+ ${diff}`.toLowerCase();
176
+ if (/critical|crash|data.*loss|security.*vuln/i.test(content) || files.some((f) => /auth|security|payment/i.test(f))) {
177
+ return "critical";
178
+ }
179
+ if (/breaking|major|important|urgent/i.test(content) || files.length > 10) {
180
+ return "high";
181
+ }
182
+ if (/moderate|minor.*issue/i.test(content) || files.length > 3) {
183
+ return "medium";
184
+ }
185
+ return "low";
186
+ }
187
+ function extractRootCause(message, diff) {
188
+ const causePatterns = [
189
+ /caused by[:\s]+(.+)/i,
190
+ /root cause[:\s]+(.+)/i,
191
+ /because[:\s]+(.+)/i,
192
+ /due to[:\s]+(.+)/i,
193
+ /原因[::]\s*(.+)/,
194
+ /由于\s*(.+)/
195
+ ];
196
+ for (const pattern of causePatterns) {
197
+ const match = message.match(pattern);
198
+ if (match) {
199
+ return match[1].trim();
200
+ }
201
+ }
202
+ const removedLines = diff.match(/^-[^-].*/gm) || [];
203
+ const addedLines = diff.match(/^\+[^+].*/gm) || [];
204
+ if (removedLines.length > 0 && addedLines.length > 0) {
205
+ return `\u4EE3\u7801\u53D8\u66F4: \u79FB\u9664 ${removedLines.length} \u884C, \u65B0\u589E ${addedLines.length} \u884C`;
206
+ }
207
+ return "\u9700\u8981\u8FDB\u4E00\u6B65\u5206\u6790";
208
+ }
209
+ function extractSolution(diff) {
210
+ const addedLines = diff.match(/^\+[^+].*/gm) || [];
211
+ if (addedLines.length === 0) {
212
+ return "\u5220\u9664\u4E86\u95EE\u9898\u4EE3\u7801";
213
+ }
214
+ if (addedLines.length <= 5) {
215
+ return addedLines.map((l) => l.substring(1)).join("\n");
216
+ }
217
+ return `\u65B0\u589E ${addedLines.length} \u884C\u4EE3\u7801\u4FEE\u590D\u95EE\u9898`;
218
+ }
219
+ function generatePreventionSuggestions(bugType, _diff) {
220
+ const suggestions = {
221
+ "type-safety": [
222
+ "\u542F\u7528 TypeScript strict \u6A21\u5F0F",
223
+ "\u4F7F\u7528\u53EF\u9009\u94FE\u64CD\u4F5C\u7B26 (?.) \u8FDB\u884C\u7A7A\u503C\u68C0\u67E5",
224
+ "\u4E3A\u6240\u6709\u5916\u90E8\u6570\u636E\u6DFB\u52A0\u8FD0\u884C\u65F6\u9A8C\u8BC1",
225
+ "\u4F7F\u7528 zod \u6216 io-ts \u8FDB\u884C\u7C7B\u578B\u9A8C\u8BC1"
226
+ ],
227
+ "error-handling": [
228
+ "\u4E3A\u6240\u6709\u5F02\u6B65\u64CD\u4F5C\u6DFB\u52A0 try-catch",
229
+ "\u5B9E\u73B0\u5168\u5C40\u9519\u8BEF\u5904\u7406\u4E2D\u95F4\u4EF6",
230
+ "\u6DFB\u52A0\u9519\u8BEF\u8FB9\u754C\u7EC4\u4EF6 (React)",
231
+ "\u4F7F\u7528 Result \u7C7B\u578B\u66FF\u4EE3\u5F02\u5E38"
232
+ ],
233
+ "performance": [
234
+ "\u6DFB\u52A0\u6027\u80FD\u76D1\u63A7\u548C\u544A\u8B66",
235
+ "\u5B9E\u73B0\u7F13\u5B58\u7B56\u7565",
236
+ "\u4F7F\u7528\u61D2\u52A0\u8F7D\u548C\u4EE3\u7801\u5206\u5272",
237
+ "\u5B9A\u671F\u8FDB\u884C\u6027\u80FD\u6D4B\u8BD5"
238
+ ],
239
+ "security": [
240
+ "\u5B9E\u65BD\u5B89\u5168\u4EE3\u7801\u5BA1\u67E5",
241
+ "\u4F7F\u7528\u5B89\u5168\u626B\u63CF\u5DE5\u5177",
242
+ "\u9075\u5FAA OWASP \u5B89\u5168\u6307\u5357",
243
+ "\u5B9A\u671F\u66F4\u65B0\u4F9D\u8D56"
244
+ ],
245
+ "race-condition": [
246
+ "\u4F7F\u7528\u9002\u5F53\u7684\u9501\u673A\u5236",
247
+ "\u907F\u514D\u5171\u4EAB\u53EF\u53D8\u72B6\u6001",
248
+ "\u4F7F\u7528\u539F\u5B50\u64CD\u4F5C",
249
+ "\u6DFB\u52A0\u5E76\u53D1\u6D4B\u8BD5"
250
+ ],
251
+ "logic-error": [
252
+ "\u589E\u52A0\u5355\u5143\u6D4B\u8BD5\u8986\u76D6",
253
+ "\u5B9E\u65BD\u4EE3\u7801\u5BA1\u67E5",
254
+ "\u6DFB\u52A0\u65AD\u8A00\u548C\u4E0D\u53D8\u91CF\u68C0\u67E5",
255
+ "\u4F7F\u7528\u5F62\u5F0F\u5316\u9A8C\u8BC1\u5DE5\u5177"
256
+ ],
257
+ "api-misuse": [
258
+ "\u5B8C\u5584 API \u6587\u6863",
259
+ "\u6DFB\u52A0\u53C2\u6570\u9A8C\u8BC1",
260
+ "\u63D0\u4F9B\u4F7F\u7528\u793A\u4F8B",
261
+ "\u5B9E\u73B0 API \u7248\u672C\u63A7\u5236"
262
+ ],
263
+ "configuration": [
264
+ "\u4F7F\u7528\u914D\u7F6E\u9A8C\u8BC1",
265
+ "\u63D0\u4F9B\u9ED8\u8BA4\u914D\u7F6E",
266
+ "\u6587\u6863\u5316\u6240\u6709\u914D\u7F6E\u9879",
267
+ "\u5B9E\u73B0\u914D\u7F6E\u70ED\u91CD\u8F7D"
268
+ ],
269
+ "dependency": [
270
+ "\u9501\u5B9A\u4F9D\u8D56\u7248\u672C",
271
+ "\u5B9A\u671F\u66F4\u65B0\u4F9D\u8D56",
272
+ "\u4F7F\u7528\u4F9D\u8D56\u626B\u63CF\u5DE5\u5177",
273
+ "\u6D4B\u8BD5\u4F9D\u8D56\u5347\u7EA7"
274
+ ],
275
+ "memory-leak": [
276
+ "\u5B9E\u73B0\u8D44\u6E90\u6E05\u7406",
277
+ "\u4F7F\u7528\u5185\u5B58\u5206\u6790\u5DE5\u5177",
278
+ "\u907F\u514D\u5FAA\u73AF\u5F15\u7528",
279
+ "\u5B9A\u671F\u8FDB\u884C\u5185\u5B58\u6D4B\u8BD5"
280
+ ],
281
+ "other": [
282
+ "\u589E\u52A0\u6D4B\u8BD5\u8986\u76D6",
283
+ "\u5B9E\u65BD\u4EE3\u7801\u5BA1\u67E5",
284
+ "\u5B8C\u5584\u6587\u6863"
285
+ ]
286
+ };
287
+ return suggestions[bugType] || suggestions.other;
288
+ }
289
+ function generatePostmortem(analyses, existingIds) {
290
+ const grouped = groupByCategory(analyses);
291
+ const reports = [];
292
+ let nextId = getNextId(existingIds);
293
+ for (const [category, categoryAnalyses] of Object.entries(grouped)) {
294
+ const merged = mergeAnalyses(categoryAnalyses);
295
+ for (const analysis of merged) {
296
+ const id = `PM-${String(nextId++).padStart(3, "0")}`;
297
+ const report = {
298
+ id,
299
+ title: generateTitle(analysis),
300
+ severity: analysis.severity,
301
+ category: analysis.bugType,
302
+ status: "active",
303
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
304
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
305
+ relatedCommits: [analysis.commit],
306
+ affectedVersions: {
307
+ from: "unknown",
308
+ to: "unknown"
309
+ },
310
+ description: generateDescription(analysis),
311
+ rootCause: [analysis.rootCause],
312
+ solution: {
313
+ description: analysis.solution
314
+ },
315
+ preventionMeasures: analysis.preventionSuggestions,
316
+ aiDirectives: generateAiDirectives(analysis),
317
+ detectionPatterns: generateDetectionPatterns(analysis),
318
+ relatedFiles: analysis.commit.files,
319
+ tags: [category, analysis.severity],
320
+ metadata: {
321
+ generatedBy: "ccjk-postmortem",
322
+ version: "1.0.0"
323
+ }
324
+ };
325
+ reports.push(report);
326
+ }
327
+ }
328
+ return reports;
329
+ }
330
+ function groupByCategory(analyses) {
331
+ const grouped = {};
332
+ for (const analysis of analyses) {
333
+ const category = analysis.bugType;
334
+ if (!grouped[category]) {
335
+ grouped[category] = [];
336
+ }
337
+ grouped[category].push(analysis);
338
+ }
339
+ return grouped;
340
+ }
341
+ function mergeAnalyses(analyses) {
342
+ const merged = [];
343
+ for (const analysis of analyses) {
344
+ const similar = merged.find(
345
+ (m) => calculateFileOverlap(m.commit.files, analysis.commit.files) > 0.5
346
+ );
347
+ if (similar) {
348
+ similar.commit.files = Array.from(/* @__PURE__ */ new Set([...similar.commit.files, ...analysis.commit.files]));
349
+ similar.preventionSuggestions = Array.from(/* @__PURE__ */ new Set([...similar.preventionSuggestions, ...analysis.preventionSuggestions]));
350
+ } else {
351
+ merged.push({ ...analysis });
352
+ }
353
+ }
354
+ return merged;
355
+ }
356
+ function calculateFileOverlap(files1, files2) {
357
+ const set1 = new Set(files1);
358
+ const set2 = new Set(files2);
359
+ const intersection = Array.from(set1).filter((f) => set2.has(f));
360
+ const union = /* @__PURE__ */ new Set([...files1, ...files2]);
361
+ return intersection.length / union.size;
362
+ }
363
+ function getNextId(existingIds) {
364
+ const numbers = existingIds.map((id) => Number.parseInt(id.replace("PM-", ""), 10)).filter((n) => !Number.isNaN(n));
365
+ return numbers.length > 0 ? Math.max(...numbers) + 1 : 1;
366
+ }
367
+ function generateTitle(analysis) {
368
+ const categoryTitles = {
369
+ "type-safety": "\u7C7B\u578B\u5B89\u5168\u95EE\u9898",
370
+ "error-handling": "\u9519\u8BEF\u5904\u7406\u7F3A\u5931",
371
+ "performance": "\u6027\u80FD\u95EE\u9898",
372
+ "security": "\u5B89\u5168\u6F0F\u6D1E",
373
+ "race-condition": "\u7ADE\u6001\u6761\u4EF6",
374
+ "logic-error": "\u903B\u8F91\u9519\u8BEF",
375
+ "api-misuse": "API \u4F7F\u7528\u4E0D\u5F53",
376
+ "configuration": "\u914D\u7F6E\u95EE\u9898",
377
+ "dependency": "\u4F9D\u8D56\u95EE\u9898",
378
+ "memory-leak": "\u5185\u5B58\u6CC4\u6F0F",
379
+ "other": "\u5176\u4ED6\u95EE\u9898"
380
+ };
381
+ const baseTitle = categoryTitles[analysis.bugType] || "\u672A\u5206\u7C7B\u95EE\u9898";
382
+ const message = analysis.commit.message;
383
+ const specificPart = message.replace(/^(fix|bugfix|hotfix)[(:]\s*/i, "").split("\n")[0];
384
+ if (specificPart && specificPart.length < 50) {
385
+ return `${baseTitle}: ${specificPart}`;
386
+ }
387
+ return baseTitle;
388
+ }
389
+ function generateDescription(analysis) {
390
+ return `
391
+ \u5728 ${analysis.commit.date} \u53D1\u73B0\u5E76\u4FEE\u590D\u4E86\u4E00\u4E2A ${analysis.bugType} \u7C7B\u578B\u7684\u95EE\u9898\u3002
392
+
393
+ **\u63D0\u4EA4\u4FE1\u606F**: ${analysis.commit.message}
394
+
395
+ **\u5F71\u54CD\u6587\u4EF6**:
396
+ ${analysis.commit.files.map((f) => `- ${f}`).join("\n")}
397
+
398
+ **\u6839\u672C\u539F\u56E0**: ${analysis.rootCause}
399
+ `.trim();
400
+ }
401
+ function generateAiDirectives(analysis) {
402
+ const directives = [];
403
+ const categoryDirectives = {
404
+ "type-safety": [
405
+ "\u5904\u7406\u5916\u90E8\u6570\u636E\u65F6\u5FC5\u987B\u8FDB\u884C\u7A7A\u503C\u68C0\u67E5",
406
+ "\u4F7F\u7528 TypeScript \u4E25\u683C\u6A21\u5F0F",
407
+ "\u907F\u514D\u4F7F\u7528 any \u7C7B\u578B"
408
+ ],
409
+ "error-handling": [
410
+ "\u6240\u6709\u5F02\u6B65\u64CD\u4F5C\u5FC5\u987B\u6709\u9519\u8BEF\u5904\u7406",
411
+ "\u63D0\u4F9B\u6709\u610F\u4E49\u7684\u9519\u8BEF\u6D88\u606F",
412
+ "\u5B9E\u73B0\u4F18\u96C5\u964D\u7EA7"
413
+ ],
414
+ "performance": [
415
+ "\u907F\u514D\u5728\u5FAA\u73AF\u4E2D\u8FDB\u884C I/O \u64CD\u4F5C",
416
+ "\u4F7F\u7528\u9002\u5F53\u7684\u7F13\u5B58\u7B56\u7565",
417
+ "\u6CE8\u610F\u5927\u6570\u636E\u96C6\u7684\u5904\u7406"
418
+ ],
419
+ "security": [
420
+ "\u9A8C\u8BC1\u6240\u6709\u7528\u6237\u8F93\u5165",
421
+ "\u4F7F\u7528\u53C2\u6570\u5316\u67E5\u8BE2",
422
+ "\u4E0D\u8981\u5728\u65E5\u5FD7\u4E2D\u8BB0\u5F55\u654F\u611F\u4FE1\u606F"
423
+ ],
424
+ "race-condition": [
425
+ "\u6CE8\u610F\u5F02\u6B65\u64CD\u4F5C\u7684\u6267\u884C\u987A\u5E8F",
426
+ "\u4F7F\u7528\u9002\u5F53\u7684\u540C\u6B65\u673A\u5236",
427
+ "\u907F\u514D\u5171\u4EAB\u53EF\u53D8\u72B6\u6001"
428
+ ],
429
+ "logic-error": [
430
+ "\u6DFB\u52A0\u8FB9\u754C\u6761\u4EF6\u68C0\u67E5",
431
+ "\u4F7F\u7528\u65AD\u8A00\u9A8C\u8BC1\u5047\u8BBE",
432
+ "\u7F16\u5199\u5355\u5143\u6D4B\u8BD5\u8986\u76D6\u8FB9\u754C\u60C5\u51B5"
433
+ ],
434
+ "api-misuse": [
435
+ "\u67E5\u9605 API \u6587\u6863\u786E\u8BA4\u6B63\u786E\u7528\u6CD5",
436
+ "\u68C0\u67E5\u53C2\u6570\u7C7B\u578B\u548C\u8303\u56F4",
437
+ "\u5904\u7406\u6240\u6709\u53EF\u80FD\u7684\u8FD4\u56DE\u503C"
438
+ ],
439
+ "configuration": [
440
+ "\u63D0\u4F9B\u5408\u7406\u7684\u9ED8\u8BA4\u503C",
441
+ "\u9A8C\u8BC1\u914D\u7F6E\u503C\u7684\u6709\u6548\u6027",
442
+ "\u6587\u6863\u5316\u914D\u7F6E\u9009\u9879"
443
+ ],
444
+ "dependency": [
445
+ "\u68C0\u67E5\u4F9D\u8D56\u7684\u517C\u5BB9\u6027",
446
+ "\u9605\u8BFB\u66F4\u65B0\u65E5\u5FD7",
447
+ "\u5728\u5347\u7EA7\u524D\u8FDB\u884C\u6D4B\u8BD5"
448
+ ],
449
+ "memory-leak": [
450
+ "\u53CA\u65F6\u6E05\u7406\u4E0D\u518D\u4F7F\u7528\u7684\u8D44\u6E90",
451
+ "\u907F\u514D\u5FAA\u73AF\u5F15\u7528",
452
+ "\u4F7F\u7528 WeakMap/WeakSet"
453
+ ],
454
+ "other": [
455
+ "\u4ED4\u7EC6\u5BA1\u67E5\u4EE3\u7801\u53D8\u66F4",
456
+ "\u6DFB\u52A0\u9002\u5F53\u7684\u6D4B\u8BD5"
457
+ ]
458
+ };
459
+ directives.push(...categoryDirectives[analysis.bugType] || categoryDirectives.other);
460
+ for (const file of analysis.commit.files) {
461
+ if (file.includes("api") || file.includes("service")) {
462
+ directives.push(`\u4FEE\u6539 ${path.basename(file)} \u65F6\u6CE8\u610F API \u517C\u5BB9\u6027`);
463
+ }
464
+ if (file.includes("config")) {
465
+ directives.push(`\u4FEE\u6539\u914D\u7F6E\u6587\u4EF6\u65F6\u786E\u4FDD\u5411\u540E\u517C\u5BB9`);
466
+ }
467
+ }
468
+ return Array.from(new Set(directives));
469
+ }
470
+ function generateDetectionPatterns(analysis) {
471
+ const patterns = [];
472
+ const categoryPatterns = {
473
+ "type-safety": [
474
+ {
475
+ type: "regex",
476
+ pattern: "\\.\\w+\\.\\w+\\.\\w+(?!\\?)",
477
+ description: "\u8FDE\u7EED\u5C5E\u6027\u8BBF\u95EE\u672A\u4F7F\u7528\u53EF\u9009\u94FE",
478
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
479
+ severity: "medium"
480
+ },
481
+ {
482
+ type: "regex",
483
+ pattern: "as any",
484
+ description: "\u4F7F\u7528 any \u7C7B\u578B\u65AD\u8A00",
485
+ fileTypes: [".ts", ".tsx"],
486
+ severity: "low"
487
+ }
488
+ ],
489
+ "error-handling": [
490
+ {
491
+ type: "regex",
492
+ pattern: "catch\\s*\\(\\s*\\w*\\s*\\)\\s*\\{\\s*\\}",
493
+ description: "\u7A7A\u7684 catch \u5757",
494
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
495
+ severity: "high"
496
+ },
497
+ {
498
+ type: "regex",
499
+ pattern: "\\.then\\([^)]+\\)(?!\\.catch)",
500
+ description: "Promise \u672A\u5904\u7406 rejection",
501
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
502
+ severity: "medium"
503
+ }
504
+ ],
505
+ "performance": [
506
+ {
507
+ type: "regex",
508
+ pattern: "for\\s*\\([^)]+\\)\\s*\\{[^}]*await",
509
+ description: "\u5FAA\u73AF\u4E2D\u4F7F\u7528 await",
510
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
511
+ severity: "medium"
512
+ }
513
+ ],
514
+ "security": [
515
+ {
516
+ type: "regex",
517
+ pattern: "innerHTML\\s*=",
518
+ description: "\u76F4\u63A5\u8BBE\u7F6E innerHTML \u53EF\u80FD\u5BFC\u81F4 XSS",
519
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
520
+ severity: "high"
521
+ },
522
+ {
523
+ type: "regex",
524
+ pattern: "eval\\s*\\(",
525
+ description: "\u4F7F\u7528 eval \u5B58\u5728\u5B89\u5168\u98CE\u9669",
526
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
527
+ severity: "critical"
528
+ }
529
+ ],
530
+ "race-condition": [],
531
+ "logic-error": [],
532
+ "api-misuse": [],
533
+ "configuration": [],
534
+ "dependency": [],
535
+ "memory-leak": [
536
+ {
537
+ type: "regex",
538
+ pattern: "addEventListener\\([^)]+\\)(?![\\s\\S]*removeEventListener)",
539
+ description: "\u6DFB\u52A0\u4E8B\u4EF6\u76D1\u542C\u5668\u4F46\u672A\u79FB\u9664",
540
+ fileTypes: [".ts", ".tsx", ".js", ".jsx"],
541
+ severity: "medium"
542
+ }
543
+ ],
544
+ "other": []
545
+ };
546
+ patterns.push(...categoryPatterns[analysis.bugType] || []);
547
+ return patterns;
548
+ }
549
+ const PostmortemAnalyzer = {
550
+ getFixCommits,
551
+ analyzeFixCommit,
552
+ generatePostmortem
553
+ };
554
+
555
+ const DEFAULT_CONFIG = {
556
+ enabled: true,
557
+ directory: "./postmortem",
558
+ autoSyncToClaudeMd: true,
559
+ maxSyncItems: 10,
560
+ minSyncSeverity: "medium",
561
+ detection: {
562
+ enabled: true,
563
+ excludePatterns: ["node_modules/**", "dist/**", "*.test.*", "*.spec.*"],
564
+ includePatterns: ["src/**/*.ts", "src/**/*.tsx"]
565
+ },
566
+ aiAnalysis: {
567
+ provider: "claude"
568
+ }
569
+ };
570
+ const INDEX_FILE = "index.json";
571
+ const CLAUDE_MD_SECTION_START = "<!-- POSTMORTEM_START -->";
572
+ const CLAUDE_MD_SECTION_END = "<!-- POSTMORTEM_END -->";
573
+ class PostmortemManager {
574
+ config;
575
+ projectRoot;
576
+ postmortemDir;
577
+ constructor(projectRoot = process.cwd(), config = {}) {
578
+ this.projectRoot = projectRoot;
579
+ this.config = { ...DEFAULT_CONFIG, ...config };
580
+ this.postmortemDir = path.join(projectRoot, this.config.directory);
581
+ }
582
+ // ==========================================================================
583
+ // Initialization
584
+ // ==========================================================================
585
+ /**
586
+ * 初始化 Postmortem 系统
587
+ */
588
+ async init() {
589
+ this.ensureDirectories();
590
+ const commits = PostmortemAnalyzer.getFixCommits({
591
+ limit: 200,
592
+ cwd: this.projectRoot
593
+ });
594
+ if (commits.length === 0) {
595
+ this.saveIndex(this.createEmptyIndex());
596
+ return { created: 0, directory: this.postmortemDir };
597
+ }
598
+ const analyses = commits.map(
599
+ (commit) => PostmortemAnalyzer.analyzeFixCommit(commit, this.projectRoot)
600
+ );
601
+ const reports = PostmortemAnalyzer.generatePostmortem(analyses, []);
602
+ for (const report of reports) {
603
+ this.saveReport(report);
604
+ }
605
+ this.updateIndex();
606
+ if (this.config.autoSyncToClaudeMd) {
607
+ await this.syncToClaudeMd();
608
+ }
609
+ return { created: reports.length, directory: this.postmortemDir };
610
+ }
611
+ /**
612
+ * 确保目录存在
613
+ */
614
+ ensureDirectories() {
615
+ const dirs = [
616
+ this.postmortemDir,
617
+ path.join(this.postmortemDir, "categories"),
618
+ path.join(this.postmortemDir, "summaries")
619
+ ];
620
+ for (const dir of dirs) {
621
+ if (!fs.existsSync(dir)) {
622
+ fs.mkdirSync(dir, { recursive: true });
623
+ }
624
+ }
625
+ }
626
+ // ==========================================================================
627
+ // Report Management
628
+ // ==========================================================================
629
+ /**
630
+ * 保存 Postmortem 报告
631
+ */
632
+ saveReport(report) {
633
+ const filename = `${report.id}-${this.slugify(report.title)}.md`;
634
+ const filepath = path.join(this.postmortemDir, filename);
635
+ const content = this.renderReportToMarkdown(report);
636
+ fs.writeFileSync(filepath, content, "utf-8");
637
+ const jsonPath = path.join(this.postmortemDir, `${report.id}.json`);
638
+ fs.writeFileSync(jsonPath, JSON.stringify(report, null, 2), "utf-8");
639
+ return filepath;
640
+ }
641
+ /**
642
+ * 读取 Postmortem 报告
643
+ */
644
+ getReport(id) {
645
+ const jsonPath = path.join(this.postmortemDir, `${id}.json`);
646
+ if (!fs.existsSync(jsonPath)) {
647
+ return null;
648
+ }
649
+ try {
650
+ const content = fs.readFileSync(jsonPath, "utf-8");
651
+ return JSON.parse(content);
652
+ } catch {
653
+ return null;
654
+ }
655
+ }
656
+ /**
657
+ * 列出所有 Postmortem
658
+ */
659
+ listReports() {
660
+ const index = this.loadIndex();
661
+ return index?.reports || [];
662
+ }
663
+ /**
664
+ * 渲染报告为 Markdown
665
+ */
666
+ renderReportToMarkdown(report) {
667
+ const severityEmoji = {
668
+ critical: "\u{1F534}",
669
+ high: "\u{1F7E0}",
670
+ medium: "\u{1F7E1}",
671
+ low: "\u{1F7E2}"
672
+ };
673
+ return `# ${report.id}: ${report.title}
674
+
675
+ ## \u5143\u6570\u636E
676
+ - **ID**: ${report.id}
677
+ - **\u4E25\u91CD\u7A0B\u5EA6**: ${severityEmoji[report.severity]} ${report.severity.toUpperCase()}
678
+ - **\u7C7B\u522B**: ${report.category}
679
+ - **\u72B6\u6001**: ${report.status}
680
+ - **\u521B\u5EFA\u65F6\u95F4**: ${report.createdAt}
681
+ - **\u66F4\u65B0\u65F6\u95F4**: ${report.updatedAt}
682
+
683
+ ## \u76F8\u5173\u63D0\u4EA4
684
+ ${report.relatedCommits.map((c) => `- \`${c.shortHash}\` - ${c.message} (${c.author}, ${c.date})`).join("\n")}
685
+
686
+ ## \u5F71\u54CD\u7248\u672C
687
+ - **\u4ECE**: ${report.affectedVersions.from}
688
+ - **\u5230**: ${report.affectedVersions.to}
689
+
690
+ ## \u95EE\u9898\u63CF\u8FF0
691
+ ${report.description}
692
+
693
+ ## \u6839\u672C\u539F\u56E0
694
+ ${report.rootCause.map((c) => `- ${c}`).join("\n")}
695
+
696
+ ## \u4FEE\u590D\u65B9\u6848
697
+ ${report.solution.description}
698
+
699
+ ${report.solution.codeExample ? `
700
+ ### \u4EE3\u7801\u793A\u4F8B
701
+
702
+ **\u274C \u9519\u8BEF\u5199\u6CD5**
703
+ \`\`\`typescript
704
+ ${report.solution.codeExample.bad}
705
+ \`\`\`
706
+
707
+ **\u2705 \u6B63\u786E\u5199\u6CD5**
708
+ \`\`\`typescript
709
+ ${report.solution.codeExample.good}
710
+ \`\`\`
711
+ ` : ""}
712
+
713
+ ## \u9884\u9632\u63AA\u65BD
714
+ ${report.preventionMeasures.map((m, i) => `${i + 1}. ${m}`).join("\n")}
715
+
716
+ ## AI \u5F00\u53D1\u6307\u4EE4
717
+ > \u4EE5\u4E0B\u6307\u4EE4\u4F1A\u81EA\u52A8\u6CE8\u5165\u5230 CLAUDE.md \u4E2D\uFF0C\u6307\u5BFC AI \u5728\u5F00\u53D1\u65F6\u907F\u514D\u7C7B\u4F3C\u95EE\u9898
718
+
719
+ ${report.aiDirectives.map((d) => `- ${d}`).join("\n")}
720
+
721
+ ## \u68C0\u6D4B\u6A21\u5F0F
722
+ ${report.detectionPatterns.length > 0 ? report.detectionPatterns.map((p) => `
723
+ ### ${p.description}
724
+ - **\u7C7B\u578B**: ${p.type}
725
+ - **\u6A21\u5F0F**: \`${p.pattern}\`
726
+ - **\u9002\u7528\u6587\u4EF6**: ${p.fileTypes.join(", ")}
727
+ - **\u4E25\u91CD\u7A0B\u5EA6**: ${p.severity}
728
+ `).join("\n") : "\u6682\u65E0\u81EA\u52A8\u68C0\u6D4B\u6A21\u5F0F"}
729
+
730
+ ## \u76F8\u5173\u6587\u4EF6
731
+ ${report.relatedFiles.map((f) => `- \`${f}\``).join("\n")}
732
+
733
+ ## \u6807\u7B7E
734
+ ${report.tags.map((t) => `\`${t}\``).join(" ")}
735
+
736
+ ---
737
+ *\u7531 CCJK Postmortem System \u81EA\u52A8\u751F\u6210*
738
+ `;
739
+ }
740
+ /**
741
+ * 生成 slug
742
+ */
743
+ slugify(text) {
744
+ return text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").substring(0, 50);
745
+ }
746
+ // ==========================================================================
747
+ // Index Management
748
+ // ==========================================================================
749
+ /**
750
+ * 创建空索引
751
+ */
752
+ createEmptyIndex() {
753
+ return {
754
+ version: "1.0.0",
755
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
756
+ stats: {
757
+ total: 0,
758
+ bySeverity: { critical: 0, high: 0, medium: 0, low: 0 },
759
+ byCategory: {
760
+ "type-safety": 0,
761
+ "error-handling": 0,
762
+ "performance": 0,
763
+ "security": 0,
764
+ "logic-error": 0,
765
+ "race-condition": 0,
766
+ "memory-leak": 0,
767
+ "api-misuse": 0,
768
+ "configuration": 0,
769
+ "dependency": 0,
770
+ "other": 0
771
+ },
772
+ byStatus: { active: 0, resolved: 0, monitoring: 0, archived: 0 }
773
+ },
774
+ reports: []
775
+ };
776
+ }
777
+ /**
778
+ * 加载索引
779
+ */
780
+ loadIndex() {
781
+ const indexPath = path.join(this.postmortemDir, INDEX_FILE);
782
+ if (!fs.existsSync(indexPath)) {
783
+ return null;
784
+ }
785
+ try {
786
+ const content = fs.readFileSync(indexPath, "utf-8");
787
+ return JSON.parse(content);
788
+ } catch {
789
+ return null;
790
+ }
791
+ }
792
+ /**
793
+ * 保存索引
794
+ */
795
+ saveIndex(index) {
796
+ const indexPath = path.join(this.postmortemDir, INDEX_FILE);
797
+ fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
798
+ }
799
+ /**
800
+ * 更新索引
801
+ */
802
+ updateIndex() {
803
+ const index = this.createEmptyIndex();
804
+ const files = fs.readdirSync(this.postmortemDir).filter((f) => f.startsWith("PM-") && f.endsWith(".json"));
805
+ for (const file of files) {
806
+ try {
807
+ const content = fs.readFileSync(path.join(this.postmortemDir, file), "utf-8");
808
+ const report = JSON.parse(content);
809
+ index.stats.total++;
810
+ index.stats.bySeverity[report.severity]++;
811
+ index.stats.byCategory[report.category]++;
812
+ index.stats.byStatus[report.status]++;
813
+ index.reports.push({
814
+ id: report.id,
815
+ title: report.title,
816
+ severity: report.severity,
817
+ category: report.category,
818
+ status: report.status,
819
+ createdAt: report.createdAt,
820
+ filePath: file.replace(".json", ".md")
821
+ });
822
+ } catch {
823
+ }
824
+ }
825
+ index.reports.sort((a, b) => {
826
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
827
+ const severityDiff = severityOrder[a.severity] - severityOrder[b.severity];
828
+ if (severityDiff !== 0)
829
+ return severityDiff;
830
+ return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
831
+ });
832
+ index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
833
+ this.saveIndex(index);
834
+ return index;
835
+ }
836
+ // ==========================================================================
837
+ // CLAUDE.md Integration
838
+ // ==========================================================================
839
+ /**
840
+ * 同步到 CLAUDE.md
841
+ */
842
+ async syncToClaudeMd() {
843
+ const claudeMdPath = path.join(this.projectRoot, "CLAUDE.md");
844
+ const injection = this.generateClaudeMdInjection();
845
+ let content = "";
846
+ if (fs.existsSync(claudeMdPath)) {
847
+ content = fs.readFileSync(claudeMdPath, "utf-8");
848
+ }
849
+ const startIndex = content.indexOf(CLAUDE_MD_SECTION_START);
850
+ const endIndex = content.indexOf(CLAUDE_MD_SECTION_END);
851
+ if (startIndex !== -1 && endIndex !== -1) {
852
+ content = content.substring(0, startIndex) + content.substring(endIndex + CLAUDE_MD_SECTION_END.length);
853
+ }
854
+ const injectionContent = `
855
+ ${CLAUDE_MD_SECTION_START}
856
+ ${injection.content}
857
+ ${CLAUDE_MD_SECTION_END}
858
+ `;
859
+ content = `${content.trim()}
860
+
861
+ ${injectionContent.trim()}
862
+ `;
863
+ fs.writeFileSync(claudeMdPath, content, "utf-8");
864
+ return {
865
+ synced: injection.sourcePostmortems.length,
866
+ claudeMdPath
867
+ };
868
+ }
869
+ /**
870
+ * 生成 CLAUDE.md 注入内容
871
+ */
872
+ generateClaudeMdInjection() {
873
+ const index = this.loadIndex();
874
+ const reports = [];
875
+ if (index) {
876
+ const severityOrder = {
877
+ critical: 0,
878
+ high: 1,
879
+ medium: 2,
880
+ low: 3
881
+ };
882
+ const minSeverityOrder = severityOrder[this.config.minSyncSeverity];
883
+ for (const meta of index.reports) {
884
+ if (severityOrder[meta.severity] <= minSeverityOrder && meta.status === "active") {
885
+ const report = this.getReport(meta.id);
886
+ if (report) {
887
+ reports.push(report);
888
+ }
889
+ }
890
+ if (reports.length >= this.config.maxSyncItems) {
891
+ break;
892
+ }
893
+ }
894
+ }
895
+ const lines = [
896
+ "## \u26A0\uFE0F \u5DF2\u77E5\u95EE\u9898\u9884\u8B66 (Postmortem Intelligence)",
897
+ "",
898
+ "> \u57FA\u4E8E\u5386\u53F2 bug \u5206\u6790\u81EA\u52A8\u751F\u6210\uFF0C\u5E2E\u52A9\u907F\u514D\u91CD\u590D\u72AF\u9519",
899
+ ""
900
+ ];
901
+ if (reports.length === 0) {
902
+ lines.push("\u6682\u65E0\u9700\u8981\u5173\u6CE8\u7684\u95EE\u9898\u3002");
903
+ } else {
904
+ const critical = reports.filter((r) => r.severity === "critical");
905
+ const high = reports.filter((r) => r.severity === "high");
906
+ const medium = reports.filter((r) => r.severity === "medium");
907
+ if (critical.length > 0) {
908
+ lines.push("### \u{1F534} \u4E25\u91CD");
909
+ for (const r of critical) {
910
+ lines.push(`- **${r.id}**: ${r.title}`);
911
+ lines.push(` - ${r.aiDirectives[0] || r.preventionMeasures[0]}`);
912
+ }
913
+ lines.push("");
914
+ }
915
+ if (high.length > 0) {
916
+ lines.push("### \u{1F7E0} \u9AD8\u4F18\u5148\u7EA7");
917
+ for (const r of high) {
918
+ lines.push(`- **${r.id}**: ${r.title}`);
919
+ lines.push(` - ${r.aiDirectives[0] || r.preventionMeasures[0]}`);
920
+ }
921
+ lines.push("");
922
+ }
923
+ if (medium.length > 0) {
924
+ lines.push("### \u{1F7E1} \u4E2D\u4F18\u5148\u7EA7");
925
+ for (const r of medium) {
926
+ lines.push(`- **${r.id}**: ${r.title}`);
927
+ }
928
+ lines.push("");
929
+ }
930
+ lines.push("### \u{1F4CB} \u5F00\u53D1\u6307\u4EE4");
931
+ const allDirectives = /* @__PURE__ */ new Set();
932
+ for (const r of reports.slice(0, 5)) {
933
+ for (const d of r.aiDirectives.slice(0, 2)) {
934
+ allDirectives.add(d);
935
+ }
936
+ }
937
+ for (const d of allDirectives) {
938
+ lines.push(`- ${d}`);
939
+ }
940
+ lines.push("");
941
+ lines.push(`> \u8BE6\u7EC6\u4FE1\u606F\u8BF7\u67E5\u770B \`${this.config.directory}/\` \u76EE\u5F55`);
942
+ }
943
+ return {
944
+ sectionId: "postmortem-warnings",
945
+ title: "\u5DF2\u77E5\u95EE\u9898\u9884\u8B66",
946
+ content: lines.join("\n"),
947
+ priority: 100,
948
+ sourcePostmortems: reports.map((r) => r.id),
949
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
950
+ };
951
+ }
952
+ // ==========================================================================
953
+ // Code Checking
954
+ // ==========================================================================
955
+ /**
956
+ * 检查代码是否可能触发已知问题
957
+ */
958
+ async checkCode(options = {}) {
959
+ const { files, staged } = options;
960
+ let filesToCheck = [];
961
+ if (files && files.length > 0) {
962
+ filesToCheck = files;
963
+ } else if (staged) {
964
+ filesToCheck = this.getStagedFiles();
965
+ } else {
966
+ filesToCheck = this.getAllSourceFiles();
967
+ }
968
+ const issues = [];
969
+ const index = this.loadIndex();
970
+ if (!index) {
971
+ return this.createEmptyCheckReport(filesToCheck.length);
972
+ }
973
+ const patterns = [];
974
+ for (const meta of index.reports) {
975
+ if (meta.status !== "active")
976
+ continue;
977
+ const report = this.getReport(meta.id);
978
+ if (!report)
979
+ continue;
980
+ for (const pattern of report.detectionPatterns) {
981
+ patterns.push({ pattern, postmortemId: report.id });
982
+ }
983
+ }
984
+ for (const file of filesToCheck) {
985
+ const fullPath = path.isAbsolute(file) ? file : path.join(this.projectRoot, file);
986
+ if (!fs.existsSync(fullPath))
987
+ continue;
988
+ const content = fs.readFileSync(fullPath, "utf-8");
989
+ const lines = content.split("\n");
990
+ for (const { pattern, postmortemId } of patterns) {
991
+ if (!pattern.fileTypes.some((ft) => file.endsWith(ft))) {
992
+ continue;
993
+ }
994
+ if (pattern.type === "regex") {
995
+ try {
996
+ const regex = new RegExp(pattern.pattern, "g");
997
+ for (let i = 0; i < lines.length; i++) {
998
+ const line = lines[i];
999
+ const matches = line.match(regex);
1000
+ if (matches) {
1001
+ issues.push({
1002
+ file,
1003
+ line: i + 1,
1004
+ column: line.indexOf(matches[0]) + 1,
1005
+ pattern,
1006
+ postmortemId,
1007
+ message: `\u53EF\u80FD\u89E6\u53D1 ${postmortemId}: ${pattern.description}`,
1008
+ suggestion: `\u53C2\u8003 ${this.config.directory}/${postmortemId}.md`
1009
+ });
1010
+ }
1011
+ }
1012
+ } catch {
1013
+ }
1014
+ }
1015
+ }
1016
+ }
1017
+ const summary = {
1018
+ critical: issues.filter((i) => i.pattern.severity === "critical").length,
1019
+ high: issues.filter((i) => i.pattern.severity === "high").length,
1020
+ medium: issues.filter((i) => i.pattern.severity === "medium").length,
1021
+ low: issues.filter((i) => i.pattern.severity === "low").length
1022
+ };
1023
+ return {
1024
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1025
+ filesChecked: filesToCheck.length,
1026
+ issuesFound: issues,
1027
+ summary,
1028
+ passed: summary.critical === 0 && summary.high === 0
1029
+ };
1030
+ }
1031
+ /**
1032
+ * 获取暂存的文件
1033
+ */
1034
+ getStagedFiles() {
1035
+ try {
1036
+ const output = execSync("git diff --cached --name-only", {
1037
+ cwd: this.projectRoot,
1038
+ encoding: "utf-8"
1039
+ });
1040
+ return output.trim().split("\n").filter(Boolean);
1041
+ } catch {
1042
+ return [];
1043
+ }
1044
+ }
1045
+ /**
1046
+ * 获取所有源文件
1047
+ */
1048
+ getAllSourceFiles() {
1049
+ const files = [];
1050
+ const walk = (dir) => {
1051
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1052
+ for (const entry of entries) {
1053
+ const fullPath = path.join(dir, entry.name);
1054
+ const relativePath = path.relative(this.projectRoot, fullPath);
1055
+ if (this.config.detection.excludePatterns.some((p) => this.matchGlob(relativePath, p))) {
1056
+ continue;
1057
+ }
1058
+ if (entry.isDirectory()) {
1059
+ walk(fullPath);
1060
+ } else if (entry.isFile()) {
1061
+ if (this.config.detection.includePatterns.some((p) => this.matchGlob(relativePath, p))) {
1062
+ files.push(relativePath);
1063
+ }
1064
+ }
1065
+ }
1066
+ };
1067
+ walk(this.projectRoot);
1068
+ return files;
1069
+ }
1070
+ /**
1071
+ * 简单的 glob 匹配
1072
+ */
1073
+ matchGlob(filepath, pattern) {
1074
+ const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
1075
+ return new RegExp(`^${regexPattern}$`).test(filepath);
1076
+ }
1077
+ /**
1078
+ * 创建空的检查报告
1079
+ */
1080
+ createEmptyCheckReport(filesChecked) {
1081
+ return {
1082
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1083
+ filesChecked,
1084
+ issuesFound: [],
1085
+ summary: { critical: 0, high: 0, medium: 0, low: 0 },
1086
+ passed: true
1087
+ };
1088
+ }
1089
+ // ==========================================================================
1090
+ // Release Summary
1091
+ // ==========================================================================
1092
+ /**
1093
+ * 生成发布摘要
1094
+ */
1095
+ async generateReleaseSummary(options) {
1096
+ const { version, since, until } = options;
1097
+ const commits = PostmortemAnalyzer.getFixCommits({
1098
+ since,
1099
+ until,
1100
+ cwd: this.projectRoot
1101
+ });
1102
+ const analyses = commits.map(
1103
+ (c) => PostmortemAnalyzer.analyzeFixCommit(c, this.projectRoot)
1104
+ );
1105
+ const existingIds = this.listReports().map((r) => r.id);
1106
+ const newReports = PostmortemAnalyzer.generatePostmortem(analyses, existingIds);
1107
+ const newIds = [];
1108
+ for (const report of newReports) {
1109
+ report.affectedVersions = { from: since || "unknown", to: version };
1110
+ this.saveReport(report);
1111
+ newIds.push(report.id);
1112
+ }
1113
+ this.updateIndex();
1114
+ const summary = {
1115
+ version,
1116
+ releaseDate: (/* @__PURE__ */ new Date()).toISOString(),
1117
+ fixCommitCount: commits.length,
1118
+ newPostmortems: newIds,
1119
+ updatedPostmortems: [],
1120
+ summary: this.generateReleaseSummaryText(commits, newReports),
1121
+ keyLessons: this.extractKeyLessons(newReports)
1122
+ };
1123
+ const summaryPath = path.join(this.postmortemDir, "summaries", `${version}.json`);
1124
+ fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2), "utf-8");
1125
+ if (this.config.autoSyncToClaudeMd) {
1126
+ await this.syncToClaudeMd();
1127
+ }
1128
+ return summary;
1129
+ }
1130
+ /**
1131
+ * 生成发布摘要文本
1132
+ */
1133
+ generateReleaseSummaryText(commits, reports) {
1134
+ const lines = [
1135
+ `\u672C\u6B21\u53D1\u5E03\u5305\u542B ${commits.length} \u4E2A bug \u4FEE\u590D\uFF0C\u751F\u6210\u4E86 ${reports.length} \u4E2A\u65B0\u7684 Postmortem \u62A5\u544A\u3002`,
1136
+ ""
1137
+ ];
1138
+ if (reports.length > 0) {
1139
+ lines.push("\u4E3B\u8981\u95EE\u9898\u7C7B\u578B:");
1140
+ const categories = /* @__PURE__ */ new Map();
1141
+ for (const r of reports) {
1142
+ categories.set(r.category, (categories.get(r.category) || 0) + 1);
1143
+ }
1144
+ for (const [cat, count] of categories) {
1145
+ lines.push(`- ${cat}: ${count} \u4E2A`);
1146
+ }
1147
+ }
1148
+ return lines.join("\n");
1149
+ }
1150
+ /**
1151
+ * 提取关键教训
1152
+ */
1153
+ extractKeyLessons(reports) {
1154
+ const lessons = /* @__PURE__ */ new Set();
1155
+ for (const report of reports) {
1156
+ for (const measure of report.preventionMeasures.slice(0, 2)) {
1157
+ lessons.add(measure);
1158
+ }
1159
+ }
1160
+ return Array.from(lessons).slice(0, 10);
1161
+ }
1162
+ }
1163
+ let managerInstance = null;
1164
+ function getPostmortemManager(projectRoot, config) {
1165
+ if (!managerInstance || projectRoot) {
1166
+ managerInstance = new PostmortemManager(projectRoot, config);
1167
+ }
1168
+ return managerInstance;
1169
+ }
1170
+
1171
+ export { PostmortemAnalyzer, PostmortemManager, getPostmortemManager };