@comfanion/workflow 4.36.17 → 4.36.18
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/bin/cli.js +130 -60
- package/package.json +1 -1
- package/src/build-info.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -274,16 +274,27 @@ program
|
|
|
274
274
|
const vectorizerDir = path.join(targetDir, 'vectorizer');
|
|
275
275
|
const vectorsDir = path.join(targetDir, 'vectors');
|
|
276
276
|
const tempVectors = path.join(process.cwd(), '.vectors-temp');
|
|
277
|
+
const tempNodeModules = path.join(process.cwd(), '.vectorizer-nm-temp');
|
|
277
278
|
|
|
278
279
|
let hadVectors = false;
|
|
280
|
+
let hadVectorizerModules = false;
|
|
281
|
+
let oldPkgHash = null;
|
|
279
282
|
let existingConfigContent = null;
|
|
280
283
|
|
|
281
284
|
if (await fs.pathExists(targetDir)) {
|
|
282
285
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
283
286
|
const backupDir = path.join(process.cwd(), `.opencode.backup-${timestamp}`);
|
|
284
287
|
|
|
285
|
-
// Check what we need to preserve
|
|
288
|
+
// Check what we need to preserve
|
|
286
289
|
hadVectors = await fs.pathExists(vectorsDir);
|
|
290
|
+
hadVectorizerModules = await fs.pathExists(path.join(vectorizerDir, 'node_modules'));
|
|
291
|
+
|
|
292
|
+
// Get old package.json hash
|
|
293
|
+
const oldPkgPath = path.join(vectorizerDir, 'package.json');
|
|
294
|
+
if (await fs.pathExists(oldPkgPath)) {
|
|
295
|
+
const oldPkg = await fs.readFile(oldPkgPath, 'utf8');
|
|
296
|
+
oldPkgHash = require('crypto').createHash('md5').update(oldPkg).digest('hex');
|
|
297
|
+
}
|
|
287
298
|
|
|
288
299
|
// Read existing config.yaml for merge
|
|
289
300
|
const existingConfigPath = path.join(targetDir, 'config.yaml');
|
|
@@ -291,12 +302,18 @@ program
|
|
|
291
302
|
existingConfigContent = await fs.readFile(existingConfigPath, 'utf8');
|
|
292
303
|
}
|
|
293
304
|
|
|
294
|
-
// Preserve vector indexes
|
|
305
|
+
// Preserve vector indexes
|
|
295
306
|
if (hadVectors) {
|
|
296
307
|
spinner.text = 'Preserving vector indexes...';
|
|
297
308
|
await fs.move(vectorsDir, tempVectors, { overwrite: true });
|
|
298
309
|
}
|
|
299
310
|
|
|
311
|
+
// Preserve vectorizer node_modules
|
|
312
|
+
if (hadVectorizerModules) {
|
|
313
|
+
spinner.text = 'Preserving vectorizer cache...';
|
|
314
|
+
await fs.move(path.join(vectorizerDir, 'node_modules'), tempNodeModules, { overwrite: true });
|
|
315
|
+
}
|
|
316
|
+
|
|
300
317
|
// Create backup (without node_modules and vectors)
|
|
301
318
|
spinner.text = 'Creating backup...';
|
|
302
319
|
await fs.copy(targetDir, backupDir, {
|
|
@@ -314,41 +331,59 @@ program
|
|
|
314
331
|
// Copy .opencode structure (fresh, no old files)
|
|
315
332
|
await fs.copy(OPENCODE_SRC, targetDir);
|
|
316
333
|
|
|
317
|
-
// Copy vectorizer source files
|
|
334
|
+
// Copy vectorizer source files
|
|
318
335
|
if (await fs.pathExists(VECTORIZER_SRC)) {
|
|
319
336
|
const newVectorizerDir = path.join(targetDir, 'vectorizer');
|
|
320
337
|
await fs.ensureDir(newVectorizerDir);
|
|
321
338
|
await fs.copy(path.join(VECTORIZER_SRC, 'index.js'), path.join(newVectorizerDir, 'index.js'));
|
|
322
339
|
await fs.copy(path.join(VECTORIZER_SRC, 'package.json'), path.join(newVectorizerDir, 'package.json'));
|
|
323
340
|
|
|
324
|
-
// Install dependencies only if vectorizer is enabled
|
|
325
341
|
if (config.vectorizer_enabled) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
342
|
+
// Check if package.json changed
|
|
343
|
+
const newPkgPath = path.join(newVectorizerDir, 'package.json');
|
|
344
|
+
const newPkg = await fs.readFile(newPkgPath, 'utf8');
|
|
345
|
+
const newPkgHash = require('crypto').createHash('md5').update(newPkg).digest('hex');
|
|
346
|
+
|
|
347
|
+
if (hadVectorizerModules && oldPkgHash === newPkgHash) {
|
|
348
|
+
// Dependencies unchanged - restore cached node_modules
|
|
349
|
+
spinner.text = 'Restoring vectorizer cache (deps unchanged)...';
|
|
350
|
+
await fs.move(tempNodeModules, path.join(newVectorizerDir, 'node_modules'), { overwrite: true });
|
|
351
|
+
} else {
|
|
352
|
+
// Dependencies changed or new install
|
|
353
|
+
spinner.text = 'Installing vectorizer dependencies...';
|
|
354
|
+
if (await fs.pathExists(tempNodeModules)) {
|
|
355
|
+
await fs.remove(tempNodeModules);
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
const steps = [
|
|
359
|
+
'Installing vectorizer dependencies...',
|
|
360
|
+
'Downloading @xenova/transformers (~50MB)...',
|
|
361
|
+
'Installing vectordb...',
|
|
362
|
+
'Installing glob...',
|
|
363
|
+
'Finalizing vectorizer setup...'
|
|
364
|
+
];
|
|
365
|
+
let stepIndex = 0;
|
|
366
|
+
const progressInterval = setInterval(() => {
|
|
367
|
+
stepIndex = (stepIndex + 1) % steps.length;
|
|
368
|
+
spinner.text = steps[stepIndex];
|
|
369
|
+
}, 3000);
|
|
370
|
+
|
|
371
|
+
execSync('npm install', {
|
|
372
|
+
cwd: newVectorizerDir,
|
|
373
|
+
stdio: 'pipe',
|
|
374
|
+
timeout: 180000
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
clearInterval(progressInterval);
|
|
378
|
+
spinner.text = 'Vectorizer installed!';
|
|
379
|
+
} catch (e) {
|
|
380
|
+
// Non-fatal
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
// Vectorizer disabled - clean up temp
|
|
385
|
+
if (await fs.pathExists(tempNodeModules)) {
|
|
386
|
+
await fs.remove(tempNodeModules);
|
|
352
387
|
}
|
|
353
388
|
}
|
|
354
389
|
}
|
|
@@ -576,8 +611,17 @@ program
|
|
|
576
611
|
spinner.text = 'Reading config.yaml...';
|
|
577
612
|
const configBackup = await fs.readFile(configPath, 'utf8');
|
|
578
613
|
|
|
579
|
-
// Check
|
|
614
|
+
// Check what exists
|
|
580
615
|
const hasVectors = await fs.pathExists(vectorsDir);
|
|
616
|
+
const hasVectorizerModules = await fs.pathExists(path.join(vectorizerDir, 'node_modules'));
|
|
617
|
+
|
|
618
|
+
// Get old package.json hash (to check if deps changed)
|
|
619
|
+
let oldPkgHash = null;
|
|
620
|
+
const oldPkgPath = path.join(vectorizerDir, 'package.json');
|
|
621
|
+
if (await fs.pathExists(oldPkgPath)) {
|
|
622
|
+
const oldPkg = await fs.readFile(oldPkgPath, 'utf8');
|
|
623
|
+
oldPkgHash = require('crypto').createHash('md5').update(oldPkg).digest('hex');
|
|
624
|
+
}
|
|
581
625
|
|
|
582
626
|
// Create full backup (unless --no-backup)
|
|
583
627
|
if (options.backup !== false) {
|
|
@@ -587,13 +631,20 @@ program
|
|
|
587
631
|
});
|
|
588
632
|
}
|
|
589
633
|
|
|
590
|
-
// Preserve
|
|
634
|
+
// Preserve vector indexes
|
|
591
635
|
const tempVectors = path.join(process.cwd(), '.vectors-temp');
|
|
592
636
|
if (hasVectors) {
|
|
593
637
|
spinner.text = 'Preserving vector indexes...';
|
|
594
638
|
await fs.move(vectorsDir, tempVectors, { overwrite: true });
|
|
595
639
|
}
|
|
596
640
|
|
|
641
|
+
// Preserve vectorizer node_modules (will restore if package.json unchanged)
|
|
642
|
+
const tempNodeModules = path.join(process.cwd(), '.vectorizer-nm-temp');
|
|
643
|
+
if (hasVectorizerModules) {
|
|
644
|
+
spinner.text = 'Preserving vectorizer cache...';
|
|
645
|
+
await fs.move(path.join(vectorizerDir, 'node_modules'), tempNodeModules, { overwrite: true });
|
|
646
|
+
}
|
|
647
|
+
|
|
597
648
|
// Remove old .opencode directory
|
|
598
649
|
spinner.text = 'Removing old files...';
|
|
599
650
|
await fs.remove(targetDir);
|
|
@@ -602,7 +653,7 @@ program
|
|
|
602
653
|
spinner.text = 'Installing new version...';
|
|
603
654
|
await fs.copy(OPENCODE_SRC, targetDir);
|
|
604
655
|
|
|
605
|
-
// Copy vectorizer source files
|
|
656
|
+
// Copy vectorizer source files
|
|
606
657
|
if (await fs.pathExists(VECTORIZER_SRC)) {
|
|
607
658
|
const newVectorizerDir = path.join(targetDir, 'vectorizer');
|
|
608
659
|
await fs.ensureDir(newVectorizerDir);
|
|
@@ -612,34 +663,53 @@ program
|
|
|
612
663
|
// Check if vectorizer is enabled in user's config
|
|
613
664
|
const vectorizerEnabled = /vectorizer:[\s\S]*?enabled:\s*true/i.test(configBackup);
|
|
614
665
|
|
|
615
|
-
// Install dependencies only if vectorizer is enabled
|
|
616
666
|
if (vectorizerEnabled) {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
667
|
+
// Check if package.json changed
|
|
668
|
+
const newPkgPath = path.join(newVectorizerDir, 'package.json');
|
|
669
|
+
const newPkg = await fs.readFile(newPkgPath, 'utf8');
|
|
670
|
+
const newPkgHash = require('crypto').createHash('md5').update(newPkg).digest('hex');
|
|
671
|
+
|
|
672
|
+
if (hasVectorizerModules && oldPkgHash === newPkgHash) {
|
|
673
|
+
// Dependencies unchanged - restore cached node_modules
|
|
674
|
+
spinner.text = 'Restoring vectorizer cache (deps unchanged)...';
|
|
675
|
+
await fs.move(tempNodeModules, path.join(newVectorizerDir, 'node_modules'), { overwrite: true });
|
|
676
|
+
} else {
|
|
677
|
+
// Dependencies changed or new install - run npm install
|
|
678
|
+
spinner.text = 'Installing vectorizer dependencies...';
|
|
679
|
+
// Clean up temp if exists
|
|
680
|
+
if (await fs.pathExists(tempNodeModules)) {
|
|
681
|
+
await fs.remove(tempNodeModules);
|
|
682
|
+
}
|
|
683
|
+
try {
|
|
684
|
+
const steps = [
|
|
685
|
+
'Installing vectorizer dependencies...',
|
|
686
|
+
'Downloading @xenova/transformers (~50MB)...',
|
|
687
|
+
'Installing vectordb...',
|
|
688
|
+
'Installing glob...',
|
|
689
|
+
'Finalizing vectorizer setup...'
|
|
690
|
+
];
|
|
691
|
+
let stepIndex = 0;
|
|
692
|
+
const progressInterval = setInterval(() => {
|
|
693
|
+
stepIndex = (stepIndex + 1) % steps.length;
|
|
694
|
+
spinner.text = steps[stepIndex];
|
|
695
|
+
}, 3000);
|
|
696
|
+
|
|
697
|
+
execSync('npm install', {
|
|
698
|
+
cwd: newVectorizerDir,
|
|
699
|
+
stdio: 'pipe',
|
|
700
|
+
timeout: 180000
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
clearInterval(progressInterval);
|
|
704
|
+
spinner.text = 'Vectorizer installed!';
|
|
705
|
+
} catch (e) {
|
|
706
|
+
// Non-fatal
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
} else {
|
|
710
|
+
// Vectorizer disabled - clean up temp
|
|
711
|
+
if (await fs.pathExists(tempNodeModules)) {
|
|
712
|
+
await fs.remove(tempNodeModules);
|
|
643
713
|
}
|
|
644
714
|
}
|
|
645
715
|
}
|
package/package.json
CHANGED