@equilateral_ai/mindmeld 3.0.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.
- package/README.md +300 -0
- package/hooks/README.md +494 -0
- package/hooks/pre-compact.js +392 -0
- package/hooks/session-start.js +264 -0
- package/package.json +90 -0
- package/scripts/harvest.js +561 -0
- package/scripts/init-project.js +437 -0
- package/scripts/inject.js +388 -0
- package/src/collaboration/CollaborationPrompt.js +460 -0
- package/src/core/AlertEngine.js +813 -0
- package/src/core/AlertNotifier.js +363 -0
- package/src/core/CorrelationAnalyzer.js +774 -0
- package/src/core/CurationEngine.js +688 -0
- package/src/core/LLMPatternDetector.js +508 -0
- package/src/core/LoadBearingDetector.js +242 -0
- package/src/core/NotificationService.js +1032 -0
- package/src/core/PatternValidator.js +355 -0
- package/src/core/README.md +160 -0
- package/src/core/RapportOrchestrator.js +446 -0
- package/src/core/RelevanceDetector.js +577 -0
- package/src/core/StandardsIngestion.js +575 -0
- package/src/core/TeamLoadBearingDetector.js +431 -0
- package/src/database/dbOperations.js +105 -0
- package/src/handlers/activity/activityGetMe.js +98 -0
- package/src/handlers/activity/activityGetTeam.js +130 -0
- package/src/handlers/alerts/alertsAcknowledge.js +91 -0
- package/src/handlers/alerts/alertsGet.js +250 -0
- package/src/handlers/collaborators/collaboratorAdd.js +201 -0
- package/src/handlers/collaborators/collaboratorInvite.js +218 -0
- package/src/handlers/collaborators/collaboratorList.js +88 -0
- package/src/handlers/collaborators/collaboratorRemove.js +127 -0
- package/src/handlers/collaborators/inviteAccept.js +122 -0
- package/src/handlers/context/contextGet.js +57 -0
- package/src/handlers/context/invariantsGet.js +74 -0
- package/src/handlers/context/loopsGet.js +82 -0
- package/src/handlers/context/notesCreate.js +74 -0
- package/src/handlers/context/purposeGet.js +78 -0
- package/src/handlers/correlations/correlationsDeveloperGet.js +226 -0
- package/src/handlers/correlations/correlationsGet.js +93 -0
- package/src/handlers/correlations/correlationsProjectGet.js +161 -0
- package/src/handlers/github/githubConnectionStatus.js +49 -0
- package/src/handlers/github/githubDiscoverPatterns.js +364 -0
- package/src/handlers/github/githubOAuthCallback.js +166 -0
- package/src/handlers/github/githubOAuthStart.js +59 -0
- package/src/handlers/github/githubPatternsReview.js +109 -0
- package/src/handlers/github/githubReposList.js +105 -0
- package/src/handlers/helpers/checkSuperAdmin.js +85 -0
- package/src/handlers/helpers/dbOperations.js +53 -0
- package/src/handlers/helpers/errorHandler.js +49 -0
- package/src/handlers/helpers/index.js +106 -0
- package/src/handlers/helpers/lambdaWrapper.js +60 -0
- package/src/handlers/helpers/responseUtil.js +55 -0
- package/src/handlers/helpers/subscriptionTiers.js +1168 -0
- package/src/handlers/notifications/getPreferences.js +84 -0
- package/src/handlers/notifications/sendNotification.js +170 -0
- package/src/handlers/notifications/updatePreferences.js +316 -0
- package/src/handlers/patterns/patternUsagePost.js +182 -0
- package/src/handlers/patterns/patternViolationPost.js +185 -0
- package/src/handlers/projects/projectCreate.js +107 -0
- package/src/handlers/projects/projectDelete.js +82 -0
- package/src/handlers/projects/projectGet.js +95 -0
- package/src/handlers/projects/projectUpdate.js +118 -0
- package/src/handlers/reports/aiLeverage.js +206 -0
- package/src/handlers/reports/engineeringInvestment.js +132 -0
- package/src/handlers/reports/riskForecast.js +186 -0
- package/src/handlers/reports/standardsRoi.js +162 -0
- package/src/handlers/scheduled/analyzeCorrelations.js +178 -0
- package/src/handlers/scheduled/analyzeGitHistory.js +510 -0
- package/src/handlers/scheduled/generateAlerts.js +135 -0
- package/src/handlers/scheduled/refreshActivity.js +21 -0
- package/src/handlers/scheduled/scanCompliance.js +334 -0
- package/src/handlers/sessions/sessionEndPost.js +180 -0
- package/src/handlers/sessions/sessionStandardsPost.js +135 -0
- package/src/handlers/stripe/addonManagePost.js +240 -0
- package/src/handlers/stripe/billingPortalPost.js +93 -0
- package/src/handlers/stripe/enterpriseCheckoutPost.js +272 -0
- package/src/handlers/stripe/seatsUpdatePost.js +185 -0
- package/src/handlers/stripe/subscriptionCancelDelete.js +169 -0
- package/src/handlers/stripe/subscriptionCreatePost.js +221 -0
- package/src/handlers/stripe/subscriptionUpdatePut.js +163 -0
- package/src/handlers/stripe/webhookPost.js +454 -0
- package/src/handlers/users/cognitoPostConfirmation.js +150 -0
- package/src/handlers/users/userEntitlementsGet.js +89 -0
- package/src/handlers/users/userGet.js +114 -0
- package/src/handlers/webhooks/githubWebhook.js +223 -0
- package/src/index.js +969 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MindMeld CLI - Inject relevant standards into AI coding tool config
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* mindmeld inject # stdout (raw markdown)
|
|
7
|
+
* mindmeld inject --format cursorrules
|
|
8
|
+
* mindmeld inject --format windsurfrules
|
|
9
|
+
* mindmeld inject --format aider
|
|
10
|
+
* mindmeld inject --format claude # Claude Code hook format
|
|
11
|
+
*
|
|
12
|
+
* @equilateral_ai/mindmeld v3.0.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs').promises;
|
|
17
|
+
|
|
18
|
+
const FORMATS = {
|
|
19
|
+
raw: { file: null, description: 'Raw markdown to stdout' },
|
|
20
|
+
cursorrules: { file: '.cursorrules', description: 'Cursor rules file' },
|
|
21
|
+
windsurfrules: { file: '.windsurfrules', description: 'Windsurf rules file' },
|
|
22
|
+
aider: { file: '.aider.conventions.md', description: 'Aider conventions file' },
|
|
23
|
+
claude: { file: null, description: 'Claude Code hook format (stdout)' }
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function showInjectHelp() {
|
|
27
|
+
console.log(`
|
|
28
|
+
MindMeld inject - Generate context-aware standards for any AI coding tool
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
mindmeld inject [options]
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
--format <type> Output format (default: raw)
|
|
35
|
+
--path <dir> Project path (default: current directory)
|
|
36
|
+
--help, -h Show this help
|
|
37
|
+
|
|
38
|
+
Formats:
|
|
39
|
+
raw Plain markdown to stdout (pipe anywhere)
|
|
40
|
+
cursorrules Write .cursorrules file
|
|
41
|
+
windsurfrules Write .windsurfrules file
|
|
42
|
+
aider Write .aider.conventions.md file
|
|
43
|
+
claude Claude Code hook format (stdout)
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
mindmeld inject # Print standards to stdout
|
|
47
|
+
mindmeld inject --format cursorrules # Update .cursorrules
|
|
48
|
+
mindmeld inject --format aider # Update aider conventions
|
|
49
|
+
mindmeld inject | ollama run qwen3-coder # Pipe to local model
|
|
50
|
+
mindmeld inject --format raw >> system.txt # Append to system prompt
|
|
51
|
+
`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Detect project context by scanning files in the working directory
|
|
56
|
+
*/
|
|
57
|
+
async function detectProjectContext(projectPath) {
|
|
58
|
+
const context = {
|
|
59
|
+
projectName: path.basename(projectPath),
|
|
60
|
+
languages: [],
|
|
61
|
+
frameworks: [],
|
|
62
|
+
files: []
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Check for common project indicators
|
|
66
|
+
const checks = [
|
|
67
|
+
{ file: 'package.json', language: 'javascript', frameworks: ['node'] },
|
|
68
|
+
{ file: 'tsconfig.json', language: 'typescript', frameworks: ['node'] },
|
|
69
|
+
{ file: 'template.yaml', language: 'yaml', frameworks: ['aws-sam'] },
|
|
70
|
+
{ file: 'serverless.yml', language: 'yaml', frameworks: ['serverless'] },
|
|
71
|
+
{ file: 'Dockerfile', language: 'docker', frameworks: ['docker'] },
|
|
72
|
+
{ file: 'requirements.txt', language: 'python', frameworks: [] },
|
|
73
|
+
{ file: 'go.mod', language: 'go', frameworks: [] },
|
|
74
|
+
{ file: 'Cargo.toml', language: 'rust', frameworks: [] },
|
|
75
|
+
{ file: '.terraform', language: 'hcl', frameworks: ['terraform'] }
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
for (const check of checks) {
|
|
79
|
+
try {
|
|
80
|
+
await fs.access(path.join(projectPath, check.file));
|
|
81
|
+
if (!context.languages.includes(check.language)) {
|
|
82
|
+
context.languages.push(check.language);
|
|
83
|
+
}
|
|
84
|
+
context.frameworks.push(...check.frameworks);
|
|
85
|
+
context.files.push(check.file);
|
|
86
|
+
} catch {
|
|
87
|
+
// File doesn't exist
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Check for specific patterns in package.json
|
|
92
|
+
try {
|
|
93
|
+
const pkg = JSON.parse(await fs.readFile(path.join(projectPath, 'package.json'), 'utf-8'));
|
|
94
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
95
|
+
if (deps['react'] || deps['next']) context.frameworks.push('react');
|
|
96
|
+
if (deps['express'] || deps['fastify']) context.frameworks.push('api');
|
|
97
|
+
if (deps['@aws-sdk']) context.frameworks.push('aws');
|
|
98
|
+
if (deps['pg'] || deps['mysql2'] || deps['mongoose']) context.frameworks.push('database');
|
|
99
|
+
} catch {
|
|
100
|
+
// No package.json or can't parse
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return context;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Load and score standards from .equilateral-standards
|
|
108
|
+
*/
|
|
109
|
+
async function getRelevantStandards(projectPath, context) {
|
|
110
|
+
const standardsDir = path.join(projectPath, '.equilateral-standards');
|
|
111
|
+
const standards = [];
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
await fs.access(standardsDir);
|
|
115
|
+
} catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Recursively find all .md standard files from community repo
|
|
120
|
+
async function scanDir(dir) {
|
|
121
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
122
|
+
for (const entry of entries) {
|
|
123
|
+
const fullPath = path.join(dir, entry.name);
|
|
124
|
+
if (entry.isDirectory()) {
|
|
125
|
+
await scanDir(fullPath);
|
|
126
|
+
} else if (entry.name.endsWith('.md') && entry.name !== 'README.md') {
|
|
127
|
+
try {
|
|
128
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
129
|
+
const relativePath = path.relative(standardsDir, fullPath);
|
|
130
|
+
const category = path.dirname(relativePath).replace(/\//g, '/');
|
|
131
|
+
standards.push({
|
|
132
|
+
element: entry.name.replace('.md', '').replace(/_/g, ' '),
|
|
133
|
+
category: category === '.' ? 'general' : category,
|
|
134
|
+
content: content,
|
|
135
|
+
path: relativePath,
|
|
136
|
+
score: 0
|
|
137
|
+
});
|
|
138
|
+
} catch {
|
|
139
|
+
// Skip unreadable files
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
await scanDir(standardsDir);
|
|
146
|
+
|
|
147
|
+
// Score relevance based on project context
|
|
148
|
+
for (const standard of standards) {
|
|
149
|
+
let score = 0;
|
|
150
|
+
const contentLower = standard.content.toLowerCase();
|
|
151
|
+
const categoryLower = standard.category.toLowerCase();
|
|
152
|
+
|
|
153
|
+
// Language match
|
|
154
|
+
for (const lang of context.languages) {
|
|
155
|
+
if (contentLower.includes(lang) || categoryLower.includes(lang)) {
|
|
156
|
+
score += 3;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Framework match
|
|
161
|
+
for (const fw of context.frameworks) {
|
|
162
|
+
if (contentLower.includes(fw) || categoryLower.includes(fw)) {
|
|
163
|
+
score += 5;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Category relevance boost
|
|
168
|
+
if (categoryLower.includes('serverless') && context.frameworks.includes('aws-sam')) score += 4;
|
|
169
|
+
if (categoryLower.includes('api') && context.frameworks.includes('api')) score += 4;
|
|
170
|
+
if (categoryLower.includes('database') && context.frameworks.includes('database')) score += 4;
|
|
171
|
+
if (categoryLower.includes('react') && context.frameworks.includes('react')) score += 4;
|
|
172
|
+
if (categoryLower.includes('cost') && context.frameworks.includes('aws')) score += 3;
|
|
173
|
+
|
|
174
|
+
// Base score for all standards (everyone gets some relevance)
|
|
175
|
+
score += 1;
|
|
176
|
+
|
|
177
|
+
standard.score = score;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Sort by relevance, return top 10
|
|
181
|
+
standards.sort((a, b) => b.score - a.score);
|
|
182
|
+
return standards.slice(0, 10);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Load team patterns from .mindmeld config
|
|
187
|
+
*/
|
|
188
|
+
async function loadTeamPatterns(projectPath) {
|
|
189
|
+
try {
|
|
190
|
+
const configPath = path.join(projectPath, '.mindmeld', 'config.json');
|
|
191
|
+
const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));
|
|
192
|
+
return {
|
|
193
|
+
projectName: config.projectName || path.basename(projectPath),
|
|
194
|
+
collaborators: config.collaborators || [],
|
|
195
|
+
team: config.team || false
|
|
196
|
+
};
|
|
197
|
+
} catch {
|
|
198
|
+
return {
|
|
199
|
+
projectName: path.basename(projectPath),
|
|
200
|
+
collaborators: [],
|
|
201
|
+
team: false
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Format standards as raw markdown
|
|
208
|
+
*/
|
|
209
|
+
function formatRaw(standards, projectInfo, context) {
|
|
210
|
+
const sections = [];
|
|
211
|
+
|
|
212
|
+
sections.push(`# Standards for ${projectInfo.projectName}`);
|
|
213
|
+
sections.push(`<!-- Generated by MindMeld | ${new Date().toISOString()} -->`);
|
|
214
|
+
sections.push(`<!-- Context: ${context.languages.join(', ')} | ${context.frameworks.join(', ')} -->`);
|
|
215
|
+
sections.push('');
|
|
216
|
+
|
|
217
|
+
if (standards.length === 0) {
|
|
218
|
+
sections.push('No standards found. Run `mindmeld init` to set up your project.');
|
|
219
|
+
return sections.join('\n');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
sections.push(`Injecting ${standards.length} relevant standards (of ${standards.length} scored):`);
|
|
223
|
+
sections.push('');
|
|
224
|
+
|
|
225
|
+
for (const standard of standards) {
|
|
226
|
+
sections.push(`## ${standard.element}`);
|
|
227
|
+
sections.push(`**Category**: ${standard.category} | **Relevance**: ${standard.score}`);
|
|
228
|
+
sections.push('');
|
|
229
|
+
// Truncate content to keep injection lean
|
|
230
|
+
const lines = standard.content.split('\n');
|
|
231
|
+
const truncated = lines.slice(0, 30).join('\n');
|
|
232
|
+
sections.push(truncated);
|
|
233
|
+
if (lines.length > 30) {
|
|
234
|
+
sections.push('...');
|
|
235
|
+
}
|
|
236
|
+
sections.push('');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
sections.push('---');
|
|
240
|
+
sections.push('*Generated by MindMeld - mindmeld.dev*');
|
|
241
|
+
|
|
242
|
+
return sections.join('\n');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Format for .cursorrules / .windsurfrules (compact rules format)
|
|
247
|
+
*/
|
|
248
|
+
function formatRulesFile(standards, projectInfo, context) {
|
|
249
|
+
const sections = [];
|
|
250
|
+
|
|
251
|
+
sections.push(`# Project Standards - ${projectInfo.projectName}`);
|
|
252
|
+
sections.push(`# Auto-generated by MindMeld (mindmeld.dev)`);
|
|
253
|
+
sections.push(`# Context: ${context.frameworks.join(', ') || context.languages.join(', ')}`);
|
|
254
|
+
sections.push(`# Run \`mindmeld inject --format ${context._format}\` to regenerate`);
|
|
255
|
+
sections.push('');
|
|
256
|
+
|
|
257
|
+
for (const standard of standards) {
|
|
258
|
+
sections.push(`## ${standard.element}`);
|
|
259
|
+
// Extract just the key rules, not full prose
|
|
260
|
+
const lines = standard.content.split('\n');
|
|
261
|
+
const ruleLines = lines.filter(l =>
|
|
262
|
+
l.startsWith('- ') || l.startsWith('* ') ||
|
|
263
|
+
l.startsWith(' - ') || l.startsWith('> ') ||
|
|
264
|
+
l.match(/^#{1,4}\s/) || l.match(/^\*\*[^*]+\*\*:/)
|
|
265
|
+
).slice(0, 10);
|
|
266
|
+
|
|
267
|
+
if (ruleLines.length > 0) {
|
|
268
|
+
sections.push(ruleLines.join('\n'));
|
|
269
|
+
} else {
|
|
270
|
+
// Fallback: first meaningful paragraph
|
|
271
|
+
const meaningful = lines.filter(l => l.trim().length > 20 && !l.startsWith('#')).slice(0, 3);
|
|
272
|
+
sections.push(meaningful.join('\n'));
|
|
273
|
+
}
|
|
274
|
+
sections.push('');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return sections.join('\n');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Format for aider conventions
|
|
282
|
+
*/
|
|
283
|
+
function formatAider(standards, projectInfo, context) {
|
|
284
|
+
const sections = [];
|
|
285
|
+
|
|
286
|
+
sections.push(`# Coding Conventions - ${projectInfo.projectName}`);
|
|
287
|
+
sections.push('');
|
|
288
|
+
sections.push(`> Auto-generated by MindMeld (mindmeld.dev)`);
|
|
289
|
+
sections.push(`> Run \`mindmeld inject --format aider\` to regenerate`);
|
|
290
|
+
sections.push('');
|
|
291
|
+
|
|
292
|
+
for (const standard of standards) {
|
|
293
|
+
sections.push(`## ${standard.element}`);
|
|
294
|
+
sections.push('');
|
|
295
|
+
// Aider conventions prefer concise bullet points
|
|
296
|
+
const lines = standard.content.split('\n');
|
|
297
|
+
const bullets = lines.filter(l =>
|
|
298
|
+
l.startsWith('- ') || l.startsWith('* ') || l.match(/^\*\*[^*]+\*\*:/)
|
|
299
|
+
).slice(0, 8);
|
|
300
|
+
|
|
301
|
+
if (bullets.length > 0) {
|
|
302
|
+
sections.push(bullets.join('\n'));
|
|
303
|
+
} else {
|
|
304
|
+
const meaningful = lines.filter(l => l.trim().length > 10 && !l.startsWith('#')).slice(0, 4);
|
|
305
|
+
sections.push(meaningful.join('\n'));
|
|
306
|
+
}
|
|
307
|
+
sections.push('');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return sections.join('\n');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Main inject execution
|
|
315
|
+
*/
|
|
316
|
+
async function inject(options = {}) {
|
|
317
|
+
const format = options.format || 'raw';
|
|
318
|
+
const projectPath = options.path || process.cwd();
|
|
319
|
+
|
|
320
|
+
if (!FORMATS[format]) {
|
|
321
|
+
console.error(`Unknown format: ${format}`);
|
|
322
|
+
console.error(`Available: ${Object.keys(FORMATS).join(', ')}`);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Standalone detection (no database, no prompts, works everywhere)
|
|
327
|
+
let standards = [];
|
|
328
|
+
let projectInfo = {};
|
|
329
|
+
let context = {};
|
|
330
|
+
|
|
331
|
+
context = await detectProjectContext(projectPath);
|
|
332
|
+
standards = await getRelevantStandards(projectPath, context);
|
|
333
|
+
projectInfo = await loadTeamPatterns(projectPath);
|
|
334
|
+
|
|
335
|
+
context._format = format;
|
|
336
|
+
|
|
337
|
+
// 2. Format output
|
|
338
|
+
let output;
|
|
339
|
+
switch (format) {
|
|
340
|
+
case 'cursorrules':
|
|
341
|
+
case 'windsurfrules':
|
|
342
|
+
output = formatRulesFile(standards, projectInfo, context);
|
|
343
|
+
break;
|
|
344
|
+
case 'aider':
|
|
345
|
+
output = formatAider(standards, projectInfo, context);
|
|
346
|
+
break;
|
|
347
|
+
case 'claude':
|
|
348
|
+
// Use the session-start formatter with mapped fields
|
|
349
|
+
try {
|
|
350
|
+
const { formatContextInjection } = require('../hooks/session-start');
|
|
351
|
+
const mappedStandards = standards.map(s => ({
|
|
352
|
+
element: s.element,
|
|
353
|
+
category: s.category,
|
|
354
|
+
rule: s.content.split('\n').find(l => l.trim().length > 10 && !l.startsWith('#')) || s.element
|
|
355
|
+
}));
|
|
356
|
+
output = formatContextInjection({
|
|
357
|
+
project: projectInfo.projectName,
|
|
358
|
+
relevantStandards: mappedStandards,
|
|
359
|
+
teamPatterns: [],
|
|
360
|
+
recentLearning: [],
|
|
361
|
+
collaborators: projectInfo.collaborators || []
|
|
362
|
+
});
|
|
363
|
+
} catch {
|
|
364
|
+
output = formatRaw(standards, projectInfo, context);
|
|
365
|
+
}
|
|
366
|
+
break;
|
|
367
|
+
case 'raw':
|
|
368
|
+
default:
|
|
369
|
+
output = formatRaw(standards, projectInfo, context);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// 3. Write to file or stdout
|
|
374
|
+
const targetFile = FORMATS[format].file;
|
|
375
|
+
|
|
376
|
+
if (targetFile) {
|
|
377
|
+
const targetPath = path.join(projectPath, targetFile);
|
|
378
|
+
await fs.writeFile(targetPath, output);
|
|
379
|
+
console.error(`[MindMeld] Written ${standards.length} standards to ${targetFile}`);
|
|
380
|
+
console.error(`[MindMeld] Context: ${context.languages ? context.languages.join(', ') : 'unknown'} | ${context.frameworks ? context.frameworks.join(', ') : ''}`);
|
|
381
|
+
console.error(`[MindMeld] Regenerate anytime: mindmeld inject --format ${format}`);
|
|
382
|
+
} else {
|
|
383
|
+
// Output to stdout (for piping)
|
|
384
|
+
console.log(output);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
module.exports = { inject, showInjectHelp, FORMATS };
|