@equilateral_ai/mindmeld 3.5.3 → 4.0.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/hooks/session-start.js +312 -85
- package/package.json +20 -14
- package/scripts/init-project.js +9 -23
- package/src/client/dbShim.js +16 -0
- package/src/core/AuthManager.js +3 -2
- package/src/handlers/helpers/dbOperations.js +9 -46
- package/src/index.js +2 -217
- package/src/utils/piiMask.js +16 -0
- package/scripts/harvest.js +0 -601
- package/scripts/inject.js +0 -409
- package/scripts/mcp-bridge.js +0 -220
- package/scripts/repo-analyzer.js +0 -870
- package/scripts/standards.js +0 -285
- package/src/collaboration/CollaborationPrompt.js +0 -460
- package/src/core/AlertEngine.js +0 -813
- package/src/core/AlertNotifier.js +0 -363
- package/src/core/CorrelationAnalyzer.js +0 -931
- package/src/core/CrossReferenceEngine.js +0 -624
- package/src/core/CurationEngine.js +0 -688
- package/src/core/DeprecationScheduler.js +0 -183
- package/src/core/LoadBearingDetector.js +0 -242
- package/src/core/NotificationService.js +0 -1032
- package/src/core/RapportOrchestrator.js +0 -632
- package/src/core/RelevanceDetector.js +0 -694
- package/src/core/StandardLifecycle.js +0 -244
- package/src/core/StandardsIngestion.js +0 -991
- package/src/core/TeamLoadBearingDetector.js +0 -431
- package/src/core/parsers/adrParser.js +0 -479
- package/src/core/parsers/cursorRulesParser.js +0 -564
- package/src/core/parsers/eslintParser.js +0 -439
- package/src/database/dbOperations.js +0 -105
- package/src/handlers/activity/activityGetMe.js +0 -98
- package/src/handlers/activity/activityGetTeam.js +0 -175
- package/src/handlers/admin/adminSetup.js +0 -216
- package/src/handlers/alerts/alertsAcknowledge.js +0 -92
- package/src/handlers/alerts/alertsGet.js +0 -250
- package/src/handlers/analytics/activitySummaryGet.js +0 -234
- package/src/handlers/analytics/coachingGet.js +0 -361
- package/src/handlers/analytics/convergenceGet.js +0 -236
- package/src/handlers/analytics/developerScoreGet.js +0 -137
- package/src/handlers/collaborators/collaboratorAdd.js +0 -200
- package/src/handlers/collaborators/collaboratorInvite.js +0 -219
- package/src/handlers/collaborators/collaboratorList.js +0 -82
- package/src/handlers/collaborators/collaboratorRemove.js +0 -128
- package/src/handlers/collaborators/inviteAccept.js +0 -122
- package/src/handlers/company/companyUsersDelete.js +0 -141
- package/src/handlers/company/companyUsersGet.js +0 -90
- package/src/handlers/company/companyUsersPost.js +0 -267
- package/src/handlers/company/companyUsersPut.js +0 -76
- package/src/handlers/context/contextGet.js +0 -57
- package/src/handlers/context/invariantsGet.js +0 -74
- package/src/handlers/context/loopsGet.js +0 -82
- package/src/handlers/context/notesCreate.js +0 -74
- package/src/handlers/context/purposeGet.js +0 -78
- package/src/handlers/correlations/correlationsDeveloperGet.js +0 -227
- package/src/handlers/correlations/correlationsGet.js +0 -93
- package/src/handlers/correlations/correlationsProjectGet.js +0 -153
- package/src/handlers/enterprise/controlTowerGet.js +0 -224
- package/src/handlers/enterprise/enterpriseAuditGet.js +0 -108
- package/src/handlers/enterprise/enterpriseContributorsGet.js +0 -85
- package/src/handlers/enterprise/enterpriseKnowledgeCategoriesGet.js +0 -53
- package/src/handlers/enterprise/enterpriseKnowledgeCreate.js +0 -77
- package/src/handlers/enterprise/enterpriseKnowledgeDelete.js +0 -71
- package/src/handlers/enterprise/enterpriseKnowledgeGet.js +0 -87
- package/src/handlers/enterprise/enterpriseKnowledgeUpdate.js +0 -122
- package/src/handlers/enterprise/enterpriseOnboardingComplete.js +0 -77
- package/src/handlers/enterprise/enterpriseOnboardingInvite.js +0 -138
- package/src/handlers/enterprise/enterpriseOnboardingSetup.js +0 -128
- package/src/handlers/enterprise/enterpriseOnboardingStatus.js +0 -88
- package/src/handlers/github/githubConnectionStatus.js +0 -49
- package/src/handlers/github/githubDiscoverPatterns.js +0 -621
- package/src/handlers/github/githubOAuthCallback.js +0 -178
- package/src/handlers/github/githubOAuthStart.js +0 -59
- package/src/handlers/github/githubPatternsReview.js +0 -76
- package/src/handlers/github/githubReposList.js +0 -105
- package/src/handlers/health/healthGet.js +0 -55
- package/src/handlers/helpers/auditLogger.js +0 -201
- package/src/handlers/helpers/checkSuperAdmin.js +0 -84
- package/src/handlers/helpers/decisionFrames.js +0 -29
- package/src/handlers/helpers/errorHandler.js +0 -49
- package/src/handlers/helpers/index.js +0 -138
- package/src/handlers/helpers/lambdaWrapper.js +0 -60
- package/src/handlers/helpers/mindmeldMcpCore.js +0 -1103
- package/src/handlers/helpers/predictiveCache.js +0 -51
- package/src/handlers/helpers/projectAccess.js +0 -88
- package/src/handlers/helpers/responseUtil.js +0 -55
- package/src/handlers/helpers/subscriptionTiers.js +0 -1168
- package/src/handlers/mcp/mcpHandler.js +0 -569
- package/src/handlers/mcp/mindmeldMcpHandler.js +0 -124
- package/src/handlers/mcp/mindmeldMcpStreamHandler.js +0 -342
- package/src/handlers/notifications/getPreferences.js +0 -84
- package/src/handlers/notifications/sendNotification.js +0 -170
- package/src/handlers/notifications/updatePreferences.js +0 -316
- package/src/handlers/patterns/patternEvaluatePromotionPost.js +0 -173
- package/src/handlers/patterns/patternUsagePost.js +0 -182
- package/src/handlers/patterns/patternViolationPost.js +0 -185
- package/src/handlers/projects/projectCreate.js +0 -248
- package/src/handlers/projects/projectDelete.js +0 -82
- package/src/handlers/projects/projectGet.js +0 -95
- package/src/handlers/projects/projectUpdate.js +0 -117
- package/src/handlers/reports/aiLeverage.js +0 -210
- package/src/handlers/reports/engineeringInvestment.js +0 -132
- package/src/handlers/reports/riskForecast.js +0 -206
- package/src/handlers/reports/standardsRoi.js +0 -254
- package/src/handlers/scheduled/analyzeCorrelations.js +0 -178
- package/src/handlers/scheduled/analyzeGitHistory.js +0 -510
- package/src/handlers/scheduled/generateAlerts.js +0 -135
- package/src/handlers/scheduled/maturityUpdateJob.js +0 -166
- package/src/handlers/scheduled/refreshActivity.js +0 -21
- package/src/handlers/scheduled/scanCompliance.js +0 -334
- package/src/handlers/sessions/sessionEndPost.js +0 -180
- package/src/handlers/sessions/sessionStandardsPost.js +0 -171
- package/src/handlers/standards/catalogGet.js +0 -185
- package/src/handlers/standards/catalogSync.js +0 -120
- package/src/handlers/standards/discoveriesGet.js +0 -89
- package/src/handlers/standards/projectStandardsGet.js +0 -129
- package/src/handlers/standards/projectStandardsPut.js +0 -151
- package/src/handlers/standards/standardsAuditGet.js +0 -65
- package/src/handlers/standards/standardsParseUpload.js +0 -149
- package/src/handlers/standards/standardsRelevantPost.js +0 -405
- package/src/handlers/standards/standardsTransition.js +0 -161
- package/src/handlers/stripe/addonManagePost.js +0 -240
- package/src/handlers/stripe/billingPortalPost.js +0 -93
- package/src/handlers/stripe/enterpriseCheckoutPost.js +0 -272
- package/src/handlers/stripe/seatsUpdatePost.js +0 -185
- package/src/handlers/stripe/subscriptionCancelDelete.js +0 -169
- package/src/handlers/stripe/subscriptionCreatePost.js +0 -221
- package/src/handlers/stripe/subscriptionUpdatePut.js +0 -163
- package/src/handlers/stripe/webhookPost.js +0 -482
- package/src/handlers/user/apiTokenCreate.js +0 -71
- package/src/handlers/user/apiTokenList.js +0 -64
- package/src/handlers/user/userSplashAck.js +0 -91
- package/src/handlers/user/userSplashGet.js +0 -211
- package/src/handlers/users/cognitoPostConfirmation.js +0 -186
- package/src/handlers/users/cognitoPreSignUp.js +0 -114
- package/src/handlers/users/userEntitlementsGet.js +0 -89
- package/src/handlers/users/userGet.js +0 -118
- package/src/handlers/users/userProfilePut.js +0 -77
- package/src/handlers/webhooks/githubWebhook.js +0 -215
|
@@ -1,53 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Database
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Follows lambda_database_standards.md
|
|
2
|
+
* Database operations shim for NPM client package.
|
|
3
|
+
* Core modules import dbOperations at the top level, but hooks never
|
|
4
|
+
* execute DB queries — they communicate via HTTP to the MindMeld API.
|
|
5
|
+
* This shim satisfies the require() without shipping pg or connection logic.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Cached client for connection reuse across warm invocations
|
|
12
|
-
let cachedClient = null;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Get database client (cached)
|
|
16
|
-
* Reuses connection across Lambda invocations
|
|
17
|
-
*/
|
|
18
|
-
async function getClient() {
|
|
19
|
-
if (cachedClient && cachedClient._connected) {
|
|
20
|
-
return cachedClient;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Create new client with environment variables (resolved at deployment)
|
|
24
|
-
// AWS RDS requires SSL for all connections
|
|
25
|
-
cachedClient = new Client({
|
|
26
|
-
host: process.env.DB_HOST,
|
|
27
|
-
port: parseInt(process.env.DB_PORT || '5432'),
|
|
28
|
-
database: process.env.DB_NAME,
|
|
29
|
-
user: process.env.DB_USER,
|
|
30
|
-
password: process.env.DB_PASS || process.env.DB_PASSWORD, // Support both naming conventions
|
|
31
|
-
ssl: { rejectUnauthorized: false } // Required for AWS RDS
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
await cachedClient.connect();
|
|
35
|
-
cachedClient._connected = true;
|
|
36
|
-
|
|
37
|
-
console.log('Database client connected');
|
|
38
|
-
|
|
39
|
-
return cachedClient;
|
|
8
|
+
async function executeQuery() {
|
|
9
|
+
throw new Error('Database operations are not available in the client package. Use the MindMeld API instead.');
|
|
40
10
|
}
|
|
41
11
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
* @param {string} query - SQL query
|
|
45
|
-
* @param {array} params - Query parameters
|
|
46
|
-
* @returns {Promise<object>} Query result
|
|
47
|
-
*/
|
|
48
|
-
async function executeQuery(query, params = []) {
|
|
49
|
-
const client = await getClient();
|
|
50
|
-
return client.query(query, params);
|
|
12
|
+
function getPool() {
|
|
13
|
+
return null;
|
|
51
14
|
}
|
|
52
15
|
|
|
53
|
-
module.exports = { executeQuery };
|
|
16
|
+
module.exports = { executeQuery, getPool };
|
package/src/index.js
CHANGED
|
@@ -4,16 +4,13 @@
|
|
|
4
4
|
* Intelligent standards injection for AI coding sessions.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const TeamLoadBearingDetector = require('./core/TeamLoadBearingDetector');
|
|
8
|
-
const CollaborationPrompt = require('./collaboration/CollaborationPrompt');
|
|
9
|
-
const { RelevanceDetector } = require('./core/RelevanceDetector');
|
|
10
7
|
const { PatternValidator } = require('./core/PatternValidator');
|
|
11
|
-
const { StandardsIngestion } = require('./core/StandardsIngestion');
|
|
12
8
|
const { AuthManager } = require('./core/AuthManager');
|
|
13
9
|
|
|
14
10
|
class MindmeldClient {
|
|
15
11
|
constructor(config = {}) {
|
|
16
12
|
this.config = {
|
|
13
|
+
// AEGIS review: projectPath is config-driven (CLI cwd), not HTTP user input — no traversal risk
|
|
17
14
|
projectPath: config.projectPath || process.cwd(),
|
|
18
15
|
userId: config.userId || process.env.USER || 'unknown',
|
|
19
16
|
apiUrl: config.apiUrl || process.env.MINDMELD_API_URL || 'https://api.mindmeld.dev',
|
|
@@ -23,19 +20,7 @@ class MindmeldClient {
|
|
|
23
20
|
...config
|
|
24
21
|
};
|
|
25
22
|
|
|
26
|
-
// Initialize components
|
|
27
|
-
this.teamDetector = new TeamLoadBearingDetector();
|
|
28
|
-
this.collaborationPrompt = new CollaborationPrompt();
|
|
29
|
-
|
|
30
|
-
// Phase 2-5 components (Claude Code integration)
|
|
31
|
-
this.relevanceDetector = new RelevanceDetector({
|
|
32
|
-
workingDirectory: this.config.projectPath,
|
|
33
|
-
standardsPath: this.config.standardsPath
|
|
34
|
-
});
|
|
35
23
|
this.patternValidator = new PatternValidator();
|
|
36
|
-
this.standardsIngestion = new StandardsIngestion({
|
|
37
|
-
standardsPath: this.config.standardsPath
|
|
38
|
-
});
|
|
39
24
|
|
|
40
25
|
// Project context
|
|
41
26
|
this.currentProject = null;
|
|
@@ -167,129 +152,6 @@ class MindmeldClient {
|
|
|
167
152
|
return null;
|
|
168
153
|
}
|
|
169
154
|
|
|
170
|
-
/**
|
|
171
|
-
* Initialize new project
|
|
172
|
-
* Creates project via API if authenticated, stores locally as fallback
|
|
173
|
-
* @param {string} projectName - Name of the project
|
|
174
|
-
* @param {Object} options - Project options
|
|
175
|
-
* @param {Array} options.collaborators - List of collaborator emails
|
|
176
|
-
* @param {boolean} options.private - Whether project is private
|
|
177
|
-
* @param {string} options.description - Project description
|
|
178
|
-
* @param {string} options.repoUrl - Repository URL
|
|
179
|
-
* @returns {Promise<Object>} Created project object
|
|
180
|
-
*/
|
|
181
|
-
async initializeProject(projectName, options = {}) {
|
|
182
|
-
const project = this.collaborationPrompt.createProjectConfig(
|
|
183
|
-
projectName,
|
|
184
|
-
options.collaborators || [],
|
|
185
|
-
{
|
|
186
|
-
private: options.private || false
|
|
187
|
-
}
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
// Try API first if authenticated
|
|
191
|
-
if (this.config.authToken && this.config.companyId) {
|
|
192
|
-
try {
|
|
193
|
-
const apiUrl = this.config.apiUrl;
|
|
194
|
-
|
|
195
|
-
// Build request payload matching projectCreate handler
|
|
196
|
-
const payload = {
|
|
197
|
-
Company_ID: this.config.companyId,
|
|
198
|
-
project_name: projectName,
|
|
199
|
-
description: options.description || `Project for ${projectName}`,
|
|
200
|
-
private: options.private || false,
|
|
201
|
-
repo_url: options.repoUrl || null
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
const response = await this._makeApiRequest(
|
|
205
|
-
`${apiUrl}/api/projects`,
|
|
206
|
-
'POST',
|
|
207
|
-
payload
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
if (response.error) {
|
|
211
|
-
// Handle specific error cases
|
|
212
|
-
if (response.status === 409) {
|
|
213
|
-
console.log('[Rapport] Project already exists, fetching existing...');
|
|
214
|
-
const existing = await this.getProject(projectName);
|
|
215
|
-
if (existing) return existing;
|
|
216
|
-
}
|
|
217
|
-
console.error('[Rapport] initializeProject API error:', response.error);
|
|
218
|
-
// Fall through to local storage
|
|
219
|
-
} else if (response.Records && response.Records.length > 0) {
|
|
220
|
-
const created = response.Records[0];
|
|
221
|
-
|
|
222
|
-
// Add collaborators if specified
|
|
223
|
-
if (options.collaborators && options.collaborators.length > 0) {
|
|
224
|
-
for (const email of options.collaborators) {
|
|
225
|
-
await this._addCollaborator(created.project_id, email);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return {
|
|
230
|
-
projectId: created.project_id,
|
|
231
|
-
projectName: created.project_name,
|
|
232
|
-
companyId: created.company_id,
|
|
233
|
-
description: created.description,
|
|
234
|
-
private: created.private,
|
|
235
|
-
collaborators: options.collaborators || [],
|
|
236
|
-
createdAt: created.created_at
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
} catch (error) {
|
|
240
|
-
console.error('[Rapport] initializeProject API call failed:', error.message);
|
|
241
|
-
// Fall through to local storage
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Fallback: store locally
|
|
246
|
-
await this.storeProjectLocally(project);
|
|
247
|
-
return project;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Add collaborator to project (internal helper)
|
|
252
|
-
* @private
|
|
253
|
-
*/
|
|
254
|
-
async _addCollaborator(projectId, email, role = 'collaborator') {
|
|
255
|
-
try {
|
|
256
|
-
const apiUrl = this.config.apiUrl;
|
|
257
|
-
await this._makeApiRequest(
|
|
258
|
-
`${apiUrl}/api/collaborators`,
|
|
259
|
-
'POST',
|
|
260
|
-
{ project_id: projectId, email, role }
|
|
261
|
-
);
|
|
262
|
-
} catch (error) {
|
|
263
|
-
console.error(`[Rapport] Failed to add collaborator ${email}:`, error.message);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Store project configuration locally
|
|
269
|
-
*/
|
|
270
|
-
async storeProjectLocally(project) {
|
|
271
|
-
const fs = require('fs').promises;
|
|
272
|
-
const path = require('path');
|
|
273
|
-
|
|
274
|
-
const projectDir = path.join(__dirname, '../projects', project.projectId);
|
|
275
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
276
|
-
|
|
277
|
-
const configPath = path.join(projectDir, 'config.json');
|
|
278
|
-
await fs.writeFile(configPath, JSON.stringify(project, null, 2));
|
|
279
|
-
|
|
280
|
-
// Create collaborators file
|
|
281
|
-
const collabPath = path.join(projectDir, 'collaborators.json');
|
|
282
|
-
await fs.writeFile(collabPath, JSON.stringify({
|
|
283
|
-
projectId: project.projectId,
|
|
284
|
-
collaborators: project.collaborators,
|
|
285
|
-
updated: new Date().toISOString()
|
|
286
|
-
}, null, 2));
|
|
287
|
-
|
|
288
|
-
// Create sessions directory
|
|
289
|
-
const sessionsDir = path.join(projectDir, 'sessions');
|
|
290
|
-
await fs.mkdir(sessionsDir, { recursive: true });
|
|
291
|
-
}
|
|
292
|
-
|
|
293
155
|
/**
|
|
294
156
|
* Load project context including team patterns, load-bearing elements, and recent learning
|
|
295
157
|
* Fetches from API if authenticated, falls back to local storage
|
|
@@ -404,79 +266,6 @@ class MindmeldClient {
|
|
|
404
266
|
}
|
|
405
267
|
}
|
|
406
268
|
|
|
407
|
-
/**
|
|
408
|
-
* Analyze handoff (team-wide)
|
|
409
|
-
*/
|
|
410
|
-
async analyzeHandoff(handoff, outcome) {
|
|
411
|
-
if (!this.currentProject) {
|
|
412
|
-
throw new Error('No project initialized. Call detectProject() first.');
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return this.teamDetector.analyzeHandoff(
|
|
416
|
-
this.config.userId,
|
|
417
|
-
handoff,
|
|
418
|
-
outcome
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Get team load-bearing elements
|
|
424
|
-
*/
|
|
425
|
-
getTeamLoadBearing() {
|
|
426
|
-
return this.teamDetector.getTeamLoadBearing();
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Get team summary
|
|
431
|
-
*/
|
|
432
|
-
getTeamSummary() {
|
|
433
|
-
return this.teamDetector.getTeamSummary();
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// ============================================================================
|
|
437
|
-
// Phase 5: Claude Code Hook Methods
|
|
438
|
-
// ============================================================================
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Ensure standards are ingested (cached check)
|
|
442
|
-
* Fast execution for session-start hook
|
|
443
|
-
*/
|
|
444
|
-
async ensureStandardsIngested() {
|
|
445
|
-
try {
|
|
446
|
-
const check = await this.standardsIngestion.needsIngestion();
|
|
447
|
-
|
|
448
|
-
if (check.needed) {
|
|
449
|
-
console.log(`[Rapport] Standards ingestion needed: ${check.reason}`);
|
|
450
|
-
await this.standardsIngestion.ingestEquilateralStandards();
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
return check;
|
|
454
|
-
} catch (error) {
|
|
455
|
-
console.error('[Rapport] ensureStandardsIngested error:', error.message);
|
|
456
|
-
return { needed: false, error: error.message };
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* Get relevant standards for current project context
|
|
462
|
-
* Used by session-start hook
|
|
463
|
-
*/
|
|
464
|
-
async getRelevantStandards(projectContext) {
|
|
465
|
-
try {
|
|
466
|
-
const context = {
|
|
467
|
-
workingDirectory: projectContext.workingDirectory || this.config.projectPath,
|
|
468
|
-
currentFile: projectContext.currentFile || null,
|
|
469
|
-
recentFiles: projectContext.recentFiles || [],
|
|
470
|
-
gitHistory: projectContext.gitHistory || null
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
return await this.relevanceDetector.detectRelevantStandards(context);
|
|
474
|
-
} catch (error) {
|
|
475
|
-
console.error('[Rapport] getRelevantStandards error:', error.message);
|
|
476
|
-
return { standards: [], characteristics: {}, categories: [] };
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
269
|
/**
|
|
481
270
|
* Get recent learning for project (last N days)
|
|
482
271
|
*/
|
|
@@ -964,9 +753,5 @@ module.exports = {
|
|
|
964
753
|
MindmeldClient,
|
|
965
754
|
RapportClient,
|
|
966
755
|
AuthManager,
|
|
967
|
-
|
|
968
|
-
CollaborationPrompt,
|
|
969
|
-
RelevanceDetector,
|
|
970
|
-
PatternValidator,
|
|
971
|
-
StandardsIngestion
|
|
756
|
+
PatternValidator
|
|
972
757
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PII masking utilities for safe logging.
|
|
3
|
+
* Prevents email, user IDs from leaking to CloudWatch/log aggregators.
|
|
4
|
+
*/
|
|
5
|
+
const maskEmail = (email) => {
|
|
6
|
+
if (!email) return '[no-email]';
|
|
7
|
+
const [local, domain] = email.split('@');
|
|
8
|
+
return `${local.substring(0, 2)}***@${domain || '***'}`;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const maskUserId = (id) => {
|
|
12
|
+
if (!id) return '[no-id]';
|
|
13
|
+
return typeof id === 'string' && id.length > 8 ? `${id.substring(0, 8)}...` : String(id);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
module.exports = { maskEmail, maskUserId };
|