vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739
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 +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const os = require('os');
|
|
4
|
-
const crypto = require('crypto');
|
|
5
|
-
const EventEmitter = require('events');
|
|
6
|
-
const RemoteControlServer = require('./remote-control-server');
|
|
7
|
-
const SyncEngineCore = require('./sync-engine-core');
|
|
8
|
-
const SyncEngineFileOperations = require('./sync-engine-file-ops');
|
|
9
|
-
const SyncEngineConflictResolution = require('./sync-engine-conflicts');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* SyncEngine - Handles bidirectional sync between local files and AWS DynamoDB
|
|
13
|
-
*
|
|
14
|
-
* Features:
|
|
15
|
-
* - Real-time change detection using file watchers
|
|
16
|
-
* - Conflict resolution strategies
|
|
17
|
-
* - Offline queue for disconnected state
|
|
18
|
-
* - Change history tracking
|
|
19
|
-
* - Delta sync for efficiency
|
|
20
|
-
*/
|
|
21
|
-
class SyncEngine extends SyncEngineCore {
|
|
22
|
-
constructor(options = {}) {
|
|
23
|
-
super(options);
|
|
24
|
-
|
|
25
|
-
// Enhanced options
|
|
26
|
-
this.options = {
|
|
27
|
-
syncInterval: options.syncInterval || 30000, // 30 seconds
|
|
28
|
-
conflictStrategy: options.conflictStrategy || 'last-write-wins',
|
|
29
|
-
offlineMode: options.offlineMode || false,
|
|
30
|
-
enableRemoteControl: options.enableRemoteControl !== false, // Default to true
|
|
31
|
-
remoteControlPort: options.remoteControlPort || 3457,
|
|
32
|
-
...options
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// Initialize components
|
|
36
|
-
this.fileOperations = new SyncEngineFileOperations(this);
|
|
37
|
-
this.conflictResolution = new SyncEngineConflictResolution(this);
|
|
38
|
-
|
|
39
|
-
// Remote control server
|
|
40
|
-
this.remoteControlServer = null;
|
|
41
|
-
|
|
42
|
-
// Start remote control server if enabled
|
|
43
|
-
if (this.options.enableRemoteControl) {
|
|
44
|
-
this.remoteControlServer = new RemoteControlServer({
|
|
45
|
-
port: this.options.remoteControlPort,
|
|
46
|
-
region: options.region,
|
|
47
|
-
syncEngine: this
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
userPoolId: options.cognitoUserPoolId
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Set up remote control event handlers
|
|
55
|
-
this.setupRemoteControlHandlers();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Setup remote control event handlers
|
|
61
|
-
*/
|
|
62
|
-
setupRemoteControlHandlers() {
|
|
63
|
-
if (!this.remoteControlServer) return;
|
|
64
|
-
|
|
65
|
-
// Handle remote control commands
|
|
66
|
-
this.remoteControlServer.on('command', async (command) => {
|
|
67
|
-
console.log('🎮 Remote control command received:', command);
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
switch (command.type) {
|
|
71
|
-
case 'start-auto':
|
|
72
|
-
await this.handleStartAutoCommand(command);
|
|
73
|
-
break;
|
|
74
|
-
case 'stop-auto':
|
|
75
|
-
await this.handleStopAutoCommand(command);
|
|
76
|
-
break;
|
|
77
|
-
case 'get-status':
|
|
78
|
-
await this.handleGetStatusCommand(command);
|
|
79
|
-
break;
|
|
80
|
-
default:
|
|
81
|
-
console.warn('⚠️ Unknown remote control command:', command.type);
|
|
82
|
-
}
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error('❌ Error handling remote control command:', error);
|
|
85
|
-
this.remoteControlServer.sendToClientById(command.clientId, 'command-error', {
|
|
86
|
-
command: command.type,
|
|
87
|
-
error: error.message
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Handle client authentication
|
|
93
|
-
this.remoteControlServer.on('client-authenticated', (data) => {
|
|
94
|
-
console.log('🔐 Remote control client authenticated:', data.userInfo.username);
|
|
95
|
-
this.emit('remote-client-authenticated', data);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Handle client disconnection
|
|
99
|
-
this.remoteControlServer.on('client-disconnected', (data) => {
|
|
100
|
-
console.log('🔌 Remote control client disconnected:', data.clientId);
|
|
101
|
-
this.emit('remote-client-disconnected', data);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Handle start-auto command
|
|
107
|
-
*/
|
|
108
|
-
async handleStartAutoCommand(command) {
|
|
109
|
-
console.log('🚀 Starting auto mode via remote control');
|
|
110
|
-
|
|
111
|
-
// Emit event for main application to handle
|
|
112
|
-
this.emit('remote-start-auto', {
|
|
113
|
-
clientId: command.clientId,
|
|
114
|
-
userInfo: command.userInfo,
|
|
115
|
-
data: command.data
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Send confirmation back to client
|
|
119
|
-
this.remoteControlServer.sendToClientById(command.clientId, 'command-success', {
|
|
120
|
-
command: 'start-auto',
|
|
121
|
-
message: 'Auto mode started successfully'
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Handle stop-auto command
|
|
127
|
-
*/
|
|
128
|
-
async handleStopAutoCommand(command) {
|
|
129
|
-
console.log('🛑 Stopping auto mode via remote control');
|
|
130
|
-
|
|
131
|
-
// Emit event for main application to handle
|
|
132
|
-
this.emit('remote-stop-auto', {
|
|
133
|
-
clientId: command.clientId,
|
|
134
|
-
userInfo: command.userInfo,
|
|
135
|
-
data: command.data
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// Send confirmation back to client
|
|
139
|
-
this.remoteControlServer.sendToClientById(command.clientId, 'command-success', {
|
|
140
|
-
command: 'stop-auto',
|
|
141
|
-
message: 'Auto mode stopped successfully'
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Handle get-status command
|
|
147
|
-
*/
|
|
148
|
-
async handleGetStatusCommand(command) {
|
|
149
|
-
console.log('📊 Getting status via remote control');
|
|
150
|
-
|
|
151
|
-
// Get current status
|
|
152
|
-
const status = {
|
|
153
|
-
computerId: this.computerId,
|
|
154
|
-
isOnline: this.isOnline,
|
|
155
|
-
isSyncing: this.isSyncing,
|
|
156
|
-
lastSyncTime: this.lastSyncTime,
|
|
157
|
-
offlineQueueSize: this.offlineQueue.length,
|
|
158
|
-
changeHistorySize: this.changeHistory.length,
|
|
159
|
-
syncEngineStatus: 'running'
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// Send status back to client
|
|
163
|
-
this.remoteControlServer.sendToClientById(command.clientId, 'status-response', {
|
|
164
|
-
command: 'get-status',
|
|
165
|
-
status
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Get unique computer ID
|
|
171
|
-
*/
|
|
172
|
-
_getComputerId() {
|
|
173
|
-
const hostname = os.hostname();
|
|
174
|
-
return hostname;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Initialize AWS clients
|
|
179
|
-
*/
|
|
180
|
-
async initialize() {
|
|
181
|
-
try {
|
|
182
|
-
// Initialize DynamoDB client
|
|
183
|
-
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
|
|
184
|
-
const { DynamoDBDocumentClient } = require('@aws-sdk/lib-dynamodb');
|
|
185
|
-
|
|
186
|
-
const region = process.env.AWS_REGION || 'us-east-1';
|
|
187
|
-
const client = new DynamoDBClient({ region });
|
|
188
|
-
this.dynamoClient = DynamoDBDocumentClient.from(client);
|
|
189
|
-
|
|
190
|
-
// Initialize WebSocket client for real-time updates
|
|
191
|
-
await this._initializeWebSocket();
|
|
192
|
-
|
|
193
|
-
this.emit('initialized');
|
|
194
|
-
return true;
|
|
195
|
-
} catch (error) {
|
|
196
|
-
// If AWS SDK is not installed in this environment (common in local dev),
|
|
197
|
-
// fall back to offline mode instead of throwing so the CLI remains usable.
|
|
198
|
-
if (error && error.code === 'MODULE_NOT_FOUND' && /@aws-sdk\//.test(error.message)) {
|
|
199
|
-
this.options.offlineMode = true;
|
|
200
|
-
this.isOnline = false;
|
|
201
|
-
this.emit('warning', { type: 'offline-fallback', message: 'AWS SDK not available, running in offline mode', error });
|
|
202
|
-
this.emit('initialized');
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
this.emit('error', { type: 'initialization', error });
|
|
207
|
-
throw error;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Initialize WebSocket connection for real-time updates
|
|
213
|
-
*/
|
|
214
|
-
async _initializeWebSocket() {
|
|
215
|
-
// TODO: Implement WebSocket connection to AWS IoT Core or API Gateway WebSocket
|
|
216
|
-
// For now, we'll use polling
|
|
217
|
-
this.emit('websocket-status', { connected: false, reason: 'not-implemented' });
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Start sync engine
|
|
222
|
-
*/
|
|
223
|
-
async start() {
|
|
224
|
-
if (!this.dynamoClient) {
|
|
225
|
-
await this.initialize();
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Start remote control server
|
|
229
|
-
if (this.remoteControlServer && !this.remoteControlServer.isRunning) {
|
|
230
|
-
try {
|
|
231
|
-
await this.remoteControlServer.start();
|
|
232
|
-
console.log('🚀 Remote control server started');
|
|
233
|
-
} catch (error) {
|
|
234
|
-
console.error('❌ Failed to start remote control server:', error);
|
|
235
|
-
this.emit('error', { type: 'remote-control-start', error });
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Start periodic sync
|
|
240
|
-
this.syncInterval = setInterval(() => {
|
|
241
|
-
this.sync().catch(error => {
|
|
242
|
-
this.emit('error', { type: 'sync', error });
|
|
243
|
-
});
|
|
244
|
-
}, this.options.syncInterval);
|
|
245
|
-
|
|
246
|
-
// Do initial sync
|
|
247
|
-
await this.sync();
|
|
248
|
-
|
|
249
|
-
this.emit('started');
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Stop sync engine
|
|
254
|
-
*/
|
|
255
|
-
async stop() {
|
|
256
|
-
// Stop remote control server
|
|
257
|
-
if (this.remoteControlServer && this.remoteControlServer.isRunning) {
|
|
258
|
-
try {
|
|
259
|
-
await this.remoteControlServer.stop();
|
|
260
|
-
console.log('🛑 Remote control server stopped');
|
|
261
|
-
} catch (error) {
|
|
262
|
-
console.error('❌ Failed to stop remote control server:', error);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (this.syncInterval) {
|
|
267
|
-
clearInterval(this.syncInterval);
|
|
268
|
-
this.syncInterval = null;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
this.emit('stopped');
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Perform sync operation
|
|
276
|
-
*/
|
|
277
|
-
async sync() {
|
|
278
|
-
if (this.isSyncing) {
|
|
279
|
-
return; // Already syncing
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
this.isSyncing = true;
|
|
283
|
-
this.emit('sync-start');
|
|
284
|
-
|
|
285
|
-
try {
|
|
286
|
-
// Check if online
|
|
287
|
-
if (!this.isOnline) {
|
|
288
|
-
this.emit('sync-complete', { status: 'offline', queued: this.offlineQueue.length });
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Process offline queue first
|
|
293
|
-
if (this.offlineQueue.length > 0) {
|
|
294
|
-
await this._processOfflineQueue();
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Fetch remote changes
|
|
298
|
-
const remoteChanges = await this._fetchRemoteChanges();
|
|
299
|
-
|
|
300
|
-
// Detect local changes
|
|
301
|
-
const localChanges = await this._detectLocalChanges();
|
|
302
|
-
|
|
303
|
-
// Resolve conflicts
|
|
304
|
-
const conflicts = this._detectConflicts(localChanges, remoteChanges);
|
|
305
|
-
if (conflicts.length > 0) {
|
|
306
|
-
await this._resolveConflicts(conflicts);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Apply remote changes locally
|
|
310
|
-
if (remoteChanges.length > 0) {
|
|
311
|
-
await this._applyRemoteChanges(remoteChanges);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Push local changes to remote
|
|
315
|
-
if (localChanges.length > 0) {
|
|
316
|
-
await this._pushLocalChanges(localChanges);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
this.lastSyncTime = Date.now();
|
|
320
|
-
this.emit('sync-complete', {
|
|
321
|
-
status: 'success',
|
|
322
|
-
remoteChanges: remoteChanges.length,
|
|
323
|
-
localChanges: localChanges.length,
|
|
324
|
-
conflicts: conflicts.length
|
|
325
|
-
});
|
|
326
|
-
} catch (error) {
|
|
327
|
-
this.emit('sync-complete', { status: 'error', error: error.message });
|
|
328
|
-
// Don't throw - just emit error event
|
|
329
|
-
this.emit('error', { type: 'sync', error: error.message });
|
|
330
|
-
} finally {
|
|
331
|
-
this.isSyncing = false;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Fetch remote changes from DynamoDB
|
|
337
|
-
*/
|
|
338
|
-
async _fetchRemoteChanges() {
|
|
339
|
-
if (!this.dynamoClient) {
|
|
340
|
-
this.emit('warning', { type: 'no-dynamo', message: 'DynamoDB client not initialized, skipping remote fetch' });
|
|
341
|
-
return [];
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const { ScanCommand } = require('@aws-sdk/lib-dynamodb');
|
|
345
|
-
|
|
346
|
-
const tableName = process.env.DYNAMODB_TABLE_NAME || 'vibecodingmachine-requirements';
|
|
347
|
-
const lastSync = this.lastSyncTime || 0;
|
|
348
|
-
|
|
349
|
-
try {
|
|
350
|
-
// Use Scan with filter instead of Query since we need to check all items
|
|
351
|
-
// In production, consider using DynamoDB Streams for real-time updates
|
|
352
|
-
const command = new ScanCommand({
|
|
353
|
-
TableName: tableName,
|
|
354
|
-
FilterExpression: '#ts > :lastSync',
|
|
355
|
-
ExpressionAttributeNames: {
|
|
356
|
-
'#ts': 'timestamp'
|
|
357
|
-
},
|
|
358
|
-
ExpressionAttributeValues: {
|
|
359
|
-
':lastSync': lastSync
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
const response = await this.dynamoClient.send(command);
|
|
364
|
-
return response.Items || [];
|
|
365
|
-
} catch (error) {
|
|
366
|
-
this.emit('error', { type: 'fetch-remote', error });
|
|
367
|
-
return [];
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Detect local changes
|
|
373
|
-
*/
|
|
374
|
-
async _detectLocalChanges() {
|
|
375
|
-
// TODO: Implement file watching and change detection
|
|
376
|
-
// For now, return empty array
|
|
377
|
-
return [];
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Detect conflicts between local and remote changes
|
|
382
|
-
*/
|
|
383
|
-
_detectConflicts(localChanges, remoteChanges) {
|
|
384
|
-
const conflicts = [];
|
|
385
|
-
|
|
386
|
-
for (const local of localChanges) {
|
|
387
|
-
for (const remote of remoteChanges) {
|
|
388
|
-
if (local.requirementId === remote.requirementId) {
|
|
389
|
-
// Same requirement modified both locally and remotely
|
|
390
|
-
if (local.timestamp !== remote.timestamp) {
|
|
391
|
-
conflicts.push({ local, remote });
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return conflicts;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Resolve conflicts based on strategy
|
|
402
|
-
*/
|
|
403
|
-
async _resolveConflicts(conflicts) {
|
|
404
|
-
for (const conflict of conflicts) {
|
|
405
|
-
this.emit('conflict', conflict);
|
|
406
|
-
|
|
407
|
-
let resolution;
|
|
408
|
-
switch (this.options.conflictStrategy) {
|
|
409
|
-
case 'last-write-wins':
|
|
410
|
-
resolution = conflict.local.timestamp > conflict.remote.timestamp
|
|
411
|
-
? conflict.local
|
|
412
|
-
: conflict.remote;
|
|
413
|
-
break;
|
|
414
|
-
|
|
415
|
-
case 'manual':
|
|
416
|
-
// Emit event for manual resolution
|
|
417
|
-
resolution = await new Promise((resolve) => {
|
|
418
|
-
this.once('conflict-resolved', resolve);
|
|
419
|
-
});
|
|
420
|
-
break;
|
|
421
|
-
|
|
422
|
-
case 'auto-merge':
|
|
423
|
-
resolution = this._autoMerge(conflict.local, conflict.remote);
|
|
424
|
-
break;
|
|
425
|
-
|
|
426
|
-
default:
|
|
427
|
-
resolution = conflict.remote; // Default to remote
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Log conflict resolution
|
|
431
|
-
this.changeHistory.push({
|
|
432
|
-
type: 'conflict-resolution',
|
|
433
|
-
timestamp: Date.now(),
|
|
434
|
-
conflict,
|
|
435
|
-
resolution
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Auto-merge non-overlapping changes
|
|
442
|
-
*/
|
|
443
|
-
_autoMerge(local, remote) {
|
|
444
|
-
// Simple merge: combine changes from both
|
|
445
|
-
return {
|
|
446
|
-
...remote,
|
|
447
|
-
...local,
|
|
448
|
-
timestamp: Math.max(local.timestamp, remote.timestamp)
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Apply remote changes locally
|
|
454
|
-
*/
|
|
455
|
-
async _applyRemoteChanges(changes) {
|
|
456
|
-
for (const change of changes) {
|
|
457
|
-
try {
|
|
458
|
-
// TODO: Apply change to local requirements file
|
|
459
|
-
this.emit('remote-change-applied', change);
|
|
460
|
-
} catch (error) {
|
|
461
|
-
this.emit('error', { type: 'apply-remote', change, error });
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Push local changes to remote
|
|
468
|
-
*/
|
|
469
|
-
async _pushLocalChanges(changes) {
|
|
470
|
-
if (!this.dynamoClient) {
|
|
471
|
-
this.emit('warning', { type: 'no-dynamo', message: 'DynamoDB client not initialized, queuing local changes' });
|
|
472
|
-
// Queue all changes for later push
|
|
473
|
-
this.offlineQueue.push(...changes);
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
const { PutCommand } = require('@aws-sdk/lib-dynamodb');
|
|
478
|
-
|
|
479
|
-
const tableName = process.env.DYNAMODB_TABLE_NAME || 'vibecodingmachine-requirements';
|
|
480
|
-
|
|
481
|
-
for (const change of changes) {
|
|
482
|
-
try {
|
|
483
|
-
const command = new PutCommand({
|
|
484
|
-
TableName: tableName,
|
|
485
|
-
Item: {
|
|
486
|
-
computerId: this.computerId,
|
|
487
|
-
timestamp: Date.now(),
|
|
488
|
-
...change
|
|
489
|
-
}
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
await this.dynamoClient.send(command);
|
|
493
|
-
this.emit('local-change-pushed', change);
|
|
494
|
-
} catch (error) {
|
|
495
|
-
this.emit('error', { type: 'push-local', change, error });
|
|
496
|
-
|
|
497
|
-
// Add to offline queue if push fails
|
|
498
|
-
if (!this.isOnline) {
|
|
499
|
-
this.offlineQueue.push(change);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* Process offline queue
|
|
507
|
-
*/
|
|
508
|
-
async _processOfflineQueue() {
|
|
509
|
-
const queue = [...this.offlineQueue];
|
|
510
|
-
this.offlineQueue = [];
|
|
511
|
-
|
|
512
|
-
for (const change of queue) {
|
|
513
|
-
try {
|
|
514
|
-
await this._pushLocalChanges([change]);
|
|
515
|
-
} catch (error) {
|
|
516
|
-
// Re-add to queue if still failing
|
|
517
|
-
this.offlineQueue.push(change);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Get sync status
|
|
524
|
-
*/
|
|
525
|
-
getStatus() {
|
|
526
|
-
return {
|
|
527
|
-
computerId: this.computerId,
|
|
528
|
-
isOnline: this.isOnline,
|
|
529
|
-
isSyncing: this.isSyncing,
|
|
530
|
-
lastSyncTime: this.lastSyncTime,
|
|
531
|
-
queuedChanges: this.offlineQueue.length,
|
|
532
|
-
conflictStrategy: this.options.conflictStrategy
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Get change history
|
|
538
|
-
*/
|
|
539
|
-
getHistory(limit = 100) {
|
|
540
|
-
return this.changeHistory.slice(-limit);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Set online/offline mode
|
|
545
|
-
*/
|
|
546
|
-
setOnlineMode(isOnline) {
|
|
547
|
-
this.isOnline = isOnline;
|
|
548
|
-
this.emit('online-status-changed', { isOnline });
|
|
549
|
-
|
|
550
|
-
if (isOnline && this.offlineQueue.length > 0) {
|
|
551
|
-
// Trigger sync to process offline queue
|
|
552
|
-
this.sync().catch(error => {
|
|
553
|
-
this.emit('error', { type: 'sync', error });
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
module.exports = SyncEngine;
|