@pigcloud/skills 1.0.11 → 1.1.2

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 (298) hide show
  1. package/CHANGELOG.md +25 -20
  2. package/README.en.md +41 -75
  3. package/README.md +26 -39
  4. package/bin/cli.js +260 -151
  5. package/bin/rules-loader.js +271 -484
  6. package/codex-commands/README.md +25 -23
  7. package/codex-commands/commands/analyze.md +21 -22
  8. package/codex-commands/commands/build.md +22 -22
  9. package/codex-commands/commands/design.md +21 -22
  10. package/codex-commands/commands/distill.md +21 -21
  11. package/codex-commands/commands/doc.md +21 -22
  12. package/codex-commands/commands/infra.md +21 -21
  13. package/codex-commands/commands/init.md +20 -20
  14. package/codex-commands/commands/kb.md +21 -20
  15. package/codex-commands/commands/perf.md +21 -21
  16. package/codex-commands/commands/prd.md +21 -22
  17. package/codex-commands/commands/review.md +21 -22
  18. package/codex-commands/commands/security.md +21 -22
  19. package/codex-commands/commands/test.md +21 -21
  20. package/codex-commands/commands/workflow.md +21 -20
  21. package/package.json +5 -2
  22. package/rules/core/index.md +26 -41
  23. package/rules/delivery/index.md +25 -0
  24. package/rules/design/index.md +25 -0
  25. package/rules/discovery/index.md +25 -0
  26. package/rules/implementation/index.md +25 -0
  27. package/rules/index.md +24 -39
  28. package/rules/overlays/index.md +19 -19
  29. package/rules/overlays/pig-cloud.md +20 -45
  30. package/rules/shared/index.md +25 -0
  31. package/rules/skill-stage-map.json +26 -0
  32. package/rules/stages.json +48 -0
  33. package/rules/validation/index.md +25 -0
  34. package/scripts/add-skill-reference-nav.js +3 -0
  35. package/scripts/bootstrap-skill-specs.js +96 -0
  36. package/scripts/ci-validator.sh +51 -114
  37. package/scripts/generate-skill-prompt-library.js +3 -0
  38. package/scripts/golden-prompt-suite.current.js +211 -0
  39. package/scripts/migrate-skill-packages.js +309 -0
  40. package/scripts/run-golden-replays.js +110 -79
  41. package/scripts/validate-rules.js +128 -125
  42. package/scripts/validate-skill-replay-signals.js +45 -57
  43. package/scripts/validate-skill-shapes.js +153 -127
  44. package/scripts/validate-skill-stop-rules.js +54 -46
  45. package/skills/01-discovery/ambiguity-detection/SKILL.md +30 -0
  46. package/skills/01-discovery/ambiguity-detection/assets/golden-prompt-suite.current.js +22 -0
  47. package/skills/01-discovery/ambiguity-detection/references/README.md +17 -0
  48. package/skills/01-discovery/ambiguity-detection/references/cases.md +26 -0
  49. package/skills/01-discovery/ambiguity-detection/references/prompt-template.md +18 -0
  50. package/skills/01-discovery/ambiguity-detection/skill-spec.json +26 -0
  51. package/skills/01-discovery/business-analysis/SKILL.md +30 -0
  52. package/skills/01-discovery/business-analysis/assets/golden-prompt-suite.current.js +22 -0
  53. package/skills/01-discovery/business-analysis/references/README.md +17 -0
  54. package/skills/01-discovery/business-analysis/references/cases.md +26 -0
  55. package/skills/01-discovery/business-analysis/references/prompt-template.md +18 -0
  56. package/skills/01-discovery/business-analysis/skill-spec.json +26 -0
  57. package/skills/01-discovery/impact-analysis/SKILL.md +30 -0
  58. package/skills/01-discovery/impact-analysis/assets/golden-prompt-suite.current.js +22 -0
  59. package/skills/01-discovery/impact-analysis/references/README.md +17 -0
  60. package/skills/01-discovery/impact-analysis/references/cases.md +26 -0
  61. package/skills/01-discovery/impact-analysis/references/prompt-template.md +18 -0
  62. package/skills/01-discovery/impact-analysis/skill-spec.json +26 -0
  63. package/skills/01-discovery/requirement-discovery/SKILL.md +30 -0
  64. package/skills/01-discovery/requirement-discovery/assets/golden-prompt-suite.current.js +24 -0
  65. package/skills/01-discovery/requirement-discovery/references/README.md +17 -0
  66. package/skills/01-discovery/requirement-discovery/references/cases.md +28 -0
  67. package/skills/01-discovery/requirement-discovery/references/prompt-template.md +18 -0
  68. package/skills/01-discovery/requirement-discovery/skill-spec.json +26 -0
  69. package/skills/02-design/api-design/SKILL.md +29 -0
  70. package/skills/02-design/api-design/assets/golden-prompt-suite.current.js +22 -0
  71. package/skills/02-design/api-design/references/README.md +17 -0
  72. package/skills/02-design/api-design/references/cases.md +26 -0
  73. package/skills/02-design/api-design/references/prompt-template.md +18 -0
  74. package/skills/02-design/api-design/skill-spec.json +25 -0
  75. package/skills/02-design/architecture-design/SKILL.md +29 -0
  76. package/skills/02-design/architecture-design/assets/golden-prompt-suite.current.js +22 -0
  77. package/skills/02-design/architecture-design/references/README.md +17 -0
  78. package/skills/02-design/architecture-design/references/cases.md +26 -0
  79. package/skills/02-design/architecture-design/references/prompt-template.md +18 -0
  80. package/skills/02-design/architecture-design/skill-spec.json +25 -0
  81. package/skills/02-design/database-design/SKILL.md +29 -0
  82. package/skills/02-design/database-design/assets/golden-prompt-suite.current.js +22 -0
  83. package/skills/02-design/database-design/references/README.md +17 -0
  84. package/skills/02-design/database-design/references/cases.md +26 -0
  85. package/skills/02-design/database-design/references/prompt-template.md +18 -0
  86. package/skills/02-design/database-design/skill-spec.json +25 -0
  87. package/skills/02-design/task-breakdown/SKILL.md +29 -0
  88. package/skills/02-design/task-breakdown/assets/golden-prompt-suite.current.js +22 -0
  89. package/skills/02-design/task-breakdown/references/README.md +17 -0
  90. package/skills/02-design/task-breakdown/references/cases.md +26 -0
  91. package/skills/02-design/task-breakdown/references/prompt-template.md +18 -0
  92. package/skills/02-design/task-breakdown/skill-spec.json +25 -0
  93. package/skills/03-implementation/backend-development/SKILL.md +29 -0
  94. package/skills/03-implementation/backend-development/assets/golden-prompt-suite.current.js +22 -0
  95. package/skills/03-implementation/backend-development/references/README.md +17 -0
  96. package/skills/03-implementation/backend-development/references/cases.md +26 -0
  97. package/skills/03-implementation/backend-development/references/prompt-template.md +18 -0
  98. package/skills/03-implementation/backend-development/skill-spec.json +25 -0
  99. package/skills/03-implementation/bug-fix/SKILL.md +29 -0
  100. package/skills/03-implementation/bug-fix/assets/golden-prompt-suite.current.js +22 -0
  101. package/skills/03-implementation/bug-fix/references/README.md +17 -0
  102. package/skills/03-implementation/bug-fix/references/cases.md +26 -0
  103. package/skills/03-implementation/bug-fix/references/prompt-template.md +18 -0
  104. package/skills/03-implementation/bug-fix/skill-spec.json +25 -0
  105. package/skills/03-implementation/database-change/SKILL.md +29 -0
  106. package/skills/03-implementation/database-change/assets/golden-prompt-suite.current.js +22 -0
  107. package/skills/03-implementation/database-change/references/README.md +17 -0
  108. package/skills/03-implementation/database-change/references/cases.md +26 -0
  109. package/skills/03-implementation/database-change/references/prompt-template.md +18 -0
  110. package/skills/03-implementation/database-change/skill-spec.json +25 -0
  111. package/skills/03-implementation/frontend-development/SKILL.md +29 -0
  112. package/skills/03-implementation/frontend-development/assets/golden-prompt-suite.current.js +22 -0
  113. package/skills/03-implementation/frontend-development/references/README.md +17 -0
  114. package/skills/03-implementation/frontend-development/references/cases.md +26 -0
  115. package/skills/03-implementation/frontend-development/references/prompt-template.md +18 -0
  116. package/skills/03-implementation/frontend-development/skill-spec.json +25 -0
  117. package/skills/04-validation/code-review/SKILL.md +29 -0
  118. package/skills/04-validation/code-review/assets/golden-prompt-suite.current.js +22 -0
  119. package/skills/04-validation/code-review/references/README.md +17 -0
  120. package/skills/04-validation/code-review/references/cases.md +26 -0
  121. package/skills/04-validation/code-review/references/prompt-template.md +18 -0
  122. package/skills/04-validation/code-review/skill-spec.json +25 -0
  123. package/skills/04-validation/performance-review/SKILL.md +29 -0
  124. package/skills/04-validation/performance-review/assets/golden-prompt-suite.current.js +22 -0
  125. package/skills/04-validation/performance-review/references/README.md +17 -0
  126. package/skills/04-validation/performance-review/references/cases.md +26 -0
  127. package/skills/04-validation/performance-review/references/prompt-template.md +18 -0
  128. package/skills/04-validation/performance-review/skill-spec.json +25 -0
  129. package/skills/04-validation/regression-check/SKILL.md +29 -0
  130. package/skills/04-validation/regression-check/assets/golden-prompt-suite.current.js +22 -0
  131. package/skills/04-validation/regression-check/references/README.md +17 -0
  132. package/skills/04-validation/regression-check/references/cases.md +26 -0
  133. package/skills/04-validation/regression-check/references/prompt-template.md +18 -0
  134. package/skills/04-validation/regression-check/skill-spec.json +25 -0
  135. package/skills/04-validation/security-review/SKILL.md +29 -0
  136. package/skills/04-validation/security-review/assets/golden-prompt-suite.current.js +22 -0
  137. package/skills/04-validation/security-review/references/README.md +17 -0
  138. package/skills/04-validation/security-review/references/cases.md +26 -0
  139. package/skills/04-validation/security-review/references/prompt-template.md +18 -0
  140. package/skills/04-validation/security-review/skill-spec.json +25 -0
  141. package/skills/04-validation/unit-test/SKILL.md +29 -0
  142. package/skills/04-validation/unit-test/assets/golden-prompt-suite.current.js +22 -0
  143. package/skills/04-validation/unit-test/references/README.md +17 -0
  144. package/skills/04-validation/unit-test/references/cases.md +26 -0
  145. package/skills/04-validation/unit-test/references/prompt-template.md +18 -0
  146. package/skills/04-validation/unit-test/skill-spec.json +25 -0
  147. package/skills/05-delivery/change-log/SKILL.md +29 -0
  148. package/skills/05-delivery/change-log/assets/golden-prompt-suite.current.js +22 -0
  149. package/skills/05-delivery/change-log/references/README.md +17 -0
  150. package/skills/05-delivery/change-log/references/cases.md +26 -0
  151. package/skills/05-delivery/change-log/references/prompt-template.md +18 -0
  152. package/skills/05-delivery/change-log/skill-spec.json +25 -0
  153. package/skills/05-delivery/deployment-guide/SKILL.md +29 -0
  154. package/skills/05-delivery/deployment-guide/assets/golden-prompt-suite.current.js +22 -0
  155. package/skills/05-delivery/deployment-guide/references/README.md +17 -0
  156. package/skills/05-delivery/deployment-guide/references/cases.md +26 -0
  157. package/skills/05-delivery/deployment-guide/references/prompt-template.md +18 -0
  158. package/skills/05-delivery/deployment-guide/skill-spec.json +25 -0
  159. package/skills/05-delivery/release-check/SKILL.md +29 -0
  160. package/skills/05-delivery/release-check/assets/golden-prompt-suite.current.js +22 -0
  161. package/skills/05-delivery/release-check/references/README.md +17 -0
  162. package/skills/05-delivery/release-check/references/cases.md +26 -0
  163. package/skills/05-delivery/release-check/references/prompt-template.md +18 -0
  164. package/skills/05-delivery/release-check/skill-spec.json +25 -0
  165. package/skills/05-delivery/release-validation/SKILL.md +29 -0
  166. package/skills/05-delivery/release-validation/assets/golden-prompt-suite.current.js +22 -0
  167. package/skills/05-delivery/release-validation/references/README.md +17 -0
  168. package/skills/05-delivery/release-validation/references/cases.md +26 -0
  169. package/skills/05-delivery/release-validation/references/prompt-template.md +18 -0
  170. package/skills/05-delivery/release-validation/skill-spec.json +25 -0
  171. package/skills/shared/codebase-learning/SKILL.md +29 -0
  172. package/skills/shared/codebase-learning/assets/golden-prompt-suite.current.js +22 -0
  173. package/skills/shared/codebase-learning/references/README.md +17 -0
  174. package/skills/shared/codebase-learning/references/cases.md +26 -0
  175. package/skills/shared/codebase-learning/references/prompt-template.md +18 -0
  176. package/skills/shared/codebase-learning/skill-spec.json +25 -0
  177. package/skills/shared/evidence-collector/SKILL.md +29 -0
  178. package/skills/shared/evidence-collector/assets/golden-prompt-suite.current.js +22 -0
  179. package/skills/shared/evidence-collector/references/README.md +17 -0
  180. package/skills/shared/evidence-collector/references/cases.md +26 -0
  181. package/skills/shared/evidence-collector/references/prompt-template.md +18 -0
  182. package/skills/shared/evidence-collector/skill-spec.json +25 -0
  183. package/skills/shared/framework-guide/SKILL.md +28 -0
  184. package/skills/shared/framework-guide/assets/golden-prompt-suite.current.js +22 -0
  185. package/skills/shared/framework-guide/references/README.md +17 -0
  186. package/skills/shared/framework-guide/references/cases.md +26 -0
  187. package/skills/shared/framework-guide/references/prompt-template.md +18 -0
  188. package/skills/shared/framework-guide/skill-spec.json +24 -0
  189. package/rules/bundles.json +0 -358
  190. package/rules/coding/analysis.md +0 -27
  191. package/rules/coding/backend/cache-invalidation.md +0 -30
  192. package/rules/coding/backend/cache-keying.md +0 -30
  193. package/rules/coding/backend/cache.md +0 -37
  194. package/rules/coding/backend/database.md +0 -32
  195. package/rules/coding/backend/feign.md +0 -30
  196. package/rules/coding/backend/index.md +0 -42
  197. package/rules/coding/backend/query.md +0 -32
  198. package/rules/coding/backend/remote.md +0 -33
  199. package/rules/coding/backend/transaction-boundary.md +0 -30
  200. package/rules/coding/backend/transaction-rollback.md +0 -30
  201. package/rules/coding/backend/transaction.md +0 -38
  202. package/rules/coding/boundary.md +0 -25
  203. package/rules/coding/implementation.md +0 -26
  204. package/rules/coding/index.md +0 -38
  205. package/rules/coding/scaffold.md +0 -28
  206. package/rules/coding/testing.md +0 -29
  207. package/rules/coding/validation.md +0 -29
  208. package/rules/core/code-quality.md +0 -30
  209. package/rules/core/evidence.md +0 -26
  210. package/rules/core/interface.md +0 -26
  211. package/rules/core/iteration.md +0 -26
  212. package/rules/core/layer-boundary.md +0 -25
  213. package/rules/core/logging.md +0 -26
  214. package/rules/core/security.md +0 -26
  215. package/rules/core/task-boundary.md +0 -27
  216. package/rules/docs/api.md +0 -34
  217. package/rules/docs/capture-summary.md +0 -29
  218. package/rules/docs/capture.md +0 -34
  219. package/rules/docs/contract.md +0 -30
  220. package/rules/docs/decision-log.md +0 -32
  221. package/rules/docs/examples.md +0 -28
  222. package/rules/docs/index.md +0 -49
  223. package/rules/docs/reference.md +0 -32
  224. package/rules/overlays/pig-cloud/controller.md +0 -33
  225. package/rules/overlays/pig-cloud/dto-vo.md +0 -33
  226. package/rules/overlays/pig-cloud/entity.md +0 -32
  227. package/rules/overlays/pig-cloud/exception.md +0 -32
  228. package/rules/overlays/pig-cloud/layering.md +0 -31
  229. package/rules/overlays/pig-cloud/mapper.md +0 -32
  230. package/rules/overlays/pig-cloud/query-style.md +0 -32
  231. package/rules/overlays/pig-cloud/rest-response.md +0 -33
  232. package/rules/overlays/pig-cloud/service.md +0 -33
  233. package/rules/overlays/pig-cloud/transactions.md +0 -32
  234. package/rules/overlays/pig-cloud/validation.md +0 -33
  235. package/rules/product/acceptance.md +0 -25
  236. package/rules/product/briefing.md +0 -27
  237. package/rules/product/index.md +0 -36
  238. package/rules/product/intake.md +0 -27
  239. package/rules/product/modeling.md +0 -25
  240. package/rules/product/project-context.md +0 -29
  241. package/rules/review/code.md +0 -35
  242. package/rules/review/evidence.md +0 -31
  243. package/rules/review/index.md +0 -50
  244. package/rules/review/java.md +0 -42
  245. package/rules/review/performance.md +0 -38
  246. package/rules/review/rubric.md +0 -28
  247. package/rules/review/security.md +0 -38
  248. package/rules/review/ts.md +0 -33
  249. package/rules/review/vue.md +0 -33
  250. package/rules/skill-profile-map.json +0 -59
  251. package/rules/skill-profile-map.md +0 -29
  252. package/rules/workflow/handoff.md +0 -25
  253. package/rules/workflow/index.md +0 -37
  254. package/rules/workflow/refinement.md +0 -29
  255. package/rules/workflow/router.md +0 -25
  256. package/rules/workflow/selection.md +0 -25
  257. package/rules/workflow/stop.md +0 -25
  258. package/skills/api-contract-docs/SKILL.md +0 -77
  259. package/skills/business-fact-extraction/SKILL.md +0 -337
  260. package/skills/business-fact-extraction/scripts/write-knowledge-base.js +0 -228
  261. package/skills/code-review/SKILL.md +0 -136
  262. package/skills/code-review/references/findings-template.md +0 -51
  263. package/skills/code-review/references/performance-checklist.md +0 -213
  264. package/skills/code-review/references/rubric.md +0 -232
  265. package/skills/code-review/references/rules.md +0 -32
  266. package/skills/code-review/references/security-checklist.md +0 -178
  267. package/skills/code-review/references/stack-notes.md +0 -25
  268. package/skills/code-review/references/template-review.md +0 -39
  269. package/skills/code-review/scripts/lint-code-review.mjs +0 -431
  270. package/skills/domain-modeling/SKILL.md +0 -81
  271. package/skills/domain-modeling/references/README.md +0 -134
  272. package/skills/domain-modeling/references/distillation-checklist.md +0 -44
  273. package/skills/domain-modeling/references/test-cases-template.md +0 -128
  274. package/skills/environment-deploy/SKILL.md +0 -81
  275. package/skills/feature-build/SKILL.md +0 -122
  276. package/skills/feature-build/references/coding-checklist.md +0 -97
  277. package/skills/feature-build/references/comment-specification.md +0 -89
  278. package/skills/knowledge-capture/SKILL.md +0 -93
  279. package/skills/performance-audit/SKILL.md +0 -118
  280. package/skills/project-bootstrap/SKILL.md +0 -81
  281. package/skills/references/anti-rationalization.md +0 -144
  282. package/skills/references/business-fact-extraction.md +0 -415
  283. package/skills/references/engineering-delivery-method.md +0 -64
  284. package/skills/references/engineering-delivery-template.md +0 -81
  285. package/skills/references/golden-prompt-suite.js +0 -436
  286. package/skills/references/golden-prompt-suite.md +0 -33
  287. package/skills/references/project-requirement-alignment.md +0 -42
  288. package/skills/references/rule-loading-map.md +0 -117
  289. package/skills/references/skill-authoring-standard.md +0 -74
  290. package/skills/references/skill-boundary-template.md +0 -71
  291. package/skills/references/skill-enhanced-template.md +0 -103
  292. package/skills/references/skill-reference-matrix.md +0 -62
  293. package/skills/security-audit/SKILL.md +0 -119
  294. package/skills/spec-refinement/SKILL.md +0 -149
  295. package/skills/technical-design/SKILL.md +0 -106
  296. package/skills/technical-design/references/solid-checklist.md +0 -199
  297. package/skills/test-design/SKILL.md +0 -92
  298. package/skills/workflow-router/SKILL.md +0 -86
