@@ -650,6 +650,170 @@ export default defineConfig({
650650 ) ;
651651 }
652652
653+ // Step 14: Patch extensionsScannerService (node/) to fetch
654+ // extensions from Mountain via IPC instead of reading from disk.
655+ // The webview has no filesystem access, so the scanner can't read
656+ // builtinExtensionsPath. Instead, we override scanSystemExtensions
657+ // to call extensions:getAll via TauriMainProcessService.
658+ try {
659+ const ScannerPath = join (
660+ TargetDir ,
661+ "Static/Application/vs/workbench/services/extensions/electron-browser/extensionsScannerService.js" ,
662+ ) ;
663+ await writeFile (
664+ ScannerPath ,
665+ `import { URI } from '../../../../base/common/uri.js';
666+ import { IExtensionsScannerService } from '../../../../platform/extensionManagement/common/extensionsScannerService.js';
667+ import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
668+ import { ILogService } from '../../../../platform/log/common/log.js';
669+ import { Emitter } from '../../../../base/common/event.js';
670+
671+ const _t = (Tag, Detail) => { try { performance.mark('land:exthost:' + Tag, Detail ? { detail: Detail } : undefined); } catch {} };
672+ const _w = (...Args) => { try { console.warn('[Land Scanner]', ...Args); } catch {} };
673+
674+ class ExtensionsScannerService {
675+ constructor(logService) {
676+ this._logService = logService;
677+ this.userExtensionsLocation = URI.file('/extensions');
678+ this._onDidChangeCache = new Emitter();
679+ this.onDidChangeCache = this._onDidChangeCache.event;
680+ _t('scanner:construct');
681+ _w('Constructed');
682+ }
683+
684+ async _fetchFromMountain() {
685+ _t('scanner:fetch:start');
686+ try {
687+ const Invoke = globalThis.__TAURI__?.core?.invoke ?? globalThis.__TAURI__?.invoke;
688+ if (typeof Invoke !== 'function') {
689+ _t('scanner:fetch:no-tauri');
690+ _w('No Tauri invoke available');
691+ return [];
692+ }
693+ const RawResult = await Invoke('MountainIPCInvoke', {
694+ method: 'extensions:getAll',
695+ params: [],
696+ });
697+ const Extensions = Array.isArray(RawResult) ? RawResult : [];
698+ _t('scanner:fetch:result', { count: Extensions.length, type: typeof RawResult, isArray: Array.isArray(RawResult) });
699+ _w('IPC returned', Extensions.length, 'extensions');
700+ if (Extensions.length === 0) return [];
701+
702+ const Mapped = [];
703+ let Errors = 0;
704+ for (let I = 0; I < Extensions.length; I++) {
705+ const ext = Extensions[I];
706+ try {
707+ const location = ext.extensionLocation
708+ ? (typeof ext.extensionLocation === 'string' ? URI.parse(ext.extensionLocation) : URI.revive(ext.extensionLocation))
709+ : URI.file('/extensions/' + (ext.name || 'unknown'));
710+ const id = ext.identifier?.value
711+ || (ext.publisher ? ext.publisher + '.' + ext.name : ext.name)
712+ || 'unknown';
713+ Mapped.push({
714+ type: 0,
715+ identifier: { id },
716+ manifest: {
717+ name: ext.name || '',
718+ publisher: ext.publisher || '',
719+ version: ext.version || '0.0.0',
720+ engines: ext.engines || { vscode: '*' },
721+ main: ext.main || undefined,
722+ browser: ext.browser || undefined,
723+ activationEvents: ext.activationEvents || [],
724+ contributes: ext.contributes || {},
725+ extensionDependencies: [],
726+ extensionPack: [],
727+ enabledApiProposals: [],
728+ },
729+ location,
730+ isBuiltin: true,
731+ targetPlatform: 'undefined',
732+ isValid: true,
733+ validationMessages: [],
734+ });
735+ } catch (e) {
736+ Errors++;
737+ if (Errors <= 3) _w('Map error for ext', I, ':', String(e).slice(0, 100));
738+ }
739+ }
740+ _t('scanner:fetch:mapped', { mapped: Mapped.length, errors: Errors });
741+ _w('Mapped', Mapped.length, 'extensions,', Errors, 'errors');
742+ if (Mapped.length > 0) {
743+ _w('First:', Mapped[0].identifier.id, 'name:', Mapped[0].manifest.name, 'pub:', Mapped[0].manifest.publisher, 'loc:', Mapped[0].location?.toString?.()?.slice(0, 80));
744+ }
745+ return Mapped;
746+ } catch (e) {
747+ _t('scanner:fetch:error', { message: String(e).slice(0, 200) });
748+ _w('Fetch error:', String(e).slice(0, 200));
749+ return [];
750+ }
751+ }
752+
753+ async scanAllExtensions(systemScanOptions, userScanOptions) {
754+ _t('scanner:scanAll:start');
755+ const sys = await this.scanSystemExtensions(systemScanOptions);
756+ const usr = await this.scanUserExtensions(userScanOptions);
757+ const all = [...sys, ...usr];
758+ _t('scanner:scanAll:done', { system: sys.length, user: usr.length, total: all.length });
759+ _w('scanAll:', sys.length, 'system +', usr.length, 'user =', all.length);
760+ return all;
761+ }
762+
763+ async scanSystemExtensions(scanOptions) {
764+ _t('scanner:scanSystem:start');
765+ const result = await this._fetchFromMountain();
766+ _t('scanner:scanSystem:done', { count: result.length });
767+ _w('scanSystemExtensions returning', result.length);
768+ return result;
769+ }
770+
771+ async scanUserExtensions(scanOptions) {
772+ _t('scanner:scanUser:start');
773+ _w('scanUserExtensions returning 0');
774+ return [];
775+ }
776+
777+ getTargetPlatform() { return Promise.resolve('undefined'); }
778+ getProductVersion() { return { version: '0.0.1', date: undefined }; }
779+ async scanAllUserExtensions(scanOptions) { return []; }
780+ async scanExtensionsUnderDevelopment(existingExtensions, scanOptions) { _t('scanner:scanDev'); return []; }
781+ async scanExistingExtension(extensionLocation, extensionType, scanOptions) { return null; }
782+ async scanOneOrMultipleExtensions(extensionLocation, extensionType, scanOptions) { return []; }
783+ async scanMetadata(extensionLocation) { return undefined; }
784+ async updateMetadata(extensionLocation, metadata) { return undefined; }
785+ async initializeDefaultProfileExtensions() { _t('scanner:initDefaults'); }
786+ }
787+
788+ // DI decorators must be defined before use
789+ var __decorate = function(decorators, target, key, desc) {
790+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
791+ if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') r = Reflect.decorate(decorators, target, key, desc);
792+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
793+ return c > 3 && r && Object.defineProperty(target, key, r), r;
794+ };
795+ var __param = function(paramIndex, decorator) {
796+ return function(target, key) { decorator(target, key, paramIndex); };
797+ };
798+ ExtensionsScannerService = __decorate([
799+ __param(0, ILogService)
800+ ], ExtensionsScannerService);
801+
802+ registerSingleton(IExtensionsScannerService, ExtensionsScannerService, InstantiationType.Delayed);
803+ export { ExtensionsScannerService, IExtensionsScannerService };
804+ ` ,
805+ "utf-8" ,
806+ ) ;
807+ console . log (
808+ "[CopyVSCode] Step 14: Patched extensionsScannerService (IPC override)" ,
809+ ) ;
810+ } catch ( Error ) {
811+ console . warn (
812+ "[CopyVSCode] Step 14: extensionsScannerService patch failed:" ,
813+ Error ,
814+ ) ;
815+ }
816+
653817 StepMark ( "done" ) ;
654818 console . log ( "[CopyVSCode] ✓ Assets ready in Target/" ) ;
655819
0 commit comments