@pigcloud/skills 1.0.10 → 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 +282 -188
  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]');
@@ -468,104 +583,83 @@ function printHelp() {
468
583
  console.log(' pig-skills update [--tool codex]');
469
584
  }
470
585
 
471
- async function ensureRuntimeForInstall() {
472
- if (!commandAvailable('npm')) {
473
- throw new Error('npm is not available. Install Node.js LTS first, then rerun the command.');
474
- }
475
-
476
- return { installed: false, skipped: false, npmPath: 'npm' };
477
- }
478
-
479
- async function run() {
480
- const { options, positionals } = parseArgs(process.argv.slice(2));
481
- const command = positionals[0];
586
+ async function run() {
587
+ const { options, positionals } = parseArgs(process.argv.slice(2));
588
+ const command = positionals[0];
482
589
 
483
590
  if (!command) {
484
591
  printHelp();
485
592
  return;
486
593
  }
487
594
 
488
- if (command === 'init') {
489
- const skills = getSelectedSkills(options.skills, options.all || !options.skills);
490
- try {
491
- await ensureRuntimeForInstall();
595
+ if (command === 'init') {
596
+ const skills = getSelectedSkills(options.skills, options.all || !options.skills);
597
+ try {
492
598
  const tools = resolveRequestedTools(options.tool);
493
- await installSkillsForTools(skills, tools, getInstallRoot(), { resetCodexNamespace: true });
599
+ await installSkillsForTools(skills, tools, getInstallRoot());
494
600
  console.log(chalk.green(`Installed ${skills.length} skills for ${tools.join(', ')}`));
495
- } catch (error) {
496
- console.error(chalk.red(error.message));
497
- process.exitCode = 1;
601
+ } catch (error) {
602
+ console.error(chalk.red(error.message));
603
+ process.exitCode = 1;
498
604
  }
499
605
  return;
500
606
  }
501
607
 
502
- if (command === 'auto') {
503
- const skills = getSelectedSkills(options.skills, options.all || !options.skills);
504
- try {
505
- await ensureRuntimeForInstall();
608
+ if (command === 'auto') {
609
+ const skills = getSelectedSkills(options.skills, options.all || !options.skills);
610
+ try {
506
611
  const tools = resolveRequestedTools('auto');
507
- await installSkillsForTools(skills, tools, getInstallRoot(), { resetCodexNamespace: true });
612
+ await installSkillsForTools(skills, tools, getInstallRoot());
508
613
  console.log(chalk.green(`Auto-installed ${skills.length} skills for ${tools.join(', ')}`));
509
- } catch (error) {
510
- console.error(chalk.red(error.message));
511
- process.exitCode = 1;
614
+ } catch (error) {
615
+ console.error(chalk.red(error.message));
616
+ process.exitCode = 1;
512
617
  }
513
618
  return;
514
619
  }
515
620
 
516
- if (command === 'codex') {
517
- const skills = getSelectedSkills(options.skills, options.all || !options.skills);
518
- try {
519
- await ensureRuntimeForInstall();
520
- await installSkills(skills, 'codex', getInstallRoot(), { resetCodexNamespace: true });
621
+ if (command === 'codex') {
622
+ const skills = getSelectedSkills(options.skills, options.all || !options.skills);
623
+ try {
624
+ await installSkills(skills, 'codex', getInstallRoot());
521
625
  console.log(chalk.green(`Synced ${skills.length} skills into Codex`));
522
- console.log(chalk.green(`Installed Codex command pack: ${COMMAND_PACK_NAME}`));
523
- } catch (error) {
524
- console.error(chalk.red(error.message));
525
- process.exitCode = 1;
626
+ console.log(chalk.green(`Installed Codex command pack: ${COMMAND_PACK_NAME}`));
627
+ } catch (error) {
628
+ console.error(chalk.red(error.message));
629
+ process.exitCode = 1;
526
630
  }
527
631
  return;
528
632
  }
529
633
 
530
- if (command === 'rules') {
531
- try {
532
- if (options.bundle) {
533
- process.env.PIG_SKILLS_RULE_BUNDLE = options.bundle;
534
- }
535
- if (options.profile) {
536
- process.env.PIG_SKILLS_RULE_PROFILE = options.profile;
537
- }
538
- if (options.skill) {
539
- process.env.PIG_SKILLS_RULE_SKILL = options.skill;
540
- }
541
- if (options.files) {
542
- process.env.PIG_SKILLS_CHANGED_FILES = options.files;
543
- }
544
- const selection = detectRulesBundle(
545
- process.env.INIT_CWD || process.cwd(),
546
- options.files ? options.files.split(',').map(item => item.trim()).filter(Boolean) : []
547
- );
548
- console.log(JSON.stringify(selection, null, 2));
549
- } catch (error) {
550
- 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));
551
649
  process.exitCode = 1;
552
650
  }
553
651
  return;
554
652
  }
555
653
 
556
- if (command === 'bootstrap') {
557
- try {
558
- const result = await ensureRuntimeForInstall();
559
- if (result.skipped) {
560
- console.log(chalk.yellow('Runtime bootstrap skipped by PIG_SKILLS_SKIP_RUNTIME_BOOTSTRAP.'));
561
- } else if (result.installed) {
562
- console.log(chalk.green('Node.js/npm runtime is ready.'));
563
- } else {
564
- console.log(chalk.green('Node.js/npm runtime is already available.'));
565
- }
566
- } catch (error) {
567
- console.error(chalk.red(error.message));
568
- process.exitCode = 1;
654
+ if (command === 'bootstrap') {
655
+ try {
656
+ if (!commandAvailable('npm')) {
657
+ throw new Error('npm is not available. Install Node.js LTS first, then rerun the command.');
658
+ }
659
+ console.log(chalk.green('Node.js/npm runtime is already available.'));
660
+ } catch (error) {
661
+ console.error(chalk.red(error.message));
662
+ process.exitCode = 1;
569
663
  }
570
664
  return;
571
665
  }
@@ -661,22 +755,22 @@ async function run() {
661
755
  return;
662
756
  }
663
757
 
664
- console.log(chalk.blue(info.name));
665
- console.log(chalk.gray(`Category: ${info.category}`));
666
- console.log(chalk.gray(`Description: ${info.description}`));
667
- console.log(chalk.gray(`Path: skills/${info.name}/SKILL.md`));
668
- return;
669
- }
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
+ }
670
764
 
671
- if (command === 'update') {
672
- try {
765
+ if (command === 'update') {
766
+ try {
673
767
  await ensureRuntimeForInstall();
674
768
  const tools = resolveRequestedTools(options.tool);
675
- await installSkillsForTools(SKILLS.map(skill => skill.name), tools, getInstallRoot(), { resetCodexNamespace: true });
769
+ await installSkillsForTools(SKILLS.map(skill => skill.name), tools, getInstallRoot());
676
770
  console.log(chalk.green(`Updated ${SKILLS.length} skills for ${tools.join(', ')}`));
677
- } catch (error) {
678
- console.error(chalk.red(error.message));
679
- process.exitCode = 1;
771
+ } catch (error) {
772
+ console.error(chalk.red(error.message));
773
+ process.exitCode = 1;
680
774
  }
681
775
  return;
682
776
  }