package/bin/cli.js CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const fs = require('fs/promises');
4
- const fsSync = require('fs');
5
- const path = require('path');
3
+ const fs = require('fs/promises');
4
+ const fsSync = require('fs');
5
+ const path = require('path');
6
6
  const os = require('os');
7
- const { detectRulesBundle } = require('./rules-loader');
7
+ const crypto = require('crypto');
8
+ const { detectRulesStage } = require('./rules-loader');
8
9
 
9
10
  const PACKAGE_ROOT = path.join(__dirname, '..');
10
11
  const SKILLS_DIR = path.join(PACKAGE_ROOT, 'skills');
@@ -41,22 +42,32 @@ const chalk = {
41
42
  gray: text => colorize(COLORS.gray, text)
42
43
  };
43
44
 
44
- const SKILLS = [
45
- { name: 'workflow-router', category: 'core', description: '路由工作阶段' },
46
- { name: 'spec-refinement', category: 'analysis', description: '将需求输入整理为可执行规格' },
47
- { name: 'technical-design', category: 'core', description: '梳理实现设计' },
48
- { name: 'feature-build', category: 'core', description: '安全实现功能变更' },
49
- { name: 'code-review', category: 'core', description: '审查代码变更' },
50
- { name: 'domain-modeling', category: 'analysis', description: '提炼领域知识' },
51
- { name: 'business-fact-extraction', category: 'analysis', description: '从代码中提取业务事实' },
52
- { name: 'api-contract-docs', category: 'integration', description: '整理 API 契约文档' },
53
- { name: 'test-design', category: 'integration', description: '设计测试覆盖' },
54
- { name: 'security-audit', category: 'review', description: '审查安全风险' },
55
- { name: 'performance-audit', category: 'review', description: '审查性能风险' },
56
- { name: 'knowledge-capture', category: 'collaboration', description: '沉淀可复用知识' },
57
- { name: 'project-bootstrap', category: 'infrastructure', description: '初始化项目骨架' },
58
- { name: 'environment-deploy', category: 'infrastructure', description: '部署支撑环境' }
59
- ];
45
+ const SKILLS = [
46
+ { name: 'requirement-discovery', stage: '01-discovery', category: 'discovery', description: '梳理需求与问题边界' },
47
+ { name: 'business-analysis', stage: '01-discovery', category: 'discovery', description: '提炼业务语义和术语' },
48
+ { name: 'ambiguity-detection', stage: '01-discovery', category: 'discovery', description: '识别歧义、冲突和缺口' },
49
+ { name: 'impact-analysis', stage: '01-discovery', category: 'discovery', description: '评估变更影响面' },
50
+ { name: 'architecture-design', stage: '02-design', category: 'design', description: '梳理系统级设计边界' },
51
+ { name: 'api-design', stage: '02-design', category: 'design', description: '设计接口契约和兼容性' },
52
+ { name: 'database-design', stage: '02-design', category: 'design', description: '设计表结构和查询方案' },
53
+ { name: 'task-breakdown', stage: '02-design', category: 'design', description: '拆解成可执行任务' },
54
+ { name: 'backend-development', stage: '03-implementation', category: 'implementation', description: '实现后端变更' },
55
+ { name: 'frontend-development', stage: '03-implementation', category: 'implementation', description: '实现前端变更' },
56
+ { name: 'database-change', stage: '03-implementation', category: 'implementation', description: '执行数据库变更' },
57
+ { name: 'bug-fix', stage: '03-implementation', category: 'implementation', description: '修复缺陷并收敛回归' },
58
+ { name: 'unit-test', stage: '04-validation', category: 'validation', description: '补充和运行单元测试' },
59
+ { name: 'code-review', stage: '04-validation', category: 'validation', description: '审查代码变更' },
60
+ { name: 'security-review', stage: '04-validation', category: 'validation', description: '审查安全风险' },
61
+ { name: 'performance-review', stage: '04-validation', category: 'validation', description: '审查性能风险' },
62
+ { name: 'regression-check', stage: '04-validation', category: 'validation', description: '检查回归风险' },
63
+ { name: 'release-check', stage: '05-delivery', category: 'delivery', description: '检查发布前准备' },
64
+ { name: 'release-validation', stage: '05-delivery', category: 'delivery', description: '验证发布结果' },
65
+ { name: 'change-log', stage: '05-delivery', category: 'delivery', description: '记录变更说明' },
66
+ { name: 'deployment-guide', stage: '05-delivery', category: 'delivery', description: '整理部署和交付指南' },
67
+ { name: 'framework-guide', stage: 'shared', category: 'shared', description: '提供框架约束和约定' },
68
+ { name: 'codebase-learning', stage: 'shared', category: 'shared', description: '帮助快速理解代码库' },
69
+ { name: 'evidence-collector', stage: 'shared', category: 'shared', description: '收集可追溯证据' }
70
+ ];
60
71
 
