|
50 | 50 | } |
51 | 51 |
|
52 | 52 | const zcodeCoreExtensions = [ |
53 | | - { path: '/extensions/zcode-welcome' }, |
54 | 53 | { path: '/extensions/zcode-browser-fs' }, |
55 | 54 | { path: '/extensions/zcode-git' }, |
56 | 55 | { path: '/extensions/zcode-diagnostics' }, |
@@ -94,8 +93,8 @@ const defaultProduct = { |
94 | 93 | configurationDefaults: { |
95 | 94 | 'security.workspace.trust.enabled': false, |
96 | 95 | 'security.workspace.trust.startupPrompt': 'never', |
97 | | - // zcode-welcome owns the startup surface; do not open VS Code's Getting Started page. |
98 | | - 'workbench.startupEditor': 'none', |
| 96 | + // The built-in Welcome page renders reliably on CDN-hosted VS Code Web. |
| 97 | + 'workbench.startupEditor': 'welcomePage', |
99 | 98 | ...themeConfigurationDefaults, |
100 | 99 | 'files.exclude': { |
101 | 100 | '**/.git': true, |
@@ -506,6 +505,71 @@ const bootstrap = `/* ZCode workbench bootstrap — load VS Code Web + inject ex |
506 | 505 | } catch (_) { /* ignore */ } |
507 | 506 |
|
508 | 507 | window.product = withHostAuthority(window.product || {}); |
| 508 | + // The extension host does not inherit the workbench page's URL fragment. |
| 509 | + // Pass a safe public repository URL through transient product defaults so |
| 510 | + // zcode-git can consume hash repository links deterministically. |
| 511 | + let startupRepository = ''; |
| 512 | + try { |
| 513 | + const raw = (location.hash || '').slice(1).trim(); |
| 514 | + if (/^https?:\\/\\//i.test(raw)) { |
| 515 | + const repo = new URL(decodeURIComponent(raw)); |
| 516 | + if ( |
| 517 | + (repo.protocol === 'http:' || repo.protocol === 'https:') && |
| 518 | + repo.hostname && |
| 519 | + repo.pathname !== '/' && |
| 520 | + !repo.username && |
| 521 | + !repo.password && |
| 522 | + !repo.search && |
| 523 | + !repo.hash |
| 524 | + ) { |
| 525 | + startupRepository = repo.toString().replace(/#$/, ''); |
| 526 | + history.replaceState(null, '', location.pathname + location.search); |
| 527 | + } |
| 528 | + } |
| 529 | + } catch (_) { /* malformed fragments stay inert */ } |
| 530 | + if (startupRepository) { |
| 531 | + if (window.product.folderUri?.scheme === 'zcode-opfs') { |
| 532 | + const startupBytes = Array.from(new TextEncoder().encode(startupRepository), (byte) => |
| 533 | + String.fromCharCode(byte), |
| 534 | + ).join(''); |
| 535 | + const startupToken = btoa(startupBytes).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, ''); |
| 536 | + window.product.folderUri = { |
| 537 | + ...window.product.folderUri, |
| 538 | + path: '/workspace/__zcode_repo__' + startupToken, |
| 539 | + query: 'zcodeRepository=' + encodeURIComponent(startupRepository), |
| 540 | + }; |
| 541 | + } |
| 542 | + try { |
| 543 | + sessionStorage.setItem('zcode.startupRepository', startupRepository); |
| 544 | + } catch (_) { /* private browsing can disable session storage */ } |
| 545 | + try { |
| 546 | + // localStorage is shared with the extension-host iframe; consume/remove |
| 547 | + // this immediately in zcode-git so it remains a one-shot handoff. |
| 548 | + localStorage.setItem('zcode.startupRepository', startupRepository); |
| 549 | + } catch (_) { /* private browsing can disable local storage */ } |
| 550 | + const topDefaults = window.product.configurationDefaults || {}; |
| 551 | + const nestedDefaults = window.product.productConfiguration?.configurationDefaults || {}; |
| 552 | + window.product.configurationDefaults = { |
| 553 | + ...topDefaults, |
| 554 | + 'zcode.startupRepository': startupRepository, |
| 555 | + }; |
| 556 | + if (window.product.productConfiguration) { |
| 557 | + window.product.productConfiguration.configurationDefaults = { |
| 558 | + ...nestedDefaults, |
| 559 | + 'zcode.startupRepository': startupRepository, |
| 560 | + }; |
| 561 | + } |
| 562 | + try { |
| 563 | + if (typeof BroadcastChannel !== 'undefined') { |
| 564 | + const channel = new BroadcastChannel('zcode.startup'); |
| 565 | + const message = { type: 'openRepository', url: startupRepository }; |
| 566 | + [0, 500, 1500, 3000].forEach((delay) => { |
| 567 | + setTimeout(() => channel.postMessage(message), delay); |
| 568 | + }); |
| 569 | + setTimeout(() => channel.close(), 5000); |
| 570 | + } |
| 571 | + } catch (_) { /* extension host can still use product/storage handoff */ } |
| 572 | + } |
509 | 573 | // Walkthrough / markdown webviews must load same-origin (not vscode-cdn.net). |
510 | 574 | // Microsoft’s CDN blocks framing from non-Microsoft origins → “content is blocked”. |
511 | 575 | const webviewEndpointPath = |
@@ -751,7 +815,6 @@ writeFileSync(join(dist, 'bootstrap.js'), bootstrap); |
751 | 815 | const extRoot = join(monorepo, 'extensions'); |
752 | 816 | const extOut = join(dist, 'extensions'); |
753 | 817 | const productExts = [ |
754 | | - 'zcode-welcome', |
755 | 818 | 'zcode-browser-fs', |
756 | 819 | 'zcode-git', |
757 | 820 | 'zcode-diagnostics', |
|
0 commit comments