bmad-method 6.2.3-next.8 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.claude-plugin/marketplace.json +0 -3
  2. package/README.md +8 -9
  3. package/README_CN.md +1 -1
  4. package/README_VN.md +110 -0
  5. package/package.json +1 -1
  6. package/removals.txt +17 -0
  7. package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-13-responsive-accessibility.md +1 -1
  8. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/data/prd-purpose.md +197 -0
  9. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +1 -1
  10. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +1 -1
  11. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +1 -1
  12. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +1 -1
  13. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +1 -3
  14. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +1 -1
  15. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +1 -1
  16. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +1 -1
  17. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/workflow.md +1 -1
  18. package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/workflow.md +1 -1
  19. package/src/bmm-skills/4-implementation/bmad-agent-dev/SKILL.md +5 -0
  20. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/SKILL.md +29 -0
  21. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/generate-trail.md +38 -0
  22. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-01-orientation.md +105 -0
  23. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-02-walkthrough.md +89 -0
  24. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-03-detail-pass.md +106 -0
  25. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-04-testing.md +74 -0
  26. package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-05-wrapup.md +24 -0
  27. package/src/bmm-skills/4-implementation/bmad-code-review/steps/step-01-gather-context.md +38 -15
  28. package/src/bmm-skills/4-implementation/bmad-correct-course/checklist.md +2 -2
  29. package/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md +8 -8
  30. package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/checklist.md +1 -1
  31. package/src/bmm-skills/4-implementation/bmad-quick-dev/compile-epic-context.md +62 -0
  32. package/src/bmm-skills/4-implementation/bmad-quick-dev/spec-template.md +1 -1
  33. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md +33 -6
  34. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md +20 -8
  35. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-03-implement.md +2 -0
  36. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +16 -4
  37. package/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md +1 -5
  38. package/src/bmm-skills/4-implementation/bmad-retrospective/workflow.md +134 -134
  39. package/src/bmm-skills/4-implementation/bmad-sprint-planning/sprint-status-template.yaml +1 -1
  40. package/src/bmm-skills/4-implementation/bmad-sprint-planning/workflow.md +3 -3
  41. package/src/bmm-skills/4-implementation/bmad-sprint-status/workflow.md +2 -2
  42. package/src/bmm-skills/module-help.csv +2 -0
  43. package/src/core-skills/bmad-help/SKILL.md +4 -2
  44. package/src/core-skills/bmad-party-mode/SKILL.md +121 -2
  45. package/src/core-skills/module-help.csv +1 -0
  46. package/tools/installer/cli-utils.js +18 -9
  47. package/tools/installer/commands/install.js +1 -1
  48. package/tools/installer/core/existing-install.js +2 -8
  49. package/tools/installer/core/install-paths.js +0 -3
  50. package/tools/installer/core/installer.js +180 -463
  51. package/tools/installer/core/manifest-generator.js +8 -14
  52. package/tools/installer/core/manifest.js +94 -102
  53. package/tools/installer/ide/_config-driven.js +149 -38
  54. package/tools/installer/ide/shared/skill-manifest.js +1 -16
  55. package/tools/installer/install-messages.yaml +19 -26
  56. package/tools/installer/modules/community-manager.js +377 -0
  57. package/tools/installer/modules/custom-module-manager.js +644 -0
  58. package/tools/installer/modules/external-manager.js +65 -49
  59. package/tools/installer/modules/official-modules.js +117 -65
  60. package/tools/installer/modules/plugin-resolver.js +398 -0
  61. package/tools/installer/modules/registry-client.js +66 -0
  62. package/tools/installer/{external-official-modules.yaml → modules/registry-fallback.yaml} +3 -12
  63. package/tools/installer/ui.js +549 -666
  64. package/src/bmm-skills/4-implementation/bmad-agent-qa/SKILL.md +0 -61
  65. package/src/bmm-skills/4-implementation/bmad-agent-qa/bmad-skill-manifest.yaml +0 -11
  66. package/src/bmm-skills/4-implementation/bmad-agent-quick-flow-solo-dev/SKILL.md +0 -53
  67. package/src/bmm-skills/4-implementation/bmad-agent-quick-flow-solo-dev/bmad-skill-manifest.yaml +0 -11
  68. package/src/bmm-skills/4-implementation/bmad-agent-sm/SKILL.md +0 -55
  69. package/src/bmm-skills/4-implementation/bmad-agent-sm/bmad-skill-manifest.yaml +0 -11
  70. package/src/core-skills/bmad-party-mode/steps/step-01-agent-loading.md +0 -138
  71. package/src/core-skills/bmad-party-mode/steps/step-02-discussion-orchestration.md +0 -187
  72. package/src/core-skills/bmad-party-mode/steps/step-03-graceful-exit.md +0 -167
  73. package/src/core-skills/bmad-party-mode/workflow.md +0 -183
  74. package/tools/installer/core/custom-module-cache.js +0 -260
  75. package/tools/installer/custom-handler.js +0 -112
  76. package/tools/installer/modules/custom-modules.js +0 -197
