erosolar-cli 2.1.243 → 2.1.244

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 (31) hide show
  1. package/dist/capabilities/index.d.ts +1 -0
  2. package/dist/capabilities/index.d.ts.map +1 -1
  3. package/dist/capabilities/index.js +1 -0
  4. package/dist/capabilities/index.js.map +1 -1
  5. package/dist/capabilities/unifiedInvestigationCapability.d.ts +22 -0
  6. package/dist/capabilities/unifiedInvestigationCapability.d.ts.map +1 -0
  7. package/dist/capabilities/unifiedInvestigationCapability.js +41 -0
  8. package/dist/capabilities/unifiedInvestigationCapability.js.map +1 -0
  9. package/dist/core/agentOrchestrator.d.ts +130 -1
  10. package/dist/core/agentOrchestrator.d.ts.map +1 -1
  11. package/dist/core/agentOrchestrator.js +553 -1
  12. package/dist/core/agentOrchestrator.js.map +1 -1
  13. package/dist/core/unifiedFraudOrchestrator.d.ts +542 -0
  14. package/dist/core/unifiedFraudOrchestrator.d.ts.map +1 -0
  15. package/dist/core/unifiedFraudOrchestrator.js +1449 -0
  16. package/dist/core/unifiedFraudOrchestrator.js.map +1 -0
  17. package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
  18. package/dist/plugins/tools/nodeDefaults.js +2 -0
  19. package/dist/plugins/tools/nodeDefaults.js.map +1 -1
  20. package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.d.ts +3 -0
  21. package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.d.ts.map +1 -0
  22. package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.js +14 -0
  23. package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.js.map +1 -0
  24. package/dist/tools/taoTools.d.ts.map +1 -1
  25. package/dist/tools/taoTools.js +790 -4
  26. package/dist/tools/taoTools.js.map +1 -1
  27. package/dist/tools/unifiedInvestigationTools.d.ts +19 -0
  28. package/dist/tools/unifiedInvestigationTools.d.ts.map +1 -0
  29. package/dist/tools/unifiedInvestigationTools.js +851 -0
  30. package/dist/tools/unifiedInvestigationTools.js.map +1 -0
  31. package/package.json +1 -1