61
72
  const TOOL_CONFIGS = {
62
73
  codex: { dir: '.codex/skills/pigcloud', rootFile: '.codex/AGENTS.md', markers: ['.codex/AGENTS.md', '.codex'] },
@@ -126,9 +137,15 @@ function resolveRequestedTools(toolOption, cwd = getInstallRoot()) {
126
137
  return [normalized];
127
138
  }
128
139
 
129
- function getSkillInfo(name) {
130
- return SKILLS.find(skill => skill.name === name);
131
- }
140
+ function getSkillInfo(name) {
141
+ return SKILLS.find(skill => skill.name === name);
142
+ }
143
+
144
+ function getSkillSourceDir(skillName) {
145
+ const info = getSkillInfo(skillName);
146
+ if (!info) return null;
147
+ return path.join(SKILLS_DIR, info.stage, info.name);
148
+ }
132
149
 
133
150
  function getSelectedSkills(rawSkills, includeAll = false) {
134
151
  if (includeAll || !rawSkills) return [...SKILLS.map(skill => skill.name)];
@@ -202,19 +219,118 @@ async function ensureDir(targetPath) {
202
219
  await fs.mkdir(targetPath, { recursive: true });
203
220
  }
204
221
 
205
- async function copyDirectory(sourcePath, destinationPath) {
206
- await ensureDir(path.dirname(destinationPath));
207
- await fs.cp(sourcePath, destinationPath, { recursive: true, force: true });
208
- }
209
-
210
- async function copyDirectoryIfMissing(sourcePath, destinationPath) {
222
+ async function copyDirectory(sourcePath, destinationPath) {
223
+ await ensureDir(path.dirname(destinationPath));
224
+ await fs.cp(sourcePath, destinationPath, { recursive: true, force: true });
225
+ }
226
+
227
+ async function copyDirectoryIfMissing(sourcePath, destinationPath) {
211
228
  if (await pathExists(destinationPath)) {
212
229
  return false;
213
230
  }
214
231
 
215
- await copyDirectory(sourcePath, destinationPath);
216
- return true;
217
- }
232
+ await copyDirectory(sourcePath, destinationPath);
233
+ return true;
234
+ }
235
+
236
+ async function readDirectoryEntries(targetPath) {
237
+ try {
238
+ return await fs.readdir(targetPath, { withFileTypes: true });
239
+ } catch (error) {
240
+ if (error && error.code === 'ENOENT') {
241
+ return [];
242
+ }
243
+ throw error;
244
+ }
245
+ }
246
+
247
+ async function fileDigest(filePath) {
248
+ const content = await fs.readFile(filePath);
249
+ return crypto.createHash('sha1').update(content).digest('hex');
250
+ }
251
+
252
+ async function filesAreEqual(sourcePath, destinationPath) {
253
+ try {
254
+ const [sourceStats, destinationStats] = await Promise.all([
255
+ fs.stat(sourcePath),
256
+ fs.stat(destinationPath)
257
+ ]);
258
+
259
+ if (!sourceStats.isFile() || !destinationStats.isFile()) {
260
+ return false;
261
+ }
262
+
263
+ if (sourceStats.size !== destinationStats.size) {
264
+ return false;
265
+ }
266
+
267
+ if (sourceStats.size === 0) {
268
+ return true;
269
+ }
270
+
271
+ const [sourceDigest, destinationDigest] = await Promise.all([
272
+ fileDigest(sourcePath),
273
+ fileDigest(destinationPath)
274
+ ]);
275
+
276
+ return sourceDigest === destinationDigest;
277
+ } catch (error) {
278
+ if (error && error.code === 'ENOENT') {
279
+ return false;
280
+ }
281
+ throw error;
282
+ }
283
+ }
284
+
285
+ async function syncFile(sourcePath, destinationPath) {
286
+ if (await filesAreEqual(sourcePath, destinationPath)) {
287
+ return false;
288
+ }
289
+
290
+ await ensureDir(path.dirname(destinationPath));
291
+ await fs.copyFile(sourcePath, destinationPath);
292
+ return true;
293
+ }
294
+
295
+ async function syncDirectory(sourcePath, destinationPath) {
296
+ const sourceEntries = await readDirectoryEntries(sourcePath);
297
+ const destinationExists = await pathExists(destinationPath);
298
+
299
+ if (destinationExists) {
300
+ const destinationStats = await fs.stat(destinationPath);
301
+ if (!destinationStats.isDirectory()) {
302
+ await removePath(destinationPath);
303
+ }
304
+ }
305
+
306
+ await ensureDir(destinationPath);
307
+
308
+ const destinationEntries = await readDirectoryEntries(destinationPath);
309
+ const sourceNames = new Set(sourceEntries.map(entry => entry.name));
310
+
311
+ for (const entry of sourceEntries) {
312
+ const sourceEntryPath = path.join(sourcePath, entry.name);
313
+ const destinationEntryPath = path.join(destinationPath, entry.name);
314
+
315
+ if (entry.isDirectory()) {
316
+ await syncDirectory(sourceEntryPath, destinationEntryPath);
317
+ continue;
318
+ }
319
+
320
+ if (entry.isFile()) {
321
+ await syncFile(sourceEntryPath, destinationEntryPath);
322
+ continue;
323
+ }
324
+
325
+ await copyDirectory(sourceEntryPath, destinationEntryPath);
326
+ }
327
+
328
+ for (const entry of destinationEntries) {
329
+ if (!sourceNames.has(entry.name)) {
330
+ await removePath(path.join(destinationPath, entry.name));
331
+ }
332
+ }
333
+ }
218
334
 
219
335
  async function readJson(filePath) {
220
336
  const content = await fs.readFile(filePath, 'utf8');
@@ -230,22 +346,22 @@ async function removePath(targetPath) {
230
346
  await fs.rm(targetPath, { recursive: true, force: true });
231
347
  }
232
348
 
233
- async function copySkill(skillName, tool, cwd = process.cwd()) {
234
- const skill = normalizeSkillName(skillName);
235
- if (!getSkillInfo(skill)) {
236
- throw new Error(`Unknown skill: ${skillName}`);
237
- }
349
+ async function copySkill(skillName, tool, cwd = process.cwd()) {
350
+ const skill = normalizeSkillName(skillName);
351
+ const sourceDir = getSkillSourceDir(skill);
352
+ if (!sourceDir) {
353
+ throw new Error(`Unknown skill: ${skillName}`);
354
+ }
238
355
 
239
356
  const targetSkillDir = getTargetSkillDir(tool, cwd);
240
357
  if (!targetSkillDir) {
241
358
  throw new Error(`Unsupported tool: ${tool}`);
242
- }
243
-
244
- const sourceDir = path.join(SKILLS_DIR, skill);
245
- const destDir = path.join(targetSkillDir, skill);
246
- await ensureDir(targetSkillDir);
247
- await copyDirectory(sourceDir, destDir);
248
- }
359
+ }
360
+
361
+ const destDir = path.join(targetSkillDir, skill);
362
+ await ensureDir(targetSkillDir);
363
+ await syncDirectory(sourceDir, destDir);
364
+ }
249
365
 
250
366
  async function writeRootFile(tool, cwd = process.cwd()) {
251
367
  const config = TOOL_CONFIGS[tool];
@@ -261,16 +377,14 @@ async function writeRootFile(tool, cwd = process.cwd()) {
261
377
 
262
378
  async function copySkillToCodexHome(skillName) {
263
379
  const skill = normalizeSkillName(skillName);
264
- if (!getSkillInfo(skill)) {
380
+ const sourceDir = getSkillSourceDir(skill);
381
+ if (!sourceDir) {
265
382
  throw new Error(`Unknown skill: ${skillName}`);
266
383
  }
267
384
 
268
- const sourceDir = path.join(SKILLS_DIR, skill);
269
385
  const destDir = path.join(CODEX_HOME_SKILLS_NAMESPACE_DIR, skill);
270
386
  await removePath(path.join(CODEX_HOME_SKILLS_DIR, skill));
271
- await removePath(destDir);
272
- await ensureDir(CODEX_HOME_SKILLS_NAMESPACE_DIR);
273
- await copyDirectory(sourceDir, destDir);
387
+ await syncDirectory(sourceDir, destDir);
274
388
  }
275
389
 
276
390
  async function clearCodexPersonalSkillsNamespace() {
@@ -326,7 +440,7 @@ async function installCodexCommandPack() {
326
440
 
327
441
  const destDir = path.join(CODEX_PLUGINS_DIR, COMMAND_PACK_NAME);
328
442
  await ensureDir(CODEX_PLUGINS_DIR);
329
- await copyDirectory(COMMAND_PACK_SOURCE, destDir);
443
+ await syncDirectory(COMMAND_PACK_SOURCE, destDir);
330
444
  await writeCodexMarketplaceEntry(COMMAND_PACK_NAME);
331
445
  }
332
446
 
@@ -343,33 +457,44 @@ async function installSharedWorkspaceAssets(cwd = getInstallRoot()) {
343
457
  }
344
458
  }
345
459
 
346
- async function installSkills(skills, tool, cwd = getInstallRoot(), options = {}) {
347
- const { resetCodexNamespace = false } = options;
348
- await installSharedWorkspaceAssets(cwd);
349
- if (tool === 'codex' && resetCodexNamespace) {
350
- await clearCodexPersonalSkillsNamespace();
351
- await clearCodexLegacyFlatSkills(skills);
460
+ async function syncCodexSkills(skills) {
461
+ const selectedSkills = [...new Set(skills.map(skill => normalizeSkillName(skill)).filter(Boolean))];
462
+ const selectedSkillNames = new Set(selectedSkills);
463
+
464
+ await ensureDir(CODEX_HOME_SKILLS_NAMESPACE_DIR);
465
+
466
+ for (const skill of selectedSkills) {
467
+ await copySkillToCodexHome(skill);
468
+ }
469
+
470
+ const existingEntries = await readDirectoryEntries(CODEX_HOME_SKILLS_NAMESPACE_DIR);
471
+ for (const entry of existingEntries) {
472
+ if (!selectedSkillNames.has(entry.name)) {
473
+ await removePath(path.join(CODEX_HOME_SKILLS_NAMESPACE_DIR, entry.name));
474
+ }
352
475
  }
476
+ }
477
+
478
+ async function installSkills(skills, tool, cwd = getInstallRoot()) {
479
+ await installSharedWorkspaceAssets(cwd);
353
480
  for (const skill of skills) {
354
481
  await copySkill(skill, tool, cwd);
355
482
  }
356
483
  await writeRootFile(tool, cwd);
357
484
  if (tool === 'codex') {
358
- for (const skill of skills) {
359
- await copySkillToCodexHome(skill);
360
- }
361
- await installCodexCommandPack();
362
- }
363
- }
364
-
365
- async function installSkillsForTools(skills, tools, cwd = getInstallRoot(), options = {}) {
485
+ await syncCodexSkills(skills);
486
+ await installCodexCommandPack();
487
+ }
488
+ }
489
+
490
+ async function installSkillsForTools(skills, tools, cwd = getInstallRoot()) {
366
491
  const uniqueTools = [...new Set(tools.filter(Boolean))];
367
492
  if (uniqueTools.length === 0) {
368
493
  throw new Error('Unable to resolve any install targets.');
369
494
  }
370
495
 
371
496
  for (const tool of uniqueTools) {
372
- await installSkills(skills, tool, cwd, options);
497
+ await installSkills(skills, tool, cwd);
373
498
  }
374
499
  }
375
500
 
@@ -404,45 +529,35 @@ function parseArgs(argv) {
404
529
  continue;
405
530
  }
406
531
 
407
- if (token === '-b' || token === '--bundle') {
408
- options.bundle = argv[++index];
409
- continue;
410
- }
411
-
412
- if (token.startsWith('--bundle=')) {
413
- options.bundle = token.slice('--bundle='.length);
414
- continue;
415
- }
416
-
417
- if (token === '-k' || token === '--skill') {
418
- options.skill = argv[++index];
419
- continue;
420
- }
421
-
422
- if (token.startsWith('--skill=')) {
423
- options.skill = token.slice('--skill='.length);
424
- continue;
425
- }
426
-
427
- if (token === '-p' || token === '--profile') {
428
- options.profile = argv[++index];
429
- continue;
430
- }
431
-
432
- if (token.startsWith('--profile=')) {
433
- options.profile = token.slice('--profile='.length);
434
- continue;
435
- }
436
-
437
- if (token === '-f' || token === '--files') {
438
- options.files = argv[++index];
439
- continue;
440
- }
441
-
442
- if (token.startsWith('--files=')) {
443
- options.files = token.slice('--files='.length);
444
- continue;
445
- }
532
+ if (token === '-k' || token === '--skill') {
533
+ options.skill = argv[++index];
534
+ continue;
535
+ }
536
+
537
+ if (token.startsWith('--skill=')) {
538
+ options.skill = token.slice('--skill='.length);
539
+ continue;
540
+ }
541
+
542
+ if (token === '-g' || token === '--stage') {
543
+ options.stage = argv[++index];
544
+ continue;
545
+ }
546
+
547
+ if (token.startsWith('--stage=')) {
548
+ options.stage = token.slice('--stage='.length);
549
+ continue;
550
+ }
551
+
552
+ if (token === '-o' || token === '--overlay') {
553
+ options.overlay = argv[++index];
554
+ continue;
555
+ }
556
+
557
+ if (token.startsWith('--overlay=')) {
558
+ options.overlay = token.slice('--overlay='.length);
559
+ continue;
560
+ }
446
561
 
447
562
  positionals.push(token);
448
563
  }
@@ -459,8 +574,8 @@ function printHelp() {
459
574
  console.log(' pig-skills auto [--skills a,b] [--all]');
460
575
  console.log(' pig-skills codex [--skills a,b] [--all]');
461
576
  console.log(' pig-skills bootstrap');
462
- console.log(' pig-skills rules [--bundle <bundle>] [--profile <profile>] [--skill name] [--files a,b]');
463
- console.log(' pig-skills rules [--bundle <bundle>] [--profile <profile>] [--files a,b]');
577
+ console.log(' pig-skills rules [--skill name] [--stage <stage>] [--overlay <overlay>]');
578
+ console.log(' pig-skills rules [--stage <stage>] [--overlay <overlay>]');
464
579
  console.log(' pig-skills list');
465
580
  console.log(' pig-skills add <skill> [--tool codex]');
466
581
  console.log(' pig-skills remove <skill> [--tool codex]');
@@ -481,11 +596,11 @@ async function run() {
481
596
  const skills = getSelectedSkills(options.skills, options.all || !options.skills);
482
597
  try {
483
598
  const tools = resolveRequestedTools(options.tool);
484
- await installSkillsForTools(skills, tools, getInstallRoot(), { resetCodexNamespace: true });
599
+ await installSkillsForTools(skills, tools, getInstallRoot());
485
600
  console.log(chalk.green(`Installed ${skills.length} skills for ${tools.join(', ')}`));
486
- } catch (error) {
487
- console.error(chalk.red(error.message));
488
- process.exitCode = 1;
601
+ } catch (error) {
602
+ console.error(chalk.red(error.message));
603
+ process.exitCode = 1;
489
604
  }
490
605
  return;
491
606
  }
@@ -494,11 +609,11 @@ async function run() {
494
609
  const skills = getSelectedSkills(options.skills, options.all || !options.skills);
495
610
  try {
496
611
  const tools = resolveRequestedTools('auto');
497
- await installSkillsForTools(skills, tools, getInstallRoot(), { resetCodexNamespace: true });
612
+ await installSkillsForTools(skills, tools, getInstallRoot());
498
613
  console.log(chalk.green(`Auto-installed ${skills.length} skills for ${tools.join(', ')}`));
499
- } catch (error) {
500
- console.error(chalk.red(error.message));
501
- process.exitCode = 1;
614
+ } catch (error) {
615
+ console.error(chalk.red(error.message));
616
+ process.exitCode = 1;
502
617
  }
503
618
  return;
504
619
  }
@@ -506,37 +621,31 @@ async function run() {
506
621
  if (command === 'codex') {
507
622
  const skills = getSelectedSkills(options.skills, options.all || !options.skills);
508
623
  try {
509
- await installSkills(skills, 'codex', getInstallRoot(), { resetCodexNamespace: true });
624
+ await installSkills(skills, 'codex', getInstallRoot());
510
625
  console.log(chalk.green(`Synced ${skills.length} skills into Codex`));
511
626
  console.log(chalk.green(`Installed Codex command pack: ${COMMAND_PACK_NAME}`));
512
- } catch (error) {
513
- console.error(chalk.red(error.message));
514
- process.exitCode = 1;
627
+ } catch (error) {
628
+ console.error(chalk.red(error.message));
629
+ process.exitCode = 1;
515
630
  }
516
631
  return;
517
632
  }
518
633
 
519
- if (command === 'rules') {
520
- try {
521
- if (options.bundle) {
522
- process.env.PIG_SKILLS_RULE_BUNDLE = options.bundle;
523
- }
524
- if (options.profile) {
525
- process.env.PIG_SKILLS_RULE_PROFILE = options.profile;
526
- }
527
- if (options.skill) {
528
- process.env.PIG_SKILLS_RULE_SKILL = options.skill;
529
- }
530
- if (options.files) {
531
- process.env.PIG_SKILLS_CHANGED_FILES = options.files;
532
- }
533
- const selection = detectRulesBundle(
534
- process.env.INIT_CWD || process.cwd(),
535
- options.files ? options.files.split(',').map(item => item.trim()).filter(Boolean) : []
536
- );
537
- console.log(JSON.stringify(selection, null, 2));
538
- } catch (error) {
539
- console.error(chalk.red(error.message));
634
+ if (command === 'rules') {
635
+ try {
636
+ if (options.stage) {
637
+ process.env.PIG_SKILLS_RULE_STAGE = options.stage;
638
+ }
639
+ if (options.skill) {
640
+ process.env.PIG_SKILLS_RULE_SKILL = options.skill;
641
+ }
642
+ if (options.overlay) {
643
+ process.env.PIG_SKILLS_RULE_OVERLAY = options.overlay;
644
+ }
645
+ const selection = detectRulesStage(process.env.INIT_CWD || process.cwd());
646
+ console.log(JSON.stringify(selection, null, 2));
647
+ } catch (error) {
648
+ console.error(chalk.red(error.message));
540
649
  process.exitCode = 1;
541
650
  }
542
651
  return;
@@ -646,22 +755,22 @@ async function run() {
646
755
  return;
647
756
  }
648
757
 
649
- console.log(chalk.blue(info.name));
650
- console.log(chalk.gray(`Category: ${info.category}`));
651
- console.log(chalk.gray(`Description: ${info.description}`));
652
- console.log(chalk.gray(`Path: skills/${info.name}/SKILL.md`));
653
- return;
654
- }
758
+ console.log(chalk.blue(info.name));
759
+ console.log(chalk.gray(`Category: ${info.category}`));
760
+ console.log(chalk.gray(`Description: ${info.description}`));
761
+ console.log(chalk.gray(`Path: skills/${info.stage}/${info.name}/SKILL.md`));
762
+ return;
763
+ }
655
764
 
656
- if (command === 'update') {
657
- try {
765
+ if (command === 'update') {
766
+ try {
658
767
  await ensureRuntimeForInstall();
659
768
  const tools = resolveRequestedTools(options.tool);
660
- await installSkillsForTools(SKILLS.map(skill => skill.name), tools, getInstallRoot(), { resetCodexNamespace: true });
769
+ await installSkillsForTools(SKILLS.map(skill => skill.name), tools, getInstallRoot());
661
770
  console.log(chalk.green(`Updated ${SKILLS.length} skills for ${tools.join(', ')}`));
662
- } catch (error) {
663
- console.error(chalk.red(error.message));
664
- process.exitCode = 1;
771
+ } catch (error) {
772
+ console.error(chalk.red(error.message));
773
+ process.exitCode = 1;
665
774
  }
666
775
  return;
667
776
  }