create-ai-chat-context-experimental
Version:
Phase 2: TypeScript rewrite - AI Chat Context & Memory System with conversation extraction and AICF format support (powered by aicf-core v2.1.0).
176 lines (174 loc) • 6.97 kB
JavaScript
"use strict";
/**
* This file is part of create-ai-chat-context-experimental.
* Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).
* See LICENSE file for details.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MultiClaudeConsolidationService = void 0;
/**
* Multi-Claude Consolidation Service
* Phase 5.5: Multi-Claude Support - October 2025
*
* Service to consolidate messages from all three Claude instances
*/
const ClaudeCliWatcher_js_1 = require("../watchers/ClaudeCliWatcher.js");
const ClaudeDesktopWatcher_js_1 = require("../watchers/ClaudeDesktopWatcher.js");
const MultiClaudeOrchestrator_js_1 = require("../orchestrators/MultiClaudeOrchestrator.js");
const result_js_1 = require("../types/result.js");
/**
* Service to consolidate messages from all Claude instances
*/
class MultiClaudeConsolidationService {
cliWatcher;
desktopWatcher;
orchestrator;
options;
lastStats = null;
lastCheckTime = 0;
pollingInterval;
constructor(options = {}) {
this.cliWatcher = new ClaudeCliWatcher_js_1.ClaudeCliWatcher();
this.desktopWatcher = new ClaudeDesktopWatcher_js_1.ClaudeDesktopWatcher();
this.orchestrator = new MultiClaudeOrchestrator_js_1.MultiClaudeOrchestrator();
this.options = {
verbose: false,
enableCli: true,
enableDesktop: true,
pollingInterval: 300000, // 5 minutes default
...options,
};
this.pollingInterval = this.options.pollingInterval || 300000;
}
/**
* Check if any Claude instance is available
*/
isAvailable() {
const cliAvailable = (this.options.enableCli ?? false) && this.cliWatcher.isAvailable();
const desktopAvailable = (this.options.enableDesktop ?? false) && this.desktopWatcher.isAvailable();
return cliAvailable || desktopAvailable;
}
/**
* Get available sources
*/
getAvailableSources() {
const sources = [];
if (this.options.enableCli && this.cliWatcher.isAvailable()) {
sources.push('claude-cli');
}
if (this.options.enableDesktop && this.desktopWatcher.isAvailable()) {
sources.push('claude-desktop');
}
return sources;
}
/**
* Consolidate messages from all available sources
* Respects polling interval to avoid excessive disk I/O
*/
async consolidate(webMessages = []) {
try {
// Check if enough time has passed since last check
const now = Date.now();
if (this.lastCheckTime > 0 && now - this.lastCheckTime < this.pollingInterval) {
// Not enough time has passed, return empty result
return (0, result_js_1.Ok)([]);
}
// Update last check time
this.lastCheckTime = now;
let cliMessages = [];
let desktopMessages = [];
// Collect from CLI
if (this.options.enableCli && this.cliWatcher.isAvailable()) {
const projectPath = this.options.cliProjectPath || '.';
const cliResult = this.cliWatcher.getProjectSessions(projectPath);
if (cliResult.ok) {
cliMessages = cliResult.value;
}
else if (this.options.verbose) {
console.warn('Failed to get CLI messages:', cliResult.error);
}
}
// Collect from Desktop
if (this.options.enableDesktop && this.desktopWatcher.isAvailable()) {
const desktopResult = this.desktopWatcher.getAllMessages();
if (desktopResult.ok) {
desktopMessages = desktopResult.value;
}
else if (this.options.verbose) {
console.warn('Failed to get Desktop messages:', desktopResult.error);
}
}
// Consolidate all sources
const consolidationResult = this.orchestrator.consolidate(webMessages, desktopMessages, cliMessages);
if (!consolidationResult.ok) {
return (0, result_js_1.Err)(consolidationResult.error);
}
// Calculate and store statistics
this.orchestrator.getStatistics(consolidationResult.value);
this.lastStats = {
totalMessages: consolidationResult.value.messages.length,
deduplicatedCount: consolidationResult.value.deduplicatedCount,
deduplicationRate: `${((consolidationResult.value.deduplicatedCount / (consolidationResult.value.messages.length + consolidationResult.value.deduplicatedCount)) * 100).toFixed(2)}%`,
sourceBreakdown: consolidationResult.value.sourceBreakdown,
conflictCount: consolidationResult.value.conflictCount,
timestamp: new Date().toISOString(),
};
return (0, result_js_1.Ok)(consolidationResult.value.messages);
}
catch (error) {
return (0, result_js_1.Err)(error instanceof Error ? error : new Error(String(error)));
}
}
/**
* Get last consolidation statistics
*/
getLastStats() {
return this.lastStats;
}
/**
* Get messages by source
*/
getMessagesBySource(messages, source) {
return messages.filter((msg) => {
const metadata = msg.metadata;
return metadata?.['source'] === source;
});
}
/**
* Get messages by conversation
*/
getMessagesByConversation(messages, conversationId) {
return messages.filter((msg) => msg.conversationId === conversationId);
}
/**
* Get unique conversations
*/
getConversations(messages) {
const conversations = new Set(messages.map((msg) => msg.conversationId));
return Array.from(conversations);
}
/**
* Get consolidation summary
*/
getSummary() {
if (!this.lastStats) {
return 'No consolidation data available';
}
const { totalMessages, deduplicatedCount, deduplicationRate, sourceBreakdown, conflictCount } = this.lastStats;
return `
Multi-Claude Consolidation Summary
═══════════════════════════════════
Total Messages: ${totalMessages}
Deduplicated: ${deduplicatedCount} (${deduplicationRate})
Conflicts Resolved: ${conflictCount}
Source Breakdown:
• Claude Web: ${sourceBreakdown.web}
• Claude Desktop: ${sourceBreakdown.desktop}
• Claude CLI: ${sourceBreakdown.cli}
Available Sources: ${this.getAvailableSources().join(', ') || 'None'}
Last Updated: ${this.lastStats.timestamp}
`.trim();
}
}
exports.MultiClaudeConsolidationService = MultiClaudeConsolidationService;
//# sourceMappingURL=MultiClaudeConsolidationService.js.map