@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.
- package/CHANGELOG.md +25 -20
- package/README.en.md +41 -75
- package/README.md +26 -39
- package/bin/cli.js +260 -151
- package/bin/rules-loader.js +271 -484
- package/codex-commands/README.md +25 -23
- package/codex-commands/commands/analyze.md +21 -22
- package/codex-commands/commands/build.md +22 -22
- package/codex-commands/commands/design.md +21 -22
- package/codex-commands/commands/distill.md +21 -21
- package/codex-commands/commands/doc.md +21 -22
- package/codex-commands/commands/infra.md +21 -21
- package/codex-commands/commands/init.md +20 -20
- package/codex-commands/commands/kb.md +21 -20
- package/codex-commands/commands/perf.md +21 -21
- package/codex-commands/commands/prd.md +21 -22
- package/codex-commands/commands/review.md +21 -22
- package/codex-commands/commands/security.md +21 -22
- package/codex-commands/commands/test.md +21 -21
- package/codex-commands/commands/workflow.md +21 -20
- package/package.json +5 -2
- package/rules/core/index.md +26 -41
- package/rules/delivery/index.md +25 -0
- package/rules/design/index.md +25 -0
- package/rules/discovery/index.md +25 -0
- package/rules/implementation/index.md +25 -0
- package/rules/index.md +24 -39
- package/rules/overlays/index.md +19 -19
- package/rules/overlays/pig-cloud.md +20 -45
- package/rules/shared/index.md +25 -0
- package/rules/skill-stage-map.json +26 -0
- package/rules/stages.json +48 -0
- package/rules/validation/index.md +25 -0
- package/scripts/add-skill-reference-nav.js +3 -0
- package/scripts/bootstrap-skill-specs.js +96 -0
- package/scripts/ci-validator.sh +51 -114
- package/scripts/generate-skill-prompt-library.js +3 -0
- package/scripts/golden-prompt-suite.current.js +211 -0
- package/scripts/migrate-skill-packages.js +309 -0
- package/scripts/run-golden-replays.js +110 -79
- package/scripts/validate-rules.js +128 -125
- package/scripts/validate-skill-replay-signals.js +45 -57
- package/scripts/validate-skill-shapes.js +153 -127
- package/scripts/validate-skill-stop-rules.js +54 -46
- package/skills/01-discovery/ambiguity-detection/SKILL.md +30 -0
- package/skills/01-discovery/ambiguity-detection/assets/golden-prompt-suite.current.js +22 -0
- package/skills/01-discovery/ambiguity-detection/references/README.md +17 -0
- package/skills/01-discovery/ambiguity-detection/references/cases.md +26 -0
- package/skills/01-discovery/ambiguity-detection/references/prompt-template.md +18 -0
- package/skills/01-discovery/ambiguity-detection/skill-spec.json +26 -0
- package/skills/01-discovery/business-analysis/SKILL.md +30 -0
- package/skills/01-discovery/business-analysis/assets/golden-prompt-suite.current.js +22 -0
- package/skills/01-discovery/business-analysis/references/README.md +17 -0
- package/skills/01-discovery/business-analysis/references/cases.md +26 -0
- package/skills/01-discovery/business-analysis/references/prompt-template.md +18 -0
- package/skills/01-discovery/business-analysis/skill-spec.json +26 -0
- package/skills/01-discovery/impact-analysis/SKILL.md +30 -0
- package/skills/01-discovery/impact-analysis/assets/golden-prompt-suite.current.js +22 -0
- package/skills/01-discovery/impact-analysis/references/README.md +17 -0
- package/skills/01-discovery/impact-analysis/references/cases.md +26 -0
- package/skills/01-discovery/impact-analysis/references/prompt-template.md +18 -0
- package/skills/01-discovery/impact-analysis/skill-spec.json +26 -0
- package/skills/01-discovery/requirement-discovery/SKILL.md +30 -0
- package/skills/01-discovery/requirement-discovery/assets/golden-prompt-suite.current.js +24 -0
- package/skills/01-discovery/requirement-discovery/references/README.md +17 -0
- package/skills/01-discovery/requirement-discovery/references/cases.md +28 -0
- package/skills/01-discovery/requirement-discovery/references/prompt-template.md +18 -0
- package/skills/01-discovery/requirement-discovery/skill-spec.json +26 -0
- package/skills/02-design/api-design/SKILL.md +29 -0
- package/skills/02-design/api-design/assets/golden-prompt-suite.current.js +22 -0
- package/skills/02-design/api-design/references/README.md +17 -0
- package/skills/02-design/api-design/references/cases.md +26 -0
- package/skills/02-design/api-design/references/prompt-template.md +18 -0
- package/skills/02-design/api-design/skill-spec.json +25 -0
- package/skills/02-design/architecture-design/SKILL.md +29 -0
- package/skills/02-design/architecture-design/assets/golden-prompt-suite.current.js +22 -0
- package/skills/02-design/architecture-design/references/README.md +17 -0
- package/skills/02-design/architecture-design/references/cases.md +26 -0
- package/skills/02-design/architecture-design/references/prompt-template.md +18 -0
- package/skills/02-design/architecture-design/skill-spec.json +25 -0
- package/skills/02-design/database-design/SKILL.md +29 -0
- package/skills/02-design/database-design/assets/golden-prompt-suite.current.js +22 -0
- package/skills/02-design/database-design/references/README.md +17 -0
- package/skills/02-design/database-design/references/cases.md +26 -0
- package/skills/02-design/database-design/references/prompt-template.md +18 -0
- package/skills/02-design/database-design/skill-spec.json +25 -0
- package/skills/02-design/task-breakdown/SKILL.md +29 -0
- package/skills/02-design/task-breakdown/assets/golden-prompt-suite.current.js +22 -0
- package/skills/02-design/task-breakdown/references/README.md +17 -0
- package/skills/02-design/task-breakdown/references/cases.md +26 -0
- package/skills/02-design/task-breakdown/references/prompt-template.md +18 -0
- package/skills/02-design/task-breakdown/skill-spec.json +25 -0
- package/skills/03-implementation/backend-development/SKILL.md +29 -0
- package/skills/03-implementation/backend-development/assets/golden-prompt-suite.current.js +22 -0
- package/skills/03-implementation/backend-development/references/README.md +17 -0
- package/skills/03-implementation/backend-development/references/cases.md +26 -0
- package/skills/03-implementation/backend-development/references/prompt-template.md +18 -0
- package/skills/03-implementation/backend-development/skill-spec.json +25 -0
- package/skills/03-implementation/bug-fix/SKILL.md +29 -0
- package/skills/03-implementation/bug-fix/assets/golden-prompt-suite.current.js +22 -0
- package/skills/03-implementation/bug-fix/references/README.md +17 -0
- package/skills/03-implementation/bug-fix/references/cases.md +26 -0
- package/skills/03-implementation/bug-fix/references/prompt-template.md +18 -0
- package/skills/03-implementation/bug-fix/skill-spec.json +25 -0
- package/skills/03-implementation/database-change/SKILL.md +29 -0
- package/skills/03-implementation/database-change/assets/golden-prompt-suite.current.js +22 -0
- package/skills/03-implementation/database-change/references/README.md +17 -0
- package/skills/03-implementation/database-change/references/cases.md +26 -0
- package/skills/03-implementation/database-change/references/prompt-template.md +18 -0
- package/skills/03-implementation/database-change/skill-spec.json +25 -0
- package/skills/03-implementation/frontend-development/SKILL.md +29 -0
- package/skills/03-implementation/frontend-development/assets/golden-prompt-suite.current.js +22 -0
- package/skills/03-implementation/frontend-development/references/README.md +17 -0
- package/skills/03-implementation/frontend-development/references/cases.md +26 -0
- package/skills/03-implementation/frontend-development/references/prompt-template.md +18 -0
- package/skills/03-implementation/frontend-development/skill-spec.json +25 -0
- package/skills/04-validation/code-review/SKILL.md +29 -0
- package/skills/04-validation/code-review/assets/golden-prompt-suite.current.js +22 -0
- package/skills/04-validation/code-review/references/README.md +17 -0
- package/skills/04-validation/code-review/references/cases.md +26 -0
- package/skills/04-validation/code-review/references/prompt-template.md +18 -0
- package/skills/04-validation/code-review/skill-spec.json +25 -0
- package/skills/04-validation/performance-review/SKILL.md +29 -0
- package/skills/04-validation/performance-review/assets/golden-prompt-suite.current.js +22 -0
- package/skills/04-validation/performance-review/references/README.md +17 -0
- package/skills/04-validation/performance-review/references/cases.md +26 -0
- package/skills/04-validation/performance-review/references/prompt-template.md +18 -0
- package/skills/04-validation/performance-review/skill-spec.json +25 -0
- package/skills/04-validation/regression-check/SKILL.md +29 -0
- package/skills/04-validation/regression-check/assets/golden-prompt-suite.current.js +22 -0
- package/skills/04-validation/regression-check/references/README.md +17 -0
- package/skills/04-validation/regression-check/references/cases.md +26 -0
- package/skills/04-validation/regression-check/references/prompt-template.md +18 -0
- package/skills/04-validation/regression-check/skill-spec.json +25 -0
- package/skills/04-validation/security-review/SKILL.md +29 -0
- package/skills/04-validation/security-review/assets/golden-prompt-suite.current.js +22 -0
- package/skills/04-validation/security-review/references/README.md +17 -0
- package/skills/04-validation/security-review/references/cases.md +26 -0
- package/skills/04-validation/security-review/references/prompt-template.md +18 -0
- package/skills/04-validation/security-review/skill-spec.json +25 -0
- package/skills/04-validation/unit-test/SKILL.md +29 -0
- package/skills/04-validation/unit-test/assets/golden-prompt-suite.current.js +22 -0
- package/skills/04-validation/unit-test/references/README.md +17 -0
- package/skills/04-validation/unit-test/references/cases.md +26 -0
- package/skills/04-validation/unit-test/references/prompt-template.md +18 -0
- package/skills/04-validation/unit-test/skill-spec.json +25 -0
- package/skills/05-delivery/change-log/SKILL.md +29 -0
- package/skills/05-delivery/change-log/assets/golden-prompt-suite.current.js +22 -0
- package/skills/05-delivery/change-log/references/README.md +17 -0
- package/skills/05-delivery/change-log/references/cases.md +26 -0
- package/skills/05-delivery/change-log/references/prompt-template.md +18 -0
- package/skills/05-delivery/change-log/skill-spec.json +25 -0
- package/skills/05-delivery/deployment-guide/SKILL.md +29 -0
- package/skills/05-delivery/deployment-guide/assets/golden-prompt-suite.current.js +22 -0
- package/skills/05-delivery/deployment-guide/references/README.md +17 -0
- package/skills/05-delivery/deployment-guide/references/cases.md +26 -0
- package/skills/05-delivery/deployment-guide/references/prompt-template.md +18 -0
- package/skills/05-delivery/deployment-guide/skill-spec.json +25 -0
- package/skills/05-delivery/release-check/SKILL.md +29 -0
- package/skills/05-delivery/release-check/assets/golden-prompt-suite.current.js +22 -0
- package/skills/05-delivery/release-check/references/README.md +17 -0
- package/skills/05-delivery/release-check/references/cases.md +26 -0
- package/skills/05-delivery/release-check/references/prompt-template.md +18 -0
- package/skills/05-delivery/release-check/skill-spec.json +25 -0
- package/skills/05-delivery/release-validation/SKILL.md +29 -0
- package/skills/05-delivery/release-validation/assets/golden-prompt-suite.current.js +22 -0
- package/skills/05-delivery/release-validation/references/README.md +17 -0
- package/skills/05-delivery/release-validation/references/cases.md +26 -0
- package/skills/05-delivery/release-validation/references/prompt-template.md +18 -0
- package/skills/05-delivery/release-validation/skill-spec.json +25 -0
- package/skills/shared/codebase-learning/SKILL.md +29 -0
- package/skills/shared/codebase-learning/assets/golden-prompt-suite.current.js +22 -0
- package/skills/shared/codebase-learning/references/README.md +17 -0
- package/skills/shared/codebase-learning/references/cases.md +26 -0
- package/skills/shared/codebase-learning/references/prompt-template.md +18 -0
- package/skills/shared/codebase-learning/skill-spec.json +25 -0
- package/skills/shared/evidence-collector/SKILL.md +29 -0
- package/skills/shared/evidence-collector/assets/golden-prompt-suite.current.js +22 -0
- package/skills/shared/evidence-collector/references/README.md +17 -0
- package/skills/shared/evidence-collector/references/cases.md +26 -0
- package/skills/shared/evidence-collector/references/prompt-template.md +18 -0
- package/skills/shared/evidence-collector/skill-spec.json +25 -0
- package/skills/shared/framework-guide/SKILL.md +28 -0
- package/skills/shared/framework-guide/assets/golden-prompt-suite.current.js +22 -0
- package/skills/shared/framework-guide/references/README.md +17 -0
- package/skills/shared/framework-guide/references/cases.md +26 -0
- package/skills/shared/framework-guide/references/prompt-template.md +18 -0
- package/skills/shared/framework-guide/skill-spec.json +24 -0
- package/rules/bundles.json +0 -358
- package/rules/coding/analysis.md +0 -27
- package/rules/coding/backend/cache-invalidation.md +0 -30
- package/rules/coding/backend/cache-keying.md +0 -30
- package/rules/coding/backend/cache.md +0 -37
- package/rules/coding/backend/database.md +0 -32
- package/rules/coding/backend/feign.md +0 -30
- package/rules/coding/backend/index.md +0 -42
- package/rules/coding/backend/query.md +0 -32
- package/rules/coding/backend/remote.md +0 -33
- package/rules/coding/backend/transaction-boundary.md +0 -30
- package/rules/coding/backend/transaction-rollback.md +0 -30
- package/rules/coding/backend/transaction.md +0 -38
- package/rules/coding/boundary.md +0 -25
- package/rules/coding/implementation.md +0 -26
- package/rules/coding/index.md +0 -38
- package/rules/coding/scaffold.md +0 -28
- package/rules/coding/testing.md +0 -29
- package/rules/coding/validation.md +0 -29
- package/rules/core/code-quality.md +0 -30
- package/rules/core/evidence.md +0 -26
- package/rules/core/interface.md +0 -26
- package/rules/core/iteration.md +0 -26
- package/rules/core/layer-boundary.md +0 -25
- package/rules/core/logging.md +0 -26
- package/rules/core/security.md +0 -26
- package/rules/core/task-boundary.md +0 -27
- package/rules/docs/api.md +0 -34
- package/rules/docs/capture-summary.md +0 -29
- package/rules/docs/capture.md +0 -34
- package/rules/docs/contract.md +0 -30
- package/rules/docs/decision-log.md +0 -32
- package/rules/docs/examples.md +0 -28
- package/rules/docs/index.md +0 -49
- package/rules/docs/reference.md +0 -32
- package/rules/overlays/pig-cloud/controller.md +0 -33
- package/rules/overlays/pig-cloud/dto-vo.md +0 -33
- package/rules/overlays/pig-cloud/entity.md +0 -32
- package/rules/overlays/pig-cloud/exception.md +0 -32
- package/rules/overlays/pig-cloud/layering.md +0 -31
- package/rules/overlays/pig-cloud/mapper.md +0 -32
- package/rules/overlays/pig-cloud/query-style.md +0 -32
- package/rules/overlays/pig-cloud/rest-response.md +0 -33
- package/rules/overlays/pig-cloud/service.md +0 -33
- package/rules/overlays/pig-cloud/transactions.md +0 -32
- package/rules/overlays/pig-cloud/validation.md +0 -33
- package/rules/product/acceptance.md +0 -25
- package/rules/product/briefing.md +0 -27
- package/rules/product/index.md +0 -36
- package/rules/product/intake.md +0 -27
- package/rules/product/modeling.md +0 -25
- package/rules/product/project-context.md +0 -29
- package/rules/review/code.md +0 -35
- package/rules/review/evidence.md +0 -31
- package/rules/review/index.md +0 -50
- package/rules/review/java.md +0 -42
- package/rules/review/performance.md +0 -38
- package/rules/review/rubric.md +0 -28
- package/rules/review/security.md +0 -38
- package/rules/review/ts.md +0 -33
- package/rules/review/vue.md +0 -33
- package/rules/skill-profile-map.json +0 -59
- package/rules/skill-profile-map.md +0 -29
- package/rules/workflow/handoff.md +0 -25
- package/rules/workflow/index.md +0 -37
- package/rules/workflow/refinement.md +0 -29
- package/rules/workflow/router.md +0 -25
- package/rules/workflow/selection.md +0 -25
- package/rules/workflow/stop.md +0 -25
- package/skills/api-contract-docs/SKILL.md +0 -77
- package/skills/business-fact-extraction/SKILL.md +0 -337
- package/skills/business-fact-extraction/scripts/write-knowledge-base.js +0 -228
- package/skills/code-review/SKILL.md +0 -136
- package/skills/code-review/references/findings-template.md +0 -51
- package/skills/code-review/references/performance-checklist.md +0 -213
- package/skills/code-review/references/rubric.md +0 -232
- package/skills/code-review/references/rules.md +0 -32
- package/skills/code-review/references/security-checklist.md +0 -178
- package/skills/code-review/references/stack-notes.md +0 -25
- package/skills/code-review/references/template-review.md +0 -39
- package/skills/code-review/scripts/lint-code-review.mjs +0 -431
- package/skills/domain-modeling/SKILL.md +0 -81
- package/skills/domain-modeling/references/README.md +0 -134
- package/skills/domain-modeling/references/distillation-checklist.md +0 -44
- package/skills/domain-modeling/references/test-cases-template.md +0 -128
- package/skills/environment-deploy/SKILL.md +0 -81
- package/skills/feature-build/SKILL.md +0 -122
- package/skills/feature-build/references/coding-checklist.md +0 -97
- package/skills/feature-build/references/comment-specification.md +0 -89
- package/skills/knowledge-capture/SKILL.md +0 -93
- package/skills/performance-audit/SKILL.md +0 -118
- package/skills/project-bootstrap/SKILL.md +0 -81
- package/skills/references/anti-rationalization.md +0 -144
- package/skills/references/business-fact-extraction.md +0 -415
- package/skills/references/engineering-delivery-method.md +0 -64
- package/skills/references/engineering-delivery-template.md +0 -81
- package/skills/references/golden-prompt-suite.js +0 -436
- package/skills/references/golden-prompt-suite.md +0 -33
- package/skills/references/project-requirement-alignment.md +0 -42
- package/skills/references/rule-loading-map.md +0 -117
- package/skills/references/skill-authoring-standard.md +0 -74
- package/skills/references/skill-boundary-template.md +0 -71
- package/skills/references/skill-enhanced-template.md +0 -103
- package/skills/references/skill-reference-matrix.md +0 -62
- package/skills/security-audit/SKILL.md +0 -119
- package/skills/spec-refinement/SKILL.md +0 -149
- package/skills/technical-design/SKILL.md +0 -106
- package/skills/technical-design/references/solid-checklist.md +0 -199
- package/skills/test-design/SKILL.md +0 -92
- package/skills/workflow-router/SKILL.md +0 -86
package/bin/rules-loader.js
CHANGED
|
@@ -1,484 +1,271 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const PACKAGE_ROOT = path.join(__dirname, '..');
|
|
7
|
-
const RULES_ROOT = path.join(PACKAGE_ROOT, 'rules');
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const SKILLS_ROOT = path.join(PACKAGE_ROOT, 'skills');
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
'
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function hasTypeScriptSignals(cwd) {
|
|
275
|
-
return [
|
|
276
|
-
'tsconfig.json',
|
|
277
|
-
'tsconfig.app.json',
|
|
278
|
-
'tsconfig.node.json',
|
|
279
|
-
'src',
|
|
280
|
-
'frontend/src',
|
|
281
|
-
'src/main.ts',
|
|
282
|
-
'src/env.d.ts',
|
|
283
|
-
'frontend/tsconfig.json'
|
|
284
|
-
].some((hint) => existsInRoot(cwd, hint));
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function detectReviewAutoOverlayProfiles(cwd, registry, changedFilesInput = []) {
|
|
288
|
-
const profiles = [];
|
|
289
|
-
const reviewBundle = registry[REVIEW_BUNDLE_NAME] || {};
|
|
290
|
-
const reviewProfiles = reviewBundle.profiles || {};
|
|
291
|
-
const changedFiles = normalizeChangedFiles(changedFilesInput);
|
|
292
|
-
|
|
293
|
-
if (changedFiles.length > 0) {
|
|
294
|
-
if (reviewProfiles['code-java'] && (
|
|
295
|
-
hasChangedFile(changedFiles, (filePath) => /\.(java|kt|xml)$/i.test(filePath))
|
|
296
|
-
|| hasChangedFile(changedFiles, (filePath) => /(^|\/)(pom\.xml|build\.gradle(\.kts)?|mvnw|gradlew)$/i.test(filePath))
|
|
297
|
-
|| hasChangedFile(changedFiles, (filePath) => /(^|\/)(src\/main\/java|src\/test\/java)(\/|$)/i.test(filePath))
|
|
298
|
-
)) {
|
|
299
|
-
profiles.push('code-java');
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (reviewProfiles['code-vue'] && (
|
|
303
|
-
hasChangedFile(changedFiles, (filePath) => /\.vue$/i.test(filePath))
|
|
304
|
-
|| hasChangedFile(changedFiles, (filePath) => /(^|\/)(src\/main\.(ts|js)|src\/App\.vue|src\/components|src\/views|frontend\/)/i.test(filePath))
|
|
305
|
-
|| hasChangedFile(changedFiles, (filePath) => /(^|\/)(vite\.config\.(ts|js)|vue\.config\.js)$/i.test(filePath))
|
|
306
|
-
)) {
|
|
307
|
-
profiles.push('code-vue');
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (reviewProfiles['code-ts'] && (
|
|
311
|
-
hasChangedFile(changedFiles, (filePath) => /\.(ts|tsx|d\.ts)$/i.test(filePath))
|
|
312
|
-
|| hasChangedFile(changedFiles, (filePath) => /(^|\/)(tsconfig(\.[^.]+)?\.json|vite\.config\.ts|eslint\.config\.ts|src\/env\.d\.ts)$/i.test(filePath))
|
|
313
|
-
|| hasChangedFile(changedFiles, (filePath) => /(^|\/)(src\/store|src\/stores|src\/state|frontend\/src\/store|frontend\/src\/stores|frontend\/src\/state)(\/|$)/i.test(filePath))
|
|
314
|
-
)) {
|
|
315
|
-
profiles.push('code-ts');
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return profiles;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if (hasJavaSignals(cwd) && reviewProfiles['code-java']) {
|
|
322
|
-
profiles.push('code-java');
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
if (hasVueSignals(cwd) && reviewProfiles['code-vue']) {
|
|
326
|
-
profiles.push('code-vue');
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (hasTypeScriptSignals(cwd) && reviewProfiles['code-ts']) {
|
|
330
|
-
profiles.push('code-ts');
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return profiles;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function parseBundleOverride(override) {
|
|
337
|
-
if (!override) {
|
|
338
|
-
return { bundle: '', profile: '' };
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (override.includes(':')) {
|
|
342
|
-
const [bundle, profile] = override.split(':', 2);
|
|
343
|
-
return { bundle, profile };
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if (override.includes('/')) {
|
|
347
|
-
const [bundle, profile] = override.split('/', 2);
|
|
348
|
-
return { bundle, profile };
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return { bundle: override, profile: '' };
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
function detectRulesBundle(cwd = process.cwd(), changedFilesInput = []) {
|
|
355
|
-
const registry = readRegistry();
|
|
356
|
-
const skillProfileMap = readSkillProfileMap();
|
|
357
|
-
const override = String(process.env.PIG_SKILLS_RULE_BUNDLE || process.env.PIG_SKILLS_RULES_BUNDLE || '').trim();
|
|
358
|
-
const profileOverride = String(process.env.PIG_SKILLS_RULE_PROFILE || '').trim();
|
|
359
|
-
const skillOverride = String(process.env.PIG_SKILLS_RULE_SKILL || '').trim();
|
|
360
|
-
const overlayOverride = String(process.env.PIG_SKILLS_RULE_OVERLAY || '').trim();
|
|
361
|
-
const changedFiles = normalizeChangedFiles(
|
|
362
|
-
changedFilesInput.length > 0
|
|
363
|
-
? changedFilesInput
|
|
364
|
-
: process.env.PIG_SKILLS_CHANGED_FILES || ''
|
|
365
|
-
);
|
|
366
|
-
|
|
367
|
-
if (shouldValidateSkillProfiles()) {
|
|
368
|
-
validateSkillProfileConsistency();
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
function resolveBundleSelection(bundleName, profileName = '') {
|
|
372
|
-
const layers = [];
|
|
373
|
-
let baseLayer = null;
|
|
374
|
-
const seenLayers = new Set();
|
|
375
|
-
|
|
376
|
-
function addLayer(bundle, profile, markAsBase = false) {
|
|
377
|
-
const layer = getLayer(registry, bundle, profile);
|
|
378
|
-
if (!layer) return null;
|
|
379
|
-
const key = `${layer.bundle}:${layer.profile || ''}`;
|
|
380
|
-
if (seenLayers.has(key)) {
|
|
381
|
-
if (markAsBase) baseLayer = layer;
|
|
382
|
-
return layer;
|
|
383
|
-
}
|
|
384
|
-
seenLayers.add(key);
|
|
385
|
-
layers.push(layer);
|
|
386
|
-
if (markAsBase) baseLayer = layer;
|
|
387
|
-
return layer;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if (bundleName === CORE_BUNDLE_NAME) {
|
|
391
|
-
addLayer(CORE_BUNDLE_NAME, CORE_PROFILE_NAME, true);
|
|
392
|
-
} else {
|
|
393
|
-
addLayer(CORE_BUNDLE_NAME, CORE_PROFILE_NAME);
|
|
394
|
-
addLayer(bundleName, profileName, true);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
if (bundleName === REVIEW_BUNDLE_NAME) {
|
|
398
|
-
for (const autoProfile of detectReviewAutoOverlayProfiles(cwd, registry, changedFiles)) {
|
|
399
|
-
addLayer(REVIEW_BUNDLE_NAME, autoProfile);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
if (overlayOverride && registry[overlayOverride]) {
|
|
404
|
-
const overlayProfile = profileOverride && registry[overlayOverride].profiles && registry[overlayOverride].profiles[profileOverride]
|
|
405
|
-
? profileOverride
|
|
406
|
-
: (registry[overlayOverride].profiles && registry[overlayOverride].profiles[CORE_PROFILE_NAME] ? CORE_PROFILE_NAME : '');
|
|
407
|
-
addLayer(overlayOverride, overlayProfile);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (layers.length === 0) return null;
|
|
411
|
-
return combineLayers(layers, {
|
|
412
|
-
bundle: bundleName,
|
|
413
|
-
profile: profileName || null,
|
|
414
|
-
baseLayer,
|
|
415
|
-
source: 'environment override'
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
if (override) {
|
|
420
|
-
const parsed = parseBundleOverride(override);
|
|
421
|
-
if (registry[parsed.bundle]) {
|
|
422
|
-
const resolved = resolveBundleSelection(parsed.bundle, profileOverride || parsed.profile || '');
|
|
423
|
-
if (resolved) return resolved;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (skillOverride) {
|
|
428
|
-
const mapped = skillProfileMap[skillOverride] || {};
|
|
429
|
-
const declaredProfile = readSkillRuleProfile(skillOverride);
|
|
430
|
-
const selectedProfile = profileOverride || mapped.profile || declaredProfile || '';
|
|
431
|
-
const selectedBundle = mapped.bundle || readSkillRuleBundle(skillOverride) || findBundleByProfile(registry, selectedProfile);
|
|
432
|
-
const resolved = selectedBundle ? resolveBundleSelection(selectedBundle, selectedProfile) : null;
|
|
433
|
-
if (resolved) {
|
|
434
|
-
return {
|
|
435
|
-
...resolved,
|
|
436
|
-
skill: skillOverride,
|
|
437
|
-
source: declaredProfile ? 'skill declaration' : 'skill mapping'
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
const bundle = hasCodingSignals(cwd) ? 'coding' : CORE_BUNDLE_NAME;
|
|
443
|
-
const bundleConfig = registry[bundle];
|
|
444
|
-
const profileName = bundle === CORE_BUNDLE_NAME
|
|
445
|
-
? CORE_PROFILE_NAME
|
|
446
|
-
: (profileOverride && bundleConfig && bundleConfig.profiles && bundleConfig.profiles[profileOverride]
|
|
447
|
-
? profileOverride
|
|
448
|
-
: (bundleConfig && bundleConfig.profiles && bundleConfig.profiles.analysis ? 'analysis' : 'core'));
|
|
449
|
-
const selection = resolveBundleSelection(bundle, profileName || '');
|
|
450
|
-
|
|
451
|
-
if (!selection) {
|
|
452
|
-
return combineLayers(
|
|
453
|
-
[getLayer(registry, CORE_BUNDLE_NAME, CORE_PROFILE_NAME)].filter(Boolean),
|
|
454
|
-
{
|
|
455
|
-
bundle: CORE_BUNDLE_NAME,
|
|
456
|
-
profile: CORE_PROFILE_NAME,
|
|
457
|
-
skill: skillOverride || null,
|
|
458
|
-
source: 'workspace detection'
|
|
459
|
-
}
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
...selection,
|
|
465
|
-
skill: skillOverride || null,
|
|
466
|
-
source: 'workspace detection'
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (require.main === module) {
|
|
471
|
-
const cwd = process.argv[2] ? path.resolve(process.argv[2]) : process.cwd();
|
|
472
|
-
process.stdout.write(`${JSON.stringify(detectRulesBundle(cwd), null, 2)}\n`);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
module.exports = {
|
|
476
|
-
detectRulesBundle,
|
|
477
|
-
readRegistry,
|
|
478
|
-
readSkillProfileMap,
|
|
479
|
-
readSkillRuleProfile,
|
|
480
|
-
readSkillRuleBundle,
|
|
481
|
-
validateSkillProfileConsistency,
|
|
482
|
-
shouldValidateSkillProfiles,
|
|
483
|
-
findBundleByProfile
|
|
484
|
-
};
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const PACKAGE_ROOT = path.join(__dirname, '..');
|
|
7
|
+
const RULES_ROOT = path.join(PACKAGE_ROOT, 'rules');
|
|
8
|
+
const STAGE_REGISTRY_PATH = path.join(RULES_ROOT, 'stages.json');
|
|
9
|
+
const SKILL_STAGE_MAP_PATH = path.join(RULES_ROOT, 'skill-stage-map.json');
|
|
10
|
+
const SKILLS_ROOT = path.join(PACKAGE_ROOT, 'skills');
|
|
11
|
+
const CORE_STAGE_NAME = 'core';
|
|
12
|
+
const OVERLAY_STAGE_NAME = 'overlays';
|
|
13
|
+
|
|
14
|
+
function readRegistry() {
|
|
15
|
+
return JSON.parse(fs.readFileSync(STAGE_REGISTRY_PATH, 'utf8'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function readSkillStageMap() {
|
|
19
|
+
return JSON.parse(fs.readFileSync(SKILL_STAGE_MAP_PATH, 'utf8'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function readSkillStage(skillName) {
|
|
23
|
+
return readSkillStageMap()[skillName]?.stage || null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function listSkillDirectories() {
|
|
27
|
+
if (!fs.existsSync(SKILLS_ROOT)) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const results = [];
|
|
32
|
+
|
|
33
|
+
function walk(dir) {
|
|
34
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
35
|
+
if (entry.name === 'references') {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const fullPath = path.join(dir, entry.name);
|
|
40
|
+
if (entry.isDirectory()) {
|
|
41
|
+
const skillFile = path.join(fullPath, 'SKILL.md');
|
|
42
|
+
if (fs.existsSync(skillFile)) {
|
|
43
|
+
results.push(path.relative(SKILLS_ROOT, fullPath).replace(/\\/g, '/'));
|
|
44
|
+
}
|
|
45
|
+
walk(fullPath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
walk(SKILLS_ROOT);
|
|
51
|
+
return results.sort();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function readSkillName(skillDir) {
|
|
55
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
56
|
+
if (!fs.existsSync(skillFile)) {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const content = fs.readFileSync(skillFile, 'utf8');
|
|
61
|
+
const match = content.match(/^name:\s*(.+)$/m);
|
|
62
|
+
return match ? match[1].trim() : '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function validateSkillStageConsistency() {
|
|
66
|
+
const registry = readRegistry();
|
|
67
|
+
const stageMap = readSkillStageMap();
|
|
68
|
+
const skillDirs = listSkillDirectories();
|
|
69
|
+
const issues = [];
|
|
70
|
+
|
|
71
|
+
const mappedSkills = Object.keys(stageMap).sort();
|
|
72
|
+
const discoveredSkillNames = [];
|
|
73
|
+
|
|
74
|
+
for (const skillPath of skillDirs) {
|
|
75
|
+
const skillName = readSkillName(path.join(SKILLS_ROOT, skillPath));
|
|
76
|
+
if (!skillName) {
|
|
77
|
+
issues.push(`Missing skill name in: ${skillPath}`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
discoveredSkillNames.push(skillName);
|
|
82
|
+
const mapping = stageMap[skillName];
|
|
83
|
+
if (!mapping) {
|
|
84
|
+
issues.push(`Missing stage mapping for skill: ${skillPath}`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const stageName = mapping.stage;
|
|
89
|
+
const stage = registry[stageName];
|
|
90
|
+
if (!stage) {
|
|
91
|
+
issues.push(`Unknown stage mapped for ${skillPath}: ${stageName}`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const files = new Set(stage.files || []);
|
|
96
|
+
if (stage.entry) {
|
|
97
|
+
files.add(stage.entry);
|
|
98
|
+
}
|
|
99
|
+
for (const relativePath of files) {
|
|
100
|
+
const filePath = path.join(RULES_ROOT, relativePath);
|
|
101
|
+
if (!fs.existsSync(filePath)) {
|
|
102
|
+
issues.push(`Missing stage file for ${skillPath}: ${relativePath}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const mappedSkill of mappedSkills) {
|
|
108
|
+
if (!discoveredSkillNames.includes(mappedSkill)) {
|
|
109
|
+
issues.push(`Mapping exists for missing skill directory: ${mappedSkill}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (issues.length > 0) {
|
|
114
|
+
const error = new Error(`Rule stage consistency check failed:\n- ${issues.join('\n- ')}`);
|
|
115
|
+
error.issues = issues;
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
skillCount: skillDirs.length,
|
|
121
|
+
mappedSkillCount: mappedSkills.length
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function normalizeStageName(stageName) {
|
|
126
|
+
return String(stageName || '').trim();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function getLayer(registry, stageName, variantName = '') {
|
|
130
|
+
const stage = registry[stageName];
|
|
131
|
+
if (!stage) return null;
|
|
132
|
+
|
|
133
|
+
if (variantName) {
|
|
134
|
+
const variant = stage.variants && stage.variants[variantName];
|
|
135
|
+
if (!variant) return null;
|
|
136
|
+
return {
|
|
137
|
+
stage: stageName,
|
|
138
|
+
variant: variantName,
|
|
139
|
+
entry: variant.entry,
|
|
140
|
+
files: variant.files,
|
|
141
|
+
description: variant.description || stage.description
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
stage: stageName,
|
|
147
|
+
variant: null,
|
|
148
|
+
entry: stage.entry,
|
|
149
|
+
files: stage.files,
|
|
150
|
+
description: stage.description
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function combineLayers(layers, meta = {}) {
|
|
155
|
+
const flattenedFiles = [];
|
|
156
|
+
const seen = new Set();
|
|
157
|
+
|
|
158
|
+
for (const layer of layers) {
|
|
159
|
+
for (const file of layer.files || []) {
|
|
160
|
+
if (seen.has(file)) continue;
|
|
161
|
+
seen.add(file);
|
|
162
|
+
flattenedFiles.push(file);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const primary = meta.baseLayer || layers[layers.length - 1] || layers[0] || null;
|
|
167
|
+
return {
|
|
168
|
+
stage: meta.stage || (primary ? primary.stage : CORE_STAGE_NAME),
|
|
169
|
+
overlay: meta.overlay || null,
|
|
170
|
+
skill: meta.skill || null,
|
|
171
|
+
source: meta.source || 'stage map',
|
|
172
|
+
entry: meta.entry || (primary ? primary.entry : 'core/index.md'),
|
|
173
|
+
files: flattenedFiles,
|
|
174
|
+
description: primary ? primary.description : 'Baseline rules',
|
|
175
|
+
layers
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function resolveStageSelection(registry, stageName, overlayName = '', meta = {}) {
|
|
180
|
+
const layers = [];
|
|
181
|
+
let baseLayer = null;
|
|
182
|
+
const seenLayers = new Set();
|
|
183
|
+
|
|
184
|
+
function addLayer(selectedStage, variant = '', markAsBase = false) {
|
|
185
|
+
const layer = getLayer(registry, selectedStage, variant);
|
|
186
|
+
if (!layer) return null;
|
|
187
|
+
const key = `${layer.stage}:${layer.variant || ''}`;
|
|
188
|
+
if (seenLayers.has(key)) {
|
|
189
|
+
if (markAsBase) baseLayer = layer;
|
|
190
|
+
return layer;
|
|
191
|
+
}
|
|
192
|
+
seenLayers.add(key);
|
|
193
|
+
layers.push(layer);
|
|
194
|
+
if (markAsBase) baseLayer = layer;
|
|
195
|
+
return layer;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
addLayer(CORE_STAGE_NAME, '', stageName === CORE_STAGE_NAME);
|
|
199
|
+
|
|
200
|
+
if (stageName !== CORE_STAGE_NAME) {
|
|
201
|
+
addLayer(stageName, '', true);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (overlayName) {
|
|
205
|
+
const overlayExists = registry[OVERLAY_STAGE_NAME]
|
|
206
|
+
&& registry[OVERLAY_STAGE_NAME].variants
|
|
207
|
+
&& registry[OVERLAY_STAGE_NAME].variants[overlayName];
|
|
208
|
+
if (!overlayExists) {
|
|
209
|
+
throw new Error(`Unknown overlay: ${overlayName}`);
|
|
210
|
+
}
|
|
211
|
+
addLayer(OVERLAY_STAGE_NAME, overlayName, false);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (layers.length === 0) return null;
|
|
215
|
+
return combineLayers(layers, {
|
|
216
|
+
stage: stageName,
|
|
217
|
+
overlay: overlayName || null,
|
|
218
|
+
baseLayer,
|
|
219
|
+
source: meta.source || 'explicit selection'
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function readEnvironmentStage() {
|
|
224
|
+
return normalizeStageName(process.env.PIG_SKILLS_RULE_STAGE || process.env.PIG_SKILLS_RULES_STAGE);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function readEnvironmentOverlay() {
|
|
228
|
+
return normalizeStageName(process.env.PIG_SKILLS_RULE_OVERLAY);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function detectRulesStage(cwd = process.cwd()) { // eslint-disable-line no-unused-vars
|
|
232
|
+
const registry = readRegistry();
|
|
233
|
+
const stageMap = readSkillStageMap();
|
|
234
|
+
const stageOverride = readEnvironmentStage();
|
|
235
|
+
const skillOverride = normalizeStageName(process.env.PIG_SKILLS_RULE_SKILL);
|
|
236
|
+
const overlayOverride = readEnvironmentOverlay();
|
|
237
|
+
|
|
238
|
+
if (stageOverride) {
|
|
239
|
+
if (!registry[stageOverride]) {
|
|
240
|
+
throw new Error(`Unknown stage: ${stageOverride}`);
|
|
241
|
+
}
|
|
242
|
+
return resolveStageSelection(registry, stageOverride, overlayOverride, { source: 'stage override' });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (skillOverride) {
|
|
246
|
+
const mapped = stageMap[skillOverride];
|
|
247
|
+
if (!mapped) {
|
|
248
|
+
throw new Error(`Unknown skill mapping: ${skillOverride}`);
|
|
249
|
+
}
|
|
250
|
+
return resolveStageSelection(registry, mapped.stage, overlayOverride, {
|
|
251
|
+
skill: skillOverride,
|
|
252
|
+
source: 'skill mapping'
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return resolveStageSelection(registry, CORE_STAGE_NAME, overlayOverride, { source: 'default' });
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (require.main === module) {
|
|
260
|
+
const cwd = process.argv[2] ? path.resolve(process.argv[2]) : process.cwd();
|
|
261
|
+
process.stdout.write(`${JSON.stringify(detectRulesStage(cwd), null, 2)}\n`);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
module.exports = {
|
|
265
|
+
detectRulesStage,
|
|
266
|
+
readRegistry,
|
|
267
|
+
readSkillStageMap,
|
|
268
|
+
readSkillStage,
|
|
269
|
+
validateSkillStageConsistency,
|
|
270
|
+
resolveStageSelection
|
|
271
|
+
};
|