opencodespaces 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/sync.js +41 -25
- package/package.json +1 -1
package/dist/commands/sync.js
CHANGED
|
@@ -116,33 +116,18 @@ async function startSync(sessionId, localDir) {
|
|
|
116
116
|
const spinner = ora('Initializing sync...').start();
|
|
117
117
|
try {
|
|
118
118
|
// Initialize sync on server (get SSH credentials)
|
|
119
|
+
// The API auto-cleans stale connections, but handle 409 as fallback
|
|
119
120
|
let syncInfo;
|
|
120
121
|
try {
|
|
121
122
|
syncInfo = await api.initSync(sessionId);
|
|
122
123
|
}
|
|
123
124
|
catch (initError) {
|
|
124
|
-
// Handle "Sync already active" error (409)
|
|
125
125
|
if (initError instanceof ApiError && initError.statusCode === 409) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
name: 'cleanup',
|
|
132
|
-
message: 'Clean up stale connection and retry?',
|
|
133
|
-
default: true,
|
|
134
|
-
},
|
|
135
|
-
]);
|
|
136
|
-
if (cleanup) {
|
|
137
|
-
spinner.start('Cleaning up stale connection...');
|
|
138
|
-
await api.stopSync(sessionId);
|
|
139
|
-
spinner.text = 'Initializing sync...';
|
|
140
|
-
syncInfo = await api.initSync(sessionId);
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
logger.info('Run "opencodespaces sync stop" to manually clean up.');
|
|
144
|
-
process.exit(0);
|
|
145
|
-
}
|
|
126
|
+
// Fallback: force cleanup and retry (API should auto-clean, but just in case)
|
|
127
|
+
spinner.text = 'Cleaning up stale connection...';
|
|
128
|
+
await api.stopSync(sessionId);
|
|
129
|
+
spinner.text = 'Initializing sync...';
|
|
130
|
+
syncInfo = await api.initSync(sessionId);
|
|
146
131
|
}
|
|
147
132
|
else {
|
|
148
133
|
throw initError;
|
|
@@ -176,7 +161,20 @@ async function startSync(sessionId, localDir) {
|
|
|
176
161
|
'two-way-resolved',
|
|
177
162
|
...ignoreArgs,
|
|
178
163
|
];
|
|
179
|
-
|
|
164
|
+
try {
|
|
165
|
+
execFileSync('mutagen', mutagenArgs, { stdio: 'pipe' });
|
|
166
|
+
}
|
|
167
|
+
catch (mutagenError) {
|
|
168
|
+
const errorMsg = mutagenError?.stderr?.toString() ||
|
|
169
|
+
mutagenError.message;
|
|
170
|
+
if (errorMsg.includes('unable to locate agent bundle') ||
|
|
171
|
+
errorMsg.includes('unable to install agent')) {
|
|
172
|
+
throw new Error('Mutagen agent installation failed. Your mutagen installation may be missing agent bundles.\n' +
|
|
173
|
+
'Fix: Download the full mutagen release from https://github.com/mutagen-io/mutagen/releases\n' +
|
|
174
|
+
'and ensure mutagen-agents.tar.gz is next to the mutagen binary.');
|
|
175
|
+
}
|
|
176
|
+
throw mutagenError;
|
|
177
|
+
}
|
|
180
178
|
spinner.succeed(`Syncing ${localPath} ↔ ${hostAlias}:${remotePath}`);
|
|
181
179
|
logger.log('');
|
|
182
180
|
logger.warn('Note: node_modules and other large directories are excluded by default.');
|
|
@@ -366,18 +364,36 @@ async function ensureSshConfigIncludes() {
|
|
|
366
364
|
}
|
|
367
365
|
}
|
|
368
366
|
/**
|
|
369
|
-
* Check if Mutagen is installed
|
|
367
|
+
* Check if Mutagen is installed and warn about missing agent bundles on Linux
|
|
370
368
|
*/
|
|
371
369
|
function checkDependencies() {
|
|
372
370
|
try {
|
|
373
371
|
execSync('mutagen version', { stdio: 'pipe' });
|
|
372
|
+
// Warn about missing agent bundles (common Linux issue)
|
|
373
|
+
if (process.platform === 'linux') {
|
|
374
|
+
try {
|
|
375
|
+
const mutagenPath = execSync('which mutagen', { encoding: 'utf-8' }).trim();
|
|
376
|
+
const mutagenDir = path.dirname(mutagenPath);
|
|
377
|
+
const bundlePaths = [
|
|
378
|
+
path.join(mutagenDir, 'mutagen-agents.tar.gz'),
|
|
379
|
+
'/usr/local/libexec/mutagen-agents.tar.gz',
|
|
380
|
+
];
|
|
381
|
+
if (!bundlePaths.some(p => fs.existsSync(p))) {
|
|
382
|
+
logger.warn('mutagen-agents.tar.gz not found. Sync relies on the container\'s pre-installed agent.');
|
|
383
|
+
logger.dim('For best compatibility, download the full mutagen release archive.');
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
// Non-critical, continue
|
|
388
|
+
}
|
|
389
|
+
}
|
|
374
390
|
}
|
|
375
391
|
catch {
|
|
376
392
|
logger.error('Mutagen not found. Please install it:');
|
|
377
393
|
logger.log('');
|
|
378
394
|
logger.log(' macOS: brew install mutagen-io/mutagen/mutagen');
|
|
379
|
-
logger.log(' Linux: Download from https://mutagen
|
|
380
|
-
logger.log('
|
|
395
|
+
logger.log(' Linux: Download FULL archive from https://github.com/mutagen-io/mutagen/releases');
|
|
396
|
+
logger.log(' (must include mutagen-agents.tar.gz)');
|
|
381
397
|
logger.log('');
|
|
382
398
|
process.exit(1);
|
|
383
399
|
}
|