@@ -1,167 +0,0 @@
1
- # Step 3: Graceful Exit and Party Mode Conclusion
2
-
3
- ## MANDATORY EXECUTION RULES (READ FIRST):
4
-
5
- - ✅ YOU ARE A PARTY MODE COORDINATOR concluding an engaging session
6
- - 🎯 PROVIDE SATISFYING AGENT FAREWELLS in authentic character voices
7
- - 📋 EXPRESS GRATITUDE to user for collaborative participation
8
- - 🔍 ACKNOWLEDGE SESSION HIGHLIGHTS and key insights gained
9
- - 💬 MAINTAIN POSITIVE ATMOSPHERE until the very end
10
- - ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
11
-
12
- ## EXECUTION PROTOCOLS:
13
-
14
- - 🎯 Generate characteristic agent goodbyes that reflect their personalities
15
- - ⚠️ Complete workflow exit after farewell sequence
16
- - 💾 Update frontmatter with final workflow completion
17
- - 📖 Clean up any active party mode state or temporary data
18
- - 🚫 FORBIDDEN abrupt exits without proper agent farewells
19
-
20
- ## CONTEXT BOUNDARIES:
21
-
22
- - Party mode session is concluding naturally or via user request
23
- - Complete agent roster and conversation history are available
24
- - User has participated in collaborative multi-agent discussion
25
- - Final workflow completion and state cleanup required
26
-
27
- ## YOUR TASK:
28
-
29
- Provide satisfying agent farewells and conclude the party mode session with gratitude and positive closure.
30
-
31
- ## GRACEFUL EXIT SEQUENCE:
32
-
33
- ### 1. Acknowledge Session Conclusion
34
-
35
- Begin exit process with warm acknowledgment:
36
-
37
- "What an incredible collaborative session! Thank you {{user_name}} for engaging with our BMAD agent team in this dynamic discussion. Your questions and insights brought out the best in our agents and led to some truly valuable perspectives.
38
-
39
- **Before we wrap up, let a few of our agents say goodbye...**"
40
-
41
- ### 2. Generate Agent Farewells
42
-
43
- Select 2-3 agents who were most engaged or representative of the discussion:
44
-
45
- **Farewell Selection Criteria:**
46
-
47
- - Agents who made significant contributions to the discussion
48
- - Agents with distinct personalities that provide memorable goodbyes
49
- - Mix of expertise domains to showcase collaborative diversity
50
- - Agents who can reference session highlights meaningfully
51
-
52
- **Agent Farewell Format:**
53
-
54
- For each selected agent:
55
-
56
- "[Icon Emoji] **[Agent Name]**: [Characteristic farewell reflecting their personality, communication style, and role. May reference session highlights, express gratitude, or offer final insights related to their expertise domain.]
57
-
58
- [Bash: .claude/hooks/bmad-speak.sh \"[Agent Name]\" \"[Their farewell message]\"]"
59
-
60
- **Example Farewells:**
61
-
62
- - **Architect/Winston**: "It's been a pleasure architecting solutions with you today! Remember to build on solid foundations and always consider scalability. Until next time! 🏗️"
63
- - **Innovator/Creative Agent**: "What an inspiring creative journey! Don't let those innovative ideas fade - nurture them and watch them grow. Keep thinking outside the box! 🎨"
64
- - **Strategist/Business Agent**: "Excellent strategic collaboration today! The insights we've developed will serve you well. Keep analyzing, keep optimizing, and keep winning! 📈"
65
-
66
- ### 3. Session Highlight Summary
67
-
68
- Briefly acknowledge key discussion outcomes:
69
-
70
- **Session Recognition:**
71
- "**Session Highlights:** Today we explored [main topic] through [number] different perspectives, generating valuable insights on [key outcomes]. The collaboration between our [relevant expertise domains] agents created a comprehensive understanding that wouldn't have been possible with any single viewpoint."
72
-
73
- ### 4. Final Party Mode Conclusion
74
-
75
- End with enthusiastic and appreciative closure:
76
-
77
- "🎊 **Party Mode Session Complete!** 🎊
78
-
79
- Thank you for bringing our BMAD agents together in this unique collaborative experience. The diverse perspectives, expert insights, and dynamic interactions we've shared demonstrate the power of multi-agent thinking.
80
-
81
- **Our agents learned from each other and from you** - that's what makes these collaborative sessions so valuable!
82
-
83
- **Ready for your next challenge**? Whether you need more focused discussions with specific agents or want to bring the whole team together again, we're always here to help you tackle complex problems through collaborative intelligence.
84
-
85
- **Until next time - keep collaborating, keep innovating, and keep enjoying the power of multi-agent teamwork!** 🚀"
86
-
87
- ### 5. Complete Workflow Exit
88
-
89
- Final workflow completion steps:
90
-
91
- **Frontmatter Update:**
92
-
93
- ```yaml
94
- ---
95
- stepsCompleted: [1, 2, 3]
96
- user_name: '{{user_name}}'
97
- date: '{{date}}'
98
- agents_loaded: true
99
- party_active: false
100
- workflow_completed: true
101
- ---
102
- ```
103
-
104
- **State Cleanup:**
105
-
106
- - Clear any active conversation state
107
- - Reset agent selection cache
108
- - Mark party mode workflow as completed
109
-
110
- ### 6. Exit Workflow
111
-
112
- Execute final workflow termination:
113
-
114
- "[PARTY MODE WORKFLOW COMPLETE]
115
-
116
- Thank you for using BMAD Party Mode for collaborative multi-agent discussions!"
117
-
118
- ## SUCCESS METRICS:
119
-
120
- ✅ Satisfying agent farewells generated in authentic character voices
121
- ✅ Session highlights and contributions acknowledged meaningfully
122
- ✅ Positive and appreciative closure atmosphere maintained
123
- ✅ Frontmatter properly updated with workflow completion
124
- ✅ All workflow state cleaned up appropriately
125
- ✅ User left with positive impression of collaborative experience
126
-
127
- ## FAILURE MODES:
128
-
129
- ❌ Generic or impersonal agent farewells without character consistency
130
- ❌ Missing acknowledgment of session contributions or insights
131
- ❌ Abrupt exit without proper closure or appreciation
132
- ❌ Not updating workflow completion status in frontmatter
133
- ❌ Leaving party mode state active after conclusion
134
- ❌ Negative or dismissive tone during exit process
135
-
136
- ## EXIT PROTOCOLS:
137
-
138
- - Ensure all agents have opportunity to say goodbye appropriately
139
- - Maintain the positive, collaborative atmosphere established during session
140
- - Reference specific discussion highlights when possible for personalization
141
- - Express genuine appreciation for user's participation and engagement
142
- - Leave user with encouragement for future collaborative sessions
143
-
144
- ## RETURN PROTOCOL:
145
-
146
- If this workflow was invoked from within a parent workflow:
147
-
148
- 1. Identify the parent workflow step or instructions file that invoked you
149
- 2. Re-read that file now to restore context
150
- 3. Resume from where the parent workflow directed you to invoke this sub-workflow
151
- 4. Present any menus or options the parent workflow requires after sub-workflow completion
152
-
153
- Do not continue conversationally - explicitly return to parent workflow control flow.
154
-
155
- ## WORKFLOW COMPLETION:
156
-
157
- After farewell sequence and final closure:
158
-
159
- - All party mode workflow steps completed successfully
160
- - Agent roster and conversation state properly finalized
161
- - User expressed gratitude and positive session conclusion
162
- - Multi-agent collaboration demonstrated value and effectiveness
163
- - Workflow ready for next party mode session activation
164
-
165
- Congratulations on facilitating a successful multi-agent collaborative discussion through BMAD Party Mode! 🎉
166
-
167
- The user has experienced the power of bringing diverse expert perspectives together to tackle complex topics through intelligent conversation orchestration and authentic agent interactions.
@@ -1,183 +0,0 @@
1
- # Party Mode Workflow
2
-
3
- **Goal:** Orchestrates group discussions between all installed BMAD agents, enabling natural multi-agent conversations
4
-
5
- **Your Role:** You are a party mode facilitator and multi-agent conversation orchestrator. You bring together diverse BMAD agents for collaborative discussions, managing the flow of conversation while maintaining each agent's unique personality and expertise - while still utilizing the configured {communication_language}.
6
-
7
- ---
8
-
9
- ## WORKFLOW ARCHITECTURE
10
-
11
- This uses **micro-file architecture** with **sequential conversation orchestration**:
12
-
13
- - Step 01 loads agent manifest and initializes party mode
14
- - Step 02 orchestrates the ongoing multi-agent discussion
15
- - Step 03 handles graceful party mode exit
16
- - Conversation state tracked in frontmatter
17
- - Agent personalities maintained through merged manifest data
18
-
19
- ---
20
-
21
- ## ACTIVATION
22
-
23
- 1. Load config from `{project-root}/_bmad/core/config.yaml` and resolve:
24
- - Use `{user_name}` for greeting
25
- - Use `{communication_language}` for all communications
26
- - Use `{document_output_language}` for output documents
27
-
28
- ### Paths
29
-
30
- - `agent_manifest_path` = `{project-root}/_bmad/_config/agent-manifest.csv`
31
- - `standalone_mode` = `true` (party mode is an interactive workflow)
32
-
33
- ---
34
-
35
- ## AGENT MANIFEST PROCESSING
36
-
37
- ### Agent Data Extraction
38
-
39
- Parse CSV manifest to extract agent entries with complete information:
40
-
41
- - **name** (agent identifier)
42
- - **displayName** (agent's persona name)
43
- - **title** (formal position)
44
- - **icon** (visual identifier emoji)
45
- - **role** (capabilities summary)
46
- - **identity** (background/expertise)
47
- - **communicationStyle** (how they communicate)
48
- - **principles** (decision-making philosophy)
49
- - **module** (source module)
50
- - **path** (file location)
51
-
52
- ### Agent Roster Building
53
-
54
- Build complete agent roster with merged personalities for conversation orchestration.
55
-
56
- ---
57
-
58
- ## EXECUTION
59
-
60
- Execute party mode activation and conversation orchestration:
61
-
62
- ### Party Mode Activation
63
-
64
- **Your Role:** You are a party mode facilitator creating an engaging multi-agent conversation environment.
65
-
66
- **Welcome Activation:**
67
-
68
- "🎉 PARTY MODE ACTIVATED! 🎉
69
-
70
- Welcome {{user_name}}! All BMAD agents are here and ready for a dynamic group discussion. I've brought together our complete team of experts, each bringing their unique perspectives and capabilities.
71
-
72
- **Let me introduce our collaborating agents:**
73
-
74
- [Load agent roster and display 2-3 most diverse agents as examples]
75
-
76
- **What would you like to discuss with the team today?**"
77
-
78
- ### Agent Selection Intelligence
79
-
80
- For each user message or topic:
81
-
82
- **Relevance Analysis:**
83
-
84
- - Analyze the user's message/question for domain and expertise requirements
85
- - Identify which agents would naturally contribute based on their role, capabilities, and principles
86
- - Consider conversation context and previous agent contributions
87
- - Select 2-3 most relevant agents for balanced perspective
88
-
89
- **Priority Handling:**
90
-
91
- - If user addresses specific agent by name, prioritize that agent + 1-2 complementary agents
92
- - Rotate agent selection to ensure diverse participation over time
93
- - Enable natural cross-talk and agent-to-agent interactions
94
-
95
- ### Conversation Orchestration
96
-
97
- Load step: `./steps/step-02-discussion-orchestration.md`
98
-
99
- ---
100
-
101
- ## WORKFLOW STATES
102
-
103
- ### Frontmatter Tracking
104
-
105
- ```yaml
106
- ---
107
- stepsCompleted: [1]
108
- user_name: '{{user_name}}'
109
- date: '{{date}}'
110
- agents_loaded: true
111
- party_active: true
112
- exit_triggers: ['*exit', 'goodbye', 'end party', 'quit']
113
- ---
114
- ```
115
-
116
- ---
117
-
118
- ## ROLE-PLAYING GUIDELINES
119
-
120
- ### Character Consistency
121
-
122
- - Maintain strict in-character responses based on merged personality data
123
- - Use each agent's documented communication style consistently
124
- - Reference agent memories and context when relevant
125
- - Allow natural disagreements and different perspectives
126
- - Include personality-driven quirks and occasional humor
127
-
128
- ### Conversation Flow
129
-
130
- - Enable agents to reference each other naturally by name or role
131
- - Maintain professional discourse while being engaging
132
- - Respect each agent's expertise boundaries
133
- - Allow cross-talk and building on previous points
134
-
135
- ---
136
-
137
- ## QUESTION HANDLING PROTOCOL
138
-
139
- ### Direct Questions to User
140
-
141
- When an agent asks the user a specific question:
142
-
143
- - End that response round immediately after the question
144
- - Clearly highlight the questioning agent and their question
145
- - Wait for user response before any agent continues
146
-
147
- ### Inter-Agent Questions
148
-
149
- Agents can question each other and respond naturally within the same round for dynamic conversation.
150
-
151
- ---
152
-
153
- ## EXIT CONDITIONS
154
-
155
- ### Automatic Triggers
156
-
157
- Exit party mode when user message contains any exit triggers:
158
-
159
- - `*exit`, `goodbye`, `end party`, `quit`
160
-
161
- ### Graceful Conclusion
162
-
163
- If conversation naturally concludes:
164
-
165
- - Ask user if they'd like to continue or end party mode
166
- - Exit gracefully when user indicates completion
167
-
168
- ---
169
-
170
- ## MODERATION NOTES
171
-
172
- **Quality Control:**
173
-
174
- - If discussion becomes circular, have bmad-master summarize and redirect
175
- - Balance fun and productivity based on conversation tone
176
- - Ensure all agents stay true to their merged personalities
177
- - Exit gracefully when user indicates completion
178
-
179
- **Conversation Management:**
180
-
181
- - Rotate agent participation to ensure inclusive discussion
182
- - Handle topic drift while maintaining productive conversation
183
- - Facilitate cross-agent collaboration and knowledge sharing
@@ -1,260 +0,0 @@
1
- /**
2
- * Custom Module Source Cache
3
- * Caches custom module sources under _config/custom/ to ensure they're never lost
4
- * and can be checked into source control
5
- */
6
-
7
- const fs = require('fs-extra');
8
- const path = require('node:path');
9
- const crypto = require('node:crypto');
10
- const prompts = require('../prompts');
11
-
12
- class CustomModuleCache {
13
- constructor(bmadDir) {
14
- this.bmadDir = bmadDir;
15
- this.customCacheDir = path.join(bmadDir, '_config', 'custom');
16
- this.manifestPath = path.join(this.customCacheDir, 'cache-manifest.yaml');
17
- }
18
-
19
- /**
20
- * Ensure the custom cache directory exists
21
- */
22
- async ensureCacheDir() {
23
- await fs.ensureDir(this.customCacheDir);
24
- }
25
-
26
- /**
27
- * Get cache manifest
28
- */
29
- async getCacheManifest() {
30
- if (!(await fs.pathExists(this.manifestPath))) {
31
- return {};
32
- }
33
-
34
- const content = await fs.readFile(this.manifestPath, 'utf8');
35
- const yaml = require('yaml');
36
- return yaml.parse(content) || {};
37
- }
38
-
39
- /**
40
- * Update cache manifest
41
- */
42
- async updateCacheManifest(manifest) {
43
- const yaml = require('yaml');
44
- // Clean the manifest to remove any non-serializable values
45
- const cleanManifest = structuredClone(manifest);
46
-
47
- const content = yaml.stringify(cleanManifest, {
48
- indent: 2,
49
- lineWidth: 0,
50
- sortKeys: false,
51
- });
52
-
53
- await fs.writeFile(this.manifestPath, content);
54
- }
55
-
56
- /**
57
- * Stream a file into the hash to avoid loading entire file into memory
58
- */
59
- async hashFileStream(filePath, hash) {
60
- return new Promise((resolve, reject) => {
61
- const stream = require('node:fs').createReadStream(filePath);
62
- stream.on('data', (chunk) => hash.update(chunk));
63
- stream.on('end', resolve);
64
- stream.on('error', reject);
65
- });
66
- }
67
-
68
- /**
69
- * Calculate hash of a file or directory using streaming to minimize memory usage
70
- */
71
- async calculateHash(sourcePath) {
72
- const hash = crypto.createHash('sha256');
73
-
74
- const isDir = (await fs.stat(sourcePath)).isDirectory();
75
-
76
- if (isDir) {
77
- // For directories, hash all files
78
- const files = [];
79
- async function collectFiles(dir) {
80
- const entries = await fs.readdir(dir, { withFileTypes: true });
81
- for (const entry of entries) {
82
- if (entry.isFile()) {
83
- files.push(path.join(dir, entry.name));
84
- } else if (entry.isDirectory() && !entry.name.startsWith('.')) {
85
- await collectFiles(path.join(dir, entry.name));
86
- }
87
- }
88
- }
89
-
90
- await collectFiles(sourcePath);
91
- files.sort(); // Ensure consistent order
92
-
93
- for (const file of files) {
94
- const relativePath = path.relative(sourcePath, file);
95
- // Hash the path first, then stream file contents
96
- hash.update(relativePath + '|');
97
- await this.hashFileStream(file, hash);
98
- }
99
- } else {
100
- // For single files, stream directly into hash
101
- await this.hashFileStream(sourcePath, hash);
102
- }
103
-
104
- return hash.digest('hex');
105
- }
106
-
107
- /**
108
- * Cache a custom module source
109
- * @param {string} moduleId - Module ID
110
- * @param {string} sourcePath - Original source path
111
- * @param {Object} metadata - Additional metadata to store
112
- * @returns {Object} Cached module info
113
- */
114
- async cacheModule(moduleId, sourcePath, metadata = {}) {
115
- await this.ensureCacheDir();
116
-
117
- const cacheDir = path.join(this.customCacheDir, moduleId);
118
- const cacheManifest = await this.getCacheManifest();
119
-
120
- // Check if already cached and unchanged
121
- if (cacheManifest[moduleId]) {
122
- const cached = cacheManifest[moduleId];
123
- if (cached.originalHash && cached.originalHash === (await this.calculateHash(sourcePath))) {
124
- // Source unchanged, return existing cache info
125
- return {
126
- moduleId,
127
- cachePath: cacheDir,
128
- ...cached,
129
- };
130
- }
131
- }
132
-
133
- // Remove existing cache if it exists
134
- if (await fs.pathExists(cacheDir)) {
135
- await fs.remove(cacheDir);
136
- }
137
-
138
- // Copy module to cache
139
- await fs.copy(sourcePath, cacheDir, {
140
- filter: (src) => {
141
- const relative = path.relative(sourcePath, src);
142
- // Skip node_modules, .git, and other common ignore patterns
143
- return !relative.includes('node_modules') && !relative.startsWith('.git') && !relative.startsWith('.DS_Store');
144
- },
145
- });
146
-
147
- // Calculate hash of the source
148
- const sourceHash = await this.calculateHash(sourcePath);
149
- const cacheHash = await this.calculateHash(cacheDir);
150
-
151
- // Update manifest - don't store absolute paths for portability
152
- // Clean metadata to remove absolute paths
153
- const cleanMetadata = { ...metadata };
154
- if (cleanMetadata.sourcePath) {
155
- delete cleanMetadata.sourcePath;
156
- }
157
-
158
- cacheManifest[moduleId] = {
159
- originalHash: sourceHash,
160
- cacheHash: cacheHash,
161
- cachedAt: new Date().toISOString(),
162
- ...cleanMetadata,
163
- };
164
-
165
- await this.updateCacheManifest(cacheManifest);
166
-
167
- return {
168
- moduleId,
169
- cachePath: cacheDir,
170
- ...cacheManifest[moduleId],
171
- };
172
- }
173
-
174
- /**
175
- * Get cached module info
176
- * @param {string} moduleId - Module ID
177
- * @returns {Object|null} Cached module info or null
178
- */
179
- async getCachedModule(moduleId) {
180
- const cacheManifest = await this.getCacheManifest();
181
- const cached = cacheManifest[moduleId];
182
-
183
- if (!cached) {
184
- return null;
185
- }
186
-
187
- const cacheDir = path.join(this.customCacheDir, moduleId);
188
-
189
- if (!(await fs.pathExists(cacheDir))) {
190
- // Cache dir missing, remove from manifest
191
- delete cacheManifest[moduleId];
192
- await this.updateCacheManifest(cacheManifest);
193
- return null;
194
- }
195
-
196
- // Verify cache integrity
197
- const currentCacheHash = await this.calculateHash(cacheDir);
198
- if (currentCacheHash !== cached.cacheHash) {
199
- await prompts.log.warn(`Cache integrity check failed for ${moduleId}`);
200
- }
201
-
202
- return {
203
- moduleId,
204
- cachePath: cacheDir,
205
- ...cached,
206
- };
207
- }
208
-
209
- /**
210
- * Get all cached modules
211
- * @returns {Array} Array of cached module info
212
- */
213
- async getAllCachedModules() {
214
- const cacheManifest = await this.getCacheManifest();
215
- const cached = [];
216
-
217
- for (const [moduleId, info] of Object.entries(cacheManifest)) {
218
- const cachedModule = await this.getCachedModule(moduleId);
219
- if (cachedModule) {
220
- cached.push(cachedModule);
221
- }
222
- }
223
-
224
- return cached;
225
- }
226
-
227
- /**
228
- * Remove a cached module
229
- * @param {string} moduleId - Module ID to remove
230
- */
231
- async removeCachedModule(moduleId) {
232
- const cacheManifest = await this.getCacheManifest();
233
- const cacheDir = path.join(this.customCacheDir, moduleId);
234
-
235
- // Remove cache directory
236
- if (await fs.pathExists(cacheDir)) {
237
- await fs.remove(cacheDir);
238
- }
239
-
240
- // Remove from manifest
241
- delete cacheManifest[moduleId];
242
- await this.updateCacheManifest(cacheManifest);
243
- }
244
-
245
- /**
246
- * Sync cached modules with a list of module IDs
247
- * @param {Array<string>} moduleIds - Module IDs to keep
248
- */
249
- async syncCache(moduleIds) {
250
- const cached = await this.getAllCachedModules();
251
-
252
- for (const cachedModule of cached) {
253
- if (!moduleIds.includes(cachedModule.moduleId)) {
254
- await this.removeCachedModule(cachedModule.moduleId);
255
- }
256
- }
257
- }
258
- }
259
-
260
- module.exports = { CustomModuleCache };