@@ -0,0 +1,851 @@
1
+ /**
2
+ * Unified Tech Fraud Investigation Tools
3
+ *
4
+ * CLI tool suite for investigating tech company fraud across:
5
+ * - Apple iMessage (via existing iMessageVerificationTools)
6
+ * - Google Gmail (hidden threads, draft manipulation, unauthorized access)
7
+ * - Google Chrome (unauthorized launches, session hijacking, history manipulation)
8
+ * - Cross-platform correlation
9
+ *
10
+ * Tools:
11
+ * - Investigation: Manage investigations
12
+ * - GmailInvestigate: Gmail manipulation detection
13
+ * - ChromeInvestigate: Chrome browser control detection
14
+ * - CorrelateEvidence: Cross-vector correlation
15
+ * - FraudReport: Generate unified reports
16
+ */
17
+ import * as path from 'node:path';
18
+ import { UnifiedFraudOrchestrator, GOOGLE_GMAIL_CLAIMS, GOOGLE_CHROME_CLAIMS, } from '../core/unifiedFraudOrchestrator.js';
19
+ // ═══════════════════════════════════════════════════════════════════════════════
20
+ // TOOL SUITE FACTORY
21
+ // ═══════════════════════════════════════════════════════════════════════════════
22
+ export function createUnifiedInvestigationTools(workingDir = process.cwd()) {
23
+ // Orchestrator instance (lazy initialization)
24
+ let orchestratorInstance = null;
25
+ const getOrchestrator = async () => {
26
+ if (!orchestratorInstance) {
27
+ orchestratorInstance = new UnifiedFraudOrchestrator(workingDir);
28
+ await orchestratorInstance.initialize();
29
+ }
30
+ return orchestratorInstance;
31
+ };
32
+ return {
33
+ id: 'unified-investigation',
34
+ description: 'Unified tech fraud investigation across Apple, Google, and other platforms',
35
+ tools: [
36
+ // ─────────────────────────────────────────────────────────────────────────
37
+ // Investigation Management
38
+ // ─────────────────────────────────────────────────────────────────────────
39
+ {
40
+ name: 'Investigation',
41
+ description: `Manage fraud investigations across tech companies.
42
+
43
+ Create and manage investigations that span multiple fraud vectors:
44
+ - Apple: iMessage key substitution, false E2E claims
45
+ - Google: Gmail manipulation, Chrome browser control
46
+ - Cross-platform: Coordinated manipulation detection
47
+
48
+ Operations:
49
+ - create: Start a new investigation
50
+ - list: List all investigations
51
+ - status: Get investigation status
52
+ - activate: Set investigation to active
53
+ - correlate: Run cross-vector correlation
54
+ - report: Generate investigation report
55
+ - export: Export for legal proceedings`,
56
+ parameters: {
57
+ type: 'object',
58
+ required: ['operation'],
59
+ properties: {
60
+ operation: {
61
+ type: 'string',
62
+ enum: ['create', 'list', 'status', 'activate', 'correlate', 'report', 'export'],
63
+ description: 'Operation to perform',
64
+ },
65
+ name: {
66
+ type: 'string',
67
+ description: 'Investigation name (for create)',
68
+ },
69
+ target: {
70
+ type: 'string',
71
+ enum: ['apple', 'google', 'meta', 'microsoft', 'amazon'],
72
+ description: 'Primary investigation target (for create)',
73
+ },
74
+ vectors: {
75
+ type: 'array',
76
+ items: { type: 'string' },
77
+ description: 'Fraud vectors to investigate',
78
+ },
79
+ investigationId: {
80
+ type: 'string',
81
+ description: 'Investigation ID (for status/activate/correlate/report/export)',
82
+ },
83
+ outputDir: {
84
+ type: 'string',
85
+ description: 'Output directory (for export)',
86
+ },
87
+ },
88
+ },
89
+ handler: async (args) => {
90
+ const operation = args['operation'];
91
+ const orchestrator = await getOrchestrator();
92
+ switch (operation) {
93
+ case 'create': {
94
+ const name = args['name'];
95
+ const target = args['target'];
96
+ const vectors = args['vectors'] || [];
97
+ if (!name || !target) {
98
+ return JSON.stringify({
99
+ success: false,
100
+ error: 'name and target required',
101
+ availableTargets: ['apple', 'google', 'meta', 'microsoft', 'amazon'],
102
+ availableVectors: [
103
+ 'imessage_key_substitution', 'imessage_false_e2e',
104
+ 'gmail_hidden_threads', 'gmail_draft_manipulation', 'gmail_unauthorized_access', 'gmail_filter_tampering',
105
+ 'chrome_unauthorized_launch', 'chrome_session_hijacking', 'chrome_history_manipulation',
106
+ 'cross_platform_surveillance', 'coordinated_manipulation',
107
+ ],
108
+ });
109
+ }
110
+ const investigation = await orchestrator.createInvestigation({
111
+ name,
112
+ target,
113
+ vectors: vectors.length > 0 ? vectors : getDefaultVectors(target),
114
+ });
115
+ return JSON.stringify({
116
+ success: true,
117
+ operation: 'create',
118
+ investigation: {
119
+ id: investigation.id,
120
+ name: investigation.name,
121
+ target: investigation.target,
122
+ vectors: investigation.vectors,
123
+ status: investigation.status,
124
+ evidenceChainId: investigation.evidenceChainId,
125
+ },
126
+ message: `Investigation "${name}" created. Use investigationId: ${investigation.id} for subsequent operations.`,
127
+ });
128
+ }
129
+ case 'list': {
130
+ const investigations = orchestrator.getInvestigations();
131
+ return JSON.stringify({
132
+ success: true,
133
+ operation: 'list',
134
+ count: investigations.length,
135
+ investigations: investigations.map(i => ({
136
+ id: i.id,
137
+ name: i.name,
138
+ target: i.target,
139
+ status: i.status,
140
+ findingCount: i.findings.length,
141
+ correlationCount: i.correlations.length,
142
+ created: i.created,
143
+ lastActivity: i.lastActivity,
144
+ })),
145
+ });
146
+ }
147
+ case 'status': {
148
+ const investigationId = args['investigationId'];
149
+ if (!investigationId) {
150
+ return JSON.stringify({ success: false, error: 'investigationId required' });
151
+ }
152
+ const investigations = orchestrator.getInvestigations();
153
+ const investigation = investigations.find(i => i.id === investigationId);
154
+ if (!investigation) {
155
+ return JSON.stringify({ success: false, error: `Investigation not found: ${investigationId}` });
156
+ }
157
+ return JSON.stringify({
158
+ success: true,
159
+ operation: 'status',
160
+ investigation: {
161
+ id: investigation.id,
162
+ name: investigation.name,
163
+ target: investigation.target,
164
+ vectors: investigation.vectors,
165
+ status: investigation.status,
166
+ created: investigation.created,
167
+ lastActivity: investigation.lastActivity,
168
+ findingCount: investigation.findings.length,
169
+ correlationCount: investigation.correlations.length,
170
+ hash: investigation.hash,
171
+ },
172
+ });
173
+ }
174
+ case 'activate': {
175
+ const investigationId = args['investigationId'];
176
+ if (!investigationId) {
177
+ return JSON.stringify({ success: false, error: 'investigationId required' });
178
+ }
179
+ const investigation = await orchestrator.updateInvestigationStatus(investigationId, 'active');
180
+ return JSON.stringify({
181
+ success: true,
182
+ operation: 'activate',
183
+ investigationId: investigation.id,
184
+ status: investigation.status,
185
+ message: `Investigation "${investigation.name}" is now active. Begin collecting evidence.`,
186
+ });
187
+ }
188
+ case 'correlate': {
189
+ const investigationId = args['investigationId'];
190
+ if (!investigationId) {
191
+ return JSON.stringify({ success: false, error: 'investigationId required' });
192
+ }
193
+ const correlations = await orchestrator.correlateFindings(investigationId);
194
+ return JSON.stringify({
195
+ success: true,
196
+ operation: 'correlate',
197
+ investigationId,
198
+ newCorrelations: correlations.length,
199
+ correlations: correlations.map(c => ({
200
+ id: c.id,
201
+ type: c.correlationType,
202
+ description: c.description,
203
+ confidence: c.confidence,
204
+ implications: c.implications,
205
+ })),
206
+ message: correlations.length > 0
207
+ ? `Found ${correlations.length} cross-vector correlations. These may indicate coordinated manipulation.`
208
+ : 'No new correlations detected.',
209
+ });
210
+ }
211
+ case 'report': {
212
+ const investigationId = args['investigationId'];
213
+ if (!investigationId) {
214
+ return JSON.stringify({ success: false, error: 'investigationId required' });
215
+ }
216
+ const report = await orchestrator.generateUnifiedReport(investigationId);
217
+ return JSON.stringify({
218
+ success: true,
219
+ operation: 'report',
220
+ report: {
221
+ investigation: {
222
+ id: report.investigation.id,
223
+ name: report.investigation.name,
224
+ target: report.investigation.target,
225
+ status: report.investigation.status,
226
+ },
227
+ summary: report.summary,
228
+ findingsByVector: Object.entries(report.byVector).map(([vector, data]) => ({
229
+ vector,
230
+ severity: data.severity,
231
+ findingCount: data.findings.length,
232
+ })),
233
+ correlationCount: report.correlations.length,
234
+ legalSummary: report.legalSummary,
235
+ },
236
+ });
237
+ }
238
+ case 'export': {
239
+ const investigationId = args['investigationId'];
240
+ const outputDir = args['outputDir'] || path.join(workingDir, 'evidence-export');
241
+ if (!investigationId) {
242
+ return JSON.stringify({ success: false, error: 'investigationId required' });
243
+ }
244
+ const exportPath = await orchestrator.exportForLitigation(investigationId, outputDir);
245
+ return JSON.stringify({
246
+ success: true,
247
+ operation: 'export',
248
+ exportPath,
249
+ message: `Evidence exported to ${exportPath}. Contains unified report, all findings, correlations, and legal summary.`,
250
+ });
251
+ }
252
+ default:
253
+ return JSON.stringify({ success: false, error: `Unknown operation: ${operation}` });
254
+ }
255
+ },
256
+ },
257
+ // ─────────────────────────────────────────────────────────────────────────
258
+ // Gmail Investigation
259
+ // ─────────────────────────────────────────────────────────────────────────
260
+ {
261
+ name: 'GmailInvestigate',
262
+ description: `Investigate Gmail manipulation by Google.
263
+
264
+ Detects:
265
+ - Hidden threads (visible via API but hidden in UI)
266
+ - Draft manipulation (unauthorized changes, sends)
267
+ - Unauthorized access (Google accessing your account)
268
+ - Filter tampering (filters added without consent)
269
+
270
+ Operations:
271
+ - recordThread: Record thread observation
272
+ - recordDraft: Record draft observation
273
+ - recordAccess: Record access event
274
+ - recordFilter: Record filter observation
275
+ - crossReference: Compare different data sources
276
+ - findings: List all Gmail findings
277
+ - claims: Show Google's claims vs reality`,
278
+ parameters: {
279
+ type: 'object',
280
+ required: ['operation'],
281
+ properties: {
282
+ operation: {
283
+ type: 'string',
284
+ enum: ['recordThread', 'recordDraft', 'recordAccess', 'recordFilter', 'crossReference', 'findings', 'claims'],
285
+ description: 'Operation to perform',
286
+ },
287
+ // Thread params
288
+ threadId: { type: 'string' },
289
+ messageIds: { type: 'array', items: { type: 'string' } },
290
+ subject: { type: 'string' },
291
+ labels: { type: 'array', items: { type: 'string' } },
292
+ isVisible: { type: 'boolean' },
293
+ isInSearch: { type: 'boolean' },
294
+ lastMessageDate: { type: 'string' },
295
+ participantCount: { type: 'number' },
296
+ captureMethod: { type: 'string', enum: ['api', 'ui_scrape', 'network_capture', 'takeout'] },
297
+ rawData: { type: 'string' },
298
+ // Draft params
299
+ draftId: { type: 'string' },
300
+ recipientCount: { type: 'number' },
301
+ bodyContent: { type: 'string' },
302
+ hasAttachments: { type: 'boolean' },
303
+ createdAt: { type: 'string' },
304
+ modifiedAt: { type: 'string' },
305
+ // Access params
306
+ accessType: { type: 'string', enum: ['login', 'api_access', 'imap', 'pop', 'oauth_grant', 'security_event'] },
307
+ ipAddress: { type: 'string' },
308
+ location: { type: 'string' },
309
+ userAgent: { type: 'string' },
310
+ deviceType: { type: 'string' },
311
+ wasUser: { type: 'boolean' },
312
+ // Filter params
313
+ filterId: { type: 'string' },
314
+ criteria: { type: 'object' },
315
+ actions: { type: 'object' },
316
+ createdByUser: { type: 'boolean' },
317
+ // Cross-reference params
318
+ apiThreadIds: { type: 'array', items: { type: 'string' } },
319
+ uiThreadIds: { type: 'array', items: { type: 'string' } },
320
+ takeoutThreadIds: { type: 'array', items: { type: 'string' } },
321
+ imapThreadIds: { type: 'array', items: { type: 'string' } },
322
+ },
323
+ },
324
+ handler: async (args) => {
325
+ const operation = args['operation'];
326
+ const orchestrator = await getOrchestrator();
327
+ const gmailEngine = orchestrator.getGmailEngine();
328
+ switch (operation) {
329
+ case 'recordThread': {
330
+ const result = await gmailEngine.recordThreadObservation({
331
+ threadId: args['threadId'],
332
+ messageIds: args['messageIds'] || [],
333
+ subject: args['subject'] || '',
334
+ labels: args['labels'] || [],
335
+ isVisible: args['isVisible'] ?? true,
336
+ isInSearch: args['isInSearch'] ?? true,
337
+ lastMessageDate: args['lastMessageDate'] || new Date().toISOString(),
338
+ participantCount: args['participantCount'] || 0,
339
+ captureMethod: args['captureMethod'] || 'api',
340
+ rawData: args['rawData'],
341
+ });
342
+ return JSON.stringify({
343
+ success: true,
344
+ operation: 'recordThread',
345
+ observation: {
346
+ id: result.observation.id,
347
+ threadId: result.observation.threadId,
348
+ isVisible: result.observation.isVisible,
349
+ isInSearch: result.observation.isInSearch,
350
+ hash: result.observation.hash,
351
+ },
352
+ anomalyDetected: result.anomalyDetected,
353
+ finding: result.finding ? {
354
+ id: result.finding.id,
355
+ severity: result.finding.severity,
356
+ title: result.finding.title,
357
+ } : null,
358
+ message: result.anomalyDetected
359
+ ? `⚠️ ANOMALY DETECTED: ${result.finding?.title}`
360
+ : 'Thread observation recorded.',
361
+ });
362
+ }
363
+ case 'recordDraft': {
364
+ const result = await gmailEngine.recordDraftObservation({
365
+ draftId: args['draftId'],
366
+ threadId: args['threadId'],
367
+ subject: args['subject'] || '',
368
+ recipientCount: args['recipientCount'] || 0,
369
+ bodyContent: args['bodyContent'] || '',
370
+ hasAttachments: args['hasAttachments'] ?? false,
371
+ createdAt: args['createdAt'] || new Date().toISOString(),
372
+ modifiedAt: args['modifiedAt'] || new Date().toISOString(),
373
+ captureMethod: args['captureMethod'] || 'api',
374
+ });
375
+ return JSON.stringify({
376
+ success: true,
377
+ operation: 'recordDraft',
378
+ observation: {
379
+ id: result.observation.id,
380
+ draftId: result.observation.draftId,
381
+ bodyHash: result.observation.bodyHash,
382
+ hash: result.observation.hash,
383
+ },
384
+ changes: result.changes,
385
+ finding: result.finding ? {
386
+ id: result.finding.id,
387
+ severity: result.finding.severity,
388
+ title: result.finding.title,
389
+ } : null,
390
+ message: result.changes.length > 0
391
+ ? `⚠️ DRAFT CHANGES DETECTED: ${result.changes.map(c => c.reason).join('; ')}`
392
+ : 'Draft observation recorded.',
393
+ });
394
+ }
395
+ case 'recordAccess': {
396
+ const result = await gmailEngine.recordAccessLog({
397
+ accessType: args['accessType'],
398
+ ipAddress: args['ipAddress'],
399
+ location: args['location'],
400
+ userAgent: args['userAgent'],
401
+ deviceType: args['deviceType'],
402
+ wasUser: args['wasUser'] ?? true,
403
+ });
404
+ return JSON.stringify({
405
+ success: true,
406
+ operation: 'recordAccess',
407
+ log: {
408
+ id: result.log.id,
409
+ accessType: result.log.accessType,
410
+ ipAddress: result.log.ipAddress,
411
+ suspicious: result.log.suspicious,
412
+ reason: result.log.reason,
413
+ hash: result.log.hash,
414
+ },
415
+ finding: result.finding ? {
416
+ id: result.finding.id,
417
+ severity: result.finding.severity,
418
+ title: result.finding.title,
419
+ } : null,
420
+ message: result.log.suspicious
421
+ ? `🚨 SUSPICIOUS ACCESS: ${result.log.reason}`
422
+ : 'Access logged.',
423
+ });
424
+ }
425
+ case 'recordFilter': {
426
+ const result = await gmailEngine.recordFilterObservation({
427
+ filterId: args['filterId'],
428
+ criteria: args['criteria'] || {},
429
+ actions: args['actions'] || {},
430
+ createdByUser: args['createdByUser'] ?? false,
431
+ createdAt: args['createdAt'],
432
+ });
433
+ return JSON.stringify({
434
+ success: true,
435
+ operation: 'recordFilter',
436
+ observation: {
437
+ id: result.observation.id,
438
+ filterId: result.observation.filterId,
439
+ createdByUser: result.observation.createdByUser,
440
+ hash: result.observation.hash,
441
+ },
442
+ finding: result.finding ? {
443
+ id: result.finding.id,
444
+ severity: result.finding.severity,
445
+ title: result.finding.title,
446
+ } : null,
447
+ message: result.finding
448
+ ? `⚠️ SUSPICIOUS FILTER: ${result.finding.title}`
449
+ : 'Filter observation recorded.',
450
+ });
451
+ }
452
+ case 'crossReference': {
453
+ const result = await gmailEngine.crossReferenceThreadSources({
454
+ apiThreadIds: args['apiThreadIds'] || [],
455
+ uiThreadIds: args['uiThreadIds'] || [],
456
+ takeoutThreadIds: args['takeoutThreadIds'],
457
+ imapThreadIds: args['imapThreadIds'],
458
+ });
459
+ return JSON.stringify({
460
+ success: true,
461
+ operation: 'crossReference',
462
+ discrepancyCount: result.discrepancies.length,
463
+ discrepancies: result.discrepancies,
464
+ finding: result.finding ? {
465
+ id: result.finding.id,
466
+ severity: result.finding.severity,
467
+ title: result.finding.title,
468
+ } : null,
469
+ message: result.discrepancies.length > 0
470
+ ? `🚨 HIDDEN THREADS DETECTED: ${result.discrepancies.length} threads exist in some sources but are hidden from others.`
471
+ : 'No discrepancies found.',
472
+ });
473
+ }
474
+ case 'findings': {
475
+ const findings = gmailEngine.getFindings();
476
+ return JSON.stringify({
477
+ success: true,
478
+ operation: 'findings',
479
+ count: findings.length,
480
+ bySeverity: {
481
+ critical: findings.filter(f => f.severity === 'critical').length,
482
+ high: findings.filter(f => f.severity === 'high').length,
483
+ medium: findings.filter(f => f.severity === 'medium').length,
484
+ low: findings.filter(f => f.severity === 'low').length,
485
+ },
486
+ findings: findings.map(f => ({
487
+ id: f.id,
488
+ timestamp: f.timestamp,
489
+ vector: f.vector,
490
+ severity: f.severity,
491
+ title: f.title,
492
+ hash: f.hash,
493
+ })),
494
+ });
495
+ }
496
+ case 'claims': {
497
+ return JSON.stringify({
498
+ success: true,
499
+ operation: 'claims',
500
+ googleGmailClaims: Object.entries(GOOGLE_GMAIL_CLAIMS).map(([key, data]) => ({
501
+ claim: key,
502
+ statement: data.claim,
503
+ source: data.source,
504
+ verifiable: data.verifiable,
505
+ reality: data.reason,
506
+ })),
507
+ summary: `Google makes ${Object.keys(GOOGLE_GMAIL_CLAIMS).length} security/privacy claims about Gmail. The investigation tools help verify these claims against observed behavior.`,
508
+ });
509
+ }
510
+ default:
511
+ return JSON.stringify({ success: false, error: `Unknown operation: ${operation}` });
512
+ }
513
+ },
514
+ },
515
+ // ─────────────────────────────────────────────────────────────────────────
516
+ // Chrome Investigation
517
+ // ─────────────────────────────────────────────────────────────────────────
518
+ {
519
+ name: 'ChromeInvestigate',
520
+ description: `Investigate Chrome browser manipulation by Google.
521
+
522
+ Detects:
523
+ - Unauthorized browser launches (Chrome starting without user action)
524
+ - Session hijacking (cookie/localStorage manipulation)
525
+ - History manipulation (deletions, suspicious entries)
526
+ - Remote control indicators
527
+
528
+ Operations:
529
+ - recordProcess: Record Chrome process observation
530
+ - recordSession: Record session state
531
+ - recordHistory: Record history state
532
+ - findings: List all Chrome findings
533
+ - claims: Show Google's claims vs reality`,
534
+ parameters: {
535
+ type: 'object',
536
+ required: ['operation'],
537
+ properties: {
538
+ operation: {
539
+ type: 'string',
540
+ enum: ['recordProcess', 'recordSession', 'recordHistory', 'findings', 'claims'],
541
+ description: 'Operation to perform',
542
+ },
543
+ // Process params
544
+ pid: { type: 'number' },
545
+ parentPid: { type: 'number' },
546
+ commandLine: { type: 'array', items: { type: 'string' } },
547
+ profilePath: { type: 'string' },
548
+ startTime: { type: 'string' },
549
+ userInitiated: { type: 'boolean' },
550
+ networkConnections: {
551
+ type: 'array',
552
+ items: {
553
+ type: 'object',
554
+ properties: {
555
+ localPort: { type: 'number' },
556
+ remoteIp: { type: 'string' },
557
+ remotePort: { type: 'number' },
558
+ state: { type: 'string' },
559
+ protocol: { type: 'string' },
560
+ },
561
+ },
562
+ },
563
+ // Session params
564
+ profileId: { type: 'string' },
565
+ tabs: { type: 'array', items: { type: 'object' } },
566
+ cookies: { type: 'array', items: { type: 'object' } },
567
+ localStorage: { type: 'array', items: { type: 'object' } },
568
+ syncStatus: { type: 'string', enum: ['synced', 'local_only', 'sync_disabled'] },
569
+ lastSyncTime: { type: 'string' },
570
+ // History params
571
+ captureMethod: { type: 'string', enum: ['sqlite', 'api', 'ui_scrape'] },
572
+ entryCount: { type: 'number' },
573
+ dateRange: { type: 'object' },
574
+ entries: { type: 'array', items: { type: 'object' } },
575
+ },
576
+ },
577
+ handler: async (args) => {
578
+ const operation = args['operation'];
579
+ const orchestrator = await getOrchestrator();
580
+ const chromeEngine = orchestrator.getChromeEngine();
581
+ switch (operation) {
582
+ case 'recordProcess': {
583
+ const result = await chromeEngine.recordProcessObservation({
584
+ pid: args['pid'],
585
+ parentPid: args['parentPid'] || 0,
586
+ commandLine: args['commandLine'] || [],
587
+ profilePath: args['profilePath'],
588
+ startTime: args['startTime'] || new Date().toISOString(),
589
+ userInitiated: args['userInitiated'] ?? true,
590
+ networkConnections: args['networkConnections'],
591
+ });
592
+ return JSON.stringify({
593
+ success: true,
594
+ operation: 'recordProcess',
595
+ observation: {
596
+ id: result.observation.id,
597
+ pid: result.observation.pid,
598
+ suspicionLevel: result.observation.suspicionLevel,
599
+ launchSource: result.observation.launchSource,
600
+ reason: result.observation.reason,
601
+ hash: result.observation.hash,
602
+ },
603
+ finding: result.finding ? {
604
+ id: result.finding.id,
605
+ severity: result.finding.severity,
606
+ title: result.finding.title,
607
+ } : null,
608
+ message: result.observation.suspicionLevel !== 'normal'
609
+ ? `🚨 SUSPICIOUS LAUNCH: ${result.observation.reason}`
610
+ : 'Process observation recorded.',
611
+ });
612
+ }
613
+ case 'recordSession': {
614
+ const result = await chromeEngine.recordSessionObservation({
615
+ profileId: args['profileId'],
616
+ tabs: args['tabs'] || [],
617
+ cookies: args['cookies'] || [],
618
+ localStorage: args['localStorage'] || [],
619
+ syncStatus: args['syncStatus'] || 'local_only',
620
+ lastSyncTime: args['lastSyncTime'],
621
+ });
622
+ return JSON.stringify({
623
+ success: true,
624
+ operation: 'recordSession',
625
+ observation: {
626
+ id: result.observation.id,
627
+ profileId: result.observation.profileId,
628
+ tabCount: result.observation.tabs.length,
629
+ anomalyCount: result.anomalies.length,
630
+ hash: result.observation.hash,
631
+ },
632
+ anomalies: result.anomalies,
633
+ finding: result.finding ? {
634
+ id: result.finding.id,
635
+ severity: result.finding.severity,
636
+ title: result.finding.title,
637
+ } : null,
638
+ message: result.anomalies.length > 0
639
+ ? `⚠️ SESSION ANOMALIES: ${result.anomalies.map(a => a.description).join('; ')}`
640
+ : 'Session observation recorded.',
641
+ });
642
+ }
643
+ case 'recordHistory': {
644
+ const result = await chromeEngine.recordHistoryObservation({
645
+ captureMethod: args['captureMethod'] || 'sqlite',
646
+ entryCount: args['entryCount'] || 0,
647
+ dateRange: args['dateRange'] || {
648
+ start: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
649
+ end: new Date().toISOString(),
650
+ },
651
+ entries: args['entries'] || [],
652
+ });
653
+ return JSON.stringify({
654
+ success: true,
655
+ operation: 'recordHistory',
656
+ observation: {
657
+ id: result.observation.id,
658
+ entryCount: result.observation.entryCount,
659
+ deletedEntries: result.observation.deletedEntries?.length || 0,
660
+ unexpectedEntries: result.observation.unexpectedEntries?.length || 0,
661
+ hash: result.observation.hash,
662
+ },
663
+ finding: result.finding ? {
664
+ id: result.finding.id,
665
+ severity: result.finding.severity,
666
+ title: result.finding.title,
667
+ } : null,
668
+ message: result.finding
669
+ ? `⚠️ HISTORY ANOMALY: ${result.finding.title}`
670
+ : 'History observation recorded.',
671
+ });
672
+ }
673
+ case 'findings': {
674
+ const findings = chromeEngine.getFindings();
675
+ return JSON.stringify({
676
+ success: true,
677
+ operation: 'findings',
678
+ count: findings.length,
679
+ bySeverity: {
680
+ critical: findings.filter(f => f.severity === 'critical').length,
681
+ high: findings.filter(f => f.severity === 'high').length,
682
+ medium: findings.filter(f => f.severity === 'medium').length,
683
+ low: findings.filter(f => f.severity === 'low').length,
684
+ },
685
+ findings: findings.map(f => ({
686
+ id: f.id,
687
+ timestamp: f.timestamp,
688
+ vector: f.vector,
689
+ severity: f.severity,
690
+ title: f.title,
691
+ hash: f.hash,
692
+ })),
693
+ });
694
+ }
695
+ case 'claims': {
696
+ return JSON.stringify({
697
+ success: true,
698
+ operation: 'claims',
699
+ googleChromeClaims: Object.entries(GOOGLE_CHROME_CLAIMS).map(([key, data]) => ({
700
+ claim: key,
701
+ statement: data.claim,
702
+ source: data.source,
703
+ verifiable: data.verifiable,
704
+ reality: data.reason,
705
+ })),
706
+ summary: `Google makes ${Object.keys(GOOGLE_CHROME_CLAIMS).length} security/privacy claims about Chrome. Monitor Chrome process behavior to verify these claims.`,
707
+ });
708
+ }
709
+ default:
710
+ return JSON.stringify({ success: false, error: `Unknown operation: ${operation}` });
711
+ }
712
+ },
713
+ },
714
+ // ─────────────────────────────────────────────────────────────────────────
715
+ // Evidence Correlation
716
+ // ─────────────────────────────────────────────────────────────────────────
717
+ {
718
+ name: 'CorrelateEvidence',
719
+ description: `Correlate evidence across multiple fraud vectors.
720
+
721
+ Detects coordinated manipulation:
722
+ - Temporal correlation: Events across different services happening together
723
+ - Behavioral correlation: Chrome launch + Gmail access
724
+ - Cross-platform: Apple + Google coordinated patterns
725
+
726
+ This is critical for proving systematic fraud vs isolated incidents.`,
727
+ parameters: {
728
+ type: 'object',
729
+ required: ['operation'],
730
+ properties: {
731
+ operation: {
732
+ type: 'string',
733
+ enum: ['correlate', 'list', 'analyze'],
734
+ description: 'Operation to perform',
735
+ },
736
+ investigationId: {
737
+ type: 'string',
738
+ description: 'Investigation to correlate (required for correlate)',
739
+ },
740
+ },
741
+ },
742
+ handler: async (args) => {
743
+ const operation = args['operation'];
744
+ const orchestrator = await getOrchestrator();
745
+ switch (operation) {
746
+ case 'correlate': {
747
+ const investigationId = args['investigationId'];
748
+ if (!investigationId) {
749
+ return JSON.stringify({ success: false, error: 'investigationId required' });
750
+ }
751
+ const correlations = await orchestrator.correlateFindings(investigationId);
752
+ return JSON.stringify({
753
+ success: true,
754
+ operation: 'correlate',
755
+ newCorrelations: correlations.length,
756
+ byType: {
757
+ temporal: correlations.filter(c => c.correlationType === 'temporal').length,
758
+ behavioral: correlations.filter(c => c.correlationType === 'behavioral').length,
759
+ pattern: correlations.filter(c => c.correlationType === 'pattern').length,
760
+ },
761
+ correlations: correlations.map(c => ({
762
+ id: c.id,
763
+ type: c.correlationType,
764
+ description: c.description,
765
+ confidence: c.confidence,
766
+ implications: c.implications,
767
+ findingCount: c.findingIds.length,
768
+ })),
769
+ message: correlations.length > 0
770
+ ? `Found ${correlations.length} cross-vector correlations. High correlation count may indicate coordinated manipulation.`
771
+ : 'No new correlations found.',
772
+ });
773
+ }
774
+ case 'list': {
775
+ const investigations = orchestrator.getInvestigations();
776
+ const allCorrelations = investigations.flatMap(i => i.correlations);
777
+ return JSON.stringify({
778
+ success: true,
779
+ operation: 'list',
780
+ totalCorrelations: allCorrelations.length,
781
+ byType: {
782
+ temporal: allCorrelations.filter(c => c.correlationType === 'temporal').length,
783
+ behavioral: allCorrelations.filter(c => c.correlationType === 'behavioral').length,
784
+ pattern: allCorrelations.filter(c => c.correlationType === 'pattern').length,
785
+ technical: allCorrelations.filter(c => c.correlationType === 'technical').length,
786
+ },
787
+ correlations: allCorrelations.map(c => ({
788
+ id: c.id,
789
+ type: c.correlationType,
790
+ description: c.description,
791
+ confidence: c.confidence,
792
+ })),
793
+ });
794
+ }
795
+ case 'analyze': {
796
+ const investigations = orchestrator.getInvestigations();
797
+ const allCorrelations = investigations.flatMap(i => i.correlations);
798
+ const highConfidence = allCorrelations.filter(c => c.confidence > 0.7);
799
+ // Analyze patterns
800
+ const patterns = {
801
+ chromeGmailPattern: allCorrelations.filter(c => c.correlationType === 'behavioral' &&
802
+ c.description.includes('Chrome') && c.description.includes('Gmail')).length,
803
+ crossPlatformPattern: allCorrelations.filter(c => c.correlationType === 'pattern' &&
804
+ (c.description.includes('Apple') || c.description.includes('Google'))).length,
805
+ temporalClusters: allCorrelations.filter(c => c.correlationType === 'temporal' && c.confidence > 0.8).length,
806
+ };
807
+ return JSON.stringify({
808
+ success: true,
809
+ operation: 'analyze',
810
+ totalCorrelations: allCorrelations.length,
811
+ highConfidenceCorrelations: highConfidence.length,
812
+ patterns,
813
+ analysis: {
814
+ coordinatedManipulationLikelihood: highConfidence.length > 3 ? 'HIGH' :
815
+ highConfidence.length > 1 ? 'MEDIUM' : 'LOW',
816
+ evidence: highConfidence.length > 0
817
+ ? `${highConfidence.length} high-confidence correlations detected. ${patterns.chromeGmailPattern > 0 ? 'Chrome-Gmail pattern detected. ' : ''}${patterns.crossPlatformPattern > 0 ? 'Cross-platform pattern detected.' : ''}`
818
+ : 'Insufficient correlation evidence.',
819
+ recommendations: [
820
+ highConfidence.length > 3 ? 'Consider filing FTC complaint for coordinated manipulation' : null,
821
+ patterns.chromeGmailPattern > 0 ? 'Document all Chrome-Gmail interactions' : null,
822
+ patterns.crossPlatformPattern > 0 ? 'Investigate data sharing agreements between companies' : null,
823
+ ].filter(Boolean),
824
+ },
825
+ });
826
+ }
827
+ default:
828
+ return JSON.stringify({ success: false, error: `Unknown operation: ${operation}` });
829
+ }
830
+ },
831
+ },
832
+ ],
833
+ };
834
+ }
835
+ // ═══════════════════════════════════════════════════════════════════════════════
836
+ // HELPER FUNCTIONS
837
+ // ═══════════════════════════════════════════════════════════════════════════════
838
+ function getDefaultVectors(target) {
839
+ const defaults = {
840
+ apple: ['imessage_key_substitution', 'imessage_false_e2e'],
841
+ google: [
842
+ 'gmail_hidden_threads', 'gmail_draft_manipulation', 'gmail_unauthorized_access',
843
+ 'chrome_unauthorized_launch', 'chrome_session_hijacking', 'chrome_history_manipulation',
844
+ ],
845
+ meta: [],
846
+ microsoft: [],
847
+ amazon: [],
848
+ };
849
+ return defaults[target] || [];
850
+ }
851
+ //# sourceMappingURL=unifiedInvestigationTools.js.map