@cregis-dev/cckit 0.4.0 → 0.4.1
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/LICENSE +21 -21
- package/README.md +76 -84
- package/bin/cckit.js +3 -3
- package/package.json +7 -5
- package/registry.json +234 -234
- package/src/adapters/trae-adapter.js +90 -90
- package/src/cli.js +2 -2
- package/src/commands/init.js +337 -337
- package/src/commands/status.js +62 -62
- package/src/commands/sync.js +325 -325
- package/src/commands/update.js +430 -430
- package/src/core/config.js +82 -82
- package/src/core/differ.js +57 -57
- package/src/core/installer.js +97 -97
- package/src/core/plugin-installer.js +278 -278
- package/src/core/registry.js +75 -75
- package/src/core/templatize.js +42 -42
- package/src/core/upstream.js +357 -357
- package/src/utils/fs.js +55 -55
- package/src/utils/logger.js +16 -16
- package/templates/bmad/_config/agent-manifest.csv +12 -12
- package/templates/bmad/_config/agents/bmm-analyst.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-architect.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-dev.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-pm.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-qa.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-quick-flow-solo-dev.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-sm.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-tech-writer.customize.yaml +41 -41
- package/templates/bmad/_config/agents/bmm-ux-designer.customize.yaml +41 -41
- package/templates/bmad/_config/agents/core-bmad-master.customize.yaml +41 -41
- package/templates/bmad/_config/agents/tea-tea.customize.yaml +41 -41
- package/templates/bmad/_config/bmad-help.csv +48 -48
- package/templates/bmad/_config/files-manifest.csv +437 -437
- package/templates/bmad/_config/ides/claude-code.yaml +5 -5
- package/templates/bmad/_config/ides/opencode.yaml +5 -5
- package/templates/bmad/_config/ides/trae.yaml +5 -5
- package/templates/bmad/_config/task-manifest.csv +8 -8
- package/templates/bmad/_config/tool-manifest.csv +1 -1
- package/templates/bmad/_config/workflow-manifest.csv +35 -35
- package/templates/bmad/bmm/agents/analyst.md +78 -78
- package/templates/bmad/bmm/agents/architect.md +58 -58
- package/templates/bmad/bmm/agents/dev.md +69 -69
- package/templates/bmad/bmm/agents/pm.md +72 -72
- package/templates/bmad/bmm/agents/qa.md +92 -92
- package/templates/bmad/bmm/agents/quick-flow-solo-dev.md +69 -69
- package/templates/bmad/bmm/agents/sm.md +70 -70
- package/templates/bmad/bmm/agents/tech-writer/tech-writer.md +70 -70
- package/templates/bmad/bmm/agents/ux-designer.md +57 -57
- package/templates/bmad/bmm/config.yaml +15 -15
- package/templates/bmad/bmm/data/project-context-template.md +26 -26
- package/templates/bmad/bmm/module-help.csv +31 -31
- package/templates/bmad/bmm/teams/default-party.csv +20 -20
- package/templates/bmad/bmm/teams/team-fullstack.yaml +12 -12
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -10
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -177
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -161
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -199
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -202
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -205
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -219
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -162
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +57 -57
- package/templates/bmad/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -137
- package/templates/bmad/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -229
- package/templates/bmad/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -238
- package/templates/bmad/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -206
- package/templates/bmad/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -234
- package/templates/bmad/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +444 -444
- package/templates/bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -182
- package/templates/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -237
- package/templates/bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -249
- package/templates/bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -259
- package/templates/bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -177
- package/templates/bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +476 -476
- package/templates/bmad/bmm/workflows/1-analysis/research/research.template.md +29 -29
- package/templates/bmad/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -137
- package/templates/bmad/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -239
- package/templates/bmad/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -248
- package/templates/bmad/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -202
- package/templates/bmad/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +233 -233
- package/templates/bmad/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +487 -487
- package/templates/bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md +54 -54
- package/templates/bmad/bmm/workflows/1-analysis/research/workflow-market-research.md +54 -54
- package/templates/bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md +54 -54
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +14 -14
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -197
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +10 -10
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +191 -191
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +152 -152
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +224 -224
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +154 -154
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +170 -170
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +226 -226
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +213 -213
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +207 -207
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +226 -226
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +237 -237
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +228 -228
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +231 -231
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +242 -242
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +217 -217
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +124 -124
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +247 -247
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +208 -208
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +249 -249
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +253 -253
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +168 -168
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +226 -226
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -191
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -209
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -174
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -214
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -228
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -217
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -205
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -243
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -263
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -209
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -264
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -242
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +231 -231
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -10
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +63 -63
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +65 -65
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +63 -63
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -135
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -127
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -190
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -216
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -219
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -234
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -252
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -254
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -224
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -224
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -241
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -248
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -237
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -264
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -171
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -13
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +42 -42
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +184 -184
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +172 -172
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +173 -173
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +133 -133
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +245 -245
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +129 -129
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -4
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -54
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -12
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +12 -12
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +6 -6
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -153
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +173 -173
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -224
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +329 -329
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -318
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -359
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -379
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -359
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -76
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -49
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -259
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -233
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -272
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -149
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -57
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -58
- package/templates/bmad/bmm/workflows/4-implementation/code-review/checklist.md +23 -23
- package/templates/bmad/bmm/workflows/4-implementation/code-review/instructions.xml +226 -226
- package/templates/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +43 -43
- package/templates/bmad/bmm/workflows/4-implementation/correct-course/checklist.md +288 -288
- package/templates/bmad/bmm/workflows/4-implementation/correct-course/instructions.md +207 -207
- package/templates/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +53 -53
- package/templates/bmad/bmm/workflows/4-implementation/create-story/checklist.md +358 -358
- package/templates/bmad/bmm/workflows/4-implementation/create-story/instructions.xml +346 -346
- package/templates/bmad/bmm/workflows/4-implementation/create-story/template.md +49 -49
- package/templates/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +52 -52
- package/templates/bmad/bmm/workflows/4-implementation/dev-story/checklist.md +80 -80
- package/templates/bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -410
- package/templates/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +20 -20
- package/templates/bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1444 -1444
- package/templates/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +52 -52
- package/templates/bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -33
- package/templates/bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +226 -226
- package/templates/bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -55
- package/templates/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +47 -47
- package/templates/bmad/bmm/workflows/4-implementation/sprint-status/instructions.md +230 -230
- package/templates/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +25 -25
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +174 -174
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +118 -118
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +111 -111
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +111 -111
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +104 -104
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +146 -146
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -50
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +189 -189
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +143 -143
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +126 -126
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +200 -200
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -74
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -79
- package/templates/bmad/bmm/workflows/document-project/checklist.md +245 -245
- package/templates/bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -12
- package/templates/bmad/bmm/workflows/document-project/instructions.md +130 -130
- package/templates/bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -345
- package/templates/bmad/bmm/workflows/document-project/templates/index-template.md +169 -169
- package/templates/bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -103
- package/templates/bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -160
- package/templates/bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -135
- package/templates/bmad/bmm/workflows/document-project/workflow.yaml +22 -22
- package/templates/bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -298
- package/templates/bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -31
- package/templates/bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -1106
- package/templates/bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -31
- package/templates/bmad/bmm/workflows/generate-project-context/project-context-template.md +21 -21
- package/templates/bmad/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -184
- package/templates/bmad/bmm/workflows/generate-project-context/steps/step-02-generate.md +318 -318
- package/templates/bmad/bmm/workflows/generate-project-context/steps/step-03-complete.md +278 -278
- package/templates/bmad/bmm/workflows/generate-project-context/workflow.md +49 -49
- package/templates/bmad/bmm/workflows/qa/automate/checklist.md +33 -33
- package/templates/bmad/bmm/workflows/qa/automate/instructions.md +110 -110
- package/templates/bmad/bmm/workflows/qa/automate/workflow.yaml +44 -44
- package/templates/bmad/bmm/workflows/qa-generate-e2e-tests/checklist.md +33 -33
- package/templates/bmad/bmm/workflows/qa-generate-e2e-tests/instructions.md +110 -110
- package/templates/bmad/bmm/workflows/qa-generate-e2e-tests/workflow.yaml +42 -42
- package/templates/bmad/commands/bmad-agent-bmad-master.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-analyst.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-architect.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-dev.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-pm.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-qa.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-quick-flow-solo-dev.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-sm.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-tech-writer.md +15 -15
- package/templates/bmad/commands/bmad-agent-bmm-ux-designer.md +15 -15
- package/templates/bmad/commands/bmad-agent-tea-tea.md +15 -15
- package/templates/bmad/commands/bmad-bmm-check-implementation-readiness.md +6 -6
- package/templates/bmad/commands/bmad-bmm-code-review.md +14 -14
- package/templates/bmad/commands/bmad-bmm-correct-course.md +14 -14
- package/templates/bmad/commands/bmad-bmm-create-architecture.md +6 -6
- package/templates/bmad/commands/bmad-bmm-create-epics-and-stories.md +6 -6
- package/templates/bmad/commands/bmad-bmm-create-prd.md +6 -6
- package/templates/bmad/commands/bmad-bmm-create-product-brief.md +6 -6
- package/templates/bmad/commands/bmad-bmm-create-story.md +14 -14
- package/templates/bmad/commands/bmad-bmm-create-ux-design.md +6 -6
- package/templates/bmad/commands/bmad-bmm-dev-story.md +14 -14
- package/templates/bmad/commands/bmad-bmm-document-project.md +14 -14
- package/templates/bmad/commands/bmad-bmm-domain-research.md +6 -6
- package/templates/bmad/commands/bmad-bmm-edit-prd.md +6 -6
- package/templates/bmad/commands/bmad-bmm-generate-project-context.md +6 -6
- package/templates/bmad/commands/bmad-bmm-market-research.md +6 -6
- package/templates/bmad/commands/bmad-bmm-qa-automate.md +15 -15
- package/templates/bmad/commands/bmad-bmm-qa-generate-e2e-tests.md +14 -14
- package/templates/bmad/commands/bmad-bmm-quick-dev.md +6 -6
- package/templates/bmad/commands/bmad-bmm-quick-spec.md +6 -6
- package/templates/bmad/commands/bmad-bmm-retrospective.md +14 -14
- package/templates/bmad/commands/bmad-bmm-sprint-planning.md +14 -14
- package/templates/bmad/commands/bmad-bmm-sprint-status.md +14 -14
- package/templates/bmad/commands/bmad-bmm-technical-research.md +6 -6
- package/templates/bmad/commands/bmad-bmm-validate-prd.md +6 -6
- package/templates/bmad/commands/bmad-brainstorming.md +6 -6
- package/templates/bmad/commands/bmad-editorial-review-prose.md +10 -10
- package/templates/bmad/commands/bmad-editorial-review-structure.md +10 -10
- package/templates/bmad/commands/bmad-help.md +10 -10
- package/templates/bmad/commands/bmad-index-docs.md +10 -10
- package/templates/bmad/commands/bmad-party-mode.md +6 -6
- package/templates/bmad/commands/bmad-review-adversarial-general.md +10 -10
- package/templates/bmad/commands/bmad-review-edge-case-hunter.md +10 -10
- package/templates/bmad/commands/bmad-shard-doc.md +10 -10
- package/templates/bmad/commands/bmad-tea-teach-me-testing.md +6 -6
- package/templates/bmad/commands/bmad-tea-testarch-atdd.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-automate.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-ci.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-framework.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-nfr.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-test-design.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-test-review.md +14 -14
- package/templates/bmad/commands/bmad-tea-testarch-trace.md +14 -14
- package/templates/bmad/core/agents/bmad-master.md +56 -56
- package/templates/bmad/core/config.yaml +8 -8
- package/templates/bmad/core/module-help.csv +10 -10
- package/templates/bmad/core/tasks/editorial-review-prose.xml +101 -101
- package/templates/bmad/core/tasks/editorial-review-structure.xml +207 -207
- package/templates/bmad/core/tasks/help.md +86 -86
- package/templates/bmad/core/tasks/index-docs.xml +64 -64
- package/templates/bmad/core/tasks/review-adversarial-general.xml +48 -48
- package/templates/bmad/core/tasks/review-edge-case-hunter.xml +63 -63
- package/templates/bmad/core/tasks/shard-doc.xml +107 -107
- package/templates/bmad/core/tasks/workflow.xml +234 -234
- package/templates/bmad/core/workflows/advanced-elicitation/methods.csv +51 -51
- package/templates/bmad/core/workflows/advanced-elicitation/workflow.xml +117 -117
- package/templates/bmad/core/workflows/brainstorming/brain-methods.csv +61 -61
- package/templates/bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +210 -210
- package/templates/bmad/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
- package/templates/bmad/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
- package/templates/bmad/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
- package/templates/bmad/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
- package/templates/bmad/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
- package/templates/bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -399
- package/templates/bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
- package/templates/bmad/core/workflows/brainstorming/template.md +15 -15
- package/templates/bmad/core/workflows/brainstorming/workflow.md +60 -60
- package/templates/bmad/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -138
- package/templates/bmad/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -187
- package/templates/bmad/core/workflows/party-mode/steps/step-03-graceful-exit.md +168 -168
- package/templates/bmad/core/workflows/party-mode/workflow.md +194 -194
- package/templates/bmad/tea/agents/tea.md +71 -71
- package/templates/bmad/tea/config.yaml +24 -24
- package/templates/mcp/claude-code/.mcp.json +35 -35
- package/templates/mcp/trae/mcp.json +35 -35
- package/templates/trae-bmad/rules/bmad-agent-bmad-master.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-analyst.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-architect.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-dev.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-pm.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-qa.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-quick-flow-solo-dev.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-sm.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-tech-writer.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-bmm-ux-designer.md +15 -15
- package/templates/trae-bmad/rules/bmad-agent-tea-tea.md +15 -15
- package/templates/trae-bmad/rules/bmad-bmm-check-implementation-readiness.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-code-review.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-correct-course.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-create-architecture.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-create-epics-and-stories.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-create-prd.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-create-product-brief.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-create-story.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-create-ux-design.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-dev-story.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-document-project.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-domain-research.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-edit-prd.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-generate-project-context.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-market-research.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-qa-automate.md +15 -15
- package/templates/trae-bmad/rules/bmad-bmm-qa-generate-e2e-tests.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-quick-dev.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-quick-spec.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-retrospective.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-sprint-planning.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-sprint-status.md +14 -14
- package/templates/trae-bmad/rules/bmad-bmm-technical-research.md +6 -6
- package/templates/trae-bmad/rules/bmad-bmm-validate-prd.md +6 -6
- package/templates/trae-bmad/rules/bmad-brainstorming.md +6 -6
- package/templates/trae-bmad/rules/bmad-editorial-review-prose.md +10 -10
- package/templates/trae-bmad/rules/bmad-editorial-review-structure.md +10 -10
- package/templates/trae-bmad/rules/bmad-help.md +10 -10
- package/templates/trae-bmad/rules/bmad-index-docs.md +10 -10
- package/templates/trae-bmad/rules/bmad-party-mode.md +6 -6
- package/templates/trae-bmad/rules/bmad-review-adversarial-general.md +10 -10
- package/templates/trae-bmad/rules/bmad-review-edge-case-hunter.md +10 -10
- package/templates/trae-bmad/rules/bmad-shard-doc.md +10 -10
- package/templates/trae-bmad/rules/bmad-tea-teach-me-testing.md +6 -6
- package/templates/trae-bmad/rules/bmad-tea-testarch-atdd.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-automate.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-ci.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-framework.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-nfr.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-test-design.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-test-review.md +14 -14
- package/templates/trae-bmad/rules/bmad-tea-testarch-trace.md +14 -14
package/src/core/upstream.js
CHANGED
|
@@ -1,357 +1,357 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Upstream source fetching, path mapping, and file copying for sync.
|
|
3
|
-
*
|
|
4
|
-
* Handles pulling content from BMAD (npm), ECC (git), plugins (git),
|
|
5
|
-
* and external skills (git) upstreams, then copying files to the local
|
|
6
|
-
* templates/ directory via configurable path mappings with optional
|
|
7
|
-
* filters, excludes, and post-processing.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import path from 'node:path'
|
|
11
|
-
import fse from 'fs-extra'
|
|
12
|
-
import os from 'node:os'
|
|
13
|
-
import { execFile as execFileCb } from 'node:child_process'
|
|
14
|
-
import { promisify } from 'node:util'
|
|
15
|
-
import { mkdtemp } from 'node:fs/promises'
|
|
16
|
-
import { listFiles, TEXT_EXTENSIONS } from '../utils/fs.js'
|
|
17
|
-
|
|
18
|
-
const execFile = promisify(execFileCb)
|
|
19
|
-
|
|
20
|
-
// ─── Path Mappings ──────────────────────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
export const BMAD_PATH_MAPPINGS = [
|
|
23
|
-
{ src: '_bmad/core', dest: 'bmad/core' },
|
|
24
|
-
{ src: '_bmad/bmm', dest: 'bmad/bmm' },
|
|
25
|
-
{ src: '_bmad/tea', dest: 'bmad/tea' },
|
|
26
|
-
{ src: '_bmad/_config', dest: 'bmad/_config', exclude: ['manifest.yaml'] },
|
|
27
|
-
{ src: '.claude/commands', dest: 'bmad/commands', filter: /^bmad-/ },
|
|
28
|
-
{ src: '.trae/rules', dest: 'trae-bmad/rules', filter: /^bmad-/ },
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
export const ECC_REPO_URL = 'https://github.com/affaan-m/everything-claude-code'
|
|
32
|
-
|
|
33
|
-
export const ECC_PATH_MAPPINGS = [
|
|
34
|
-
{ src: 'rules', dest: 'ecc/rules' },
|
|
35
|
-
{ src: 'agents', dest: 'ecc/agents' },
|
|
36
|
-
{ src: 'skills', dest: 'ecc/skills' },
|
|
37
|
-
{ src: 'commands', dest: 'ecc/commands' },
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
// ─── Fetch Functions ────────────────────────────────────────────────────────
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Fetch BMAD content by running `npx bmad-method install` in a temp directory.
|
|
44
|
-
* BMAD v6+ uses a CLI with `install` subcommand and module selection.
|
|
45
|
-
*
|
|
46
|
-
* @param {{ tmpDir: string, logger: object }} opts
|
|
47
|
-
* @returns {Promise<{ version: string, dir: string }>} Extracted npm package version and install dir
|
|
48
|
-
*/
|
|
49
|
-
export async function fetchBmad({ tmpDir, logger }) {
|
|
50
|
-
logger.debug('Fetching BMAD via npx bmad-method install...')
|
|
51
|
-
|
|
52
|
-
const bmadDir = path.join(tmpDir, 'bmad')
|
|
53
|
-
await fse.ensureDir(bmadDir)
|
|
54
|
-
|
|
55
|
-
// BMAD v6 CLI: install --yes --modules bmm,tea --tools claude-code,trae
|
|
56
|
-
await execFile('npx', [
|
|
57
|
-
'-y', 'bmad-method@latest', 'install',
|
|
58
|
-
'--yes',
|
|
59
|
-
'--directory', bmadDir,
|
|
60
|
-
'--modules', 'bmm,tea',
|
|
61
|
-
'--tools', 'claude-code,trae',
|
|
62
|
-
'--user-name', 'User',
|
|
63
|
-
'--communication-language', 'English',
|
|
64
|
-
'--document-output-language', 'English',
|
|
65
|
-
], {
|
|
66
|
-
cwd: bmadDir,
|
|
67
|
-
timeout: 120_000,
|
|
68
|
-
shell: process.platform === 'win32',
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
// Extract version from the installed manifest
|
|
72
|
-
let version = 'unknown'
|
|
73
|
-
try {
|
|
74
|
-
const manifestPath = path.join(bmadDir, '_bmad', '_config', 'manifest.yaml')
|
|
75
|
-
if (await fse.pathExists(manifestPath)) {
|
|
76
|
-
const content = await fse.readFile(manifestPath, 'utf8')
|
|
77
|
-
const match = content.match(/version:\s*['"]?([^\s'"]+)/)
|
|
78
|
-
if (match) version = match[1]
|
|
79
|
-
}
|
|
80
|
-
} catch {
|
|
81
|
-
// Fallback: try package.json in npm cache
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (version === 'unknown') {
|
|
85
|
-
try {
|
|
86
|
-
const { stdout } = await execFile('npx', ['-y', 'bmad-method@latest', '--version'], {
|
|
87
|
-
timeout: 30_000,
|
|
88
|
-
shell: process.platform === 'win32',
|
|
89
|
-
})
|
|
90
|
-
version = stdout.trim() || 'unknown'
|
|
91
|
-
} catch {
|
|
92
|
-
logger.warn('Could not determine BMAD package version')
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
logger.debug(`BMAD fetched, version: ${version}`)
|
|
97
|
-
return { version, dir: bmadDir }
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Fetch ECC content by cloning the git repository.
|
|
102
|
-
*
|
|
103
|
-
* @param {{ tmpDir: string, logger: object }} opts
|
|
104
|
-
* @returns {Promise<{ sha: string }>} HEAD commit SHA
|
|
105
|
-
*/
|
|
106
|
-
export async function fetchEcc({ tmpDir, logger }) {
|
|
107
|
-
const repo = `${ECC_REPO_URL}.git`
|
|
108
|
-
const eccDir = path.join(tmpDir, 'ecc')
|
|
109
|
-
|
|
110
|
-
logger.debug(`Cloning ECC from ${repo}...`)
|
|
111
|
-
|
|
112
|
-
await execFile('git', ['clone', '--depth', '1', repo, eccDir], {
|
|
113
|
-
timeout: 120_000,
|
|
114
|
-
shell: process.platform === 'win32',
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
// Get HEAD SHA
|
|
118
|
-
let sha = 'unknown'
|
|
119
|
-
try {
|
|
120
|
-
const { stdout } = await execFile('git', ['rev-parse', 'HEAD'], {
|
|
121
|
-
cwd: eccDir,
|
|
122
|
-
shell: process.platform === 'win32',
|
|
123
|
-
})
|
|
124
|
-
sha = stdout.trim()
|
|
125
|
-
} catch {
|
|
126
|
-
logger.warn('Could not determine ECC commit SHA')
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
logger.debug(`ECC cloned, SHA: ${sha}`)
|
|
130
|
-
return { sha, dir: eccDir }
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// ─── Mapping & Copy ─────────────────────────────────────────────────────────
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Apply path mappings to copy files from source to destination.
|
|
137
|
-
*
|
|
138
|
-
* @param {{
|
|
139
|
-
* srcBase: string,
|
|
140
|
-
* destBase: string,
|
|
141
|
-
* mappings: Array<{ src: string, dest: string, exclude?: string[], filter?: RegExp }>,
|
|
142
|
-
* postProcess?: (content: string, relPath: string) => string,
|
|
143
|
-
* logger: object
|
|
144
|
-
* }} opts
|
|
145
|
-
* @returns {Promise<number>} Total number of files copied
|
|
146
|
-
*/
|
|
147
|
-
export async function applyMappings({ srcBase, destBase, mappings, postProcess, logger }) {
|
|
148
|
-
let totalFiles = 0
|
|
149
|
-
|
|
150
|
-
for (const mapping of mappings) {
|
|
151
|
-
const srcDir = path.join(srcBase, mapping.src)
|
|
152
|
-
const destDir = path.join(destBase, mapping.dest)
|
|
153
|
-
|
|
154
|
-
if (!await fse.pathExists(srcDir)) {
|
|
155
|
-
logger.warn(`Source directory not found, skipping: ${mapping.src}`)
|
|
156
|
-
continue
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const files = await listFiles(srcDir)
|
|
160
|
-
|
|
161
|
-
for (const relPath of files) {
|
|
162
|
-
const fileName = path.basename(relPath)
|
|
163
|
-
|
|
164
|
-
// Apply exclude list
|
|
165
|
-
if (mapping.exclude && mapping.exclude.includes(fileName)) {
|
|
166
|
-
logger.debug(` Excluded: ${mapping.src}/${relPath}`)
|
|
167
|
-
continue
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Apply filename filter (regex must match basename)
|
|
171
|
-
if (mapping.filter && !mapping.filter.test(fileName)) {
|
|
172
|
-
continue
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const srcFile = path.join(srcDir, relPath)
|
|
176
|
-
const destFile = path.join(destDir, relPath)
|
|
177
|
-
|
|
178
|
-
await fse.ensureDir(path.dirname(destFile))
|
|
179
|
-
|
|
180
|
-
// Read, optionally post-process, then write
|
|
181
|
-
const ext = path.extname(relPath).toLowerCase()
|
|
182
|
-
const isText = TEXT_EXTENSIONS.has(ext)
|
|
183
|
-
|
|
184
|
-
if (isText && postProcess) {
|
|
185
|
-
let content = await fse.readFile(srcFile, 'utf8')
|
|
186
|
-
const destRelPath = path.join(mapping.dest, relPath).replace(/\\/g, '/')
|
|
187
|
-
content = postProcess(content, destRelPath)
|
|
188
|
-
await fse.writeFile(destFile, content, 'utf8')
|
|
189
|
-
} else {
|
|
190
|
-
await fse.copy(srcFile, destFile)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
totalFiles++
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
logger.debug(` Mapped ${mapping.src} → ${mapping.dest}`)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
return totalFiles
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// ─── Plugin Fetch ───────────────────────────────────────────────────────────
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Fetch plugin content by cloning a marketplace GitHub repository.
|
|
206
|
-
*
|
|
207
|
-
* @param {{ tmpDir: string, logger: object, registry: object }} opts
|
|
208
|
-
* @returns {Promise<{ sha: string, dir: string }>} HEAD commit SHA and clone directory
|
|
209
|
-
*/
|
|
210
|
-
export async function fetchPlugins({ tmpDir, logger, registry }) {
|
|
211
|
-
const upstream = registry.upstream?.plugins
|
|
212
|
-
if (!upstream?.repo) {
|
|
213
|
-
throw new Error('No plugins upstream configured in registry.json')
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const repo = upstream.repo.endsWith('.git') ? upstream.repo : `${upstream.repo}.git`
|
|
217
|
-
const pluginsDir = path.join(tmpDir, 'plugins')
|
|
218
|
-
|
|
219
|
-
logger.debug(`Cloning plugins from ${repo}...`)
|
|
220
|
-
|
|
221
|
-
await execFile('git', ['clone', '--depth', '1', repo, pluginsDir], {
|
|
222
|
-
timeout: 120_000,
|
|
223
|
-
shell: process.platform === 'win32',
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
// Get HEAD SHA
|
|
227
|
-
let sha = 'unknown'
|
|
228
|
-
try {
|
|
229
|
-
const { stdout } = await execFile('git', ['rev-parse', 'HEAD'], {
|
|
230
|
-
cwd: pluginsDir,
|
|
231
|
-
shell: process.platform === 'win32',
|
|
232
|
-
})
|
|
233
|
-
sha = stdout.trim()
|
|
234
|
-
} catch {
|
|
235
|
-
logger.warn('Could not determine plugins commit SHA')
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
logger.debug(`Plugins cloned, SHA: ${sha}`)
|
|
239
|
-
return { sha, dir: pluginsDir }
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Build path mappings for plugins based on registry.plugins entries.
|
|
244
|
-
* Each plugin maps from its source directory in the marketplace repo
|
|
245
|
-
* to its destination in templates/plugins/.
|
|
246
|
-
*
|
|
247
|
-
* @param {object} registry - Registry object with plugins section
|
|
248
|
-
* @returns {Array<{ src: string, dest: string }>} Path mappings
|
|
249
|
-
*/
|
|
250
|
-
export function buildPluginMappings(registry) {
|
|
251
|
-
const pluginsPath = registry.upstream?.plugins?.pluginsPath || 'plugins'
|
|
252
|
-
const plugins = registry.plugins || {}
|
|
253
|
-
|
|
254
|
-
return Object.keys(plugins).map(id => ({
|
|
255
|
-
src: `${pluginsPath}/${id}`,
|
|
256
|
-
dest: `plugins/${id}`,
|
|
257
|
-
}))
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// ─── External Skills Fetch ─────────────────────────────────────────────────
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Fetch external skills by cloning each registered repo and extracting
|
|
264
|
-
* the configured skillPath into a unified output directory.
|
|
265
|
-
*
|
|
266
|
-
* Each skill entry in `registry.upstream['ext-skills']` is cloned
|
|
267
|
-
* independently, allowing skills from different repos to coexist.
|
|
268
|
-
*
|
|
269
|
-
* @param {{ tmpDir: string, logger: object, registry: object }} opts
|
|
270
|
-
* @returns {Promise<{ skills: Record<string, { sha: string }>, dir: string }>}
|
|
271
|
-
*/
|
|
272
|
-
export async function fetchExtSkills({ tmpDir, logger, registry }) {
|
|
273
|
-
const entries = registry.upstream?.['ext-skills'] || {}
|
|
274
|
-
const ids = Object.keys(entries)
|
|
275
|
-
|
|
276
|
-
if (ids.length === 0) {
|
|
277
|
-
throw new Error('No ext-skills upstream configured in registry.json')
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const outputDir = path.join(tmpDir, 'ext-skills')
|
|
281
|
-
await fse.ensureDir(outputDir)
|
|
282
|
-
|
|
283
|
-
const skills = {}
|
|
284
|
-
|
|
285
|
-
for (const id of ids) {
|
|
286
|
-
const entry = entries[id]
|
|
287
|
-
if (entry.type !== 'git' || !entry.repo) {
|
|
288
|
-
logger.warn(`ext-skill "${id}" has invalid config, skipping`)
|
|
289
|
-
continue
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const repo = entry.repo.endsWith('.git') ? entry.repo : `${entry.repo}.git`
|
|
293
|
-
const cloneDir = path.join(tmpDir, `ext-skill-${id}`)
|
|
294
|
-
|
|
295
|
-
logger.debug(`Cloning ext-skill "${id}" from ${repo}...`)
|
|
296
|
-
|
|
297
|
-
await execFile('git', ['clone', '--depth', '1', repo, cloneDir], {
|
|
298
|
-
timeout: 120_000,
|
|
299
|
-
shell: process.platform === 'win32',
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
// Get HEAD SHA
|
|
303
|
-
let sha = 'unknown'
|
|
304
|
-
try {
|
|
305
|
-
const { stdout } = await execFile('git', ['rev-parse', 'HEAD'], {
|
|
306
|
-
cwd: cloneDir,
|
|
307
|
-
shell: process.platform === 'win32',
|
|
308
|
-
})
|
|
309
|
-
sha = stdout.trim()
|
|
310
|
-
} catch {
|
|
311
|
-
logger.warn(`Could not determine commit SHA for ext-skill "${id}"`)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Copy skillPath contents to output/<id>/
|
|
315
|
-
const skillSrc = path.join(cloneDir, entry.skillPath || id)
|
|
316
|
-
const skillDest = path.join(outputDir, id)
|
|
317
|
-
|
|
318
|
-
if (await fse.pathExists(skillSrc)) {
|
|
319
|
-
await fse.copy(skillSrc, skillDest)
|
|
320
|
-
logger.debug(`ext-skill "${id}": copied ${entry.skillPath} → ${id}/, SHA: ${sha}`)
|
|
321
|
-
} else {
|
|
322
|
-
logger.warn(`ext-skill "${id}": skillPath "${entry.skillPath}" not found in repo`)
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
skills[id] = { sha }
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return { skills, dir: outputDir }
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Build path mappings for external skills based on registry.upstream['ext-skills'].
|
|
333
|
-
* Each skill maps from its ID subdirectory to templates/ext-skills/<id>.
|
|
334
|
-
*
|
|
335
|
-
* @param {object} registry - Registry object
|
|
336
|
-
* @returns {Array<{ src: string, dest: string }>} Path mappings
|
|
337
|
-
*/
|
|
338
|
-
export function buildExtSkillMappings(registry) {
|
|
339
|
-
const entries = registry.upstream?.['ext-skills'] || {}
|
|
340
|
-
|
|
341
|
-
return Object.keys(entries).map(id => ({
|
|
342
|
-
src: id,
|
|
343
|
-
dest: `ext-skills/${id}`,
|
|
344
|
-
}))
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// ─── Temp Directory Helper ──────────────────────────────────────────────────
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* Create a uniquely-named temporary directory.
|
|
351
|
-
*
|
|
352
|
-
* @param {string} prefix - Prefix for the temp directory name
|
|
353
|
-
* @returns {Promise<string>} Absolute path to the created directory
|
|
354
|
-
*/
|
|
355
|
-
export async function createTempDir(prefix = 'cckit-sync') {
|
|
356
|
-
return mkdtemp(path.join(os.tmpdir(), `${prefix}-`))
|
|
357
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Upstream source fetching, path mapping, and file copying for sync.
|
|
3
|
+
*
|
|
4
|
+
* Handles pulling content from BMAD (npm), ECC (git), plugins (git),
|
|
5
|
+
* and external skills (git) upstreams, then copying files to the local
|
|
6
|
+
* templates/ directory via configurable path mappings with optional
|
|
7
|
+
* filters, excludes, and post-processing.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import path from 'node:path'
|
|
11
|
+
import fse from 'fs-extra'
|
|
12
|
+
import os from 'node:os'
|
|
13
|
+
import { execFile as execFileCb } from 'node:child_process'
|
|
14
|
+
import { promisify } from 'node:util'
|
|
15
|
+
import { mkdtemp } from 'node:fs/promises'
|
|
16
|
+
import { listFiles, TEXT_EXTENSIONS } from '../utils/fs.js'
|
|
17
|
+
|
|
18
|
+
const execFile = promisify(execFileCb)
|
|
19
|
+
|
|
20
|
+
// ─── Path Mappings ──────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
export const BMAD_PATH_MAPPINGS = [
|
|
23
|
+
{ src: '_bmad/core', dest: 'bmad/core' },
|
|
24
|
+
{ src: '_bmad/bmm', dest: 'bmad/bmm' },
|
|
25
|
+
{ src: '_bmad/tea', dest: 'bmad/tea' },
|
|
26
|
+
{ src: '_bmad/_config', dest: 'bmad/_config', exclude: ['manifest.yaml'] },
|
|
27
|
+
{ src: '.claude/commands', dest: 'bmad/commands', filter: /^bmad-/ },
|
|
28
|
+
{ src: '.trae/rules', dest: 'trae-bmad/rules', filter: /^bmad-/ },
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
export const ECC_REPO_URL = 'https://github.com/affaan-m/everything-claude-code'
|
|
32
|
+
|
|
33
|
+
export const ECC_PATH_MAPPINGS = [
|
|
34
|
+
{ src: 'rules', dest: 'ecc/rules' },
|
|
35
|
+
{ src: 'agents', dest: 'ecc/agents' },
|
|
36
|
+
{ src: 'skills', dest: 'ecc/skills' },
|
|
37
|
+
{ src: 'commands', dest: 'ecc/commands' },
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
// ─── Fetch Functions ────────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fetch BMAD content by running `npx bmad-method install` in a temp directory.
|
|
44
|
+
* BMAD v6+ uses a CLI with `install` subcommand and module selection.
|
|
45
|
+
*
|
|
46
|
+
* @param {{ tmpDir: string, logger: object }} opts
|
|
47
|
+
* @returns {Promise<{ version: string, dir: string }>} Extracted npm package version and install dir
|
|
48
|
+
*/
|
|
49
|
+
export async function fetchBmad({ tmpDir, logger }) {
|
|
50
|
+
logger.debug('Fetching BMAD via npx bmad-method install...')
|
|
51
|
+
|
|
52
|
+
const bmadDir = path.join(tmpDir, 'bmad')
|
|
53
|
+
await fse.ensureDir(bmadDir)
|
|
54
|
+
|
|
55
|
+
// BMAD v6 CLI: install --yes --modules bmm,tea --tools claude-code,trae
|
|
56
|
+
await execFile('npx', [
|
|
57
|
+
'-y', 'bmad-method@latest', 'install',
|
|
58
|
+
'--yes',
|
|
59
|
+
'--directory', bmadDir,
|
|
60
|
+
'--modules', 'bmm,tea',
|
|
61
|
+
'--tools', 'claude-code,trae',
|
|
62
|
+
'--user-name', 'User',
|
|
63
|
+
'--communication-language', 'English',
|
|
64
|
+
'--document-output-language', 'English',
|
|
65
|
+
], {
|
|
66
|
+
cwd: bmadDir,
|
|
67
|
+
timeout: 120_000,
|
|
68
|
+
shell: process.platform === 'win32',
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// Extract version from the installed manifest
|
|
72
|
+
let version = 'unknown'
|
|
73
|
+
try {
|
|
74
|
+
const manifestPath = path.join(bmadDir, '_bmad', '_config', 'manifest.yaml')
|
|
75
|
+
if (await fse.pathExists(manifestPath)) {
|
|
76
|
+
const content = await fse.readFile(manifestPath, 'utf8')
|
|
77
|
+
const match = content.match(/version:\s*['"]?([^\s'"]+)/)
|
|
78
|
+
if (match) version = match[1]
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
// Fallback: try package.json in npm cache
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (version === 'unknown') {
|
|
85
|
+
try {
|
|
86
|
+
const { stdout } = await execFile('npx', ['-y', 'bmad-method@latest', '--version'], {
|
|
87
|
+
timeout: 30_000,
|
|
88
|
+
shell: process.platform === 'win32',
|
|
89
|
+
})
|
|
90
|
+
version = stdout.trim() || 'unknown'
|
|
91
|
+
} catch {
|
|
92
|
+
logger.warn('Could not determine BMAD package version')
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
logger.debug(`BMAD fetched, version: ${version}`)
|
|
97
|
+
return { version, dir: bmadDir }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Fetch ECC content by cloning the git repository.
|
|
102
|
+
*
|
|
103
|
+
* @param {{ tmpDir: string, logger: object }} opts
|
|
104
|
+
* @returns {Promise<{ sha: string }>} HEAD commit SHA
|
|
105
|
+
*/
|
|
106
|
+
export async function fetchEcc({ tmpDir, logger }) {
|
|
107
|
+
const repo = `${ECC_REPO_URL}.git`
|
|
108
|
+
const eccDir = path.join(tmpDir, 'ecc')
|
|
109
|
+
|
|
110
|
+
logger.debug(`Cloning ECC from ${repo}...`)
|
|
111
|
+
|
|
112
|
+
await execFile('git', ['clone', '--depth', '1', repo, eccDir], {
|
|
113
|
+
timeout: 120_000,
|
|
114
|
+
shell: process.platform === 'win32',
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
// Get HEAD SHA
|
|
118
|
+
let sha = 'unknown'
|
|
119
|
+
try {
|
|
120
|
+
const { stdout } = await execFile('git', ['rev-parse', 'HEAD'], {
|
|
121
|
+
cwd: eccDir,
|
|
122
|
+
shell: process.platform === 'win32',
|
|
123
|
+
})
|
|
124
|
+
sha = stdout.trim()
|
|
125
|
+
} catch {
|
|
126
|
+
logger.warn('Could not determine ECC commit SHA')
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
logger.debug(`ECC cloned, SHA: ${sha}`)
|
|
130
|
+
return { sha, dir: eccDir }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ─── Mapping & Copy ─────────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Apply path mappings to copy files from source to destination.
|
|
137
|
+
*
|
|
138
|
+
* @param {{
|
|
139
|
+
* srcBase: string,
|
|
140
|
+
* destBase: string,
|
|
141
|
+
* mappings: Array<{ src: string, dest: string, exclude?: string[], filter?: RegExp }>,
|
|
142
|
+
* postProcess?: (content: string, relPath: string) => string,
|
|
143
|
+
* logger: object
|
|
144
|
+
* }} opts
|
|
145
|
+
* @returns {Promise<number>} Total number of files copied
|
|
146
|
+
*/
|
|
147
|
+
export async function applyMappings({ srcBase, destBase, mappings, postProcess, logger }) {
|
|
148
|
+
let totalFiles = 0
|
|
149
|
+
|
|
150
|
+
for (const mapping of mappings) {
|
|
151
|
+
const srcDir = path.join(srcBase, mapping.src)
|
|
152
|
+
const destDir = path.join(destBase, mapping.dest)
|
|
153
|
+
|
|
154
|
+
if (!await fse.pathExists(srcDir)) {
|
|
155
|
+
logger.warn(`Source directory not found, skipping: ${mapping.src}`)
|
|
156
|
+
continue
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const files = await listFiles(srcDir)
|
|
160
|
+
|
|
161
|
+
for (const relPath of files) {
|
|
162
|
+
const fileName = path.basename(relPath)
|
|
163
|
+
|
|
164
|
+
// Apply exclude list
|
|
165
|
+
if (mapping.exclude && mapping.exclude.includes(fileName)) {
|
|
166
|
+
logger.debug(` Excluded: ${mapping.src}/${relPath}`)
|
|
167
|
+
continue
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Apply filename filter (regex must match basename)
|
|
171
|
+
if (mapping.filter && !mapping.filter.test(fileName)) {
|
|
172
|
+
continue
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const srcFile = path.join(srcDir, relPath)
|
|
176
|
+
const destFile = path.join(destDir, relPath)
|
|
177
|
+
|
|
178
|
+
await fse.ensureDir(path.dirname(destFile))
|
|
179
|
+
|
|
180
|
+
// Read, optionally post-process, then write
|
|
181
|
+
const ext = path.extname(relPath).toLowerCase()
|
|
182
|
+
const isText = TEXT_EXTENSIONS.has(ext)
|
|
183
|
+
|
|
184
|
+
if (isText && postProcess) {
|
|
185
|
+
let content = await fse.readFile(srcFile, 'utf8')
|
|
186
|
+
const destRelPath = path.join(mapping.dest, relPath).replace(/\\/g, '/')
|
|
187
|
+
content = postProcess(content, destRelPath)
|
|
188
|
+
await fse.writeFile(destFile, content, 'utf8')
|
|
189
|
+
} else {
|
|
190
|
+
await fse.copy(srcFile, destFile)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
totalFiles++
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
logger.debug(` Mapped ${mapping.src} → ${mapping.dest}`)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return totalFiles
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ─── Plugin Fetch ───────────────────────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Fetch plugin content by cloning a marketplace GitHub repository.
|
|
206
|
+
*
|
|
207
|
+
* @param {{ tmpDir: string, logger: object, registry: object }} opts
|
|
208
|
+
* @returns {Promise<{ sha: string, dir: string }>} HEAD commit SHA and clone directory
|
|
209
|
+
*/
|
|
210
|
+
export async function fetchPlugins({ tmpDir, logger, registry }) {
|
|
211
|
+
const upstream = registry.upstream?.plugins
|
|
212
|
+
if (!upstream?.repo) {
|
|
213
|
+
throw new Error('No plugins upstream configured in registry.json')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const repo = upstream.repo.endsWith('.git') ? upstream.repo : `${upstream.repo}.git`
|
|
217
|
+
const pluginsDir = path.join(tmpDir, 'plugins')
|
|
218
|
+
|
|
219
|
+
logger.debug(`Cloning plugins from ${repo}...`)
|
|
220
|
+
|
|
221
|
+
await execFile('git', ['clone', '--depth', '1', repo, pluginsDir], {
|
|
222
|
+
timeout: 120_000,
|
|
223
|
+
shell: process.platform === 'win32',
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
// Get HEAD SHA
|
|
227
|
+
let sha = 'unknown'
|
|
228
|
+
try {
|
|
229
|
+
const { stdout } = await execFile('git', ['rev-parse', 'HEAD'], {
|
|
230
|
+
cwd: pluginsDir,
|
|
231
|
+
shell: process.platform === 'win32',
|
|
232
|
+
})
|
|
233
|
+
sha = stdout.trim()
|
|
234
|
+
} catch {
|
|
235
|
+
logger.warn('Could not determine plugins commit SHA')
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
logger.debug(`Plugins cloned, SHA: ${sha}`)
|
|
239
|
+
return { sha, dir: pluginsDir }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Build path mappings for plugins based on registry.plugins entries.
|
|
244
|
+
* Each plugin maps from its source directory in the marketplace repo
|
|
245
|
+
* to its destination in templates/plugins/.
|
|
246
|
+
*
|
|
247
|
+
* @param {object} registry - Registry object with plugins section
|
|
248
|
+
* @returns {Array<{ src: string, dest: string }>} Path mappings
|
|
249
|
+
*/
|
|
250
|
+
export function buildPluginMappings(registry) {
|
|
251
|
+
const pluginsPath = registry.upstream?.plugins?.pluginsPath || 'plugins'
|
|
252
|
+
const plugins = registry.plugins || {}
|
|
253
|
+
|
|
254
|
+
return Object.keys(plugins).map(id => ({
|
|
255
|
+
src: `${pluginsPath}/${id}`,
|
|
256
|
+
dest: `plugins/${id}`,
|
|
257
|
+
}))
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ─── External Skills Fetch ─────────────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Fetch external skills by cloning each registered repo and extracting
|
|
264
|
+
* the configured skillPath into a unified output directory.
|
|
265
|
+
*
|
|
266
|
+
* Each skill entry in `registry.upstream['ext-skills']` is cloned
|
|
267
|
+
* independently, allowing skills from different repos to coexist.
|
|
268
|
+
*
|
|
269
|
+
* @param {{ tmpDir: string, logger: object, registry: object }} opts
|
|
270
|
+
* @returns {Promise<{ skills: Record<string, { sha: string }>, dir: string }>}
|
|
271
|
+
*/
|
|
272
|
+
export async function fetchExtSkills({ tmpDir, logger, registry }) {
|
|
273
|
+
const entries = registry.upstream?.['ext-skills'] || {}
|
|
274
|
+
const ids = Object.keys(entries)
|
|
275
|
+
|
|
276
|
+
if (ids.length === 0) {
|
|
277
|
+
throw new Error('No ext-skills upstream configured in registry.json')
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const outputDir = path.join(tmpDir, 'ext-skills')
|
|
281
|
+
await fse.ensureDir(outputDir)
|
|
282
|
+
|
|
283
|
+
const skills = {}
|
|
284
|
+
|
|
285
|
+
for (const id of ids) {
|
|
286
|
+
const entry = entries[id]
|
|
287
|
+
if (entry.type !== 'git' || !entry.repo) {
|
|
288
|
+
logger.warn(`ext-skill "${id}" has invalid config, skipping`)
|
|
289
|
+
continue
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const repo = entry.repo.endsWith('.git') ? entry.repo : `${entry.repo}.git`
|
|
293
|
+
const cloneDir = path.join(tmpDir, `ext-skill-${id}`)
|
|
294
|
+
|
|
295
|
+
logger.debug(`Cloning ext-skill "${id}" from ${repo}...`)
|
|
296
|
+
|
|
297
|
+
await execFile('git', ['clone', '--depth', '1', repo, cloneDir], {
|
|
298
|
+
timeout: 120_000,
|
|
299
|
+
shell: process.platform === 'win32',
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
// Get HEAD SHA
|
|
303
|
+
let sha = 'unknown'
|
|
304
|
+
try {
|
|
305
|
+
const { stdout } = await execFile('git', ['rev-parse', 'HEAD'], {
|
|
306
|
+
cwd: cloneDir,
|
|
307
|
+
shell: process.platform === 'win32',
|
|
308
|
+
})
|
|
309
|
+
sha = stdout.trim()
|
|
310
|
+
} catch {
|
|
311
|
+
logger.warn(`Could not determine commit SHA for ext-skill "${id}"`)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Copy skillPath contents to output/<id>/
|
|
315
|
+
const skillSrc = path.join(cloneDir, entry.skillPath || id)
|
|
316
|
+
const skillDest = path.join(outputDir, id)
|
|
317
|
+
|
|
318
|
+
if (await fse.pathExists(skillSrc)) {
|
|
319
|
+
await fse.copy(skillSrc, skillDest)
|
|
320
|
+
logger.debug(`ext-skill "${id}": copied ${entry.skillPath} → ${id}/, SHA: ${sha}`)
|
|
321
|
+
} else {
|
|
322
|
+
logger.warn(`ext-skill "${id}": skillPath "${entry.skillPath}" not found in repo`)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
skills[id] = { sha }
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return { skills, dir: outputDir }
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Build path mappings for external skills based on registry.upstream['ext-skills'].
|
|
333
|
+
* Each skill maps from its ID subdirectory to templates/ext-skills/<id>.
|
|
334
|
+
*
|
|
335
|
+
* @param {object} registry - Registry object
|
|
336
|
+
* @returns {Array<{ src: string, dest: string }>} Path mappings
|
|
337
|
+
*/
|
|
338
|
+
export function buildExtSkillMappings(registry) {
|
|
339
|
+
const entries = registry.upstream?.['ext-skills'] || {}
|
|
340
|
+
|
|
341
|
+
return Object.keys(entries).map(id => ({
|
|
342
|
+
src: id,
|
|
343
|
+
dest: `ext-skills/${id}`,
|
|
344
|
+
}))
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ─── Temp Directory Helper ──────────────────────────────────────────────────
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Create a uniquely-named temporary directory.
|
|
351
|
+
*
|
|
352
|
+
* @param {string} prefix - Prefix for the temp directory name
|
|
353
|
+
* @returns {Promise<string>} Absolute path to the created directory
|
|
354
|
+
*/
|
|
355
|
+
export async function createTempDir(prefix = 'cckit-sync') {
|
|
356
|
+
return mkdtemp(path.join(os.tmpdir(), `${prefix}-`))
|
|
357
|
+
}
|