diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json deleted file mode 100644 index cdad40b8a..000000000 --- a/.agents/plugins/marketplace.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "devfast", - "plugins": [ - { - "name": "whiteboard", - "source": { "source": "local", "path": "./packages/agent-plugins/codex" }, - "policy": { "installation": "AVAILABLE" }, - "category": "Productivity" - } - ] -} diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json deleted file mode 100644 index 99cfaf44d..000000000 --- a/.claude-plugin/marketplace.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "devfast", - "owner": { "name": "dev.fast" }, - "plugins": [ - { - "name": "whiteboard", - "source": "./packages/agent-plugins/claude", - "description": "Connect Claude Code to dev.fast Whiteboard" - } - ] -} diff --git a/.github/workflows/review-cli-release.yml b/.github/workflows/review-cli-release.yml index 80cb386cf..98b37c28c 100644 --- a/.github/workflows/review-cli-release.yml +++ b/.github/workflows/review-cli-release.yml @@ -1,10 +1,10 @@ -name: Whiteboard CLI Release +name: Review CLI Release on: workflow_dispatch: inputs: bump: - description: Next CLI version (calculated from npm releases and whiteboard-v tags) + description: Next CLI version (calculated from npm releases and review-v tags) type: choice required: true default: patch @@ -18,7 +18,7 @@ on: default: false push: tags: - - whiteboard-v* + - review-v* permissions: contents: write @@ -50,27 +50,27 @@ jobs: id: release env: RELEASE_BUMP: ${{ inputs.bump }} - run: node scripts/whiteboard-cli-release.mjs plan + run: node scripts/review-cli-release.mjs plan - name: Check release and headless behavior if: steps.release.outputs.published != 'true' run: | - node --test scripts/whiteboard-cli-release.test.mjs scripts/whiteboard-cli-dependencies.test.mjs + node --test scripts/review-cli-release.test.mjs scripts/review-cli-dependencies.test.mjs pnpm --filter @dev.fast/trace-core test - pnpm --filter @dev.fast/whiteboard ensure:tutorial-assets - pnpm --filter @dev.fast/whiteboard exec vitest run --config vitest.config.ts --project shared-module-graph src/server/headless-host.test.ts src/server/headless-sharing.test.ts src/cli-install.test.ts + pnpm --filter @dev.fast/review ensure:tutorial-assets + pnpm --filter @dev.fast/review exec vitest run --config vitest.config.ts --project shared-module-graph src/server/headless-host.test.ts src/server/headless-sharing.test.ts src/cli-install.test.ts - name: Build release tarball if: steps.release.outputs.published != 'true' - run: node scripts/pack-whiteboard-cli.mjs release-artifacts + run: node scripts/pack-review-cli.mjs release-artifacts - name: Test installed tarball without Desktop if: steps.release.outputs.published != 'true' env: VERSION: ${{ steps.release.outputs.version }} - run: node scripts/smoke-whiteboard-cli.mjs "release-artifacts/dev.fast-whiteboard-${VERSION}.tgz" "$VERSION" + run: node scripts/smoke-review-cli.mjs "release-artifacts/dev.fast-review-${VERSION}.tgz" "$VERSION" - name: Validate npm publish command if: steps.release.outputs.published != 'true' env: VERSION: ${{ steps.release.outputs.version }} - run: npm publish "./release-artifacts/dev.fast-whiteboard-${VERSION}.tgz" --dry-run --registry=https://registry.npmjs.org --access public --tag latest --ignore-scripts + run: npm publish "./release-artifacts/dev.fast-review-${VERSION}.tgz" --dry-run --registry=https://registry.npmjs.org --access public --tag latest --ignore-scripts - name: Retain tested package if: steps.release.outputs.published != 'true' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 @@ -88,13 +88,13 @@ jobs: - name: Reserve release tag if: steps.release.outputs.published != 'true' && !inputs.dry_run # GITHUB_TOKEN tag pushes don't start another workflow. This run publishes below. - run: node scripts/whiteboard-cli-release.mjs tag + run: node scripts/review-cli-release.mjs tag - name: Publish tested package if: steps.release.outputs.published != 'true' && !inputs.dry_run env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} VERSION: ${{ steps.release.outputs.version }} - run: npm publish "./release-artifacts/dev.fast-whiteboard-${VERSION}.tgz" --registry=https://registry.npmjs.org --access public --tag latest --provenance --ignore-scripts + run: npm publish "./release-artifacts/dev.fast-review-${VERSION}.tgz" --registry=https://registry.npmjs.org --access public --tag latest --provenance --ignore-scripts - name: Release summary env: VERSION: ${{ steps.release.outputs.version }} @@ -104,13 +104,13 @@ jobs: DRY_RUN: ${{ inputs.dry_run }} run: | { - echo "### Whiteboard CLI ${VERSION}" + echo "### Review CLI ${VERSION}" echo "Source: ${COMMIT}; tag: ${RELEASE_TAG}" if [ "$DRY_RUN" = true ]; then echo 'Dry run: no tag or npm publication was created. Download the tested tarball from this run.' elif [ "$PUBLISHED" = true ]; then echo 'This exact version and source commit were already published; no changes made.' else - echo "Install: npm install --global @dev.fast/whiteboard@${VERSION}" + echo "Install: npm install --global @dev.fast/review@${VERSION}" fi } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/review-desktop-ci.yml b/.github/workflows/review-desktop-ci.yml index 316add159..a07e48130 100644 --- a/.github/workflows/review-desktop-ci.yml +++ b/.github/workflows/review-desktop-ci.yml @@ -38,7 +38,7 @@ jobs: jq -r ' select(.sourceRepository == "devdotfast/review") | .baseCommit, .sourceCommit - ' packages/whiteboard/src/fixtures/legacy-reviews/*.json | + ' packages/review/src/fixtures/legacy-reviews/*.json | sort -u ) test "${#fixture_commits[@]}" -gt 0 @@ -68,7 +68,7 @@ jobs: - name: Install Playwright Chromium if: steps.playwright-chromium.outputs.cache-hit != 'true' - run: pnpm --filter @dev.fast/whiteboard-canvas exec playwright install chromium --only-shell + run: pnpm --filter @dev.fast/review-canvas exec playwright install chromium --only-shell - name: Save Playwright Chromium if: steps.playwright-chromium.outputs.cache-hit != 'true' @@ -96,14 +96,14 @@ jobs: libx11-dev libxkbfile-dev libkrb5-dev libsecret-1-dev xvfb python3 - name: Install Playwright Chromium system dependencies - run: pnpm --filter @dev.fast/whiteboard-canvas exec playwright install-deps chromium + run: pnpm --filter @dev.fast/review-canvas exec playwright install-deps chromium - name: Setup Code OSS Node uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version-file: apps/whiteboard-desktop/code-oss/.nvmrc + node-version-file: apps/review-desktop/code-oss/.nvmrc cache: npm - cache-dependency-path: apps/whiteboard-desktop/code-oss/**/package-lock.json + cache-dependency-path: apps/review-desktop/code-oss/**/package-lock.json # out/ is deliberately not cached: the build rebuilds it from scratch, so # caching it only adds download/upload time. The nested extension and @@ -118,64 +118,64 @@ jobs: uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules - apps/whiteboard-desktop/code-oss/.build/electron + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/.build/electron ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} restore-keys: | ${{ runner.os }}-code-oss-deps-v2- - name: Build Review Desktop env: GITHUB_TOKEN: ${{ github.token }} - WHITEBOARD_DESKTOP_CI_FAST: "1" - run: pnpm --filter @dev.fast/whiteboard-desktop app:build + REVIEW_DESKTOP_CI_FAST: "1" + run: pnpm --filter @dev.fast/review-desktop app:build - name: Validate Review Desktop build run: | - test -d apps/whiteboard-desktop/code-oss/node_modules - test -f apps/whiteboard-desktop/code-oss/out/main.js + test -d apps/review-desktop/code-oss/node_modules + test -f apps/review-desktop/code-oss/out/main.js - name: Save Code OSS dependencies if: steps.code-oss-deps.outputs.cache-hit != 'true' uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules - apps/whiteboard-desktop/code-oss/.build/electron + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/.build/electron ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} - name: Check the tutorial assets - run: pnpm --filter @dev.fast/whiteboard check:tutorial + run: pnpm --filter @dev.fast/review check:tutorial - name: Check repository quality run: pnpm lint && pnpm format:check && pnpm typecheck && pnpm test - name: Bundled diffr integration - run: pnpm --filter @dev.fast/whiteboard test:integration:diffr + run: pnpm --filter @dev.fast/review test:integration:diffr - name: Configure Electron sandbox run: | - sudo chown root:root apps/whiteboard-desktop/code-oss/.build/electron/chrome-sandbox - sudo chmod 4755 apps/whiteboard-desktop/code-oss/.build/electron/chrome-sandbox + sudo chown root:root apps/review-desktop/code-oss/.build/electron/chrome-sandbox + sudo chmod 4755 apps/review-desktop/code-oss/.build/electron/chrome-sandbox - name: Desktop language services E2E - run: xvfb-run -a pnpm --filter @dev.fast/whiteboard-desktop test:e2e:lsp --keep + run: xvfb-run -a pnpm --filter @dev.fast/review-desktop test:e2e:lsp --keep - name: Upload Desktop language services diagnostics if: always() @@ -196,7 +196,7 @@ jobs: with: name: vitest-browser-diagnostics path: | - packages/whiteboard/app/.vitest-attachments - packages/whiteboard/**/__screenshots__ - packages/whiteboard/**/__traces__ + packages/review/app/.vitest-attachments + packages/review/**/__screenshots__ + packages/review/**/__traces__ if-no-files-found: ignore diff --git a/.github/workflows/review-desktop-preview.yml b/.github/workflows/review-desktop-preview.yml index 953fbb43c..cd0e11c75 100644 --- a/.github/workflows/review-desktop-preview.yml +++ b/.github/workflows/review-desktop-preview.yml @@ -67,7 +67,7 @@ jobs: id: version shell: bash run: | - CURRENT=$(node -p "require('./apps/whiteboard-desktop/package.json').version") + CURRENT=$(node -p "require('./apps/review-desktop/package.json').version") if [[ "$CURRENT" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)([-+].*)?$ ]]; then PATCH="${BASH_REMATCH[3]}" NEXT_PATCH="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.$((PATCH + 1))" @@ -121,7 +121,7 @@ jobs: - name: Stamp preview release channel run: | - node apps/whiteboard-desktop/scripts/stamp-release-channel.mjs \ + node apps/review-desktop/scripts/stamp-release-channel.mjs \ --version "${{ needs.version.outputs.version }}" \ --quality preview @@ -150,25 +150,25 @@ jobs: - name: Setup Code OSS Node uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version-file: apps/whiteboard-desktop/code-oss/.nvmrc + node-version-file: apps/review-desktop/code-oss/.nvmrc cache: npm - cache-dependency-path: apps/whiteboard-desktop/code-oss/**/package-lock.json + cache-dependency-path: apps/review-desktop/code-oss/**/package-lock.json - name: Restore Code OSS dependencies id: code-oss-deps uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} restore-keys: | ${{ runner.os }}-code-oss-deps-v2- @@ -179,14 +179,14 @@ jobs: env: # Embeds the PostHog project key into the review runtime build so # released apps ship telemetry enabled. Source builds embed nothing. - WHITEBOARD_POSTHOG_KEY: ${{ vars.WHITEBOARD_POSTHOG_KEY }} - run: bash apps/whiteboard-desktop/scripts/compile-darwin-payload.sh + REVIEW_POSTHOG_KEY: ${{ vars.REVIEW_POSTHOG_KEY }} + run: bash apps/review-desktop/scripts/compile-darwin-payload.sh - name: Upload darwin payload uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: darwin-payload - path: apps/whiteboard-desktop/dist/darwin-payload.tar.zst + path: apps/review-desktop/dist/darwin-payload.tar.zst retention-days: 3 compression-level: 0 @@ -196,8 +196,8 @@ jobs: uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + apps/review-desktop/code-oss/node_modules + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} lookup-only: true - name: Save Code OSS dependencies @@ -205,16 +205,16 @@ jobs: uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} build: name: Build, sign, publish preview @@ -232,7 +232,7 @@ jobs: - name: Stamp preview release channel run: | - node apps/whiteboard-desktop/scripts/stamp-release-channel.mjs \ + node apps/review-desktop/scripts/stamp-release-channel.mjs \ --version "$RELEASE_VERSION" \ --quality preview @@ -251,26 +251,26 @@ jobs: - name: Setup Code OSS Node uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version-file: apps/whiteboard-desktop/code-oss/.nvmrc + node-version-file: apps/review-desktop/code-oss/.nvmrc cache: npm - cache-dependency-path: apps/whiteboard-desktop/code-oss/**/package-lock.json + cache-dependency-path: apps/review-desktop/code-oss/**/package-lock.json - name: Restore Code OSS dependencies id: code-oss-deps uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules - apps/whiteboard-desktop/code-oss/.build/electron + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/.build/electron ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} restore-keys: | ${{ runner.os }}-code-oss-deps-v2- @@ -334,13 +334,13 @@ jobs: APPLE_API_KEY_ID: ${{ vars.APPLE_API_KEY_ID }} APPLE_API_ISSUER_ID: ${{ vars.APPLE_API_ISSUER_ID }} SKIP_NOTARIZE: ${{ vars.SKIP_NOTARIZE }} - WHITEBOARD_DESKTOP_PRECOMPILED: "1" - WHITEBOARD_APP_ICON_CHANNEL: preview + REVIEW_DESKTOP_PRECOMPILED: "1" + REVIEW_APP_ICON_CHANNEL: preview run: | # The build can run well over an hour before the first codesign call. security unlock-keychain -p "${{ secrets.APPLE_KEYCHAIN_PASSWORD }}" \ "$RUNNER_TEMP/buildagent.keychain" - pnpm --filter @dev.fast/whiteboard-desktop app:package:macos + pnpm --filter @dev.fast/review-desktop app:package:macos - name: Check for existing Code OSS dependency cache if: steps.code-oss-deps.outputs.cache-hit != 'true' @@ -348,8 +348,8 @@ jobs: uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + apps/review-desktop/code-oss/node_modules + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} lookup-only: true - name: Save Code OSS dependencies @@ -357,21 +357,21 @@ jobs: uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules - apps/whiteboard-desktop/code-oss/.build/electron + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/.build/electron ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} - name: Validate release artifacts run: | - node apps/whiteboard-desktop/scripts/validate-release-artifacts.mjs \ + node apps/review-desktop/scripts/validate-release-artifacts.mjs \ --version "$RELEASE_VERSION" \ --commit "$RELEASE_COMMIT" \ --channel preview @@ -379,7 +379,7 @@ jobs: # Signed and stapled says nothing about whether the app runs. Launch it # and require a renderer before anything reaches R2. - name: Smoke launch the packaged app - run: node apps/whiteboard-desktop/scripts/smoke-launch-packaged.mjs + run: node apps/review-desktop/scripts/smoke-launch-packaged.mjs # Payloads first, manifest last: a client must never see a latest.json # whose zip is not yet downloadable. @@ -392,25 +392,21 @@ jobs: AWS_REGION: auto R2_BUCKET: ${{ vars.R2_RELEASE_BUCKET }} run: | - DIST=apps/whiteboard-desktop/dist + DIST=apps/review-desktop/dist RELEASE_PREFIX="s3://${R2_BUCKET}/releases/${RELEASE_VERSION}/darwin-arm64" - DMG_DISPOSITION="attachment; filename=\"df-whiteboard-preview-${RELEASE_VERSION}.dmg\"" + DMG_DISPOSITION="attachment; filename=\"df-review-preview-${RELEASE_VERSION}.dmg\"" - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \ - "${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \ + aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.zip" \ + "${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.zip" \ --content-type application/zip - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ - "${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ + aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \ + "${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \ --content-type application/x-apple-diskimage \ --content-disposition "$DMG_DISPOSITION" - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ + aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \ "s3://${R2_BUCKET}/releases/preview-latest/darwin-arm64/Review.dmg" \ --content-type application/x-apple-diskimage \ --content-disposition "$DMG_DISPOSITION" - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ - "s3://${R2_BUCKET}/releases/preview-latest/darwin-arm64/Whiteboard.dmg" \ - --content-type application/x-apple-diskimage \ - --content-disposition "$DMG_DISPOSITION" aws s3 cp "$DIST/latest.json" \ "s3://${R2_BUCKET}/update/preview/darwin-arm64/latest.json" \ @@ -436,11 +432,7 @@ jobs: echo "install.dev.fast/preview (expect 302 to the preview disk image):" LOCATION=$(curl -s -o /dev/null -w "%{redirect_url}" https://install.dev.fast/preview) echo "$LOCATION" - # The landing worker can deploy before or after this release. - case "$LOCATION" in - "https://install.dev.fast/releases/preview-latest/darwin-arm64/Review.dmg"|"https://install.dev.fast/releases/preview-latest/darwin-arm64/Whiteboard.dmg") ;; - *) echo "Unexpected install redirect: $LOCATION" >&2; exit 1 ;; - esac + test "$LOCATION" = "https://install.dev.fast/releases/preview-latest/darwin-arm64/Review.dmg" echo "Following it (expect 200 and a disk image):" curl -sfL -o /dev/null -w "%{http_code} %{content_type}\n" https://install.dev.fast/preview \ @@ -450,7 +442,7 @@ jobs: uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: review-desktop-preview-${{ env.RELEASE_VERSION }}-dmg - path: apps/whiteboard-desktop/dist/Whiteboard-darwin-arm64-${{ env.RELEASE_VERSION }}.dmg + path: apps/review-desktop/dist/Review-darwin-arm64-${{ env.RELEASE_VERSION }}.dmg retention-days: 3 compression-level: 0 @@ -484,7 +476,7 @@ jobs: run: | mkdir linux-repository tar --zstd -xf linux-packages/linux-publication.tar.zst -C linux-repository - python3 apps/whiteboard-desktop/scripts/publish-linux-repository.py --directory linux-repository --bucket "$R2_BUCKET" --channel preview + python3 apps/review-desktop/scripts/publish-linux-repository.py --directory linux-repository --bucket "$R2_BUCKET" --channel preview - name: Check the preview channel is served env: RELEASE_VERSION: ${{ needs.version.outputs.version }} diff --git a/.github/workflows/review-desktop-release.yml b/.github/workflows/review-desktop-release.yml index b26f0ea0b..f72f10767 100644 --- a/.github/workflows/review-desktop-release.yml +++ b/.github/workflows/review-desktop-release.yml @@ -100,12 +100,12 @@ jobs: exit 1 fi - CURRENT=$(node -p "require('./apps/whiteboard-desktop/package.json').version") + CURRENT=$(node -p "require('./apps/review-desktop/package.json').version") # The pattern must stay an unquoted variable: bash matches a quoted # right-hand side as a literal string, not as a regex. version_re='^([0-9]+)\.([0-9]+)\.([0-9]+)$' if [[ ! $CURRENT =~ $version_re ]]; then - echo "::error::apps/whiteboard-desktop/package.json is at '${CURRENT}', which is not X.Y.Z. ${GITHUB_REF_NAME} must never carry a prerelease version." + echo "::error::apps/review-desktop/package.json is at '${CURRENT}', which is not X.Y.Z. ${GITHUB_REF_NAME} must never carry a prerelease version." exit 1 fi MAJOR="${BASH_REMATCH[1]}" @@ -169,9 +169,9 @@ jobs: exit 1 fi - echo "Promoting ${PREVIEW_TAG} (${PREVIEW_COMMIT}) to Whiteboard ${TAG}." + echo "Promoting ${PREVIEW_TAG} (${PREVIEW_COMMIT}) to Review Desktop ${TAG}." else - echo "Releasing Whiteboard ${TAG} from ${GITHUB_REF_NAME}." + echo "Releasing Review Desktop ${TAG} from ${GITHUB_REF_NAME}." fi # Remote write-state, checked only where a push actually follows. Both @@ -206,13 +206,13 @@ jobs: # product.json carries the same number to the running app, which shows # it in the About panel, alongside the stable channel identity. # `scripts/product-hardening.test.mjs` fails if these drift apart. - node apps/whiteboard-desktop/scripts/stamp-release-channel.mjs \ + node apps/review-desktop/scripts/stamp-release-channel.mjs \ --version "$VERSION" \ --quality stable git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add apps/whiteboard-desktop/package.json apps/whiteboard-desktop/code-oss/product.json + git add apps/review-desktop/package.json apps/review-desktop/code-oss/product.json git commit -m "chore(review-desktop): bump version to ${VERSION} [skip ci]" # The tag marks what shipped, which for a promotion is the commit the @@ -246,7 +246,7 @@ jobs: else # Nothing stamps a release-from-main dry run, so the artifacts carry # the version already committed here. - VERSION=$(node -p "require('./apps/whiteboard-desktop/package.json').version") + VERSION=$(node -p "require('./apps/review-desktop/package.json').version") fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "commit=${PREVIEW_COMMIT:-$(git rev-parse HEAD)}" >> "$GITHUB_OUTPUT" @@ -258,7 +258,7 @@ jobs: run: | gh release create "${{ steps.bump.outputs.tag }}" \ --repo "${{ github.repository }}" \ - --title "Whiteboard ${{ steps.bump.outputs.version }}" \ + --title "Review Desktop ${{ steps.bump.outputs.version }}" \ --draft \ --generate-notes @@ -280,7 +280,7 @@ jobs: - name: Stamp the promoted version if: ${{ inputs.release_source == 'preview' }} run: | - node apps/whiteboard-desktop/scripts/stamp-release-channel.mjs \ + node apps/review-desktop/scripts/stamp-release-channel.mjs \ --version "${{ needs.tag.outputs.version }}" \ --quality stable @@ -309,25 +309,25 @@ jobs: - name: Setup Code OSS Node uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version-file: apps/whiteboard-desktop/code-oss/.nvmrc + node-version-file: apps/review-desktop/code-oss/.nvmrc cache: npm - cache-dependency-path: apps/whiteboard-desktop/code-oss/**/package-lock.json + cache-dependency-path: apps/review-desktop/code-oss/**/package-lock.json - name: Restore Code OSS dependencies id: code-oss-deps uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} restore-keys: | ${{ runner.os }}-code-oss-deps-v2- @@ -338,14 +338,14 @@ jobs: env: # Embeds the PostHog project key into the review runtime build so # released apps ship telemetry enabled. Source builds embed nothing. - WHITEBOARD_POSTHOG_KEY: ${{ vars.WHITEBOARD_POSTHOG_KEY }} - run: bash apps/whiteboard-desktop/scripts/compile-darwin-payload.sh + REVIEW_POSTHOG_KEY: ${{ vars.REVIEW_POSTHOG_KEY }} + run: bash apps/review-desktop/scripts/compile-darwin-payload.sh - name: Upload darwin payload uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: darwin-payload - path: apps/whiteboard-desktop/dist/darwin-payload.tar.zst + path: apps/review-desktop/dist/darwin-payload.tar.zst retention-days: 3 compression-level: 0 @@ -355,8 +355,8 @@ jobs: uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + apps/review-desktop/code-oss/node_modules + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} lookup-only: true - name: Save Code OSS dependencies @@ -364,16 +364,16 @@ jobs: uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} linux: needs: tag @@ -406,7 +406,7 @@ jobs: - name: Stamp the promoted version if: ${{ inputs.release_source == 'preview' }} run: | - node apps/whiteboard-desktop/scripts/stamp-release-channel.mjs \ + node apps/review-desktop/scripts/stamp-release-channel.mjs \ --version "${{ needs.tag.outputs.version }}" \ --quality stable @@ -425,26 +425,26 @@ jobs: - name: Setup Code OSS Node uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version-file: apps/whiteboard-desktop/code-oss/.nvmrc + node-version-file: apps/review-desktop/code-oss/.nvmrc cache: npm - cache-dependency-path: apps/whiteboard-desktop/code-oss/**/package-lock.json + cache-dependency-path: apps/review-desktop/code-oss/**/package-lock.json - name: Restore Code OSS dependencies id: code-oss-deps uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules - apps/whiteboard-desktop/code-oss/.build/electron + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/.build/electron ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} restore-keys: | ${{ runner.os }}-code-oss-deps-v2- @@ -507,12 +507,12 @@ jobs: APPLE_API_KEY_ID: ${{ vars.APPLE_API_KEY_ID }} APPLE_API_ISSUER_ID: ${{ vars.APPLE_API_ISSUER_ID }} SKIP_NOTARIZE: ${{ vars.SKIP_NOTARIZE }} - WHITEBOARD_DESKTOP_PRECOMPILED: "1" + REVIEW_DESKTOP_PRECOMPILED: "1" run: | # The build can run well over an hour before the first codesign call. security unlock-keychain -p "${{ secrets.APPLE_KEYCHAIN_PASSWORD }}" \ "$RUNNER_TEMP/buildagent.keychain" - pnpm --filter @dev.fast/whiteboard-desktop app:package:macos + pnpm --filter @dev.fast/review-desktop app:package:macos - name: Check for existing Code OSS dependency cache if: steps.code-oss-deps.outputs.cache-hit != 'true' @@ -520,8 +520,8 @@ jobs: uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + apps/review-desktop/code-oss/node_modules + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} lookup-only: true - name: Save Code OSS dependencies @@ -529,21 +529,21 @@ jobs: uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: | - apps/whiteboard-desktop/code-oss/node_modules - apps/whiteboard-desktop/code-oss/build/node_modules - apps/whiteboard-desktop/code-oss/extensions/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/node_modules - apps/whiteboard-desktop/code-oss/extensions/*/server/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/node_modules - apps/whiteboard-desktop/code-oss/.build/distro/npm/remote/web/node_modules - apps/whiteboard-desktop/code-oss/.build/electron + apps/review-desktop/code-oss/node_modules + apps/review-desktop/code-oss/build/node_modules + apps/review-desktop/code-oss/extensions/node_modules + apps/review-desktop/code-oss/extensions/*/node_modules + apps/review-desktop/code-oss/extensions/*/server/node_modules + apps/review-desktop/code-oss/.build/distro/npm/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/node_modules + apps/review-desktop/code-oss/.build/distro/npm/remote/web/node_modules + apps/review-desktop/code-oss/.build/electron ~/.cache/node-gyp - key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/whiteboard-desktop/code-oss/**/package-lock.json') }} + key: ${{ runner.os }}-code-oss-deps-v2-${{ hashFiles('apps/review-desktop/code-oss/**/package-lock.json') }} - name: Validate release artifacts run: | - node apps/whiteboard-desktop/scripts/validate-release-artifacts.mjs \ + node apps/review-desktop/scripts/validate-release-artifacts.mjs \ --version "$RELEASE_VERSION" \ --commit "$RELEASE_COMMIT" @@ -552,7 +552,7 @@ jobs: # main process that threw before creating a window — both passed every check # above. Launch it and require a renderer before anything reaches R2. - name: Smoke launch the packaged app - run: node apps/whiteboard-desktop/scripts/smoke-launch-packaged.mjs + run: node apps/review-desktop/scripts/smoke-launch-packaged.mjs # Payloads first, manifest last: a client must never see a latest.json # whose zip is not yet downloadable. @@ -565,27 +565,23 @@ jobs: AWS_REGION: auto R2_BUCKET: ${{ vars.R2_RELEASE_BUCKET }} run: | - DIST=apps/whiteboard-desktop/dist + DIST=apps/review-desktop/dist RELEASE_PREFIX="s3://${R2_BUCKET}/releases/${RELEASE_VERSION}/darwin-arm64" # The releases/latest/ key is version-free by design, so the version # rides along in the filename a client saves the download as. - DMG_DISPOSITION="attachment; filename=\"df-whiteboard-${RELEASE_VERSION}.dmg\"" + DMG_DISPOSITION="attachment; filename=\"df-review-${RELEASE_VERSION}.dmg\"" - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \ - "${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \ + aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.zip" \ + "${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.zip" \ --content-type application/zip - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ - "${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ + aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \ + "${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \ --content-type application/x-apple-diskimage \ --content-disposition "$DMG_DISPOSITION" - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ + aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \ "s3://${R2_BUCKET}/releases/latest/darwin-arm64/Review.dmg" \ --content-type application/x-apple-diskimage \ --content-disposition "$DMG_DISPOSITION" - aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \ - "s3://${R2_BUCKET}/releases/latest/darwin-arm64/Whiteboard.dmg" \ - --content-type application/x-apple-diskimage \ - --content-disposition "$DMG_DISPOSITION" aws s3 cp "$DIST/latest.json" \ "s3://${R2_BUCKET}/update/stable/darwin-arm64/latest.json" \ @@ -611,11 +607,7 @@ jobs: echo "install.dev.fast (expect 302 to the disk image):" LOCATION=$(curl -s -o /dev/null -w "%{redirect_url}" https://install.dev.fast/) echo "$LOCATION" - # The landing worker can deploy before or after this release. - case "$LOCATION" in - "https://install.dev.fast/releases/latest/darwin-arm64/Review.dmg"|"https://install.dev.fast/releases/latest/darwin-arm64/Whiteboard.dmg") ;; - *) echo "Unexpected install redirect: $LOCATION" >&2; exit 1 ;; - esac + test "$LOCATION" = "https://install.dev.fast/releases/latest/darwin-arm64/Review.dmg" echo "Following it (expect 200 and a disk image):" curl -sfL -o /dev/null -w "%{http_code} %{content_type}\n" https://install.dev.fast/ \ @@ -628,7 +620,7 @@ jobs: run: | gh release upload "$RELEASE_TAG" \ --repo "${{ github.repository }}" \ - "apps/whiteboard-desktop/dist/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" + "apps/review-desktop/dist/Review-darwin-arm64-${RELEASE_VERSION}.dmg" - name: Remove signing credentials if: always() @@ -660,7 +652,7 @@ jobs: run: | mkdir linux-repository tar --zstd -xf linux-packages/linux-publication.tar.zst -C linux-repository - python3 apps/whiteboard-desktop/scripts/publish-linux-repository.py --directory linux-repository --bucket "$R2_BUCKET" --channel stable + python3 apps/review-desktop/scripts/publish-linux-repository.py --directory linux-repository --bucket "$R2_BUCKET" --channel stable - name: Attach Linux packages env: GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/review-linux-backfill.yml b/.github/workflows/review-linux-backfill.yml index 95ee3e298..2d9a11d6a 100644 --- a/.github/workflows/review-linux-backfill.yml +++ b/.github/workflows/review-linux-backfill.yml @@ -59,7 +59,7 @@ jobs: TAG=$(gh api "repos/$GITHUB_REPOSITORY/releases/latest" --jq .tag_name) [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] VERSION=${TAG#v} - CURRENT=$(node -p "require('./apps/whiteboard-desktop/package.json').version") + CURRENT=$(node -p "require('./apps/review-desktop/package.json').version") if [ "$CURRENT" != "$VERSION" ]; then echo '::error::Main no longer matches the published stable version. Use the normal release workflow.' exit 1 @@ -112,7 +112,7 @@ jobs: run: | mkdir linux-repository tar --zstd -xf linux-packages/linux-publication.tar.zst -C linux-repository - python3 apps/whiteboard-desktop/scripts/publish-linux-repository.py --directory linux-repository --bucket "$R2_BUCKET" + python3 apps/review-desktop/scripts/publish-linux-repository.py --directory linux-repository --bucket "$R2_BUCKET" curl -fsS https://install.dev.fast/linux >/dev/null curl -fsS https://install.dev.fast/repos/dev-fast-review.repo >/dev/null - name: Attach RPM to the existing release diff --git a/.github/workflows/review-linux-build.yml b/.github/workflows/review-linux-build.yml index fcf98b674..31a78c945 100644 --- a/.github/workflows/review-linux-build.yml +++ b/.github/workflows/review-linux-build.yml @@ -29,7 +29,7 @@ jobs: BUILD_SOURCEVERSION: ${{ inputs.commit }} REVIEW_LINUX_PACKAGE_REVISION: ${{ inputs.package_revision }} GNUPGHOME: ${{ github.workspace }}/.linux-signing - WHITEBOARD_SIGNING_PASSPHRASE_FILE: ${{ github.workspace }}/.linux-signing/passphrase + REVIEW_SIGNING_PASSPHRASE_FILE: ${{ github.workspace }}/.linux-signing/passphrase steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 with: @@ -41,15 +41,15 @@ jobs: run: | QUALITY=stable if [[ "$VERSION" == *-preview.* ]]; then QUALITY=preview; fi - node apps/whiteboard-desktop/scripts/stamp-release-channel.mjs --version "$VERSION" --quality "$QUALITY" + node apps/review-desktop/scripts/stamp-release-channel.mjs --version "$VERSION" --quality "$QUALITY" - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 with: - node-version-file: apps/whiteboard-desktop/code-oss/.nvmrc + node-version-file: apps/review-desktop/code-oss/.nvmrc cache: pnpm - run: pnpm install --frozen-lockfile - name: Test publication failure boundaries - run: python3 apps/whiteboard-desktop/scripts/linux/test-publication.py + run: python3 apps/review-desktop/scripts/linux/test-publication.py - name: Install native build and package tools run: | sudo apt-get update @@ -62,23 +62,23 @@ jobs: - name: Build and assemble Linux app env: GITHUB_TOKEN: ${{ github.token }} - WHITEBOARD_DESKTOP_CI_FAST: "1" + REVIEW_DESKTOP_CI_FAST: "1" # Only stamped releases ship the telemetry key. - WHITEBOARD_POSTHOG_KEY: ${{ inputs.version != '' && vars.WHITEBOARD_POSTHOG_KEY || '' }} + REVIEW_POSTHOG_KEY: ${{ inputs.version != '' && vars.REVIEW_POSTHOG_KEY || '' }} run: | pnpm desktop:build pnpm desktop:package:linux - name: Configure packaged Electron sandbox run: | - sudo chown root:root apps/whiteboard-desktop/VSCode-linux-x64/chrome-sandbox - sudo chmod 4755 apps/whiteboard-desktop/VSCode-linux-x64/chrome-sandbox + sudo chown root:root apps/review-desktop/VSCode-linux-x64/chrome-sandbox + sudo chmod 4755 apps/review-desktop/VSCode-linux-x64/chrome-sandbox - name: Smoke test the packaged app - run: xvfb-run -a node apps/whiteboard-desktop/scripts/smoke-launch-packaged.mjs --app apps/whiteboard-desktop/VSCode-linux-x64 + run: xvfb-run -a node apps/review-desktop/scripts/smoke-launch-packaged.mjs --app apps/review-desktop/VSCode-linux-x64 # Preview versions build the dev-fast-review-preview package; see # code-oss/build/linux/review-package.ts for the channel mapping. - name: Create Fedora RPM run: | - pnpm --filter @dev.fast/whiteboard-desktop app:package:linux:distributions + pnpm --filter @dev.fast/review-desktop app:package:linux:distributions - name: Prepare repository signing key id: signing env: @@ -89,7 +89,7 @@ jobs: run: | install -d -m 0700 "$GNUPGHOME" umask 077 - printf '%s' "$SIGNING_PASSPHRASE" > "$WHITEBOARD_SIGNING_PASSPHRASE_FILE" + printf '%s' "$SIGNING_PASSPHRASE" > "$REVIEW_SIGNING_PASSPHRASE_FILE" if [ "$RELEASE_SIGNING" = true ]; then test -n "$SIGNING_KEY" [[ "$SIGNING_FINGERPRINT" =~ ^[A-F0-9]{40}$ ]] @@ -105,23 +105,23 @@ jobs: CHANNEL: ${{ contains(inputs.version, '-preview.') && 'preview' || 'stable' }} run: | # The RPM version is the tilde form of a preview version. - VERSION=$(node -p "require('./apps/whiteboard-desktop/package.json').version.replace('-preview.', '~preview.')") - python3 apps/whiteboard-desktop/scripts/build-linux-repository.py \ - --packages apps/whiteboard-desktop/dist/linux \ - --output apps/whiteboard-desktop/dist/linux-repository \ + VERSION=$(node -p "require('./apps/review-desktop/package.json').version.replace('-preview.', '~preview.')") + python3 apps/review-desktop/scripts/build-linux-repository.py \ + --packages apps/review-desktop/dist/linux \ + --output apps/review-desktop/dist/linux-repository \ --version "$VERSION" --revision "$REVIEW_LINUX_PACKAGE_REVISION" \ --commit "$BUILD_SOURCEVERSION" --fingerprint "$FINGERPRINT" --channel "$CHANNEL" - find apps/whiteboard-desktop/dist/linux-repository -name '*.rpm' -exec cp {} apps/whiteboard-desktop/dist/linux/ \; - tar --zstd -cf apps/whiteboard-desktop/dist/linux/linux-publication.tar.zst -C apps/whiteboard-desktop/dist/linux-repository . + find apps/review-desktop/dist/linux-repository -name '*.rpm' -exec cp {} apps/review-desktop/dist/linux/ \; + tar --zstd -cf apps/review-desktop/dist/linux/linux-publication.tar.zst -C apps/review-desktop/dist/linux-repository . - name: Validate clean installs and rejected signatures - run: bash apps/whiteboard-desktop/scripts/linux/verify-repository.sh apps/whiteboard-desktop/dist/linux-repository + run: bash apps/review-desktop/scripts/linux/verify-repository.sh apps/review-desktop/dist/linux-repository - name: Upload Linux artifacts uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: linux-packages path: | - apps/whiteboard-desktop/dist/linux/*.rpm - apps/whiteboard-desktop/dist/linux/*.tar.zst + apps/review-desktop/dist/linux/*.rpm + apps/review-desktop/dist/linux/*.tar.zst retention-days: 7 compression-level: 0 - name: Remove signing credentials diff --git a/.gitignore b/.gitignore index 0edd0a1fe..9d7e91909 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ # Node node_modules/ dist/ -packages/whiteboard/tutorial/.bundle/ -packages/whiteboard/tutorial/git-stub/ +packages/review/tutorial/.bundle/ +packages/review/tutorial/git-stub/ *.tsbuildinfo # pnpm @@ -31,10 +31,10 @@ Thumbs.db **/.wrangler/ apps/ci/.wrangler-jaeger.jsonc .dev-fast/ -apps/whiteboard-desktop/.node/ -apps/whiteboard-desktop/VSCode-darwin-arm64/ -apps/whiteboard-desktop/VSCode-linux-*/ -apps/whiteboard-desktop/*.dmg +apps/review-desktop/.node/ +apps/review-desktop/VSCode-darwin-arm64/ +apps/review-desktop/VSCode-linux-*/ +apps/review-desktop/*.dmg # Logs *.log @@ -61,11 +61,11 @@ packages/code-graph/canvas/public/snapshot*.json packages/code-graph/.ci-tools/ packages/code-graph/fixtures/indexing/rust/target/ packages/code-graph/fixtures/semantic-baseline/rust/target/ -packages/whiteboard/.playwright-cli/ -packages/whiteboard/.vitest-attachments/ -packages/whiteboard/app/.vitest-attachments/ -packages/whiteboard/**/__screenshots__/ -packages/whiteboard/**/__traces__/ +packages/review/.playwright-cli/ +packages/review/.vitest-attachments/ +packages/review/app/.vitest-attachments/ +packages/review/**/__screenshots__/ +packages/review/**/__traces__/ .playwright-mcp backups/ @@ -91,5 +91,5 @@ backend.hcl artifacts/devbox/ scripts/acceptance/evidence/ -packages/whiteboard/tutorial/pins.json -packages/whiteboard/bin/ +packages/review/tutorial/pins.json +packages/review/bin/ diff --git a/.oxfmtrc.json b/.oxfmtrc.json index c7e023428..4895799d1 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -23,7 +23,7 @@ "**/dist/**", "**/.claude/**", "**/.vite/**", - "apps/whiteboard-desktop/code-oss/**", + "apps/review-desktop/code-oss/**", ".agent/**", ".agents/**", ".claude/**", diff --git a/.oxlintrc.json b/.oxlintrc.json index d5268fc4b..542ec2197 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -23,7 +23,7 @@ "dist/**", "**/dist/**", "**/.vite/**", - "apps/whiteboard-desktop/code-oss/**", + "apps/review-desktop/code-oss/**", ".agent/**", ".agents/**", ".claude/**", @@ -120,8 +120,8 @@ "no-restricted-imports": [ "error", { - "paths": ["@dev.fast/whiteboard"], - "patterns": ["@dev.fast/whiteboard/*", "**/review/**"] + "paths": ["@dev.fast/review"], + "patterns": ["@dev.fast/review/*", "**/review/**"] } ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d4956587..e5df20628 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,17 +1,17 @@ -# Contributing to Whiteboard +# Contributing to Review Desktop -Thank you for your interest in Whiteboard. +Thank you for your interest in Review Desktop. ## Repository layout -- `apps/whiteboard-desktop/` contains the application, packaging scripts, and the +- `apps/review-desktop/` contains the application, packaging scripts, and the pinned Code - OSS fork. -- `packages/whiteboard/` contains the Whiteboard command-line interface, +- `packages/review/` contains the Review command-line interface, embedded server, and canvas. -- `packages/whiteboard-protocol/` contains the shared process contracts. +- `packages/review-protocol/` contains the shared process contracts. - `packages/local-vcs/` contains local version-control helpers. -See [apps/whiteboard-desktop/UPSTREAM](apps/whiteboard-desktop/UPSTREAM) for the +See [apps/review-desktop/UPSTREAM](apps/review-desktop/UPSTREAM) for the Code - OSS source revision and fork differences. ## Build and test @@ -19,19 +19,19 @@ Code - OSS source revision and fork differences. See the [README](README.md) for setup and build instructions. Run `pnpm run ci` before you submit a pull request. -Whiteboard's DOM-facing tests run in Chromium through Vitest Browser Mode. Install +Review's DOM-facing tests run in Chromium through Vitest Browser Mode. Install the browser once with -`pnpm --filter @dev.fast/whiteboard exec playwright install chromium`, then use -`pnpm --filter @dev.fast/whiteboard test:browser` for a headless run or -`pnpm --filter @dev.fast/whiteboard test:browser:watch` while developing. Pure Node, +`pnpm --filter @dev.fast/review exec playwright install chromium`, then use +`pnpm --filter @dev.fast/review test:browser` for a headless run or +`pnpm --filter @dev.fast/review test:browser:watch` while developing. Pure Node, filesystem, and server tests remain available through -`pnpm --filter @dev.fast/whiteboard test:node`. +`pnpm --filter @dev.fast/review test:node`. -`pnpm --filter @dev.fast/whiteboard test:legacy-corpus` replays a private corpus of -legacy sessions through migration. Point `WHITEBOARD_LEGACY_CORPUS` at a directory whose -children are Whiteboard UUID folders; the script fails if the variable is unset. The +`pnpm --filter @dev.fast/review test:legacy-corpus` replays a private corpus of +legacy Reviews through migration. Point `REVIEW_LEGACY_CORPUS` at a directory whose +children are Review UUID folders; the script fails if the variable is unset. The corpus is copied before it is touched and the originals are re-verified afterwards. -The files under `apps/whiteboard-desktop/code-oss/` include upstream contribution +The files under `apps/review-desktop/code-oss/` include upstream contribution and security documents. Those files apply to Microsoft's VS Code project. -This document and [SECURITY.md](SECURITY.md) apply to Whiteboard. +This document and [SECURITY.md](SECURITY.md) apply to Review Desktop. diff --git a/SECURITY.md b/SECURITY.md index 4d709a89d..32750a837 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,10 +1,10 @@ # Security Policy -Report a suspected Whiteboard vulnerability through this repository's +Report a suspected Review Desktop vulnerability through this repository's private GitHub security advisory form. Do not open a public issue. -Do not report Whiteboard issues to Microsoft. The security document under -`apps/whiteboard-desktop/code-oss/` applies to Microsoft's VS Code project. +Do not report Review Desktop issues to Microsoft. The security document under +`apps/review-desktop/code-oss/` applies to Microsoft's VS Code project. If an issue originates in Code - OSS, report it to Microsoft and to us when it -also affects Whiteboard. +also affects Review Desktop. diff --git a/apps/whiteboard-desktop/CONTRIBUTING.md b/apps/review-desktop/CONTRIBUTING.md similarity index 92% rename from apps/whiteboard-desktop/CONTRIBUTING.md rename to apps/review-desktop/CONTRIBUTING.md index c59839225..74cf0b561 100644 --- a/apps/whiteboard-desktop/CONTRIBUTING.md +++ b/apps/review-desktop/CONTRIBUTING.md @@ -8,7 +8,7 @@ Thank you for your interest in Review Desktop. Do not send fork-tree changes upstream to Microsoft, and do not report Review Desktop issues to the upstream project. See [`UPSTREAM`](UPSTREAM) for provenance and the complete divergence inventory. -- Review-owned workbench code lives in `code-oss/src/vs/whiteboard/`. +- Review-owned workbench code lives in `code-oss/src/vs/review/`. - Build, packaging, and release scripts live in `scripts/`. ## Building diff --git a/apps/whiteboard-desktop/LICENSE b/apps/review-desktop/LICENSE similarity index 100% rename from apps/whiteboard-desktop/LICENSE rename to apps/review-desktop/LICENSE diff --git a/apps/whiteboard-desktop/README.md b/apps/review-desktop/README.md similarity index 100% rename from apps/whiteboard-desktop/README.md rename to apps/review-desktop/README.md diff --git a/apps/whiteboard-desktop/SECURITY.md b/apps/review-desktop/SECURITY.md similarity index 100% rename from apps/whiteboard-desktop/SECURITY.md rename to apps/review-desktop/SECURITY.md diff --git a/apps/whiteboard-desktop/UPSTREAM b/apps/review-desktop/UPSTREAM similarity index 96% rename from apps/whiteboard-desktop/UPSTREAM rename to apps/review-desktop/UPSTREAM index d73b06df7..75cea731e 100644 --- a/apps/whiteboard-desktop/UPSTREAM +++ b/apps/review-desktop/UPSTREAM @@ -88,7 +88,7 @@ CVE-2026-81379 (all high), fixed upstream in - Its enforcement points are the chat fetch-page tool, the browser-view tools, and the agent-host sandbox terminal. Review registers no chat, browser-view, or agent contributions; `IChatWidgetService` is bound to an inert stub in - `src/vs/whiteboard/whiteboard.common.main.ts`. The extension-host `browser` API is + `src/vs/review/review.common.main.ts`. The extension-host `browser` API is gated on the `browser` proposed API, and `product.json` declares no `extensionEnabledApiProposals`. - Upstream rewrote this module after the vendored commit. Its fixes target @@ -157,7 +157,7 @@ for ipynb, mermaid-markdown-features, and notebook-renderers — from - `vscode-api-tests` - `vscode-test-resolver` -To restore one: `git checkout code-oss-upstream-8a7abeba -- apps/whiteboard-desktop/code-oss/extensions/` +To restore one: `git checkout code-oss-upstream-8a7abeba -- apps/review-desktop/code-oss/extensions/` and re-add its lines to the three build files above. In a checkout without that tag (the standalone open-source repository), take the extension from `microsoft/vscode` at the upstream commit recorded above instead. @@ -220,7 +220,7 @@ one of these entries: match their `engines.vscode` range against it, so the release number needs a field of its own. The About panel reads it, the release workflow writes it, and `scripts/product-hardening.test.mjs` fails when it drifts from - `apps/whiteboard-desktop/package.json`. Beyond that: Review product identity, VSCodium-derived telemetry, + `apps/review-desktop/package.json`. Beyond that: Review product identity, VSCodium-derived telemetry, experiment, crash-reporting, edit-statistics, and natural-language-search opt-out defaults; stable updates from `update.dev.fast` rather than Microsoft's update service; no extension gallery; no unused debugger @@ -308,11 +308,11 @@ one of these entries: explicit re-import IPC handler, and record a crash that happens before `startup()` finishes. These are the fork's only additions to the pre-`bootstrapESM()` import graph, so they are held to that window's rules. - The first reaches only `vs/whiteboard/node/whiteboardUserConfigImport.ts`, which reads + The first reaches only `vs/review/node/reviewUserConfigImport.ts`, which reads setting keys from the import-free - `vs/whiteboard/common/whiteboardConfigurationDefaults.ts` and never touches the + `vs/review/common/reviewConfigurationDefaults.ts` and never touches the configuration registry. The second reaches only - `vs/whiteboard/node/whiteboardBootstrapBreadcrumb.ts`, which imports node built-ins + `vs/review/node/reviewBootstrapBreadcrumb.ts`, which imports node built-ins and nothing else; `scripts/main-bootstrap-imports.test.mjs` asserts that. It appends one JSON line under the user-data directory, which the next launch reports through the normal opted-in telemetry path and deletes. See "The @@ -326,9 +326,9 @@ one of these entries: and register the Review connection channel that hands the renderer the server endpoint the main process validated. Also swaps two update- and menu-related registrations, because Review's workbench drives neither surface: - `WhiteboardMenubarMainService` replaces `MenubarMainService` (the stock service + `ReviewMenubarMainService` replaces `MenubarMainService` (the stock service builds its menu from data the renderer never sends, and reinstalls that empty - menu on window focus and count changes), and `WhiteboardUpdateDialog` replaces + menu on window focus and count changes), and `ReviewUpdateDialog` replaces `NotAvailableUpdateDialog` (the stock dialog defers to a workbench `UpdateContribution` that Review does not load). Finally, it does not register `IAgentNetworkFilterService`, @@ -376,7 +376,7 @@ one of these entries: `CannotClose` editors so the menu does not offer a dead action. - `.gitignore`: ignore the curated built-in extension payloads that `scripts/curated-extensions.mjs` materializes under `extensions/`. -- `src/vs/whiteboard/`: Review-owned workbench, protocol, and tests. These files +- `src/vs/review/`: Review-owned workbench, protocol, and tests. These files carry a dev.fast copyright header rather than Microsoft's. - `src/vs/platform/agentHost/` planning documents (deleted): the upstream commit vendored internal phase plans and design notes @@ -395,7 +395,7 @@ one of these entries: From the monorepo root: ```sh -git diff code-oss-upstream-8a7abeba..HEAD -- apps/whiteboard-desktop/code-oss +git diff code-oss-upstream-8a7abeba..HEAD -- apps/review-desktop/code-oss ``` For an upstream refresh, clone the recorded commit into a fresh temporary diff --git a/apps/whiteboard-desktop/code-oss/.agents/skills/launch/SKILL.md b/apps/review-desktop/code-oss/.agents/skills/launch/SKILL.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/.agents/skills/launch/SKILL.md rename to apps/review-desktop/code-oss/.agents/skills/launch/SKILL.md diff --git a/apps/whiteboard-desktop/code-oss/.agents/skills/launch/scripts/launch.sh b/apps/review-desktop/code-oss/.agents/skills/launch/scripts/launch.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/.agents/skills/launch/scripts/launch.sh rename to apps/review-desktop/code-oss/.agents/skills/launch/scripts/launch.sh diff --git a/apps/whiteboard-desktop/code-oss/.agents/skills/launch/scripts/monaco-paste.sh b/apps/review-desktop/code-oss/.agents/skills/launch/scripts/monaco-paste.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/.agents/skills/launch/scripts/monaco-paste.sh rename to apps/review-desktop/code-oss/.agents/skills/launch/scripts/monaco-paste.sh diff --git a/apps/whiteboard-desktop/code-oss/.config/1espt/PipelineAutobaseliningConfig.yml b/apps/review-desktop/code-oss/.config/1espt/PipelineAutobaseliningConfig.yml similarity index 100% rename from apps/whiteboard-desktop/code-oss/.config/1espt/PipelineAutobaseliningConfig.yml rename to apps/review-desktop/code-oss/.config/1espt/PipelineAutobaseliningConfig.yml diff --git a/apps/whiteboard-desktop/code-oss/.config/configuration.winget b/apps/review-desktop/code-oss/.config/configuration.winget similarity index 100% rename from apps/whiteboard-desktop/code-oss/.config/configuration.winget rename to apps/review-desktop/code-oss/.config/configuration.winget diff --git a/apps/whiteboard-desktop/code-oss/.config/guardian/.gdnsuppress b/apps/review-desktop/code-oss/.config/guardian/.gdnsuppress similarity index 100% rename from apps/whiteboard-desktop/code-oss/.config/guardian/.gdnsuppress rename to apps/review-desktop/code-oss/.config/guardian/.gdnsuppress diff --git a/apps/whiteboard-desktop/code-oss/.devcontainer/Dockerfile b/apps/review-desktop/code-oss/.devcontainer/Dockerfile similarity index 100% rename from apps/whiteboard-desktop/code-oss/.devcontainer/Dockerfile rename to apps/review-desktop/code-oss/.devcontainer/Dockerfile diff --git a/apps/whiteboard-desktop/code-oss/.devcontainer/README.md b/apps/review-desktop/code-oss/.devcontainer/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/.devcontainer/README.md rename to apps/review-desktop/code-oss/.devcontainer/README.md diff --git a/apps/whiteboard-desktop/code-oss/.devcontainer/devcontainer-lock.json b/apps/review-desktop/code-oss/.devcontainer/devcontainer-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/.devcontainer/devcontainer-lock.json rename to apps/review-desktop/code-oss/.devcontainer/devcontainer-lock.json diff --git a/apps/whiteboard-desktop/code-oss/.devcontainer/devcontainer.json b/apps/review-desktop/code-oss/.devcontainer/devcontainer.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/.devcontainer/devcontainer.json rename to apps/review-desktop/code-oss/.devcontainer/devcontainer.json diff --git a/apps/whiteboard-desktop/code-oss/.devcontainer/install-vscode.sh b/apps/review-desktop/code-oss/.devcontainer/install-vscode.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/.devcontainer/install-vscode.sh rename to apps/review-desktop/code-oss/.devcontainer/install-vscode.sh diff --git a/apps/whiteboard-desktop/code-oss/.devcontainer/post-create.sh b/apps/review-desktop/code-oss/.devcontainer/post-create.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/.devcontainer/post-create.sh rename to apps/review-desktop/code-oss/.devcontainer/post-create.sh diff --git a/apps/whiteboard-desktop/code-oss/.editorconfig b/apps/review-desktop/code-oss/.editorconfig similarity index 100% rename from apps/whiteboard-desktop/code-oss/.editorconfig rename to apps/review-desktop/code-oss/.editorconfig diff --git a/apps/whiteboard-desktop/code-oss/.eslint-allowed-javascript-files b/apps/review-desktop/code-oss/.eslint-allowed-javascript-files similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-allowed-javascript-files rename to apps/review-desktop/code-oss/.eslint-allowed-javascript-files diff --git a/apps/whiteboard-desktop/code-oss/.eslint-ignore b/apps/review-desktop/code-oss/.eslint-ignore similarity index 98% rename from apps/whiteboard-desktop/code-oss/.eslint-ignore rename to apps/review-desktop/code-oss/.eslint-ignore index 19a7e4287..5b2879d23 100644 --- a/apps/whiteboard-desktop/code-oss/.eslint-ignore +++ b/apps/review-desktop/code-oss/.eslint-ignore @@ -50,7 +50,7 @@ **/src/vs/*/**/*.d.ts **/src/vs/base/test/common/filters.perf.data.js **/src/vs/platform/agentHost/node/codex/protocol/generated/** -**/src/vs/whiteboard/common/whiteboardProtocol.ts +**/src/vs/review/common/reviewProtocol.ts **/test/unit/assert.js **/test/automation/out/** **/typings/** diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/README.md b/apps/review-desktop/code-oss/.eslint-plugin-local/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/README.md rename to apps/review-desktop/code-oss/.eslint-plugin-local/README.md diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-amd-node-module.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-amd-node-module.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-amd-node-module.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-amd-node-module.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-declare-service-brand.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-declare-service-brand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-declare-service-brand.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-declare-service-brand.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-ensure-no-disposables-leak-in-test.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-ensure-no-disposables-leak-in-test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-ensure-no-disposables-leak-in-test.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-ensure-no-disposables-leak-in-test.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-import-patterns.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-import-patterns.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-import-patterns.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-import-patterns.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-layering.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-layering.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-layering.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-layering.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-limited-top-functions.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-limited-top-functions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-limited-top-functions.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-limited-top-functions.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-must-use-result.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-must-use-result.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-must-use-result.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-must-use-result.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-must-use-super-dispose.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-must-use-super-dispose.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-must-use-super-dispose.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-must-use-super-dispose.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-accessor-after-await.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-accessor-after-await.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-accessor-after-await.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-accessor-after-await.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-any-casts.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-any-casts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-any-casts.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-any-casts.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-dangerous-type-assertions.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-dangerous-type-assertions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-dangerous-type-assertions.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-dangerous-type-assertions.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-declare-const-enum.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-declare-const-enum.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-declare-const-enum.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-declare-const-enum.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-deep-import-of-internal.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-deep-import-of-internal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-deep-import-of-internal.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-deep-import-of-internal.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-direct-gulp-import.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-direct-gulp-import.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-direct-gulp-import.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-direct-gulp-import.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-global-document-listener.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-global-document-listener.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-global-document-listener.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-global-document-listener.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-http-import.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-http-import.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-http-import.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-http-import.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-icons-in-localized-strings.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-icons-in-localized-strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-icons-in-localized-strings.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-icons-in-localized-strings.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-in-operator.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-in-operator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-in-operator.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-in-operator.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-localization-template-literals.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-localization-template-literals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-localization-template-literals.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-localization-template-literals.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-localized-model-description.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-localized-model-description.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-localized-model-description.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-localized-model-description.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-new-javascript-files.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-new-javascript-files.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-new-javascript-files.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-new-javascript-files.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-nls-in-standalone-editor.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-nls-in-standalone-editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-nls-in-standalone-editor.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-nls-in-standalone-editor.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-observable-get-in-reactive-context.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-observable-get-in-reactive-context.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-observable-get-in-reactive-context.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-observable-get-in-reactive-context.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-potentially-unsafe-disposables.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-potentially-unsafe-disposables.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-potentially-unsafe-disposables.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-potentially-unsafe-disposables.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-reader-after-await.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-reader-after-await.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-reader-after-await.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-reader-after-await.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-runtime-import.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-runtime-import.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-runtime-import.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-runtime-import.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-standalone-editor.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-standalone-editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-standalone-editor.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-standalone-editor.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-static-node-module-import.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-static-node-module-import.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-static-node-module-import.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-static-node-module-import.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-static-self-ref.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-static-self-ref.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-static-self-ref.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-static-self-ref.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-telemetry-common-property.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-telemetry-common-property.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-telemetry-common-property.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-telemetry-common-property.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-test-async-suite.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-test-async-suite.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-test-async-suite.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-test-async-suite.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-test-only.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-test-only.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-test-only.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-test-only.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-unexternalized-strings.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-unexternalized-strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-unexternalized-strings.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-unexternalized-strings.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-untyped-meta-access.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-untyped-meta-access.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-untyped-meta-access.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-untyped-meta-access.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-unused-expressions.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-no-unused-expressions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-no-unused-expressions.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-no-unused-expressions.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-parameter-properties-must-have-explicit-accessibility.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-parameter-properties-must-have-explicit-accessibility.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-parameter-properties-must-have-explicit-accessibility.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-parameter-properties-must-have-explicit-accessibility.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-policy-localization-key-match.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-policy-localization-key-match.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-policy-localization-key-match.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-policy-localization-key-match.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-translation-remind.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/code-translation-remind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/code-translation-remind.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/code-translation-remind.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/index.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/index.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/index.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/package.json b/apps/review-desktop/code-oss/.eslint-plugin-local/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/package.json rename to apps/review-desktop/code-oss/.eslint-plugin-local/package.json diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/tests/code-no-observable-get-in-reactive-context-test.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/tests/code-no-observable-get-in-reactive-context-test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/tests/code-no-observable-get-in-reactive-context-test.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/tests/code-no-observable-get-in-reactive-context-test.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/tests/code-no-reader-after-await-test.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/tests/code-no-reader-after-await-test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/tests/code-no-reader-after-await-test.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/tests/code-no-reader-after-await-test.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/tsconfig.json b/apps/review-desktop/code-oss/.eslint-plugin-local/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/tsconfig.json rename to apps/review-desktop/code-oss/.eslint-plugin-local/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/utils.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/utils.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-cancellation.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-cancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-cancellation.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-cancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-create-func.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-create-func.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-create-func.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-create-func.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-event-naming.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-event-naming.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-event-naming.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-event-naming.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-interface-naming.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-interface-naming.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-interface-naming.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-interface-naming.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-literal-or-types.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-literal-or-types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-literal-or-types.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-literal-or-types.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-provider-naming.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-provider-naming.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-provider-naming.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-provider-naming.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-string-type-literals.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-string-type-literals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-string-type-literals.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-string-type-literals.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-export.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-export.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-export.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-export.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-thenable.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-thenable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-thenable.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-use-thenable.ts diff --git a/apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-vscode-in-comments.ts b/apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-vscode-in-comments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/.eslint-plugin-local/vscode-dts-vscode-in-comments.ts rename to apps/review-desktop/code-oss/.eslint-plugin-local/vscode-dts-vscode-in-comments.ts diff --git a/apps/whiteboard-desktop/code-oss/.git-blame-ignore-revs b/apps/review-desktop/code-oss/.git-blame-ignore-revs similarity index 100% rename from apps/whiteboard-desktop/code-oss/.git-blame-ignore-revs rename to apps/review-desktop/code-oss/.git-blame-ignore-revs diff --git a/apps/whiteboard-desktop/code-oss/.gitattributes b/apps/review-desktop/code-oss/.gitattributes similarity index 100% rename from apps/whiteboard-desktop/code-oss/.gitattributes rename to apps/review-desktop/code-oss/.gitattributes diff --git a/apps/whiteboard-desktop/code-oss/.gitignore b/apps/review-desktop/code-oss/.gitignore similarity index 83% rename from apps/whiteboard-desktop/code-oss/.gitignore rename to apps/review-desktop/code-oss/.gitignore index 68fc0c4b0..439c46cd0 100644 --- a/apps/whiteboard-desktop/code-oss/.gitignore +++ b/apps/review-desktop/code-oss/.gitignore @@ -52,7 +52,7 @@ dist .github/skills/.local/ # Review curated built-in extensions, materialized by -# apps/whiteboard-desktop/scripts/curated-extensions.mjs from pinned Open VSX VSIXes. +# apps/review-desktop/scripts/curated-extensions.mjs from pinned Open VSX VSIXes. /extensions/vscodevim.vim/ /extensions/tuttieee.emacs-mcx/ /extensions/rust-lang.rust-analyzer/ @@ -65,6 +65,6 @@ dist /extensions/charliermarsh.ruff/ /extensions/golang.go/ -# Review protocol overlay, generated by apps/whiteboard-desktop/scripts/protocol-sync.mjs -# from packages/whiteboard-protocol/src before every build, test, and typecheck. -/src/vs/whiteboard/common/whiteboardProtocol.ts +# Review protocol overlay, generated by apps/review-desktop/scripts/protocol-sync.mjs +# from packages/review-protocol/src before every build, test, and typecheck. +/src/vs/review/common/reviewProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/.lsifrc.json b/apps/review-desktop/code-oss/.lsifrc.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/.lsifrc.json rename to apps/review-desktop/code-oss/.lsifrc.json diff --git a/apps/whiteboard-desktop/code-oss/.mailmap b/apps/review-desktop/code-oss/.mailmap similarity index 100% rename from apps/whiteboard-desktop/code-oss/.mailmap rename to apps/review-desktop/code-oss/.mailmap diff --git a/apps/whiteboard-desktop/code-oss/.mention-bot b/apps/review-desktop/code-oss/.mention-bot similarity index 100% rename from apps/whiteboard-desktop/code-oss/.mention-bot rename to apps/review-desktop/code-oss/.mention-bot diff --git a/apps/whiteboard-desktop/code-oss/.npmrc b/apps/review-desktop/code-oss/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/.npmrc rename to apps/review-desktop/code-oss/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/.nvmrc b/apps/review-desktop/code-oss/.nvmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/.nvmrc rename to apps/review-desktop/code-oss/.nvmrc diff --git a/apps/whiteboard-desktop/code-oss/.vscode-test.js b/apps/review-desktop/code-oss/.vscode-test.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/.vscode-test.js rename to apps/review-desktop/code-oss/.vscode-test.js diff --git a/apps/whiteboard-desktop/code-oss/AGENTS.md b/apps/review-desktop/code-oss/AGENTS.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/AGENTS.md rename to apps/review-desktop/code-oss/AGENTS.md diff --git a/apps/whiteboard-desktop/code-oss/CONTRIBUTING.md b/apps/review-desktop/code-oss/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/CONTRIBUTING.md rename to apps/review-desktop/code-oss/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/CodeQL.yml b/apps/review-desktop/code-oss/CodeQL.yml similarity index 100% rename from apps/whiteboard-desktop/code-oss/CodeQL.yml rename to apps/review-desktop/code-oss/CodeQL.yml diff --git a/apps/whiteboard-desktop/code-oss/LICENSE.txt b/apps/review-desktop/code-oss/LICENSE.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/LICENSE.txt rename to apps/review-desktop/code-oss/LICENSE.txt diff --git a/apps/whiteboard-desktop/code-oss/README.md b/apps/review-desktop/code-oss/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/README.md rename to apps/review-desktop/code-oss/README.md diff --git a/apps/whiteboard-desktop/code-oss/SECURITY.md b/apps/review-desktop/code-oss/SECURITY.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/SECURITY.md rename to apps/review-desktop/code-oss/SECURITY.md diff --git a/apps/whiteboard-desktop/code-oss/ThirdPartyNotices.txt b/apps/review-desktop/code-oss/ThirdPartyNotices.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/ThirdPartyNotices.txt rename to apps/review-desktop/code-oss/ThirdPartyNotices.txt diff --git a/apps/whiteboard-desktop/code-oss/build/.cachesalt b/apps/review-desktop/code-oss/build/.cachesalt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.cachesalt rename to apps/review-desktop/code-oss/build/.cachesalt diff --git a/apps/whiteboard-desktop/code-oss/build/.gitattributes b/apps/review-desktop/code-oss/build/.gitattributes similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.gitattributes rename to apps/review-desktop/code-oss/build/.gitattributes diff --git a/apps/whiteboard-desktop/code-oss/build/.gitignore b/apps/review-desktop/code-oss/build/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.gitignore rename to apps/review-desktop/code-oss/build/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/build/.moduleignore b/apps/review-desktop/code-oss/build/.moduleignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.moduleignore rename to apps/review-desktop/code-oss/build/.moduleignore diff --git a/apps/whiteboard-desktop/code-oss/build/.moduleignore.darwin b/apps/review-desktop/code-oss/build/.moduleignore.darwin similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.moduleignore.darwin rename to apps/review-desktop/code-oss/build/.moduleignore.darwin diff --git a/apps/whiteboard-desktop/code-oss/build/.moduleignore.linux b/apps/review-desktop/code-oss/build/.moduleignore.linux similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.moduleignore.linux rename to apps/review-desktop/code-oss/build/.moduleignore.linux diff --git a/apps/whiteboard-desktop/code-oss/build/.moduleignore.win32 b/apps/review-desktop/code-oss/build/.moduleignore.win32 similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.moduleignore.win32 rename to apps/review-desktop/code-oss/build/.moduleignore.win32 diff --git a/apps/whiteboard-desktop/code-oss/build/.npmrc b/apps/review-desktop/code-oss/build/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.npmrc rename to apps/review-desktop/code-oss/build/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/build/.webignore b/apps/review-desktop/code-oss/build/.webignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/.webignore rename to apps/review-desktop/code-oss/build/.webignore diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/README.md b/apps/review-desktop/code-oss/build/agent-sdk/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/README.md rename to apps/review-desktop/code-oss/build/agent-sdk/README.md diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/claude/package-lock.json b/apps/review-desktop/code-oss/build/agent-sdk/agents/claude/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/claude/package-lock.json rename to apps/review-desktop/code-oss/build/agent-sdk/agents/claude/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/claude/package.json b/apps/review-desktop/code-oss/build/agent-sdk/agents/claude/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/claude/package.json rename to apps/review-desktop/code-oss/build/agent-sdk/agents/claude/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/codex/package-lock.json b/apps/review-desktop/code-oss/build/agent-sdk/agents/codex/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/codex/package-lock.json rename to apps/review-desktop/code-oss/build/agent-sdk/agents/codex/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/codex/package.json b/apps/review-desktop/code-oss/build/agent-sdk/agents/codex/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/agents/codex/package.json rename to apps/review-desktop/code-oss/build/agent-sdk/agents/codex/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/common.ts b/apps/review-desktop/code-oss/build/agent-sdk/common.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/common.ts rename to apps/review-desktop/code-oss/build/agent-sdk/common.ts diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/package.ts b/apps/review-desktop/code-oss/build/agent-sdk/package.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/package.ts rename to apps/review-desktop/code-oss/build/agent-sdk/package.ts diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/produce.ts b/apps/review-desktop/code-oss/build/agent-sdk/produce.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/produce.ts rename to apps/review-desktop/code-oss/build/agent-sdk/produce.ts diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/test/versionSync.test.ts b/apps/review-desktop/code-oss/build/agent-sdk/test/versionSync.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/test/versionSync.test.ts rename to apps/review-desktop/code-oss/build/agent-sdk/test/versionSync.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/agent-sdk/upload.ts b/apps/review-desktop/code-oss/build/agent-sdk/upload.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/agent-sdk/upload.ts rename to apps/review-desktop/code-oss/build/agent-sdk/upload.ts diff --git a/apps/whiteboard-desktop/code-oss/build/buildConfig.ts b/apps/review-desktop/code-oss/build/buildConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/buildConfig.ts rename to apps/review-desktop/code-oss/build/buildConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/build/buildfile.ts b/apps/review-desktop/code-oss/build/buildfile.ts similarity index 95% rename from apps/whiteboard-desktop/code-oss/build/buildfile.ts rename to apps/review-desktop/code-oss/build/buildfile.ts index f69206119..187db4466 100644 --- a/apps/whiteboard-desktop/code-oss/build/buildfile.ts +++ b/apps/review-desktop/code-oss/build/buildfile.ts @@ -26,8 +26,8 @@ export const workbenchDesktop = [ createModuleDescription('vs/platform/agentHost/node/agentHostMain'), createModuleDescription('vs/platform/agentHost/node/diffWorkerMain'), createModuleDescription('vs/workbench/api/node/extensionHostProcess'), - createModuleDescription('vs/whiteboard/whiteboard.desktop.main'), - createModuleDescription('vs/whiteboard/electron-utility/whiteboardDesktopHostMain') + createModuleDescription('vs/review/review.desktop.main'), + createModuleDescription('vs/review/electron-utility/reviewDesktopHostMain') ]; export const keyboardMaps = [ diff --git a/apps/whiteboard-desktop/code-oss/build/builtin/browser-main.js b/apps/review-desktop/code-oss/build/builtin/browser-main.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/builtin/browser-main.js rename to apps/review-desktop/code-oss/build/builtin/browser-main.js diff --git a/apps/whiteboard-desktop/code-oss/build/builtin/index.html b/apps/review-desktop/code-oss/build/builtin/index.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/builtin/index.html rename to apps/review-desktop/code-oss/build/builtin/index.html diff --git a/apps/whiteboard-desktop/code-oss/build/builtin/main.js b/apps/review-desktop/code-oss/build/builtin/main.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/builtin/main.js rename to apps/review-desktop/code-oss/build/builtin/main.js diff --git a/apps/whiteboard-desktop/code-oss/build/builtin/package.json b/apps/review-desktop/code-oss/build/builtin/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/builtin/package.json rename to apps/review-desktop/code-oss/build/builtin/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/checker/layersChecker.ts b/apps/review-desktop/code-oss/build/checker/layersChecker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/layersChecker.ts rename to apps/review-desktop/code-oss/build/checker/layersChecker.ts diff --git a/apps/whiteboard-desktop/code-oss/build/checker/tsconfig.browser.json b/apps/review-desktop/code-oss/build/checker/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/tsconfig.browser.json rename to apps/review-desktop/code-oss/build/checker/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/build/checker/tsconfig.electron-browser.json b/apps/review-desktop/code-oss/build/checker/tsconfig.electron-browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/tsconfig.electron-browser.json rename to apps/review-desktop/code-oss/build/checker/tsconfig.electron-browser.json diff --git a/apps/whiteboard-desktop/code-oss/build/checker/tsconfig.electron-main.json b/apps/review-desktop/code-oss/build/checker/tsconfig.electron-main.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/tsconfig.electron-main.json rename to apps/review-desktop/code-oss/build/checker/tsconfig.electron-main.json diff --git a/apps/whiteboard-desktop/code-oss/build/checker/tsconfig.electron-utility.json b/apps/review-desktop/code-oss/build/checker/tsconfig.electron-utility.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/tsconfig.electron-utility.json rename to apps/review-desktop/code-oss/build/checker/tsconfig.electron-utility.json diff --git a/apps/whiteboard-desktop/code-oss/build/checker/tsconfig.node.json b/apps/review-desktop/code-oss/build/checker/tsconfig.node.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/tsconfig.node.json rename to apps/review-desktop/code-oss/build/checker/tsconfig.node.json diff --git a/apps/whiteboard-desktop/code-oss/build/checker/tsconfig.worker.json b/apps/review-desktop/code-oss/build/checker/tsconfig.worker.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checker/tsconfig.worker.json rename to apps/review-desktop/code-oss/build/checker/tsconfig.worker.json diff --git a/apps/whiteboard-desktop/code-oss/build/checksums/electron.txt b/apps/review-desktop/code-oss/build/checksums/electron.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checksums/electron.txt rename to apps/review-desktop/code-oss/build/checksums/electron.txt diff --git a/apps/whiteboard-desktop/code-oss/build/checksums/explorer-dll.txt b/apps/review-desktop/code-oss/build/checksums/explorer-dll.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checksums/explorer-dll.txt rename to apps/review-desktop/code-oss/build/checksums/explorer-dll.txt diff --git a/apps/whiteboard-desktop/code-oss/build/checksums/nodejs.txt b/apps/review-desktop/code-oss/build/checksums/nodejs.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checksums/nodejs.txt rename to apps/review-desktop/code-oss/build/checksums/nodejs.txt diff --git a/apps/whiteboard-desktop/code-oss/build/checksums/vscode-sysroot.txt b/apps/review-desktop/code-oss/build/checksums/vscode-sysroot.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/checksums/vscode-sysroot.txt rename to apps/review-desktop/code-oss/build/checksums/vscode-sysroot.txt diff --git a/apps/whiteboard-desktop/code-oss/build/codex/check-protocol-sync.ts b/apps/review-desktop/code-oss/build/codex/check-protocol-sync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/codex/check-protocol-sync.ts rename to apps/review-desktop/code-oss/build/codex/check-protocol-sync.ts diff --git a/apps/whiteboard-desktop/code-oss/build/codex/codex-version.txt b/apps/review-desktop/code-oss/build/codex/codex-version.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/codex/codex-version.txt rename to apps/review-desktop/code-oss/build/codex/codex-version.txt diff --git a/apps/whiteboard-desktop/code-oss/build/codex/generate-protocol.d.mts b/apps/review-desktop/code-oss/build/codex/generate-protocol.d.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/codex/generate-protocol.d.mts rename to apps/review-desktop/code-oss/build/codex/generate-protocol.d.mts diff --git a/apps/whiteboard-desktop/code-oss/build/codex/generate-protocol.mjs b/apps/review-desktop/code-oss/build/codex/generate-protocol.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/codex/generate-protocol.mjs rename to apps/review-desktop/code-oss/build/codex/generate-protocol.mjs diff --git a/apps/whiteboard-desktop/code-oss/build/codex/test/checkProtocolSync.test.ts b/apps/review-desktop/code-oss/build/codex/test/checkProtocolSync.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/codex/test/checkProtocolSync.test.ts rename to apps/review-desktop/code-oss/build/codex/test/checkProtocolSync.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/create-dmg.ts b/apps/review-desktop/code-oss/build/darwin/create-dmg.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/create-dmg.ts rename to apps/review-desktop/code-oss/build/darwin/create-dmg.ts diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/create-universal-app.ts b/apps/review-desktop/code-oss/build/darwin/create-universal-app.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/create-universal-app.ts rename to apps/review-desktop/code-oss/build/darwin/create-universal-app.ts diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/dmg-background-exploration.tiff b/apps/review-desktop/code-oss/build/darwin/dmg-background-exploration.tiff similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/dmg-background-exploration.tiff rename to apps/review-desktop/code-oss/build/darwin/dmg-background-exploration.tiff diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/dmg-background-insider.tiff b/apps/review-desktop/code-oss/build/darwin/dmg-background-insider.tiff similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/dmg-background-insider.tiff rename to apps/review-desktop/code-oss/build/darwin/dmg-background-insider.tiff diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/dmg-background-stable.tiff b/apps/review-desktop/code-oss/build/darwin/dmg-background-stable.tiff similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/dmg-background-stable.tiff rename to apps/review-desktop/code-oss/build/darwin/dmg-background-stable.tiff diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/dmg-settings.py.template b/apps/review-desktop/code-oss/build/darwin/dmg-settings.py.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/dmg-settings.py.template rename to apps/review-desktop/code-oss/build/darwin/dmg-settings.py.template diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/entitlements/app.plist b/apps/review-desktop/code-oss/build/darwin/entitlements/app.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/entitlements/app.plist rename to apps/review-desktop/code-oss/build/darwin/entitlements/app.plist diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/entitlements/diffr.plist b/apps/review-desktop/code-oss/build/darwin/entitlements/diffr.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/entitlements/diffr.plist rename to apps/review-desktop/code-oss/build/darwin/entitlements/diffr.plist diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper-gpu.plist b/apps/review-desktop/code-oss/build/darwin/entitlements/helper-gpu.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper-gpu.plist rename to apps/review-desktop/code-oss/build/darwin/entitlements/helper-gpu.plist diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper-plugin.plist b/apps/review-desktop/code-oss/build/darwin/entitlements/helper-plugin.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper-plugin.plist rename to apps/review-desktop/code-oss/build/darwin/entitlements/helper-plugin.plist diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper-renderer.plist b/apps/review-desktop/code-oss/build/darwin/entitlements/helper-renderer.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper-renderer.plist rename to apps/review-desktop/code-oss/build/darwin/entitlements/helper-renderer.plist diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper.plist b/apps/review-desktop/code-oss/build/darwin/entitlements/helper.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/entitlements/helper.plist rename to apps/review-desktop/code-oss/build/darwin/entitlements/helper.plist diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/patch-dmg.py b/apps/review-desktop/code-oss/build/darwin/patch-dmg.py similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/patch-dmg.py rename to apps/review-desktop/code-oss/build/darwin/patch-dmg.py diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/sign-server.ts b/apps/review-desktop/code-oss/build/darwin/sign-server.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/sign-server.ts rename to apps/review-desktop/code-oss/build/darwin/sign-server.ts diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/sign.ts b/apps/review-desktop/code-oss/build/darwin/sign.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/sign.ts rename to apps/review-desktop/code-oss/build/darwin/sign.ts diff --git a/apps/whiteboard-desktop/code-oss/build/darwin/verify-macho.ts b/apps/review-desktop/code-oss/build/darwin/verify-macho.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/darwin/verify-macho.ts rename to apps/review-desktop/code-oss/build/darwin/verify-macho.ts diff --git a/apps/whiteboard-desktop/code-oss/build/eslint.ts b/apps/review-desktop/code-oss/build/eslint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/eslint.ts rename to apps/review-desktop/code-oss/build/eslint.ts diff --git a/apps/whiteboard-desktop/code-oss/build/filters.ts b/apps/review-desktop/code-oss/build/filters.ts similarity index 98% rename from apps/whiteboard-desktop/code-oss/build/filters.ts rename to apps/review-desktop/code-oss/build/filters.ts index be936675e..e0a325b25 100644 --- a/apps/whiteboard-desktop/code-oss/build/filters.ts +++ b/apps/review-desktop/code-oss/build/filters.ts @@ -202,7 +202,7 @@ export const copyrightFilter = Object.freeze([ '!extensions/html-language-features/server/src/modes/typescript/*', '!extensions/*/server/bin/*', '!src/vs/platform/agentHost/node/codex/protocol/generated/**', - '!src/vs/whiteboard/common/whiteboardProtocol.ts', + '!src/vs/review/common/reviewProtocol.ts', '!src/vs/workbench/contrib/terminal/common/scripts/psreadline/**', '!extensions/mermaid-markdown-features/chat-webview-out/**', '!extensions/mermaid-markdown-features/markdown-preview-out/**', @@ -232,7 +232,7 @@ export const tsFormattingFilter = Object.freeze([ '!extensions/terminal-suggest/src/shell/zshBuiltinsCache.ts', '!extensions/terminal-suggest/src/shell/fishBuiltinsCache.ts', '!src/vs/platform/agentHost/node/codex/protocol/generated/**', - '!src/vs/whiteboard/common/whiteboardProtocol.ts', + '!src/vs/review/common/reviewProtocol.ts', ]); @@ -241,7 +241,7 @@ export const eslintFilter = Object.freeze([ '**/*.{ts,tsx,mts,cts}', '.eslint-plugin-local/**/*.ts', '!src/vs/platform/agentHost/node/codex/protocol/generated/**', - '!src/vs/whiteboard/common/whiteboardProtocol.ts', + '!src/vs/review/common/reviewProtocol.ts', ...readFileSync(join(import.meta.dirname, '..', '.eslint-ignore')) .toString() .split(/\r\n|\n/) diff --git a/apps/whiteboard-desktop/code-oss/build/gulp-eslint.ts b/apps/review-desktop/code-oss/build/gulp-eslint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulp-eslint.ts rename to apps/review-desktop/code-oss/build/gulp-eslint.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.cli.ts b/apps/review-desktop/code-oss/build/gulpfile.cli.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.cli.ts rename to apps/review-desktop/code-oss/build/gulpfile.cli.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.compile.ts b/apps/review-desktop/code-oss/build/gulpfile.compile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.compile.ts rename to apps/review-desktop/code-oss/build/gulpfile.compile.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.editor.ts b/apps/review-desktop/code-oss/build/gulpfile.editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.editor.ts rename to apps/review-desktop/code-oss/build/gulpfile.editor.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.extensions.ts b/apps/review-desktop/code-oss/build/gulpfile.extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.extensions.ts rename to apps/review-desktop/code-oss/build/gulpfile.extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.hygiene.ts b/apps/review-desktop/code-oss/build/gulpfile.hygiene.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.hygiene.ts rename to apps/review-desktop/code-oss/build/gulpfile.hygiene.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.scan.ts b/apps/review-desktop/code-oss/build/gulpfile.scan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.scan.ts rename to apps/review-desktop/code-oss/build/gulpfile.scan.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.ts b/apps/review-desktop/code-oss/build/gulpfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.ts rename to apps/review-desktop/code-oss/build/gulpfile.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.linux.ts b/apps/review-desktop/code-oss/build/gulpfile.vscode.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.linux.ts rename to apps/review-desktop/code-oss/build/gulpfile.vscode.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.ts b/apps/review-desktop/code-oss/build/gulpfile.vscode.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.ts rename to apps/review-desktop/code-oss/build/gulpfile.vscode.ts index 241d5af79..32a1abfe2 100644 --- a/apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.ts +++ b/apps/review-desktop/code-oss/build/gulpfile.vscode.ts @@ -227,8 +227,8 @@ function packageTask(platform: string, arch: string, sourceFolderName: string, d const checksums = computeChecksums(out, [ 'vs/base/parts/sandbox/electron-browser/preload.js', - 'vs/whiteboard/whiteboard.desktop.main.js', - 'vs/whiteboard/whiteboard.desktop.main.css', + 'vs/review/review.desktop.main.js', + 'vs/review/review.desktop.main.css', 'vs/workbench/api/node/extensionHostProcess.js', 'vs/code/electron-browser/workbench/workbench.html', 'vs/code/electron-browser/workbench/workbench.js' diff --git a/apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.win32.ts b/apps/review-desktop/code-oss/build/gulpfile.vscode.win32.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/gulpfile.vscode.win32.ts rename to apps/review-desktop/code-oss/build/gulpfile.vscode.win32.ts diff --git a/apps/whiteboard-desktop/code-oss/build/hygiene.ts b/apps/review-desktop/code-oss/build/hygiene.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/hygiene.ts rename to apps/review-desktop/code-oss/build/hygiene.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/asar.ts b/apps/review-desktop/code-oss/build/lib/asar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/asar.ts rename to apps/review-desktop/code-oss/build/lib/asar.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/azureFeed.ts b/apps/review-desktop/code-oss/build/lib/azureFeed.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/azureFeed.ts rename to apps/review-desktop/code-oss/build/lib/azureFeed.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/builtInExtensions.ts b/apps/review-desktop/code-oss/build/lib/builtInExtensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/builtInExtensions.ts rename to apps/review-desktop/code-oss/build/lib/builtInExtensions.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/builtInExtensionsCG.ts b/apps/review-desktop/code-oss/build/lib/builtInExtensionsCG.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/builtInExtensionsCG.ts rename to apps/review-desktop/code-oss/build/lib/builtInExtensionsCG.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/bundle.ts b/apps/review-desktop/code-oss/build/lib/bundle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/bundle.ts rename to apps/review-desktop/code-oss/build/lib/bundle.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/checkCyclicDependencies.ts b/apps/review-desktop/code-oss/build/lib/checkCyclicDependencies.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/checkCyclicDependencies.ts rename to apps/review-desktop/code-oss/build/lib/checkCyclicDependencies.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/compilation.ts b/apps/review-desktop/code-oss/build/lib/compilation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/compilation.ts rename to apps/review-desktop/code-oss/build/lib/compilation.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/date.ts b/apps/review-desktop/code-oss/build/lib/date.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/date.ts rename to apps/review-desktop/code-oss/build/lib/date.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/dependencies.ts b/apps/review-desktop/code-oss/build/lib/dependencies.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/dependencies.ts rename to apps/review-desktop/code-oss/build/lib/dependencies.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/electron.ts b/apps/review-desktop/code-oss/build/lib/electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/electron.ts rename to apps/review-desktop/code-oss/build/lib/electron.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/esbuild.ts b/apps/review-desktop/code-oss/build/lib/esbuild.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/esbuild.ts rename to apps/review-desktop/code-oss/build/lib/esbuild.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/extensions.ts b/apps/review-desktop/code-oss/build/lib/extensions.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/build/lib/extensions.ts rename to apps/review-desktop/code-oss/build/lib/extensions.ts index 837d87577..d07cfd03c 100644 --- a/apps/whiteboard-desktop/code-oss/build/lib/extensions.ts +++ b/apps/review-desktop/code-oss/build/lib/extensions.ts @@ -309,7 +309,7 @@ const excludedExtensions = [ 'ms-vscode.node-debug2', // Review's curated built-ins are prebuilt VSIX payloads, not sources. Packaging // them here would run vsce's npm file listing against dependencies they already - // bundle; apps/whiteboard-desktop/scripts/curated-extensions.mjs stages them into + // bundle; apps/review-desktop/scripts/curated-extensions.mjs stages them into // the packaged app instead. 'vscodevim.vim', 'tuttieee.emacs-mcx', diff --git a/apps/whiteboard-desktop/code-oss/build/lib/extractExtensionPoints.ts b/apps/review-desktop/code-oss/build/lib/extractExtensionPoints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/extractExtensionPoints.ts rename to apps/review-desktop/code-oss/build/lib/extractExtensionPoints.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/fetch.ts b/apps/review-desktop/code-oss/build/lib/fetch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/fetch.ts rename to apps/review-desktop/code-oss/build/lib/fetch.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/formatter.ts b/apps/review-desktop/code-oss/build/lib/formatter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/formatter.ts rename to apps/review-desktop/code-oss/build/lib/formatter.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/getVersion.ts b/apps/review-desktop/code-oss/build/lib/getVersion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/getVersion.ts rename to apps/review-desktop/code-oss/build/lib/getVersion.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/git.ts b/apps/review-desktop/code-oss/build/lib/git.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/git.ts rename to apps/review-desktop/code-oss/build/lib/git.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/gulp/facade.ts b/apps/review-desktop/code-oss/build/lib/gulp/facade.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/gulp/facade.ts rename to apps/review-desktop/code-oss/build/lib/gulp/facade.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/gulp/task.ts b/apps/review-desktop/code-oss/build/lib/gulp/task.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/gulp/task.ts rename to apps/review-desktop/code-oss/build/lib/gulp/task.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/i18n.resources.json b/apps/review-desktop/code-oss/build/lib/i18n.resources.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/i18n.resources.json rename to apps/review-desktop/code-oss/build/lib/i18n.resources.json diff --git a/apps/whiteboard-desktop/code-oss/build/lib/i18n.ts b/apps/review-desktop/code-oss/build/lib/i18n.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/i18n.ts rename to apps/review-desktop/code-oss/build/lib/i18n.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/inlineMeta.ts b/apps/review-desktop/code-oss/build/lib/inlineMeta.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/inlineMeta.ts rename to apps/review-desktop/code-oss/build/lib/inlineMeta.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/mangle/index.ts b/apps/review-desktop/code-oss/build/lib/mangle/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/mangle/index.ts rename to apps/review-desktop/code-oss/build/lib/mangle/index.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/mangle/renameWorker.ts b/apps/review-desktop/code-oss/build/lib/mangle/renameWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/mangle/renameWorker.ts rename to apps/review-desktop/code-oss/build/lib/mangle/renameWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/mangle/staticLanguageServiceHost.ts b/apps/review-desktop/code-oss/build/lib/mangle/staticLanguageServiceHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/mangle/staticLanguageServiceHost.ts rename to apps/review-desktop/code-oss/build/lib/mangle/staticLanguageServiceHost.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/monaco-api.ts b/apps/review-desktop/code-oss/build/lib/monaco-api.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/monaco-api.ts rename to apps/review-desktop/code-oss/build/lib/monaco-api.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/nls-analysis.ts b/apps/review-desktop/code-oss/build/lib/nls-analysis.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/nls-analysis.ts rename to apps/review-desktop/code-oss/build/lib/nls-analysis.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/nls.ts b/apps/review-desktop/code-oss/build/lib/nls.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/nls.ts rename to apps/review-desktop/code-oss/build/lib/nls.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/node.ts b/apps/review-desktop/code-oss/build/lib/node.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/node.ts rename to apps/review-desktop/code-oss/build/lib/node.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/optimize.ts b/apps/review-desktop/code-oss/build/lib/optimize.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/optimize.ts rename to apps/review-desktop/code-oss/build/lib/optimize.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/basePolicy.ts b/apps/review-desktop/code-oss/build/lib/policies/basePolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/basePolicy.ts rename to apps/review-desktop/code-oss/build/lib/policies/basePolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/booleanPolicy.ts b/apps/review-desktop/code-oss/build/lib/policies/booleanPolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/booleanPolicy.ts rename to apps/review-desktop/code-oss/build/lib/policies/booleanPolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/copyPolicyDto.ts b/apps/review-desktop/code-oss/build/lib/policies/copyPolicyDto.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/copyPolicyDto.ts rename to apps/review-desktop/code-oss/build/lib/policies/copyPolicyDto.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/exportPolicyData.ts b/apps/review-desktop/code-oss/build/lib/policies/exportPolicyData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/exportPolicyData.ts rename to apps/review-desktop/code-oss/build/lib/policies/exportPolicyData.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/numberPolicy.ts b/apps/review-desktop/code-oss/build/lib/policies/numberPolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/numberPolicy.ts rename to apps/review-desktop/code-oss/build/lib/policies/numberPolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/objectPolicy.ts b/apps/review-desktop/code-oss/build/lib/policies/objectPolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/objectPolicy.ts rename to apps/review-desktop/code-oss/build/lib/policies/objectPolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/policyData.jsonc b/apps/review-desktop/code-oss/build/lib/policies/policyData.jsonc similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/policyData.jsonc rename to apps/review-desktop/code-oss/build/lib/policies/policyData.jsonc diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/policyGenerator.ts b/apps/review-desktop/code-oss/build/lib/policies/policyGenerator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/policyGenerator.ts rename to apps/review-desktop/code-oss/build/lib/policies/policyGenerator.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/render.ts b/apps/review-desktop/code-oss/build/lib/policies/render.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/render.ts rename to apps/review-desktop/code-oss/build/lib/policies/render.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/stringEnumPolicy.ts b/apps/review-desktop/code-oss/build/lib/policies/stringEnumPolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/stringEnumPolicy.ts rename to apps/review-desktop/code-oss/build/lib/policies/stringEnumPolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/stringPolicy.ts b/apps/review-desktop/code-oss/build/lib/policies/stringPolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/stringPolicy.ts rename to apps/review-desktop/code-oss/build/lib/policies/stringPolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/policies/types.ts b/apps/review-desktop/code-oss/build/lib/policies/types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/policies/types.ts rename to apps/review-desktop/code-oss/build/lib/policies/types.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/preLaunch.ts b/apps/review-desktop/code-oss/build/lib/preLaunch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/preLaunch.ts rename to apps/review-desktop/code-oss/build/lib/preLaunch.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/propertyInitOrderChecker.ts b/apps/review-desktop/code-oss/build/lib/propertyInitOrderChecker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/propertyInitOrderChecker.ts rename to apps/review-desktop/code-oss/build/lib/propertyInitOrderChecker.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/reporter.ts b/apps/review-desktop/code-oss/build/lib/reporter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/reporter.ts rename to apps/review-desktop/code-oss/build/lib/reporter.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/runtimePlatform.ts b/apps/review-desktop/code-oss/build/lib/runtimePlatform.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/runtimePlatform.ts rename to apps/review-desktop/code-oss/build/lib/runtimePlatform.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/screenshotBlocksCi.ts b/apps/review-desktop/code-oss/build/lib/screenshotBlocksCi.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/screenshotBlocksCi.ts rename to apps/review-desktop/code-oss/build/lib/screenshotBlocksCi.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/screenshotDiffReport.ts b/apps/review-desktop/code-oss/build/lib/screenshotDiffReport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/screenshotDiffReport.ts rename to apps/review-desktop/code-oss/build/lib/screenshotDiffReport.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/standalone.ts b/apps/review-desktop/code-oss/build/lib/standalone.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/standalone.ts rename to apps/review-desktop/code-oss/build/lib/standalone.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/stats.ts b/apps/review-desktop/code-oss/build/lib/stats.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/stats.ts rename to apps/review-desktop/code-oss/build/lib/stats.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/stylelint/validateDesignTokens.ts b/apps/review-desktop/code-oss/build/lib/stylelint/validateDesignTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/stylelint/validateDesignTokens.ts rename to apps/review-desktop/code-oss/build/lib/stylelint/validateDesignTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/stylelint/validateVariableNames.ts b/apps/review-desktop/code-oss/build/lib/stylelint/validateVariableNames.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/stylelint/validateVariableNames.ts rename to apps/review-desktop/code-oss/build/lib/stylelint/validateVariableNames.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/stylelint/vscode-known-variables.json b/apps/review-desktop/code-oss/build/lib/stylelint/vscode-known-variables.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/stylelint/vscode-known-variables.json rename to apps/review-desktop/code-oss/build/lib/stylelint/vscode-known-variables.json diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/agentHostDependencies.test.ts b/apps/review-desktop/code-oss/build/lib/test/agentHostDependencies.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/agentHostDependencies.test.ts rename to apps/review-desktop/code-oss/build/lib/test/agentHostDependencies.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/booleanPolicy.test.ts b/apps/review-desktop/code-oss/build/lib/test/booleanPolicy.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/booleanPolicy.test.ts rename to apps/review-desktop/code-oss/build/lib/test/booleanPolicy.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/checkCyclicDependencies.test.ts b/apps/review-desktop/code-oss/build/lib/test/checkCyclicDependencies.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/checkCyclicDependencies.test.ts rename to apps/review-desktop/code-oss/build/lib/test/checkCyclicDependencies.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/darwin/com.visualstudio.code.oss.mobileconfig b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/darwin/com.visualstudio.code.oss.mobileconfig similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/darwin/com.visualstudio.code.oss.mobileconfig rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/darwin/com.visualstudio.code.oss.mobileconfig diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/darwin/en-us/com.visualstudio.code.oss.plist b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/darwin/en-us/com.visualstudio.code.oss.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/darwin/en-us/com.visualstudio.code.oss.plist rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/darwin/en-us/com.visualstudio.code.oss.plist diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/darwin/fr-fr/com.visualstudio.code.oss.plist b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/darwin/fr-fr/com.visualstudio.code.oss.plist similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/darwin/fr-fr/com.visualstudio.code.oss.plist rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/darwin/fr-fr/com.visualstudio.code.oss.plist diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/linux/policy.json b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/linux/policy.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/linux/policy.json rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/linux/policy.json diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/win32/CodeOSS.admx b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/win32/CodeOSS.admx similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/win32/CodeOSS.admx rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/win32/CodeOSS.admx diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/win32/en-us/CodeOSS.adml b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/win32/en-us/CodeOSS.adml similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/win32/en-us/CodeOSS.adml rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/win32/en-us/CodeOSS.adml diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/win32/fr-fr/CodeOSS.adml b/apps/review-desktop/code-oss/build/lib/test/fixtures/policies/win32/fr-fr/CodeOSS.adml similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/fixtures/policies/win32/fr-fr/CodeOSS.adml rename to apps/review-desktop/code-oss/build/lib/test/fixtures/policies/win32/fr-fr/CodeOSS.adml diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/i18n.test.ts b/apps/review-desktop/code-oss/build/lib/test/i18n.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/i18n.test.ts rename to apps/review-desktop/code-oss/build/lib/test/i18n.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/numberPolicy.test.ts b/apps/review-desktop/code-oss/build/lib/test/numberPolicy.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/numberPolicy.test.ts rename to apps/review-desktop/code-oss/build/lib/test/numberPolicy.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/objectPolicy.test.ts b/apps/review-desktop/code-oss/build/lib/test/objectPolicy.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/objectPolicy.test.ts rename to apps/review-desktop/code-oss/build/lib/test/objectPolicy.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/policyConversion.test.ts b/apps/review-desktop/code-oss/build/lib/test/policyConversion.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/policyConversion.test.ts rename to apps/review-desktop/code-oss/build/lib/test/policyConversion.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/render.test.ts b/apps/review-desktop/code-oss/build/lib/test/render.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/render.test.ts rename to apps/review-desktop/code-oss/build/lib/test/render.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/stringEnumPolicy.test.ts b/apps/review-desktop/code-oss/build/lib/test/stringEnumPolicy.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/stringEnumPolicy.test.ts rename to apps/review-desktop/code-oss/build/lib/test/stringEnumPolicy.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/test/stringPolicy.test.ts b/apps/review-desktop/code-oss/build/lib/test/stringPolicy.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/test/stringPolicy.test.ts rename to apps/review-desktop/code-oss/build/lib/test/stringPolicy.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/treeshaking.ts b/apps/review-desktop/code-oss/build/lib/treeshaking.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/treeshaking.ts rename to apps/review-desktop/code-oss/build/lib/treeshaking.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/tsb/builder.ts b/apps/review-desktop/code-oss/build/lib/tsb/builder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/tsb/builder.ts rename to apps/review-desktop/code-oss/build/lib/tsb/builder.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/tsb/index.ts b/apps/review-desktop/code-oss/build/lib/tsb/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/tsb/index.ts rename to apps/review-desktop/code-oss/build/lib/tsb/index.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/tsb/transpiler.ts b/apps/review-desktop/code-oss/build/lib/tsb/transpiler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/tsb/transpiler.ts rename to apps/review-desktop/code-oss/build/lib/tsb/transpiler.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/tsb/utils.ts b/apps/review-desktop/code-oss/build/lib/tsb/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/tsb/utils.ts rename to apps/review-desktop/code-oss/build/lib/tsb/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/tsconfigUtils.ts b/apps/review-desktop/code-oss/build/lib/tsconfigUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/tsconfigUtils.ts rename to apps/review-desktop/code-oss/build/lib/tsconfigUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/tsgo.ts b/apps/review-desktop/code-oss/build/lib/tsgo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/tsgo.ts rename to apps/review-desktop/code-oss/build/lib/tsgo.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typeScriptLanguageServiceHost.ts b/apps/review-desktop/code-oss/build/lib/typeScriptLanguageServiceHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typeScriptLanguageServiceHost.ts rename to apps/review-desktop/code-oss/build/lib/typeScriptLanguageServiceHost.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/@vscode/gulp-electron.d.ts b/apps/review-desktop/code-oss/build/lib/typings/@vscode/gulp-electron.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/@vscode/gulp-electron.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/@vscode/gulp-electron.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/asar.d.ts b/apps/review-desktop/code-oss/build/lib/typings/asar.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/asar.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/asar.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/cgmanifest.json b/apps/review-desktop/code-oss/build/lib/typings/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/cgmanifest.json rename to apps/review-desktop/code-oss/build/lib/typings/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/chromium-pickle-js.d.ts b/apps/review-desktop/code-oss/build/lib/typings/chromium-pickle-js.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/chromium-pickle-js.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/chromium-pickle-js.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/event-stream.d.ts b/apps/review-desktop/code-oss/build/lib/typings/event-stream.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/event-stream.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/event-stream.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-azure-storage.d.ts b/apps/review-desktop/code-oss/build/lib/typings/gulp-azure-storage.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-azure-storage.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/gulp-azure-storage.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-bom.d.ts b/apps/review-desktop/code-oss/build/lib/typings/gulp-bom.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-bom.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/gulp-bom.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-buffer.d.ts b/apps/review-desktop/code-oss/build/lib/typings/gulp-buffer.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-buffer.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/gulp-buffer.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-gunzip.d.ts b/apps/review-desktop/code-oss/build/lib/typings/gulp-gunzip.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-gunzip.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/gulp-gunzip.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-vinyl-zip.d.ts b/apps/review-desktop/code-oss/build/lib/typings/gulp-vinyl-zip.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/gulp-vinyl-zip.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/gulp-vinyl-zip.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/rcedit.d.ts b/apps/review-desktop/code-oss/build/lib/typings/rcedit.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/rcedit.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/rcedit.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/stream.d.ts b/apps/review-desktop/code-oss/build/lib/typings/stream.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/stream.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/stream.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/ternary-stream.d.ts b/apps/review-desktop/code-oss/build/lib/typings/ternary-stream.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/ternary-stream.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/ternary-stream.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/typings/vscode-gulp-watch.d.ts b/apps/review-desktop/code-oss/build/lib/typings/vscode-gulp-watch.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/typings/vscode-gulp-watch.d.ts rename to apps/review-desktop/code-oss/build/lib/typings/vscode-gulp-watch.d.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/util.ts b/apps/review-desktop/code-oss/build/lib/util.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/util.ts rename to apps/review-desktop/code-oss/build/lib/util.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/watch/index.ts b/apps/review-desktop/code-oss/build/lib/watch/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/watch/index.ts rename to apps/review-desktop/code-oss/build/lib/watch/index.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/watch/watch-win32.ts b/apps/review-desktop/code-oss/build/lib/watch/watch-win32.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/watch/watch-win32.ts rename to apps/review-desktop/code-oss/build/lib/watch/watch-win32.ts diff --git a/apps/whiteboard-desktop/code-oss/build/lib/watch/watcher.exe b/apps/review-desktop/code-oss/build/lib/watch/watcher.exe similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/lib/watch/watcher.exe rename to apps/review-desktop/code-oss/build/lib/watch/watcher.exe diff --git a/apps/whiteboard-desktop/code-oss/build/linux/debian/calculate-deps.ts b/apps/review-desktop/code-oss/build/linux/debian/calculate-deps.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/debian/calculate-deps.ts rename to apps/review-desktop/code-oss/build/linux/debian/calculate-deps.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/debian/dep-lists.ts b/apps/review-desktop/code-oss/build/linux/debian/dep-lists.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/debian/dep-lists.ts rename to apps/review-desktop/code-oss/build/linux/debian/dep-lists.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/debian/install-sysroot.ts b/apps/review-desktop/code-oss/build/linux/debian/install-sysroot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/debian/install-sysroot.ts rename to apps/review-desktop/code-oss/build/linux/debian/install-sysroot.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/debian/types.ts b/apps/review-desktop/code-oss/build/linux/debian/types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/debian/types.ts rename to apps/review-desktop/code-oss/build/linux/debian/types.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/dependencies-generator.ts b/apps/review-desktop/code-oss/build/linux/dependencies-generator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/dependencies-generator.ts rename to apps/review-desktop/code-oss/build/linux/dependencies-generator.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/libcxx-fetcher.ts b/apps/review-desktop/code-oss/build/linux/libcxx-fetcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/libcxx-fetcher.ts rename to apps/review-desktop/code-oss/build/linux/libcxx-fetcher.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/review-package.ts b/apps/review-desktop/code-oss/build/linux/review-package.ts similarity index 95% rename from apps/whiteboard-desktop/code-oss/build/linux/review-package.ts rename to apps/review-desktop/code-oss/build/linux/review-package.ts index 3403fedf2..ffc2eccf6 100644 --- a/apps/whiteboard-desktop/code-oss/build/linux/review-package.ts +++ b/apps/review-desktop/code-oss/build/linux/review-package.ts @@ -29,7 +29,7 @@ export interface ReviewPackage { } /** Derive the Fedora package identity from the stamped release channel. */ -export function whiteboardPackage(product: ReviewPackageProduct, version: string, revision = process.env.REVIEW_LINUX_PACKAGE_REVISION ?? '1'): ReviewPackage { +export function reviewPackage(product: ReviewPackageProduct, version: string, revision = process.env.REVIEW_LINUX_PACKAGE_REVISION ?? '1'): ReviewPackage { const match = /^(\d+\.\d+\.\d+)(?:-(preview\.\d{8}\.\d+))?$/.exec(version); if (!match || !/^[1-9]\d*$/.test(revision)) { throw new Error('Linux repository packages require an X.Y.Z or X.Y.Z-preview.YYYYMMDD.N version and positive package revision'); @@ -61,7 +61,7 @@ async function loadReviewPackage(appRoot: string) { if (product.reviewVersion !== metadata.version || !/^[a-f0-9]{40}$/.test(product.commit ?? '')) { throw new Error('Linux payload must carry the stamped Review version and source commit'); } - return { pkg: whiteboardPackage(product, metadata.version), source, urlProtocol: product.urlProtocol }; + return { pkg: reviewPackage(product, metadata.version), source, urlProtocol: product.urlProtocol }; } /** Stage the Review runtime for the existing Code OSS RPM build task. */ @@ -88,7 +88,7 @@ export async function prepareReviewRpmPackage(codeRoot: string, arch: string): P // The CLI launches this channel's desktop app, not the stable one. await write(`usr/bin/${app}`, `#!/bin/sh export ELECTRON_RUN_AS_NODE=1 -export DEV_FAST_WHITEBOARD_DESKTOP_COMMAND=/usr/bin/${app}-desktop +export DEV_FAST_REVIEW_DESKTOP_COMMAND=/usr/bin/${app}-desktop exec ${share}/${app} ${share}/resources/app/review-runtime/dist/cli.js "$@" `, 0o755); await write(`usr/bin/${app}-desktop`, `#!/bin/sh @@ -128,7 +128,7 @@ MimeType=x-scheme-handler/${urlProtocol}; `); const icon = join(destination, `usr/share/icons/hicolor/512x512/apps/${app}.png`); await mkdir(dirname(icon), { recursive: true }); - await cp(join(monorepoRoot, `packages/whiteboard/app/icons/${app}-square-512.png`), icon); + await cp(join(monorepoRoot, `packages/review/app/icons/${app}-square-512.png`), icon); // Electron's packaged sandbox helper must be root-owned with setuid in the // system package. Package creation sets ownership; no runtime chmod is needed. await chmod(join(destination, share, 'chrome-sandbox'), 0o4755); diff --git a/apps/whiteboard-desktop/code-oss/build/linux/rpm/calculate-deps.ts b/apps/review-desktop/code-oss/build/linux/rpm/calculate-deps.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/rpm/calculate-deps.ts rename to apps/review-desktop/code-oss/build/linux/rpm/calculate-deps.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/rpm/dep-lists.ts b/apps/review-desktop/code-oss/build/linux/rpm/dep-lists.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/rpm/dep-lists.ts rename to apps/review-desktop/code-oss/build/linux/rpm/dep-lists.ts diff --git a/apps/whiteboard-desktop/code-oss/build/linux/rpm/types.ts b/apps/review-desktop/code-oss/build/linux/rpm/types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/linux/rpm/types.ts rename to apps/review-desktop/code-oss/build/linux/rpm/types.ts diff --git a/apps/whiteboard-desktop/code-oss/build/loader.min b/apps/review-desktop/code-oss/build/loader.min similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/loader.min rename to apps/review-desktop/code-oss/build/loader.min diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/LICENSE b/apps/review-desktop/code-oss/build/monaco/LICENSE similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/LICENSE rename to apps/review-desktop/code-oss/build/monaco/LICENSE diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/README-npm.md b/apps/review-desktop/code-oss/build/monaco/README-npm.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/README-npm.md rename to apps/review-desktop/code-oss/build/monaco/README-npm.md diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/README.md b/apps/review-desktop/code-oss/build/monaco/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/README.md rename to apps/review-desktop/code-oss/build/monaco/README.md diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/ThirdPartyNotices.txt b/apps/review-desktop/code-oss/build/monaco/ThirdPartyNotices.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/ThirdPartyNotices.txt rename to apps/review-desktop/code-oss/build/monaco/ThirdPartyNotices.txt diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/monaco.d.ts.recipe b/apps/review-desktop/code-oss/build/monaco/monaco.d.ts.recipe similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/monaco.d.ts.recipe rename to apps/review-desktop/code-oss/build/monaco/monaco.d.ts.recipe diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/monaco.usage.recipe b/apps/review-desktop/code-oss/build/monaco/monaco.usage.recipe similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/monaco.usage.recipe rename to apps/review-desktop/code-oss/build/monaco/monaco.usage.recipe diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/package.json b/apps/review-desktop/code-oss/build/monaco/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/package.json rename to apps/review-desktop/code-oss/build/monaco/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/monaco/version.txt b/apps/review-desktop/code-oss/build/monaco/version.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/monaco/version.txt rename to apps/review-desktop/code-oss/build/monaco/version.txt diff --git a/apps/review-desktop/code-oss/build/next/index.ts b/apps/review-desktop/code-oss/build/next/index.ts new file mode 100644 index 000000000..a00f9fc50 --- /dev/null +++ b/apps/review-desktop/code-oss/build/next/index.ts @@ -0,0 +1,1045 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as esbuild from 'esbuild'; +import * as fs from 'fs'; +import { createRequire } from 'module'; +import * as path from 'path'; +import { promisify } from 'util'; + +import glob from 'glob'; +import gulpWatch from '../lib/watch/index.ts'; +import { nlsPlugin, createNLSCollector, finalizeNLS, postProcessNLS } from './nls-plugin.ts'; +import { convertPrivateFields, adjustSourceMap, type ConvertPrivateFieldsResult } from './private-to-property.ts'; +import { getVersion } from '../lib/getVersion.ts'; +import { getGitCommitDate } from '../lib/date.ts'; +import product from '../../product.json' with { type: 'json' }; +import packageJson from '../../package.json' with { type: 'json' }; +import { useEsbuildTranspile } from '../buildConfig.ts'; +import { isWebExtension, type IScannedBuiltinExtension } from '../lib/extensions.ts'; + +const globAsync = promisify(glob); +const nodeRequire = createRequire(import.meta.url); + +// ============================================================================ +// Configuration +// ============================================================================ + +const REPO_ROOT = path.dirname(path.dirname(import.meta.dirname)); +const commit = getVersion(REPO_ROOT); +const quality = (product as { quality?: string }).quality; +const version = (quality && quality !== 'stable') ? `${packageJson.version}-${quality}` : packageJson.version; + +// CLI: transpile [--watch] | bundle [--minify] [--nls] [--out ] +const command = process.argv[2]; // 'transpile' or 'bundle' + +function getArgValue(name: string): string | undefined { + const index = process.argv.indexOf(name); + if (index !== -1 && index + 1 < process.argv.length) { + return process.argv[index + 1]; + } + return undefined; +} + +const options = { + watch: process.argv.includes('--watch'), + minify: process.argv.includes('--minify'), + nls: process.argv.includes('--nls'), + manglePrivates: process.argv.includes('--mangle-privates'), + excludeTests: process.argv.includes('--exclude-tests'), + out: getArgValue('--out'), + sourceMapBaseUrl: getArgValue('--source-map-base-url'), +}; + +const SRC_DIR = 'src'; +const OUT_DIR = 'out'; +const OUT_VSCODE_DIR = 'out-vscode'; + +// UTF-8 BOM - added to test files with 'utf8' in the path (matches gulp build behavior) +const UTF8_BOM = Buffer.from([0xef, 0xbb, 0xbf]); + +// ============================================================================ +// Entry Points (from build/buildfile.ts) +// ============================================================================ + +// Extension host bundles are excluded from private field mangling because they +// expose API surface to extensions where encapsulation matters. +const extensionHostEntryPoints = [ + 'vs/workbench/api/node/extensionHostProcess', + 'vs/workbench/api/worker/extensionHostWorkerMain', +]; + +function isExtensionHostBundle(filePath: string): boolean { + const normalized = filePath.replaceAll('\\', '/'); + return extensionHostEntryPoints.some(ep => normalized.endsWith(`${ep}.js`)); +} + +// Workers - shared between targets +const workerEntryPoints = [ + 'vs/editor/common/services/editorWebWorkerMain', + 'vs/workbench/api/worker/extensionHostWorkerMain', + 'vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain', + 'vs/workbench/services/search/worker/localFileSearchMain', + 'vs/workbench/contrib/output/common/outputLinkComputerMain', + 'vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain', +]; + +// Desktop-only workers (use electron-browser) +const desktopWorkerEntryPoints = [ + 'vs/platform/profiling/electron-browser/profileAnalysisWorkerMain', +]; + +// Desktop workbench and code entry points +const desktopEntryPoints = [ + 'vs/review/review.desktop.main', + 'vs/review/electron-utility/reviewDesktopHostMain', + 'vs/workbench/contrib/debug/node/telemetryApp', + 'vs/platform/files/node/watcher/watcherMain', + 'vs/platform/terminal/node/ptyHostMain', + 'vs/platform/agentHost/node/agentHostMain', + 'vs/platform/agentHost/node/diffWorkerMain', + 'vs/workbench/api/node/extensionHostProcess', +]; + +const codeEntryPoints = [ + 'vs/code/node/cliProcessMain', + 'vs/code/electron-utility/sharedProcess/sharedProcessMain', + 'vs/code/electron-browser/workbench/workbench', +]; + +const bootstrapEntryPoints = [ + 'main', + 'cli', + 'bootstrap-fork', +]; + +const entryPoints = [ + ...workerEntryPoints, + ...desktopWorkerEntryPoints, + ...desktopEntryPoints, + ...codeEntryPoints, +]; + +const cssBundleEntryPoints = new Set([ + 'vs/review/review.desktop.main', + 'vs/code/electron-browser/workbench/workbench', +]); + +// ============================================================================ +// Resource Patterns (files to copy, not transpile/bundle) +// ============================================================================ + +// Common resources needed by all targets +const commonResourcePatterns = [ + // Tree-sitter queries + 'vs/editor/common/languages/highlights/*.scm', + 'vs/editor/common/languages/injections/*.scm', + + // SVGs referenced from CSS (needed for transpile/dev builds where CSS is copied as-is) + 'vs/workbench/browser/media/code-icon.svg', + 'vs/workbench/browser/parts/editor/media/letterpress*.svg' +]; + +// Resources for desktop target +const desktopResourcePatterns = [ + ...commonResourcePatterns, + + // HTML + 'vs/code/electron-browser/workbench/workbench.html', + 'vs/code/electron-browser/workbench/workbench-dev.html', + 'vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html', + 'vs/workbench/contrib/webview/browser/pre/*.html', + + // Webview pre scripts + 'vs/workbench/contrib/webview/browser/pre/*.js', + + // Shell scripts + 'vs/base/node/*.sh', + 'vs/workbench/contrib/terminal/common/scripts/*.sh', + 'vs/workbench/contrib/terminal/common/scripts/*.ps1', + 'vs/workbench/contrib/terminal/common/scripts/*.psm1', + 'vs/workbench/contrib/terminal/common/scripts/*.fish', + 'vs/workbench/contrib/terminal/common/scripts/*.zsh', + 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.psd1', + 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.psm1', + 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.dll', + 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.ps1xml', + 'vs/workbench/contrib/terminal/common/scripts/psreadline/net6plus/*.dll', + 'vs/workbench/contrib/terminal/common/scripts/psreadline/netstd/*.dll', + 'vs/workbench/contrib/externalTerminal/**/*.scpt', + + // Media - audio + 'vs/platform/accessibilitySignal/browser/media/*.mp3', + + // Media - images + 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.svg', + 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.png', + 'vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', + 'vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}', + 'vs/workbench/services/extensionManagement/common/media/*.svg', + 'vs/workbench/services/extensionManagement/common/media/*.png', + 'vs/workbench/browser/parts/editor/media/*.png', + 'vs/workbench/contrib/debug/browser/media/*.png', + +]; + +// ============================================================================ +// Utilities +// ============================================================================ + +async function cleanDir(dir: string): Promise { + const fullPath = path.join(REPO_ROOT, dir); + console.log(`[clean] ${dir}`); + await fs.promises.rm(fullPath, { recursive: true, force: true }); + await fs.promises.mkdir(fullPath, { recursive: true }); +} + +/** + * Scan for built-in extensions in the given directory. + * Returns an array of extension entries for the builtinExtensionsScannerService. + */ +function scanBuiltinExtensions(extensionsRoot: string): Array { + const scannedExtensions: Array = []; + const extensionsPath = path.join(REPO_ROOT, extensionsRoot); + + if (!fs.existsSync(extensionsPath)) { + return scannedExtensions; + } + + for (const extensionFolder of fs.readdirSync(extensionsPath)) { + const packageJSONPath = path.join(extensionsPath, extensionFolder, 'package.json'); + if (!fs.existsSync(packageJSONPath)) { + continue; + } + try { + const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf8')); + if (!isWebExtension(packageJSON)) { + continue; + } + const children = fs.readdirSync(path.join(extensionsPath, extensionFolder)); + const packageNLSPath = children.filter(child => child === 'package.nls.json')[0]; + const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(extensionsPath, extensionFolder, packageNLSPath), 'utf8')) : undefined; + const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0]; + const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; + + scannedExtensions.push({ + extensionPath: extensionFolder, + packageJSON, + packageNLS, + readmePath: readme ? path.join(extensionFolder, readme) : undefined, + changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined, + }); + } catch (e) { + // Skip invalid extensions + } + } + + return scannedExtensions; +} + +/** + * Get the date from the out directory date file, or return the git commit date. + */ +function readISODate(outDir: string): string { + try { + return fs.readFileSync(path.join(REPO_ROOT, outDir, 'date'), 'utf8'); + } catch { + return getGitCommitDate(); + } +} + +/** + * Only used to make encoding tests happy. The source files don't have a BOM but the + * tests expect one... so we add it here. + */ +function needsBomAdded(filePath: string): boolean { + return /([\/\\])test\1.*utf8/.test(filePath); +} + +async function copyFile(srcPath: string, destPath: string): Promise { + await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); + + if (needsBomAdded(srcPath)) { + const content = await fs.promises.readFile(srcPath); + if (content[0] !== 0xef || content[1] !== 0xbb || content[2] !== 0xbf) { + await fs.promises.writeFile(destPath, Buffer.concat([UTF8_BOM, content])); + return; + } + } + await fs.promises.copyFile(srcPath, destPath); +} + +/** + * Standalone TypeScript files that need to be compiled separately (not bundled). + * These run in special contexts (e.g., Electron preload) where bundling isn't appropriate. + * Only needed for desktop target. + */ +const desktopStandaloneFiles = [ + 'vs/base/parts/sandbox/electron-browser/preload.ts', + 'vs/base/parts/sandbox/electron-browser/preload-aux.ts', + 'vs/platform/browserView/electron-browser/preload-browserView.ts', +]; + +async function compileStandaloneFiles(outDir: string, doMinify: boolean): Promise { + console.log(`[standalone] Compiling ${desktopStandaloneFiles.length} standalone files...`); + + const banner = `/*!-------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/`; + + await Promise.all(desktopStandaloneFiles.map(async (file) => { + const entryPath = path.join(REPO_ROOT, SRC_DIR, file); + const outPath = path.join(REPO_ROOT, outDir, file.replace(/\.ts$/, '.js')); + + await esbuild.build({ + entryPoints: [entryPath], + outfile: outPath, + bundle: false, // Don't bundle - these are standalone scripts + format: 'cjs', // CommonJS for Electron preload + platform: 'node', + target: ['es2024'], + sourcemap: 'linked', + sourcesContent: false, + minify: doMinify, + banner: { js: banner }, + logLevel: 'warning', + }); + })); + + console.log(`[standalone] Done`); +} + +/** + * Copy ALL non-TypeScript files from src/ to the output directory. + * This matches the old gulp build behavior where `gulp.src('src/**')` streams + * every file and non-TS files bypass the compiler via tsFilter.restore. + * Used for development/transpile builds only - production bundles use + * copyResources() with curated per-target patterns instead. + */ +async function copyAllNonTsFiles(outDir: string, excludeTests: boolean): Promise { + console.log(`[resources] Copying all non-TS files to ${outDir}...`); + + const ignorePatterns = [ + // Exclude .ts files but keep .d.ts files (they're needed at runtime for type references) + '**/*.ts', + ]; + if (excludeTests) { + ignorePatterns.push('**/test/**'); + } + + const files = await globAsync('**/*', { + cwd: path.join(REPO_ROOT, SRC_DIR), + nodir: true, + ignore: ignorePatterns, + }); + + // Re-include .d.ts files that were excluded by the *.ts ignore + const dtsFiles = await globAsync('**/*.d.ts', { + cwd: path.join(REPO_ROOT, SRC_DIR), + ignore: excludeTests ? ['**/test/**'] : [], + }); + + const allFiles = [...new Set([...files, ...dtsFiles])]; + + await Promise.all(allFiles.map(file => { + const srcPath = path.join(REPO_ROOT, SRC_DIR, file); + const destPath = path.join(REPO_ROOT, outDir, file); + return copyFile(srcPath, destPath); + })); + + console.log(`[resources] Copied ${allFiles.length} files`); +} + +/** + * Copy curated resource files for production bundles. + * Uses desktop resource patterns from the old build. Only called by bundle(). + */ +async function copyResources(outDir: string): Promise { + console.log(`[resources] Copying to ${outDir}...`); + let copied = 0; + + const ignorePatterns = ['**/test/**', '**/*-dev.html']; + + for (const pattern of desktopResourcePatterns) { + const files = await globAsync(pattern, { + cwd: path.join(REPO_ROOT, SRC_DIR), + ignore: ignorePatterns, + }); + + for (const file of files) { + const srcPath = path.join(REPO_ROOT, SRC_DIR, file); + const destPath = path.join(REPO_ROOT, outDir, file); + + await copyFile(srcPath, destPath); + copied++; + } + } + + console.log(`[resources] Copied ${copied} files`); +} + +// ============================================================================ +// Plugins +// ============================================================================ + +function inlineMinimistPlugin(): esbuild.Plugin { + return { + name: 'inline-minimist', + setup(build) { + build.onResolve({ filter: /^minimist$/ }, () => ({ + path: path.join(REPO_ROOT, 'node_modules/minimist/index.js'), + external: false, + })); + }, + }; +} + +function inlineReviewBrowserDependenciesPlugin(): esbuild.Plugin { + return { + name: 'inline-review-browser-dependencies', + setup(build) { + build.onResolve({ filter: /^(?:eventsource-parser|zod(?:\/.*)?)$/ }, args => ({ + path: nodeRequire.resolve(args.path, { paths: [args.resolveDir] }), + external: false, + })); + }, + }; +} + +function cssExternalPlugin(): esbuild.Plugin { + // Mark CSS imports as external so they stay as import statements + // The CSS files are copied separately and loaded by the browser at runtime + return { + name: 'css-external', + setup(build) { + build.onResolve({ filter: /\.css$/ }, (args) => ({ + path: args.path, + external: true, + })); + }, + }; +} + +/** + * esbuild plugin that transforms source files to inject build-time configuration. + * This runs during onLoad so the transformation happens before esbuild processes the content, + * ensuring placeholders like `/*BUILD->INSERT_PRODUCT_CONFIGURATION* /` are replaced + * before esbuild strips them as non-legal comments. + */ +function fileContentMapperPlugin(outDir: string): esbuild.Plugin { + // Cache the replacement strings (computed once) + let productConfigReplacement: string | undefined; + let builtinExtensionsReplacement: string | undefined; + + return { + name: 'file-content-mapper', + setup(build) { + build.onLoad({ filter: /\.ts$/ }, async (args) => { + // Skip .d.ts files + if (args.path.endsWith('.d.ts')) { + return undefined; + } + + let contents = await fs.promises.readFile(args.path, 'utf-8'); + let modified = false; + + // Inject product configuration + if (contents.includes('/*BUILD->INSERT_PRODUCT_CONFIGURATION*/')) { + if (productConfigReplacement === undefined) { + const productConfiguration = JSON.stringify({ + ...product, + version, + commit, + date: readISODate(outDir) + }); + // Remove the outer braces since the placeholder is inside an object literal + productConfigReplacement = productConfiguration.substring(1, productConfiguration.length - 1); + } + contents = contents.replace('/*BUILD->INSERT_PRODUCT_CONFIGURATION*/', () => productConfigReplacement!); + modified = true; + } + + // Inject built-in extensions list + if (contents.includes('/*BUILD->INSERT_BUILTIN_EXTENSIONS*/')) { + if (builtinExtensionsReplacement === undefined) { + const builtinExtensions = JSON.stringify(scanBuiltinExtensions('.build/extensions')); + // Remove the outer brackets since the placeholder is inside an array literal + builtinExtensionsReplacement = builtinExtensions.substring(1, builtinExtensions.length - 1); + } + contents = contents.replace('/*BUILD->INSERT_BUILTIN_EXTENSIONS*/', () => builtinExtensionsReplacement!); + modified = true; + } + + if (modified) { + return { contents, loader: 'ts' }; + } + + // No modifications, let esbuild handle normally + return undefined; + }); + }, + }; +} + +// ============================================================================ +// Transpile (Goal 1: TS → JS using esbuild.transform for maximum speed) +// ============================================================================ + +// Shared transform options for single-file transpilation +const transformOptions: esbuild.TransformOptions = { + loader: 'ts', + format: 'esm', + target: 'es2024', + sourcemap: 'inline', + sourcesContent: false, + tsconfigRaw: JSON.stringify({ + compilerOptions: { + experimentalDecorators: true, + useDefineForClassFields: false + } + }), +}; + +async function transpileFile(srcPath: string, destPath: string): Promise { + const source = await fs.promises.readFile(srcPath, 'utf-8'); + const result = await esbuild.transform(source, { + ...transformOptions, + sourcefile: srcPath, + }); + + await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); + + const adjustedCode = adjustEsmUrl(result.code); + await fs.promises.writeFile(destPath, adjustedCode); +} + +/* + * This enables https://github.com/microsoft/esm-url-bundler-plugins to work on both original and transpiled sources. + * Usees regex to only replace `.ts?esm` inside quoted URL strings, avoiding false positives. + * + * E.g.: + * - esmModuleLocationBundler: () => new URL("../../../api/worker/extensionHostWorkerMain.ts?esm", import.meta.url) + * + esmModuleLocationBundler: () => new URL("../../../api/worker/extensionHostWorkerMain.js?esm", import.meta.url) + */ +function adjustEsmUrl(code: string): string { + const fixedCode = code.replace(/\.ts(\?esm['"])/g, '.js$1'); + return fixedCode; +} + +async function transpile(outDir: string, excludeTests: boolean): Promise { + // Find all .ts files + const ignorePatterns = ['**/*.d.ts']; + if (excludeTests) { + ignorePatterns.push('**/test/**'); + } + + const files = await globAsync('**/*.ts', { + cwd: path.join(REPO_ROOT, SRC_DIR), + ignore: ignorePatterns, + }); + + console.log(`[transpile] Found ${files.length} files`); + + // Transpile all files in parallel using esbuild.transform (fastest approach) + await Promise.all(files.map(file => { + const srcPath = path.join(REPO_ROOT, SRC_DIR, file); + const destPath = path.join(REPO_ROOT, outDir, file.replace(/\.ts$/, '.js')); + return transpileFile(srcPath, destPath); + })); +} + +// ============================================================================ +// Bundle (Goal 2: JS → bundled JS) +// ============================================================================ + +async function bundle(outDir: string, doMinify: boolean, doNls: boolean, doManglePrivates: boolean, sourceMapBaseUrl?: string): Promise { + await cleanDir(outDir); + + // Write build date file (used by packaging to embed in product.json). + // Reuse the date from out-build/date if it exists (written by the gulp + // writeISODate task) so that all parallel bundle outputs share the same + // timestamp - this is required for deterministic builds (e.g. macOS Universal). + const outDirPath = path.join(REPO_ROOT, outDir); + await fs.promises.mkdir(outDirPath, { recursive: true }); + let buildDate: string; + try { + buildDate = await fs.promises.readFile(path.join(REPO_ROOT, 'out-build', 'date'), 'utf8'); + } catch { + buildDate = getGitCommitDate(); + } + await fs.promises.writeFile(path.join(outDirPath, 'date'), buildDate, 'utf8'); + + console.log(`[bundle] ${SRC_DIR} → ${outDir}${doMinify ? ' (minify)' : ''}${doNls ? ' (nls)' : ''}${doManglePrivates ? ' (mangle-privates)' : ''}`); + const t1 = Date.now(); + + // Read TSLib for banner + const tslibPath = path.join(REPO_ROOT, 'node_modules/tslib/tslib.es6.js'); + const tslib = await fs.promises.readFile(tslibPath, 'utf-8'); + const banner = { + js: `/*!-------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ +${tslib}`, + css: `/*!-------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/`, + }; + + // Shared TypeScript options for bundling directly from source + const tsconfigRaw = JSON.stringify({ + compilerOptions: { + experimentalDecorators: true, + useDefineForClassFields: false + } + }); + + // Create shared NLS collector (only used if doNls is true) + const nlsCollector = createNLSCollector(); + const preserveEnglish = false; // Production mode: replace messages with null + + // Collect all build results (with write: false) + const buildResults: { outPath: string; result: esbuild.BuildResult }[] = []; + + // Create the file content mapper plugin (injects product config, builtin extensions) + const contentMapperPlugin = fileContentMapperPlugin(outDir); + + // Bundle each entry point directly from TypeScript source + await Promise.all(entryPoints.map(async (entryPoint) => { + const entryPath = path.join(REPO_ROOT, SRC_DIR, `${entryPoint}.ts`); + const outPath = path.join(REPO_ROOT, outDir, `${entryPoint}.js`); + + // Use CSS external plugin for entry points that don't need bundled CSS + const plugins: esbuild.Plugin[] = cssBundleEntryPoints.has(entryPoint) ? [] : [cssExternalPlugin()]; + if (entryPoint === 'vs/review/review.desktop.main') { + plugins.push(inlineReviewBrowserDependenciesPlugin()); + } + // Add content mapper plugin to inject product config and builtin extensions + plugins.push(contentMapperPlugin); + if (doNls) { + plugins.unshift(nlsPlugin({ + baseDir: path.join(REPO_ROOT, SRC_DIR), + collector: nlsCollector, + })); + } + + // For entry points that bundle CSS, we need to use outdir instead of outfile + // because esbuild can't produce multiple output files (JS + CSS) with outfile + const needsCssBundling = cssBundleEntryPoints.has(entryPoint); + + const buildOptions: esbuild.BuildOptions = { + entryPoints: needsCssBundling + ? [{ in: entryPath, out: entryPoint }] + : [entryPath], + ...(needsCssBundling + ? { outdir: path.join(REPO_ROOT, outDir) } + : { outfile: outPath }), + bundle: true, + format: 'esm', + platform: 'neutral', + target: ['es2024'], + packages: 'external', + sourcemap: 'linked', + sourcesContent: true, + minify: doMinify, + treeShaking: true, + banner, + loader: { + '.ttf': 'file', + '.svg': 'file', + '.png': 'file', + '.sh': 'file', + }, + assetNames: 'media/[name]', + plugins, + write: false, // Don't write yet, we need to post-process + logLevel: 'warning', + logOverride: { + 'unsupported-require-call': 'silent', + }, + tsconfigRaw, + }; + + const result = await esbuild.build(buildOptions); + + buildResults.push({ outPath, result }); + })); + + // Bundle bootstrap files (with minimist inlined) directly from TypeScript source + for (const entry of bootstrapEntryPoints) { + const entryPath = path.join(REPO_ROOT, SRC_DIR, `${entry}.ts`); + if (!fs.existsSync(entryPath)) { + console.log(`[bundle] Skipping ${entry} (not found)`); + continue; + } + + const outPath = path.join(REPO_ROOT, outDir, `${entry}.js`); + + const bootstrapPlugins: esbuild.Plugin[] = [inlineMinimistPlugin(), contentMapperPlugin]; + if (doNls) { + bootstrapPlugins.unshift(nlsPlugin({ + baseDir: path.join(REPO_ROOT, SRC_DIR), + collector: nlsCollector, + })); + } + + const result = await esbuild.build({ + entryPoints: [entryPath], + outfile: outPath, + bundle: true, + format: 'esm', + platform: 'node', + target: ['es2024'], + packages: 'external', + sourcemap: 'linked', + sourcesContent: true, + minify: doMinify, + treeShaking: true, + banner, + plugins: bootstrapPlugins, + write: false, // Don't write yet, we need to post-process + logLevel: 'warning', + logOverride: { + 'unsupported-require-call': 'silent', + }, + tsconfigRaw, + }); + + buildResults.push({ outPath, result }); + } + + // Finalize NLS: sort entries, assign indices, write metadata files + let indexMap = new Map(); + if (doNls) { + // Also write NLS files to out-build for backwards compatibility with test runner + const nlsResult = await finalizeNLS( + nlsCollector, + path.join(REPO_ROOT, outDir), + [path.join(REPO_ROOT, 'out-build')] + ); + indexMap = nlsResult.indexMap; + } + + // Post-process and write all output files + let bundled = 0; + const mangleStats: { file: string; result: ConvertPrivateFieldsResult }[] = []; + // Map from JS file path to pre-mangle content + edits, for source map adjustment + const mangleEdits = new Map(); + // Map from JS file path to pre-NLS content + edits, for source map adjustment + const nlsEdits = new Map(); + // Defer .map files until all .js files are processed, because esbuild may + // emit the .map file in a different build result than the .js file (e.g. + // code-split chunks), and we need the NLS/mangle edits from the .js pass + // to be available when adjusting the .map. + const deferredMaps: { path: string; text: string; contents: Uint8Array }[] = []; + for (const { result } of buildResults) { + if (!result.outputFiles) { + continue; + } + + for (const file of result.outputFiles) { + await fs.promises.mkdir(path.dirname(file.path), { recursive: true }); + + if (file.path.endsWith('.js') || file.path.endsWith('.css')) { + let content = file.text; + + // Convert native #private fields to regular properties BEFORE NLS + // post-processing, so that the edit offsets align with esbuild's + // source map coordinate system (both reference the raw esbuild output). + // Skip extension host bundles - they expose API surface to extensions + // where true encapsulation matters more than the perf gain. + if (file.path.endsWith('.js') && doManglePrivates && !isExtensionHostBundle(file.path)) { + const preMangleCode = content; + const mangleResult = convertPrivateFields(content, file.path); + content = mangleResult.code; + if (mangleResult.editCount > 0) { + mangleStats.push({ file: path.relative(path.join(REPO_ROOT, outDir), file.path), result: mangleResult }); + mangleEdits.set(file.path, { preMangleCode, edits: mangleResult.edits }); + } + } + + // Apply NLS post-processing if enabled (JS only) + if (file.path.endsWith('.js') && doNls && indexMap.size > 0) { + const preNLSCode = content; + const nlsResult = postProcessNLS(content, indexMap, preserveEnglish); + content = nlsResult.code; + if (nlsResult.edits.length > 0) { + nlsEdits.set(file.path, { preNLSCode, edits: nlsResult.edits }); + } + } + + // Rewrite sourceMappingURL to CDN URL if configured + if (sourceMapBaseUrl) { + const relativePath = path.relative(path.join(REPO_ROOT, outDir), file.path); + content = content.replace( + /\/\/# sourceMappingURL=.+$/m, + `//# sourceMappingURL=${sourceMapBaseUrl}/${relativePath}.map` + ); + content = content.replace( + /\/\*# sourceMappingURL=.+\*\/$/m, + `/*# sourceMappingURL=${sourceMapBaseUrl}/${relativePath}.map*/` + ); + } + + await fs.promises.writeFile(file.path, content); + } else if (file.path.endsWith('.map')) { + // Defer .map processing until all .js files have been handled + deferredMaps.push({ path: file.path, text: file.text, contents: file.contents }); + } else { + // Write other files (assets, etc.) as-is + await fs.promises.writeFile(file.path, file.contents); + } + } + bundled++; + } + + // Second pass: process deferred .map files now that all mangle/NLS edits + // have been collected from .js processing above. + for (const mapFile of deferredMaps) { + const jsPath = mapFile.path.replace(/\.map$/, ''); + const mangle = mangleEdits.get(jsPath); + const nls = nlsEdits.get(jsPath); + + if (mangle || nls) { + let mapJson = JSON.parse(mapFile.text); + if (mangle) { + mapJson = adjustSourceMap(mapJson, mangle.preMangleCode, mangle.edits); + } + if (nls) { + mapJson = adjustSourceMap(mapJson, nls.preNLSCode, nls.edits); + } + await fs.promises.writeFile(mapFile.path, JSON.stringify(mapJson)); + } else { + await fs.promises.writeFile(mapFile.path, mapFile.contents); + } + } + + // Syntax-check JS files that were post-processed (mangle-privates, NLS). + // These steps do raw string surgery on bundled JS so a bug could silently + // produce syntactically broken output. Catch it here at build time. + // Uses esbuild.transform() as a parser since the bundles are ESM. + const postProcessedFiles = new Set([...mangleEdits.keys(), ...nlsEdits.keys()]); + if (postProcessedFiles.size > 0) { + const errors = (await Promise.all([...postProcessedFiles].map(async jsPath => { + try { + const src = await fs.promises.readFile(jsPath, 'utf-8'); + await esbuild.transform(src, { loader: 'js', format: 'esm' }); + return undefined; + } catch (e: unknown) { + const rel = path.relative(path.join(REPO_ROOT, outDir), jsPath); + const message = e instanceof Error ? e.message : String(e); + return { rel, message }; + } + }))).filter(error => error !== undefined).sort((a, b) => a.rel.localeCompare(b.rel)); + if (errors.length > 0) { + throw new Error(`[bundle] Syntax errors in post-processed JS files:\n${errors.map(e => `${e.rel}: ${e.message}`).join('\n')}`); + } + console.log(`[bundle] Syntax check passed for ${postProcessedFiles.size} post-processed JS files`); + } + + // Log mangle-privates stats + if (doManglePrivates && mangleStats.length > 0) { + let totalClasses = 0, totalFields = 0, totalEdits = 0, totalElapsed = 0; + for (const { file, result } of mangleStats) { + console.log(`[mangle-privates] ${file}: ${result.classCount} classes, ${result.fieldCount} fields, ${result.editCount} edits, ${result.elapsed}ms`); + totalClasses += result.classCount; + totalFields += result.fieldCount; + totalEdits += result.editCount; + totalElapsed += result.elapsed; + } + console.log(`[mangle-privates] Total: ${totalClasses} classes, ${totalFields} fields, ${totalEdits} edits, ${totalElapsed}ms`); + } + + // Copy resources (curated per-target patterns for production) + await copyResources(outDir); + + // Compile standalone TypeScript files (like Electron preload scripts) that cannot be bundled + await compileStandaloneFiles(outDir, doMinify); + + console.log(`[bundle] Done in ${Date.now() - t1}ms (${bundled} bundles)`); +} + +// ============================================================================ +// Watch Mode +// ============================================================================ + +async function watch(): Promise { + if (!useEsbuildTranspile) { + console.log('Starting transpilation...'); + console.log('Finished transpilation with 0 errors after 0 ms'); + console.log('[watch] esbuild transpile disabled (useEsbuildTranspile=false). Keeping process alive as no-op.'); + await new Promise(() => { }); // keep alive + return; + } + + console.log('Starting transpilation...'); + + const outDir = OUT_DIR; + + // Initial setup + await cleanDir(outDir); + console.log(`[transpile] ${SRC_DIR} → ${outDir}`); + + // Initial full build + const t1 = Date.now(); + try { + await transpile(outDir, false); + await copyAllNonTsFiles(outDir, false); + console.log(`Finished transpilation with 0 errors after ${Date.now() - t1} ms`); + } catch (err) { + console.error('[watch] Initial build failed:', err); + console.log(`Finished transpilation with 1 errors after ${Date.now() - t1} ms`); + // Continue watching anyway + } + + let pendingTsFiles: Set = new Set(); + let pendingCopyFiles: Set = new Set(); + + const processChanges = async () => { + console.log('Starting transpilation...'); + const t1 = Date.now(); + const tsFiles = [...pendingTsFiles]; + const filesToCopy = [...pendingCopyFiles]; + pendingTsFiles = new Set(); + pendingCopyFiles = new Set(); + + try { + // Transform changed TypeScript files in parallel + if (tsFiles.length > 0) { + console.log(`[watch] Transpiling ${tsFiles.length} file(s)...`); + await Promise.all(tsFiles.map(srcPath => { + const relativePath = path.relative(path.join(REPO_ROOT, SRC_DIR), srcPath); + const destPath = path.join(REPO_ROOT, outDir, relativePath.replace(/\.ts$/, '.js')); + return transpileFile(srcPath, destPath); + })); + } + + // Copy changed resource files in parallel + if (filesToCopy.length > 0) { + await Promise.all(filesToCopy.map(async (srcPath) => { + const relativePath = path.relative(path.join(REPO_ROOT, SRC_DIR), srcPath); + const destPath = path.join(REPO_ROOT, outDir, relativePath); + await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); + await fs.promises.copyFile(srcPath, destPath); + console.log(`[watch] Copied ${relativePath}`); + })); + } + + if (tsFiles.length > 0 || filesToCopy.length > 0) { + console.log(`Finished transpilation with 0 errors after ${Date.now() - t1} ms`); + } + } catch (err) { + console.error('[watch] Rebuild failed:', err); + console.log(`Finished transpilation with 1 errors after ${Date.now() - t1} ms`); + // Continue watching + } + }; + + // Watch src directory using existing gulp-watch based watcher + let debounceTimer: ReturnType | undefined; + const srcDir = path.join(REPO_ROOT, SRC_DIR); + const watchStream = gulpWatch('src/**', { base: srcDir, readDelay: 200 }); + + watchStream.on('data', (file: { path: string }) => { + if (file.path.endsWith('.ts') && !file.path.endsWith('.d.ts')) { + pendingTsFiles.add(file.path); + } else { + // Copy any non-TS file (matches old gulp build's `src/**` behavior) + pendingCopyFiles.add(file.path); + } + + if (pendingTsFiles.size > 0 || pendingCopyFiles.size > 0) { + clearTimeout(debounceTimer); + debounceTimer = setTimeout(processChanges, 200); + } + }); + + console.log('[watch] Watching src/**/*.{ts,css,...} (Ctrl+C to stop)'); + + // Keep process alive + process.on('SIGINT', () => { + console.log('\n[watch] Stopping...'); + watchStream.end(); + process.exit(0); + }); +} + +// ============================================================================ +// Main +// ============================================================================ + +function printUsage(): void { + console.log(`Usage: npx tsx build/next/index.ts [options] + +Commands: + transpile Transpile TypeScript to JavaScript (single-file, fast) + bundle Bundle entry points into optimized bundles + +Options for 'transpile': + --watch Watch for changes and rebuild incrementally + --out Output directory (default: out) + --exclude-tests Exclude test files from transpilation + +Options for 'bundle': + --minify Minify the output bundles + --nls Process NLS (localization) strings + --mangle-privates Convert native #private fields to regular properties + --out Output directory (default: out-vscode) + --source-map-base-url Rewrite sourceMappingURL to CDN URL + +Examples: + npx tsx build/next/index.ts transpile + npx tsx build/next/index.ts transpile --watch + npx tsx build/next/index.ts transpile --out out-build + npx tsx build/next/index.ts transpile --out out-build --exclude-tests + npx tsx build/next/index.ts bundle + npx tsx build/next/index.ts bundle --minify --nls + npx tsx build/next/index.ts bundle --nls --out out-vscode-min +`); +} + +async function main(): Promise { + const t1 = Date.now(); + + try { + switch (command) { + case 'transpile': + if (options.watch) { + await watch(); + } else { + const outDir = options.out ?? OUT_DIR; + await cleanDir(outDir); + + // Write build date file (used by packaging to embed in product.json) + const outDirPath = path.join(REPO_ROOT, outDir); + await fs.promises.mkdir(outDirPath, { recursive: true }); + await fs.promises.writeFile(path.join(outDirPath, 'date'), getGitCommitDate(), 'utf8'); + + console.log(`[transpile] ${SRC_DIR} → ${outDir}${options.excludeTests ? ' (excluding tests)' : ''}`); + const t1 = Date.now(); + await transpile(outDir, options.excludeTests); + await copyAllNonTsFiles(outDir, options.excludeTests); + console.log(`[transpile] Done in ${Date.now() - t1}ms`); + } + break; + + case 'bundle': + await bundle(options.out ?? OUT_VSCODE_DIR, options.minify, options.nls, options.manglePrivates, options.sourceMapBaseUrl); + break; + + default: + printUsage(); + process.exit(command ? 1 : 0); + } + + if (!options.watch) { + console.log(`\n✓ Total: ${Date.now() - t1}ms`); + } + } catch (err) { + console.error('Build failed:', err); + process.exit(1); + } +} + +main(); diff --git a/apps/whiteboard-desktop/code-oss/build/next/nls-plugin.ts b/apps/review-desktop/code-oss/build/next/nls-plugin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/next/nls-plugin.ts rename to apps/review-desktop/code-oss/build/next/nls-plugin.ts diff --git a/apps/whiteboard-desktop/code-oss/build/next/private-to-property.ts b/apps/review-desktop/code-oss/build/next/private-to-property.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/next/private-to-property.ts rename to apps/review-desktop/code-oss/build/next/private-to-property.ts diff --git a/apps/whiteboard-desktop/code-oss/build/next/test/nls-sourcemap.test.ts b/apps/review-desktop/code-oss/build/next/test/nls-sourcemap.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/next/test/nls-sourcemap.test.ts rename to apps/review-desktop/code-oss/build/next/test/nls-sourcemap.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/next/test/private-to-property.test.ts b/apps/review-desktop/code-oss/build/next/test/private-to-property.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/next/test/private-to-property.test.ts rename to apps/review-desktop/code-oss/build/next/test/private-to-property.test.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/dirs.ts b/apps/review-desktop/code-oss/build/npm/dirs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/dirs.ts rename to apps/review-desktop/code-oss/build/npm/dirs.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/fast-install.ts b/apps/review-desktop/code-oss/build/npm/fast-install.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/fast-install.ts rename to apps/review-desktop/code-oss/build/npm/fast-install.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/gyp/custom-headers/v8-source-location.h b/apps/review-desktop/code-oss/build/npm/gyp/custom-headers/v8-source-location.h similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/gyp/custom-headers/v8-source-location.h rename to apps/review-desktop/code-oss/build/npm/gyp/custom-headers/v8-source-location.h diff --git a/apps/whiteboard-desktop/code-oss/build/npm/gyp/package-lock.json b/apps/review-desktop/code-oss/build/npm/gyp/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/gyp/package-lock.json rename to apps/review-desktop/code-oss/build/npm/gyp/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/build/npm/gyp/package.json b/apps/review-desktop/code-oss/build/npm/gyp/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/gyp/package.json rename to apps/review-desktop/code-oss/build/npm/gyp/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/npm/installStateHash.ts b/apps/review-desktop/code-oss/build/npm/installStateHash.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/installStateHash.ts rename to apps/review-desktop/code-oss/build/npm/installStateHash.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/mixin-telemetry-docs.ts b/apps/review-desktop/code-oss/build/npm/mixin-telemetry-docs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/mixin-telemetry-docs.ts rename to apps/review-desktop/code-oss/build/npm/mixin-telemetry-docs.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/postinstall.ts b/apps/review-desktop/code-oss/build/npm/postinstall.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/postinstall.ts rename to apps/review-desktop/code-oss/build/npm/postinstall.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/preinstall.ts b/apps/review-desktop/code-oss/build/npm/preinstall.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/preinstall.ts rename to apps/review-desktop/code-oss/build/npm/preinstall.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/update-all-grammars.ts b/apps/review-desktop/code-oss/build/npm/update-all-grammars.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/update-all-grammars.ts rename to apps/review-desktop/code-oss/build/npm/update-all-grammars.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/update-distro.ts b/apps/review-desktop/code-oss/build/npm/update-distro.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/update-distro.ts rename to apps/review-desktop/code-oss/build/npm/update-distro.ts diff --git a/apps/whiteboard-desktop/code-oss/build/npm/update-localization-extension.ts b/apps/review-desktop/code-oss/build/npm/update-localization-extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/npm/update-localization-extension.ts rename to apps/review-desktop/code-oss/build/npm/update-localization-extension.ts diff --git a/apps/whiteboard-desktop/code-oss/build/package-lock.json b/apps/review-desktop/code-oss/build/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/package-lock.json rename to apps/review-desktop/code-oss/build/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/build/package.json b/apps/review-desktop/code-oss/build/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/package.json rename to apps/review-desktop/code-oss/build/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/rspack/cssSourceMarkerLoader.mts b/apps/review-desktop/code-oss/build/rspack/cssSourceMarkerLoader.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/rspack/cssSourceMarkerLoader.mts rename to apps/review-desktop/code-oss/build/rspack/cssSourceMarkerLoader.mts diff --git a/apps/whiteboard-desktop/code-oss/build/rspack/package-lock.json b/apps/review-desktop/code-oss/build/rspack/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/rspack/package-lock.json rename to apps/review-desktop/code-oss/build/rspack/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/build/rspack/package.json b/apps/review-desktop/code-oss/build/rspack/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/rspack/package.json rename to apps/review-desktop/code-oss/build/rspack/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/rspack/rspack.serve-out.config.mts b/apps/review-desktop/code-oss/build/rspack/rspack.serve-out.config.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/rspack/rspack.serve-out.config.mts rename to apps/review-desktop/code-oss/build/rspack/rspack.serve-out.config.mts diff --git a/apps/whiteboard-desktop/code-oss/build/rspack/workbench-rspack.html b/apps/review-desktop/code-oss/build/rspack/workbench-rspack.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/rspack/workbench-rspack.html rename to apps/review-desktop/code-oss/build/rspack/workbench-rspack.html diff --git a/apps/whiteboard-desktop/code-oss/build/setup-npm-registry.ts b/apps/review-desktop/code-oss/build/setup-npm-registry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/setup-npm-registry.ts rename to apps/review-desktop/code-oss/build/setup-npm-registry.ts diff --git a/apps/whiteboard-desktop/code-oss/build/stylelint.ts b/apps/review-desktop/code-oss/build/stylelint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/stylelint.ts rename to apps/review-desktop/code-oss/build/stylelint.ts diff --git a/apps/whiteboard-desktop/code-oss/build/tsconfig.json b/apps/review-desktop/code-oss/build/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/tsconfig.json rename to apps/review-desktop/code-oss/build/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/build/vite/index-workbench.ts b/apps/review-desktop/code-oss/build/vite/index-workbench.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/index-workbench.ts rename to apps/review-desktop/code-oss/build/vite/index-workbench.ts diff --git a/apps/whiteboard-desktop/code-oss/build/vite/index.html b/apps/review-desktop/code-oss/build/vite/index.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/index.html rename to apps/review-desktop/code-oss/build/vite/index.html diff --git a/apps/whiteboard-desktop/code-oss/build/vite/index.ts b/apps/review-desktop/code-oss/build/vite/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/index.ts rename to apps/review-desktop/code-oss/build/vite/index.ts diff --git a/apps/whiteboard-desktop/code-oss/build/vite/package-lock.json b/apps/review-desktop/code-oss/build/vite/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/package-lock.json rename to apps/review-desktop/code-oss/build/vite/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/build/vite/package.json b/apps/review-desktop/code-oss/build/vite/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/package.json rename to apps/review-desktop/code-oss/build/vite/package.json diff --git a/apps/whiteboard-desktop/code-oss/build/vite/setup-dev.ts b/apps/review-desktop/code-oss/build/vite/setup-dev.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/setup-dev.ts rename to apps/review-desktop/code-oss/build/vite/setup-dev.ts diff --git a/apps/whiteboard-desktop/code-oss/build/vite/style.css b/apps/review-desktop/code-oss/build/vite/style.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/style.css rename to apps/review-desktop/code-oss/build/vite/style.css diff --git a/apps/whiteboard-desktop/code-oss/build/vite/tsconfig.json b/apps/review-desktop/code-oss/build/vite/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/tsconfig.json rename to apps/review-desktop/code-oss/build/vite/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/build/vite/vite.config.ts b/apps/review-desktop/code-oss/build/vite/vite.config.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/vite.config.ts rename to apps/review-desktop/code-oss/build/vite/vite.config.ts diff --git a/apps/whiteboard-desktop/code-oss/build/vite/workbench-electron.ts b/apps/review-desktop/code-oss/build/vite/workbench-electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/workbench-electron.ts rename to apps/review-desktop/code-oss/build/vite/workbench-electron.ts diff --git a/apps/whiteboard-desktop/code-oss/build/vite/workbench-vite-electron.html b/apps/review-desktop/code-oss/build/vite/workbench-vite-electron.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/workbench-vite-electron.html rename to apps/review-desktop/code-oss/build/vite/workbench-vite-electron.html diff --git a/apps/whiteboard-desktop/code-oss/build/vite/workbench-vite.html b/apps/review-desktop/code-oss/build/vite/workbench-vite.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/vite/workbench-vite.html rename to apps/review-desktop/code-oss/build/vite/workbench-vite.html diff --git a/apps/whiteboard-desktop/code-oss/build/win32/.gitignore b/apps/review-desktop/code-oss/build/win32/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/.gitignore rename to apps/review-desktop/code-oss/build/win32/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/build/win32/Cargo.lock b/apps/review-desktop/code-oss/build/win32/Cargo.lock similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/Cargo.lock rename to apps/review-desktop/code-oss/build/win32/Cargo.lock diff --git a/apps/whiteboard-desktop/code-oss/build/win32/Cargo.toml b/apps/review-desktop/code-oss/build/win32/Cargo.toml similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/Cargo.toml rename to apps/review-desktop/code-oss/build/win32/Cargo.toml diff --git a/apps/whiteboard-desktop/code-oss/build/win32/code.iss b/apps/review-desktop/code-oss/build/win32/code.iss similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/code.iss rename to apps/review-desktop/code-oss/build/win32/code.iss diff --git a/apps/whiteboard-desktop/code-oss/build/win32/explorer-dll-fetcher.ts b/apps/review-desktop/code-oss/build/win32/explorer-dll-fetcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/explorer-dll-fetcher.ts rename to apps/review-desktop/code-oss/build/win32/explorer-dll-fetcher.ts diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.hu.isl b/apps/review-desktop/code-oss/build/win32/i18n/Default.hu.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.hu.isl rename to apps/review-desktop/code-oss/build/win32/i18n/Default.hu.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.ko.isl b/apps/review-desktop/code-oss/build/win32/i18n/Default.ko.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.ko.isl rename to apps/review-desktop/code-oss/build/win32/i18n/Default.ko.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.zh-cn.isl b/apps/review-desktop/code-oss/build/win32/i18n/Default.zh-cn.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.zh-cn.isl rename to apps/review-desktop/code-oss/build/win32/i18n/Default.zh-cn.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.zh-tw.isl b/apps/review-desktop/code-oss/build/win32/i18n/Default.zh-tw.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/Default.zh-tw.isl rename to apps/review-desktop/code-oss/build/win32/i18n/Default.zh-tw.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.de.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.de.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.de.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.de.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.en.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.en.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.en.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.en.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.es.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.es.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.es.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.es.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.fr.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.fr.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.fr.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.fr.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.hu.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.hu.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.hu.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.hu.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.it.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.it.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.it.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.it.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.ja.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.ja.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.ja.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.ja.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.ko.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.ko.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.ko.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.ko.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.pt-br.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.pt-br.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.pt-br.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.pt-br.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.ru.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.ru.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.ru.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.ru.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.tr.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.tr.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.tr.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.tr.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.zh-cn.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.zh-cn.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.zh-cn.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.zh-cn.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.zh-tw.isl b/apps/review-desktop/code-oss/build/win32/i18n/messages.zh-tw.isl similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/i18n/messages.zh-tw.isl rename to apps/review-desktop/code-oss/build/win32/i18n/messages.zh-tw.isl diff --git a/apps/whiteboard-desktop/code-oss/build/win32/inno_updater.exe b/apps/review-desktop/code-oss/build/win32/inno_updater.exe similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/inno_updater.exe rename to apps/review-desktop/code-oss/build/win32/inno_updater.exe diff --git a/apps/whiteboard-desktop/code-oss/build/win32/vcruntime140.dll b/apps/review-desktop/code-oss/build/win32/vcruntime140.dll similarity index 100% rename from apps/whiteboard-desktop/code-oss/build/win32/vcruntime140.dll rename to apps/review-desktop/code-oss/build/win32/vcruntime140.dll diff --git a/apps/whiteboard-desktop/code-oss/cglicenses.json b/apps/review-desktop/code-oss/cglicenses.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/cglicenses.json rename to apps/review-desktop/code-oss/cglicenses.json diff --git a/apps/whiteboard-desktop/code-oss/cgmanifest.json b/apps/review-desktop/code-oss/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/cgmanifest.json rename to apps/review-desktop/code-oss/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/cli/.cargo/config.toml b/apps/review-desktop/code-oss/cli/.cargo/config.toml similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/.cargo/config.toml rename to apps/review-desktop/code-oss/cli/.cargo/config.toml diff --git a/apps/whiteboard-desktop/code-oss/cli/CONTRIBUTING.md b/apps/review-desktop/code-oss/cli/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/CONTRIBUTING.md rename to apps/review-desktop/code-oss/cli/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/cli/Cargo.lock b/apps/review-desktop/code-oss/cli/Cargo.lock similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/Cargo.lock rename to apps/review-desktop/code-oss/cli/Cargo.lock diff --git a/apps/whiteboard-desktop/code-oss/cli/Cargo.toml b/apps/review-desktop/code-oss/cli/Cargo.toml similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/Cargo.toml rename to apps/review-desktop/code-oss/cli/Cargo.toml diff --git a/apps/whiteboard-desktop/code-oss/cli/ThirdPartyNotices.txt b/apps/review-desktop/code-oss/cli/ThirdPartyNotices.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/ThirdPartyNotices.txt rename to apps/review-desktop/code-oss/cli/ThirdPartyNotices.txt diff --git a/apps/whiteboard-desktop/code-oss/cli/build.rs b/apps/review-desktop/code-oss/cli/build.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/build.rs rename to apps/review-desktop/code-oss/cli/build.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/rustfmt.toml b/apps/review-desktop/code-oss/cli/rustfmt.toml similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/rustfmt.toml rename to apps/review-desktop/code-oss/cli/rustfmt.toml diff --git a/apps/whiteboard-desktop/code-oss/cli/src/async_pipe.rs b/apps/review-desktop/code-oss/cli/src/async_pipe.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/async_pipe.rs rename to apps/review-desktop/code-oss/cli/src/async_pipe.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/auth.rs b/apps/review-desktop/code-oss/cli/src/auth.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/auth.rs rename to apps/review-desktop/code-oss/cli/src/auth.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/bin/code/legacy_args.rs b/apps/review-desktop/code-oss/cli/src/bin/code/legacy_args.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/bin/code/legacy_args.rs rename to apps/review-desktop/code-oss/cli/src/bin/code/legacy_args.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/bin/code/main.rs b/apps/review-desktop/code-oss/cli/src/bin/code/main.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/bin/code/main.rs rename to apps/review-desktop/code-oss/cli/src/bin/code/main.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands.rs b/apps/review-desktop/code-oss/cli/src/commands.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands.rs rename to apps/review-desktop/code-oss/cli/src/commands.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/agent.rs b/apps/review-desktop/code-oss/cli/src/commands/agent.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/agent.rs rename to apps/review-desktop/code-oss/cli/src/commands/agent.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/agent_host.rs b/apps/review-desktop/code-oss/cli/src/commands/agent_host.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/agent_host.rs rename to apps/review-desktop/code-oss/cli/src/commands/agent_host.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/agent_kill.rs b/apps/review-desktop/code-oss/cli/src/commands/agent_kill.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/agent_kill.rs rename to apps/review-desktop/code-oss/cli/src/commands/agent_kill.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/agent_logs.rs b/apps/review-desktop/code-oss/cli/src/commands/agent_logs.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/agent_logs.rs rename to apps/review-desktop/code-oss/cli/src/commands/agent_logs.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/agent_ps.rs b/apps/review-desktop/code-oss/cli/src/commands/agent_ps.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/agent_ps.rs rename to apps/review-desktop/code-oss/cli/src/commands/agent_ps.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/agent_stop.rs b/apps/review-desktop/code-oss/cli/src/commands/agent_stop.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/agent_stop.rs rename to apps/review-desktop/code-oss/cli/src/commands/agent_stop.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/args.rs b/apps/review-desktop/code-oss/cli/src/commands/args.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/args.rs rename to apps/review-desktop/code-oss/cli/src/commands/args.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/context.rs b/apps/review-desktop/code-oss/cli/src/commands/context.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/context.rs rename to apps/review-desktop/code-oss/cli/src/commands/context.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/output.rs b/apps/review-desktop/code-oss/cli/src/commands/output.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/output.rs rename to apps/review-desktop/code-oss/cli/src/commands/output.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/serve_web.rs b/apps/review-desktop/code-oss/cli/src/commands/serve_web.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/serve_web.rs rename to apps/review-desktop/code-oss/cli/src/commands/serve_web.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/tunnels.rs b/apps/review-desktop/code-oss/cli/src/commands/tunnels.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/tunnels.rs rename to apps/review-desktop/code-oss/cli/src/commands/tunnels.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/update.rs b/apps/review-desktop/code-oss/cli/src/commands/update.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/update.rs rename to apps/review-desktop/code-oss/cli/src/commands/update.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/commands/version.rs b/apps/review-desktop/code-oss/cli/src/commands/version.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/commands/version.rs rename to apps/review-desktop/code-oss/cli/src/commands/version.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/constants.rs b/apps/review-desktop/code-oss/cli/src/constants.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/constants.rs rename to apps/review-desktop/code-oss/cli/src/constants.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/desktop.rs b/apps/review-desktop/code-oss/cli/src/desktop.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/desktop.rs rename to apps/review-desktop/code-oss/cli/src/desktop.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/desktop/version_manager.rs b/apps/review-desktop/code-oss/cli/src/desktop/version_manager.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/desktop/version_manager.rs rename to apps/review-desktop/code-oss/cli/src/desktop/version_manager.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/download_cache.rs b/apps/review-desktop/code-oss/cli/src/download_cache.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/download_cache.rs rename to apps/review-desktop/code-oss/cli/src/download_cache.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/json_rpc.rs b/apps/review-desktop/code-oss/cli/src/json_rpc.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/json_rpc.rs rename to apps/review-desktop/code-oss/cli/src/json_rpc.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/lib.rs b/apps/review-desktop/code-oss/cli/src/lib.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/lib.rs rename to apps/review-desktop/code-oss/cli/src/lib.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/log.rs b/apps/review-desktop/code-oss/cli/src/log.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/log.rs rename to apps/review-desktop/code-oss/cli/src/log.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/msgpack_rpc.rs b/apps/review-desktop/code-oss/cli/src/msgpack_rpc.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/msgpack_rpc.rs rename to apps/review-desktop/code-oss/cli/src/msgpack_rpc.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/options.rs b/apps/review-desktop/code-oss/cli/src/options.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/options.rs rename to apps/review-desktop/code-oss/cli/src/options.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/rpc.rs b/apps/review-desktop/code-oss/cli/src/rpc.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/rpc.rs rename to apps/review-desktop/code-oss/cli/src/rpc.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/self_update.rs b/apps/review-desktop/code-oss/cli/src/self_update.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/self_update.rs rename to apps/review-desktop/code-oss/cli/src/self_update.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/singleton.rs b/apps/review-desktop/code-oss/cli/src/singleton.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/singleton.rs rename to apps/review-desktop/code-oss/cli/src/singleton.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/state.rs b/apps/review-desktop/code-oss/cli/src/state.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/state.rs rename to apps/review-desktop/code-oss/cli/src/state.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels.rs b/apps/review-desktop/code-oss/cli/src/tunnels.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels.rs rename to apps/review-desktop/code-oss/cli/src/tunnels.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/agent_host.rs b/apps/review-desktop/code-oss/cli/src/tunnels/agent_host.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/agent_host.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/agent_host.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/agent_host_metadata.rs b/apps/review-desktop/code-oss/cli/src/tunnels/agent_host_metadata.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/agent_host_metadata.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/agent_host_metadata.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/challenge.rs b/apps/review-desktop/code-oss/cli/src/tunnels/challenge.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/challenge.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/challenge.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/code_server.rs b/apps/review-desktop/code-oss/cli/src/tunnels/code_server.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/code_server.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/code_server.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/control_server.rs b/apps/review-desktop/code-oss/cli/src/tunnels/control_server.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/control_server.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/control_server.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/dev_tunnels.rs b/apps/review-desktop/code-oss/cli/src/tunnels/dev_tunnels.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/dev_tunnels.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/dev_tunnels.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/legal.rs b/apps/review-desktop/code-oss/cli/src/tunnels/legal.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/legal.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/legal.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/local_forwarding.rs b/apps/review-desktop/code-oss/cli/src/tunnels/local_forwarding.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/local_forwarding.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/local_forwarding.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep.rs b/apps/review-desktop/code-oss/cli/src/tunnels/nosleep.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/nosleep.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep_linux.rs b/apps/review-desktop/code-oss/cli/src/tunnels/nosleep_linux.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep_linux.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/nosleep_linux.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep_macos.rs b/apps/review-desktop/code-oss/cli/src/tunnels/nosleep_macos.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep_macos.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/nosleep_macos.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep_windows.rs b/apps/review-desktop/code-oss/cli/src/tunnels/nosleep_windows.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/nosleep_windows.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/nosleep_windows.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/paths.rs b/apps/review-desktop/code-oss/cli/src/tunnels/paths.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/paths.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/paths.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/port_forwarder.rs b/apps/review-desktop/code-oss/cli/src/tunnels/port_forwarder.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/port_forwarder.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/port_forwarder.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/protocol.rs b/apps/review-desktop/code-oss/cli/src/tunnels/protocol.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/protocol.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/protocol.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/server_bridge.rs b/apps/review-desktop/code-oss/cli/src/tunnels/server_bridge.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/server_bridge.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/server_bridge.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/server_multiplexer.rs b/apps/review-desktop/code-oss/cli/src/tunnels/server_multiplexer.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/server_multiplexer.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/server_multiplexer.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/service.rs b/apps/review-desktop/code-oss/cli/src/tunnels/service.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/service.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/service.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/service_linux.rs b/apps/review-desktop/code-oss/cli/src/tunnels/service_linux.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/service_linux.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/service_linux.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/service_macos.rs b/apps/review-desktop/code-oss/cli/src/tunnels/service_macos.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/service_macos.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/service_macos.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/service_windows.rs b/apps/review-desktop/code-oss/cli/src/tunnels/service_windows.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/service_windows.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/service_windows.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/shutdown_signal.rs b/apps/review-desktop/code-oss/cli/src/tunnels/shutdown_signal.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/shutdown_signal.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/shutdown_signal.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/singleton_client.rs b/apps/review-desktop/code-oss/cli/src/tunnels/singleton_client.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/singleton_client.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/singleton_client.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/singleton_server.rs b/apps/review-desktop/code-oss/cli/src/tunnels/singleton_server.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/singleton_server.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/singleton_server.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/socket_signal.rs b/apps/review-desktop/code-oss/cli/src/tunnels/socket_signal.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/socket_signal.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/socket_signal.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/tunnels/wsl_detect.rs b/apps/review-desktop/code-oss/cli/src/tunnels/wsl_detect.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/tunnels/wsl_detect.rs rename to apps/review-desktop/code-oss/cli/src/tunnels/wsl_detect.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/update_service.rs b/apps/review-desktop/code-oss/cli/src/update_service.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/update_service.rs rename to apps/review-desktop/code-oss/cli/src/update_service.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util.rs b/apps/review-desktop/code-oss/cli/src/util.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util.rs rename to apps/review-desktop/code-oss/cli/src/util.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/app_lock.rs b/apps/review-desktop/code-oss/cli/src/util/app_lock.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/app_lock.rs rename to apps/review-desktop/code-oss/cli/src/util/app_lock.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/command.rs b/apps/review-desktop/code-oss/cli/src/util/command.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/command.rs rename to apps/review-desktop/code-oss/cli/src/util/command.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/errors.rs b/apps/review-desktop/code-oss/cli/src/util/errors.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/errors.rs rename to apps/review-desktop/code-oss/cli/src/util/errors.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/extract_safety.rs b/apps/review-desktop/code-oss/cli/src/util/extract_safety.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/extract_safety.rs rename to apps/review-desktop/code-oss/cli/src/util/extract_safety.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/file_lock.rs b/apps/review-desktop/code-oss/cli/src/util/file_lock.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/file_lock.rs rename to apps/review-desktop/code-oss/cli/src/util/file_lock.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/http.rs b/apps/review-desktop/code-oss/cli/src/util/http.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/http.rs rename to apps/review-desktop/code-oss/cli/src/util/http.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/input.rs b/apps/review-desktop/code-oss/cli/src/util/input.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/input.rs rename to apps/review-desktop/code-oss/cli/src/util/input.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/io.rs b/apps/review-desktop/code-oss/cli/src/util/io.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/io.rs rename to apps/review-desktop/code-oss/cli/src/util/io.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/is_integrated.rs b/apps/review-desktop/code-oss/cli/src/util/is_integrated.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/is_integrated.rs rename to apps/review-desktop/code-oss/cli/src/util/is_integrated.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/machine.rs b/apps/review-desktop/code-oss/cli/src/util/machine.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/machine.rs rename to apps/review-desktop/code-oss/cli/src/util/machine.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/os.rs b/apps/review-desktop/code-oss/cli/src/util/os.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/os.rs rename to apps/review-desktop/code-oss/cli/src/util/os.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/prereqs.rs b/apps/review-desktop/code-oss/cli/src/util/prereqs.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/prereqs.rs rename to apps/review-desktop/code-oss/cli/src/util/prereqs.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/ring_buffer.rs b/apps/review-desktop/code-oss/cli/src/util/ring_buffer.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/ring_buffer.rs rename to apps/review-desktop/code-oss/cli/src/util/ring_buffer.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/sync.rs b/apps/review-desktop/code-oss/cli/src/util/sync.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/sync.rs rename to apps/review-desktop/code-oss/cli/src/util/sync.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/tar.rs b/apps/review-desktop/code-oss/cli/src/util/tar.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/tar.rs rename to apps/review-desktop/code-oss/cli/src/util/tar.rs diff --git a/apps/whiteboard-desktop/code-oss/cli/src/util/zipper.rs b/apps/review-desktop/code-oss/cli/src/util/zipper.rs similarity index 100% rename from apps/whiteboard-desktop/code-oss/cli/src/util/zipper.rs rename to apps/review-desktop/code-oss/cli/src/util/zipper.rs diff --git a/apps/whiteboard-desktop/code-oss/eslint.config.js b/apps/review-desktop/code-oss/eslint.config.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/eslint.config.js rename to apps/review-desktop/code-oss/eslint.config.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/.npmrc b/apps/review-desktop/code-oss/extensions/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/.npmrc rename to apps/review-desktop/code-oss/extensions/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/CONTRIBUTING.md b/apps/review-desktop/code-oss/extensions/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/CONTRIBUTING.md rename to apps/review-desktop/code-oss/extensions/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/.vscodeignore b/apps/review-desktop/code-oss/extensions/bat/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/.vscodeignore rename to apps/review-desktop/code-oss/extensions/bat/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/cgmanifest.json b/apps/review-desktop/code-oss/extensions/bat/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/bat/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/language-configuration.json b/apps/review-desktop/code-oss/extensions/bat/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/language-configuration.json rename to apps/review-desktop/code-oss/extensions/bat/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/package.json b/apps/review-desktop/code-oss/extensions/bat/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/package.json rename to apps/review-desktop/code-oss/extensions/bat/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/package.nls.json b/apps/review-desktop/code-oss/extensions/bat/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/package.nls.json rename to apps/review-desktop/code-oss/extensions/bat/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/snippets/batchfile.code-snippets b/apps/review-desktop/code-oss/extensions/bat/snippets/batchfile.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/snippets/batchfile.code-snippets rename to apps/review-desktop/code-oss/extensions/bat/snippets/batchfile.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/bat/syntaxes/batchfile.tmLanguage.json b/apps/review-desktop/code-oss/extensions/bat/syntaxes/batchfile.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/bat/syntaxes/batchfile.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/bat/syntaxes/batchfile.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cgmanifest.json b/apps/review-desktop/code-oss/extensions/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/clojure/.vscodeignore b/apps/review-desktop/code-oss/extensions/clojure/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/clojure/.vscodeignore rename to apps/review-desktop/code-oss/extensions/clojure/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/clojure/cgmanifest.json b/apps/review-desktop/code-oss/extensions/clojure/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/clojure/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/clojure/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/clojure/language-configuration.json b/apps/review-desktop/code-oss/extensions/clojure/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/clojure/language-configuration.json rename to apps/review-desktop/code-oss/extensions/clojure/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/clojure/package.json b/apps/review-desktop/code-oss/extensions/clojure/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/clojure/package.json rename to apps/review-desktop/code-oss/extensions/clojure/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/clojure/package.nls.json b/apps/review-desktop/code-oss/extensions/clojure/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/clojure/package.nls.json rename to apps/review-desktop/code-oss/extensions/clojure/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/clojure/syntaxes/clojure.tmLanguage.json b/apps/review-desktop/code-oss/extensions/clojure/syntaxes/clojure.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/clojure/syntaxes/clojure.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/clojure/syntaxes/clojure.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/.vscodeignore b/apps/review-desktop/code-oss/extensions/coffeescript/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/.vscodeignore rename to apps/review-desktop/code-oss/extensions/coffeescript/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/cgmanifest.json b/apps/review-desktop/code-oss/extensions/coffeescript/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/coffeescript/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/language-configuration.json b/apps/review-desktop/code-oss/extensions/coffeescript/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/language-configuration.json rename to apps/review-desktop/code-oss/extensions/coffeescript/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/package.json b/apps/review-desktop/code-oss/extensions/coffeescript/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/package.json rename to apps/review-desktop/code-oss/extensions/coffeescript/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/package.nls.json b/apps/review-desktop/code-oss/extensions/coffeescript/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/package.nls.json rename to apps/review-desktop/code-oss/extensions/coffeescript/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/snippets/coffeescript.code-snippets b/apps/review-desktop/code-oss/extensions/coffeescript/snippets/coffeescript.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/snippets/coffeescript.code-snippets rename to apps/review-desktop/code-oss/extensions/coffeescript/snippets/coffeescript.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/coffeescript/syntaxes/coffeescript.tmLanguage.json b/apps/review-desktop/code-oss/extensions/coffeescript/syntaxes/coffeescript.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/coffeescript/syntaxes/coffeescript.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/coffeescript/syntaxes/coffeescript.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/.npmrc b/apps/review-desktop/code-oss/extensions/configuration-editing/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/.npmrc rename to apps/review-desktop/code-oss/extensions/configuration-editing/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/.vscodeignore b/apps/review-desktop/code-oss/extensions/configuration-editing/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/.vscodeignore rename to apps/review-desktop/code-oss/extensions/configuration-editing/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/configuration-editing/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/configuration-editing/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/esbuild.mts b/apps/review-desktop/code-oss/extensions/configuration-editing/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/esbuild.mts rename to apps/review-desktop/code-oss/extensions/configuration-editing/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/images/icon.png b/apps/review-desktop/code-oss/extensions/configuration-editing/images/icon.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/images/icon.png rename to apps/review-desktop/code-oss/extensions/configuration-editing/images/icon.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/package-lock.json b/apps/review-desktop/code-oss/extensions/configuration-editing/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/package-lock.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/package.json b/apps/review-desktop/code-oss/extensions/configuration-editing/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/package.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/package.nls.json b/apps/review-desktop/code-oss/extensions/configuration-editing/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/package.nls.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/schemas/attachContainer.schema.json b/apps/review-desktop/code-oss/extensions/configuration-editing/schemas/attachContainer.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/schemas/attachContainer.schema.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/schemas/attachContainer.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json b/apps/review-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.vscode.schema.json b/apps/review-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.vscode.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.vscode.schema.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/schemas/devContainer.vscode.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/browser/net.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/browser/net.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/browser/net.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/browser/net.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/configurationEditingMain.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/configurationEditingMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/configurationEditingMain.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/configurationEditingMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/extensionsProposals.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/extensionsProposals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/extensionsProposals.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/extensionsProposals.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/importExportProfiles.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/importExportProfiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/importExportProfiles.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/importExportProfiles.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/node/net.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/node/net.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/node/net.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/node/net.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/settingsDocumentHelper.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/settingsDocumentHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/settingsDocumentHelper.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/settingsDocumentHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/test/completion.test.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/test/completion.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/test/completion.test.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/test/completion.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/test/index.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/test/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/test/index.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/test/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/typings/ref.d.ts b/apps/review-desktop/code-oss/extensions/configuration-editing/src/typings/ref.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/src/typings/ref.d.ts rename to apps/review-desktop/code-oss/extensions/configuration-editing/src/typings/ref.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/configuration-editing/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/configuration-editing/tsconfig.json b/apps/review-desktop/code-oss/extensions/configuration-editing/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/configuration-editing/tsconfig.json rename to apps/review-desktop/code-oss/extensions/configuration-editing/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/.vscodeignore b/apps/review-desktop/code-oss/extensions/cpp/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/.vscodeignore rename to apps/review-desktop/code-oss/extensions/cpp/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/build/update-grammars.js b/apps/review-desktop/code-oss/extensions/cpp/build/update-grammars.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/build/update-grammars.js rename to apps/review-desktop/code-oss/extensions/cpp/build/update-grammars.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/cgmanifest.json b/apps/review-desktop/code-oss/extensions/cpp/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/cpp/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/language-configuration.json b/apps/review-desktop/code-oss/extensions/cpp/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/language-configuration.json rename to apps/review-desktop/code-oss/extensions/cpp/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/package.json b/apps/review-desktop/code-oss/extensions/cpp/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/package.json rename to apps/review-desktop/code-oss/extensions/cpp/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/package.nls.json b/apps/review-desktop/code-oss/extensions/cpp/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/package.nls.json rename to apps/review-desktop/code-oss/extensions/cpp/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/snippets/c.code-snippets b/apps/review-desktop/code-oss/extensions/cpp/snippets/c.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/snippets/c.code-snippets rename to apps/review-desktop/code-oss/extensions/cpp/snippets/c.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/snippets/cpp.code-snippets b/apps/review-desktop/code-oss/extensions/cpp/snippets/cpp.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/snippets/cpp.code-snippets rename to apps/review-desktop/code-oss/extensions/cpp/snippets/cpp.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/c.tmLanguage.json b/apps/review-desktop/code-oss/extensions/cpp/syntaxes/c.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/c.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/cpp/syntaxes/c.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json b/apps/review-desktop/code-oss/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/cpp.tmLanguage.json b/apps/review-desktop/code-oss/extensions/cpp/syntaxes/cpp.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/cpp.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/cpp/syntaxes/cpp.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/cuda-cpp.tmLanguage.json b/apps/review-desktop/code-oss/extensions/cpp/syntaxes/cuda-cpp.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/cuda-cpp.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/cpp/syntaxes/cuda-cpp.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/platform.tmLanguage.json b/apps/review-desktop/code-oss/extensions/cpp/syntaxes/platform.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/cpp/syntaxes/platform.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/cpp/syntaxes/platform.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/.vscodeignore b/apps/review-desktop/code-oss/extensions/csharp/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/.vscodeignore rename to apps/review-desktop/code-oss/extensions/csharp/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/cgmanifest.json b/apps/review-desktop/code-oss/extensions/csharp/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/csharp/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/language-configuration.json b/apps/review-desktop/code-oss/extensions/csharp/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/language-configuration.json rename to apps/review-desktop/code-oss/extensions/csharp/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/package.json b/apps/review-desktop/code-oss/extensions/csharp/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/package.json rename to apps/review-desktop/code-oss/extensions/csharp/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/package.nls.json b/apps/review-desktop/code-oss/extensions/csharp/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/package.nls.json rename to apps/review-desktop/code-oss/extensions/csharp/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/snippets/csharp.code-snippets b/apps/review-desktop/code-oss/extensions/csharp/snippets/csharp.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/snippets/csharp.code-snippets rename to apps/review-desktop/code-oss/extensions/csharp/snippets/csharp.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/csharp/syntaxes/csharp.tmLanguage.json b/apps/review-desktop/code-oss/extensions/csharp/syntaxes/csharp.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/csharp/syntaxes/csharp.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/csharp/syntaxes/csharp.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/.npmrc b/apps/review-desktop/code-oss/extensions/css-language-features/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/.npmrc rename to apps/review-desktop/code-oss/extensions/css-language-features/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/.vscodeignore b/apps/review-desktop/code-oss/extensions/css-language-features/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/.vscodeignore rename to apps/review-desktop/code-oss/extensions/css-language-features/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/CONTRIBUTING.md b/apps/review-desktop/code-oss/extensions/css-language-features/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/CONTRIBUTING.md rename to apps/review-desktop/code-oss/extensions/css-language-features/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/README.md b/apps/review-desktop/code-oss/extensions/css-language-features/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/README.md rename to apps/review-desktop/code-oss/extensions/css-language-features/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/browser/cssClientMain.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/browser/cssClientMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/browser/cssClientMain.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/browser/cssClientMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/cssClient.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/cssClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/cssClient.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/cssClient.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/customData.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/customData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/customData.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/customData.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/dropOrPasteResource.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/dropOrPasteResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/dropOrPasteResource.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/dropOrPasteResource.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/shared.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/shared.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/shared.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/shared.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/uriList.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/uriList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/uriList.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/dropOrPaste/uriList.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/node/cssClientMain.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/node/cssClientMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/node/cssClientMain.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/node/cssClientMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/node/nodeFs.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/node/nodeFs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/node/nodeFs.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/node/nodeFs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/requests.ts b/apps/review-desktop/code-oss/extensions/css-language-features/client/src/requests.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/src/requests.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/client/src/requests.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/css-language-features/client/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/css-language-features/client/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/tsconfig.json b/apps/review-desktop/code-oss/extensions/css-language-features/client/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/client/tsconfig.json rename to apps/review-desktop/code-oss/extensions/css-language-features/client/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/css-language-features/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/css-language-features/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/esbuild.mts b/apps/review-desktop/code-oss/extensions/css-language-features/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/esbuild.mts rename to apps/review-desktop/code-oss/extensions/css-language-features/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/icons/css.png b/apps/review-desktop/code-oss/extensions/css-language-features/icons/css.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/icons/css.png rename to apps/review-desktop/code-oss/extensions/css-language-features/icons/css.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/package-lock.json b/apps/review-desktop/code-oss/extensions/css-language-features/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/package-lock.json rename to apps/review-desktop/code-oss/extensions/css-language-features/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/package.json b/apps/review-desktop/code-oss/extensions/css-language-features/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/package.json rename to apps/review-desktop/code-oss/extensions/css-language-features/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/package.nls.json b/apps/review-desktop/code-oss/extensions/css-language-features/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/package.nls.json rename to apps/review-desktop/code-oss/extensions/css-language-features/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/schemas/package.schema.json b/apps/review-desktop/code-oss/extensions/css-language-features/schemas/package.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/schemas/package.schema.json rename to apps/review-desktop/code-oss/extensions/css-language-features/schemas/package.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/.npmrc b/apps/review-desktop/code-oss/extensions/css-language-features/server/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/.npmrc rename to apps/review-desktop/code-oss/extensions/css-language-features/server/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/package-lock.json b/apps/review-desktop/code-oss/extensions/css-language-features/server/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/package-lock.json rename to apps/review-desktop/code-oss/extensions/css-language-features/server/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/package.json b/apps/review-desktop/code-oss/extensions/css-language-features/server/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/package.json rename to apps/review-desktop/code-oss/extensions/css-language-features/server/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerMain.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerMain.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerWorkerMain.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerWorkerMain.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/browser/cssServerWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/cssServer.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/cssServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/cssServer.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/cssServer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/customData.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/customData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/customData.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/customData.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/languageModelCache.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/languageModelCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/languageModelCache.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/languageModelCache.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerMain.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerMain.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerNodeMain.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerNodeMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerNodeMain.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/node/cssServerNodeMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/node/nodeFs.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/node/nodeFs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/node/nodeFs.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/node/nodeFs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/requests.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/requests.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/requests.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/requests.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/test/completion.test.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/test/completion.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/test/completion.test.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/test/completion.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/test/links.test.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/test/links.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/test/links.test.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/test/links.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/documentContext.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/documentContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/documentContext.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/documentContext.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/runner.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/runner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/runner.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/runner.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/strings.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/strings.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/strings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/validation.ts b/apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/validation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/src/utils/validation.ts rename to apps/review-desktop/code-oss/extensions/css-language-features/server/src/utils/validation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/index.js b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/index.js rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/index.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/.gitignore b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/.gitignore rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/node_modules/foo/package.json b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/node_modules/foo/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/node_modules/foo/package.json rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/linksTestFixtures/node_modules/foo/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/.foo.js b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/.foo.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/.foo.js rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/.foo.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.css b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.css rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.html b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.html rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/about/about.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/index.html b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/index.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/index.html rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/index.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/_foo.scss diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/scss/main.scss diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/feature.js b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/feature.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/feature.js rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/feature.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/test.js b/apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/test.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/test.js rename to apps/review-desktop/code-oss/extensions/css-language-features/server/test/pathCompletionFixtures/src/test.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/css-language-features/server/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/css-language-features/server/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/tsconfig.json b/apps/review-desktop/code-oss/extensions/css-language-features/server/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css-language-features/server/tsconfig.json rename to apps/review-desktop/code-oss/extensions/css-language-features/server/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css/.vscodeignore b/apps/review-desktop/code-oss/extensions/css/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css/.vscodeignore rename to apps/review-desktop/code-oss/extensions/css/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/css/cgmanifest.json b/apps/review-desktop/code-oss/extensions/css/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/css/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css/language-configuration.json b/apps/review-desktop/code-oss/extensions/css/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css/language-configuration.json rename to apps/review-desktop/code-oss/extensions/css/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css/package.json b/apps/review-desktop/code-oss/extensions/css/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css/package.json rename to apps/review-desktop/code-oss/extensions/css/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css/package.nls.json b/apps/review-desktop/code-oss/extensions/css/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css/package.nls.json rename to apps/review-desktop/code-oss/extensions/css/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/css/syntaxes/css.tmLanguage.json b/apps/review-desktop/code-oss/extensions/css/syntaxes/css.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/css/syntaxes/css.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/css/syntaxes/css.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dart/.vscodeignore b/apps/review-desktop/code-oss/extensions/dart/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dart/.vscodeignore rename to apps/review-desktop/code-oss/extensions/dart/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/dart/cgmanifest.json b/apps/review-desktop/code-oss/extensions/dart/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dart/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/dart/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dart/language-configuration.json b/apps/review-desktop/code-oss/extensions/dart/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dart/language-configuration.json rename to apps/review-desktop/code-oss/extensions/dart/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dart/package.json b/apps/review-desktop/code-oss/extensions/dart/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dart/package.json rename to apps/review-desktop/code-oss/extensions/dart/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dart/package.nls.json b/apps/review-desktop/code-oss/extensions/dart/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dart/package.nls.json rename to apps/review-desktop/code-oss/extensions/dart/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dart/syntaxes/dart.tmLanguage.json b/apps/review-desktop/code-oss/extensions/dart/syntaxes/dart.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dart/syntaxes/dart.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/dart/syntaxes/dart.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/diff/.vscodeignore b/apps/review-desktop/code-oss/extensions/diff/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/diff/.vscodeignore rename to apps/review-desktop/code-oss/extensions/diff/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/diff/cgmanifest.json b/apps/review-desktop/code-oss/extensions/diff/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/diff/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/diff/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/diff/language-configuration.json b/apps/review-desktop/code-oss/extensions/diff/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/diff/language-configuration.json rename to apps/review-desktop/code-oss/extensions/diff/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/diff/package.json b/apps/review-desktop/code-oss/extensions/diff/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/diff/package.json rename to apps/review-desktop/code-oss/extensions/diff/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/diff/package.nls.json b/apps/review-desktop/code-oss/extensions/diff/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/diff/package.nls.json rename to apps/review-desktop/code-oss/extensions/diff/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/diff/syntaxes/diff.tmLanguage.json b/apps/review-desktop/code-oss/extensions/diff/syntaxes/diff.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/diff/syntaxes/diff.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/diff/syntaxes/diff.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/docker/.vscodeignore b/apps/review-desktop/code-oss/extensions/docker/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/docker/.vscodeignore rename to apps/review-desktop/code-oss/extensions/docker/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/docker/cgmanifest.json b/apps/review-desktop/code-oss/extensions/docker/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/docker/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/docker/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/docker/language-configuration.json b/apps/review-desktop/code-oss/extensions/docker/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/docker/language-configuration.json rename to apps/review-desktop/code-oss/extensions/docker/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/docker/package.json b/apps/review-desktop/code-oss/extensions/docker/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/docker/package.json rename to apps/review-desktop/code-oss/extensions/docker/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/docker/package.nls.json b/apps/review-desktop/code-oss/extensions/docker/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/docker/package.nls.json rename to apps/review-desktop/code-oss/extensions/docker/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/docker/syntaxes/docker.tmLanguage.json b/apps/review-desktop/code-oss/extensions/docker/syntaxes/docker.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/docker/syntaxes/docker.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/docker/syntaxes/docker.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dotenv/.vscodeignore b/apps/review-desktop/code-oss/extensions/dotenv/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dotenv/.vscodeignore rename to apps/review-desktop/code-oss/extensions/dotenv/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/dotenv/cgmanifest.json b/apps/review-desktop/code-oss/extensions/dotenv/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dotenv/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/dotenv/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dotenv/language-configuration.json b/apps/review-desktop/code-oss/extensions/dotenv/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dotenv/language-configuration.json rename to apps/review-desktop/code-oss/extensions/dotenv/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dotenv/package.json b/apps/review-desktop/code-oss/extensions/dotenv/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dotenv/package.json rename to apps/review-desktop/code-oss/extensions/dotenv/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dotenv/package.nls.json b/apps/review-desktop/code-oss/extensions/dotenv/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dotenv/package.nls.json rename to apps/review-desktop/code-oss/extensions/dotenv/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/dotenv/syntaxes/dotenv.tmLanguage.json b/apps/review-desktop/code-oss/extensions/dotenv/syntaxes/dotenv.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/dotenv/syntaxes/dotenv.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/dotenv/syntaxes/dotenv.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/esbuild-common.mts b/apps/review-desktop/code-oss/extensions/esbuild-common.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/esbuild-common.mts rename to apps/review-desktop/code-oss/extensions/esbuild-common.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/esbuild-extension-common.mts b/apps/review-desktop/code-oss/extensions/esbuild-extension-common.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/esbuild-extension-common.mts rename to apps/review-desktop/code-oss/extensions/esbuild-extension-common.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/esbuild-webview-common.mts b/apps/review-desktop/code-oss/extensions/esbuild-webview-common.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/esbuild-webview-common.mts rename to apps/review-desktop/code-oss/extensions/esbuild-webview-common.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/.vscodeignore b/apps/review-desktop/code-oss/extensions/fsharp/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/.vscodeignore rename to apps/review-desktop/code-oss/extensions/fsharp/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/cgmanifest.json b/apps/review-desktop/code-oss/extensions/fsharp/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/fsharp/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/language-configuration.json b/apps/review-desktop/code-oss/extensions/fsharp/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/language-configuration.json rename to apps/review-desktop/code-oss/extensions/fsharp/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/package.json b/apps/review-desktop/code-oss/extensions/fsharp/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/package.json rename to apps/review-desktop/code-oss/extensions/fsharp/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/package.nls.json b/apps/review-desktop/code-oss/extensions/fsharp/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/package.nls.json rename to apps/review-desktop/code-oss/extensions/fsharp/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/snippets/fsharp.code-snippets b/apps/review-desktop/code-oss/extensions/fsharp/snippets/fsharp.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/snippets/fsharp.code-snippets rename to apps/review-desktop/code-oss/extensions/fsharp/snippets/fsharp.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/fsharp/syntaxes/fsharp.tmLanguage.json b/apps/review-desktop/code-oss/extensions/fsharp/syntaxes/fsharp.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/fsharp/syntaxes/fsharp.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/fsharp/syntaxes/fsharp.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/.npmrc b/apps/review-desktop/code-oss/extensions/git-base/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/.npmrc rename to apps/review-desktop/code-oss/extensions/git-base/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/.vscodeignore b/apps/review-desktop/code-oss/extensions/git-base/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/.vscodeignore rename to apps/review-desktop/code-oss/extensions/git-base/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/README.md b/apps/review-desktop/code-oss/extensions/git-base/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/README.md rename to apps/review-desktop/code-oss/extensions/git-base/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/build/update-grammars.js b/apps/review-desktop/code-oss/extensions/git-base/build/update-grammars.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/build/update-grammars.js rename to apps/review-desktop/code-oss/extensions/git-base/build/update-grammars.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/cgmanifest.json b/apps/review-desktop/code-oss/extensions/git-base/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/git-base/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/git-base/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/git-base/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/esbuild.mts b/apps/review-desktop/code-oss/extensions/git-base/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/esbuild.mts rename to apps/review-desktop/code-oss/extensions/git-base/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/languages/git-commit.language-configuration.json b/apps/review-desktop/code-oss/extensions/git-base/languages/git-commit.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/languages/git-commit.language-configuration.json rename to apps/review-desktop/code-oss/extensions/git-base/languages/git-commit.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/languages/git-rebase.language-configuration.json b/apps/review-desktop/code-oss/extensions/git-base/languages/git-rebase.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/languages/git-rebase.language-configuration.json rename to apps/review-desktop/code-oss/extensions/git-base/languages/git-rebase.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/languages/ignore.language-configuration.json b/apps/review-desktop/code-oss/extensions/git-base/languages/ignore.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/languages/ignore.language-configuration.json rename to apps/review-desktop/code-oss/extensions/git-base/languages/ignore.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/package-lock.json b/apps/review-desktop/code-oss/extensions/git-base/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/package-lock.json rename to apps/review-desktop/code-oss/extensions/git-base/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/package.json b/apps/review-desktop/code-oss/extensions/git-base/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/package.json rename to apps/review-desktop/code-oss/extensions/git-base/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/package.nls.json b/apps/review-desktop/code-oss/extensions/git-base/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/package.nls.json rename to apps/review-desktop/code-oss/extensions/git-base/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/resources/icons/git.png b/apps/review-desktop/code-oss/extensions/git-base/resources/icons/git.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/resources/icons/git.png rename to apps/review-desktop/code-oss/extensions/git-base/resources/icons/git.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/api/api1.ts b/apps/review-desktop/code-oss/extensions/git-base/src/api/api1.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/api/api1.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/api/api1.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/api/extension.ts b/apps/review-desktop/code-oss/extensions/git-base/src/api/extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/api/extension.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/api/extension.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/api/git-base.d.ts b/apps/review-desktop/code-oss/extensions/git-base/src/api/git-base.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/api/git-base.d.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/api/git-base.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/decorators.ts b/apps/review-desktop/code-oss/extensions/git-base/src/decorators.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/decorators.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/decorators.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/extension.ts b/apps/review-desktop/code-oss/extensions/git-base/src/extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/extension.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/extension.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/foldingProvider.ts b/apps/review-desktop/code-oss/extensions/git-base/src/foldingProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/foldingProvider.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/foldingProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/model.ts b/apps/review-desktop/code-oss/extensions/git-base/src/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/model.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/model.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/remoteProvider.ts b/apps/review-desktop/code-oss/extensions/git-base/src/remoteProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/remoteProvider.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/remoteProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/remoteSource.ts b/apps/review-desktop/code-oss/extensions/git-base/src/remoteSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/remoteSource.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/remoteSource.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/test/foldingProvider.test.ts b/apps/review-desktop/code-oss/extensions/git-base/src/test/foldingProvider.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/test/foldingProvider.test.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/test/foldingProvider.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/src/util.ts b/apps/review-desktop/code-oss/extensions/git-base/src/util.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/src/util.ts rename to apps/review-desktop/code-oss/extensions/git-base/src/util.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/syntaxes/git-commit.tmLanguage.json b/apps/review-desktop/code-oss/extensions/git-base/syntaxes/git-commit.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/syntaxes/git-commit.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/git-base/syntaxes/git-commit.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/syntaxes/git-rebase.tmLanguage.json b/apps/review-desktop/code-oss/extensions/git-base/syntaxes/git-rebase.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/syntaxes/git-rebase.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/git-base/syntaxes/git-rebase.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/syntaxes/ignore.tmLanguage.json b/apps/review-desktop/code-oss/extensions/git-base/syntaxes/ignore.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/syntaxes/ignore.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/git-base/syntaxes/ignore.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/git-base/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/git-base/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/git-base/tsconfig.json b/apps/review-desktop/code-oss/extensions/git-base/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/git-base/tsconfig.json rename to apps/review-desktop/code-oss/extensions/git-base/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/go/.vscodeignore b/apps/review-desktop/code-oss/extensions/go/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/go/.vscodeignore rename to apps/review-desktop/code-oss/extensions/go/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/go/cgmanifest.json b/apps/review-desktop/code-oss/extensions/go/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/go/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/go/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/go/language-configuration.json b/apps/review-desktop/code-oss/extensions/go/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/go/language-configuration.json rename to apps/review-desktop/code-oss/extensions/go/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/go/package.json b/apps/review-desktop/code-oss/extensions/go/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/go/package.json rename to apps/review-desktop/code-oss/extensions/go/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/go/package.nls.json b/apps/review-desktop/code-oss/extensions/go/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/go/package.nls.json rename to apps/review-desktop/code-oss/extensions/go/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/go/syntaxes/go.tmLanguage.json b/apps/review-desktop/code-oss/extensions/go/syntaxes/go.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/go/syntaxes/go.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/go/syntaxes/go.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/.vscodeignore b/apps/review-desktop/code-oss/extensions/groovy/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/.vscodeignore rename to apps/review-desktop/code-oss/extensions/groovy/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/cgmanifest.json b/apps/review-desktop/code-oss/extensions/groovy/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/groovy/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/language-configuration.json b/apps/review-desktop/code-oss/extensions/groovy/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/language-configuration.json rename to apps/review-desktop/code-oss/extensions/groovy/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/package.json b/apps/review-desktop/code-oss/extensions/groovy/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/package.json rename to apps/review-desktop/code-oss/extensions/groovy/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/package.nls.json b/apps/review-desktop/code-oss/extensions/groovy/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/package.nls.json rename to apps/review-desktop/code-oss/extensions/groovy/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/snippets/groovy.code-snippets b/apps/review-desktop/code-oss/extensions/groovy/snippets/groovy.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/snippets/groovy.code-snippets rename to apps/review-desktop/code-oss/extensions/groovy/snippets/groovy.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/groovy/syntaxes/groovy.tmLanguage.json b/apps/review-desktop/code-oss/extensions/groovy/syntaxes/groovy.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/groovy/syntaxes/groovy.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/groovy/syntaxes/groovy.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/handlebars/.vscodeignore b/apps/review-desktop/code-oss/extensions/handlebars/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/handlebars/.vscodeignore rename to apps/review-desktop/code-oss/extensions/handlebars/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/handlebars/cgmanifest.json b/apps/review-desktop/code-oss/extensions/handlebars/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/handlebars/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/handlebars/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/handlebars/language-configuration.json b/apps/review-desktop/code-oss/extensions/handlebars/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/handlebars/language-configuration.json rename to apps/review-desktop/code-oss/extensions/handlebars/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/handlebars/package.json b/apps/review-desktop/code-oss/extensions/handlebars/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/handlebars/package.json rename to apps/review-desktop/code-oss/extensions/handlebars/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/handlebars/package.nls.json b/apps/review-desktop/code-oss/extensions/handlebars/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/handlebars/package.nls.json rename to apps/review-desktop/code-oss/extensions/handlebars/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json b/apps/review-desktop/code-oss/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/hlsl/.vscodeignore b/apps/review-desktop/code-oss/extensions/hlsl/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/hlsl/.vscodeignore rename to apps/review-desktop/code-oss/extensions/hlsl/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/hlsl/cgmanifest.json b/apps/review-desktop/code-oss/extensions/hlsl/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/hlsl/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/hlsl/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/hlsl/language-configuration.json b/apps/review-desktop/code-oss/extensions/hlsl/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/hlsl/language-configuration.json rename to apps/review-desktop/code-oss/extensions/hlsl/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/hlsl/package.json b/apps/review-desktop/code-oss/extensions/hlsl/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/hlsl/package.json rename to apps/review-desktop/code-oss/extensions/hlsl/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/hlsl/package.nls.json b/apps/review-desktop/code-oss/extensions/hlsl/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/hlsl/package.nls.json rename to apps/review-desktop/code-oss/extensions/hlsl/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/hlsl/syntaxes/hlsl.tmLanguage.json b/apps/review-desktop/code-oss/extensions/hlsl/syntaxes/hlsl.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/hlsl/syntaxes/hlsl.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/hlsl/syntaxes/hlsl.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/.npmrc b/apps/review-desktop/code-oss/extensions/html-language-features/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/.npmrc rename to apps/review-desktop/code-oss/extensions/html-language-features/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/.vscodeignore b/apps/review-desktop/code-oss/extensions/html-language-features/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/.vscodeignore rename to apps/review-desktop/code-oss/extensions/html-language-features/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/CONTRIBUTING.md b/apps/review-desktop/code-oss/extensions/html-language-features/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/CONTRIBUTING.md rename to apps/review-desktop/code-oss/extensions/html-language-features/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/README.md b/apps/review-desktop/code-oss/extensions/html-language-features/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/README.md rename to apps/review-desktop/code-oss/extensions/html-language-features/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/build/bundleTypeScriptLibraries.js b/apps/review-desktop/code-oss/extensions/html-language-features/build/bundleTypeScriptLibraries.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/build/bundleTypeScriptLibraries.js rename to apps/review-desktop/code-oss/extensions/html-language-features/build/bundleTypeScriptLibraries.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/cgmanifest.json b/apps/review-desktop/code-oss/extensions/html-language-features/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/html-language-features/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/autoInsertion.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/autoInsertion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/autoInsertion.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/autoInsertion.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/browser/htmlClientMain.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/browser/htmlClientMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/browser/htmlClientMain.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/browser/htmlClientMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/customData.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/customData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/customData.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/customData.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/htmlClient.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/htmlClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/htmlClient.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/htmlClient.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/languageParticipants.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/languageParticipants.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/languageParticipants.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/languageParticipants.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/node/htmlClientMain.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/node/htmlClientMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/node/htmlClientMain.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/node/htmlClientMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/node/nodeFs.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/node/nodeFs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/node/nodeFs.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/node/nodeFs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/requests.ts b/apps/review-desktop/code-oss/extensions/html-language-features/client/src/requests.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/src/requests.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/client/src/requests.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/html-language-features/client/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/html-language-features/client/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/tsconfig.json b/apps/review-desktop/code-oss/extensions/html-language-features/client/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/client/tsconfig.json rename to apps/review-desktop/code-oss/extensions/html-language-features/client/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/html-language-features/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/html-language-features/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/esbuild.mts b/apps/review-desktop/code-oss/extensions/html-language-features/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/esbuild.mts rename to apps/review-desktop/code-oss/extensions/html-language-features/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/icons/html.png b/apps/review-desktop/code-oss/extensions/html-language-features/icons/html.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/icons/html.png rename to apps/review-desktop/code-oss/extensions/html-language-features/icons/html.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/package-lock.json b/apps/review-desktop/code-oss/extensions/html-language-features/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/package-lock.json rename to apps/review-desktop/code-oss/extensions/html-language-features/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/package.json b/apps/review-desktop/code-oss/extensions/html-language-features/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/package.json rename to apps/review-desktop/code-oss/extensions/html-language-features/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/package.nls.json b/apps/review-desktop/code-oss/extensions/html-language-features/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/package.nls.json rename to apps/review-desktop/code-oss/extensions/html-language-features/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/schemas/package.schema.json b/apps/review-desktop/code-oss/extensions/html-language-features/schemas/package.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/schemas/package.schema.json rename to apps/review-desktop/code-oss/extensions/html-language-features/schemas/package.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/.npmrc b/apps/review-desktop/code-oss/extensions/html-language-features/server/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/.npmrc rename to apps/review-desktop/code-oss/extensions/html-language-features/server/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/lib/cgmanifest.json b/apps/review-desktop/code-oss/extensions/html-language-features/server/lib/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/lib/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/html-language-features/server/lib/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/lib/jquery.d.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/lib/jquery.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/lib/jquery.d.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/lib/jquery.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/package-lock.json b/apps/review-desktop/code-oss/extensions/html-language-features/server/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/package-lock.json rename to apps/review-desktop/code-oss/extensions/html-language-features/server/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/package.json b/apps/review-desktop/code-oss/extensions/html-language-features/server/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/package.json rename to apps/review-desktop/code-oss/extensions/html-language-features/server/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerMain.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerMain.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerWorkerMain.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerWorkerMain.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/browser/htmlServerWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/customData.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/customData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/customData.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/customData.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/htmlServer.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/htmlServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/htmlServer.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/htmlServer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/languageModelCache.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/languageModelCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/languageModelCache.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/languageModelCache.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/cssMode.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/cssMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/cssMode.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/cssMode.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/embeddedSupport.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/embeddedSupport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/embeddedSupport.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/embeddedSupport.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/formatting.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/formatting.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/formatting.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/formatting.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlFolding.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlFolding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlFolding.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlFolding.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlMode.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlMode.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/htmlMode.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptLibs.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptLibs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptLibs.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptLibs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptMode.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptMode.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptMode.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptSemanticTokens.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptSemanticTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptSemanticTokens.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/javascriptSemanticTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/languageModes.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/languageModes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/languageModes.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/languageModes.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/selectionRanges.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/selectionRanges.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/selectionRanges.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/selectionRanges.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/semanticTokens.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/semanticTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/modes/semanticTokens.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/modes/semanticTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerMain.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerMain.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerNodeMain.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerNodeMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerNodeMain.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/node/htmlServerNodeMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/node/nodeFs.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/node/nodeFs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/node/nodeFs.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/node/nodeFs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/requests.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/requests.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/requests.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/requests.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/completions.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/completions.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/completions.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/completions.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/documentContext.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/documentContext.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/documentContext.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/documentContext.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/embedded.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/embedded.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/embedded.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/embedded.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-4spaces.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-4spaces.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-4spaces.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-4spaces.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-tab.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-tab.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-tab.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813-tab.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/19813.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/21634.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/21634.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/21634.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/expected/21634.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/19813.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/19813.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/19813.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/19813.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/21634.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/21634.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/21634.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/fixtures/inputs/21634.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/folding.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/folding.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/folding.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/folding.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/formatting.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/formatting.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/formatting.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/formatting.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/hover.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/hover.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/hover.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/hover.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/.foo.js b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/.foo.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/.foo.js rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/.foo.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.css b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.css rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/about.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/media/icon.pic b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/media/icon.pic similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/media/icon.pic rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/about/media/icon.pic diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/index.html b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/index.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/index.html rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/index.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/feature.js b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/feature.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/feature.js rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/feature.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/test.js b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/test.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/test.js rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/pathCompletionFixtures/src/test.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/rename.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/rename.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/rename.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/rename.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/selectionRanges.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/selectionRanges.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/selectionRanges.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/selectionRanges.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/semanticTokens.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/semanticTokens.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/semanticTokens.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/semanticTokens.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/words.test.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/words.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/test/words.test.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/test/words.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/arrays.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/arrays.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/arrays.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/arrays.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/documentContext.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/documentContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/documentContext.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/documentContext.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/positions.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/positions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/positions.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/positions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/runner.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/runner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/runner.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/runner.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/strings.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/strings.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/strings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/validation.ts b/apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/validation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/src/utils/validation.ts rename to apps/review-desktop/code-oss/extensions/html-language-features/server/src/utils/validation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/test/index.js b/apps/review-desktop/code-oss/extensions/html-language-features/server/test/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/test/index.js rename to apps/review-desktop/code-oss/extensions/html-language-features/server/test/index.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/html-language-features/server/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/html-language-features/server/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/tsconfig.json b/apps/review-desktop/code-oss/extensions/html-language-features/server/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html-language-features/server/tsconfig.json rename to apps/review-desktop/code-oss/extensions/html-language-features/server/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/.vscodeignore b/apps/review-desktop/code-oss/extensions/html/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/.vscodeignore rename to apps/review-desktop/code-oss/extensions/html/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/build/update-grammar.mjs b/apps/review-desktop/code-oss/extensions/html/build/update-grammar.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/build/update-grammar.mjs rename to apps/review-desktop/code-oss/extensions/html/build/update-grammar.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/cgmanifest.json b/apps/review-desktop/code-oss/extensions/html/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/html/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/language-configuration.json b/apps/review-desktop/code-oss/extensions/html/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/language-configuration.json rename to apps/review-desktop/code-oss/extensions/html/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/package.json b/apps/review-desktop/code-oss/extensions/html/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/package.json rename to apps/review-desktop/code-oss/extensions/html/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/package.nls.json b/apps/review-desktop/code-oss/extensions/html/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/package.nls.json rename to apps/review-desktop/code-oss/extensions/html/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/snippets/html.code-snippets b/apps/review-desktop/code-oss/extensions/html/snippets/html.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/snippets/html.code-snippets rename to apps/review-desktop/code-oss/extensions/html/snippets/html.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/syntaxes/html-derivative.tmLanguage.json b/apps/review-desktop/code-oss/extensions/html/syntaxes/html-derivative.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/syntaxes/html-derivative.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/html/syntaxes/html-derivative.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/html/syntaxes/html.tmLanguage.json b/apps/review-desktop/code-oss/extensions/html/syntaxes/html.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/html/syntaxes/html.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/html/syntaxes/html.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/.vscodeignore b/apps/review-desktop/code-oss/extensions/ini/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/.vscodeignore rename to apps/review-desktop/code-oss/extensions/ini/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/cgmanifest.json b/apps/review-desktop/code-oss/extensions/ini/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/ini/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/ini.language-configuration.json b/apps/review-desktop/code-oss/extensions/ini/ini.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/ini.language-configuration.json rename to apps/review-desktop/code-oss/extensions/ini/ini.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/package.json b/apps/review-desktop/code-oss/extensions/ini/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/package.json rename to apps/review-desktop/code-oss/extensions/ini/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/package.nls.json b/apps/review-desktop/code-oss/extensions/ini/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/package.nls.json rename to apps/review-desktop/code-oss/extensions/ini/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/properties.language-configuration.json b/apps/review-desktop/code-oss/extensions/ini/properties.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/properties.language-configuration.json rename to apps/review-desktop/code-oss/extensions/ini/properties.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ini/syntaxes/ini.tmLanguage.json b/apps/review-desktop/code-oss/extensions/ini/syntaxes/ini.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ini/syntaxes/ini.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/ini/syntaxes/ini.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/.vscodeignore b/apps/review-desktop/code-oss/extensions/java/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/.vscodeignore rename to apps/review-desktop/code-oss/extensions/java/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/cgmanifest.json b/apps/review-desktop/code-oss/extensions/java/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/java/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/language-configuration.json b/apps/review-desktop/code-oss/extensions/java/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/language-configuration.json rename to apps/review-desktop/code-oss/extensions/java/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/package.json b/apps/review-desktop/code-oss/extensions/java/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/package.json rename to apps/review-desktop/code-oss/extensions/java/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/package.nls.json b/apps/review-desktop/code-oss/extensions/java/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/package.nls.json rename to apps/review-desktop/code-oss/extensions/java/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/snippets/java.code-snippets b/apps/review-desktop/code-oss/extensions/java/snippets/java.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/snippets/java.code-snippets rename to apps/review-desktop/code-oss/extensions/java/snippets/java.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/java/syntaxes/java.tmLanguage.json b/apps/review-desktop/code-oss/extensions/java/syntaxes/java.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/java/syntaxes/java.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/java/syntaxes/java.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/.vscodeignore b/apps/review-desktop/code-oss/extensions/javascript/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/.vscodeignore rename to apps/review-desktop/code-oss/extensions/javascript/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/cgmanifest.json b/apps/review-desktop/code-oss/extensions/javascript/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/javascript/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/javascript-language-configuration.json b/apps/review-desktop/code-oss/extensions/javascript/javascript-language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/javascript-language-configuration.json rename to apps/review-desktop/code-oss/extensions/javascript/javascript-language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/package.json b/apps/review-desktop/code-oss/extensions/javascript/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/package.json rename to apps/review-desktop/code-oss/extensions/javascript/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/package.nls.json b/apps/review-desktop/code-oss/extensions/javascript/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/package.nls.json rename to apps/review-desktop/code-oss/extensions/javascript/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/snippets/javascript.code-snippets b/apps/review-desktop/code-oss/extensions/javascript/snippets/javascript.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/snippets/javascript.code-snippets rename to apps/review-desktop/code-oss/extensions/javascript/snippets/javascript.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/apps/review-desktop/code-oss/extensions/javascript/syntaxes/JavaScript.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/JavaScript.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/javascript/syntaxes/JavaScript.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/apps/review-desktop/code-oss/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/Readme.md b/apps/review-desktop/code-oss/extensions/javascript/syntaxes/Readme.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/Readme.md rename to apps/review-desktop/code-oss/extensions/javascript/syntaxes/Readme.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/Regular Expressions (JavaScript).tmLanguage b/apps/review-desktop/code-oss/extensions/javascript/syntaxes/Regular Expressions (JavaScript).tmLanguage similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/syntaxes/Regular Expressions (JavaScript).tmLanguage rename to apps/review-desktop/code-oss/extensions/javascript/syntaxes/Regular Expressions (JavaScript).tmLanguage diff --git a/apps/whiteboard-desktop/code-oss/extensions/javascript/tags-language-configuration.json b/apps/review-desktop/code-oss/extensions/javascript/tags-language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/javascript/tags-language-configuration.json rename to apps/review-desktop/code-oss/extensions/javascript/tags-language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/.npmrc b/apps/review-desktop/code-oss/extensions/json-language-features/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/.npmrc rename to apps/review-desktop/code-oss/extensions/json-language-features/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/.vscodeignore b/apps/review-desktop/code-oss/extensions/json-language-features/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/.vscodeignore rename to apps/review-desktop/code-oss/extensions/json-language-features/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/CONTRIBUTING.md b/apps/review-desktop/code-oss/extensions/json-language-features/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/CONTRIBUTING.md rename to apps/review-desktop/code-oss/extensions/json-language-features/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/README.md b/apps/review-desktop/code-oss/extensions/json-language-features/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/README.md rename to apps/review-desktop/code-oss/extensions/json-language-features/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/browser/jsonClientMain.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/browser/jsonClientMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/browser/jsonClientMain.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/browser/jsonClientMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/jsonClient.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/jsonClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/jsonClient.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/jsonClient.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/languageParticipants.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/languageParticipants.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/languageParticipants.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/languageParticipants.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/languageStatus.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/languageStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/languageStatus.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/languageStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/node/jsonClientMain.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/node/jsonClientMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/node/jsonClientMain.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/node/jsonClientMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/node/schemaCache.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/node/schemaCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/node/schemaCache.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/node/schemaCache.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/utils/hash.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/utils/hash.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/utils/hash.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/utils/hash.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/utils/urlMatch.ts b/apps/review-desktop/code-oss/extensions/json-language-features/client/src/utils/urlMatch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/src/utils/urlMatch.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/client/src/utils/urlMatch.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/json-language-features/client/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/json-language-features/client/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/tsconfig.json b/apps/review-desktop/code-oss/extensions/json-language-features/client/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/client/tsconfig.json rename to apps/review-desktop/code-oss/extensions/json-language-features/client/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/json-language-features/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/json-language-features/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/esbuild.mts b/apps/review-desktop/code-oss/extensions/json-language-features/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/esbuild.mts rename to apps/review-desktop/code-oss/extensions/json-language-features/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/icons/json.png b/apps/review-desktop/code-oss/extensions/json-language-features/icons/json.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/icons/json.png rename to apps/review-desktop/code-oss/extensions/json-language-features/icons/json.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/package-lock.json b/apps/review-desktop/code-oss/extensions/json-language-features/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/package-lock.json rename to apps/review-desktop/code-oss/extensions/json-language-features/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/package.json b/apps/review-desktop/code-oss/extensions/json-language-features/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/package.json rename to apps/review-desktop/code-oss/extensions/json-language-features/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/package.nls.json b/apps/review-desktop/code-oss/extensions/json-language-features/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/package.nls.json rename to apps/review-desktop/code-oss/extensions/json-language-features/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/.npmignore b/apps/review-desktop/code-oss/extensions/json-language-features/server/.npmignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/.npmignore rename to apps/review-desktop/code-oss/extensions/json-language-features/server/.npmignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/.npmrc b/apps/review-desktop/code-oss/extensions/json-language-features/server/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/.npmrc rename to apps/review-desktop/code-oss/extensions/json-language-features/server/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/README.md b/apps/review-desktop/code-oss/extensions/json-language-features/server/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/README.md rename to apps/review-desktop/code-oss/extensions/json-language-features/server/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/bin/vscode-json-languageserver b/apps/review-desktop/code-oss/extensions/json-language-features/server/bin/vscode-json-languageserver similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/bin/vscode-json-languageserver rename to apps/review-desktop/code-oss/extensions/json-language-features/server/bin/vscode-json-languageserver diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/package-lock.json b/apps/review-desktop/code-oss/extensions/json-language-features/server/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/package-lock.json rename to apps/review-desktop/code-oss/extensions/json-language-features/server/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/package.json b/apps/review-desktop/code-oss/extensions/json-language-features/server/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/package.json rename to apps/review-desktop/code-oss/extensions/json-language-features/server/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerMain.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerMain.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerWorkerMain.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerWorkerMain.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/browser/jsonServerWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/jsonServer.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/jsonServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/jsonServer.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/jsonServer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/languageModelCache.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/languageModelCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/languageModelCache.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/languageModelCache.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerMain.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerMain.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerNodeMain.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerNodeMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerNodeMain.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/node/jsonServerNodeMain.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/utils/runner.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/utils/runner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/utils/runner.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/utils/runner.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/utils/strings.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/utils/strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/utils/strings.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/utils/strings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/utils/validation.ts b/apps/review-desktop/code-oss/extensions/json-language-features/server/src/utils/validation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/src/utils/validation.ts rename to apps/review-desktop/code-oss/extensions/json-language-features/server/src/utils/validation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/json-language-features/server/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/json-language-features/server/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/tsconfig.json b/apps/review-desktop/code-oss/extensions/json-language-features/server/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json-language-features/server/tsconfig.json rename to apps/review-desktop/code-oss/extensions/json-language-features/server/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/.vscodeignore b/apps/review-desktop/code-oss/extensions/json/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/.vscodeignore rename to apps/review-desktop/code-oss/extensions/json/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/build/update-grammars.js b/apps/review-desktop/code-oss/extensions/json/build/update-grammars.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/build/update-grammars.js rename to apps/review-desktop/code-oss/extensions/json/build/update-grammars.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/cgmanifest.json b/apps/review-desktop/code-oss/extensions/json/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/json/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/language-configuration.json b/apps/review-desktop/code-oss/extensions/json/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/language-configuration.json rename to apps/review-desktop/code-oss/extensions/json/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/package.json b/apps/review-desktop/code-oss/extensions/json/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/package.json rename to apps/review-desktop/code-oss/extensions/json/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/package.nls.json b/apps/review-desktop/code-oss/extensions/json/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/package.nls.json rename to apps/review-desktop/code-oss/extensions/json/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/JSON.tmLanguage.json b/apps/review-desktop/code-oss/extensions/json/syntaxes/JSON.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/JSON.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/json/syntaxes/JSON.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/JSONC.tmLanguage.json b/apps/review-desktop/code-oss/extensions/json/syntaxes/JSONC.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/JSONC.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/json/syntaxes/JSONC.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/JSONL.tmLanguage.json b/apps/review-desktop/code-oss/extensions/json/syntaxes/JSONL.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/JSONL.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/json/syntaxes/JSONL.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/snippets.tmLanguage.json b/apps/review-desktop/code-oss/extensions/json/syntaxes/snippets.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/json/syntaxes/snippets.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/json/syntaxes/snippets.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/julia/.vscodeignore b/apps/review-desktop/code-oss/extensions/julia/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/julia/.vscodeignore rename to apps/review-desktop/code-oss/extensions/julia/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/julia/cgmanifest.json b/apps/review-desktop/code-oss/extensions/julia/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/julia/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/julia/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/julia/language-configuration.json b/apps/review-desktop/code-oss/extensions/julia/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/julia/language-configuration.json rename to apps/review-desktop/code-oss/extensions/julia/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/julia/package.json b/apps/review-desktop/code-oss/extensions/julia/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/julia/package.json rename to apps/review-desktop/code-oss/extensions/julia/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/julia/package.nls.json b/apps/review-desktop/code-oss/extensions/julia/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/julia/package.nls.json rename to apps/review-desktop/code-oss/extensions/julia/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/julia/syntaxes/julia.tmLanguage.json b/apps/review-desktop/code-oss/extensions/julia/syntaxes/julia.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/julia/syntaxes/julia.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/julia/syntaxes/julia.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/.vscodeignore b/apps/review-desktop/code-oss/extensions/latex/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/.vscodeignore rename to apps/review-desktop/code-oss/extensions/latex/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/build/update-grammars.js b/apps/review-desktop/code-oss/extensions/latex/build/update-grammars.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/build/update-grammars.js rename to apps/review-desktop/code-oss/extensions/latex/build/update-grammars.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/cgmanifest.json b/apps/review-desktop/code-oss/extensions/latex/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/latex/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/cpp-bailout-license.txt b/apps/review-desktop/code-oss/extensions/latex/cpp-bailout-license.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/cpp-bailout-license.txt rename to apps/review-desktop/code-oss/extensions/latex/cpp-bailout-license.txt diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/latex-cpp-embedded-language-configuration.json b/apps/review-desktop/code-oss/extensions/latex/latex-cpp-embedded-language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/latex-cpp-embedded-language-configuration.json rename to apps/review-desktop/code-oss/extensions/latex/latex-cpp-embedded-language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/latex-language-configuration.json b/apps/review-desktop/code-oss/extensions/latex/latex-language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/latex-language-configuration.json rename to apps/review-desktop/code-oss/extensions/latex/latex-language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/markdown-latex-combined-language-configuration.json b/apps/review-desktop/code-oss/extensions/latex/markdown-latex-combined-language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/markdown-latex-combined-language-configuration.json rename to apps/review-desktop/code-oss/extensions/latex/markdown-latex-combined-language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/markdown-latex-combined-license.txt b/apps/review-desktop/code-oss/extensions/latex/markdown-latex-combined-license.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/markdown-latex-combined-license.txt rename to apps/review-desktop/code-oss/extensions/latex/markdown-latex-combined-license.txt diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/package.json b/apps/review-desktop/code-oss/extensions/latex/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/package.json rename to apps/review-desktop/code-oss/extensions/latex/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/package.nls.json b/apps/review-desktop/code-oss/extensions/latex/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/package.nls.json rename to apps/review-desktop/code-oss/extensions/latex/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/Bibtex.tmLanguage.json b/apps/review-desktop/code-oss/extensions/latex/syntaxes/Bibtex.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/Bibtex.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/latex/syntaxes/Bibtex.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/LaTeX.tmLanguage.json b/apps/review-desktop/code-oss/extensions/latex/syntaxes/LaTeX.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/LaTeX.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/latex/syntaxes/LaTeX.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/TeX.tmLanguage.json b/apps/review-desktop/code-oss/extensions/latex/syntaxes/TeX.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/TeX.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/latex/syntaxes/TeX.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/cpp-grammar-bailout.tmLanguage.json b/apps/review-desktop/code-oss/extensions/latex/syntaxes/cpp-grammar-bailout.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/cpp-grammar-bailout.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/latex/syntaxes/cpp-grammar-bailout.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/markdown-latex-combined.tmLanguage.json b/apps/review-desktop/code-oss/extensions/latex/syntaxes/markdown-latex-combined.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/latex/syntaxes/markdown-latex-combined.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/latex/syntaxes/markdown-latex-combined.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/.vscodeignore b/apps/review-desktop/code-oss/extensions/less/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/.vscodeignore rename to apps/review-desktop/code-oss/extensions/less/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/build/update-grammar.js b/apps/review-desktop/code-oss/extensions/less/build/update-grammar.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/build/update-grammar.js rename to apps/review-desktop/code-oss/extensions/less/build/update-grammar.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/cgmanifest.json b/apps/review-desktop/code-oss/extensions/less/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/less/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/language-configuration.json b/apps/review-desktop/code-oss/extensions/less/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/language-configuration.json rename to apps/review-desktop/code-oss/extensions/less/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/package.json b/apps/review-desktop/code-oss/extensions/less/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/package.json rename to apps/review-desktop/code-oss/extensions/less/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/package.nls.json b/apps/review-desktop/code-oss/extensions/less/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/package.nls.json rename to apps/review-desktop/code-oss/extensions/less/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/less/syntaxes/less.tmLanguage.json b/apps/review-desktop/code-oss/extensions/less/syntaxes/less.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/less/syntaxes/less.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/less/syntaxes/less.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/log/.vscodeignore b/apps/review-desktop/code-oss/extensions/log/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/log/.vscodeignore rename to apps/review-desktop/code-oss/extensions/log/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/log/cgmanifest.json b/apps/review-desktop/code-oss/extensions/log/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/log/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/log/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/log/package.json b/apps/review-desktop/code-oss/extensions/log/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/log/package.json rename to apps/review-desktop/code-oss/extensions/log/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/log/package.nls.json b/apps/review-desktop/code-oss/extensions/log/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/log/package.nls.json rename to apps/review-desktop/code-oss/extensions/log/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/log/syntaxes/log.tmLanguage.json b/apps/review-desktop/code-oss/extensions/log/syntaxes/log.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/log/syntaxes/log.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/log/syntaxes/log.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/lua/.vscodeignore b/apps/review-desktop/code-oss/extensions/lua/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/lua/.vscodeignore rename to apps/review-desktop/code-oss/extensions/lua/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/lua/cgmanifest.json b/apps/review-desktop/code-oss/extensions/lua/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/lua/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/lua/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/lua/language-configuration.json b/apps/review-desktop/code-oss/extensions/lua/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/lua/language-configuration.json rename to apps/review-desktop/code-oss/extensions/lua/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/lua/package.json b/apps/review-desktop/code-oss/extensions/lua/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/lua/package.json rename to apps/review-desktop/code-oss/extensions/lua/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/lua/package.nls.json b/apps/review-desktop/code-oss/extensions/lua/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/lua/package.nls.json rename to apps/review-desktop/code-oss/extensions/lua/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/lua/syntaxes/lua.tmLanguage.json b/apps/review-desktop/code-oss/extensions/lua/syntaxes/lua.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/lua/syntaxes/lua.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/lua/syntaxes/lua.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/make/.vscodeignore b/apps/review-desktop/code-oss/extensions/make/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/make/.vscodeignore rename to apps/review-desktop/code-oss/extensions/make/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/make/cgmanifest.json b/apps/review-desktop/code-oss/extensions/make/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/make/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/make/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/make/language-configuration.json b/apps/review-desktop/code-oss/extensions/make/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/make/language-configuration.json rename to apps/review-desktop/code-oss/extensions/make/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/make/package.json b/apps/review-desktop/code-oss/extensions/make/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/make/package.json rename to apps/review-desktop/code-oss/extensions/make/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/make/package.nls.json b/apps/review-desktop/code-oss/extensions/make/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/make/package.nls.json rename to apps/review-desktop/code-oss/extensions/make/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/make/syntaxes/make.tmLanguage.json b/apps/review-desktop/code-oss/extensions/make/syntaxes/make.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/make/syntaxes/make.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/make/syntaxes/make.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/.vscodeignore b/apps/review-desktop/code-oss/extensions/markdown-basics/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/.vscodeignore rename to apps/review-desktop/code-oss/extensions/markdown-basics/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/cgmanifest.json b/apps/review-desktop/code-oss/extensions/markdown-basics/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/markdown-basics/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/language-configuration.json b/apps/review-desktop/code-oss/extensions/markdown-basics/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/language-configuration.json rename to apps/review-desktop/code-oss/extensions/markdown-basics/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/package.json b/apps/review-desktop/code-oss/extensions/markdown-basics/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/package.json rename to apps/review-desktop/code-oss/extensions/markdown-basics/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/package.nls.json b/apps/review-desktop/code-oss/extensions/markdown-basics/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/package.nls.json rename to apps/review-desktop/code-oss/extensions/markdown-basics/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/snippets/markdown.code-snippets b/apps/review-desktop/code-oss/extensions/markdown-basics/snippets/markdown.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/snippets/markdown.code-snippets rename to apps/review-desktop/code-oss/extensions/markdown-basics/snippets/markdown.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/apps/review-desktop/code-oss/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/.gitignore b/apps/review-desktop/code-oss/extensions/markdown-language-features/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/.gitignore rename to apps/review-desktop/code-oss/extensions/markdown-language-features/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/.npmrc b/apps/review-desktop/code-oss/extensions/markdown-language-features/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/.npmrc rename to apps/review-desktop/code-oss/extensions/markdown-language-features/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/.vscodeignore b/apps/review-desktop/code-oss/extensions/markdown-language-features/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/.vscodeignore rename to apps/review-desktop/code-oss/extensions/markdown-language-features/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/CONTRIBUTING.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/CONTRIBUTING.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/README.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/README.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.markdownEditor.mts b/apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.markdownEditor.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.markdownEditor.mts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.markdownEditor.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.mts b/apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.mts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.notebook.mts b/apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.notebook.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.notebook.mts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.notebook.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.webview.mts b/apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.webview.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/esbuild.webview.mts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/esbuild.webview.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/icon.png b/apps/review-desktop/code-oss/extensions/markdown-language-features/icon.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/icon.png rename to apps/review-desktop/code-oss/extensions/markdown-language-features/icon.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/declarations.d.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/declarations.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/declarations.d.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/declarations.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/editor.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/editor.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/markdownEditor.css b/apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/markdownEditor.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/markdownEditor.css rename to apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/markdownEditor.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/syntaxHighlighter.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/syntaxHighlighter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/syntaxHighlighter.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/syntaxHighlighter.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/tsconfig.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/tsconfig.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/markdown-editor-src/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/highlight.css b/apps/review-desktop/code-oss/extensions/markdown-language-features/media/highlight.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/highlight.css rename to apps/review-desktop/code-oss/extensions/markdown-language-features/media/highlight.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/markdown.css b/apps/review-desktop/code-oss/extensions/markdown-language-features/media/markdown.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/markdown.css rename to apps/review-desktop/code-oss/extensions/markdown-language-features/media/markdown.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/preview-dark.svg b/apps/review-desktop/code-oss/extensions/markdown-language-features/media/preview-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/preview-dark.svg rename to apps/review-desktop/code-oss/extensions/markdown-language-features/media/preview-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/preview-light.svg b/apps/review-desktop/code-oss/extensions/markdown-language-features/media/preview-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/media/preview-light.svg rename to apps/review-desktop/code-oss/extensions/markdown-language-features/media/preview-light.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/notebook/index.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/notebook/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/notebook/index.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/notebook/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/notebook/tsconfig.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/notebook/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/notebook/tsconfig.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/notebook/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/package-lock.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/package-lock.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/package.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/package.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/package.nls.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/package.nls.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/activeLineMarker.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/activeLineMarker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/activeLineMarker.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/activeLineMarker.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/csp.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/csp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/csp.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/csp.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/diffScrollSync.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/diffScrollSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/diffScrollSync.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/diffScrollSync.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/events.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/events.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/events.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/events.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/index.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/index.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/loading.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/loading.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/loading.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/loading.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/messaging.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/messaging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/messaging.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/messaging.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/pre.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/pre.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/pre.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/pre.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/scroll-sync.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/scroll-sync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/scroll-sync.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/scroll-sync.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/settings.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/settings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/settings.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/settings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/strings.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/strings.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/strings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/tsconfig.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/preview-src/tsconfig.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/preview-src/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/schemas/package.schema.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/schemas/package.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/schemas/package.schema.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/schemas/package.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/client.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/client.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/client.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/client.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/fileWatchingManager.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/fileWatchingManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/fileWatchingManager.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/fileWatchingManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/inMemoryDocument.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/inMemoryDocument.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/inMemoryDocument.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/inMemoryDocument.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/protocol.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/protocol.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/workspace.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/workspace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/client/workspace.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/client/workspace.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commandManager.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commandManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commandManager.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commandManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/copyImage.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/copyImage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/copyImage.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/copyImage.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/index.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/index.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/insertResource.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/insertResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/insertResource.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/insertResource.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/openFrontMatterSettings.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/openFrontMatterSettings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/openFrontMatterSettings.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/openFrontMatterSettings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/openImage.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/openImage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/openImage.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/openImage.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/refreshPreview.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/refreshPreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/refreshPreview.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/refreshPreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/reloadPlugins.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/reloadPlugins.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/reloadPlugins.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/reloadPlugins.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/renderDocument.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/renderDocument.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/renderDocument.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/renderDocument.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/reopenAsPreview.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/reopenAsPreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/reopenAsPreview.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/reopenAsPreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreview.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreview.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreviewSecuritySelector.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreviewSecuritySelector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreviewSecuritySelector.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/showPreviewSecuritySelector.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/showSource.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/showSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/showSource.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/showSource.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/toggleLock.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/toggleLock.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/commands/toggleLock.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/commands/toggleLock.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extension.browser.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/extension.browser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extension.browser.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/extension.browser.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extension.shared.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/extension.shared.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extension.shared.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/extension.shared.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extension.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extension.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/extension.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extensions/yamlPreamble/yamlPreamble.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/extensions/yamlPreamble/yamlPreamble.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/extensions/yamlPreamble/yamlPreamble.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/extensions/yamlPreamble/yamlPreamble.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/copyFiles.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropOrPasteResource.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropOrPasteResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropOrPasteResource.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/dropOrPasteResource.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/newFilePathGenerator.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/newFilePathGenerator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/newFilePathGenerator.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/newFilePathGenerator.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/pasteUrlProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/smartDropOrPaste.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/smartDropOrPaste.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/smartDropOrPaste.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/smartDropOrPaste.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/snippets.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/snippets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/snippets.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/copyFiles/snippets.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/linkUpdater.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/updateLinksOnPaste.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/updateLinksOnPaste.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/updateLinksOnPaste.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/languageFeatures/updateLinksOnPaste.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/logging.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/logging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/logging.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/logging.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/markdownEngine.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/markdownEngine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/markdownEngine.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/markdownEngine.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/markdownExtensions.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/markdownExtensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/markdownExtensions.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/markdownExtensions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/documentRenderer.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/documentRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/documentRenderer.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/documentRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/lineDiff.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/lineDiff.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/lineDiff.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/lineDiff.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/markdownEditorProvider.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/markdownEditorProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/markdownEditorProvider.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/markdownEditorProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/preview.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/preview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/preview.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/preview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/previewConfig.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/previewConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/previewConfig.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/previewConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/previewManager.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/previewManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/previewManager.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/previewManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/renderedDiffWarning.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/renderedDiffWarning.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/renderedDiffWarning.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/renderedDiffWarning.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/scrolling.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/scrolling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/scrolling.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/scrolling.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/security.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/security.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/security.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/security.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/slugify.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/slugify.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/slugify.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/slugify.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/telemetryReporter.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/telemetryReporter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/telemetryReporter.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/telemetryReporter.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/copyFile.test.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/copyFile.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/copyFile.test.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/copyFile.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/documentLink.test.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/documentLink.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/documentLink.test.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/documentLink.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/engine.test.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/engine.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/engine.test.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/engine.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/engine.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/engine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/engine.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/engine.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/index.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/index.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/nulLogging.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/nulLogging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/nulLogging.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/nulLogging.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/pasteUrl.test.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/pasteUrl.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/pasteUrl.test.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/pasteUrl.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/urlToUri.test.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/urlToUri.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/urlToUri.test.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/urlToUri.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/util.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/util.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/test/util.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/test/util.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/types/textDocument.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/types/textDocument.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/types/textDocument.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/types/textDocument.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/arrays.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/arrays.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/arrays.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/arrays.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/async.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/async.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/async.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/async.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/cancellation.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/cancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/cancellation.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/cancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/dispose.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/dispose.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/dispose.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/dispose.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/document.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/document.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/document.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/document.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/dom.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/dom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/dom.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/dom.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/file.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/file.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/file.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/file.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/mimes.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/mimes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/mimes.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/mimes.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/openDocumentLink.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/openDocumentLink.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/openDocumentLink.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/openDocumentLink.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/resourceMap.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/resourceMap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/resourceMap.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/resourceMap.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/resources.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/resources.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/resources.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/resources.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/schemes.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/schemes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/schemes.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/schemes.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/uriList.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/uriList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/uriList.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/uriList.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/url.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/url.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/url.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/url.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/uuid.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/uuid.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/src/util/uuid.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/src/util/uuid.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/a.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/a.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/a.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/a.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/b.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/b.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/b.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/b.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub with space/file.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub with space/file.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub with space/file.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub with space/file.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/c.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/c.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/c.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/c.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/d.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/d.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/d.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/d.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/file with space.md b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/file with space.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/file with space.md rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/file with space.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/foo.txt b/apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/foo.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/foo.txt rename to apps/review-desktop/code-oss/extensions/markdown-language-features/test-workspace/sub/foo.txt diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/tsconfig.json b/apps/review-desktop/code-oss/extensions/markdown-language-features/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/tsconfig.json rename to apps/review-desktop/code-oss/extensions/markdown-language-features/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/types/previewMessaging.d.ts b/apps/review-desktop/code-oss/extensions/markdown-language-features/types/previewMessaging.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/markdown-language-features/types/previewMessaging.d.ts rename to apps/review-desktop/code-oss/extensions/markdown-language-features/types/previewMessaging.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/.npmrc b/apps/review-desktop/code-oss/extensions/media-preview/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/.npmrc rename to apps/review-desktop/code-oss/extensions/media-preview/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/.vscodeignore b/apps/review-desktop/code-oss/extensions/media-preview/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/.vscodeignore rename to apps/review-desktop/code-oss/extensions/media-preview/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/README.md b/apps/review-desktop/code-oss/extensions/media-preview/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/README.md rename to apps/review-desktop/code-oss/extensions/media-preview/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/media-preview/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/media-preview/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/esbuild.mts b/apps/review-desktop/code-oss/extensions/media-preview/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/esbuild.mts rename to apps/review-desktop/code-oss/extensions/media-preview/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/icon.png b/apps/review-desktop/code-oss/extensions/media-preview/icon.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/icon.png rename to apps/review-desktop/code-oss/extensions/media-preview/icon.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/audioPreview.css b/apps/review-desktop/code-oss/extensions/media-preview/media/audioPreview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/audioPreview.css rename to apps/review-desktop/code-oss/extensions/media-preview/media/audioPreview.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/audioPreview.js b/apps/review-desktop/code-oss/extensions/media-preview/media/audioPreview.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/audioPreview.js rename to apps/review-desktop/code-oss/extensions/media-preview/media/audioPreview.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/imagePreview.css b/apps/review-desktop/code-oss/extensions/media-preview/media/imagePreview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/imagePreview.css rename to apps/review-desktop/code-oss/extensions/media-preview/media/imagePreview.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/imagePreview.js b/apps/review-desktop/code-oss/extensions/media-preview/media/imagePreview.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/imagePreview.js rename to apps/review-desktop/code-oss/extensions/media-preview/media/imagePreview.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/loading-dark.svg b/apps/review-desktop/code-oss/extensions/media-preview/media/loading-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/loading-dark.svg rename to apps/review-desktop/code-oss/extensions/media-preview/media/loading-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/loading-hc.svg b/apps/review-desktop/code-oss/extensions/media-preview/media/loading-hc.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/loading-hc.svg rename to apps/review-desktop/code-oss/extensions/media-preview/media/loading-hc.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/loading.svg b/apps/review-desktop/code-oss/extensions/media-preview/media/loading.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/loading.svg rename to apps/review-desktop/code-oss/extensions/media-preview/media/loading.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/videoPreview.css b/apps/review-desktop/code-oss/extensions/media-preview/media/videoPreview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/videoPreview.css rename to apps/review-desktop/code-oss/extensions/media-preview/media/videoPreview.css diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/media/videoPreview.js b/apps/review-desktop/code-oss/extensions/media-preview/media/videoPreview.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/media/videoPreview.js rename to apps/review-desktop/code-oss/extensions/media-preview/media/videoPreview.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/package-lock.json b/apps/review-desktop/code-oss/extensions/media-preview/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/package-lock.json rename to apps/review-desktop/code-oss/extensions/media-preview/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/package.json b/apps/review-desktop/code-oss/extensions/media-preview/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/package.json rename to apps/review-desktop/code-oss/extensions/media-preview/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/package.nls.json b/apps/review-desktop/code-oss/extensions/media-preview/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/package.nls.json rename to apps/review-desktop/code-oss/extensions/media-preview/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/audioPreview.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/audioPreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/audioPreview.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/audioPreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/binarySizeStatusBarEntry.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/binarySizeStatusBarEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/binarySizeStatusBarEntry.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/binarySizeStatusBarEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/extension.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/extension.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/extension.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/imagePreview/index.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/imagePreview/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/imagePreview/index.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/imagePreview/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/imagePreview/sizeStatusBarEntry.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/imagePreview/sizeStatusBarEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/imagePreview/sizeStatusBarEntry.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/imagePreview/sizeStatusBarEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/imagePreview/zoomStatusBarEntry.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/imagePreview/zoomStatusBarEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/imagePreview/zoomStatusBarEntry.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/imagePreview/zoomStatusBarEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/mediaPreview.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/mediaPreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/mediaPreview.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/mediaPreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/ownedStatusBarEntry.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/ownedStatusBarEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/ownedStatusBarEntry.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/ownedStatusBarEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/util/dispose.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/util/dispose.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/util/dispose.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/util/dispose.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/util/dom.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/util/dom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/util/dom.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/util/dom.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/util/uuid.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/util/uuid.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/util/uuid.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/util/uuid.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/src/videoPreview.ts b/apps/review-desktop/code-oss/extensions/media-preview/src/videoPreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/src/videoPreview.ts rename to apps/review-desktop/code-oss/extensions/media-preview/src/videoPreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/media-preview/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/media-preview/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/media-preview/tsconfig.json b/apps/review-desktop/code-oss/extensions/media-preview/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/media-preview/tsconfig.json rename to apps/review-desktop/code-oss/extensions/media-preview/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/.vscodeignore b/apps/review-desktop/code-oss/extensions/objective-c/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/.vscodeignore rename to apps/review-desktop/code-oss/extensions/objective-c/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/build/update-grammars.js b/apps/review-desktop/code-oss/extensions/objective-c/build/update-grammars.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/build/update-grammars.js rename to apps/review-desktop/code-oss/extensions/objective-c/build/update-grammars.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/cgmanifest.json b/apps/review-desktop/code-oss/extensions/objective-c/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/objective-c/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/language-configuration.json b/apps/review-desktop/code-oss/extensions/objective-c/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/language-configuration.json rename to apps/review-desktop/code-oss/extensions/objective-c/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/package.json b/apps/review-desktop/code-oss/extensions/objective-c/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/package.json rename to apps/review-desktop/code-oss/extensions/objective-c/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/package.nls.json b/apps/review-desktop/code-oss/extensions/objective-c/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/package.nls.json rename to apps/review-desktop/code-oss/extensions/objective-c/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json b/apps/review-desktop/code-oss/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/objective-c/syntaxes/objective-c++.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/objective-c/syntaxes/objective-c.tmLanguage.json b/apps/review-desktop/code-oss/extensions/objective-c/syntaxes/objective-c.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/objective-c/syntaxes/objective-c.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/objective-c/syntaxes/objective-c.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/package-lock.json b/apps/review-desktop/code-oss/extensions/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/package-lock.json rename to apps/review-desktop/code-oss/extensions/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/package.json b/apps/review-desktop/code-oss/extensions/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/package.json rename to apps/review-desktop/code-oss/extensions/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/.vscodeignore b/apps/review-desktop/code-oss/extensions/perl/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/.vscodeignore rename to apps/review-desktop/code-oss/extensions/perl/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/cgmanifest.json b/apps/review-desktop/code-oss/extensions/perl/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/perl/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/package.json b/apps/review-desktop/code-oss/extensions/perl/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/package.json rename to apps/review-desktop/code-oss/extensions/perl/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/package.nls.json b/apps/review-desktop/code-oss/extensions/perl/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/package.nls.json rename to apps/review-desktop/code-oss/extensions/perl/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/perl.language-configuration.json b/apps/review-desktop/code-oss/extensions/perl/perl.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/perl.language-configuration.json rename to apps/review-desktop/code-oss/extensions/perl/perl.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/perl6.language-configuration.json b/apps/review-desktop/code-oss/extensions/perl/perl6.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/perl6.language-configuration.json rename to apps/review-desktop/code-oss/extensions/perl/perl6.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/syntaxes/perl.tmLanguage.json b/apps/review-desktop/code-oss/extensions/perl/syntaxes/perl.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/syntaxes/perl.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/perl/syntaxes/perl.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/perl/syntaxes/perl6.tmLanguage.json b/apps/review-desktop/code-oss/extensions/perl/syntaxes/perl6.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/perl/syntaxes/perl6.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/perl/syntaxes/perl6.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/.vscodeignore b/apps/review-desktop/code-oss/extensions/php/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/.vscodeignore rename to apps/review-desktop/code-oss/extensions/php/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/build/update-grammar.mjs b/apps/review-desktop/code-oss/extensions/php/build/update-grammar.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/build/update-grammar.mjs rename to apps/review-desktop/code-oss/extensions/php/build/update-grammar.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/cgmanifest.json b/apps/review-desktop/code-oss/extensions/php/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/php/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/language-configuration.json b/apps/review-desktop/code-oss/extensions/php/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/language-configuration.json rename to apps/review-desktop/code-oss/extensions/php/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/package.json b/apps/review-desktop/code-oss/extensions/php/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/package.json rename to apps/review-desktop/code-oss/extensions/php/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/package.nls.json b/apps/review-desktop/code-oss/extensions/php/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/package.nls.json rename to apps/review-desktop/code-oss/extensions/php/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/snippets/php.code-snippets b/apps/review-desktop/code-oss/extensions/php/snippets/php.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/snippets/php.code-snippets rename to apps/review-desktop/code-oss/extensions/php/snippets/php.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/syntaxes/html.tmLanguage.json b/apps/review-desktop/code-oss/extensions/php/syntaxes/html.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/syntaxes/html.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/php/syntaxes/html.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/php/syntaxes/php.tmLanguage.json b/apps/review-desktop/code-oss/extensions/php/syntaxes/php.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/php/syntaxes/php.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/php/syntaxes/php.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/postinstall.mjs b/apps/review-desktop/code-oss/extensions/postinstall.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/postinstall.mjs rename to apps/review-desktop/code-oss/extensions/postinstall.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/powershell/.vscodeignore b/apps/review-desktop/code-oss/extensions/powershell/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/powershell/.vscodeignore rename to apps/review-desktop/code-oss/extensions/powershell/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/powershell/cgmanifest.json b/apps/review-desktop/code-oss/extensions/powershell/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/powershell/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/powershell/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/powershell/language-configuration.json b/apps/review-desktop/code-oss/extensions/powershell/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/powershell/language-configuration.json rename to apps/review-desktop/code-oss/extensions/powershell/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/powershell/package.json b/apps/review-desktop/code-oss/extensions/powershell/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/powershell/package.json rename to apps/review-desktop/code-oss/extensions/powershell/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/powershell/package.nls.json b/apps/review-desktop/code-oss/extensions/powershell/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/powershell/package.nls.json rename to apps/review-desktop/code-oss/extensions/powershell/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/powershell/syntaxes/powershell.tmLanguage.json b/apps/review-desktop/code-oss/extensions/powershell/syntaxes/powershell.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/powershell/syntaxes/powershell.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/powershell/syntaxes/powershell.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/prompt-basics/.vscodeignore b/apps/review-desktop/code-oss/extensions/prompt-basics/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/prompt-basics/.vscodeignore rename to apps/review-desktop/code-oss/extensions/prompt-basics/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/prompt-basics/cgmanifest.json b/apps/review-desktop/code-oss/extensions/prompt-basics/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/prompt-basics/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/prompt-basics/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/prompt-basics/language-configuration.json b/apps/review-desktop/code-oss/extensions/prompt-basics/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/prompt-basics/language-configuration.json rename to apps/review-desktop/code-oss/extensions/prompt-basics/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/prompt-basics/package.json b/apps/review-desktop/code-oss/extensions/prompt-basics/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/prompt-basics/package.json rename to apps/review-desktop/code-oss/extensions/prompt-basics/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/prompt-basics/package.nls.json b/apps/review-desktop/code-oss/extensions/prompt-basics/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/prompt-basics/package.nls.json rename to apps/review-desktop/code-oss/extensions/prompt-basics/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/prompt-basics/syntaxes/prompt.tmLanguage.json b/apps/review-desktop/code-oss/extensions/prompt-basics/syntaxes/prompt.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/prompt-basics/syntaxes/prompt.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/prompt-basics/syntaxes/prompt.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/pug/.vscodeignore b/apps/review-desktop/code-oss/extensions/pug/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/pug/.vscodeignore rename to apps/review-desktop/code-oss/extensions/pug/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/pug/cgmanifest.json b/apps/review-desktop/code-oss/extensions/pug/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/pug/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/pug/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/pug/language-configuration.json b/apps/review-desktop/code-oss/extensions/pug/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/pug/language-configuration.json rename to apps/review-desktop/code-oss/extensions/pug/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/pug/package.json b/apps/review-desktop/code-oss/extensions/pug/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/pug/package.json rename to apps/review-desktop/code-oss/extensions/pug/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/pug/package.nls.json b/apps/review-desktop/code-oss/extensions/pug/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/pug/package.nls.json rename to apps/review-desktop/code-oss/extensions/pug/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/pug/syntaxes/pug.tmLanguage.json b/apps/review-desktop/code-oss/extensions/pug/syntaxes/pug.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/pug/syntaxes/pug.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/pug/syntaxes/pug.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/.vscodeignore b/apps/review-desktop/code-oss/extensions/python/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/.vscodeignore rename to apps/review-desktop/code-oss/extensions/python/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/cgmanifest.json b/apps/review-desktop/code-oss/extensions/python/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/python/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/language-configuration.json b/apps/review-desktop/code-oss/extensions/python/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/language-configuration.json rename to apps/review-desktop/code-oss/extensions/python/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/package.json b/apps/review-desktop/code-oss/extensions/python/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/package.json rename to apps/review-desktop/code-oss/extensions/python/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/package.nls.json b/apps/review-desktop/code-oss/extensions/python/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/package.nls.json rename to apps/review-desktop/code-oss/extensions/python/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/syntaxes/MagicPython.tmLanguage.json b/apps/review-desktop/code-oss/extensions/python/syntaxes/MagicPython.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/syntaxes/MagicPython.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/python/syntaxes/MagicPython.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/python/syntaxes/MagicRegExp.tmLanguage.json b/apps/review-desktop/code-oss/extensions/python/syntaxes/MagicRegExp.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/python/syntaxes/MagicRegExp.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/python/syntaxes/MagicRegExp.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/r/.vscodeignore b/apps/review-desktop/code-oss/extensions/r/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/r/.vscodeignore rename to apps/review-desktop/code-oss/extensions/r/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/r/cgmanifest.json b/apps/review-desktop/code-oss/extensions/r/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/r/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/r/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/r/language-configuration.json b/apps/review-desktop/code-oss/extensions/r/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/r/language-configuration.json rename to apps/review-desktop/code-oss/extensions/r/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/r/package.json b/apps/review-desktop/code-oss/extensions/r/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/r/package.json rename to apps/review-desktop/code-oss/extensions/r/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/r/package.nls.json b/apps/review-desktop/code-oss/extensions/r/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/r/package.nls.json rename to apps/review-desktop/code-oss/extensions/r/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/r/syntaxes/r.tmLanguage.json b/apps/review-desktop/code-oss/extensions/r/syntaxes/r.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/r/syntaxes/r.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/r/syntaxes/r.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/.vscodeignore b/apps/review-desktop/code-oss/extensions/razor/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/.vscodeignore rename to apps/review-desktop/code-oss/extensions/razor/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/build/update-grammar.mjs b/apps/review-desktop/code-oss/extensions/razor/build/update-grammar.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/build/update-grammar.mjs rename to apps/review-desktop/code-oss/extensions/razor/build/update-grammar.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/cgmanifest.json b/apps/review-desktop/code-oss/extensions/razor/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/razor/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/language-configuration.json b/apps/review-desktop/code-oss/extensions/razor/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/language-configuration.json rename to apps/review-desktop/code-oss/extensions/razor/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/package.json b/apps/review-desktop/code-oss/extensions/razor/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/package.json rename to apps/review-desktop/code-oss/extensions/razor/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/package.nls.json b/apps/review-desktop/code-oss/extensions/razor/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/package.nls.json rename to apps/review-desktop/code-oss/extensions/razor/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/razor/syntaxes/cshtml.tmLanguage.json b/apps/review-desktop/code-oss/extensions/razor/syntaxes/cshtml.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/razor/syntaxes/cshtml.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/razor/syntaxes/cshtml.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/.npmrc b/apps/review-desktop/code-oss/extensions/references-view/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/.npmrc rename to apps/review-desktop/code-oss/extensions/references-view/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/.vscodeignore b/apps/review-desktop/code-oss/extensions/references-view/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/.vscodeignore rename to apps/review-desktop/code-oss/extensions/references-view/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/README.md b/apps/review-desktop/code-oss/extensions/references-view/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/README.md rename to apps/review-desktop/code-oss/extensions/references-view/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/references-view/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/references-view/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/esbuild.mts b/apps/review-desktop/code-oss/extensions/references-view/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/esbuild.mts rename to apps/review-desktop/code-oss/extensions/references-view/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/media/demo.png b/apps/review-desktop/code-oss/extensions/references-view/media/demo.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/media/demo.png rename to apps/review-desktop/code-oss/extensions/references-view/media/demo.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/media/icon.png b/apps/review-desktop/code-oss/extensions/references-view/media/icon.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/media/icon.png rename to apps/review-desktop/code-oss/extensions/references-view/media/icon.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/package-lock.json b/apps/review-desktop/code-oss/extensions/references-view/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/package-lock.json rename to apps/review-desktop/code-oss/extensions/references-view/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/package.json b/apps/review-desktop/code-oss/extensions/references-view/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/package.json rename to apps/review-desktop/code-oss/extensions/references-view/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/package.nls.json b/apps/review-desktop/code-oss/extensions/references-view/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/package.nls.json rename to apps/review-desktop/code-oss/extensions/references-view/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/calls/index.ts b/apps/review-desktop/code-oss/extensions/references-view/src/calls/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/calls/index.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/calls/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/calls/model.ts b/apps/review-desktop/code-oss/extensions/references-view/src/calls/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/calls/model.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/calls/model.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/extension.ts b/apps/review-desktop/code-oss/extensions/references-view/src/extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/extension.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/extension.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/highlights.ts b/apps/review-desktop/code-oss/extensions/references-view/src/highlights.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/highlights.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/highlights.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/navigation.ts b/apps/review-desktop/code-oss/extensions/references-view/src/navigation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/navigation.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/navigation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/references-view.d.ts b/apps/review-desktop/code-oss/extensions/references-view/src/references-view.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/references-view.d.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/references-view.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/references/index.ts b/apps/review-desktop/code-oss/extensions/references-view/src/references/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/references/index.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/references/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/references/model.ts b/apps/review-desktop/code-oss/extensions/references-view/src/references/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/references/model.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/references/model.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/tree.ts b/apps/review-desktop/code-oss/extensions/references-view/src/tree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/tree.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/tree.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/types/index.ts b/apps/review-desktop/code-oss/extensions/references-view/src/types/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/types/index.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/types/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/types/model.ts b/apps/review-desktop/code-oss/extensions/references-view/src/types/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/types/model.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/types/model.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/src/utils.ts b/apps/review-desktop/code-oss/extensions/references-view/src/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/src/utils.ts rename to apps/review-desktop/code-oss/extensions/references-view/src/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/references-view/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/references-view/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/references-view/tsconfig.json b/apps/review-desktop/code-oss/extensions/references-view/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/references-view/tsconfig.json rename to apps/review-desktop/code-oss/extensions/references-view/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/restructuredtext/.vscodeignore b/apps/review-desktop/code-oss/extensions/restructuredtext/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/restructuredtext/.vscodeignore rename to apps/review-desktop/code-oss/extensions/restructuredtext/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/restructuredtext/cgmanifest.json b/apps/review-desktop/code-oss/extensions/restructuredtext/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/restructuredtext/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/restructuredtext/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/restructuredtext/language-configuration.json b/apps/review-desktop/code-oss/extensions/restructuredtext/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/restructuredtext/language-configuration.json rename to apps/review-desktop/code-oss/extensions/restructuredtext/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/restructuredtext/package.json b/apps/review-desktop/code-oss/extensions/restructuredtext/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/restructuredtext/package.json rename to apps/review-desktop/code-oss/extensions/restructuredtext/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/restructuredtext/package.nls.json b/apps/review-desktop/code-oss/extensions/restructuredtext/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/restructuredtext/package.nls.json rename to apps/review-desktop/code-oss/extensions/restructuredtext/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/restructuredtext/syntaxes/rst.tmLanguage.json b/apps/review-desktop/code-oss/extensions/restructuredtext/syntaxes/rst.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/restructuredtext/syntaxes/rst.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/restructuredtext/syntaxes/rst.tmLanguage.json diff --git a/apps/review-desktop/code-oss/extensions/review-themes/package.json b/apps/review-desktop/code-oss/extensions/review-themes/package.json new file mode 100644 index 000000000..455a66e86 --- /dev/null +++ b/apps/review-desktop/code-oss/extensions/review-themes/package.json @@ -0,0 +1,28 @@ +{ + "name": "review-themes", + "displayName": "Review Themes", + "description": "Themes for /dev/fast Review.", + "categories": [ + "Themes" + ], + "version": "0.0.1", + "publisher": "dev-fast", + "license": "MIT", + "engines": { + "vscode": "*" + }, + "contributes": { + "themes": [ + { + "label": "Review Dark", + "uiTheme": "vs-dark", + "path": "./themes/review-dark.json" + }, + { + "label": "Review Light", + "uiTheme": "vs", + "path": "./themes/review-light.json" + } + ] + } +} diff --git a/apps/review-desktop/code-oss/extensions/review-themes/themes/review-dark.json b/apps/review-desktop/code-oss/extensions/review-themes/themes/review-dark.json new file mode 100644 index 000000000..2f3a204f2 --- /dev/null +++ b/apps/review-desktop/code-oss/extensions/review-themes/themes/review-dark.json @@ -0,0 +1,442 @@ +{ + // Whiteboard Dark: the Whiteboard syntax palette over the stock Dark+ include. + // Every scope the included theme colors is listed below, so none of its colors reaches the screen; + // the include only supplies grammar coverage. Roles: keyword, type, function, ink, string, number, + // operator, comment, inserted, deleted. Regenerated from the Whiteboard System — Syntax themes board. + "$schema": "vscode://schemas/color-theme", + "name": "Review Dark", + "include": "./../../theme-defaults/themes/dark_plus.json", + "semanticHighlighting": true, + "tokenColors": [ + { + "name": "Whiteboard: comment", + "scope": [ + "comment", + "punctuation.definition.comment" + ], + "settings": { + "foreground": "#778090", + "fontStyle": "italic" + } + }, + { + "name": "Whiteboard: keyword and storage", + "scope": [ + "keyword", + "keyword.control", + "storage", + "storage.type", + "storage.modifier", + "keyword.operator.noexcept", + "keyword.operator.new", + "keyword.operator.expression", + "keyword.operator.cast", + "keyword.operator.sizeof", + "keyword.operator.alignof", + "keyword.operator.typeid", + "keyword.operator.alignas", + "keyword.operator.instanceof", + "keyword.operator.logical.python", + "keyword.operator.wordlike", + "source.cpp keyword.operator.new", + "source.cpp keyword.operator.delete", + "keyword.operator.delete", + "keyword.other.using", + "keyword.other.directive.using", + "keyword.other.operator", + "entity.name.operator", + "variable.language", + "meta.preprocessor", + "entity.name.function.preprocessor", + "keyword.operator.or.regexp", + "keyword.control.anchor.regexp", + "meta.diff.header", + "header" + ], + "settings": { + "foreground": "#5B7CFF" + } + }, + { + "name": "Whiteboard: type, class, tag, attribute and selector", + "scope": [ + "entity.name.type", + "support.type", + "support.class", + "entity.other.inherited-class", + "entity.name.namespace", + "entity.other.attribute", + "entity.name.scope-resolution", + "entity.name.class", + "meta.type.cast.expr", + "meta.type.new.expr", + "support.constant.math", + "support.constant.dom", + "support.constant.json", + "punctuation.separator.namespace.ruby", + "storage.type.numeric.go", + "storage.type.byte.go", + "storage.type.boolean.go", + "storage.type.string.go", + "storage.type.uintptr.go", + "storage.type.error.go", + "storage.type.rune.go", + "storage.type.cs", + "storage.type.generic.cs", + "storage.type.modifier.cs", + "storage.type.variable.cs", + "storage.type.annotation.java", + "storage.type.generic.java", + "storage.type.java", + "storage.type.object.array.java", + "storage.type.primitive.array.java", + "storage.type.primitive.java", + "storage.type.token.java", + "storage.type.groovy", + "storage.type.annotation.groovy", + "storage.type.parameters.groovy", + "storage.type.generic.groovy", + "storage.type.object.array.groovy", + "storage.type.primitive.array.groovy", + "storage.type.primitive.groovy", + "entity.name.tag", + "entity.name.tag.css", + "entity.name.tag.less", + "entity.name.selector", + "entity.other.attribute-name", + "entity.other.attribute-name.class.css", + "source.css entity.other.attribute-name.class", + "entity.other.attribute-name.id.css", + "entity.other.attribute-name.parent-selector.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", + "entity.other.attribute-name.pseudo-element.css", + "source.css.less entity.other.attribute-name.id", + "entity.other.attribute-name.scss" + ], + "settings": { + "foreground": "#6FC3E6" + } + }, + { + "name": "Whiteboard: class name", + "scope": [ + "entity.name.type.class" + ], + "settings": { + "foreground": "#6FC3E6", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: function, decorator and section", + "scope": [ + "entity.name.function", + "support.function", + "meta.function-call entity.name.function", + "meta.decorator", + "punctuation.decorator", + "support.constant.handlebars", + "source.powershell variable.other.member", + "entity.name.operator.custom-literal", + "support.function.git-rebase" + ], + "settings": { + "foreground": "#B7C4FF" + } + }, + { + "name": "Whiteboard: heading", + "scope": [ + "entity.name.section", + "markup.heading" + ], + "settings": { + "foreground": "#B7C4FF", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: variable, property name and key", + "scope": [ + "variable", + "variable.parameter", + "variable.other", + "variable.other.property", + "variable.other.object.property", + "support.variable", + "support.variable.property", + "meta.definition.variable.name", + "entity.name.variable", + "constant.other.placeholder", + "meta.object-literal.key", + "variable.other.constant", + "variable.other.enummember", + "support.type.vendored.property-name", + "support.type.property-name", + "support.type.property-name.json", + "source.css variable", + "source.coffee.embedded", + "meta.structure.dictionary.key.python", + "entity.name.label", + "constant.other.option", + "meta.embedded", + "source.groovy.embedded", + "string meta.image.inline.markdown", + "variable.legacy.builtin.python", + "meta.template.expression", + "storage.modifier.import.java", + "variable.language.wildcard.java", + "storage.modifier.package.java" + ], + "settings": { + "foreground": "#EEF0F4" + } + }, + { + "name": "Whiteboard: string, value and regexp", + "scope": [ + "string", + "string.template", + "punctuation.definition.string", + "meta.embedded.assembly", + "string.tag", + "string.value", + "string.regexp", + "constant.regexp", + "constant.character", + "string.comment.buffered.block.pug", + "string.quoted.pug", + "string.interpolated.pug", + "string.unquoted.plain.in.yaml", + "string.unquoted.plain.out.yaml", + "string.unquoted.block.yaml", + "string.quoted.single.yaml", + "string.quoted.double.xml", + "string.quoted.single.xml", + "string.unquoted.cdata.xml", + "string.quoted.double.html", + "string.quoted.single.html", + "string.unquoted.html", + "string.quoted.single.handlebars", + "string.quoted.double.handlebars", + "meta.preprocessor.string", + "markup.inline.raw", + "support.constant.property-value", + "support.constant.font-name", + "support.constant.media-type", + "support.constant.media", + "constant.other.color.rgb-value", + "constant.other.rgb-value", + "support.constant.color", + "constant.character.character-class.regexp", + "constant.other.character-class.set.regexp", + "constant.other.character-class.regexp", + "constant.character.set.regexp" + ], + "settings": { + "foreground": "#D9A85C" + } + }, + { + "name": "Whiteboard: number, unit and escape", + "scope": [ + "constant.numeric", + "keyword.other.unit", + "keyword.operator.plus.exponent", + "keyword.operator.minus.exponent", + "meta.preprocessor.numeric", + "constant.sha.git-rebase", + "constant.character.escape" + ], + "settings": { + "foreground": "#D48FD6" + } + }, + { + "name": "Whiteboard: boolean and language constant", + "scope": [ + "constant.language" + ], + "settings": { + "foreground": "#D48FD6", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: operator and punctuation", + "scope": [ + "keyword.operator", + "punctuation", + "meta.brace", + "punctuation.definition.tag", + "punctuation.definition.template-expression", + "punctuation.definition.template-expression.begin", + "punctuation.definition.template-expression.end", + "punctuation.section.embedded", + "punctuation.section.embedded.begin.php", + "punctuation.section.embedded.end.php", + "punctuation.definition.quote.begin.markdown", + "punctuation.definition.list.begin.markdown", + "markup.changed", + "punctuation.definition.group.regexp", + "punctuation.definition.group.assertion.regexp", + "punctuation.definition.character-class.regexp", + "punctuation.character.set.begin.regexp", + "punctuation.character.set.end.regexp", + "keyword.operator.negation.regexp", + "support.other.parenthesis.regexp", + "keyword.operator.quantifier.regexp" + ], + "settings": { + "foreground": "#9199A8" + } + }, + { + "name": "Whiteboard: inserted", + "scope": [ + "markup.inserted" + ], + "settings": { + "foreground": "#4ED990" + } + }, + { + "name": "Whiteboard: deleted", + "scope": [ + "markup.deleted" + ], + "settings": { + "foreground": "#F26A55" + } + }, + { + "name": "Whiteboard: invalid", + "scope": [ + "invalid", + "invalid.illegal" + ], + "settings": { + "foreground": "#F26A55", + "fontStyle": "underline" + } + }, + { + "name": "Whiteboard: markup bold", + "scope": [ + "markup.bold", + "strong" + ], + "settings": { + "foreground": "#EEF0F4", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: markup italic", + "scope": [ + "markup.italic", + "emphasis" + ], + "settings": { + "foreground": "#EEF0F4", + "fontStyle": "italic" + } + }, + { + "name": "Whiteboard: markup underline", + "scope": [ + "markup.underline" + ], + "settings": { + "fontStyle": "underline" + } + }, + { + "name": "Whiteboard: markup strikethrough", + "scope": [ + "markup.strikethrough" + ], + "settings": { + "fontStyle": "strikethrough" + } + }, + { + "name": "Whiteboard: link", + "scope": [ + "markup.underline.link", + "string.other.link", + "constant.other.reference.link" + ], + "settings": { + "foreground": "#5B7CFF", + "fontStyle": "underline" + } + } + ], + "semanticTokenColors": { + "newOperator": "#5B7CFF", + "stringLiteral": "#D9A85C", + "customLiteral": "#B7C4FF", + "numberLiteral": "#D48FD6" + }, + "colors": { + "editor.background": "#0C0F15", + "editorWidget.background": "#12161E", + "panel.border": "#262C37", + "editorWidget.border": "#39404D", + "focusBorder": "#5B7CFF", + "editorGroupHeader.tabsBackground": "#12161E", + "titleBar.activeBackground": "#12161E", + "titleBar.inactiveBackground": "#12161E", + "diffEditor.insertedLineBackground": "#4ED9901F", + "diffEditor.insertedTextBackground": "#4ED99038", + "diffEditor.removedLineBackground": "#F26A551F", + "diffEditor.removedTextBackground": "#F26A5538", + "widget.shadow": "#00000066", + "editorHoverWidget.border": "#39404D", + "editorHoverWidget.background": "#12161E", + "sideBar.background": "#12161E", + "diffEditor.diagonalFill": "#39404D40", + "diffEditor.unchangedCodeBackground": "#00000000", + "diffEditor.unchangedRegionBackground": "#0C0F15", + "diffEditor.unchangedRegionForeground": "#343A46", + "diffEditor.unchangedRegionShadow": "#00000000", + "gitDecoration.addedResourceForeground": "#4ED990", + "gitDecoration.modifiedResourceForeground": "#F2C14E", + "gitDecoration.renamedResourceForeground": "#9199A8", + "gitDecoration.deletedResourceForeground": "#F26A55", + "multiDiffEditor.border": "#262C37", + "multiDiffEditor.headerBackground": "#12161E", + "icon.foreground": "#9199A8", + "editor.selectionBackground": "#5B7CFF40", + "editor.lineHighlightBackground": "#12161E", + "scrollbarSlider.background": "#39404D80", + "toolbar.hoverBackground": "#1A1F29", + "list.inactiveSelectionBackground": "#1A1F29", + "list.activeSelectionForeground": "#EEF0F4", + "list.activeSelectionBackground": "#5B7CFF24", + "list.hoverBackground": "#1A1F29", + "input.background": "#1A1F29", + "editorGutter.background": "#0C0F15", + "editorLineNumber.activeForeground": "#9199A8", + "editorLineNumber.foreground": "#343A46", + "foreground": "#EEF0F4", + "disabledForeground": "#5F6776", + "descriptionForeground": "#9199A8", + "editor.foreground": "#EEF0F4", + "editorCursor.foreground": "#5B7CFF", + "editorBracketMatch.background": "#5B7CFF24", + "editorBracketMatch.border": "#5B7CFF4D", + "editorIndentGuide.background1": "#262C37", + "editorIndentGuide.activeBackground1": "#39404D", + "editorWhitespace.foreground": "#343A46", + "editorBracketHighlight.foreground1": "#9199A8", + "editorBracketHighlight.foreground2": "#9199A8", + "editorBracketHighlight.foreground3": "#9199A8", + "editorBracketHighlight.foreground4": "#9199A8", + "editorBracketHighlight.foreground5": "#9199A8", + "editorBracketHighlight.foreground6": "#9199A8", + "editorBracketHighlight.unexpectedBracket.foreground": "#F26A55" + } +} diff --git a/apps/review-desktop/code-oss/extensions/review-themes/themes/review-light.json b/apps/review-desktop/code-oss/extensions/review-themes/themes/review-light.json new file mode 100644 index 000000000..3b1f48ebb --- /dev/null +++ b/apps/review-desktop/code-oss/extensions/review-themes/themes/review-light.json @@ -0,0 +1,442 @@ +{ + // Whiteboard Light: the Whiteboard syntax palette over the stock Light+ include. + // Every scope the included theme colors is listed below, so none of its colors reaches the screen; + // the include only supplies grammar coverage. Roles: keyword, type, function, ink, string, number, + // operator, comment, inserted, deleted. Regenerated from the Whiteboard System — Syntax themes board. + "$schema": "vscode://schemas/color-theme", + "name": "Review Light", + "include": "./../../theme-defaults/themes/light_plus.json", + "semanticHighlighting": true, + "tokenColors": [ + { + "name": "Whiteboard: comment", + "scope": [ + "comment", + "punctuation.definition.comment" + ], + "settings": { + "foreground": "#6B7382", + "fontStyle": "italic" + } + }, + { + "name": "Whiteboard: keyword and storage", + "scope": [ + "keyword", + "keyword.control", + "storage", + "storage.type", + "storage.modifier", + "keyword.operator.noexcept", + "keyword.operator.new", + "keyword.operator.expression", + "keyword.operator.cast", + "keyword.operator.sizeof", + "keyword.operator.alignof", + "keyword.operator.typeid", + "keyword.operator.alignas", + "keyword.operator.instanceof", + "keyword.operator.logical.python", + "keyword.operator.wordlike", + "source.cpp keyword.operator.new", + "source.cpp keyword.operator.delete", + "keyword.operator.delete", + "keyword.other.using", + "keyword.other.directive.using", + "keyword.other.operator", + "entity.name.operator", + "variable.language", + "meta.preprocessor", + "entity.name.function.preprocessor", + "keyword.operator.or.regexp", + "keyword.control.anchor.regexp", + "meta.diff.header", + "header" + ], + "settings": { + "foreground": "#2B55E6" + } + }, + { + "name": "Whiteboard: type, class, tag, attribute and selector", + "scope": [ + "entity.name.type", + "support.type", + "support.class", + "entity.other.inherited-class", + "entity.name.namespace", + "entity.other.attribute", + "entity.name.scope-resolution", + "entity.name.class", + "meta.type.cast.expr", + "meta.type.new.expr", + "support.constant.math", + "support.constant.dom", + "support.constant.json", + "punctuation.separator.namespace.ruby", + "storage.type.numeric.go", + "storage.type.byte.go", + "storage.type.boolean.go", + "storage.type.string.go", + "storage.type.uintptr.go", + "storage.type.error.go", + "storage.type.rune.go", + "storage.type.cs", + "storage.type.generic.cs", + "storage.type.modifier.cs", + "storage.type.variable.cs", + "storage.type.annotation.java", + "storage.type.generic.java", + "storage.type.java", + "storage.type.object.array.java", + "storage.type.primitive.array.java", + "storage.type.primitive.java", + "storage.type.token.java", + "storage.type.groovy", + "storage.type.annotation.groovy", + "storage.type.parameters.groovy", + "storage.type.generic.groovy", + "storage.type.object.array.groovy", + "storage.type.primitive.array.groovy", + "storage.type.primitive.groovy", + "entity.name.tag", + "entity.name.tag.css", + "entity.name.tag.less", + "entity.name.selector", + "entity.other.attribute-name", + "entity.other.attribute-name.class.css", + "source.css entity.other.attribute-name.class", + "entity.other.attribute-name.id.css", + "entity.other.attribute-name.parent-selector.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", + "entity.other.attribute-name.pseudo-element.css", + "source.css.less entity.other.attribute-name.id", + "entity.other.attribute-name.scss" + ], + "settings": { + "foreground": "#0C6E8E" + } + }, + { + "name": "Whiteboard: class name", + "scope": [ + "entity.name.type.class" + ], + "settings": { + "foreground": "#0C6E8E", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: function, decorator and section", + "scope": [ + "entity.name.function", + "support.function", + "meta.function-call entity.name.function", + "meta.decorator", + "punctuation.decorator", + "support.constant.handlebars", + "source.powershell variable.other.member", + "entity.name.operator.custom-literal", + "support.function.git-rebase" + ], + "settings": { + "foreground": "#1F3F99" + } + }, + { + "name": "Whiteboard: heading", + "scope": [ + "entity.name.section", + "markup.heading" + ], + "settings": { + "foreground": "#1F3F99", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: variable, property name and key", + "scope": [ + "variable", + "variable.parameter", + "variable.other", + "variable.other.property", + "variable.other.object.property", + "support.variable", + "support.variable.property", + "meta.definition.variable.name", + "entity.name.variable", + "constant.other.placeholder", + "meta.object-literal.key", + "variable.other.constant", + "variable.other.enummember", + "support.type.vendored.property-name", + "support.type.property-name", + "support.type.property-name.json", + "source.css variable", + "source.coffee.embedded", + "meta.structure.dictionary.key.python", + "entity.name.label", + "constant.other.option", + "meta.embedded", + "source.groovy.embedded", + "string meta.image.inline.markdown", + "variable.legacy.builtin.python", + "meta.template.expression", + "storage.modifier.import.java", + "variable.language.wildcard.java", + "storage.modifier.package.java" + ], + "settings": { + "foreground": "#15181E" + } + }, + { + "name": "Whiteboard: string, value and regexp", + "scope": [ + "string", + "string.template", + "punctuation.definition.string", + "meta.embedded.assembly", + "string.tag", + "string.value", + "string.regexp", + "constant.regexp", + "constant.character", + "string.comment.buffered.block.pug", + "string.quoted.pug", + "string.interpolated.pug", + "string.unquoted.plain.in.yaml", + "string.unquoted.plain.out.yaml", + "string.unquoted.block.yaml", + "string.quoted.single.yaml", + "string.quoted.double.xml", + "string.quoted.single.xml", + "string.unquoted.cdata.xml", + "string.quoted.double.html", + "string.quoted.single.html", + "string.unquoted.html", + "string.quoted.single.handlebars", + "string.quoted.double.handlebars", + "meta.preprocessor.string", + "markup.inline.raw", + "support.constant.property-value", + "support.constant.font-name", + "support.constant.media-type", + "support.constant.media", + "constant.other.color.rgb-value", + "constant.other.rgb-value", + "support.constant.color", + "constant.character.character-class.regexp", + "constant.other.character-class.set.regexp", + "constant.other.character-class.regexp", + "constant.character.set.regexp" + ], + "settings": { + "foreground": "#8A5A1C" + } + }, + { + "name": "Whiteboard: number, unit and escape", + "scope": [ + "constant.numeric", + "keyword.other.unit", + "keyword.operator.plus.exponent", + "keyword.operator.minus.exponent", + "meta.preprocessor.numeric", + "constant.sha.git-rebase", + "constant.character.escape" + ], + "settings": { + "foreground": "#8B3F8A" + } + }, + { + "name": "Whiteboard: boolean and language constant", + "scope": [ + "constant.language" + ], + "settings": { + "foreground": "#8B3F8A", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: operator and punctuation", + "scope": [ + "keyword.operator", + "punctuation", + "meta.brace", + "punctuation.definition.tag", + "punctuation.definition.template-expression", + "punctuation.definition.template-expression.begin", + "punctuation.definition.template-expression.end", + "punctuation.section.embedded", + "punctuation.section.embedded.begin.php", + "punctuation.section.embedded.end.php", + "punctuation.definition.quote.begin.markdown", + "punctuation.definition.list.begin.markdown", + "markup.changed", + "punctuation.definition.group.regexp", + "punctuation.definition.group.assertion.regexp", + "punctuation.definition.character-class.regexp", + "punctuation.character.set.begin.regexp", + "punctuation.character.set.end.regexp", + "keyword.operator.negation.regexp", + "support.other.parenthesis.regexp", + "keyword.operator.quantifier.regexp" + ], + "settings": { + "foreground": "#5D6472" + } + }, + { + "name": "Whiteboard: inserted", + "scope": [ + "markup.inserted" + ], + "settings": { + "foreground": "#167A47" + } + }, + { + "name": "Whiteboard: deleted", + "scope": [ + "markup.deleted" + ], + "settings": { + "foreground": "#C93A27" + } + }, + { + "name": "Whiteboard: invalid", + "scope": [ + "invalid", + "invalid.illegal" + ], + "settings": { + "foreground": "#C93A27", + "fontStyle": "underline" + } + }, + { + "name": "Whiteboard: markup bold", + "scope": [ + "markup.bold", + "strong" + ], + "settings": { + "foreground": "#15181E", + "fontStyle": "bold" + } + }, + { + "name": "Whiteboard: markup italic", + "scope": [ + "markup.italic", + "emphasis" + ], + "settings": { + "foreground": "#15181E", + "fontStyle": "italic" + } + }, + { + "name": "Whiteboard: markup underline", + "scope": [ + "markup.underline" + ], + "settings": { + "fontStyle": "underline" + } + }, + { + "name": "Whiteboard: markup strikethrough", + "scope": [ + "markup.strikethrough" + ], + "settings": { + "fontStyle": "strikethrough" + } + }, + { + "name": "Whiteboard: link", + "scope": [ + "markup.underline.link", + "string.other.link", + "constant.other.reference.link" + ], + "settings": { + "foreground": "#2B55E6", + "fontStyle": "underline" + } + } + ], + "semanticTokenColors": { + "newOperator": "#2B55E6", + "stringLiteral": "#8A5A1C", + "customLiteral": "#1F3F99", + "numberLiteral": "#8B3F8A" + }, + "colors": { + "editor.background": "#FFFFFF", + "editorWidget.background": "#F3F4F6", + "panel.border": "#D8DBE1", + "editorWidget.border": "#B9BEC7", + "focusBorder": "#2B55E6", + "editorGroupHeader.tabsBackground": "#F3F4F6", + "titleBar.activeBackground": "#F3F4F6", + "titleBar.inactiveBackground": "#F3F4F6", + "diffEditor.insertedLineBackground": "#1B9A5716", + "diffEditor.insertedTextBackground": "#1B9A5733", + "diffEditor.removedLineBackground": "#D8402C16", + "diffEditor.removedTextBackground": "#D8402C33", + "widget.shadow": "#15181E1A", + "editorHoverWidget.border": "#B9BEC7", + "editorHoverWidget.background": "#FFFFFF", + "sideBar.background": "#F3F4F6", + "diffEditor.diagonalFill": "#D8DBE180", + "diffEditor.unchangedCodeBackground": "#00000000", + "diffEditor.unchangedRegionBackground": "#FFFFFF", + "diffEditor.unchangedRegionForeground": "#CDD1D8", + "diffEditor.unchangedRegionShadow": "#00000000", + "gitDecoration.addedResourceForeground": "#1B9A57", + "gitDecoration.modifiedResourceForeground": "#C98A0B", + "gitDecoration.renamedResourceForeground": "#5D6472", + "gitDecoration.deletedResourceForeground": "#D8402C", + "multiDiffEditor.border": "#D8DBE1", + "multiDiffEditor.headerBackground": "#F3F4F6", + "icon.foreground": "#5D6472", + "editor.selectionBackground": "#2B55E629", + "editor.lineHighlightBackground": "#F3F4F6", + "scrollbarSlider.background": "#B9BEC780", + "toolbar.hoverBackground": "#E9EBEF", + "list.inactiveSelectionBackground": "#E9EBEF", + "list.activeSelectionForeground": "#15181E", + "list.activeSelectionBackground": "#2B55E616", + "list.hoverBackground": "#E9EBEF", + "input.background": "#FFFFFF", + "editorGutter.background": "#FFFFFF", + "editorLineNumber.activeForeground": "#5D6472", + "editorLineNumber.foreground": "#CDD1D8", + "foreground": "#15181E", + "disabledForeground": "#9AA0AB", + "descriptionForeground": "#5D6472", + "editor.foreground": "#15181E", + "editorCursor.foreground": "#2B55E6", + "editorBracketMatch.background": "#2B55E616", + "editorBracketMatch.border": "#2B55E638", + "editorIndentGuide.background1": "#D8DBE1", + "editorIndentGuide.activeBackground1": "#B9BEC7", + "editorWhitespace.foreground": "#CDD1D8", + "editorBracketHighlight.foreground1": "#5D6472", + "editorBracketHighlight.foreground2": "#5D6472", + "editorBracketHighlight.foreground3": "#5D6472", + "editorBracketHighlight.foreground4": "#5D6472", + "editorBracketHighlight.foreground5": "#5D6472", + "editorBracketHighlight.foreground6": "#5D6472", + "editorBracketHighlight.unexpectedBracket.foreground": "#C93A27" + } +} diff --git a/apps/whiteboard-desktop/code-oss/extensions/ruby/.vscodeignore b/apps/review-desktop/code-oss/extensions/ruby/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ruby/.vscodeignore rename to apps/review-desktop/code-oss/extensions/ruby/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/ruby/cgmanifest.json b/apps/review-desktop/code-oss/extensions/ruby/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ruby/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/ruby/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ruby/language-configuration.json b/apps/review-desktop/code-oss/extensions/ruby/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ruby/language-configuration.json rename to apps/review-desktop/code-oss/extensions/ruby/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ruby/package.json b/apps/review-desktop/code-oss/extensions/ruby/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ruby/package.json rename to apps/review-desktop/code-oss/extensions/ruby/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ruby/package.nls.json b/apps/review-desktop/code-oss/extensions/ruby/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ruby/package.nls.json rename to apps/review-desktop/code-oss/extensions/ruby/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/ruby/syntaxes/ruby.tmLanguage.json b/apps/review-desktop/code-oss/extensions/ruby/syntaxes/ruby.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/ruby/syntaxes/ruby.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/ruby/syntaxes/ruby.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/.vscodeignore b/apps/review-desktop/code-oss/extensions/rust/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/.vscodeignore rename to apps/review-desktop/code-oss/extensions/rust/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/build/update-grammar.mjs b/apps/review-desktop/code-oss/extensions/rust/build/update-grammar.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/build/update-grammar.mjs rename to apps/review-desktop/code-oss/extensions/rust/build/update-grammar.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/cgmanifest.json b/apps/review-desktop/code-oss/extensions/rust/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/rust/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/language-configuration.json b/apps/review-desktop/code-oss/extensions/rust/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/language-configuration.json rename to apps/review-desktop/code-oss/extensions/rust/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/package.json b/apps/review-desktop/code-oss/extensions/rust/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/package.json rename to apps/review-desktop/code-oss/extensions/rust/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/package.nls.json b/apps/review-desktop/code-oss/extensions/rust/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/package.nls.json rename to apps/review-desktop/code-oss/extensions/rust/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/rust/syntaxes/rust.tmLanguage.json b/apps/review-desktop/code-oss/extensions/rust/syntaxes/rust.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/rust/syntaxes/rust.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/rust/syntaxes/rust.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/.vscodeignore b/apps/review-desktop/code-oss/extensions/scss/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/.vscodeignore rename to apps/review-desktop/code-oss/extensions/scss/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/cgmanifest.json b/apps/review-desktop/code-oss/extensions/scss/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/scss/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/language-configuration.json b/apps/review-desktop/code-oss/extensions/scss/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/language-configuration.json rename to apps/review-desktop/code-oss/extensions/scss/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/package.json b/apps/review-desktop/code-oss/extensions/scss/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/package.json rename to apps/review-desktop/code-oss/extensions/scss/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/package.nls.json b/apps/review-desktop/code-oss/extensions/scss/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/package.nls.json rename to apps/review-desktop/code-oss/extensions/scss/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/syntaxes/sassdoc.tmLanguage.json b/apps/review-desktop/code-oss/extensions/scss/syntaxes/sassdoc.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/syntaxes/sassdoc.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/scss/syntaxes/sassdoc.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/scss/syntaxes/scss.tmLanguage.json b/apps/review-desktop/code-oss/extensions/scss/syntaxes/scss.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/scss/syntaxes/scss.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/scss/syntaxes/scss.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shaderlab/.vscodeignore b/apps/review-desktop/code-oss/extensions/shaderlab/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shaderlab/.vscodeignore rename to apps/review-desktop/code-oss/extensions/shaderlab/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/shaderlab/cgmanifest.json b/apps/review-desktop/code-oss/extensions/shaderlab/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shaderlab/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/shaderlab/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shaderlab/language-configuration.json b/apps/review-desktop/code-oss/extensions/shaderlab/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shaderlab/language-configuration.json rename to apps/review-desktop/code-oss/extensions/shaderlab/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shaderlab/package.json b/apps/review-desktop/code-oss/extensions/shaderlab/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shaderlab/package.json rename to apps/review-desktop/code-oss/extensions/shaderlab/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shaderlab/package.nls.json b/apps/review-desktop/code-oss/extensions/shaderlab/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shaderlab/package.nls.json rename to apps/review-desktop/code-oss/extensions/shaderlab/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shaderlab/syntaxes/shaderlab.tmLanguage.json b/apps/review-desktop/code-oss/extensions/shaderlab/syntaxes/shaderlab.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shaderlab/syntaxes/shaderlab.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/shaderlab/syntaxes/shaderlab.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shellscript/.vscodeignore b/apps/review-desktop/code-oss/extensions/shellscript/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shellscript/.vscodeignore rename to apps/review-desktop/code-oss/extensions/shellscript/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/shellscript/cgmanifest.json b/apps/review-desktop/code-oss/extensions/shellscript/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shellscript/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/shellscript/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shellscript/language-configuration.json b/apps/review-desktop/code-oss/extensions/shellscript/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shellscript/language-configuration.json rename to apps/review-desktop/code-oss/extensions/shellscript/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shellscript/package.json b/apps/review-desktop/code-oss/extensions/shellscript/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shellscript/package.json rename to apps/review-desktop/code-oss/extensions/shellscript/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shellscript/package.nls.json b/apps/review-desktop/code-oss/extensions/shellscript/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shellscript/package.nls.json rename to apps/review-desktop/code-oss/extensions/shellscript/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json b/apps/review-desktop/code-oss/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/shellscript/syntaxes/shell-unix-bash.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/.vscodeignore b/apps/review-desktop/code-oss/extensions/sql/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/.vscodeignore rename to apps/review-desktop/code-oss/extensions/sql/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/build/update-grammar.mjs b/apps/review-desktop/code-oss/extensions/sql/build/update-grammar.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/build/update-grammar.mjs rename to apps/review-desktop/code-oss/extensions/sql/build/update-grammar.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/cgmanifest.json b/apps/review-desktop/code-oss/extensions/sql/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/sql/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/language-configuration.json b/apps/review-desktop/code-oss/extensions/sql/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/language-configuration.json rename to apps/review-desktop/code-oss/extensions/sql/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/package.json b/apps/review-desktop/code-oss/extensions/sql/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/package.json rename to apps/review-desktop/code-oss/extensions/sql/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/package.nls.json b/apps/review-desktop/code-oss/extensions/sql/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/package.nls.json rename to apps/review-desktop/code-oss/extensions/sql/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/sql/syntaxes/sql.tmLanguage.json b/apps/review-desktop/code-oss/extensions/sql/syntaxes/sql.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/sql/syntaxes/sql.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/sql/syntaxes/sql.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/.vscodeignore b/apps/review-desktop/code-oss/extensions/swift/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/.vscodeignore rename to apps/review-desktop/code-oss/extensions/swift/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/cgmanifest.json b/apps/review-desktop/code-oss/extensions/swift/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/swift/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/language-configuration.json b/apps/review-desktop/code-oss/extensions/swift/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/language-configuration.json rename to apps/review-desktop/code-oss/extensions/swift/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/package.json b/apps/review-desktop/code-oss/extensions/swift/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/package.json rename to apps/review-desktop/code-oss/extensions/swift/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/package.nls.json b/apps/review-desktop/code-oss/extensions/swift/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/package.nls.json rename to apps/review-desktop/code-oss/extensions/swift/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/snippets/swift.code-snippets b/apps/review-desktop/code-oss/extensions/swift/snippets/swift.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/snippets/swift.code-snippets rename to apps/review-desktop/code-oss/extensions/swift/snippets/swift.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/swift/syntaxes/swift.tmLanguage.json b/apps/review-desktop/code-oss/extensions/swift/syntaxes/swift.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/swift/syntaxes/swift.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/swift/syntaxes/swift.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-dark.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-dark.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-light.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-light.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/document-light.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-dark.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-dark.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-light.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-light.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-light.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-dark.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-dark.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-light.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-light.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/folder-open-light.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-dark.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-dark.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-light.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-light.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-light.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-dark.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-dark.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-light.svg b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-light.svg rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/images/root-folder-open-light.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/vs_minimal-icon-theme.json b/apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/vs_minimal-icon-theme.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/fileicons/vs_minimal-icon-theme.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/fileicons/vs_minimal-icon-theme.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/package.json b/apps/review-desktop/code-oss/extensions/theme-defaults/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/package.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/package.nls.json b/apps/review-desktop/code-oss/extensions/theme-defaults/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/package.nls.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/2026-dark.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/2026-dark.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/2026-dark.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/2026-dark.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/2026-light.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/2026-light.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/2026-light.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/2026-light.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/dark_modern.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/dark_modern.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/dark_modern.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/dark_modern.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/dark_plus.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/dark_plus.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/dark_plus.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/dark_plus.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/dark_vs.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/dark_vs.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/dark_vs.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/dark_vs.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/hc_black.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/hc_black.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/hc_black.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/hc_black.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/hc_light.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/hc_light.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/hc_light.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/hc_light.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/light_modern.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/light_modern.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/light_modern.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/light_modern.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/light_plus.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/light_plus.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/light_plus.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/light_plus.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/light_vs.json b/apps/review-desktop/code-oss/extensions/theme-defaults/themes/light_vs.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-defaults/themes/light_vs.json rename to apps/review-desktop/code-oss/extensions/theme-defaults/themes/light_vs.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/.vscodeignore b/apps/review-desktop/code-oss/extensions/theme-seti/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/.vscodeignore rename to apps/review-desktop/code-oss/extensions/theme-seti/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/CONTRIBUTING.md b/apps/review-desktop/code-oss/extensions/theme-seti/CONTRIBUTING.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/CONTRIBUTING.md rename to apps/review-desktop/code-oss/extensions/theme-seti/CONTRIBUTING.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/README.md b/apps/review-desktop/code-oss/extensions/theme-seti/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/README.md rename to apps/review-desktop/code-oss/extensions/theme-seti/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/ThirdPartyNotices.txt b/apps/review-desktop/code-oss/extensions/theme-seti/ThirdPartyNotices.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/ThirdPartyNotices.txt rename to apps/review-desktop/code-oss/extensions/theme-seti/ThirdPartyNotices.txt diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/build/update-icon-theme.js b/apps/review-desktop/code-oss/extensions/theme-seti/build/update-icon-theme.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/build/update-icon-theme.js rename to apps/review-desktop/code-oss/extensions/theme-seti/build/update-icon-theme.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/cgmanifest.json b/apps/review-desktop/code-oss/extensions/theme-seti/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/theme-seti/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/preview.html b/apps/review-desktop/code-oss/extensions/theme-seti/icons/preview.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/preview.html rename to apps/review-desktop/code-oss/extensions/theme-seti/icons/preview.html diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/seti-circular-128x128.png b/apps/review-desktop/code-oss/extensions/theme-seti/icons/seti-circular-128x128.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/seti-circular-128x128.png rename to apps/review-desktop/code-oss/extensions/theme-seti/icons/seti-circular-128x128.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/seti.woff b/apps/review-desktop/code-oss/extensions/theme-seti/icons/seti.woff similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/seti.woff rename to apps/review-desktop/code-oss/extensions/theme-seti/icons/seti.woff diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/vs-seti-icon-theme.json b/apps/review-desktop/code-oss/extensions/theme-seti/icons/vs-seti-icon-theme.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/icons/vs-seti-icon-theme.json rename to apps/review-desktop/code-oss/extensions/theme-seti/icons/vs-seti-icon-theme.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/package.json b/apps/review-desktop/code-oss/extensions/theme-seti/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/package.json rename to apps/review-desktop/code-oss/extensions/theme-seti/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/theme-seti/package.nls.json b/apps/review-desktop/code-oss/extensions/theme-seti/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/theme-seti/package.nls.json rename to apps/review-desktop/code-oss/extensions/theme-seti/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/tsconfig.base.json b/apps/review-desktop/code-oss/extensions/tsconfig.base.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/tsconfig.base.json rename to apps/review-desktop/code-oss/extensions/tsconfig.base.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/types/lib.textEncoder.d.ts b/apps/review-desktop/code-oss/extensions/types/lib.textEncoder.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/types/lib.textEncoder.d.ts rename to apps/review-desktop/code-oss/extensions/types/lib.textEncoder.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/types/lib.url.d.ts b/apps/review-desktop/code-oss/extensions/types/lib.url.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/types/lib.url.d.ts rename to apps/review-desktop/code-oss/extensions/types/lib.url.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/.vscodeignore b/apps/review-desktop/code-oss/extensions/typescript-basics/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/.vscodeignore rename to apps/review-desktop/code-oss/extensions/typescript-basics/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/build/update-grammars.mjs b/apps/review-desktop/code-oss/extensions/typescript-basics/build/update-grammars.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/build/update-grammars.mjs rename to apps/review-desktop/code-oss/extensions/typescript-basics/build/update-grammars.mjs diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/cgmanifest.json b/apps/review-desktop/code-oss/extensions/typescript-basics/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/language-configuration.json b/apps/review-desktop/code-oss/extensions/typescript-basics/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/language-configuration.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/package.json b/apps/review-desktop/code-oss/extensions/typescript-basics/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/package.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/package.nls.json b/apps/review-desktop/code-oss/extensions/typescript-basics/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/package.nls.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/snippets/typescript.code-snippets b/apps/review-desktop/code-oss/extensions/typescript-basics/snippets/typescript.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/snippets/typescript.code-snippets rename to apps/review-desktop/code-oss/extensions/typescript-basics/snippets/typescript.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/Readme.md b/apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/Readme.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/Readme.md rename to apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/Readme.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.js.injection.tmLanguage.json b/apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.js.injection.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.js.injection.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.js.injection.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.ts.injection.tmLanguage.json b/apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.ts.injection.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.ts.injection.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/typescript-basics/syntaxes/jsdoc.ts.injection.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/.npmrc b/apps/review-desktop/code-oss/extensions/typescript-language-features/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/.npmrc rename to apps/review-desktop/code-oss/extensions/typescript-language-features/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/.vscodeignore b/apps/review-desktop/code-oss/extensions/typescript-language-features/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/.vscodeignore rename to apps/review-desktop/code-oss/extensions/typescript-language-features/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/README.md b/apps/review-desktop/code-oss/extensions/typescript-language-features/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/README.md rename to apps/review-desktop/code-oss/extensions/typescript-language-features/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/cgmanifest.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/esbuild.browser.mts b/apps/review-desktop/code-oss/extensions/typescript-language-features/esbuild.browser.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/esbuild.browser.mts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/esbuild.browser.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/esbuild.mts b/apps/review-desktop/code-oss/extensions/typescript-language-features/esbuild.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/esbuild.mts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/esbuild.mts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/media/icon.png b/apps/review-desktop/code-oss/extensions/typescript-language-features/media/icon.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/media/icon.png rename to apps/review-desktop/code-oss/extensions/typescript-language-features/media/icon.png diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/package-lock.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/package-lock.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/package.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/package.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/package.nls.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/package.nls.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/create-a-js-file.svg b/apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/create-a-js-file.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/create-a-js-file.svg rename to apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/create-a-js-file.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/debug-and-run.svg b/apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/debug-and-run.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/debug-and-run.svg rename to apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/debug-and-run.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/install-node-js.svg b/apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/install-node-js.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/install-node-js.svg rename to apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/install-node-js.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/learn-more.svg b/apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/learn-more.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/learn-more.svg rename to apps/review-desktop/code-oss/extensions/typescript-language-features/resources/walkthroughs/learn-more.svg diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/schemas/jsconfig.schema.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/schemas/jsconfig.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/schemas/jsconfig.schema.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/schemas/jsconfig.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/schemas/package.schema.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/schemas/package.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/schemas/package.schema.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/schemas/package.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/schemas/tsconfig.schema.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/schemas/tsconfig.schema.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/schemas/tsconfig.schema.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/schemas/tsconfig.schema.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/api.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/api.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/api.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/api.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/commandManager.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/commandManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/commandManager.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/commandManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/configurePlugin.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/configurePlugin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/configurePlugin.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/configurePlugin.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/index.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/index.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/learnMoreAboutRefactorings.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/openJsDocLink.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/openJsDocLink.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/openJsDocLink.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/openJsDocLink.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/openTsServerLog.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/openTsServerLog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/openTsServerLog.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/openTsServerLog.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/reloadProject.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/reloadProject.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/reloadProject.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/reloadProject.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/restartTsServer.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/restartTsServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/restartTsServer.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/restartTsServer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/selectTypeScriptVersion.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/selectTypeScriptVersion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/selectTypeScriptVersion.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/selectTypeScriptVersion.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/tsserverRequests.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/tsserverRequests.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/tsserverRequests.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/tsserverRequests.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/useTsgo.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/useTsgo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/commands/useTsgo.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/commands/useTsgo.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.browser.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.browser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.browser.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.browser.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/configuration.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/documentSelector.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/documentSelector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/documentSelector.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/documentSelector.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/fileSchemes.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/fileSchemes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/fileSchemes.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/fileSchemes.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageDescription.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageDescription.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageDescription.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageDescription.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageIds.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageIds.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageIds.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/languageIds.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/schemes.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/schemes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/configuration/schemes.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/configuration/schemes.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/experimentTelemetryReporter.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/experimentTelemetryReporter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/experimentTelemetryReporter.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/experimentTelemetryReporter.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/experimentationService.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/experimentationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/experimentationService.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/experimentationService.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/extension.browser.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/extension.browser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/extension.browser.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/extension.browser.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/extension.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/extension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/extension.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/extension.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/filesystems/ata.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/filesystems/ata.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/filesystems/ata.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/filesystems/ata.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/filesystems/autoInstallerFs.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/filesystems/autoInstallerFs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/filesystems/autoInstallerFs.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/filesystems/autoInstallerFs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/filesystems/memFs.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/filesystems/memFs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/filesystems/memFs.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/filesystems/memFs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/callHierarchy.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/baseCodeLensProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/implementationsCodeLens.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/codeLens/referencesCodeLens.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/completions.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/completions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/completions.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/completions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitionProviderBase.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitions.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitions.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/definitions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/directiveCommentCompletions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentHighlight.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/documentSymbol.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileConfigurationManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fixAll.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fixAll.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fixAll.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/fixAll.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/folding.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/folding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/folding.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/folding.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/formatting.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/formatting.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/formatting.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/formatting.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/hover.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/hover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/hover.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/hover.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/implementations.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/implementations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/implementations.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/implementations.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/inlayHints.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/jsDocCompletions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/linkedEditing.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/linkedEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/linkedEditing.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/linkedEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/organizeImports.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/quickFix.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/quickFix.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/quickFix.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/quickFix.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/refactor.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/refactor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/refactor.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/refactor.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/references.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/references.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/references.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/references.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/rename.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/rename.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/rename.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/rename.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/semanticTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/smartSelect.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/sourceDefinition.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tagClosing.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/tsconfig.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/typeDefinitions.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/updatePathsOnRename.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/codeAction.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/copilot.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/copilot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/copilot.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/copilot.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/dependentRegistration.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/snippetForFunctionCall.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/util/textRendering.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageFeatures/workspaceSymbols.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/languageProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/languageProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/lazyClientHost.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/lazyClientHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/lazyClientHost.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/lazyClientHost.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/logLevelMonitor.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/logLevelMonitor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/logLevelMonitor.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/logLevelMonitor.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/logger.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/logger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/logger.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/logger.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/telemetry.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/telemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/telemetry.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/telemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/tracer.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/tracer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/logging/tracer.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/logging/tracer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/remoteRepositories.browser.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/remoteRepositories.browser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/remoteRepositories.browser.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/remoteRepositories.browser.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/task/taskProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/task/taskProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/task/taskProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/task/taskProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/task/tsconfigProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/task/tsconfigProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/task/tsconfigProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/task/tsconfigProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test-all.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test-all.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test-all.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test-all.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/index.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/index.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/completions.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/completions.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/completions.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/completions.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/fixAll.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/fixAll.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/fixAll.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/fixAll.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/implementationsCodeLens.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/implementationsCodeLens.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/implementationsCodeLens.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/implementationsCodeLens.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/index.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/index.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/jsDocCompletions.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/jsDocCompletions.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/jsDocCompletions.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/jsDocCompletions.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/quickFix.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/quickFix.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/quickFix.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/quickFix.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/referencesCodeLens.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/referencesCodeLens.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/referencesCodeLens.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/smoke/referencesCodeLens.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/suggestTestHelpers.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/suggestTestHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/suggestTestHelpers.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/suggestTestHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/testUtils.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/testUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/testUtils.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/testUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/cachedResponse.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/functionCallSnippet.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/index.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/index.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/jsdocSnippet.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/jsdocSnippet.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/jsdocSnippet.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/jsdocSnippet.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/onEnter.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/onEnter.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/onEnter.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/onEnter.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/requestQueue.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/requestQueue.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/requestQueue.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/requestQueue.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/server.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/server.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/server.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/server.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/textRendering.test.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/textRendering.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/test/unit/textRendering.test.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/test/unit/textRendering.test.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/api.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/api.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/api.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/api.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/bufferSyncSupport.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cachedResponse.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cachedResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cachedResponse.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cachedResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/callbackMap.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/callbackMap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/callbackMap.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/callbackMap.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/cancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/fileWatchingManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/logDirectoryProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/nodeManager.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/nodeManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/nodeManager.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/nodeManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/pluginPathsProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/plugins.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/plugins.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/plugins.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/plugins.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/errorCodes.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/errorCodes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/errorCodes.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/errorCodes.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/fixNames.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/modifiers.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/modifiers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/modifiers.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/modifiers.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.const.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.const.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.const.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.const.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/requestQueue.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/requestQueue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/requestQueue.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/requestQueue.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/server.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/server.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/server.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/server.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverError.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverError.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverError.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverError.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.browser.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/serverProcess.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/spawner.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/spawner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/spawner.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/spawner.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionManager.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionManager.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsServer/versionProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsconfig.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsconfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/tsconfig.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/tsconfig.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typeConverters.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/typeConverters.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typeConverters.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/typeConverters.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typescriptService.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/typescriptService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typescriptService.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/typescriptService.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typescriptServiceClient.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/typescriptServiceClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/typescriptServiceClient.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/typescriptServiceClient.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/activeJsTsEditorTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/intellisenseStatus.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/intellisenseStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/intellisenseStatus.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/intellisenseStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/largeProjectStatus.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/largeProjectStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/largeProjectStatus.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/largeProjectStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/managedFileContext.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/managedFileContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/managedFileContext.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/managedFileContext.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/suggestNativePreview.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/suggestNativePreview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/suggestNativePreview.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/suggestNativePreview.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/typingsStatus.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/typingsStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/typingsStatus.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/typingsStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/versionStatus.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/versionStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/ui/versionStatus.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/ui/versionStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/arrays.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/arrays.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/arrays.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/arrays.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/async.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/async.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/async.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/async.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/cancellation.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/cancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/cancellation.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/cancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/configuration.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/configuration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/configuration.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/configuration.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/dispose.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/dispose.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/dispose.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/dispose.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/fs.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/hash.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/hash.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/hash.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/hash.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/lazy.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/lazy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/lazy.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/lazy.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/objects.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/objects.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/objects.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/objects.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/packageInfo.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/packageInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/packageInfo.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/packageInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/platform.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/platform.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/platform.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/platform.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/regexp.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/regexp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/regexp.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/regexp.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/relativePathResolver.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/relativePathResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/relativePathResolver.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/relativePathResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/resourceMap.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/resourceMap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/resourceMap.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/resourceMap.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/temp.electron.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/temp.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/src/utils/temp.electron.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/src/utils/temp.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/bar.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/bar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/bar.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/bar.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/foo.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/foo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/foo.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/foo.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/foojs.js b/apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/foojs.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/foojs.js rename to apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/foojs.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/index.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/index.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/index.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/tsconfig.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/test-workspace/tsconfig.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/test-workspace/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/tsconfig.browser.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/tsconfig.browser.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/tsconfig.browser.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/tsconfig.browser.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/tsconfig.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/tsconfig.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/README.md b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/README.md rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/README.md diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/fileWatcherManager.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/fileWatcherManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/fileWatcherManager.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/fileWatcherManager.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/logging.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/logging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/logging.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/logging.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/pathMapper.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/pathMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/pathMapper.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/pathMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/serverHost.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/serverHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/serverHost.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/serverHost.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/jsTyping.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/jsTyping.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/jsTyping.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/jsTyping.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/typingsInstaller.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/typingsInstaller.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/typingsInstaller.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/typingsInstaller/typingsInstaller.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/util/args.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/util/args.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/util/args.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/util/args.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/util/hrtime.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/util/hrtime.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/util/hrtime.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/util/hrtime.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/wasmCancellationToken.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/wasmCancellationToken.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/wasmCancellationToken.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/wasmCancellationToken.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/webServer.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/webServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/webServer.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/webServer.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/workerSession.ts b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/workerSession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/src/workerSession.ts rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/src/workerSession.ts diff --git a/apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/tsconfig.json b/apps/review-desktop/code-oss/extensions/typescript-language-features/web/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/typescript-language-features/web/tsconfig.json rename to apps/review-desktop/code-oss/extensions/typescript-language-features/web/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/.vscodeignore b/apps/review-desktop/code-oss/extensions/vb/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/.vscodeignore rename to apps/review-desktop/code-oss/extensions/vb/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/cgmanifest.json b/apps/review-desktop/code-oss/extensions/vb/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/vb/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/language-configuration.json b/apps/review-desktop/code-oss/extensions/vb/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/language-configuration.json rename to apps/review-desktop/code-oss/extensions/vb/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/package.json b/apps/review-desktop/code-oss/extensions/vb/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/package.json rename to apps/review-desktop/code-oss/extensions/vb/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/package.nls.json b/apps/review-desktop/code-oss/extensions/vb/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/package.nls.json rename to apps/review-desktop/code-oss/extensions/vb/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/snippets/vb.code-snippets b/apps/review-desktop/code-oss/extensions/vb/snippets/vb.code-snippets similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/snippets/vb.code-snippets rename to apps/review-desktop/code-oss/extensions/vb/snippets/vb.code-snippets diff --git a/apps/whiteboard-desktop/code-oss/extensions/vb/syntaxes/asp-vb-net.tmLanguage.json b/apps/review-desktop/code-oss/extensions/vb/syntaxes/asp-vb-net.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/vb/syntaxes/asp-vb-net.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/vb/syntaxes/asp-vb-net.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/.vscodeignore b/apps/review-desktop/code-oss/extensions/xml/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/.vscodeignore rename to apps/review-desktop/code-oss/extensions/xml/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/cgmanifest.json b/apps/review-desktop/code-oss/extensions/xml/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/xml/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/package.json b/apps/review-desktop/code-oss/extensions/xml/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/package.json rename to apps/review-desktop/code-oss/extensions/xml/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/package.nls.json b/apps/review-desktop/code-oss/extensions/xml/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/package.nls.json rename to apps/review-desktop/code-oss/extensions/xml/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/syntaxes/xml.tmLanguage.json b/apps/review-desktop/code-oss/extensions/xml/syntaxes/xml.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/syntaxes/xml.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/xml/syntaxes/xml.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/syntaxes/xsl.tmLanguage.json b/apps/review-desktop/code-oss/extensions/xml/syntaxes/xsl.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/syntaxes/xsl.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/xml/syntaxes/xsl.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/xml.language-configuration.json b/apps/review-desktop/code-oss/extensions/xml/xml.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/xml.language-configuration.json rename to apps/review-desktop/code-oss/extensions/xml/xml.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/xml/xsl.language-configuration.json b/apps/review-desktop/code-oss/extensions/xml/xsl.language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/xml/xsl.language-configuration.json rename to apps/review-desktop/code-oss/extensions/xml/xsl.language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/.vscodeignore b/apps/review-desktop/code-oss/extensions/yaml/.vscodeignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/.vscodeignore rename to apps/review-desktop/code-oss/extensions/yaml/.vscodeignore diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/build/update-grammar.js b/apps/review-desktop/code-oss/extensions/yaml/build/update-grammar.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/build/update-grammar.js rename to apps/review-desktop/code-oss/extensions/yaml/build/update-grammar.js diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/cgmanifest.json b/apps/review-desktop/code-oss/extensions/yaml/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/cgmanifest.json rename to apps/review-desktop/code-oss/extensions/yaml/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/language-configuration.json b/apps/review-desktop/code-oss/extensions/yaml/language-configuration.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/language-configuration.json rename to apps/review-desktop/code-oss/extensions/yaml/language-configuration.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/package.json b/apps/review-desktop/code-oss/extensions/yaml/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/package.json rename to apps/review-desktop/code-oss/extensions/yaml/package.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/package.nls.json b/apps/review-desktop/code-oss/extensions/yaml/package.nls.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/package.nls.json rename to apps/review-desktop/code-oss/extensions/yaml/package.nls.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.0.tmLanguage.json b/apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.0.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.0.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.0.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.1.tmLanguage.json b/apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.1.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.1.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.1.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.2.tmLanguage.json b/apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.2.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.2.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.2.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.3.tmLanguage.json b/apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.3.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.3.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-1.3.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-embedded.tmLanguage.json b/apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-embedded.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml-embedded.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml-embedded.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml.tmLanguage.json b/apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml.tmLanguage.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/extensions/yaml/syntaxes/yaml.tmLanguage.json rename to apps/review-desktop/code-oss/extensions/yaml/syntaxes/yaml.tmLanguage.json diff --git a/apps/whiteboard-desktop/code-oss/gulpfile.mjs b/apps/review-desktop/code-oss/gulpfile.mjs similarity index 100% rename from apps/whiteboard-desktop/code-oss/gulpfile.mjs rename to apps/review-desktop/code-oss/gulpfile.mjs diff --git a/apps/whiteboard-desktop/code-oss/licenses/elkjs.txt b/apps/review-desktop/code-oss/licenses/elkjs.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/licenses/elkjs.txt rename to apps/review-desktop/code-oss/licenses/elkjs.txt diff --git a/apps/whiteboard-desktop/code-oss/licenses/eventsource-parser.txt b/apps/review-desktop/code-oss/licenses/eventsource-parser.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/licenses/eventsource-parser.txt rename to apps/review-desktop/code-oss/licenses/eventsource-parser.txt diff --git a/apps/whiteboard-desktop/code-oss/licenses/katex.txt b/apps/review-desktop/code-oss/licenses/katex.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/licenses/katex.txt rename to apps/review-desktop/code-oss/licenses/katex.txt diff --git a/apps/whiteboard-desktop/code-oss/licenses/libavoid-js.txt b/apps/review-desktop/code-oss/licenses/libavoid-js.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/licenses/libavoid-js.txt rename to apps/review-desktop/code-oss/licenses/libavoid-js.txt diff --git a/apps/whiteboard-desktop/code-oss/licenses/vscode-codicons.txt b/apps/review-desktop/code-oss/licenses/vscode-codicons.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/licenses/vscode-codicons.txt rename to apps/review-desktop/code-oss/licenses/vscode-codicons.txt diff --git a/apps/whiteboard-desktop/code-oss/licenses/zod.txt b/apps/review-desktop/code-oss/licenses/zod.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/licenses/zod.txt rename to apps/review-desktop/code-oss/licenses/zod.txt diff --git a/apps/whiteboard-desktop/code-oss/package-lock.json b/apps/review-desktop/code-oss/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/package-lock.json rename to apps/review-desktop/code-oss/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/package.json b/apps/review-desktop/code-oss/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/package.json rename to apps/review-desktop/code-oss/package.json diff --git a/apps/whiteboard-desktop/code-oss/product.json b/apps/review-desktop/code-oss/product.json similarity index 98% rename from apps/whiteboard-desktop/code-oss/product.json rename to apps/review-desktop/code-oss/product.json index 1178f9316..c9a69d9f3 100644 --- a/apps/whiteboard-desktop/code-oss/product.json +++ b/apps/review-desktop/code-oss/product.json @@ -1,6 +1,6 @@ { - "nameShort": "Whiteboard", - "nameLong": "/dev/fast Whiteboard", + "nameShort": "Review", + "nameLong": "/dev/fast Review", "reviewVersion": "0.0.33", "applicationName": "review", "dataFolderName": ".dev-fast-review", @@ -16,7 +16,7 @@ "serverDataFolderName": ".vscode-server-oss", "tunnelApplicationName": "code-tunnel-oss", "win32DirName": "Review", - "win32NameVersion": "/dev/fast Whiteboard", + "win32NameVersion": "/dev/fast Review", "win32RegValueName": "Review", "win32x64AppId": "{{B35E642E-885D-48BC-8386-C06377164CC5}", "win32arm64AppId": "{{6854770A-F656-4CAC-9F4C-A50D0B97F241}", diff --git a/apps/whiteboard-desktop/code-oss/remote/.npmrc b/apps/review-desktop/code-oss/remote/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/remote/.npmrc rename to apps/review-desktop/code-oss/remote/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/remote/package-lock.json b/apps/review-desktop/code-oss/remote/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/remote/package-lock.json rename to apps/review-desktop/code-oss/remote/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/remote/package.json b/apps/review-desktop/code-oss/remote/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/remote/package.json rename to apps/review-desktop/code-oss/remote/package.json diff --git a/apps/whiteboard-desktop/code-oss/remote/web/.npmrc b/apps/review-desktop/code-oss/remote/web/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/remote/web/.npmrc rename to apps/review-desktop/code-oss/remote/web/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/remote/web/package-lock.json b/apps/review-desktop/code-oss/remote/web/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/remote/web/package-lock.json rename to apps/review-desktop/code-oss/remote/web/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/remote/web/package.json b/apps/review-desktop/code-oss/remote/web/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/remote/web/package.json rename to apps/review-desktop/code-oss/remote/web/package.json diff --git a/apps/whiteboard-desktop/code-oss/resources/completions/bash/code b/apps/review-desktop/code-oss/resources/completions/bash/code similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/completions/bash/code rename to apps/review-desktop/code-oss/resources/completions/bash/code diff --git a/apps/whiteboard-desktop/code-oss/resources/completions/zsh/_code b/apps/review-desktop/code-oss/resources/completions/zsh/_code similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/completions/zsh/_code rename to apps/review-desktop/code-oss/resources/completions/zsh/_code diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/bat.icns b/apps/review-desktop/code-oss/resources/darwin/bat.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/bat.icns rename to apps/review-desktop/code-oss/resources/darwin/bat.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/bin/code.sh b/apps/review-desktop/code-oss/resources/darwin/bin/code.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/bin/code.sh rename to apps/review-desktop/code-oss/resources/darwin/bin/code.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/bower.icns b/apps/review-desktop/code-oss/resources/darwin/bower.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/bower.icns rename to apps/review-desktop/code-oss/resources/darwin/bower.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/c.icns b/apps/review-desktop/code-oss/resources/darwin/c.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/c.icns rename to apps/review-desktop/code-oss/resources/darwin/c.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/code.icns b/apps/review-desktop/code-oss/resources/darwin/code.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/code.icns rename to apps/review-desktop/code-oss/resources/darwin/code.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/config.icns b/apps/review-desktop/code-oss/resources/darwin/config.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/config.icns rename to apps/review-desktop/code-oss/resources/darwin/config.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/cpp.icns b/apps/review-desktop/code-oss/resources/darwin/cpp.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/cpp.icns rename to apps/review-desktop/code-oss/resources/darwin/cpp.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/csharp.icns b/apps/review-desktop/code-oss/resources/darwin/csharp.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/csharp.icns rename to apps/review-desktop/code-oss/resources/darwin/csharp.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/css.icns b/apps/review-desktop/code-oss/resources/darwin/css.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/css.icns rename to apps/review-desktop/code-oss/resources/darwin/css.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/default.icns b/apps/review-desktop/code-oss/resources/darwin/default.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/default.icns rename to apps/review-desktop/code-oss/resources/darwin/default.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/go.icns b/apps/review-desktop/code-oss/resources/darwin/go.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/go.icns rename to apps/review-desktop/code-oss/resources/darwin/go.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/html.icns b/apps/review-desktop/code-oss/resources/darwin/html.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/html.icns rename to apps/review-desktop/code-oss/resources/darwin/html.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/jade.icns b/apps/review-desktop/code-oss/resources/darwin/jade.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/jade.icns rename to apps/review-desktop/code-oss/resources/darwin/jade.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/java.icns b/apps/review-desktop/code-oss/resources/darwin/java.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/java.icns rename to apps/review-desktop/code-oss/resources/darwin/java.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/javascript.icns b/apps/review-desktop/code-oss/resources/darwin/javascript.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/javascript.icns rename to apps/review-desktop/code-oss/resources/darwin/javascript.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/json.icns b/apps/review-desktop/code-oss/resources/darwin/json.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/json.icns rename to apps/review-desktop/code-oss/resources/darwin/json.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/less.icns b/apps/review-desktop/code-oss/resources/darwin/less.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/less.icns rename to apps/review-desktop/code-oss/resources/darwin/less.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/markdown.icns b/apps/review-desktop/code-oss/resources/darwin/markdown.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/markdown.icns rename to apps/review-desktop/code-oss/resources/darwin/markdown.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/php.icns b/apps/review-desktop/code-oss/resources/darwin/php.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/php.icns rename to apps/review-desktop/code-oss/resources/darwin/php.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/powershell.icns b/apps/review-desktop/code-oss/resources/darwin/powershell.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/powershell.icns rename to apps/review-desktop/code-oss/resources/darwin/powershell.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/python.icns b/apps/review-desktop/code-oss/resources/darwin/python.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/python.icns rename to apps/review-desktop/code-oss/resources/darwin/python.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/react.icns b/apps/review-desktop/code-oss/resources/darwin/react.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/react.icns rename to apps/review-desktop/code-oss/resources/darwin/react.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/ruby.icns b/apps/review-desktop/code-oss/resources/darwin/ruby.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/ruby.icns rename to apps/review-desktop/code-oss/resources/darwin/ruby.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/sass.icns b/apps/review-desktop/code-oss/resources/darwin/sass.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/sass.icns rename to apps/review-desktop/code-oss/resources/darwin/sass.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/shell.icns b/apps/review-desktop/code-oss/resources/darwin/shell.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/shell.icns rename to apps/review-desktop/code-oss/resources/darwin/shell.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/sql.icns b/apps/review-desktop/code-oss/resources/darwin/sql.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/sql.icns rename to apps/review-desktop/code-oss/resources/darwin/sql.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/typescript.icns b/apps/review-desktop/code-oss/resources/darwin/typescript.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/typescript.icns rename to apps/review-desktop/code-oss/resources/darwin/typescript.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/vue.icns b/apps/review-desktop/code-oss/resources/darwin/vue.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/vue.icns rename to apps/review-desktop/code-oss/resources/darwin/vue.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/xml.icns b/apps/review-desktop/code-oss/resources/darwin/xml.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/xml.icns rename to apps/review-desktop/code-oss/resources/darwin/xml.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/darwin/yaml.icns b/apps/review-desktop/code-oss/resources/darwin/yaml.icns similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/darwin/yaml.icns rename to apps/review-desktop/code-oss/resources/darwin/yaml.icns diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/bin/code.sh b/apps/review-desktop/code-oss/resources/linux/bin/code.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/bin/code.sh rename to apps/review-desktop/code-oss/resources/linux/bin/code.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/code-url-handler.desktop b/apps/review-desktop/code-oss/resources/linux/code-url-handler.desktop similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/code-url-handler.desktop rename to apps/review-desktop/code-oss/resources/linux/code-url-handler.desktop diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/code-workspace.xml b/apps/review-desktop/code-oss/resources/linux/code-workspace.xml similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/code-workspace.xml rename to apps/review-desktop/code-oss/resources/linux/code-workspace.xml diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/code.appdata.xml b/apps/review-desktop/code-oss/resources/linux/code.appdata.xml similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/code.appdata.xml rename to apps/review-desktop/code-oss/resources/linux/code.appdata.xml diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/code.desktop b/apps/review-desktop/code-oss/resources/linux/code.desktop similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/code.desktop rename to apps/review-desktop/code-oss/resources/linux/code.desktop diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/code.png b/apps/review-desktop/code-oss/resources/linux/code.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/code.png rename to apps/review-desktop/code-oss/resources/linux/code.png diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/debian/control.template b/apps/review-desktop/code-oss/resources/linux/debian/control.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/debian/control.template rename to apps/review-desktop/code-oss/resources/linux/debian/control.template diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/debian/postinst.template b/apps/review-desktop/code-oss/resources/linux/debian/postinst.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/debian/postinst.template rename to apps/review-desktop/code-oss/resources/linux/debian/postinst.template diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/debian/postrm.template b/apps/review-desktop/code-oss/resources/linux/debian/postrm.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/debian/postrm.template rename to apps/review-desktop/code-oss/resources/linux/debian/postrm.template diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/debian/prerm.template b/apps/review-desktop/code-oss/resources/linux/debian/prerm.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/debian/prerm.template rename to apps/review-desktop/code-oss/resources/linux/debian/prerm.template diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/debian/templates.template b/apps/review-desktop/code-oss/resources/linux/debian/templates.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/debian/templates.template rename to apps/review-desktop/code-oss/resources/linux/debian/templates.template diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/rpm/code.spec.template b/apps/review-desktop/code-oss/resources/linux/rpm/code.spec.template similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/rpm/code.spec.template rename to apps/review-desktop/code-oss/resources/linux/rpm/code.spec.template diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/rpm/code.xpm b/apps/review-desktop/code-oss/resources/linux/rpm/code.xpm similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/rpm/code.xpm rename to apps/review-desktop/code-oss/resources/linux/rpm/code.xpm diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/snap/electron-launch b/apps/review-desktop/code-oss/resources/linux/snap/electron-launch similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/snap/electron-launch rename to apps/review-desktop/code-oss/resources/linux/snap/electron-launch diff --git a/apps/whiteboard-desktop/code-oss/resources/linux/snap/snapcraft.yaml b/apps/review-desktop/code-oss/resources/linux/snap/snapcraft.yaml similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/linux/snap/snapcraft.yaml rename to apps/review-desktop/code-oss/resources/linux/snap/snapcraft.yaml diff --git a/apps/review-desktop/code-oss/resources/server/bin-dev/helpers/browser.cmd b/apps/review-desktop/code-oss/resources/server/bin-dev/helpers/browser.cmd new file mode 100644 index 000000000..be28cdc7c --- /dev/null +++ b/apps/review-desktop/code-oss/resources/server/bin-dev/helpers/browser.cmd @@ -0,0 +1,6 @@ +@echo off +setlocal +SET VSCODE_PATH=%~dp0..\..\..\.. +FOR /F "tokens=* USEBACKQ" %%g IN (`where /r "%VSCODE_PATH%\.build\node" node.exe`) do (SET "NODE=%%g") +call "%NODE%" "%VSCODE_PATH%\out\server-cli.js" "Code Server - Dev" "" "" "code.cmd" "--openExternal" %* +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/helpers/browser.sh b/apps/review-desktop/code-oss/resources/server/bin-dev/helpers/browser.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin-dev/helpers/browser.sh rename to apps/review-desktop/code-oss/resources/server/bin-dev/helpers/browser.sh diff --git a/apps/review-desktop/code-oss/resources/server/bin-dev/remote-cli/code.cmd b/apps/review-desktop/code-oss/resources/server/bin-dev/remote-cli/code.cmd new file mode 100644 index 000000000..aced2a4de --- /dev/null +++ b/apps/review-desktop/code-oss/resources/server/bin-dev/remote-cli/code.cmd @@ -0,0 +1,7 @@ +@echo off +setlocal +SET VSCODE_PATH=%~dp0..\..\..\.. +SET VSCODE_DEV=1 +FOR /F "tokens=* USEBACKQ" %%g IN (`where /r "%VSCODE_PATH%\.build\node" node.exe`) do (SET "NODE=%%g") +call "%NODE%" "%VSCODE_PATH%\out\server-cli.js" "Code Server - Dev" "" "" "code.cmd" %* +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/remote-cli/code.sh b/apps/review-desktop/code-oss/resources/server/bin-dev/remote-cli/code.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin-dev/remote-cli/code.sh rename to apps/review-desktop/code-oss/resources/server/bin-dev/remote-cli/code.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/code-server-darwin.sh b/apps/review-desktop/code-oss/resources/server/bin/code-server-darwin.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/code-server-darwin.sh rename to apps/review-desktop/code-oss/resources/server/bin/code-server-darwin.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/code-server-linux.sh b/apps/review-desktop/code-oss/resources/server/bin/code-server-linux.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/code-server-linux.sh rename to apps/review-desktop/code-oss/resources/server/bin/code-server-linux.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/code-server.cmd b/apps/review-desktop/code-oss/resources/server/bin/code-server.cmd similarity index 93% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/code-server.cmd rename to apps/review-desktop/code-oss/resources/server/bin/code-server.cmd index d2bebf818..8753fb2a9 100644 --- a/apps/whiteboard-desktop/code-oss/resources/server/bin/code-server.cmd +++ b/apps/review-desktop/code-oss/resources/server/bin/code-server.cmd @@ -1,24 +1,24 @@ -@echo off -setlocal - -set ROOT_DIR=%~dp0.. - -set _FIRST_ARG=%1 -if "%_FIRST_ARG:~0,9%"=="--inspect" ( - set INSPECT=%1 - shift -) else ( - set INSPECT= -) - -:loop1 -if "%~1"=="" goto after_loop -set RESTVAR=%RESTVAR% %1 -shift -goto loop1 - -:after_loop - -"%ROOT_DIR%\node.exe" %INSPECT% "%ROOT_DIR%\out\server-main.js" %RESTVAR% - -endlocal +@echo off +setlocal + +set ROOT_DIR=%~dp0.. + +set _FIRST_ARG=%1 +if "%_FIRST_ARG:~0,9%"=="--inspect" ( + set INSPECT=%1 + shift +) else ( + set INSPECT= +) + +:loop1 +if "%~1"=="" goto after_loop +set RESTVAR=%RESTVAR% %1 +shift +goto loop1 + +:after_loop + +"%ROOT_DIR%\node.exe" %INSPECT% "%ROOT_DIR%\out\server-main.js" %RESTVAR% + +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser-darwin.sh b/apps/review-desktop/code-oss/resources/server/bin/helpers/browser-darwin.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser-darwin.sh rename to apps/review-desktop/code-oss/resources/server/bin/helpers/browser-darwin.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser-linux.sh b/apps/review-desktop/code-oss/resources/server/bin/helpers/browser-linux.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser-linux.sh rename to apps/review-desktop/code-oss/resources/server/bin/helpers/browser-linux.sh diff --git a/apps/review-desktop/code-oss/resources/server/bin/helpers/browser.cmd b/apps/review-desktop/code-oss/resources/server/bin/helpers/browser.cmd new file mode 100644 index 000000000..f110f4cdc --- /dev/null +++ b/apps/review-desktop/code-oss/resources/server/bin/helpers/browser.cmd @@ -0,0 +1,5 @@ +@echo off +setlocal +set ROOT_DIR=%~dp0..\.. +start "Open Browser" /B "%ROOT_DIR%\node.exe" "%ROOT_DIR%\out\server-cli.js" "@@APPNAME@@" "@@VERSION@@" "@@COMMIT@@" "@@APPNAME@@.cmd" "--openExternal" "%*" +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/check-requirements-linux.sh b/apps/review-desktop/code-oss/resources/server/bin/helpers/check-requirements-linux.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/check-requirements-linux.sh rename to apps/review-desktop/code-oss/resources/server/bin/helpers/check-requirements-linux.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code-darwin.sh b/apps/review-desktop/code-oss/resources/server/bin/remote-cli/code-darwin.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code-darwin.sh rename to apps/review-desktop/code-oss/resources/server/bin/remote-cli/code-darwin.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code-linux.sh b/apps/review-desktop/code-oss/resources/server/bin/remote-cli/code-linux.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code-linux.sh rename to apps/review-desktop/code-oss/resources/server/bin/remote-cli/code-linux.sh diff --git a/apps/review-desktop/code-oss/resources/server/bin/remote-cli/code.cmd b/apps/review-desktop/code-oss/resources/server/bin/remote-cli/code.cmd new file mode 100644 index 000000000..43a35c49c --- /dev/null +++ b/apps/review-desktop/code-oss/resources/server/bin/remote-cli/code.cmd @@ -0,0 +1,5 @@ +@echo off +setlocal +set ROOT_DIR=%~dp0..\.. +call "%ROOT_DIR%\node.exe" "%ROOT_DIR%\out\server-cli.js" "@@APPNAME@@" "@@VERSION@@" "@@COMMIT@@" "@@APPNAME@@.cmd" %* +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/code-192.png b/apps/review-desktop/code-oss/resources/server/code-192.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/code-192.png rename to apps/review-desktop/code-oss/resources/server/code-192.png diff --git a/apps/whiteboard-desktop/code-oss/resources/server/code-512.png b/apps/review-desktop/code-oss/resources/server/code-512.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/code-512.png rename to apps/review-desktop/code-oss/resources/server/code-512.png diff --git a/apps/whiteboard-desktop/code-oss/resources/server/favicon.ico b/apps/review-desktop/code-oss/resources/server/favicon.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/favicon.ico rename to apps/review-desktop/code-oss/resources/server/favicon.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/server/manifest.json b/apps/review-desktop/code-oss/resources/server/manifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/server/manifest.json rename to apps/review-desktop/code-oss/resources/server/manifest.json diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/VisualElementsManifest.xml b/apps/review-desktop/code-oss/resources/win32/VisualElementsManifest.xml similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/VisualElementsManifest.xml rename to apps/review-desktop/code-oss/resources/win32/VisualElementsManifest.xml diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/appx/AppxManifest.xml b/apps/review-desktop/code-oss/resources/win32/appx/AppxManifest.xml similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/appx/AppxManifest.xml rename to apps/review-desktop/code-oss/resources/win32/appx/AppxManifest.xml diff --git a/apps/review-desktop/code-oss/resources/win32/bin/code.cmd b/apps/review-desktop/code-oss/resources/win32/bin/code.cmd new file mode 100644 index 000000000..07ae27e60 --- /dev/null +++ b/apps/review-desktop/code-oss/resources/win32/bin/code.cmd @@ -0,0 +1,7 @@ +@echo off +setlocal +set VSCODE_DEV= +set ELECTRON_RUN_AS_NODE=1 +"%~dp0..\@@NAME@@.exe" "%~dp0..\resources\app\out\cli.js" %* +IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL% +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/bin/code.sh b/apps/review-desktop/code-oss/resources/win32/bin/code.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/bin/code.sh rename to apps/review-desktop/code-oss/resources/win32/bin/code.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/bower.ico b/apps/review-desktop/code-oss/resources/win32/bower.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/bower.ico rename to apps/review-desktop/code-oss/resources/win32/bower.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/c.ico b/apps/review-desktop/code-oss/resources/win32/c.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/c.ico rename to apps/review-desktop/code-oss/resources/win32/c.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/code.ico b/apps/review-desktop/code-oss/resources/win32/code.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/code.ico rename to apps/review-desktop/code-oss/resources/win32/code.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/code_150x150.png b/apps/review-desktop/code-oss/resources/win32/code_150x150.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/code_150x150.png rename to apps/review-desktop/code-oss/resources/win32/code_150x150.png diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/code_70x70.png b/apps/review-desktop/code-oss/resources/win32/code_70x70.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/code_70x70.png rename to apps/review-desktop/code-oss/resources/win32/code_70x70.png diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/config.ico b/apps/review-desktop/code-oss/resources/win32/config.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/config.ico rename to apps/review-desktop/code-oss/resources/win32/config.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/cpp.ico b/apps/review-desktop/code-oss/resources/win32/cpp.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/cpp.ico rename to apps/review-desktop/code-oss/resources/win32/cpp.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/csharp.ico b/apps/review-desktop/code-oss/resources/win32/csharp.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/csharp.ico rename to apps/review-desktop/code-oss/resources/win32/csharp.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/css.ico b/apps/review-desktop/code-oss/resources/win32/css.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/css.ico rename to apps/review-desktop/code-oss/resources/win32/css.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/default.ico b/apps/review-desktop/code-oss/resources/win32/default.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/default.ico rename to apps/review-desktop/code-oss/resources/win32/default.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/go.ico b/apps/review-desktop/code-oss/resources/win32/go.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/go.ico rename to apps/review-desktop/code-oss/resources/win32/go.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/html.ico b/apps/review-desktop/code-oss/resources/win32/html.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/html.ico rename to apps/review-desktop/code-oss/resources/win32/html.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-100.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-100.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-100.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-100.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-125.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-125.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-125.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-125.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-150.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-150.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-150.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-150.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-175.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-175.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-175.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-175.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-200.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-200.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-200.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-200.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-225.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-225.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-225.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-225.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-big-250.bmp b/apps/review-desktop/code-oss/resources/win32/inno-big-250.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-big-250.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-big-250.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-100.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-100.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-100.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-100.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-125.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-125.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-125.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-125.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-150.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-150.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-150.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-150.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-175.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-175.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-175.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-175.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-200.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-200.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-200.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-200.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-225.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-225.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-225.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-225.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/inno-small-250.bmp b/apps/review-desktop/code-oss/resources/win32/inno-small-250.bmp similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/inno-small-250.bmp rename to apps/review-desktop/code-oss/resources/win32/inno-small-250.bmp diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/jade.ico b/apps/review-desktop/code-oss/resources/win32/jade.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/jade.ico rename to apps/review-desktop/code-oss/resources/win32/jade.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/java.ico b/apps/review-desktop/code-oss/resources/win32/java.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/java.ico rename to apps/review-desktop/code-oss/resources/win32/java.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/javascript.ico b/apps/review-desktop/code-oss/resources/win32/javascript.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/javascript.ico rename to apps/review-desktop/code-oss/resources/win32/javascript.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/json.ico b/apps/review-desktop/code-oss/resources/win32/json.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/json.ico rename to apps/review-desktop/code-oss/resources/win32/json.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/less.ico b/apps/review-desktop/code-oss/resources/win32/less.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/less.ico rename to apps/review-desktop/code-oss/resources/win32/less.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/markdown.ico b/apps/review-desktop/code-oss/resources/win32/markdown.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/markdown.ico rename to apps/review-desktop/code-oss/resources/win32/markdown.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/php.ico b/apps/review-desktop/code-oss/resources/win32/php.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/php.ico rename to apps/review-desktop/code-oss/resources/win32/php.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/powershell.ico b/apps/review-desktop/code-oss/resources/win32/powershell.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/powershell.ico rename to apps/review-desktop/code-oss/resources/win32/powershell.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/python.ico b/apps/review-desktop/code-oss/resources/win32/python.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/python.ico rename to apps/review-desktop/code-oss/resources/win32/python.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/react.ico b/apps/review-desktop/code-oss/resources/win32/react.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/react.ico rename to apps/review-desktop/code-oss/resources/win32/react.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/ruby.ico b/apps/review-desktop/code-oss/resources/win32/ruby.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/ruby.ico rename to apps/review-desktop/code-oss/resources/win32/ruby.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/sass.ico b/apps/review-desktop/code-oss/resources/win32/sass.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/sass.ico rename to apps/review-desktop/code-oss/resources/win32/sass.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/shell.ico b/apps/review-desktop/code-oss/resources/win32/shell.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/shell.ico rename to apps/review-desktop/code-oss/resources/win32/shell.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/sql.ico b/apps/review-desktop/code-oss/resources/win32/sql.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/sql.ico rename to apps/review-desktop/code-oss/resources/win32/sql.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/typescript.ico b/apps/review-desktop/code-oss/resources/win32/typescript.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/typescript.ico rename to apps/review-desktop/code-oss/resources/win32/typescript.ico diff --git a/apps/review-desktop/code-oss/resources/win32/versioned/bin/code.cmd b/apps/review-desktop/code-oss/resources/win32/versioned/bin/code.cmd new file mode 100644 index 000000000..0bc42516f --- /dev/null +++ b/apps/review-desktop/code-oss/resources/win32/versioned/bin/code.cmd @@ -0,0 +1,7 @@ +@echo off +setlocal +set VSCODE_DEV= +set ELECTRON_RUN_AS_NODE=1 +"%~dp0..\@@NAME@@.exe" "%~dp0..\@@VERSIONFOLDER@@\resources\app\out\cli.js" %* +IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL% +endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/versioned/bin/code.sh b/apps/review-desktop/code-oss/resources/win32/versioned/bin/code.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/versioned/bin/code.sh rename to apps/review-desktop/code-oss/resources/win32/versioned/bin/code.sh diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/vue.ico b/apps/review-desktop/code-oss/resources/win32/vue.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/vue.ico rename to apps/review-desktop/code-oss/resources/win32/vue.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/xml.ico b/apps/review-desktop/code-oss/resources/win32/xml.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/xml.ico rename to apps/review-desktop/code-oss/resources/win32/xml.ico diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/yaml.ico b/apps/review-desktop/code-oss/resources/win32/yaml.ico similarity index 100% rename from apps/whiteboard-desktop/code-oss/resources/win32/yaml.ico rename to apps/review-desktop/code-oss/resources/win32/yaml.ico diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/common/mock-llm-server.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/common/mock-llm-server.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/common/mock-llm-server.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/common/mock-llm-server.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/common/perf-scenarios.js b/apps/review-desktop/code-oss/scripts/chat-simulation/common/perf-scenarios.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/common/perf-scenarios.js rename to apps/review-desktop/code-oss/scripts/chat-simulation/common/perf-scenarios.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/common/utils.js b/apps/review-desktop/code-oss/scripts/chat-simulation/common/utils.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/common/utils.js rename to apps/review-desktop/code-oss/scripts/chat-simulation/common/utils.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/config.jsonc b/apps/review-desktop/code-oss/scripts/chat-simulation/config.jsonc similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/config.jsonc rename to apps/review-desktop/code-oss/scripts/chat-simulation/config.jsonc diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_arrays.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_arrays.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_arrays.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_arrays.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_async.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_async.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_async.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_async.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_errors.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_errors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_errors.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_errors.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_event.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_event.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_event.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_event.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_lifecycle.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_lifecycle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_lifecycle.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_lifecycle.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_strings.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_strings.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_strings.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_types.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_types.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_types.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_uri.ts b/apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_uri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_uri.ts rename to apps/review-desktop/code-oss/scripts/chat-simulation/fixtures/_chatperf_uri.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/jsconfig.json b/apps/review-desktop/code-oss/scripts/chat-simulation/jsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/jsconfig.json rename to apps/review-desktop/code-oss/scripts/chat-simulation/jsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/merge-ci-summary.js b/apps/review-desktop/code-oss/scripts/chat-simulation/merge-ci-summary.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/merge-ci-summary.js rename to apps/review-desktop/code-oss/scripts/chat-simulation/merge-ci-summary.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/test-chat-mem-leaks.js b/apps/review-desktop/code-oss/scripts/chat-simulation/test-chat-mem-leaks.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/test-chat-mem-leaks.js rename to apps/review-desktop/code-oss/scripts/chat-simulation/test-chat-mem-leaks.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/chat-simulation/test-chat-perf-regression.js b/apps/review-desktop/code-oss/scripts/chat-simulation/test-chat-perf-regression.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/chat-simulation/test-chat-perf-regression.js rename to apps/review-desktop/code-oss/scripts/chat-simulation/test-chat-perf-regression.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-agent-host.js b/apps/review-desktop/code-oss/scripts/code-agent-host.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-agent-host.js rename to apps/review-desktop/code-oss/scripts/code-agent-host.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-agent-host.sh b/apps/review-desktop/code-oss/scripts/code-agent-host.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-agent-host.sh rename to apps/review-desktop/code-oss/scripts/code-agent-host.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-cli.bat b/apps/review-desktop/code-oss/scripts/code-cli.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-cli.bat rename to apps/review-desktop/code-oss/scripts/code-cli.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-cli.sh b/apps/review-desktop/code-oss/scripts/code-cli.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-cli.sh rename to apps/review-desktop/code-oss/scripts/code-cli.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-perf.js b/apps/review-desktop/code-oss/scripts/code-perf.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-perf.js rename to apps/review-desktop/code-oss/scripts/code-perf.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-server.bat b/apps/review-desktop/code-oss/scripts/code-server.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-server.bat rename to apps/review-desktop/code-oss/scripts/code-server.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-server.js b/apps/review-desktop/code-oss/scripts/code-server.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-server.js rename to apps/review-desktop/code-oss/scripts/code-server.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-server.sh b/apps/review-desktop/code-oss/scripts/code-server.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-server.sh rename to apps/review-desktop/code-oss/scripts/code-server.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-web.bat b/apps/review-desktop/code-oss/scripts/code-web.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-web.bat rename to apps/review-desktop/code-oss/scripts/code-web.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-web.js b/apps/review-desktop/code-oss/scripts/code-web.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-web.js rename to apps/review-desktop/code-oss/scripts/code-web.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/code-web.sh b/apps/review-desktop/code-oss/scripts/code-web.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code-web.sh rename to apps/review-desktop/code-oss/scripts/code-web.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/code.bat b/apps/review-desktop/code-oss/scripts/code.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code.bat rename to apps/review-desktop/code-oss/scripts/code.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/code.sh b/apps/review-desktop/code-oss/scripts/code.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/code.sh rename to apps/review-desktop/code-oss/scripts/code.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/generate-definitelytyped.sh b/apps/review-desktop/code-oss/scripts/generate-definitelytyped.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/generate-definitelytyped.sh rename to apps/review-desktop/code-oss/scripts/generate-definitelytyped.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/README.md b/apps/review-desktop/code-oss/scripts/mock-policy-server/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/README.md rename to apps/review-desktop/code-oss/scripts/mock-policy-server/README.md diff --git a/apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/endpoints.ts b/apps/review-desktop/code-oss/scripts/mock-policy-server/endpoints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/endpoints.ts rename to apps/review-desktop/code-oss/scripts/mock-policy-server/endpoints.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/public/app.ts b/apps/review-desktop/code-oss/scripts/mock-policy-server/public/app.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/public/app.ts rename to apps/review-desktop/code-oss/scripts/mock-policy-server/public/app.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/public/index.html b/apps/review-desktop/code-oss/scripts/mock-policy-server/public/index.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/public/index.html rename to apps/review-desktop/code-oss/scripts/mock-policy-server/public/index.html diff --git a/apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/public/style.css b/apps/review-desktop/code-oss/scripts/mock-policy-server/public/style.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/public/style.css rename to apps/review-desktop/code-oss/scripts/mock-policy-server/public/style.css diff --git a/apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/server.ts b/apps/review-desktop/code-oss/scripts/mock-policy-server/server.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/mock-policy-server/server.ts rename to apps/review-desktop/code-oss/scripts/mock-policy-server/server.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/node-electron.bat b/apps/review-desktop/code-oss/scripts/node-electron.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/node-electron.bat rename to apps/review-desktop/code-oss/scripts/node-electron.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/node-electron.sh b/apps/review-desktop/code-oss/scripts/node-electron.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/node-electron.sh rename to apps/review-desktop/code-oss/scripts/node-electron.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/package.json b/apps/review-desktop/code-oss/scripts/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/package.json rename to apps/review-desktop/code-oss/scripts/package.json diff --git a/apps/whiteboard-desktop/code-oss/scripts/sync-agent-host-protocol.ts b/apps/review-desktop/code-oss/scripts/sync-agent-host-protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/sync-agent-host-protocol.ts rename to apps/review-desktop/code-oss/scripts/sync-agent-host-protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-documentation.bat b/apps/review-desktop/code-oss/scripts/test-documentation.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-documentation.bat rename to apps/review-desktop/code-oss/scripts/test-documentation.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-documentation.sh b/apps/review-desktop/code-oss/scripts/test-documentation.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-documentation.sh rename to apps/review-desktop/code-oss/scripts/test-documentation.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-integration.bat b/apps/review-desktop/code-oss/scripts/test-integration.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-integration.bat rename to apps/review-desktop/code-oss/scripts/test-integration.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-integration.sh b/apps/review-desktop/code-oss/scripts/test-integration.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-integration.sh rename to apps/review-desktop/code-oss/scripts/test-integration.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-remote-integration.bat b/apps/review-desktop/code-oss/scripts/test-remote-integration.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-remote-integration.bat rename to apps/review-desktop/code-oss/scripts/test-remote-integration.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-remote-integration.sh b/apps/review-desktop/code-oss/scripts/test-remote-integration.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-remote-integration.sh rename to apps/review-desktop/code-oss/scripts/test-remote-integration.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-web-integration.bat b/apps/review-desktop/code-oss/scripts/test-web-integration.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-web-integration.bat rename to apps/review-desktop/code-oss/scripts/test-web-integration.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/test-web-integration.sh b/apps/review-desktop/code-oss/scripts/test-web-integration.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test-web-integration.sh rename to apps/review-desktop/code-oss/scripts/test-web-integration.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/test.bat b/apps/review-desktop/code-oss/scripts/test.bat similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test.bat rename to apps/review-desktop/code-oss/scripts/test.bat diff --git a/apps/whiteboard-desktop/code-oss/scripts/test.sh b/apps/review-desktop/code-oss/scripts/test.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/test.sh rename to apps/review-desktop/code-oss/scripts/test.sh diff --git a/apps/whiteboard-desktop/code-oss/scripts/xterm-symlink.ps1 b/apps/review-desktop/code-oss/scripts/xterm-symlink.ps1 similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/xterm-symlink.ps1 rename to apps/review-desktop/code-oss/scripts/xterm-symlink.ps1 diff --git a/apps/whiteboard-desktop/code-oss/scripts/xterm-update.js b/apps/review-desktop/code-oss/scripts/xterm-update.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/xterm-update.js rename to apps/review-desktop/code-oss/scripts/xterm-update.js diff --git a/apps/whiteboard-desktop/code-oss/scripts/xterm-update.ps1 b/apps/review-desktop/code-oss/scripts/xterm-update.ps1 similarity index 100% rename from apps/whiteboard-desktop/code-oss/scripts/xterm-update.ps1 rename to apps/review-desktop/code-oss/scripts/xterm-update.ps1 diff --git a/apps/whiteboard-desktop/code-oss/src/bootstrap-cli.ts b/apps/review-desktop/code-oss/src/bootstrap-cli.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/bootstrap-cli.ts rename to apps/review-desktop/code-oss/src/bootstrap-cli.ts diff --git a/apps/whiteboard-desktop/code-oss/src/bootstrap-esm.ts b/apps/review-desktop/code-oss/src/bootstrap-esm.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/bootstrap-esm.ts rename to apps/review-desktop/code-oss/src/bootstrap-esm.ts diff --git a/apps/whiteboard-desktop/code-oss/src/bootstrap-fork.ts b/apps/review-desktop/code-oss/src/bootstrap-fork.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/bootstrap-fork.ts rename to apps/review-desktop/code-oss/src/bootstrap-fork.ts diff --git a/apps/whiteboard-desktop/code-oss/src/bootstrap-meta.ts b/apps/review-desktop/code-oss/src/bootstrap-meta.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/bootstrap-meta.ts rename to apps/review-desktop/code-oss/src/bootstrap-meta.ts diff --git a/apps/whiteboard-desktop/code-oss/src/bootstrap-node.ts b/apps/review-desktop/code-oss/src/bootstrap-node.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/bootstrap-node.ts rename to apps/review-desktop/code-oss/src/bootstrap-node.ts diff --git a/apps/whiteboard-desktop/code-oss/src/cli.ts b/apps/review-desktop/code-oss/src/cli.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/cli.ts rename to apps/review-desktop/code-oss/src/cli.ts diff --git a/apps/review-desktop/code-oss/src/main.ts b/apps/review-desktop/code-oss/src/main.ts new file mode 100644 index 000000000..5171314ad --- /dev/null +++ b/apps/review-desktop/code-oss/src/main.ts @@ -0,0 +1,777 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'node:path'; +import * as fs from 'original-fs'; +import * as os from 'node:os'; +import { performance } from 'node:perf_hooks'; +import { configurePortable } from './bootstrap-node.js'; +import { bootstrapESM } from './bootstrap-esm.js'; +import { app, protocol, crashReporter, Menu, contentTracing, net } from 'electron'; +import minimist from 'minimist'; +import { product } from './bootstrap-meta.js'; +import { validatedIpcMain } from './vs/base/parts/ipc/electron-main/ipcMain.js'; +import { parse } from './vs/base/common/jsonc.js'; +import { getUserDataPath } from './vs/platform/environment/node/userDataPath.js'; +// Evaluated before `startup()` calls `bootstrapESM()`, so this module and +// everything it imports runs with no NLS message table installed. It must not +// reach `vs/nls.js`, the platform registry, or the configuration registry: in a +// packaged build those throw `!!! NLS MISSING: !!!` into a modal, before any +// window or log exists, and the app never starts. That is why it reads setting +// keys from the import-free `vs/review/common/reviewConfigurationDefaults.ts` +// rather than from `reviewConfiguration.ts`, which owns the registry calls. +// Enforced by apps/review-desktop/scripts/main-bootstrap-imports.test.mjs. +import { importReviewUserConfig, type ReviewUserConfigImportMode } from './vs/review/node/reviewUserConfigImport.js'; +import { registerReviewOptionalExtensionInstaller } from './vs/review/node/reviewOptionalExtensionInstaller.js'; +import { writeReviewBootstrapBreadcrumb } from './vs/review/node/reviewBootstrapBreadcrumb.js'; +import * as perf from './vs/base/common/performance.js'; +import { resolveNLSConfiguration } from './vs/base/node/nls.js'; +import { getUNCHost, addUNCHostToAllowlist } from './vs/base/node/unc.js'; +import { INLSConfiguration } from './vs/nls.js'; +import { NativeParsedArgs } from './vs/platform/environment/common/argv.js'; + +perf.mark('code/didStartMain'); + +perf.mark('code/willLoadMainBundle', { + // When built, the main bundle is a single JS file with all + // dependencies inlined. As such, we mark `willLoadMainBundle` + // as the start of the main bundle loading process. + startTime: Math.floor(performance.timeOrigin) +}); +perf.mark('code/didLoadMainBundle'); + +// Enable portable support +const portable = configurePortable(product); + +const args = parseCLIArgs(); +// Configure static command line arguments +const argvConfig = configureCommandlineSwitchesSync(args); +// Enable sandbox globally unless +// 1) disabled via command line using either +// `--no-sandbox` or `--disable-chromium-sandbox` argument. +// 2) argv.json contains `disable-chromium-sandbox: true`. +if (args['sandbox'] && + !args['disable-chromium-sandbox'] && + !argvConfig['disable-chromium-sandbox']) { + app.enableSandbox(); +} else if (app.commandLine.hasSwitch('no-sandbox') && + !app.commandLine.hasSwitch('disable-gpu-sandbox')) { + // Disable GPU sandbox whenever --no-sandbox is used. + app.commandLine.appendSwitch('disable-gpu-sandbox'); +} else { + app.commandLine.appendSwitch('no-sandbox'); + app.commandLine.appendSwitch('disable-gpu-sandbox'); +} + +// Set userData path before app 'ready' event +const userDataPath = getUserDataPath(args, product.nameShort ?? 'code-oss-dev'); +if (process.platform === 'win32') { + const userDataUNCHost = getUNCHost(userDataPath); + if (userDataUNCHost) { + addUNCHostToAllowlist(userDataUNCHost); // enables to use UNC paths in userDataPath + } +} +app.setPath('userData', userDataPath); +registerReviewOptionalExtensionInstaller(validatedIpcMain, { + userDataPath, + platform: process.platform, + arch: process.arch, + request: options => net.request(options) +}); +try { + importReviewUserConfig({ userDataPath, log: message => console.log(message) }); +} catch (error) { + console.error('Review could not import VS Code settings and keybindings:', error); + writeReviewBootstrapBreadcrumb(userDataPath, error); +} +validatedIpcMain.handle('vscode:reviewImportUserConfig', async (_event, request: unknown) => { + const mode = request && typeof request === 'object' ? (request as { mode?: unknown }).mode : undefined; + if (mode !== 'preview' && mode !== 'apply') { + throw new Error(`Unsupported Review user-config import mode: ${String(mode)}`); + } + return importReviewUserConfig({ + userDataPath, + mode: mode satisfies ReviewUserConfigImportMode, + log: message => console.log(message), + }); +}); + +// Resolve code cache path +const codeCachePath = getCodeCachePath(); + +// Disable default menu (https://github.com/electron/electron/issues/35512) +Menu.setApplicationMenu(null); + +// Configure crash reporter +perf.mark('code/willStartCrashReporter'); +// If a crash-reporter-directory is specified we store the crash reports +// in the specified directory and don't upload them to the crash server. +// +// Appcenter crash reporting is enabled if +// * enable-crash-reporter runtime argument is set to 'true' +// * --disable-crash-reporter command line parameter is not set +// +// Disable crash reporting in all other cases. +if (args['crash-reporter-directory'] || (argvConfig['enable-crash-reporter'] && !args['disable-crash-reporter'])) { + configureCrashReporter(); +} +perf.mark('code/didStartCrashReporter'); + +// Set logs path before app 'ready' event if running portable +// to ensure that no 'logs' folder is created on disk at a +// location outside of the portable directory +// (https://github.com/microsoft/vscode/issues/56651) +if (portable.isPortable) { + app.setAppLogsPath(path.join(userDataPath, 'logs')); +} + +// Register custom schemes with privileges +protocol.registerSchemesAsPrivileged([ + { + scheme: 'vscode-webview', + privileges: { standard: true, secure: true, supportFetchAPI: true, corsEnabled: true, allowServiceWorkers: true, codeCache: true } + }, + { + scheme: 'vscode-file', + privileges: { secure: true, standard: true, supportFetchAPI: true, corsEnabled: true, codeCache: true } + }, + { + scheme: 'vscode-remote-resource', + privileges: { secure: true, supportFetchAPI: true, corsEnabled: true } + }, + { + scheme: 'vscode-managed-remote-resource', + privileges: { secure: true, supportFetchAPI: true, corsEnabled: true } + } +]); + +// Global app listeners +registerListeners(); + +/** + * We can resolve the NLS configuration early if it is defined + * in argv.json before `app.ready` event. Otherwise we can only + * resolve NLS after `app.ready` event to resolve the OS locale. + */ +let nlsConfigurationPromise: Promise | undefined = undefined; + +// Use the most preferred OS language for language recommendation. +// The API might return an empty array on Linux, such as when +// the 'C' locale is the user's only configured locale. +// No matter the OS, if the array is empty, default back to 'en'. +const osLocale = processZhLocale((app.getPreferredSystemLanguages()?.[0] ?? 'en').toLowerCase()); +const userLocale = getUserDefinedLocale(argvConfig); +if (userLocale) { + nlsConfigurationPromise = resolveNLSConfiguration({ + userLocale, + osLocale, + commit: product.commit, + userDataPath, + nlsMetadataPath: import.meta.dirname + }); +} + +// Pass in the locale to Electron so that the +// Windows Control Overlay is rendered correctly on Windows. +// For now, don't pass in the locale on macOS due to +// https://github.com/microsoft/vscode/issues/167543. +// If the locale is `qps-ploc`, the Microsoft +// Pseudo Language Language Pack is being used. +// In that case, use `en` as the Electron locale. + +if (process.platform === 'win32' || process.platform === 'linux') { + const electronLocale = (!userLocale || userLocale === 'qps-ploc') ? 'en' : userLocale; + app.commandLine.appendSwitch('lang', electronLocale); +} + +// Load our code once ready +app.once('ready', function () { + if (args['trace']) { + let traceOptions: Electron.TraceConfig | Electron.TraceCategoriesAndOptions; + if (args['trace-memory-infra']) { + const customCategories = args['trace-category-filter']?.split(',') || []; + customCategories.push('disabled-by-default-memory-infra', 'disabled-by-default-memory-infra.v8.code_stats'); + traceOptions = { + included_categories: customCategories, + excluded_categories: ['*'], + memory_dump_config: { + allowed_dump_modes: ['light', 'detailed'], + triggers: [ + { + type: 'periodic_interval', + mode: 'detailed', + min_time_between_dumps_ms: 10000 + }, + { + type: 'periodic_interval', + mode: 'light', + min_time_between_dumps_ms: 1000 + } + ] + } + }; + } else { + traceOptions = { + categoryFilter: args['trace-category-filter'] || '*', + traceOptions: args['trace-options'] || 'record-until-full,enable-sampling' + }; + } + + contentTracing.startRecording(traceOptions).finally(() => onReady()); + } else { + onReady(); + } +}); + +async function onReady() { + perf.mark('code/mainAppReady'); + + try { + const [, nlsConfig] = await Promise.all([ + mkdirpIgnoreError(codeCachePath), + resolveNlsConfiguration() + ]); + + await startup(codeCachePath, nlsConfig); + } catch (error) { + console.error(error); + // Nothing is running yet that could report this: no window, no log, no + // Review server. Leave a note on disk instead; the next launch sends it + // through the normal opted-in path and deletes it. + writeReviewBootstrapBreadcrumb(userDataPath, error); + } +} + +/** + * Main startup routine + */ +async function startup(codeCachePath: string | undefined, nlsConfig: INLSConfiguration): Promise { + process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfig); + process.env['VSCODE_CODE_CACHE_PATH'] = codeCachePath || ''; + + // Bootstrap ESM + await bootstrapESM(); + + // Load Main + await import('./vs/code/electron-main/main.js'); + perf.mark('code/didRunMainBundle'); +} + +function configureCommandlineSwitchesSync(cliArgs: NativeParsedArgs) { + const SUPPORTED_ELECTRON_SWITCHES = [ + + // alias from us for --disable-gpu + 'disable-hardware-acceleration', + + // override for the color profile to use + 'force-color-profile', + + // disable LCD font rendering, a Chromium flag + 'disable-lcd-text', + + // bypass any specified proxy for the given semi-colon-separated list of hosts + 'proxy-bypass-list', + + 'remote-debugging-port' + ]; + + if (process.platform === 'linux') { + + // Force enable screen readers on Linux via this flag + SUPPORTED_ELECTRON_SWITCHES.push('force-renderer-accessibility'); + + // override which password-store is used on Linux + SUPPORTED_ELECTRON_SWITCHES.push('password-store'); + } + + const SUPPORTED_MAIN_PROCESS_SWITCHES = [ + + // Persistently enable proposed api via argv.json: https://github.com/microsoft/vscode/issues/99775 + 'enable-proposed-api', + + // Log level to use. Default is 'info'. Allowed values are 'error', 'warn', 'info', 'debug', 'trace', 'off'. + 'log-level', + + // Use an in-memory storage for secrets + 'use-inmemory-secretstorage', + + // Enables display tracking to restore maximized windows under RDP: https://github.com/electron/electron/issues/47016 + 'enable-rdp-display-tracking', + ]; + + // Read argv config + const argvConfig = readArgvConfigSync(); + + Object.keys(argvConfig).forEach(argvKey => { + const argvValue = argvConfig[argvKey]; + + // Append Electron flags to Electron + if (SUPPORTED_ELECTRON_SWITCHES.indexOf(argvKey) !== -1) { + if (argvValue === true || argvValue === 'true') { + if (argvKey === 'disable-hardware-acceleration') { + app.disableHardwareAcceleration(); // needs to be called explicitly + } else { + app.commandLine.appendSwitch(argvKey); + } + } else if (typeof argvValue === 'string' && argvValue) { + if (argvKey === 'password-store') { + // Password store + // TODO@TylerLeonhardt: Remove this migration in 3 months + let migratedArgvValue = argvValue; + if (argvValue === 'gnome' || argvValue === 'gnome-keyring') { + migratedArgvValue = 'gnome-libsecret'; + } + app.commandLine.appendSwitch(argvKey, migratedArgvValue); + } else { + app.commandLine.appendSwitch(argvKey, argvValue); + } + } + } + + // Append main process flags to process.argv + else if (SUPPORTED_MAIN_PROCESS_SWITCHES.indexOf(argvKey) !== -1) { + switch (argvKey) { + case 'enable-proposed-api': + if (Array.isArray(argvValue)) { + argvValue.forEach(id => id && typeof id === 'string' && process.argv.push('--enable-proposed-api', id)); + } else { + console.error(`Unexpected value for \`enable-proposed-api\` in argv.json. Expected array of extension ids.`); + } + break; + + case 'log-level': + if (typeof argvValue === 'string') { + process.argv.push('--log', argvValue); + } else if (Array.isArray(argvValue)) { + for (const value of argvValue) { + process.argv.push('--log', value); + } + } + break; + + case 'use-inmemory-secretstorage': + if (argvValue) { + process.argv.push('--use-inmemory-secretstorage'); + } + break; + + case 'enable-rdp-display-tracking': + if (argvValue) { + process.argv.push('--enable-rdp-display-tracking'); + } + break; + } + } + }); + + // Following features are enabled from the runtime: + // `NetAdapterMaxBufSizeFeature` - Specify the max buffer size for NetToMojoPendingBuffer, refs https://github.com/microsoft/vscode/issues/268800 + // `DocumentPolicyIncludeJSCallStacksInCrashReports` - https://www.electronjs.org/docs/latest/api/web-frame-main#framecollectjavascriptcallstack-experimental + // `EarlyEstablishGpuChannel` - Refs https://issues.chromium.org/issues/40208065 + // `EstablishGpuChannelAsync` - Refs https://issues.chromium.org/issues/40208065 + // `GlobalShortcutsPortal` - Enables Electron's `globalShortcut` (system-wide keybindings) on Linux Wayland via the XDG global shortcuts portal (no-op elsewhere) + const featuresToEnable = + `NetAdapterMaxBufSizeFeature:NetAdapterMaxBufSize/8192,DocumentPolicyIncludeJSCallStacksInCrashReports,EarlyEstablishGpuChannel,EstablishGpuChannelAsync${process.platform === 'linux' ? ',GlobalShortcutsPortal' : ''},${app.commandLine.getSwitchValue('enable-features')}`; + app.commandLine.appendSwitch('enable-features', featuresToEnable); + + // Following features are disabled from the runtime: + // `CalculateNativeWinOcclusion` - Disable native window occlusion tracker (https://groups.google.com/a/chromium.org/g/embedder-dev/c/ZF3uHHyWLKw/m/VDN2hDXMAAAJ) + const featuresToDisable = + `CalculateNativeWinOcclusion,${app.commandLine.getSwitchValue('disable-features')}`; + app.commandLine.appendSwitch('disable-features', featuresToDisable); + + // Blink features to configure. + // `FontMatchingCTMigration` - Siwtch font matching on macOS to Appkit (Refs https://github.com/microsoft/vscode/issues/224496#issuecomment-2270418470). + // `StandardizedBrowserZoom` - Disable zoom adjustment for bounding box (https://github.com/microsoft/vscode/issues/232750#issuecomment-2459495394) + const blinkFeaturesToDisable = + `FontMatchingCTMigration,StandardizedBrowserZoom,${app.commandLine.getSwitchValue('disable-blink-features')}`; + app.commandLine.appendSwitch('disable-blink-features', blinkFeaturesToDisable); + + // Support JS Flags + const jsFlags = getJSFlags(cliArgs, argvConfig); + if (jsFlags) { + app.commandLine.appendSwitch('js-flags', jsFlags); + } + + // Use portal version 4 that supports current_folder option + // to address https://github.com/microsoft/vscode/issues/213780 + // Runtime sets the default version to 3, refs https://github.com/electron/electron/pull/44426 + app.commandLine.appendSwitch('xdg-portal-required-version', '4'); + + // Increase the maximum number of active WebGL contexts as each terminal may + // use up to 2 + app.commandLine.appendSwitch('max-active-webgl-contexts', '32'); + + return argvConfig; +} + +interface IArgvConfig { + [key: string]: string | string[] | boolean | undefined; + readonly locale?: string; + readonly 'disable-lcd-text'?: boolean; + readonly 'proxy-bypass-list'?: string; + readonly 'disable-hardware-acceleration'?: boolean; + readonly 'force-color-profile'?: string; + readonly 'enable-crash-reporter'?: boolean; + readonly 'crash-reporter-id'?: string; + readonly 'enable-proposed-api'?: string[]; + readonly 'log-level'?: string | string[]; + readonly 'disable-chromium-sandbox'?: boolean; + readonly 'use-inmemory-secretstorage'?: boolean; + readonly 'enable-rdp-display-tracking'?: boolean; + readonly 'remote-debugging-port'?: string; + readonly 'js-flags'?: string; +} + +function readArgvConfigSync(): IArgvConfig { + + // Read or create the argv.json config file sync before app('ready') + const argvConfigPath = getArgvConfigPath(); + let argvConfig: IArgvConfig | undefined = undefined; + try { + argvConfig = parse(fs.readFileSync(argvConfigPath).toString()); + } catch (error) { + if (error && error.code === 'ENOENT') { + createDefaultArgvConfigSync(argvConfigPath); + } else { + console.warn(`Unable to read argv.json configuration file in ${argvConfigPath}, falling back to defaults (${error})`); + } + } + + // Fallback to default + if (!argvConfig) { + argvConfig = {}; + } + + return argvConfig; +} + +function createDefaultArgvConfigSync(argvConfigPath: string): void { + try { + + // Ensure argv config parent exists + const argvConfigPathDirname = path.dirname(argvConfigPath); + if (!fs.existsSync(argvConfigPathDirname)) { + fs.mkdirSync(argvConfigPathDirname); + } + + // Default argv content + const defaultArgvConfigContent = [ + '// This configuration file allows you to pass permanent command line arguments to VS Code.', + '// Only a subset of arguments is currently supported to reduce the likelihood of breaking', + '// the installation.', + '//', + '// PLEASE DO NOT CHANGE WITHOUT UNDERSTANDING THE IMPACT', + '//', + '// NOTE: Changing this file requires a restart of VS Code.', + '{', + ' // Use software rendering instead of hardware accelerated rendering.', + ' // This can help in cases where you see rendering issues in VS Code.', + ' // "disable-hardware-acceleration": true', + '}' + ]; + + // Create initial argv.json with default content + fs.writeFileSync(argvConfigPath, defaultArgvConfigContent.join('\n')); + } catch (error) { + console.error(`Unable to create argv.json configuration file in ${argvConfigPath}, falling back to defaults (${error})`); + } +} + +function getArgvConfigPath(): string { + const vscodePortable = process.env['VSCODE_PORTABLE']; + if (vscodePortable) { + return path.join(vscodePortable, 'argv.json'); + } + + let dataFolderName = product.dataFolderName; + if (process.env['VSCODE_DEV']) { + dataFolderName = `${dataFolderName}-dev`; + } + + return path.join(os.homedir(), dataFolderName!, 'argv.json'); +} + +function configureCrashReporter(): void { + let crashReporterDirectory = args['crash-reporter-directory']; + let submitURL = ''; + if (crashReporterDirectory) { + crashReporterDirectory = path.normalize(crashReporterDirectory); + + if (!path.isAbsolute(crashReporterDirectory)) { + console.error(`The path '${crashReporterDirectory}' specified for --crash-reporter-directory must be absolute.`); + app.exit(1); + } + + if (!fs.existsSync(crashReporterDirectory)) { + try { + fs.mkdirSync(crashReporterDirectory, { recursive: true }); + } catch (error) { + console.error(`The path '${crashReporterDirectory}' specified for --crash-reporter-directory does not seem to exist or cannot be created.`); + app.exit(1); + } + } + + // Crashes are stored in the crashDumps directory by default, so we + // need to change that directory to the provided one + console.log(`Found --crash-reporter-directory argument. Setting crashDumps directory to be '${crashReporterDirectory}'`); + app.setPath('crashDumps', crashReporterDirectory); + } + + // Otherwise we configure the crash reporter from product.json + else { + const appCenter = product.appCenter; + if (appCenter) { + const isWindows = (process.platform === 'win32'); + const isLinux = (process.platform === 'linux'); + const isDarwin = (process.platform === 'darwin'); + const crashReporterId = argvConfig['crash-reporter-id']; + const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + if (crashReporterId && uuidPattern.test(crashReporterId)) { + if (isWindows) { + switch (process.arch) { + case 'x64': + submitURL = appCenter['win32-x64']; + break; + case 'arm64': + submitURL = appCenter['win32-arm64']; + break; + } + } else if (isDarwin) { + if (product.darwinUniversalAssetId) { + submitURL = appCenter['darwin-universal']; + } else { + switch (process.arch) { + case 'x64': + submitURL = appCenter['darwin']; + break; + case 'arm64': + submitURL = appCenter['darwin-arm64']; + break; + } + } + } else if (isLinux) { + submitURL = appCenter['linux-x64']; + } + submitURL = submitURL.concat('&uid=', crashReporterId, '&iid=', crashReporterId, '&sid=', crashReporterId); + // Send the id for child node process that are explicitly starting crash reporter. + // For vscode this is ExtensionHost process currently. + const argv = process.argv; + const endOfArgsMarkerIndex = argv.indexOf('--'); + if (endOfArgsMarkerIndex === -1) { + argv.push('--crash-reporter-id', crashReporterId); + } else { + // if the we have an argument "--" (end of argument marker) + // we cannot add arguments at the end. rather, we add + // arguments before the "--" marker. + argv.splice(endOfArgsMarkerIndex, 0, '--crash-reporter-id', crashReporterId); + } + } + } + } + + // Start crash reporter for all processes + const productName = (product.crashReporter ? product.crashReporter.productName : undefined) || product.nameShort; + const companyName = (product.crashReporter ? product.crashReporter.companyName : undefined) || 'Microsoft'; + const uploadToServer = Boolean(!process.env['VSCODE_DEV'] && submitURL && !crashReporterDirectory); + crashReporter.start({ + companyName, + productName: process.env['VSCODE_DEV'] ? `${productName} Dev` : productName, + submitURL, + uploadToServer, + compress: true, + ignoreSystemCrashHandler: true + }); +} + +function getJSFlags(cliArgs: NativeParsedArgs, argvConfig: IArgvConfig): string | null { + const jsFlags: string[] = []; + + // Add any existing JS flags we already got from the command line + if (cliArgs['js-flags']) { + jsFlags.push(cliArgs['js-flags']); + } + + // Add JS flags from runtime arguments (argv.json) + if (typeof argvConfig['js-flags'] === 'string' && argvConfig['js-flags']) { + jsFlags.push(argvConfig['js-flags']); + } + + return jsFlags.length > 0 ? jsFlags.join(' ') : null; +} + +function parseCLIArgs(): NativeParsedArgs { + return minimist(process.argv, { + string: [ + 'user-data-dir', + 'locale', + 'js-flags', + 'crash-reporter-directory' + ], + boolean: [ + 'disable-chromium-sandbox', + ], + default: { + 'sandbox': true + }, + alias: { + 'no-sandbox': 'sandbox' + } + }); +} + +function registerListeners(): void { + + /** + * macOS: when someone drops a file to the not-yet running VSCode, the open-file event fires even before + * the app-ready event. We listen very early for open-file and remember this upon startup as path to open. + */ + const macOpenFiles: string[] = []; + (globalThis as { macOpenFiles?: string[] }).macOpenFiles = macOpenFiles; + app.on('open-file', function (event, path) { + macOpenFiles.push(path); + }); + + /** + * macOS: react to open-url requests. + */ + const openUrls: string[] = []; + const onOpenUrl = + function (event: { preventDefault: () => void }, url: string) { + event.preventDefault(); + + openUrls.push(url); + }; + + app.on('will-finish-launching', function () { + app.on('open-url', onOpenUrl); + }); + + (globalThis as { getOpenUrls?: () => string[] }).getOpenUrls = function () { + app.removeListener('open-url', onOpenUrl); + + return openUrls; + }; +} + +function getCodeCachePath(): string | undefined { + + // explicitly disabled via CLI args + if (process.argv.indexOf('--no-cached-data') > 0) { + return undefined; + } + + // running out of sources + if (process.env['VSCODE_DEV']) { + return undefined; + } + + // require commit id + const commit = product.commit; + if (!commit) { + return undefined; + } + + return path.join(userDataPath, 'CachedData', commit); +} + +async function mkdirpIgnoreError(dir: string | undefined): Promise { + if (typeof dir === 'string') { + try { + await fs.promises.mkdir(dir, { recursive: true }); + + return dir; + } catch (error) { + // ignore + } + } + + return undefined; +} + +//#region NLS Support + +function processZhLocale(appLocale: string): string { + if (appLocale.startsWith('zh')) { + const region = appLocale.split('-')[1]; + + // On Windows and macOS, Chinese languages returned by + // app.getPreferredSystemLanguages() start with zh-hans + // for Simplified Chinese or zh-hant for Traditional Chinese, + // so we can easily determine whether to use Simplified or Traditional. + // However, on Linux, Chinese languages returned by that same API + // are of the form zh-XY, where XY is a country code. + // For China (CN), Singapore (SG), and Malaysia (MY) + // country codes, assume they use Simplified Chinese. + // For other cases, assume they use Traditional. + if (['hans', 'cn', 'sg', 'my'].includes(region)) { + return 'zh-cn'; + } + + return 'zh-tw'; + } + + return appLocale; +} + +/** + * Resolve the NLS configuration + */ +async function resolveNlsConfiguration(): Promise { + + // First, we need to test a user defined locale. + // If it fails we try the app locale. + // If that fails we fall back to English. + + const nlsConfiguration = nlsConfigurationPromise ? await nlsConfigurationPromise : undefined; + if (nlsConfiguration) { + return nlsConfiguration; + } + + // Try to use the app locale which is only valid + // after the app ready event has been fired. + + let userLocale = app.getLocale(); + if (!userLocale) { + return { + userLocale: 'en', + osLocale, + resolvedLanguage: 'en', + defaultMessagesFile: path.join(import.meta.dirname, 'nls.messages.json'), + + // NLS: below 2 are a relic from old times only used by vscode-nls and deprecated + locale: 'en', + availableLanguages: {} + }; + } + + // See above the comment about the loader and case sensitiveness + userLocale = processZhLocale(userLocale.toLowerCase()); + + return resolveNLSConfiguration({ + userLocale, + osLocale, + commit: product.commit, + userDataPath, + nlsMetadataPath: import.meta.dirname + }); +} + +/** + * Language tags are case insensitive however an ESM loader is case sensitive + * To make this work on case preserving & insensitive FS we do the following: + * the language bundles have lower case language tags and we always lower case + * the locale we receive from the user or OS. + */ +function getUserDefinedLocale(argvConfig: IArgvConfig): string | undefined { + const locale = args['locale']; + if (locale) { + return locale.toLowerCase(); // a directly provided --locale always wins + } + + return typeof argvConfig?.locale === 'string' ? argvConfig.locale.toLowerCase() : undefined; +} + +//#endregion diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.base.json b/apps/review-desktop/code-oss/src/tsconfig.base.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.base.json rename to apps/review-desktop/code-oss/src/tsconfig.base.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.defineClassFields.json b/apps/review-desktop/code-oss/src/tsconfig.defineClassFields.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.defineClassFields.json rename to apps/review-desktop/code-oss/src/tsconfig.defineClassFields.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.json b/apps/review-desktop/code-oss/src/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.json rename to apps/review-desktop/code-oss/src/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.monaco.json b/apps/review-desktop/code-oss/src/tsconfig.monaco.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.monaco.json rename to apps/review-desktop/code-oss/src/tsconfig.monaco.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.tsec.json b/apps/review-desktop/code-oss/src/tsconfig.tsec.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.tsec.json rename to apps/review-desktop/code-oss/src/tsconfig.tsec.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.vscode-dts.json b/apps/review-desktop/code-oss/src/tsconfig.vscode-dts.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.vscode-dts.json rename to apps/review-desktop/code-oss/src/tsconfig.vscode-dts.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsconfig.vscode-proposed-dts.json b/apps/review-desktop/code-oss/src/tsconfig.vscode-proposed-dts.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsconfig.vscode-proposed-dts.json rename to apps/review-desktop/code-oss/src/tsconfig.vscode-proposed-dts.json diff --git a/apps/whiteboard-desktop/code-oss/src/tsec.exemptions.json b/apps/review-desktop/code-oss/src/tsec.exemptions.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/tsec.exemptions.json rename to apps/review-desktop/code-oss/src/tsec.exemptions.json diff --git a/apps/whiteboard-desktop/code-oss/src/typings/base-common.d.ts b/apps/review-desktop/code-oss/src/typings/base-common.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/base-common.d.ts rename to apps/review-desktop/code-oss/src/typings/base-common.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/copilot-api.d.ts b/apps/review-desktop/code-oss/src/typings/copilot-api.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/copilot-api.d.ts rename to apps/review-desktop/code-oss/src/typings/copilot-api.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/crypto.d.ts b/apps/review-desktop/code-oss/src/typings/crypto.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/crypto.d.ts rename to apps/review-desktop/code-oss/src/typings/crypto.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/css.d.ts b/apps/review-desktop/code-oss/src/typings/css.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/css.d.ts rename to apps/review-desktop/code-oss/src/typings/css.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/editContext.d.ts b/apps/review-desktop/code-oss/src/typings/editContext.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/editContext.d.ts rename to apps/review-desktop/code-oss/src/typings/editContext.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/README.md b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/README.md rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/README.md diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/canvas.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/canvas.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/canvas.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/canvas.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/client.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/client.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/client.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/client.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/copilotRequestHandler.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/copilotRequestHandler.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/copilotRequestHandler.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/copilotRequestHandler.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/generated/rpc.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/generated/rpc.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/generated/rpc.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/generated/rpc.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/generated/session-events.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/generated/session-events.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/generated/session-events.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/generated/session-events.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/index.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/index.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/index.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/index.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/session.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/session.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/session.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/session.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/sessionFsProvider.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/sessionFsProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/sessionFsProvider.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/sessionFsProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/toolSet.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/toolSet.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/toolSet.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/toolSet.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/types.d.ts b/apps/review-desktop/code-oss/src/typings/github-copilot-sdk/types.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/github-copilot-sdk/types.d.ts rename to apps/review-desktop/code-oss/src/typings/github-copilot-sdk/types.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/removed-native-modules.d.ts b/apps/review-desktop/code-oss/src/typings/removed-native-modules.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/removed-native-modules.d.ts rename to apps/review-desktop/code-oss/src/typings/removed-native-modules.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/thenable.d.ts b/apps/review-desktop/code-oss/src/typings/thenable.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/thenable.d.ts rename to apps/review-desktop/code-oss/src/typings/thenable.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/vscode-globals-nls.d.ts b/apps/review-desktop/code-oss/src/typings/vscode-globals-nls.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/vscode-globals-nls.d.ts rename to apps/review-desktop/code-oss/src/typings/vscode-globals-nls.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/vscode-globals-product.d.ts b/apps/review-desktop/code-oss/src/typings/vscode-globals-product.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/vscode-globals-product.d.ts rename to apps/review-desktop/code-oss/src/typings/vscode-globals-product.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/typings/vscode-globals-ttp.d.ts b/apps/review-desktop/code-oss/src/typings/vscode-globals-ttp.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/typings/vscode-globals-ttp.d.ts rename to apps/review-desktop/code-oss/src/typings/vscode-globals-ttp.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/amdX.ts b/apps/review-desktop/code-oss/src/vs/amdX.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/amdX.ts rename to apps/review-desktop/code-oss/src/vs/amdX.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/animatedValue.ts b/apps/review-desktop/code-oss/src/vs/base/browser/animatedValue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/animatedValue.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/animatedValue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/animationSync.ts b/apps/review-desktop/code-oss/src/vs/base/browser/animationSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/animationSync.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/animationSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/broadcast.ts b/apps/review-desktop/code-oss/src/vs/base/browser/broadcast.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/broadcast.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/broadcast.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/browser.ts b/apps/review-desktop/code-oss/src/vs/base/browser/browser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/browser.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/browser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/canIUse.ts b/apps/review-desktop/code-oss/src/vs/base/browser/canIUse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/canIUse.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/canIUse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/contextmenu.ts b/apps/review-desktop/code-oss/src/vs/base/browser/contextmenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/contextmenu.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/contextmenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/cssValue.ts b/apps/review-desktop/code-oss/src/vs/base/browser/cssValue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/cssValue.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/cssValue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/deviceAccess.ts b/apps/review-desktop/code-oss/src/vs/base/browser/deviceAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/deviceAccess.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/deviceAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/dnd.ts b/apps/review-desktop/code-oss/src/vs/base/browser/dnd.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/dnd.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/dnd.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/dom.ts b/apps/review-desktop/code-oss/src/vs/base/browser/dom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/dom.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/dom.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/domSanitize.ts b/apps/review-desktop/code-oss/src/vs/base/browser/domSanitize.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/domSanitize.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/domSanitize.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/domStylesheets.ts b/apps/review-desktop/code-oss/src/vs/base/browser/domStylesheets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/domStylesheets.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/domStylesheets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/cgmanifest.json b/apps/review-desktop/code-oss/src/vs/base/browser/dompurify/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/cgmanifest.json rename to apps/review-desktop/code-oss/src/vs/base/browser/dompurify/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.d.ts b/apps/review-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.d.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.js b/apps/review-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.js rename to apps/review-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.js diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.license.txt b/apps/review-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.license.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.license.txt rename to apps/review-desktop/code-oss/src/vs/base/browser/dompurify/dompurify.license.txt diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/event.ts b/apps/review-desktop/code-oss/src/vs/base/browser/event.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/event.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/event.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/fastDomNode.ts b/apps/review-desktop/code-oss/src/vs/base/browser/fastDomNode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/fastDomNode.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/fastDomNode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/fonts.ts b/apps/review-desktop/code-oss/src/vs/base/browser/fonts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/fonts.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/fonts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/formattedTextRenderer.ts b/apps/review-desktop/code-oss/src/vs/base/browser/formattedTextRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/formattedTextRenderer.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/formattedTextRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/globalPointerMoveMonitor.ts b/apps/review-desktop/code-oss/src/vs/base/browser/globalPointerMoveMonitor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/globalPointerMoveMonitor.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/globalPointerMoveMonitor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/history.ts b/apps/review-desktop/code-oss/src/vs/base/browser/history.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/history.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/history.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/htmlToMarkdown.ts b/apps/review-desktop/code-oss/src/vs/base/browser/htmlToMarkdown.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/htmlToMarkdown.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/htmlToMarkdown.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/iframe.ts b/apps/review-desktop/code-oss/src/vs/base/browser/iframe.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/iframe.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/iframe.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/indexedDB.ts b/apps/review-desktop/code-oss/src/vs/base/browser/indexedDB.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/indexedDB.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/indexedDB.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/keyboardEvent.ts b/apps/review-desktop/code-oss/src/vs/base/browser/keyboardEvent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/keyboardEvent.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/keyboardEvent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/markdownRenderer.ts b/apps/review-desktop/code-oss/src/vs/base/browser/markdownRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/markdownRenderer.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/markdownRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/mouseEvent.ts b/apps/review-desktop/code-oss/src/vs/base/browser/mouseEvent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/mouseEvent.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/mouseEvent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/overlayLayoutElement.ts b/apps/review-desktop/code-oss/src/vs/base/browser/overlayLayoutElement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/overlayLayoutElement.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/overlayLayoutElement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/performance.ts b/apps/review-desktop/code-oss/src/vs/base/browser/performance.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/performance.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/performance.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/pixelRatio.ts b/apps/review-desktop/code-oss/src/vs/base/browser/pixelRatio.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/pixelRatio.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/pixelRatio.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/touch.ts b/apps/review-desktop/code-oss/src/vs/base/browser/touch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/touch.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/touch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/trustedTypes.ts b/apps/review-desktop/code-oss/src/vs/base/browser/trustedTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/trustedTypes.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/trustedTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionViewItems.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionViewItems.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionViewItems.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionViewItems.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/actionbar/actionbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/animations/animations.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/animations/animations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/animations/animations.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/animations/animations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/aria/aria.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/aria/aria.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/aria/aria.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/aria/aria.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/aria/aria.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/aria/aria.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/aria/aria.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/aria/aria.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/button/button.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/button/button.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/button/button.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/button/button.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/button/button.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/button/button.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/button/button.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/button/button.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/centered/centeredViewLayout.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/centered/centeredViewLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/centered/centeredViewLayout.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/centered/centeredViewLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/README.md b/apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/README.md rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/README.md diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon-modifiers.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon-modifiers.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon-modifiers.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon-modifiers.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codicon/codicon.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codiconStyles.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codiconStyles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/codicons/codiconStyles.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/codicons/codiconStyles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/contextview/contextview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/countBadge/countBadge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dialog/dialog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dnd/dnd.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdown.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/findInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/findInputToggles.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/findInputToggles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/findInputToggles.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/findInputToggles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/replaceInput.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/replaceInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/findinput/replaceInput.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/findinput/replaceInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/grid/grid.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/grid/grid.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/grid/grid.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/grid/grid.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/grid/gridview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hover.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hover.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hover.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate2.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate2.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate2.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegate2.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegateFactory.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegateFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegateFactory.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverDelegateFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/hover/hoverWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabels.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabels.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconLabels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconlabel.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconlabel.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconlabel.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/iconlabel.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/simpleIconLabel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/simpleIconLabel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/iconLabel/simpleIconLabel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/iconLabel/simpleIconLabel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/icons/iconSelectBox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/inputbox/inputBox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/list.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/list.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/list.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/list.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/list.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/list.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/list.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/list.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/listPaging.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/listPaging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/listPaging.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/listPaging.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/listView.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/listView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/listView.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/listView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/listWidget.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/listWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/listWidget.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/listWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/rangeMap.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/rangeMap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/rangeMap.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/rangeMap.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/rowCache.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/rowCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/rowCache.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/rowCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/splice.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/list/splice.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/list/splice.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/list/splice.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/menu/menu.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/menu/menu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/menu/menu.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/menu/menu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/menu/menubar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/mouseCursor/mouseCursor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressAccessibilitySignal.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressAccessibilitySignal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressAccessibilitySignal.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressAccessibilitySignal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/progressbar/progressbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/radio/radio.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/radio/radio.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/radio/radio.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/radio/radio.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/radio/radio.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/radio/radio.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/radio/radio.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/radio/radio.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/resizable/resizable.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/resizable/resizable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/resizable/resizable.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/resizable/resizable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/sash/sash.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/sash/sash.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/sash/sash.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/sash/sash.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/sash/sash.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/sash/sash.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/sash/sash.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/sash/sash.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/media/scrollbars.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/media/scrollbars.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/media/scrollbars.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/media/scrollbars.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElement.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarState.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarState.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxNative.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxNative.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxNative.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/selectBox/selectBoxNative.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/severityIcon/media/severityIcon.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/severityIcon/media/severityIcon.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/severityIcon/media/severityIcon.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/severityIcon/media/severityIcon.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/severityIcon/severityIcon.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/severityIcon/severityIcon.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/severityIcon/severityIcon.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/severityIcon/severityIcon.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/paneview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/splitview/splitview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/table/table.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/table/table.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/table/table.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/table/table.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/table/table.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/table/table.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/table/table.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/table/table.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/table/tableWidget.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/table/tableWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/table/tableWidget.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/table/tableWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/toggle/toggle.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/toolbar/toolbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/abstractTree.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/abstractTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/abstractTree.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/abstractTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/asyncDataTree.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/asyncDataTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/asyncDataTree.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/asyncDataTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/dataTree.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/dataTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/dataTree.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/dataTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/indexTreeModel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/indexTreeModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/indexTreeModel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/indexTreeModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/media/tree.css b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/media/tree.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/media/tree.css rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/media/tree.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/objectTree.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/objectTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/objectTree.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/objectTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/objectTreeModel.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/objectTreeModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/objectTreeModel.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/objectTreeModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/tree.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/tree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/tree.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/tree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/treeDefaults.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/treeDefaults.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/tree/treeDefaults.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/tree/treeDefaults.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/widget.ts b/apps/review-desktop/code-oss/src/vs/base/browser/ui/widget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/ui/widget.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/ui/widget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/browser/window.ts b/apps/review-desktop/code-oss/src/vs/base/browser/window.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/browser/window.ts rename to apps/review-desktop/code-oss/src/vs/base/browser/window.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/actions.ts b/apps/review-desktop/code-oss/src/vs/base/common/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/actions.ts rename to apps/review-desktop/code-oss/src/vs/base/common/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/arrays.ts b/apps/review-desktop/code-oss/src/vs/base/common/arrays.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/arrays.ts rename to apps/review-desktop/code-oss/src/vs/base/common/arrays.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/arraysFind.ts b/apps/review-desktop/code-oss/src/vs/base/common/arraysFind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/arraysFind.ts rename to apps/review-desktop/code-oss/src/vs/base/common/arraysFind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/assert.ts b/apps/review-desktop/code-oss/src/vs/base/common/assert.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/assert.ts rename to apps/review-desktop/code-oss/src/vs/base/common/assert.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/async.ts b/apps/review-desktop/code-oss/src/vs/base/common/async.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/async.ts rename to apps/review-desktop/code-oss/src/vs/base/common/async.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/buffer.ts b/apps/review-desktop/code-oss/src/vs/base/common/buffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/buffer.ts rename to apps/review-desktop/code-oss/src/vs/base/common/buffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/cache.ts b/apps/review-desktop/code-oss/src/vs/base/common/cache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/cache.ts rename to apps/review-desktop/code-oss/src/vs/base/common/cache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/cancellation.ts b/apps/review-desktop/code-oss/src/vs/base/common/cancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/cancellation.ts rename to apps/review-desktop/code-oss/src/vs/base/common/cancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/charCode.ts b/apps/review-desktop/code-oss/src/vs/base/common/charCode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/charCode.ts rename to apps/review-desktop/code-oss/src/vs/base/common/charCode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/codicons.ts b/apps/review-desktop/code-oss/src/vs/base/common/codicons.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/codicons.ts rename to apps/review-desktop/code-oss/src/vs/base/common/codicons.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/codiconsLibrary.ts b/apps/review-desktop/code-oss/src/vs/base/common/codiconsLibrary.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/codiconsLibrary.ts rename to apps/review-desktop/code-oss/src/vs/base/common/codiconsLibrary.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/codiconsUtil.ts b/apps/review-desktop/code-oss/src/vs/base/common/codiconsUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/codiconsUtil.ts rename to apps/review-desktop/code-oss/src/vs/base/common/codiconsUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/collections.ts b/apps/review-desktop/code-oss/src/vs/base/common/collections.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/collections.ts rename to apps/review-desktop/code-oss/src/vs/base/common/collections.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/color.ts b/apps/review-desktop/code-oss/src/vs/base/common/color.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/color.ts rename to apps/review-desktop/code-oss/src/vs/base/common/color.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/comparers.ts b/apps/review-desktop/code-oss/src/vs/base/common/comparers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/comparers.ts rename to apps/review-desktop/code-oss/src/vs/base/common/comparers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/console.ts b/apps/review-desktop/code-oss/src/vs/base/common/console.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/console.ts rename to apps/review-desktop/code-oss/src/vs/base/common/console.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/controlFlow.ts b/apps/review-desktop/code-oss/src/vs/base/common/controlFlow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/controlFlow.ts rename to apps/review-desktop/code-oss/src/vs/base/common/controlFlow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/dataTransfer.ts b/apps/review-desktop/code-oss/src/vs/base/common/dataTransfer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/dataTransfer.ts rename to apps/review-desktop/code-oss/src/vs/base/common/dataTransfer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/date.ts b/apps/review-desktop/code-oss/src/vs/base/common/date.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/date.ts rename to apps/review-desktop/code-oss/src/vs/base/common/date.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/decorators.ts b/apps/review-desktop/code-oss/src/vs/base/common/decorators.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/decorators.ts rename to apps/review-desktop/code-oss/src/vs/base/common/decorators.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/decorators/cancelPreviousCalls.ts b/apps/review-desktop/code-oss/src/vs/base/common/decorators/cancelPreviousCalls.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/decorators/cancelPreviousCalls.ts rename to apps/review-desktop/code-oss/src/vs/base/common/decorators/cancelPreviousCalls.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/defaultAccount.ts b/apps/review-desktop/code-oss/src/vs/base/common/defaultAccount.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/defaultAccount.ts rename to apps/review-desktop/code-oss/src/vs/base/common/defaultAccount.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/desktopEnvironmentInfo.ts b/apps/review-desktop/code-oss/src/vs/base/common/desktopEnvironmentInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/desktopEnvironmentInfo.ts rename to apps/review-desktop/code-oss/src/vs/base/common/desktopEnvironmentInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/diff/diff.ts b/apps/review-desktop/code-oss/src/vs/base/common/diff/diff.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/diff/diff.ts rename to apps/review-desktop/code-oss/src/vs/base/common/diff/diff.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/diff/diffChange.ts b/apps/review-desktop/code-oss/src/vs/base/common/diff/diffChange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/diff/diffChange.ts rename to apps/review-desktop/code-oss/src/vs/base/common/diff/diffChange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/envfile.ts b/apps/review-desktop/code-oss/src/vs/base/common/envfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/envfile.ts rename to apps/review-desktop/code-oss/src/vs/base/common/envfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/equals.ts b/apps/review-desktop/code-oss/src/vs/base/common/equals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/equals.ts rename to apps/review-desktop/code-oss/src/vs/base/common/equals.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/errorMessage.ts b/apps/review-desktop/code-oss/src/vs/base/common/errorMessage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/errorMessage.ts rename to apps/review-desktop/code-oss/src/vs/base/common/errorMessage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/errors.ts b/apps/review-desktop/code-oss/src/vs/base/common/errors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/errors.ts rename to apps/review-desktop/code-oss/src/vs/base/common/errors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/event.ts b/apps/review-desktop/code-oss/src/vs/base/common/event.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/event.ts rename to apps/review-desktop/code-oss/src/vs/base/common/event.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/extpath.ts b/apps/review-desktop/code-oss/src/vs/base/common/extpath.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/extpath.ts rename to apps/review-desktop/code-oss/src/vs/base/common/extpath.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/filters.ts b/apps/review-desktop/code-oss/src/vs/base/common/filters.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/filters.ts rename to apps/review-desktop/code-oss/src/vs/base/common/filters.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/functional.ts b/apps/review-desktop/code-oss/src/vs/base/common/functional.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/functional.ts rename to apps/review-desktop/code-oss/src/vs/base/common/functional.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/fuzzyScorer.ts b/apps/review-desktop/code-oss/src/vs/base/common/fuzzyScorer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/fuzzyScorer.ts rename to apps/review-desktop/code-oss/src/vs/base/common/fuzzyScorer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/glob.ts b/apps/review-desktop/code-oss/src/vs/base/common/glob.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/glob.ts rename to apps/review-desktop/code-oss/src/vs/base/common/glob.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/hash.ts b/apps/review-desktop/code-oss/src/vs/base/common/hash.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/hash.ts rename to apps/review-desktop/code-oss/src/vs/base/common/hash.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/hierarchicalKind.ts b/apps/review-desktop/code-oss/src/vs/base/common/hierarchicalKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/hierarchicalKind.ts rename to apps/review-desktop/code-oss/src/vs/base/common/hierarchicalKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/history.ts b/apps/review-desktop/code-oss/src/vs/base/common/history.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/history.ts rename to apps/review-desktop/code-oss/src/vs/base/common/history.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/hotReload.ts b/apps/review-desktop/code-oss/src/vs/base/common/hotReload.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/hotReload.ts rename to apps/review-desktop/code-oss/src/vs/base/common/hotReload.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/hotReloadHelpers.ts b/apps/review-desktop/code-oss/src/vs/base/common/hotReloadHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/hotReloadHelpers.ts rename to apps/review-desktop/code-oss/src/vs/base/common/hotReloadHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/htmlContent.ts b/apps/review-desktop/code-oss/src/vs/base/common/htmlContent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/htmlContent.ts rename to apps/review-desktop/code-oss/src/vs/base/common/htmlContent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/iconLabels.ts b/apps/review-desktop/code-oss/src/vs/base/common/iconLabels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/iconLabels.ts rename to apps/review-desktop/code-oss/src/vs/base/common/iconLabels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/idGenerator.ts b/apps/review-desktop/code-oss/src/vs/base/common/idGenerator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/idGenerator.ts rename to apps/review-desktop/code-oss/src/vs/base/common/idGenerator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/ime.ts b/apps/review-desktop/code-oss/src/vs/base/common/ime.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/ime.ts rename to apps/review-desktop/code-oss/src/vs/base/common/ime.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/iterator.ts b/apps/review-desktop/code-oss/src/vs/base/common/iterator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/iterator.ts rename to apps/review-desktop/code-oss/src/vs/base/common/iterator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/json.ts b/apps/review-desktop/code-oss/src/vs/base/common/json.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/json.ts rename to apps/review-desktop/code-oss/src/vs/base/common/json.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonEdit.ts b/apps/review-desktop/code-oss/src/vs/base/common/jsonEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonEdit.ts rename to apps/review-desktop/code-oss/src/vs/base/common/jsonEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonErrorMessages.ts b/apps/review-desktop/code-oss/src/vs/base/common/jsonErrorMessages.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonErrorMessages.ts rename to apps/review-desktop/code-oss/src/vs/base/common/jsonErrorMessages.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonFormatter.ts b/apps/review-desktop/code-oss/src/vs/base/common/jsonFormatter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonFormatter.ts rename to apps/review-desktop/code-oss/src/vs/base/common/jsonFormatter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonRpcProtocol.ts b/apps/review-desktop/code-oss/src/vs/base/common/jsonRpcProtocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonRpcProtocol.ts rename to apps/review-desktop/code-oss/src/vs/base/common/jsonRpcProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonSchema.ts b/apps/review-desktop/code-oss/src/vs/base/common/jsonSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonSchema.ts rename to apps/review-desktop/code-oss/src/vs/base/common/jsonSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonc.ts b/apps/review-desktop/code-oss/src/vs/base/common/jsonc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/jsonc.ts rename to apps/review-desktop/code-oss/src/vs/base/common/jsonc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/keyCodes.ts b/apps/review-desktop/code-oss/src/vs/base/common/keyCodes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/keyCodes.ts rename to apps/review-desktop/code-oss/src/vs/base/common/keyCodes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/keybindingLabels.ts b/apps/review-desktop/code-oss/src/vs/base/common/keybindingLabels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/keybindingLabels.ts rename to apps/review-desktop/code-oss/src/vs/base/common/keybindingLabels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/keybindingParser.ts b/apps/review-desktop/code-oss/src/vs/base/common/keybindingParser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/keybindingParser.ts rename to apps/review-desktop/code-oss/src/vs/base/common/keybindingParser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/keybindings.ts b/apps/review-desktop/code-oss/src/vs/base/common/keybindings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/keybindings.ts rename to apps/review-desktop/code-oss/src/vs/base/common/keybindings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/labels.ts b/apps/review-desktop/code-oss/src/vs/base/common/labels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/labels.ts rename to apps/review-desktop/code-oss/src/vs/base/common/labels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/layout.ts b/apps/review-desktop/code-oss/src/vs/base/common/layout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/layout.ts rename to apps/review-desktop/code-oss/src/vs/base/common/layout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/lazy.ts b/apps/review-desktop/code-oss/src/vs/base/common/lazy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/lazy.ts rename to apps/review-desktop/code-oss/src/vs/base/common/lazy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/lifecycle.ts b/apps/review-desktop/code-oss/src/vs/base/common/lifecycle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/lifecycle.ts rename to apps/review-desktop/code-oss/src/vs/base/common/lifecycle.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/linkedList.ts b/apps/review-desktop/code-oss/src/vs/base/common/linkedList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/linkedList.ts rename to apps/review-desktop/code-oss/src/vs/base/common/linkedList.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/linkedText.ts b/apps/review-desktop/code-oss/src/vs/base/common/linkedText.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/linkedText.ts rename to apps/review-desktop/code-oss/src/vs/base/common/linkedText.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/managedSettings.ts b/apps/review-desktop/code-oss/src/vs/base/common/managedSettings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/managedSettings.ts rename to apps/review-desktop/code-oss/src/vs/base/common/managedSettings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/map.ts b/apps/review-desktop/code-oss/src/vs/base/common/map.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/map.ts rename to apps/review-desktop/code-oss/src/vs/base/common/map.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/cgmanifest.json b/apps/review-desktop/code-oss/src/vs/base/common/marked/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/cgmanifest.json rename to apps/review-desktop/code-oss/src/vs/base/common/marked/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/marked.d.ts b/apps/review-desktop/code-oss/src/vs/base/common/marked/marked.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/marked.d.ts rename to apps/review-desktop/code-oss/src/vs/base/common/marked/marked.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/marked.js b/apps/review-desktop/code-oss/src/vs/base/common/marked/marked.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/marked.js rename to apps/review-desktop/code-oss/src/vs/base/common/marked/marked.js diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/marked.license.txt b/apps/review-desktop/code-oss/src/vs/base/common/marked/marked.license.txt similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/marked/marked.license.txt rename to apps/review-desktop/code-oss/src/vs/base/common/marked/marked.license.txt diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/marshalling.ts b/apps/review-desktop/code-oss/src/vs/base/common/marshalling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/marshalling.ts rename to apps/review-desktop/code-oss/src/vs/base/common/marshalling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/marshallingIds.ts b/apps/review-desktop/code-oss/src/vs/base/common/marshallingIds.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/marshallingIds.ts rename to apps/review-desktop/code-oss/src/vs/base/common/marshallingIds.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/mime.ts b/apps/review-desktop/code-oss/src/vs/base/common/mime.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/mime.ts rename to apps/review-desktop/code-oss/src/vs/base/common/mime.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/naturalLanguage/korean.ts b/apps/review-desktop/code-oss/src/vs/base/common/naturalLanguage/korean.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/naturalLanguage/korean.ts rename to apps/review-desktop/code-oss/src/vs/base/common/naturalLanguage/korean.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/navigator.ts b/apps/review-desktop/code-oss/src/vs/base/common/navigator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/navigator.ts rename to apps/review-desktop/code-oss/src/vs/base/common/navigator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/network.ts b/apps/review-desktop/code-oss/src/vs/base/common/network.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/network.ts rename to apps/review-desktop/code-oss/src/vs/base/common/network.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/normalization.ts b/apps/review-desktop/code-oss/src/vs/base/common/normalization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/normalization.ts rename to apps/review-desktop/code-oss/src/vs/base/common/normalization.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/numbers.ts b/apps/review-desktop/code-oss/src/vs/base/common/numbers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/numbers.ts rename to apps/review-desktop/code-oss/src/vs/base/common/numbers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/oauth.ts b/apps/review-desktop/code-oss/src/vs/base/common/oauth.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/oauth.ts rename to apps/review-desktop/code-oss/src/vs/base/common/oauth.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/objects.ts b/apps/review-desktop/code-oss/src/vs/base/common/objects.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/objects.ts rename to apps/review-desktop/code-oss/src/vs/base/common/objects.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observable.ts b/apps/review-desktop/code-oss/src/vs/base/common/observable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observable.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/base.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/base.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/base.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/base.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/changeTracker.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/changeTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/changeTracker.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/changeTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/cancellation.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/cancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/cancellation.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/cancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/deps.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/deps.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/deps.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/commonFacade/deps.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/debugLocation.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/debugLocation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/debugLocation.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/debugLocation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/debugName.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/debugName.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/debugName.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/debugName.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/experimental/reducer.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/experimental/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/experimental/reducer.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/experimental/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/experimental/time.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/experimental/time.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/experimental/time.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/experimental/time.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/experimental/utils.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/experimental/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/experimental/utils.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/experimental/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/index.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/index.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/index.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/consoleObservableLogger.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/consoleObservableLogger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/consoleObservableLogger.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/consoleObservableLogger.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugGetDependencyGraph.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugGetDependencyGraph.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugGetDependencyGraph.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugGetDependencyGraph.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerApi.d.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerApi.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerApi.d.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerApi.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerRpc.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerRpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerRpc.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/debuggerRpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/devToolsLogger.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/devToolsLogger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/devToolsLogger.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/devToolsLogger.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/rpc.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/rpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/rpc.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/rpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/utils.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/utils.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/debugger/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/logging.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/logging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/logging/logging.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/logging/logging.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/map.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/map.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/map.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/map.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/baseObservable.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/baseObservable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/baseObservable.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/baseObservable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/constObservable.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/constObservable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/constObservable.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/constObservable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/derived.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/derived.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/derived.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/derived.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/derivedImpl.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/derivedImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/derivedImpl.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/derivedImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/lazyObservableValue.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/lazyObservableValue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/lazyObservableValue.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/lazyObservableValue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableFromEvent.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableFromEvent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableFromEvent.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableFromEvent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignal.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignal.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignalFromEvent.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignalFromEvent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignalFromEvent.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableSignalFromEvent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValue.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValue.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValueOpts.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValueOpts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValueOpts.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/observables/observableValueOpts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorun.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorun.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorun.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorun.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorunImpl.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorunImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorunImpl.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/reactions/autorunImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/set.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/set.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/set.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/set.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/transaction.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/transaction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/transaction.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/transaction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/promise.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/promise.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/promise.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/promise.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/runOnChange.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/runOnChange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/runOnChange.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/runOnChange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/utils.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/utils.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/utilsCancellation.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/utilsCancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/utilsCancellation.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/utilsCancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/valueWithChangeEvent.ts b/apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/valueWithChangeEvent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/observableInternal/utils/valueWithChangeEvent.ts rename to apps/review-desktop/code-oss/src/vs/base/common/observableInternal/utils/valueWithChangeEvent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/paging.ts b/apps/review-desktop/code-oss/src/vs/base/common/paging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/paging.ts rename to apps/review-desktop/code-oss/src/vs/base/common/paging.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/parsers.ts b/apps/review-desktop/code-oss/src/vs/base/common/parsers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/parsers.ts rename to apps/review-desktop/code-oss/src/vs/base/common/parsers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/path.ts b/apps/review-desktop/code-oss/src/vs/base/common/path.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/path.ts rename to apps/review-desktop/code-oss/src/vs/base/common/path.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/performance.ts b/apps/review-desktop/code-oss/src/vs/base/common/performance.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/performance.ts rename to apps/review-desktop/code-oss/src/vs/base/common/performance.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/platform.ts b/apps/review-desktop/code-oss/src/vs/base/common/platform.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/platform.ts rename to apps/review-desktop/code-oss/src/vs/base/common/platform.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/policy.ts b/apps/review-desktop/code-oss/src/vs/base/common/policy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/policy.ts rename to apps/review-desktop/code-oss/src/vs/base/common/policy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/ports.ts b/apps/review-desktop/code-oss/src/vs/base/common/ports.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/ports.ts rename to apps/review-desktop/code-oss/src/vs/base/common/ports.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/prefixTree.ts b/apps/review-desktop/code-oss/src/vs/base/common/prefixTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/prefixTree.ts rename to apps/review-desktop/code-oss/src/vs/base/common/prefixTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/process.ts b/apps/review-desktop/code-oss/src/vs/base/common/process.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/process.ts rename to apps/review-desktop/code-oss/src/vs/base/common/process.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/processes.ts b/apps/review-desktop/code-oss/src/vs/base/common/processes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/processes.ts rename to apps/review-desktop/code-oss/src/vs/base/common/processes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/product.ts b/apps/review-desktop/code-oss/src/vs/base/common/product.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/product.ts rename to apps/review-desktop/code-oss/src/vs/base/common/product.ts index f2e65a5d3..8e4a80b84 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/base/common/product.ts +++ b/apps/review-desktop/code-oss/src/vs/base/common/product.ts @@ -93,7 +93,7 @@ export interface IProductConfiguration { * Review's own release number, the one the update feed publishes and the one * a user downloads. `version` above is the Code OSS base version, which the * curated extensions match their `engines.vscode` range against, so the two - * cannot be the same field. Kept in sync with `apps/whiteboard-desktop/package.json`. + * cannot be the same field. Kept in sync with `apps/review-desktop/package.json`. */ readonly reviewVersion?: string; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/range.ts b/apps/review-desktop/code-oss/src/vs/base/common/range.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/range.ts rename to apps/review-desktop/code-oss/src/vs/base/common/range.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/resourceTree.ts b/apps/review-desktop/code-oss/src/vs/base/common/resourceTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/resourceTree.ts rename to apps/review-desktop/code-oss/src/vs/base/common/resourceTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/resources.ts b/apps/review-desktop/code-oss/src/vs/base/common/resources.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/resources.ts rename to apps/review-desktop/code-oss/src/vs/base/common/resources.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/scrollable.ts b/apps/review-desktop/code-oss/src/vs/base/common/scrollable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/scrollable.ts rename to apps/review-desktop/code-oss/src/vs/base/common/scrollable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/search.ts b/apps/review-desktop/code-oss/src/vs/base/common/search.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/search.ts rename to apps/review-desktop/code-oss/src/vs/base/common/search.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/semver/cgmanifest.json b/apps/review-desktop/code-oss/src/vs/base/common/semver/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/semver/cgmanifest.json rename to apps/review-desktop/code-oss/src/vs/base/common/semver/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/semver/semver.d.ts b/apps/review-desktop/code-oss/src/vs/base/common/semver/semver.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/semver/semver.d.ts rename to apps/review-desktop/code-oss/src/vs/base/common/semver/semver.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/semver/semver.js b/apps/review-desktop/code-oss/src/vs/base/common/semver/semver.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/semver/semver.js rename to apps/review-desktop/code-oss/src/vs/base/common/semver/semver.js diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/sequence.ts b/apps/review-desktop/code-oss/src/vs/base/common/sequence.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/sequence.ts rename to apps/review-desktop/code-oss/src/vs/base/common/sequence.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/severity.ts b/apps/review-desktop/code-oss/src/vs/base/common/severity.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/severity.ts rename to apps/review-desktop/code-oss/src/vs/base/common/severity.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/sseParser.ts b/apps/review-desktop/code-oss/src/vs/base/common/sseParser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/sseParser.ts rename to apps/review-desktop/code-oss/src/vs/base/common/sseParser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/stopwatch.ts b/apps/review-desktop/code-oss/src/vs/base/common/stopwatch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/stopwatch.ts rename to apps/review-desktop/code-oss/src/vs/base/common/stopwatch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/stream.ts b/apps/review-desktop/code-oss/src/vs/base/common/stream.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/stream.ts rename to apps/review-desktop/code-oss/src/vs/base/common/stream.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/strings.ts b/apps/review-desktop/code-oss/src/vs/base/common/strings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/strings.ts rename to apps/review-desktop/code-oss/src/vs/base/common/strings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/symbols.ts b/apps/review-desktop/code-oss/src/vs/base/common/symbols.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/symbols.ts rename to apps/review-desktop/code-oss/src/vs/base/common/symbols.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/ternarySearchTree.ts b/apps/review-desktop/code-oss/src/vs/base/common/ternarySearchTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/ternarySearchTree.ts rename to apps/review-desktop/code-oss/src/vs/base/common/ternarySearchTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/tfIdf.ts b/apps/review-desktop/code-oss/src/vs/base/common/tfIdf.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/tfIdf.ts rename to apps/review-desktop/code-oss/src/vs/base/common/tfIdf.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/themables.ts b/apps/review-desktop/code-oss/src/vs/base/common/themables.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/themables.ts rename to apps/review-desktop/code-oss/src/vs/base/common/themables.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/types.ts b/apps/review-desktop/code-oss/src/vs/base/common/types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/types.ts rename to apps/review-desktop/code-oss/src/vs/base/common/types.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/uint.ts b/apps/review-desktop/code-oss/src/vs/base/common/uint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/uint.ts rename to apps/review-desktop/code-oss/src/vs/base/common/uint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/uri.ts b/apps/review-desktop/code-oss/src/vs/base/common/uri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/uri.ts rename to apps/review-desktop/code-oss/src/vs/base/common/uri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/uriIpc.ts b/apps/review-desktop/code-oss/src/vs/base/common/uriIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/uriIpc.ts rename to apps/review-desktop/code-oss/src/vs/base/common/uriIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/uriTemplate.ts b/apps/review-desktop/code-oss/src/vs/base/common/uriTemplate.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/uriTemplate.ts rename to apps/review-desktop/code-oss/src/vs/base/common/uriTemplate.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/uriTransformer.ts b/apps/review-desktop/code-oss/src/vs/base/common/uriTransformer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/uriTransformer.ts rename to apps/review-desktop/code-oss/src/vs/base/common/uriTransformer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/uuid.ts b/apps/review-desktop/code-oss/src/vs/base/common/uuid.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/uuid.ts rename to apps/review-desktop/code-oss/src/vs/base/common/uuid.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/validation.ts b/apps/review-desktop/code-oss/src/vs/base/common/validation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/validation.ts rename to apps/review-desktop/code-oss/src/vs/base/common/validation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/verifier.ts b/apps/review-desktop/code-oss/src/vs/base/common/verifier.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/verifier.ts rename to apps/review-desktop/code-oss/src/vs/base/common/verifier.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/worker/webWorker.ts b/apps/review-desktop/code-oss/src/vs/base/common/worker/webWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/worker/webWorker.ts rename to apps/review-desktop/code-oss/src/vs/base/common/worker/webWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/worker/webWorkerBootstrap.ts b/apps/review-desktop/code-oss/src/vs/base/common/worker/webWorkerBootstrap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/worker/webWorkerBootstrap.ts rename to apps/review-desktop/code-oss/src/vs/base/common/worker/webWorkerBootstrap.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/common/yaml.ts b/apps/review-desktop/code-oss/src/vs/base/common/yaml.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/common/yaml.ts rename to apps/review-desktop/code-oss/src/vs/base/common/yaml.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/cpuUsage.sh b/apps/review-desktop/code-oss/src/vs/base/node/cpuUsage.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/cpuUsage.sh rename to apps/review-desktop/code-oss/src/vs/base/node/cpuUsage.sh diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/crypto.ts b/apps/review-desktop/code-oss/src/vs/base/node/crypto.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/crypto.ts rename to apps/review-desktop/code-oss/src/vs/base/node/crypto.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/id.ts b/apps/review-desktop/code-oss/src/vs/base/node/id.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/id.ts rename to apps/review-desktop/code-oss/src/vs/base/node/id.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/libc.ts b/apps/review-desktop/code-oss/src/vs/base/node/libc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/libc.ts rename to apps/review-desktop/code-oss/src/vs/base/node/libc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/macAddress.ts b/apps/review-desktop/code-oss/src/vs/base/node/macAddress.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/macAddress.ts rename to apps/review-desktop/code-oss/src/vs/base/node/macAddress.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/nls.ts b/apps/review-desktop/code-oss/src/vs/base/node/nls.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/nls.ts rename to apps/review-desktop/code-oss/src/vs/base/node/nls.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/nodeStreams.ts b/apps/review-desktop/code-oss/src/vs/base/node/nodeStreams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/nodeStreams.ts rename to apps/review-desktop/code-oss/src/vs/base/node/nodeStreams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/osDisplayProtocolInfo.ts b/apps/review-desktop/code-oss/src/vs/base/node/osDisplayProtocolInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/osDisplayProtocolInfo.ts rename to apps/review-desktop/code-oss/src/vs/base/node/osDisplayProtocolInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/osReleaseInfo.ts b/apps/review-desktop/code-oss/src/vs/base/node/osReleaseInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/osReleaseInfo.ts rename to apps/review-desktop/code-oss/src/vs/base/node/osReleaseInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/pfs.ts b/apps/review-desktop/code-oss/src/vs/base/node/pfs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/pfs.ts rename to apps/review-desktop/code-oss/src/vs/base/node/pfs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/ports.ts b/apps/review-desktop/code-oss/src/vs/base/node/ports.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/ports.ts rename to apps/review-desktop/code-oss/src/vs/base/node/ports.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/powershell.ts b/apps/review-desktop/code-oss/src/vs/base/node/powershell.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/powershell.ts rename to apps/review-desktop/code-oss/src/vs/base/node/powershell.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/processes.ts b/apps/review-desktop/code-oss/src/vs/base/node/processes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/processes.ts rename to apps/review-desktop/code-oss/src/vs/base/node/processes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/profiling.ts b/apps/review-desktop/code-oss/src/vs/base/node/profiling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/profiling.ts rename to apps/review-desktop/code-oss/src/vs/base/node/profiling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/ps.sh b/apps/review-desktop/code-oss/src/vs/base/node/ps.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/ps.sh rename to apps/review-desktop/code-oss/src/vs/base/node/ps.sh diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/ps.ts b/apps/review-desktop/code-oss/src/vs/base/node/ps.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/ps.ts rename to apps/review-desktop/code-oss/src/vs/base/node/ps.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/ripgrep.ts b/apps/review-desktop/code-oss/src/vs/base/node/ripgrep.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/ripgrep.ts rename to apps/review-desktop/code-oss/src/vs/base/node/ripgrep.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/shell.ts b/apps/review-desktop/code-oss/src/vs/base/node/shell.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/shell.ts rename to apps/review-desktop/code-oss/src/vs/base/node/shell.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/terminalEncoding.ts b/apps/review-desktop/code-oss/src/vs/base/node/terminalEncoding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/terminalEncoding.ts rename to apps/review-desktop/code-oss/src/vs/base/node/terminalEncoding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/terminateProcess.sh b/apps/review-desktop/code-oss/src/vs/base/node/terminateProcess.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/terminateProcess.sh rename to apps/review-desktop/code-oss/src/vs/base/node/terminateProcess.sh diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/unc.ts b/apps/review-desktop/code-oss/src/vs/base/node/unc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/unc.ts rename to apps/review-desktop/code-oss/src/vs/base/node/unc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/windowsVersion.ts b/apps/review-desktop/code-oss/src/vs/base/node/windowsVersion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/windowsVersion.ts rename to apps/review-desktop/code-oss/src/vs/base/node/windowsVersion.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/node/zip.ts b/apps/review-desktop/code-oss/src/vs/base/node/zip.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/node/zip.ts rename to apps/review-desktop/code-oss/src/vs/base/node/zip.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/contextmenu/common/contextmenu.ts b/apps/review-desktop/code-oss/src/vs/base/parts/contextmenu/common/contextmenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/contextmenu/common/contextmenu.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/contextmenu/common/contextmenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts b/apps/review-desktop/code-oss/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/contextmenu/electron-browser/contextmenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts b/apps/review-desktop/code-oss/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/contextmenu/electron-main/contextmenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.electron.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.electron.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.mp.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.mp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.mp.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.mp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.net.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.net.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.net.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.net.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/common/ipc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.electron.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.electron.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.mp.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.mp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.mp.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-browser/ipc.mp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.electron.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.electron.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.electron.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.mp.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.mp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.mp.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipc.mp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipcMain.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipcMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipcMain.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/electron-main/ipcMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.cp.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.cp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.cp.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.cp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.mp.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.mp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.mp.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.mp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.net.ts b/apps/review-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.net.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.net.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/ipc/node/ipc.net.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/request/common/request.ts b/apps/review-desktop/code-oss/src/vs/base/parts/request/common/request.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/request/common/request.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/request/common/request.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/request/common/requestImpl.ts b/apps/review-desktop/code-oss/src/vs/base/parts/request/common/requestImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/request/common/requestImpl.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/request/common/requestImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/common/electronTypes.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/common/electronTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/common/electronTypes.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/common/electronTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/common/sandboxTypes.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/common/sandboxTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/common/sandboxTypes.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/common/sandboxTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/electronTypes.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/electronTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/electronTypes.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/electronTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/globals.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/globals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/globals.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/globals.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload-aux.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload-aux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload-aux.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload-aux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/electron-browser/preload.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/node/electronTypes.ts b/apps/review-desktop/code-oss/src/vs/base/parts/sandbox/node/electronTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/sandbox/node/electronTypes.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/sandbox/node/electronTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/storage/common/storage.ts b/apps/review-desktop/code-oss/src/vs/base/parts/storage/common/storage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/storage/common/storage.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/storage/common/storage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/base/parts/storage/node/storage.ts b/apps/review-desktop/code-oss/src/vs/base/parts/storage/node/storage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/base/parts/storage/node/storage.ts rename to apps/review-desktop/code-oss/src/vs/base/parts/storage/node/storage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench-dev.html b/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench-dev.html similarity index 97% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench-dev.html rename to apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench-dev.html index 32ef520b1..0778ac88e 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench-dev.html +++ b/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench-dev.html @@ -67,8 +67,8 @@ editorViewLayer htmlToMarkdown notebookRenderer - whiteboardCanvas - whiteboardLibavoid + reviewCanvas + reviewLibavoid stickyScrollViewLayer tokenizeToString notebookChatEditController diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.html b/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.html similarity index 92% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.html rename to apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.html index 63618e63e..6365dce48 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.html +++ b/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.html @@ -64,8 +64,8 @@ editorViewLayer htmlToMarkdown notebookRenderer - whiteboardCanvas - whiteboardLibavoid + reviewCanvas + reviewLibavoid stickyScrollViewLayer tokenizeToString notebookChatEditController @@ -75,7 +75,7 @@ "/> - + diff --git a/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.ts b/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.ts new file mode 100644 index 000000000..4eae274d2 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.ts @@ -0,0 +1,644 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/* eslint-disable no-restricted-globals */ + +(async function () { + + // Add a perf entry right from the top + performance.mark('code/didStartRenderer'); + + type ISandboxConfiguration = import('../../../base/parts/sandbox/common/sandboxTypes.js').ISandboxConfiguration; + type ILoadResult = import('../../../platform/window/electron-browser/window.js').ILoadResult; + type ILoadOptions = import('../../../platform/window/electron-browser/window.js').ILoadOptions; + type INativeWindowConfiguration = import('../../../platform/window/common/window.ts').INativeWindowConfiguration; + type IMainWindowSandboxGlobals = import('../../../base/parts/sandbox/electron-browser/globals.js').IMainWindowSandboxGlobals; + type IDesktopMain = import('../../../workbench/electron-browser/desktop.main.js').IDesktopMain; + + const preloadGlobals = (window as unknown as { vscode: IMainWindowSandboxGlobals }).vscode; // defined by preload.ts + const safeProcess = preloadGlobals.process; + + //#region Splash Screen Helpers + + function showSplash(configuration: INativeWindowConfiguration) { + performance.mark('code/willShowPartsSplash'); + showDefaultSplash(configuration); + performance.mark('code/didShowPartsSplash'); + } + + function showDefaultSplash(configuration: INativeWindowConfiguration) { + let data = configuration.partsSplash; + if (data) { + if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { + if ((configuration.colorScheme.dark && data.baseTheme !== 'hc-black') || (!configuration.colorScheme.dark && data.baseTheme !== 'hc-light')) { + data = undefined; // high contrast mode has been turned by the OS -> ignore stored colors and layouts + } + } else if (configuration.autoDetectColorScheme) { + if ((configuration.colorScheme.dark && data.baseTheme !== 'vs-dark') || (!configuration.colorScheme.dark && data.baseTheme !== 'vs')) { + data = undefined; // OS color scheme is tracked and has changed + } + } + } + + // developing an extension -> ignore stored layouts + if (data && configuration.extensionDevelopmentPath) { + data.layoutInfo = undefined; + } + + // minimal color configuration (works with or without persisted data) + let baseTheme; + let shellBackground; + let shellForeground; + if (data) { + baseTheme = data.baseTheme; + shellBackground = data.colorInfo.editorBackground; + shellForeground = data.colorInfo.foreground; + } else if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { + if (configuration.colorScheme.dark) { + baseTheme = 'hc-black'; + shellBackground = '#000000'; + shellForeground = '#FFFFFF'; + } else { + baseTheme = 'hc-light'; + shellBackground = '#FFFFFF'; + shellForeground = '#000000'; + } + } else if (configuration.autoDetectColorScheme) { + if (configuration.colorScheme.dark) { + baseTheme = 'vs-dark'; + shellBackground = '#1E1E1E'; + shellForeground = '#CCCCCC'; + } else { + baseTheme = 'vs'; + shellBackground = '#FFFFFF'; + shellForeground = '#000000'; + } + } + + const style = document.createElement('style'); + style.className = 'initialShellColors'; + window.document.head.appendChild(style); + style.textContent = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`; + + // set zoom level as soon as possible + if (typeof data?.zoomLevel === 'number' && typeof preloadGlobals?.webFrame?.setZoomLevel === 'function') { + preloadGlobals.webFrame.setZoomLevel(data.zoomLevel); + } + + // restore parts if possible (we might not always store layout info) + if (data?.layoutInfo) { + const { layoutInfo, colorInfo } = data; + const modernUI = layoutInfo.modernUI === true; + const floatingMargin = 4; + const floatingOuterMargin = floatingMargin * 2; + const floatingBorderWidth = 1; + + const splash = document.createElement('div'); + splash.id = 'monaco-parts-splash'; + splash.className = baseTheme ?? 'vs-dark'; + + if (layoutInfo.windowBorder && colorInfo.windowBorder) { + const borderElement = document.createElement('div'); + borderElement.style.position = 'absolute'; + borderElement.style.width = 'calc(100vw - 2px)'; + borderElement.style.height = 'calc(100vh - 2px)'; + borderElement.style.zIndex = '1'; // allow border above other elements + borderElement.style.border = `1px solid var(--window-border-color)`; + borderElement.style.setProperty('--window-border-color', colorInfo.windowBorder); + + if (layoutInfo.windowBorderRadius) { + borderElement.style.borderRadius = layoutInfo.windowBorderRadius; + } + + splash.appendChild(borderElement); + } + + const setBounds = (element: HTMLElement, bounds: { top: number; bottom?: number; left?: number; right?: number; width?: number; height?: number }) => { + element.style.position = 'absolute'; + element.style.top = `${bounds.top}px`; + if (typeof bounds.bottom === 'number') { + element.style.bottom = `${bounds.bottom}px`; + } + if (typeof bounds.left === 'number') { + element.style.left = `${bounds.left}px`; + } + if (typeof bounds.right === 'number') { + element.style.right = `${bounds.right}px`; + } + if (typeof bounds.width === 'number') { + element.style.width = `${bounds.width}px`; + } + if (typeof bounds.height === 'number') { + element.style.height = `${bounds.height}px`; + } + }; + + const setPartBounds = (element: HTMLElement, bounds: { top: number; left: number; width: number; height: number }) => { + element.style.position = 'absolute'; + element.style.top = `${bounds.top}px`; + element.style.left = `${bounds.left}px`; + element.style.width = `${bounds.width}px`; + element.style.height = `${bounds.height}px`; + }; + + const applyFloatingCardStyles = (element: HTMLElement, backgroundColor: string | undefined) => { + element.style.boxSizing = 'border-box'; + element.style.border = `${floatingBorderWidth}px solid ${colorInfo.agentsPanelBorder ?? colorInfo.editorGroupBorder ?? 'transparent'}`; + element.style.borderRadius = '8px'; + element.style.backgroundColor = backgroundColor ?? colorInfo.editorBackground ?? colorInfo.background; + element.style.overflow = 'hidden'; + }; + + const contentTop = layoutInfo.titleBarHeight; + const contentBottom = layoutInfo.statusBarHeight; + const contentHeight = `calc(100% - ${contentTop + contentBottom}px)`; + const activityHeight = modernUI ? `calc(100% - ${contentTop + contentBottom + floatingMargin}px)` : contentHeight; + + if (layoutInfo.auxiliaryBarWidth === Number.MAX_SAFE_INTEGER) { + // if auxiliary bar is maximized, it goes as wide as the + // window width but leaving room for activity bar + layoutInfo.auxiliaryBarWidth = window.innerWidth - layoutInfo.activityBarWidth; + } else { + // otherwise adjust for other parts sizes if not maximized + layoutInfo.auxiliaryBarWidth = Math.min(layoutInfo.auxiliaryBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth + layoutInfo.sideBarWidth)); + } + layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth + layoutInfo.auxiliaryBarWidth)); + + // part: title + if (layoutInfo.titleBarHeight > 0) { + const titleDiv = document.createElement('div'); + titleDiv.style.position = 'absolute'; + titleDiv.style.width = '100%'; + titleDiv.style.height = `${layoutInfo.titleBarHeight}px`; + titleDiv.style.left = '0'; + titleDiv.style.top = '0'; + titleDiv.style.backgroundColor = modernUI ? 'transparent' : `${colorInfo.titleBarBackground}`; + (titleDiv.style as CSSStyleDeclaration & { '-webkit-app-region': string })['-webkit-app-region'] = 'drag'; + splash.appendChild(titleDiv); + + if (!modernUI && colorInfo.titleBarBorder) { + const titleBorder = document.createElement('div'); + titleBorder.style.position = 'absolute'; + titleBorder.style.width = '100%'; + titleBorder.style.height = '1px'; + titleBorder.style.left = '0'; + titleBorder.style.bottom = '0'; + titleBorder.style.borderBottom = `1px solid ${colorInfo.titleBarBorder}`; + titleDiv.appendChild(titleBorder); + } + } + + // part: activity bar + if (layoutInfo.activityBarWidth > 0) { + const activityDiv = document.createElement('div'); + activityDiv.style.position = 'absolute'; + activityDiv.style.width = `${layoutInfo.activityBarWidth}px`; + activityDiv.style.height = activityHeight; + activityDiv.style.top = `${contentTop}px`; + if (layoutInfo.sideBarSide === 'left') { + activityDiv.style.left = '0'; + } else { + activityDiv.style.right = '0'; + } + activityDiv.style.backgroundColor = modernUI ? 'transparent' : `${colorInfo.activityBarBackground}`; + splash.appendChild(activityDiv); + + if (!modernUI && colorInfo.activityBarBorder) { + const activityBorderDiv = document.createElement('div'); + activityBorderDiv.style.position = 'absolute'; + activityBorderDiv.style.width = '1px'; + activityBorderDiv.style.height = '100%'; + activityBorderDiv.style.top = '0'; + if (layoutInfo.sideBarSide === 'left') { + activityBorderDiv.style.right = '0'; + activityBorderDiv.style.borderRight = `1px solid ${colorInfo.activityBarBorder}`; + } else { + activityBorderDiv.style.left = '0'; + activityBorderDiv.style.borderLeft = `1px solid ${colorInfo.activityBarBorder}`; + } + activityDiv.appendChild(activityBorderDiv); + } + } + + // part: side bar + if (layoutInfo.sideBarWidth > 0) { + const sideDiv = document.createElement('div'); + if (modernUI && layoutInfo.partBounds?.sideBar) { + setPartBounds(sideDiv, layoutInfo.partBounds.sideBar); + } else if (layoutInfo.sideBarSide === 'left') { + setBounds(sideDiv, { + top: contentTop, + bottom: modernUI ? contentBottom + floatingMargin : contentBottom, + left: layoutInfo.activityBarWidth + (modernUI ? floatingMargin : 0), + width: modernUI ? Math.max(0, layoutInfo.sideBarWidth - floatingOuterMargin - floatingBorderWidth * 2) : layoutInfo.sideBarWidth + }); + } else { + setBounds(sideDiv, { + top: contentTop, + bottom: modernUI ? contentBottom + floatingMargin : contentBottom, + right: layoutInfo.activityBarWidth + (modernUI ? floatingMargin : 0), + width: modernUI ? Math.max(0, layoutInfo.sideBarWidth - floatingOuterMargin - floatingBorderWidth * 2) : layoutInfo.sideBarWidth + }); + } + if (modernUI) { + applyFloatingCardStyles(sideDiv, colorInfo.agentsPanelBackground ?? colorInfo.sideBarBackground); + } else { + sideDiv.style.backgroundColor = `${colorInfo.sideBarBackground}`; + } + splash.appendChild(sideDiv); + + if (!modernUI && colorInfo.sideBarBorder) { + const sideBorderDiv = document.createElement('div'); + sideBorderDiv.style.position = 'absolute'; + sideBorderDiv.style.width = '1px'; + sideBorderDiv.style.height = '100%'; + sideBorderDiv.style.top = '0'; + sideBorderDiv.style.right = '0'; + if (layoutInfo.sideBarSide === 'left') { + sideBorderDiv.style.borderRight = `1px solid ${colorInfo.sideBarBorder}`; + } else { + sideBorderDiv.style.left = '0'; + sideBorderDiv.style.borderLeft = `1px solid ${colorInfo.sideBarBorder}`; + } + sideDiv.appendChild(sideBorderDiv); + } + } + + // part: auxiliary sidebar + if (layoutInfo.auxiliaryBarWidth > 0) { + const auxSideDiv = document.createElement('div'); + if (modernUI && layoutInfo.partBounds?.auxiliaryBar) { + setPartBounds(auxSideDiv, layoutInfo.partBounds.auxiliaryBar); + } else if (layoutInfo.sideBarSide === 'left') { + setBounds(auxSideDiv, { + top: contentTop, + bottom: modernUI ? contentBottom + floatingMargin : contentBottom, + right: modernUI ? floatingOuterMargin : 0, + width: modernUI ? Math.max(0, layoutInfo.auxiliaryBarWidth - floatingOuterMargin - floatingMargin - floatingBorderWidth * 2) : layoutInfo.auxiliaryBarWidth + }); + } else { + setBounds(auxSideDiv, { + top: contentTop, + bottom: modernUI ? contentBottom + floatingMargin : contentBottom, + left: modernUI ? floatingOuterMargin : 0, + width: modernUI ? Math.max(0, layoutInfo.auxiliaryBarWidth - floatingOuterMargin - floatingMargin - floatingBorderWidth * 2) : layoutInfo.auxiliaryBarWidth + }); + } + if (modernUI) { + applyFloatingCardStyles(auxSideDiv, colorInfo.sideBarBackground); + } else { + auxSideDiv.style.backgroundColor = `${colorInfo.sideBarBackground}`; + } + splash.appendChild(auxSideDiv); + + if (!modernUI && colorInfo.sideBarBorder) { + const auxSideBorderDiv = document.createElement('div'); + auxSideBorderDiv.style.position = 'absolute'; + auxSideBorderDiv.style.width = '1px'; + auxSideBorderDiv.style.height = '100%'; + auxSideBorderDiv.style.top = '0'; + if (layoutInfo.sideBarSide === 'left') { + auxSideBorderDiv.style.left = '0'; + auxSideBorderDiv.style.borderLeft = `1px solid ${colorInfo.sideBarBorder}`; + } else { + auxSideBorderDiv.style.right = '0'; + auxSideBorderDiv.style.borderRight = `1px solid ${colorInfo.sideBarBorder}`; + } + auxSideDiv.appendChild(auxSideBorderDiv); + } + } + + if (modernUI && (layoutInfo.partBounds?.editor || !layoutInfo.partBounds)) { + const editorDiv = document.createElement('div'); + if (layoutInfo.partBounds?.editor) { + setPartBounds(editorDiv, layoutInfo.partBounds.editor); + } else { + const editorLeft = (layoutInfo.sideBarSide === 'left' ? layoutInfo.activityBarWidth + layoutInfo.sideBarWidth : layoutInfo.auxiliaryBarWidth) + floatingMargin; + const editorRight = (layoutInfo.sideBarSide === 'left' ? layoutInfo.auxiliaryBarWidth : layoutInfo.activityBarWidth + layoutInfo.sideBarWidth) + floatingMargin; + setBounds(editorDiv, { + top: contentTop, + bottom: contentBottom + floatingMargin, + left: editorLeft, + right: editorRight + }); + } + applyFloatingCardStyles(editorDiv, colorInfo.editorBackground); + splash.appendChild(editorDiv); + } + + if (modernUI && layoutInfo.partBounds?.panel) { + const panelDiv = document.createElement('div'); + setPartBounds(panelDiv, layoutInfo.partBounds.panel); + applyFloatingCardStyles(panelDiv, colorInfo.panelBackground ?? colorInfo.editorBackground); + splash.appendChild(panelDiv); + } + + // part: statusbar + if (layoutInfo.statusBarHeight > 0) { + const statusDiv = document.createElement('div'); + statusDiv.style.position = 'absolute'; + statusDiv.style.width = '100%'; + statusDiv.style.height = `${layoutInfo.statusBarHeight}px`; + statusDiv.style.bottom = '0'; + statusDiv.style.left = '0'; + if (modernUI) { + statusDiv.style.backgroundColor = 'transparent'; + } else if (configuration.workspace && colorInfo.statusBarBackground) { + statusDiv.style.backgroundColor = colorInfo.statusBarBackground; + } else if (!configuration.workspace && colorInfo.statusBarNoFolderBackground) { + statusDiv.style.backgroundColor = colorInfo.statusBarNoFolderBackground; + } + splash.appendChild(statusDiv); + + if (!modernUI && colorInfo.statusBarBorder) { + const statusBorderDiv = document.createElement('div'); + statusBorderDiv.style.position = 'absolute'; + statusBorderDiv.style.width = '100%'; + statusBorderDiv.style.height = '1px'; + statusBorderDiv.style.top = '0'; + statusBorderDiv.style.borderTop = `1px solid ${colorInfo.statusBarBorder}`; + statusDiv.appendChild(statusBorderDiv); + } + } + + window.document.body.appendChild(splash); + } + } + + //#endregion + + //#region Window Helpers + + async function load(options: ILoadOptions): Promise> { + + // Window Configuration from Preload Script + const configuration = await resolveWindowConfiguration(); + + // Signal before import() + options?.beforeImport?.(configuration); + + // Developer settings + const { enableDeveloperKeybindings, removeDeveloperKeybindingsAfterLoad, developerDeveloperKeybindingsDisposable, forceDisableShowDevtoolsOnError } = setupDeveloperKeybindings(configuration, options); + + // NLS + setupNLS(configuration); + + // Compute base URL and set as global + const baseUrl = new URL(`${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out/`); + globalThis._VSCODE_FILE_ROOT = baseUrl.toString(); + + // Set product configuration as global (used e.g. to select the ASAR path in `amdX`) + globalThis._VSCODE_PRODUCT_JSON = { ...configuration.product }; + + // Dev only: CSS import map tricks + setupCSSImportMaps(configuration, baseUrl); + + // ESM Import + try { + let workbenchUrl: string; + if (!!safeProcess.env['VSCODE_DEV'] && globalThis._VSCODE_USE_RELATIVE_IMPORTS) { + workbenchUrl = '../../../review/review.desktop.main.js'; // Review Desktop fork + } else { + workbenchUrl = new URL(`vs/review/review.desktop.main.js`, baseUrl).href; + } + + const result = await import(workbenchUrl); + if (developerDeveloperKeybindingsDisposable && removeDeveloperKeybindingsAfterLoad) { + developerDeveloperKeybindingsDisposable(); + } + + return { result, configuration }; + } catch (error) { + onUnexpectedError(error, enableDeveloperKeybindings && !forceDisableShowDevtoolsOnError); + + throw error; + } + } + + async function resolveWindowConfiguration() { + const timeout = setTimeout(() => { console.error(`[resolve window config] Could not resolve window configuration within 10 seconds, but will continue to wait...`); }, 10000); + performance.mark('code/willWaitForWindowConfig'); + + const configuration = await preloadGlobals.context.resolveConfiguration() as T; + performance.mark('code/didWaitForWindowConfig'); + + clearTimeout(timeout); + + return configuration; + } + + function setupDeveloperKeybindings(configuration: T, options: ILoadOptions) { + const { + forceEnableDeveloperKeybindings, + disallowReloadKeybinding, + removeDeveloperKeybindingsAfterLoad, + forceDisableShowDevtoolsOnError + } = typeof options?.configureDeveloperSettings === 'function' ? options.configureDeveloperSettings(configuration) : { + forceEnableDeveloperKeybindings: false, + disallowReloadKeybinding: false, + removeDeveloperKeybindingsAfterLoad: false, + forceDisableShowDevtoolsOnError: false + }; + + const isDev = !!safeProcess.env['VSCODE_DEV']; + const enableDeveloperKeybindings = Boolean(isDev || forceEnableDeveloperKeybindings); + let developerDeveloperKeybindingsDisposable: Function | undefined = undefined; + if (enableDeveloperKeybindings) { + developerDeveloperKeybindingsDisposable = registerDeveloperKeybindings(disallowReloadKeybinding); + } + + return { + enableDeveloperKeybindings, + removeDeveloperKeybindingsAfterLoad, + developerDeveloperKeybindingsDisposable, + forceDisableShowDevtoolsOnError + }; + } + + function registerDeveloperKeybindings(disallowReloadKeybinding: boolean | undefined): Function { + const ipcRenderer = preloadGlobals.ipcRenderer; + + const extractKey = + function (e: KeyboardEvent) { + return [ + e.ctrlKey ? 'ctrl-' : '', + e.metaKey ? 'meta-' : '', + e.altKey ? 'alt-' : '', + e.shiftKey ? 'shift-' : '', + e.keyCode + ].join(''); + }; + + // Devtools & reload support + const TOGGLE_DEV_TOOLS_KB = (safeProcess.platform === 'darwin' ? 'meta-alt-73' : 'ctrl-shift-73'); // mac: Cmd-Alt-I, rest: Ctrl-Shift-I + const TOGGLE_DEV_TOOLS_KB_ALT = '123'; // F12 + const RELOAD_KB = (safeProcess.platform === 'darwin' ? 'meta-82' : 'ctrl-82'); // mac: Cmd-R, rest: Ctrl-R + + let listener: ((e: KeyboardEvent) => void) | undefined = function (e) { + const key = extractKey(e); + if (key === TOGGLE_DEV_TOOLS_KB || key === TOGGLE_DEV_TOOLS_KB_ALT) { + ipcRenderer.send('vscode:toggleDevTools'); + } else if (key === RELOAD_KB && !disallowReloadKeybinding) { + ipcRenderer.send('vscode:reloadWindow'); + } + }; + + window.addEventListener('keydown', listener); + + return function () { + if (listener) { + window.removeEventListener('keydown', listener); + listener = undefined; + } + }; + } + + function setupNLS(configuration: T): void { + globalThis._VSCODE_NLS_MESSAGES = configuration.nls.messages; + globalThis._VSCODE_NLS_LANGUAGE = configuration.nls.language; + + let language = configuration.nls.language || 'en'; + if (language === 'zh-tw') { + language = 'zh-Hant'; + } else if (language === 'zh-cn') { + language = 'zh-Hans'; + } + + window.document.documentElement.setAttribute('lang', language); + } + + function onUnexpectedError(error: string | Error, showDevtoolsOnError: boolean): void { + if (showDevtoolsOnError) { + const ipcRenderer = preloadGlobals.ipcRenderer; + ipcRenderer.send('vscode:openDevTools'); + } + + console.error(`[uncaught exception]: ${error}`); + + if (error && typeof error !== 'string' && error.stack) { + console.error(error.stack); + } + } + + function fileUriFromPath(path: string, config: { isWindows?: boolean; scheme?: string; fallbackAuthority?: string }): string { + + // Since we are building a URI, we normalize any backslash + // to slashes and we ensure that the path begins with a '/'. + let pathName = path.replace(/\\/g, '/'); + if (pathName.length > 0 && pathName.charAt(0) !== '/') { + pathName = `/${pathName}`; + } + + let uri: string; + + // Windows: in order to support UNC paths (which start with '//') + // that have their own authority, we do not use the provided authority + // but rather preserve it. + if (config.isWindows && pathName.startsWith('//')) { + uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); + } + + // Otherwise we optionally add the provided authority if specified + else { + uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); + } + + return uri.replace(/#/g, '%23'); + } + + function setupCSSImportMaps(configuration: T, baseUrl: URL) { + + // DEV --------------------------------------------------------------------------------------- + // DEV: This is for development and enables loading CSS via import-statements via import-maps. + // DEV: For each CSS modules that we have we defined an entry in the import map that maps to + // DEV: a blob URL that loads the CSS via a dynamic @import-rule. + // DEV --------------------------------------------------------------------------------------- + + if (globalThis._VSCODE_DISABLE_CSS_IMPORT_MAP) { + return; // disabled in certain development setups + } + + if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) { + performance.mark('code/willAddCssLoader'); + + globalThis._VSCODE_CSS_LOAD = function (url) { + const link = document.createElement('link'); + link.setAttribute('rel', 'stylesheet'); + link.setAttribute('type', 'text/css'); + link.setAttribute('href', url); + + window.document.head.appendChild(link); + }; + + const importMap: { imports: Record } = { imports: {} }; + for (const cssModule of configuration.cssModules) { + const cssUrl = new URL(cssModule, baseUrl).href; + const jsSrc = `globalThis._VSCODE_CSS_LOAD('${cssUrl}');\n`; + const blob = new Blob([jsSrc], { type: 'application/javascript' }); + importMap.imports[cssUrl] = URL.createObjectURL(blob); + } + + const ttp = window.trustedTypes?.createPolicy('vscode-bootstrapImportMap', { createScript(value) { return value; }, }); + const importMapSrc = JSON.stringify(importMap, undefined, 2); + const importMapScript = document.createElement('script'); + importMapScript.type = 'importmap'; + importMapScript.setAttribute('nonce', '0c6a828f1297'); + // @ts-expect-error + importMapScript.textContent = ttp?.createScript(importMapSrc) ?? importMapSrc; + window.document.head.appendChild(importMapScript); + + performance.mark('code/didAddCssLoader'); + } + } + + //#endregion + + const { result, configuration } = await load( + { + configureDeveloperSettings: function (windowConfig) { + return { + // disable automated devtools opening on error when running extension tests + // as this can lead to nondeterministic test execution (devtools steals focus) + forceDisableShowDevtoolsOnError: typeof windowConfig.extensionTestsPath === 'string' || windowConfig['enable-smoke-test-driver'] === true, + // enable devtools keybindings in extension development window + forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath) && windowConfig.extensionDevelopmentPath.length > 0, + removeDeveloperKeybindingsAfterLoad: true + }; + }, + beforeImport: function (windowConfig) { + + // Show our splash as early as possible + showSplash(windowConfig); + + // Code windows have a `vscodeWindowId` property to identify them + Object.defineProperty(window, 'vscodeWindowId', { + get: () => windowConfig.windowId + }); + + // It looks like browsers only lazily enable + // the element when needed. Since we + // leverage canvas elements in our code in many + // locations, we try to help the browser to + // initialize canvas when it is idle, right + // before we wait for the scripts to be loaded. + window.requestIdleCallback(() => { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + context?.clearRect(0, 0, canvas.width, canvas.height); + canvas.remove(); + }, { timeout: 50 }); + + // Track import() perf + performance.mark('code/willLoadWorkbenchMain'); + } + } + ); + + // Mark start of workbench + performance.mark('code/didLoadWorkbenchMain'); + + // Load workbench + result.main(configuration); +}()); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-main/app.ts b/apps/review-desktop/code-oss/src/vs/code/electron-main/app.ts similarity index 98% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-main/app.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-main/app.ts index 54614b863..bc7e3faff 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-main/app.ts +++ b/apps/review-desktop/code-oss/src/vs/code/electron-main/app.ts @@ -138,10 +138,10 @@ import { McpGatewayService } from '../../platform/mcp/node/mcpGatewayService.js' import { McpGatewayChannel } from '../../platform/mcp/node/mcpGatewayChannel.js'; import { ITerminalSandboxService, NullTerminalSandboxService } from '../../platform/sandbox/common/terminalSandboxService.js'; import ErrorTelemetry from '../../platform/telemetry/electron-main/errorTelemetry.js'; -import { WhiteboardDesktopHost } from '../../whiteboard/electron-main/whiteboardDesktopHost.js'; -import { WhiteboardMenubarMainService } from '../../whiteboard/electron-main/whiteboardMenubar.js'; -import { WhiteboardUpdateDialog } from '../../whiteboard/electron-main/whiteboardUpdateDialog.js'; -import { WHITEBOARD_DESKTOP_CHANNEL, WhiteboardDesktopChannel } from '../../whiteboard/electron-main/whiteboardDesktopChannel.js'; +import { ReviewDesktopHost } from '../../review/electron-main/reviewDesktopHost.js'; +import { ReviewMenubarMainService } from '../../review/electron-main/reviewMenubar.js'; +import { ReviewUpdateDialog } from '../../review/electron-main/reviewUpdateDialog.js'; +import { REVIEW_DESKTOP_CHANNEL, ReviewDesktopChannel } from '../../review/electron-main/reviewDesktopChannel.js'; /** * The main VS Code application. There will only ever be one instance, @@ -157,7 +157,7 @@ export class CodeApplication extends Disposable { private windowsMainService: IWindowsMainService | undefined; private auxiliaryWindowsMainService: IAuxiliaryWindowsMainService | undefined; private nativeHostMainService: INativeHostMainService | undefined; - private whiteboardDesktopHost: WhiteboardDesktopHost | undefined; + private reviewDesktopHost: ReviewDesktopHost | undefined; constructor( private readonly mainProcessNodeIpcServer: NodeIPCServer, @@ -664,7 +664,7 @@ export class CodeApplication extends Disposable { const appInstantiationService = await this.initServices(machineId, sqmId, devDeviceId, sharedProcessReady); // Review Desktop owns one global embedded server for the application lifetime. - this.whiteboardDesktopHost = this._register(appInstantiationService.createInstance(WhiteboardDesktopHost)); + this.reviewDesktopHost = this._register(appInstantiationService.createInstance(ReviewDesktopHost)); // Error telemetry appInstantiationService.invokeFunction(accessor => this._register(new ErrorTelemetry(accessor.get(ILogService), accessor.get(ITelemetryService)))); @@ -1152,7 +1152,7 @@ export class CodeApplication extends Disposable { // Menubar: Review owns the native menu in the main process, because its // workbench never sends the menu data the stock service builds from. - services.set(IMenubarMainService, new SyncDescriptor(WhiteboardMenubarMainService)); + services.set(IMenubarMainService, new SyncDescriptor(ReviewMenubarMainService)); // Extension Host Starter services.set(IExtensionHostStarter, new SyncDescriptor(ExtensionHostStarter)); @@ -1246,8 +1246,8 @@ export class CodeApplication extends Disposable { // Review Desktop hands the renderer its server endpoint over IPC rather // than through bootstrap environment variables. - if (this.whiteboardDesktopHost) { - mainProcessElectronServer.registerChannel(WHITEBOARD_DESKTOP_CHANNEL, new WhiteboardDesktopChannel(this.whiteboardDesktopHost)); + if (this.reviewDesktopHost) { + mainProcessElectronServer.registerChannel(REVIEW_DESKTOP_CHANNEL, new ReviewDesktopChannel(this.reviewDesktopHost)); } const launchChannel = ProxyChannel.fromService(accessor.get(ILaunchMainService), disposables, { disableMarshalling: true }); @@ -1286,7 +1286,7 @@ export class CodeApplication extends Disposable { // Report explicit update checks natively. Review's renderer stubs out // `IUpdateService`, so the main process owns the whole feedback path. - this._register(accessor.get(IInstantiationService).createInstance(WhiteboardUpdateDialog)); + this._register(accessor.get(IInstantiationService).createInstance(ReviewUpdateDialog)); // Metered Connection const meteredConnectionChannel = new MeteredConnectionChannel(accessor.get(IMeteredConnectionService) as MeteredConnectionMainService); diff --git a/apps/review-desktop/code-oss/src/vs/code/electron-main/main.ts b/apps/review-desktop/code-oss/src/vs/code/electron-main/main.ts new file mode 100644 index 000000000..0aad0c6bc --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/code/electron-main/main.ts @@ -0,0 +1,726 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import '../../platform/update/common/update.config.contribution.js'; + +import { app, dialog } from 'electron'; +import { unlinkSync, promises } from 'fs'; +import { URI } from '../../base/common/uri.js'; +import { coalesce, distinct } from '../../base/common/arrays.js'; +import { Promises, retry } from '../../base/common/async.js'; +import { toErrorMessage } from '../../base/common/errorMessage.js'; +import { ExpectedError, setUnexpectedErrorHandler } from '../../base/common/errors.js'; +import { IPathWithLineAndColumn, isValidBasename, parseLineAndColumnAware, sanitizeFilePath } from '../../base/common/extpath.js'; +import { Event } from '../../base/common/event.js'; +import { getPathLabel } from '../../base/common/labels.js'; +import { Schemas } from '../../base/common/network.js'; +import { basename, join, resolve } from '../../base/common/path.js'; +import { mark } from '../../base/common/performance.js'; +import { IProcessEnvironment, isLinux, isMacintosh, isWindows, OS } from '../../base/common/platform.js'; +import { cwd } from '../../base/common/process.js'; +import { rtrim, trim } from '../../base/common/strings.js'; +import { Promises as FSPromises } from '../../base/node/pfs.js'; +import { ProxyChannel } from '../../base/parts/ipc/common/ipc.js'; +import { Client as NodeIPCClient } from '../../base/parts/ipc/common/ipc.net.js'; +import { connect as nodeIPCConnect, serve as nodeIPCServe, Server as NodeIPCServer, XDG_RUNTIME_DIR } from '../../base/parts/ipc/node/ipc.net.js'; +import { CodeApplication } from './app.js'; +import { localize } from '../../nls.js'; +import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; +import { ConfigurationService } from '../../platform/configuration/common/configurationService.js'; +import { IDiagnosticsMainService } from '../../platform/diagnostics/electron-main/diagnosticsMainService.js'; +import { DiagnosticsService } from '../../platform/diagnostics/node/diagnosticsService.js'; +import { NativeParsedArgs } from '../../platform/environment/common/argv.js'; +import { EnvironmentMainService, IEnvironmentMainService } from '../../platform/environment/electron-main/environmentMainService.js'; +import { addArg, parseMainProcessArgv } from '../../platform/environment/node/argvHelper.js'; +import { createWaitMarkerFileSync } from '../../platform/environment/node/wait.js'; +import { IFileService } from '../../platform/files/common/files.js'; +import { FileService } from '../../platform/files/common/fileService.js'; +import { DiskFileSystemProvider } from '../../platform/files/node/diskFileSystemProvider.js'; +import { SyncDescriptor } from '../../platform/instantiation/common/descriptors.js'; +import { IInstantiationService, ServicesAccessor } from '../../platform/instantiation/common/instantiation.js'; +import { InstantiationService } from '../../platform/instantiation/common/instantiationService.js'; +import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; +import { ILaunchMainService } from '../../platform/launch/electron-main/launchMainService.js'; +import { ILifecycleMainService, LifecycleMainService } from '../../platform/lifecycle/electron-main/lifecycleMainService.js'; +import { BufferLogger } from '../../platform/log/common/bufferLog.js'; +import { ConsoleMainLogger, getLogLevel, ILoggerService, ILogService, isDevConsoleLogForwardingEnabled, registerDevConsoleLogForwarder } from '../../platform/log/common/log.js'; +import product from '../../platform/product/common/product.js'; +import { IProductService } from '../../platform/product/common/productService.js'; +import { IProtocolMainService } from '../../platform/protocol/electron-main/protocol.js'; +import { ProtocolMainService } from '../../platform/protocol/electron-main/protocolMainService.js'; +import { ITunnelService } from '../../platform/tunnel/common/tunnel.js'; +import { TunnelService } from '../../platform/tunnel/node/tunnelService.js'; +import { IRequestService } from '../../platform/request/common/request.js'; +import { RequestService } from '../../platform/request/electron-utility/requestService.js'; +import { ISignService } from '../../platform/sign/common/sign.js'; +import { SignService } from '../../platform/sign/node/signService.js'; +import { IStateReadService, IStateService } from '../../platform/state/node/state.js'; +import { NullTelemetryService } from '../../platform/telemetry/common/telemetryUtils.js'; +import { IThemeMainService } from '../../platform/theme/electron-main/themeMainService.js'; +import { IUserDataProfilesMainService, UserDataProfilesMainService } from '../../platform/userDataProfile/electron-main/userDataProfile.js'; +import { IPolicyService, NullPolicyService } from '../../platform/policy/common/policy.js'; +import { NativePolicyService } from '../../platform/policy/node/nativePolicyService.js'; +import { FilePolicyService } from '../../platform/policy/common/filePolicyService.js'; +import { MultiplexPolicyService } from '../../platform/policy/common/multiplexPolicyService.js'; +import { GITHUB_COPILOT_MACOS_BUNDLE_ID, GITHUB_COPILOT_WIN32_POLICY_NAME, GITHUB_COPILOT_WIN32_REGISTRY_PATH, INativeManagedSettingsService, IFileManagedSettingsService, MANAGED_SETTINGS_FILE_NAME, MANAGED_SETTINGS_LINUX_FILE_PATH, MANAGED_SETTINGS_MACOS_FILE_PATH, MANAGED_SETTINGS_WINDOWS_DIR, NullNativeManagedSettingsService, NullFileManagedSettingsService } from '../../platform/policy/common/copilotManagedSettings.js'; +import { FileManagedSettingsService } from '../../platform/policy/common/fileManagedSettingsService.js'; +import { NativeManagedSettingsService } from '../../platform/policy/node/nativeManagedSettingsService.js'; +import { DisposableStore } from '../../base/common/lifecycle.js'; +import { IUriIdentityService } from '../../platform/uriIdentity/common/uriIdentity.js'; +import { UriIdentityService } from '../../platform/uriIdentity/common/uriIdentityService.js'; +import { ILoggerMainService, LoggerMainService } from '../../platform/log/electron-main/loggerService.js'; +import { LogService } from '../../platform/log/common/logService.js'; +import { massageMessageBoxOptions } from '../../platform/dialogs/common/dialogs.js'; +import { SaveStrategy, StateService } from '../../platform/state/node/stateService.js'; +import { FileUserDataProvider } from '../../platform/userData/common/fileUserDataProvider.js'; +import { addUNCHostToAllowlist, getUNCHost } from '../../base/node/unc.js'; +import { ThemeMainService } from '../../platform/theme/electron-main/themeMainServiceImpl.js'; +import { LINUX_SYSTEM_POLICY_FILE_PATH } from '../../base/common/policy.js'; + +/** + * The main VS Code entry point. + * + * Note: This class can exist more than once for example when VS Code is already + * running and a second instance is started from the command line. It will always + * try to communicate with an existing instance to prevent that 2 VS Code instances + * are running at the same time. + */ +class CodeMain { + + main(): void { + try { + this.startup(); + } catch (error) { + console.error(error.message); + app.exit(1); + } + } + + private async startup(): Promise { + + // Set the error handler early enough so that we are not getting the + // default electron error dialog popping up + setUnexpectedErrorHandler(err => console.error(err)); + + // Graphical DevBoxes run without a desktop screen-reader daemon. Keep + // the native Linux accessibility provider enabled when Review Desktop + // explicitly opts into the generic Computer Use backend. + if (process.env['DEV_FAST_REVIEW_FORCE_ACCESSIBILITY'] === '1') { + app.setAccessibilitySupportEnabled(true); + } + + // Create services + const [instantiationService, instanceEnvironment, environmentMainService, configurationService, stateMainService, bufferLogger, productService, userDataProfilesMainService] = this.createServices(); + + try { + + // Init services + try { + await this.initServices(environmentMainService, userDataProfilesMainService, configurationService, stateMainService, productService); + } catch (error) { + + // Show a dialog for errors that can be resolved by the user + this.handleStartupDataDirError(environmentMainService, productService, error); + + throw error; + } + + // Startup + await instantiationService.invokeFunction(async accessor => { + const logService = accessor.get(ILogService); + const lifecycleMainService = accessor.get(ILifecycleMainService); + const fileService = accessor.get(IFileService); + const loggerService = accessor.get(ILoggerService); + + // Create the main IPC server by trying to be the server + // If this throws an error it means we are not the first + // instance of VS Code running and so we would quit. + const mainProcessNodeIpcServer = await this.claimInstance(logService, environmentMainService, lifecycleMainService, instantiationService, productService, true); + + // Write a lockfile to indicate an instance is running + // (https://github.com/microsoft/vscode/issues/127861#issuecomment-877417451) + FSPromises.writeFile(environmentMainService.mainLockfile, String(process.pid)).catch(err => { + logService.warn(`app#startup(): Error writing main lockfile: ${err.stack}`); + }); + + // Delay creation of spdlog for perf reasons (https://github.com/microsoft/vscode/issues/72906) + bufferLogger.logger = loggerService.createLogger('main', { name: localize('mainLog', "Main") }); + + // Lifecycle + Event.once(lifecycleMainService.onWillShutdown)(evt => { + fileService.dispose(); + configurationService.dispose(); + evt.join('instanceLockfile', promises.unlink(environmentMainService.mainLockfile).catch(() => { /* ignored */ })); + }); + + // Check if Inno Setup is running. Briefly wait for the updating mutex to be released before refusing to launch. + const innoSetupActive = await this.checkInnoSetupMutex(productService, logService); + if (innoSetupActive) { + const message = `${productService.nameShort} is currently being updated. Please wait for the update to complete before launching.`; + instantiationService.invokeFunction(this.quit, new Error(message)); + return; + } + + return instantiationService.createInstance(CodeApplication, mainProcessNodeIpcServer, instanceEnvironment).startup(); + }); + } catch (error) { + instantiationService.invokeFunction(this.quit, error); + } + } + + private createServices(): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateService, BufferLogger, IProductService, UserDataProfilesMainService] { + const services = new ServiceCollection(); + const disposables = new DisposableStore(); + process.once('exit', () => disposables.dispose()); + + // Product + const productService = { _serviceBrand: undefined, ...product }; + services.set(IProductService, productService); + + // Environment + const environmentMainService = new EnvironmentMainService(this.resolveArgs(), productService); + const instanceEnvironment = this.patchEnvironment(environmentMainService); // Patch `process.env` with the instance's environment + services.set(IEnvironmentMainService, environmentMainService); + + // Logger + const loggerService = new LoggerMainService(getLogLevel(environmentMainService), environmentMainService.logsHome); + services.set(ILoggerMainService, loggerService); + + // Log: We need to buffer the spdlog logs until we are sure + // we are the only instance running, otherwise we'll have concurrent + // log file access on Windows (https://github.com/microsoft/vscode/issues/41218) + const bufferLogger = new BufferLogger(loggerService.getLogLevel()); + const logService = disposables.add(new LogService(bufferLogger, [new ConsoleMainLogger(loggerService.getLogLevel())])); + if (!environmentMainService.isBuilt && isDevConsoleLogForwardingEnabled) { + disposables.add(registerDevConsoleLogForwarder(logService)); + } + services.set(ILogService, logService); + + // Files + const fileService = new FileService(logService); + services.set(IFileService, fileService); + const diskFileSystemProvider = new DiskFileSystemProvider(logService); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + + // URI Identity + const uriIdentityService = new UriIdentityService(fileService); + services.set(IUriIdentityService, uriIdentityService); + + // State + const stateService = new StateService(SaveStrategy.DELAYED, environmentMainService, logService, fileService); + services.set(IStateReadService, stateService); + services.set(IStateService, stateService); + + // User Data Profiles + const userDataProfilesMainService = new UserDataProfilesMainService(stateService, uriIdentityService, environmentMainService, fileService, logService, productService); + services.set(IUserDataProfilesMainService, userDataProfilesMainService); + + // Use FileUserDataProvider for user data to + // enable atomic read / write operations. + fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesMainService, uriIdentityService, logService)); + + // Policy + let policyService: IPolicyService | undefined; + const policyProductName = isWindows + ? (productService.parentPolicyConfig?.win32RegValueName ?? productService.win32RegValueName) + : (productService.parentPolicyConfig?.darwinBundleIdentifier ?? productService.darwinBundleIdentifier); + const policyServices: IPolicyService[] = []; + if (isWindows && policyProductName) { + policyServices.push(disposables.add(new NativePolicyService(logService, policyProductName))); + } else if (isMacintosh && policyProductName) { + policyServices.push(disposables.add(new NativePolicyService(logService, policyProductName))); + } else if (isLinux) { + policyServices.push(disposables.add(new FilePolicyService(URI.file(LINUX_SYSTEM_POLICY_FILE_PATH), fileService, logService))); + } else if (environmentMainService.policyFile) { + policyServices.push(disposables.add(new FilePolicyService(environmentMainService.policyFile, fileService, logService))); + } + + let nativeManagedSettingsService: NativeManagedSettingsService | undefined; + if (isWindows) { + nativeManagedSettingsService = disposables.add(new NativeManagedSettingsService(logService, GITHUB_COPILOT_WIN32_POLICY_NAME, { registryPath: GITHUB_COPILOT_WIN32_REGISTRY_PATH })); + } else if (isMacintosh) { + nativeManagedSettingsService = disposables.add(new NativeManagedSettingsService(logService, GITHUB_COPILOT_MACOS_BUNDLE_ID)); + } + if (nativeManagedSettingsService) { + services.set(INativeManagedSettingsService, nativeManagedSettingsService); + } else { + services.set(INativeManagedSettingsService, new NullNativeManagedSettingsService()); + } + + // File-based managed settings + let fileManagedSettingsPath: string | undefined; + if (isWindows) { + const programFiles = process.env['ProgramFiles']; + if (programFiles) { + fileManagedSettingsPath = join(programFiles, MANAGED_SETTINGS_WINDOWS_DIR, MANAGED_SETTINGS_FILE_NAME); + } + } else if (isMacintosh) { + fileManagedSettingsPath = MANAGED_SETTINGS_MACOS_FILE_PATH; + } else if (isLinux) { + fileManagedSettingsPath = MANAGED_SETTINGS_LINUX_FILE_PATH; + } + if (fileManagedSettingsPath) { + const fileManagedSettingsService = disposables.add(new FileManagedSettingsService(URI.file(fileManagedSettingsPath), fileService, logService)); + services.set(IFileManagedSettingsService, fileManagedSettingsService); + } else { + services.set(IFileManagedSettingsService, new NullFileManagedSettingsService()); + } + + if (policyServices.length > 1) { + policyService = disposables.add(new MultiplexPolicyService(policyServices, logService)); + } else if (policyServices.length === 1) { + policyService = policyServices[0]; + } else { + policyService = new NullPolicyService(); + } + services.set(IPolicyService, policyService); + + // Configuration + const configurationService = new ConfigurationService(userDataProfilesMainService.defaultProfile.settingsResource, fileService, policyService, logService); + services.set(IConfigurationService, configurationService); + + // Lifecycle + services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService, undefined, false)); + + // Request + services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true)); + + // Themes + services.set(IThemeMainService, new SyncDescriptor(ThemeMainService)); + + // Signing + services.set(ISignService, new SyncDescriptor(SignService, undefined, false /* proxied to other processes */)); + + // Tunnel + services.set(ITunnelService, new SyncDescriptor(TunnelService)); + + // Protocol (instantiated early and not using sync descriptor for security reasons) + services.set(IProtocolMainService, new ProtocolMainService(environmentMainService, userDataProfilesMainService, logService)); + + return [new InstantiationService(services, true), instanceEnvironment, environmentMainService, configurationService, stateService, bufferLogger, productService, userDataProfilesMainService]; + } + + private patchEnvironment(environmentMainService: IEnvironmentMainService): IProcessEnvironment { + const instanceEnvironment: IProcessEnvironment = { + VSCODE_IPC_HOOK: environmentMainService.mainIPCHandle + }; + + ['VSCODE_NLS_CONFIG', 'VSCODE_PORTABLE'].forEach(key => { + const value = process.env[key]; + if (typeof value === 'string') { + instanceEnvironment[key] = value; + } + }); + + Object.assign(process.env, instanceEnvironment); + + return instanceEnvironment; + } + + private async initServices(environmentMainService: IEnvironmentMainService, userDataProfilesMainService: UserDataProfilesMainService, configurationService: ConfigurationService, stateService: StateService, productService: IProductService): Promise { + await Promises.settled([ + + // Environment service (paths) + Promise.all([ + this.allowWindowsUNCPath(environmentMainService.extensionsPath), // enable extension paths on UNC drives... + environmentMainService.codeCachePath, // ...other user-data-derived paths should already be enlisted from `main.js` + environmentMainService.logsHome.with({ scheme: Schemas.file }).fsPath, + userDataProfilesMainService.defaultProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath, + environmentMainService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath, + environmentMainService.localHistoryHome.with({ scheme: Schemas.file }).fsPath, + environmentMainService.backupHome + ].map(path => path ? promises.mkdir(path, { recursive: true }) : undefined)), + + // State service + stateService.init(), + + // Configuration service + configurationService.initialize() + ]); + + // Initialize user data profiles after initializing the state + userDataProfilesMainService.init(); + } + + private allowWindowsUNCPath(path: string): string { + if (isWindows) { + const host = getUNCHost(path); + if (host) { + addUNCHostToAllowlist(host); + } + } + + return path; + } + + private async claimInstance(logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, productService: IProductService, retry: boolean): Promise { + + // Try to setup a server for running. If that succeeds it means + // we are the first instance to startup. Otherwise it is likely + // that another instance is already running. + let mainProcessNodeIpcServer: NodeIPCServer; + try { + mark('code/willStartMainServer'); + mainProcessNodeIpcServer = await nodeIPCServe(environmentMainService.mainIPCHandle); + mark('code/didStartMainServer'); + Event.once(lifecycleMainService.onWillShutdown)(() => mainProcessNodeIpcServer.dispose()); + } catch (error) { + + // Handle unexpected errors (the only expected error is EADDRINUSE that + // indicates another instance of VS Code is running) + if (error.code !== 'EADDRINUSE') { + + // Show a dialog for errors that can be resolved by the user + this.handleStartupDataDirError(environmentMainService, productService, error); + + // Any other runtime error is just printed to the console + throw error; + } + + // there's a running instance, let's connect to it + let client: NodeIPCClient; + try { + client = await nodeIPCConnect(environmentMainService.mainIPCHandle, 'main'); + } catch (error) { + + // Handle unexpected connection errors by showing a dialog to the user + if (!retry || isWindows || error.code !== 'ECONNREFUSED') { + if (error.code === 'EPERM') { + this.showStartupWarningDialog( + localize('secondInstanceAdmin', "Another instance of {0} is already running as administrator.", productService.nameShort), + localize('secondInstanceAdminDetail', "Please close the other instance and try again."), + productService + ); + } + + throw error; + } + + // it happens on Linux and OS X that the pipe is left behind + // let's delete it, since we can't connect to it and then + // retry the whole thing + try { + unlinkSync(environmentMainService.mainIPCHandle); + } catch (error) { + logService.warn('Could not delete obsolete instance handle', error); + + throw error; + } + + return this.claimInstance(logService, environmentMainService, lifecycleMainService, instantiationService, productService, false); + } + + // Tests from CLI require to be the only instance currently + if (environmentMainService.extensionTestsLocationURI && !environmentMainService.debugExtensionHost.break) { + const msg = `Running extension tests from the command line is currently only supported if no other instance of ${productService.nameShort} is running.`; + logService.error(msg); + client.dispose(); + + throw new Error(msg); + } + + // Show a warning dialog after some timeout if it takes long to talk to the other instance + // Skip this if we are running with --wait where it is expected that we wait for a while. + // Also skip when gathering diagnostics (--status) which can take a longer time. + let startupWarningDialogHandle: Timeout | undefined = undefined; + if (!environmentMainService.args.wait && !environmentMainService.args.status) { + startupWarningDialogHandle = setTimeout(() => { + this.showStartupWarningDialog( + localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", productService.nameShort), + localize('secondInstanceNoResponseDetail', "Please close all other instances and try again."), + productService + ); + }, 10000); + } + + const otherInstanceLaunchMainService = ProxyChannel.toService(client.getChannel('launch'), { disableMarshalling: true }); + const otherInstanceDiagnosticsMainService = ProxyChannel.toService(client.getChannel('diagnostics'), { disableMarshalling: true }); + + // Process Info + if (environmentMainService.args.status) { + return instantiationService.invokeFunction(async () => { + const diagnosticsService = new DiagnosticsService(NullTelemetryService, productService); + const mainDiagnostics = await otherInstanceDiagnosticsMainService.getMainDiagnostics(); + const remoteDiagnostics = await otherInstanceDiagnosticsMainService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true }); + const diagnostics = await diagnosticsService.getDiagnostics(mainDiagnostics, remoteDiagnostics); + console.log(diagnostics); + + throw new ExpectedError(); + }); + } + + // Windows: allow to set foreground + if (isWindows) { + await this.windowsAllowSetForegroundWindow(otherInstanceLaunchMainService, logService); + } + + // Send environment over... + logService.trace('Sending env to running instance...'); + await otherInstanceLaunchMainService.start(environmentMainService.args, process.env as IProcessEnvironment); + + // Cleanup + client.dispose(); + + // Now that we started, make sure the warning dialog is prevented + if (startupWarningDialogHandle) { + clearTimeout(startupWarningDialogHandle); + } + + throw new ExpectedError('Sent env to running instance. Terminating...'); + } + + // Print --status usage info + if (environmentMainService.args.status) { + console.log(localize('statusWarning', "Warning: The --status argument can only be used if {0} is already running. Please run it again after {0} has started.", productService.nameShort)); + + throw new ExpectedError('Terminating...'); + } + + // Set the VSCODE_PID variable here when we are sure we are the first + // instance to startup. Otherwise we would wrongly overwrite the PID + process.env['VSCODE_PID'] = String(process.pid); + + return mainProcessNodeIpcServer; + } + + private handleStartupDataDirError(environmentMainService: IEnvironmentMainService, productService: IProductService, error: NodeJS.ErrnoException): void { + if (error.code === 'EACCES' || error.code === 'EPERM') { + const directories = coalesce([environmentMainService.userDataPath, environmentMainService.extensionsPath, XDG_RUNTIME_DIR]).map(folder => getPathLabel(URI.file(folder), { os: OS, tildify: environmentMainService })); + + this.showStartupWarningDialog( + localize('startupDataDirError', "Unable to write program user data."), + localize('startupUserDataAndExtensionsDirErrorDetail', "{0}\n\nPlease make sure the following directories are writeable:\n\n{1}", toErrorMessage(error), directories.join('\n')), + productService + ); + } + } + + private showStartupWarningDialog(message: string, detail: string, productService: IProductService): void { + + // use sync variant here because we likely exit after this method + // due to startup issues and otherwise the dialog seems to disappear + // https://github.com/microsoft/vscode/issues/104493 + + dialog.showMessageBoxSync(massageMessageBoxOptions({ + type: 'warning', + buttons: [localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close")], + message, + detail + }, productService).options); + } + + private async windowsAllowSetForegroundWindow(launchMainService: ILaunchMainService, logService: ILogService): Promise { + if (isWindows) { + const processId = await launchMainService.getMainProcessId(); + + logService.trace('Sending some foreground love to the running instance:', processId); + + try { + (await import('windows-foreground-love')).allowSetForegroundWindow(processId); + } catch (error) { + logService.error(error); + } + } + } + + private quit(accessor: ServicesAccessor, reason?: ExpectedError | Error): void { + const logService = accessor.get(ILogService); + const lifecycleMainService = accessor.get(ILifecycleMainService); + + let exitCode = 0; + + if (reason) { + if ((reason as ExpectedError).isExpected) { + if (reason.message) { + logService.trace(reason.message); + } + } else { + exitCode = 1; // signal error to the outside + + if (reason.stack) { + logService.error(reason.stack); + } else { + logService.error(`Startup error: ${reason.toString()}`); + } + } + } + + lifecycleMainService.kill(exitCode); + } + + private async checkInnoSetupMutex(productService: IProductService, logService: ILogService): Promise { + if (!(isWindows && productService.win32MutexName && productService.win32VersionedUpdate)) { + return false; + } + + try { + const updatingMutexName = `${productService.win32MutexName}-updating`; + const mutex = await import('@vscode/windows-mutex'); + + if (!mutex.isActive(updatingMutexName)) { + return false; + } + + // Wait briefly for setup teardown to release the mutex; Inno's `nowait postinstall` runcode can race the setup process exit. + const pollIntervalMs = 250, retries = 120; // 30s total + logService.info(`checkInnoSetupMutex: ${updatingMutexName} is held, waiting up to ${(pollIntervalMs * retries) / 1000}s for setup to finish...`); + const start = Date.now(); + try { + await retry(async () => { + if (mutex.isActive(updatingMutexName)) { + throw new Error('mutex still held'); + } + }, pollIntervalMs, retries); + logService.info(`checkInnoSetupMutex: ${updatingMutexName} released after ${Date.now() - start}ms`); + return false; + } catch { + logService.warn(`checkInnoSetupMutex: ${updatingMutexName} still held after ${Date.now() - start}ms, giving up`); + return true; + } + } catch (error) { + logService.error('Failed to check Inno Setup mutex:', error); + return false; + } + } + + //#region Command line arguments utilities + + private resolveArgs(): NativeParsedArgs { + + // Parse arguments + const args = this.validatePaths(parseMainProcessArgv(process.argv)); + + if (args.wait && !args.waitMarkerFilePath) { + // If we are started with --wait create a random temporary file + // and pass it over to the starting instance. We can use this file + // to wait for it to be deleted to monitor that the edited file + // is closed and then exit the waiting process. + // + // Note: we are not doing this if the wait marker has been already + // added as argument. This can happen if VS Code was started from CLI. + const waitMarkerFilePath = createWaitMarkerFileSync(args.verbose); + if (waitMarkerFilePath) { + addArg(process.argv, '--waitMarkerFilePath', waitMarkerFilePath); + args.waitMarkerFilePath = waitMarkerFilePath; + } + } + + if (args.chat) { + if (args.chat['new-window']) { + // Apply `--new-window` flag to the main arguments + args['new-window'] = true; + } else if (args.chat['reuse-window']) { + // Apply `--reuse-window` flag to the main arguments + args['reuse-window'] = true; + } else if (args.chat['profile']) { + // Apply `--profile` flag to the main arguments + args['profile'] = args.chat['profile']; + } else { + // Unless we are started with specific instructions about + // new windows or reusing existing ones, always take the + // current working directory as workspace to open. + args._ = [cwd()]; + } + } + + return args; + } + + private validatePaths(args: NativeParsedArgs): NativeParsedArgs { + + // Track URLs if they're going to be used + if (args['open-url']) { + args._urls = args._; + args._ = []; + } + + // Normalize paths and watch out for goto line mode + if (!args['remote']) { + const paths = this.doValidatePaths(args._, args.goto); + args._ = paths; + } + + return args; + } + + private doValidatePaths(args: string[], gotoLineMode?: boolean): string[] { + const currentWorkingDir = cwd(); + const result = args.map(arg => { + let pathCandidate = String(arg); + + let parsedPath: IPathWithLineAndColumn | undefined = undefined; + if (gotoLineMode) { + parsedPath = parseLineAndColumnAware(pathCandidate); + pathCandidate = parsedPath.path; + } + + if (pathCandidate) { + pathCandidate = this.preparePath(currentWorkingDir, pathCandidate); + } + + const sanitizedFilePath = sanitizeFilePath(pathCandidate, currentWorkingDir); + + const filePathBasename = basename(sanitizedFilePath); + if (filePathBasename /* can be empty if code is opened on root */ && !isValidBasename(filePathBasename)) { + return null; // do not allow invalid file names + } + + if (gotoLineMode && parsedPath) { + parsedPath.path = sanitizedFilePath; + + return this.toPath(parsedPath); + } + + return sanitizedFilePath; + }); + + const caseInsensitive = isWindows || isMacintosh; + const distinctPaths = distinct(result, path => path && caseInsensitive ? path.toLowerCase() : (path || '')); + + return coalesce(distinctPaths); + } + + private preparePath(cwd: string, path: string): string { + + // Trim trailing quotes + if (isWindows) { + path = rtrim(path, '"'); // https://github.com/microsoft/vscode/issues/1498 + } + + // Trim whitespaces + path = trim(trim(path, ' '), '\t'); + + if (isWindows) { + + // Resolve the path against cwd if it is relative + path = resolve(cwd, path); + + // Trim trailing '.' chars on Windows to prevent invalid file names + path = rtrim(path, '.'); + } + + return path; + } + + private toPath(pathWithLineAndCol: IPathWithLineAndColumn): string { + const segments = [pathWithLineAndCol.path]; + + if (typeof pathWithLineAndCol.line === 'number') { + segments.push(String(pathWithLineAndCol.line)); + } + + if (typeof pathWithLineAndCol.column === 'number') { + segments.push(String(pathWithLineAndCol.column)); + } + + return segments.join(':'); + } + + //#endregion +} + +// Main Startup +const code = new CodeMain(); +code.main(); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/defaultExtensionsInitializer.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/defaultExtensionsInitializer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/defaultExtensionsInitializer.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/defaultExtensionsInitializer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/extensions.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/extensions.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/languagePackCachedDataCleaner.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/languagePackCachedDataCleaner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/languagePackCachedDataCleaner.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/languagePackCachedDataCleaner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/localizationsUpdater.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/localizationsUpdater.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/localizationsUpdater.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/localizationsUpdater.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/logsDataCleaner.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/logsDataCleaner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/logsDataCleaner.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/logsDataCleaner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/storageDataCleaner.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/storageDataCleaner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/storageDataCleaner.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/storageDataCleaner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/userDataProfilesCleaner.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/userDataProfilesCleaner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/userDataProfilesCleaner.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/contrib/userDataProfilesCleaner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts b/apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts rename to apps/review-desktop/code-oss/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/node/cli.ts b/apps/review-desktop/code-oss/src/vs/code/node/cli.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/node/cli.ts rename to apps/review-desktop/code-oss/src/vs/code/node/cli.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/node/cliArgs.ts b/apps/review-desktop/code-oss/src/vs/code/node/cliArgs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/node/cliArgs.ts rename to apps/review-desktop/code-oss/src/vs/code/node/cliArgs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/node/cliProcessMain.ts b/apps/review-desktop/code-oss/src/vs/code/node/cliProcessMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/code/node/cliProcessMain.ts rename to apps/review-desktop/code-oss/src/vs/code/node/cliProcessMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/charWidthReader.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/charWidthReader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/charWidthReader.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/charWidthReader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/domFontInfo.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/domFontInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/domFontInfo.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/domFontInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/editorConfiguration.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/editorConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/editorConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/editorConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/elementSizeObserver.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/elementSizeObserver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/elementSizeObserver.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/elementSizeObserver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/fontMeasurements.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/fontMeasurements.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/fontMeasurements.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/fontMeasurements.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/migrateOptions.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/migrateOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/migrateOptions.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/migrateOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/tabFocus.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/config/tabFocus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/config/tabFocus.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/config/tabFocus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/dragScrolling.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/dragScrolling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/dragScrolling.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/dragScrolling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/clipboardUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/clipboardUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/clipboardUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/clipboardUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/editContext.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/editContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/editContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/editContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/editContextFactory.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/editContextFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/editContextFactory.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/editContextFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.css b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/nativeEditContextUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentRich.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentRich.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentRich.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentRich.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentSimple.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentSimple.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentSimple.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderContentSimple.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/native/screenReaderUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/screenReaderUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/screenReaderUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/screenReaderUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/screenReaderUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.css b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextState.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextState.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContextState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/mouseHandler.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/mouseHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/mouseHandler.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/mouseHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/mouseTarget.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/mouseTarget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/mouseTarget.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/mouseTarget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/pointerHandler.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/controller/pointerHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/controller/pointerHandler.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/controller/pointerHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/coreCommands.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/coreCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/coreCommands.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/coreCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/dataTransfer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/dataTransfer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/dataTransfer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/dataTransfer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/editorBrowser.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/editorBrowser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/editorBrowser.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/editorBrowser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/editorDom.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/editorDom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/editorDom.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/editorDom.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/editorExtensions.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/editorExtensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/editorExtensions.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/editorExtensions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/atlas.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/atlas.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/atlas.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/atlas.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlas.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlas.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlas.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlas.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasShelfAllocator.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasShelfAllocator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasShelfAllocator.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasShelfAllocator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasSlabAllocator.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasSlabAllocator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasSlabAllocator.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/atlas/textureAtlasSlabAllocator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/bufferDirtyTracker.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/bufferDirtyTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/bufferDirtyTracker.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/bufferDirtyTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/contentSegmenter.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/contentSegmenter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/contentSegmenter.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/contentSegmenter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationCssRuleExtractor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationStyleCache.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationStyleCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationStyleCache.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/css/decorationStyleCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/css/media/decorationCssRuleExtractor.css b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/css/media/decorationCssRuleExtractor.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/css/media/decorationCssRuleExtractor.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/css/media/decorationCssRuleExtractor.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/gpu.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/gpu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/gpu.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/gpu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/gpuDisposable.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/gpuDisposable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/gpuDisposable.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/gpuDisposable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/gpuUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/gpuUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/gpuUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/gpuUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/objectCollectionBuffer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/objectCollectionBuffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/objectCollectionBuffer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/objectCollectionBuffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/raster/glyphRasterizer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/raster/glyphRasterizer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/raster/glyphRasterizer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/raster/glyphRasterizer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/raster/raster.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/raster/raster.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/raster/raster.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/raster/raster.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.wgsl.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.wgsl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.wgsl.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/rectangleRenderer.wgsl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/baseRenderStrategy.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/baseRenderStrategy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/baseRenderStrategy.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/baseRenderStrategy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.wgsl.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.wgsl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.wgsl.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/fullFileRenderStrategy.wgsl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/viewportRenderStrategy.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/viewportRenderStrategy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/viewportRenderStrategy.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/renderStrategy/viewportRenderStrategy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/taskQueue.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/taskQueue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/taskQueue.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/taskQueue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/viewGpuContext.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/gpu/viewGpuContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/gpu/viewGpuContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/gpu/viewGpuContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/observableCodeEditor.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/observableCodeEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/observableCodeEditor.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/observableCodeEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/abstractCodeEditorService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/abstractCodeEditorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/abstractCodeEditorService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/abstractCodeEditorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/bulkEditService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/bulkEditService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/bulkEditService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/bulkEditService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/codeEditorService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/codeEditorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/codeEditorService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/codeEditorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/editorWorkerService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/editorWorkerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/editorWorkerService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/editorWorkerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/inlineCompletionsService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/inlineCompletionsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/inlineCompletionsService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/inlineCompletionsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/markerDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/markerDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/markerDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/markerDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/openerService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/openerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/openerService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/openerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/renameSymbolTrackerService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/services/renameSymbolTrackerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/services/renameSymbolTrackerService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/services/renameSymbolTrackerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/stableEditorScroll.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/stableEditorScroll.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/stableEditorScroll.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/stableEditorScroll.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/triggerInlineEditCommandsRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/triggerInlineEditCommandsRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/triggerInlineEditCommandsRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/triggerInlineEditCommandsRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/domLineBreaksComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/domLineBreaksComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/domLineBreaksComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/domLineBreaksComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/dynamicViewOverlay.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/dynamicViewOverlay.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/dynamicViewOverlay.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/dynamicViewOverlay.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/renderingContext.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/renderingContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/renderingContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/renderingContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewController.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/viewController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewController.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/viewController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewLayer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/viewLayer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewLayer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/viewLayer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewOverlays.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/viewOverlays.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewOverlays.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/viewOverlays.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewPart.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/viewPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewPart.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/viewPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewUserInputEvents.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/view/viewUserInputEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/view/viewUserInputEvents.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/view/viewUserInputEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/decorations/decorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/gpuMark/gpuMark.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/margin/margin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/marginDecorations/marginDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimap.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRenderer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRenderer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRendererFactory.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRendererFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRendererFactory.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharRendererFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharSheet.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharSheet.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharSheet.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapCharSheet.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapPreBaked.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapPreBaked.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapPreBaked.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/minimap/minimapPreBaked.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/rulers/rulers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/rulersGpu/rulersGpu.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/rulersGpu/rulersGpu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/rulersGpu/rulersGpu.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/rulersGpu/rulersGpu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/selections/selections.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/domReadingContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/rangeUtil.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/rangeUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/rangeUtil.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/rangeUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLine.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLine.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLine.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLineOptions.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLineOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLineOptions.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLineOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLines/viewLines.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewZones/viewZones.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/viewZones/viewZones.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/viewZones/viewZones.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.css b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/viewParts/whitespace/whitespace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorContributions.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorContributions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorContributions.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorContributions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/editor.css b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/editor.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/editor.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/editor.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/embeddedCodeEditorWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/embeddedCodeEditorWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/embeddedCodeEditorWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/codeEditor/embeddedCodeEditorWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/commands.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/commands.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.css b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/accessibleDiffViewer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorSash.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/copySelection.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/copySelection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/copySelection.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/copySelection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/inlineDiffDeletedCodeMargin.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/inlineDiffDeletedCodeMargin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/inlineDiffDeletedCodeMargin.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/inlineDiffDeletedCodeMargin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/renderLines.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/renderLines.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/renderLines.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/components/diffEditorViewZones/renderLines.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/delegatingEditorImpl.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/delegatingEditorImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/delegatingEditorImpl.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/delegatingEditorImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorOptions.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorOptions.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorViewModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/diffProviderFactoryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/gutterFeature.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/gutterFeature.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/gutterFeature.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/gutterFeature.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/hideUnchangedRegionsFeature.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/hideUnchangedRegionsFeature.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/hideUnchangedRegionsFeature.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/hideUnchangedRegionsFeature.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/movedBlocksLinesFeature.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/overviewRulerFeature.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/overviewRulerFeature.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/overviewRulerFeature.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/overviewRulerFeature.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/registrations.contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/registrations.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/registrations.contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/registrations.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/style.css b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/style.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/style.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/style.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils/editorGutter.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils/editorGutter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils/editorGutter.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/diffEditor/utils/editorGutter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/editorMarkdownCodeBlockRenderer.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/editorMarkdownCodeBlockRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/editorMarkdownCodeBlockRenderer.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/editorMarkdownCodeBlockRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/renderedMarkdown.css b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/renderedMarkdown.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/renderedMarkdown.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/markdownRenderer/browser/renderedMarkdown.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/colors.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/colors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/colors.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/colors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/diffEditorItemTemplate.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/model.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/model.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/model.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorResourceHeader.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorResourceHeader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorResourceHeader.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorResourceHeader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/objectPool.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/objectPool.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/objectPool.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/objectPool.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/style.css b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/style.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/style.css rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/style.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/utils.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/utils.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/workbenchUIElementFactory.ts b/apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/workbenchUIElementFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/workbenchUIElementFactory.ts rename to apps/review-desktop/code-oss/src/vs/editor/browser/widget/multiDiffEditor/workbenchUIElementFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/replaceCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/common/commands/replaceCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/replaceCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/commands/replaceCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/shiftCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/common/commands/shiftCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/shiftCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/commands/shiftCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/surroundSelectionCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/common/commands/surroundSelectionCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/surroundSelectionCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/commands/surroundSelectionCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/diffEditor.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/diffEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/diffEditor.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/diffEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorConfiguration.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/editorConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/editorConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorConfigurationSchema.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/editorConfigurationSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorConfigurationSchema.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/editorConfigurationSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorOptions.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/editorOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorOptions.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/editorOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorZoom.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/editorZoom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/editorZoom.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/editorZoom.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/fontInfo.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/fontInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/fontInfo.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/fontInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/fontInfoFromSettings.ts b/apps/review-desktop/code-oss/src/vs/editor/common/config/fontInfoFromSettings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/config/fontInfoFromSettings.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/config/fontInfoFromSettings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/coordinatesConverter.ts b/apps/review-desktop/code-oss/src/vs/editor/common/coordinatesConverter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/coordinatesConverter.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/coordinatesConverter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/dimension.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/2d/dimension.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/dimension.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/2d/dimension.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/point.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/2d/point.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/point.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/2d/point.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/rect.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/2d/rect.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/rect.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/2d/rect.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/size.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/2d/size.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/2d/size.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/2d/size.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/characterClassifier.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/characterClassifier.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/characterClassifier.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/characterClassifier.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/cursorColumns.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/cursorColumns.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/cursorColumns.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/cursorColumns.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/editOperation.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/editOperation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/editOperation.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/editOperation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/editorColorRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/editorColorRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/editorColorRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/editorColorRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_compose.drawio.png b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_compose.drawio.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_compose.drawio.png rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_compose.drawio.png diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_normalize.drawio.png b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_normalize.drawio.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_normalize.drawio.png rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_normalize.drawio.png diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_rebase.drawio.png b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_rebase.drawio.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_rebase.drawio.png rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/docs/BaseEdit_rebase.drawio.png diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/edit.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/edit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/edit.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/edit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/lengthEdit.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/lengthEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/lengthEdit.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/lengthEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/lineEdit.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/lineEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/lineEdit.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/lineEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/stringEdit.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/stringEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/stringEdit.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/stringEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/textEdit.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/edits/textEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/edits/textEdit.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/edits/textEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/eolCounter.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/misc/eolCounter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/eolCounter.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/misc/eolCounter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/indentation.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/misc/indentation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/indentation.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/misc/indentation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/rgba.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/misc/rgba.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/rgba.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/misc/rgba.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/textModelDefaults.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/misc/textModelDefaults.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/misc/textModelDefaults.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/misc/textModelDefaults.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/position.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/position.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/position.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/position.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/range.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/range.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/range.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/range.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/columnRange.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/columnRange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/columnRange.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/columnRange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/lineRange.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/lineRange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/lineRange.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/lineRange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/offsetRange.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/offsetRange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/offsetRange.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/offsetRange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/rangeSingleLine.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/rangeSingleLine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/ranges/rangeSingleLine.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/ranges/rangeSingleLine.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/selection.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/selection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/selection.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/selection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/stringBuilder.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/stringBuilder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/stringBuilder.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/stringBuilder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/abstractText.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/text/abstractText.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/abstractText.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/text/abstractText.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/getPositionOffsetTransformerFromTextModel.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/text/getPositionOffsetTransformerFromTextModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/getPositionOffsetTransformerFromTextModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/text/getPositionOffsetTransformerFromTextModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/positionToOffset.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/text/positionToOffset.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/positionToOffset.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/text/positionToOffset.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/positionToOffsetImpl.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/text/positionToOffsetImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/positionToOffsetImpl.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/text/positionToOffsetImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/textLength.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/text/textLength.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/text/textLength.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/text/textLength.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/textChange.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/textChange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/textChange.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/textChange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/wordCharacterClassifier.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/wordCharacterClassifier.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/wordCharacterClassifier.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/wordCharacterClassifier.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/wordHelper.ts b/apps/review-desktop/code-oss/src/vs/editor/common/core/wordHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/core/wordHelper.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/core/wordHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursor.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursor.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorAtomicMoveOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorAtomicMoveOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorAtomicMoveOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorAtomicMoveOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorCollection.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorCollection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorCollection.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorCollection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorColumnSelection.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorColumnSelection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorColumnSelection.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorColumnSelection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorContext.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorDeleteOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorDeleteOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorDeleteOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorDeleteOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveCommands.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveCommands.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorMoveOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeEditOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeEditOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeEditOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorTypeOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorWordOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorWordOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/cursorWordOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/cursorWordOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/oneCursor.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursor/oneCursor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursor/oneCursor.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursor/oneCursor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursorCommon.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursorCommon.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursorCommon.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursorCommon.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursorEvents.ts b/apps/review-desktop/code-oss/src/vs/editor/common/cursorEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/cursorEvents.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/cursorEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/dynamicProgrammingDiffing.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/dynamicProgrammingDiffing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/dynamicProgrammingDiffing.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/dynamicProgrammingDiffing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/myersDiffAlgorithm.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/myersDiffAlgorithm.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/myersDiffAlgorithm.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/myersDiffAlgorithm.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/defaultLinesDiffComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/defaultLinesDiffComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/defaultLinesDiffComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/defaultLinesDiffComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/lineSequence.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/lineSequence.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/lineSequence.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/lineSequence.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/utils.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/utils.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/defaultLinesDiffComputer/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/documentDiffProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/documentDiffProvider.ts similarity index 95% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/documentDiffProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/documentDiffProvider.ts index 6bf2d744a..6f59444b6 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/documentDiffProvider.ts +++ b/apps/review-desktop/code-oss/src/vs/editor/common/diff/documentDiffProvider.ts @@ -99,11 +99,6 @@ export interface IDocumentDiff { }; /** Optional authoritative zero-based source row correspondence. Null denotes padding. */ readonly contextGaps?: readonly IDocumentContextGap[]; - /** Syntax scopes supplied by the context plugin, as zero-based half-open line ranges. */ - readonly contextScopes?: { - readonly original: readonly (readonly [number, number])[]; - readonly modified: readonly (readonly [number, number])[]; - }; readonly sourceLineAlignment?: readonly (readonly [number | null, number | null])[]; /** * If true, both text models are identical (byte-wise). diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/externalLinesDiffComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/externalLinesDiffComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/externalLinesDiffComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/externalLinesDiffComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/legacyLinesDiffComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/legacyLinesDiffComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/legacyLinesDiffComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/legacyLinesDiffComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputers.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputers.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/linesDiffComputers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/rangeMapping.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/rangeMapping.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/rangeMapping.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/rangeMapping.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/sourceLineAlignment.ts b/apps/review-desktop/code-oss/src/vs/editor/common/diff/sourceLineAlignment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/diff/sourceLineAlignment.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/diff/sourceLineAlignment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorAction.ts b/apps/review-desktop/code-oss/src/vs/editor/common/editorAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorAction.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/editorAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorCommon.ts b/apps/review-desktop/code-oss/src/vs/editor/common/editorCommon.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorCommon.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/editorCommon.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorContextKeys.ts b/apps/review-desktop/code-oss/src/vs/editor/common/editorContextKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorContextKeys.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/editorContextKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorFeatures.ts b/apps/review-desktop/code-oss/src/vs/editor/common/editorFeatures.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorFeatures.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/editorFeatures.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorTheme.ts b/apps/review-desktop/code-oss/src/vs/editor/common/editorTheme.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/editorTheme.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/editorTheme.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/encodedTokenAttributes.ts b/apps/review-desktop/code-oss/src/vs/editor/common/encodedTokenAttributes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/encodedTokenAttributes.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/encodedTokenAttributes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/inputMode.ts b/apps/review-desktop/code-oss/src/vs/editor/common/inputMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/inputMode.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/inputMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languageFeatureRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languageFeatureRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languageFeatureRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languageFeatureRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languageSelector.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languageSelector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languageSelector.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languageSelector.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/autoIndent.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/autoIndent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/autoIndent.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/autoIndent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/defaultDocumentColorsComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/defaultDocumentColorsComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/defaultDocumentColorsComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/defaultDocumentColorsComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/enterAction.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/enterAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/enterAction.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/enterAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/css.scm b/apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/css.scm similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/css.scm rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/css.scm diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/ini.scm b/apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/ini.scm similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/ini.scm rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/ini.scm diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/regex.scm b/apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/regex.scm similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/regex.scm rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/regex.scm diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/typescript.scm b/apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/typescript.scm similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/highlights/typescript.scm rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/highlights/typescript.scm diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/injections/typescript.scm b/apps/review-desktop/code-oss/src/vs/editor/common/languages/injections/typescript.scm similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/injections/typescript.scm rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/injections/typescript.scm diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/language.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/language.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/language.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/language.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/languageConfiguration.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/languageConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/languageConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/languageConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/languageConfigurationRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/languageConfigurationRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/languageConfigurationRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/languageConfigurationRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/linkComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/linkComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/linkComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/linkComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/modesRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/modesRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/modesRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/modesRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/nullTokenize.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/nullTokenize.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/nullTokenize.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/nullTokenize.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/characterPair.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/characterPair.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/characterPair.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/characterPair.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/electricCharacter.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/electricCharacter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/electricCharacter.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/electricCharacter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/indentRules.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/indentRules.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/indentRules.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/indentRules.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/indentationLineProcessor.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/indentationLineProcessor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/indentationLineProcessor.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/indentationLineProcessor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/languageBracketsConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/onEnter.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/onEnter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/onEnter.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/onEnter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/richEditBrackets.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/richEditBrackets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/richEditBrackets.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/richEditBrackets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/tokenization.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/tokenization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/supports/tokenization.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/supports/tokenization.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/textToHtmlTokenizer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/languages/textToHtmlTokenizer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/languages/textToHtmlTokenizer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/languages/textToHtmlTokenizer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/ast.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/brackets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/concat23Trees.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/nodeReader.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/nodeReader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/nodeReader.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/nodeReader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/parser.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/parser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/parser.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/parser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/smallImmutableSet.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/smallImmutableSet.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/smallImmutableSet.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/smallImmutableSet.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/colorizedBracketPairsDecorationProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/fixBrackets.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/fixBrackets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/fixBrackets.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/bracketPairsTextModelPart/fixBrackets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/decorationProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/decorationProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/decorationProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/decorationProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/editStack.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/editStack.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/editStack.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/editStack.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/fixedArray.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/fixedArray.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/fixedArray.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/fixedArray.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/guidesTextModelPart.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/guidesTextModelPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/guidesTextModelPart.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/guidesTextModelPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/indentationGuesser.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/indentationGuesser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/indentationGuesser.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/indentationGuesser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/intervalTree.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/intervalTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/intervalTree.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/intervalTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/mirrorTextModel.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/mirrorTextModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/mirrorTextModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/mirrorTextModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/prefixSumComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/prefixSumComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/prefixSumComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/prefixSumComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModel.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/textModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/textModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelPart.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/textModelPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelPart.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/textModelPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelSearch.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/textModelSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelSearch.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/textModelSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelStringEdit.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/textModelStringEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelStringEdit.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/textModelStringEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelText.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/textModelText.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelText.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/textModelText.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/textModelTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/textModelTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/textModelTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/abstractSyntaxTokenBackend.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/abstractSyntaxTokenBackend.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/abstractSyntaxTokenBackend.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/abstractSyntaxTokenBackend.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/annotations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/annotations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/annotations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/annotations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationFontDecorationsProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationFontDecorationsProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationFontDecorationsProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationFontDecorationsProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationTextModelPart.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationTextModelPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationTextModelPart.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizationTextModelPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizerSyntaxTokenBackend.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizerSyntaxTokenBackend.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizerSyntaxTokenBackend.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/tokenizerSyntaxTokenBackend.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/cursorUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/cursorUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/cursorUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/cursorUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/tokenStore.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/tokenStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/tokenStore.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/tokenStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterSyntaxTokenBackend.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterSyntaxTokenBackend.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterSyntaxTokenBackend.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterSyntaxTokenBackend.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTokenizationImpl.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTokenizationImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTokenizationImpl.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTokenizationImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/tokens/treeSitter/treeSitterTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/utils.ts b/apps/review-desktop/code-oss/src/vs/editor/common/model/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/model/utils.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/model/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/modelLineProjectionData.ts b/apps/review-desktop/code-oss/src/vs/editor/common/modelLineProjectionData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/modelLineProjectionData.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/modelLineProjectionData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/completionsEnablement.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/completionsEnablement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/completionsEnablement.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/completionsEnablement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorBaseApi.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/editorBaseApi.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorBaseApi.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/editorBaseApi.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWebWorker.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/editorWebWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWebWorker.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/editorWebWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWebWorkerMain.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/editorWebWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWebWorkerMain.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/editorWebWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWorker.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/editorWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWorker.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/editorWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWorkerHost.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/editorWorkerHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/editorWorkerHost.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/editorWorkerHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/findSectionHeaders.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/findSectionHeaders.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/findSectionHeaders.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/findSectionHeaders.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/getIconClasses.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/getIconClasses.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/getIconClasses.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/getIconClasses.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageFeatureDebounce.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/languageFeatureDebounce.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageFeatureDebounce.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/languageFeatureDebounce.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageFeatures.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/languageFeatures.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageFeatures.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/languageFeatures.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageFeaturesService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/languageFeaturesService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageFeaturesService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/languageFeaturesService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/languageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languageService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/languageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languagesAssociations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/languagesAssociations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languagesAssociations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/languagesAssociations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languagesRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/languagesRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/languagesRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/languagesRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/markerDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/markerDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/markerDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/markerDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/markerDecorationsService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/markerDecorationsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/markerDecorationsService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/markerDecorationsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/model.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/model.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/model.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/model.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/modelService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/modelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/modelService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/modelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/modelUndoRedoParticipant.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/modelUndoRedoParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/modelUndoRedoParticipant.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/modelUndoRedoParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/resolverService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/resolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/resolverService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/resolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensDto.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensDto.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensDto.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensDto.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensProviderStyling.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensProviderStyling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensProviderStyling.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensProviderStyling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensStyling.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensStyling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensStyling.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensStyling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensStylingService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensStylingService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/semanticTokensStylingService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/semanticTokensStylingService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.impl.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.impl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.impl.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.impl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.protocol.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.protocol.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/textModelSync/textModelSync.protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textResourceConfiguration.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/textResourceConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textResourceConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/textResourceConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textResourceConfigurationService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/textResourceConfigurationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/textResourceConfigurationService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/textResourceConfigurationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterLibraryService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterLibraryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterLibraryService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterLibraryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterThemeService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterThemeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterThemeService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/treeSitter/treeSitterThemeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeViewsDnd.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/treeViewsDnd.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeViewsDnd.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/treeViewsDnd.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeViewsDndService.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/treeViewsDndService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/treeViewsDndService.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/treeViewsDndService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/unicodeTextModelHighlighter.ts b/apps/review-desktop/code-oss/src/vs/editor/common/services/unicodeTextModelHighlighter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/services/unicodeTextModelHighlighter.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/services/unicodeTextModelHighlighter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/standalone/standaloneEnums.ts b/apps/review-desktop/code-oss/src/vs/editor/common/standalone/standaloneEnums.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/standalone/standaloneEnums.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/standalone/standaloneEnums.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/standaloneStrings.ts b/apps/review-desktop/code-oss/src/vs/editor/common/standaloneStrings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/standaloneStrings.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/standaloneStrings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelBracketPairs.ts b/apps/review-desktop/code-oss/src/vs/editor/common/textModelBracketPairs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelBracketPairs.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/textModelBracketPairs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelEditSource.ts b/apps/review-desktop/code-oss/src/vs/editor/common/textModelEditSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelEditSource.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/textModelEditSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelEvents.ts b/apps/review-desktop/code-oss/src/vs/editor/common/textModelEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelEvents.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/textModelEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelGuides.ts b/apps/review-desktop/code-oss/src/vs/editor/common/textModelGuides.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/textModelGuides.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/textModelGuides.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokenizationRegistry.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokenizationRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokenizationRegistry.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokenizationRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokenizationTextModelPart.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokenizationTextModelPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokenizationTextModelPart.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokenizationTextModelPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/common.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/common.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/common.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/common.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokensBuilder.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokensBuilder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokensBuilder.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousMultilineTokensBuilder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensEditing.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensEditing.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensStore.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensStore.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/contiguousTokensStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/lineTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/lineTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/lineTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/lineTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/sparseMultilineTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/sparseMultilineTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/sparseMultilineTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/sparseMultilineTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/sparseTokensStore.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/sparseTokensStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/sparseTokensStore.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/sparseTokensStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/tokenWithTextArray.ts b/apps/review-desktop/code-oss/src/vs/editor/common/tokens/tokenWithTextArray.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/tokens/tokenWithTextArray.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/tokens/tokenWithTextArray.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewEventHandler.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewEventHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewEventHandler.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewEventHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewEvents.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewEvents.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/lineDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/lineDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/lineDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/lineDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/lineHeights.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/lineHeights.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/lineHeights.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/lineHeights.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/linePart.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/linePart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/linePart.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/linePart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/linesLayout.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/linesLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/linesLayout.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/linesLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/viewLayout.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/viewLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/viewLayout.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/viewLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/viewLineRenderer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/viewLineRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/viewLineRenderer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/viewLineRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/viewLinesViewportData.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/viewLinesViewportData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewLayout/viewLinesViewportData.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewLayout/viewLinesViewportData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/glyphLanesModel.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/glyphLanesModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/glyphLanesModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/glyphLanesModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/inlineDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/inlineDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/inlineDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/inlineDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/minimapTokensColorTracker.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/minimapTokensColorTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/minimapTokensColorTracker.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/minimapTokensColorTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/modelLineProjection.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/modelLineProjection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/modelLineProjection.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/modelLineProjection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/monospaceLineBreaksComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/monospaceLineBreaksComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/monospaceLineBreaksComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/monospaceLineBreaksComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/overviewZoneManager.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/overviewZoneManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/overviewZoneManager.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/overviewZoneManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/screenReaderSimpleModel.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/screenReaderSimpleModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/screenReaderSimpleModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/screenReaderSimpleModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewContext.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewContext.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecoration.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecoration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecoration.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecoration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelImpl.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelImpl.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelLines.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelLines.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModel/viewModelLines.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModel/viewModelLines.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModelEventDispatcher.ts b/apps/review-desktop/code-oss/src/vs/editor/common/viewModelEventDispatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/common/viewModelEventDispatcher.ts rename to apps/review-desktop/code-oss/src/vs/editor/common/viewModelEventDispatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/anchorSelect/browser/anchorSelect.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/caretOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/caretOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/caretOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/caretOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/moveCaretCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/moveCaretCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/moveCaretCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/moveCaretCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/transpose.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/transpose.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/transpose.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/caretOperations/browser/transpose.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/clipboard/browser/clipboard.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/clipboard/browser/clipboard.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/clipboard/browser/clipboard.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/clipboard/browser/clipboard.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeAction.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeAction.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionContributions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionKeybindingResolver.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionKeybindingResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionKeybindingResolver.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionKeybindingResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionMenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/common/types.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/common/types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codeAction/common/types.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codeAction/common/types.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codeLensCache.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codeLensCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codeLensCache.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codeLensCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelens.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelens.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/codelens/browser/codelensWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/color.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/color.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/color.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/color.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorDetector.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPicker.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPicker.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPicker.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPicker.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParticipantUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParticipantUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParticipantUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParticipantUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerBody.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerBody.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerBody.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerBody.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerCloseButton.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerCloseButton.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerCloseButton.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerCloseButton.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerHeader.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerHeader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerHeader.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerHeader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerInsertButton.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerInsertButton.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerInsertButton.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerInsertButton.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerSaturationBox.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerSaturationBox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerSaturationBox.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerSaturationBox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerStrip.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerStrip.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerStrip.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerParts/colorPickerStrip.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/colorPickerWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/defaultDocumentColorProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/defaultDocumentColorProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/defaultDocumentColorProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/defaultDocumentColorProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPicker.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPicker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPicker.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPicker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerParticipant.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerParticipant.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/hoverColorPicker/hoverColorPickerParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/images/opacity-background.png b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/images/opacity-background.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/images/opacity-background.png rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/images/opacity-background.png diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerActions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerActions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerParticipant.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerParticipant.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/colorPicker/browser/standaloneColorPicker/standaloneColorPickerWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/comment/browser/blockCommentCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/comment/browser/blockCommentCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/comment/browser/blockCommentCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/comment/browser/blockCommentCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/comment/browser/comment.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/comment/browser/comment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/comment/browser/comment.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/comment/browser/comment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/comment/browser/lineCommentCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/comment/browser/lineCommentCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/comment/browser/lineCommentCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/comment/browser/lineCommentCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/cursorUndo/browser/cursorUndo.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/cursorUndo/browser/cursorUndo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/cursorUndo/browser/cursorUndo.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/cursorUndo/browser/cursorUndo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dnd.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dragAndDropCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dragAndDropCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dragAndDropCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dnd/browser/dragAndDropCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/documentSymbols.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/documentSymbols.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/documentSymbols.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/documentSymbols.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/outlineModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/outlineModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/outlineModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/documentSymbols/browser/outlineModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/defaultProviders.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/dropOrPasteInto/browser/postEditWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/editorState/browser/editorState.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/editorState/browser/editorState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/editorState/browser/editorState.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/editorState/browser/editorState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/editorState/browser/keybindingCancellation.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/editorState/browser/keybindingCancellation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/editorState/browser/keybindingCancellation.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/editorState/browser/keybindingCancellation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findOptionsWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findState.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findState.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidgetSearchHistory.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidgetSearchHistory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidgetSearchHistory.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/findWidgetSearchHistory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceAllCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceAllCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceAllCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceAllCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/replacePattern.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/replacePattern.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/replacePattern.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/replacePattern.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceWidgetHistory.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceWidgetHistory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceWidgetHistory.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/find/browser/replaceWidgetHistory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/floatingMenu/browser/floatingMenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/folding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingRanges.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingRanges.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingRanges.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/foldingRanges.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/hiddenRangeModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/indentRangeProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/syntaxRangeProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/syntaxRangeProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/folding/browser/syntaxRangeProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/folding/browser/syntaxRangeProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/fontZoom/browser/fontZoom.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/fontZoom/browser/fontZoom.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/fontZoom/browser/fontZoom.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/fontZoom/browser/fontZoom.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/format/browser/format.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/format/browser/format.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/format/browser/format.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/format/browser/format.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/format/browser/formatActions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/format/browser/formatActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/format/browser/formatActions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/format/browser/formatActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/format/browser/formattingEdit.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/format/browser/formattingEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/format/browser/formattingEdit.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/format/browser/formattingEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoError.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoError.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoError.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoError.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoErrorWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoErrorWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoErrorWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/gotoErrorWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerNavigationService.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerNavigationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerNavigationService.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerNavigationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerSelectionStatus.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerSelectionStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerSelectionStatus.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/markerSelectionStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/media/gotoErrorWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/media/gotoErrorWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/media/gotoErrorWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoError/browser/media/gotoErrorWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/goToSymbol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/clickLinkGesture.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesTree.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesTree.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/peek/referencesWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/referencesModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/referencesModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/referencesModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/referencesModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/symbolNavigation.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/symbolNavigation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/symbolNavigation.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gotoSymbol/browser/symbolNavigation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gpu/browser/gpuActions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/gpu/browser/gpuActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/gpu/browser/gpuActions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/gpu/browser/gpuActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverRendered.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverRendered.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverRendered.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverRendered.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverStatusBar.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverStatusBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverStatusBar.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverStatusBar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverTypes.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverTypes.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidgetWrapper.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidgetWrapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidgetWrapper.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/contentHoverWidgetWrapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/getHover.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/getHover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/getHover.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/getHover.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverComputer.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverComputer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverComputer.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverComputer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/glyphHoverWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hover.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hover.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hover.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hover.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActionIds.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActionIds.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActionIds.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActionIds.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverCopyButton.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverCopyButton.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverCopyButton.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverCopyButton.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverOperation.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverOperation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverOperation.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverOperation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverTypes.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverTypes.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/hoverUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/markerHoverParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplaceCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplaceCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplaceCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inPlaceReplace/browser/inPlaceReplaceCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/indentation/browser/indentation.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/indentation/browser/indentation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/indentation/browser/indentation.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/indentation/browser/indentation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentUtils.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentUtils.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentation.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentation.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/indentation/common/indentation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHints.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHints.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHints.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsHover.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsHover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsHover.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsHover.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commandIds.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commandIds.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commandIds.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commandIds.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commands.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commands.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/common.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/common.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/common.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/common.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionContextKeys.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionContextKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionContextKeys.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionContextKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/hoverParticipant.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/hoverParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/hoverParticipant.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/hoverParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/hintsWidget/inlineCompletionsHintsWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/InlineSuggestAlternativeAction.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/InlineSuggestAlternativeAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/InlineSuggestAlternativeAction.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/InlineSuggestAlternativeAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/changeRecorder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/computeGhostText.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/computeGhostText.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/computeGhostText.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/computeGhostText.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/editKind.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/editKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/editKind.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/editKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/ghostText.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/ghostText.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/ghostText.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/ghostText.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/graph.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/graph.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/graph.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/graph.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionIsVisible.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionIsVisible.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionIsVisible.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionIsVisible.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineSuggestionItem.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineSuggestionItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineSuggestionItem.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/inlineSuggestionItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/provideInlineCompletions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/provideInlineCompletions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/provideInlineCompletions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/provideInlineCompletions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/renameSymbolProcessor.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/renameSymbolProcessor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/renameSymbolProcessor.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/renameSymbolProcessor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/singleTextEditHelpers.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/singleTextEditHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/singleTextEditHelpers.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/singleTextEditHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/suggestWidgetAdapter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/textModelValueReference.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/textModelValueReference.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/textModelValueReference.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/textModelValueReference.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/typingSpeed.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/typingSpeed.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/typingSpeed.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/model/typingSpeed.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/structuredLogger.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/structuredLogger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/structuredLogger.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/structuredLogger.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/telemetry.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/telemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/telemetry.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/telemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/utils.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/utils.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/ghostText/ghostTextView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorMenu.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorMenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorMenu.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorMenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditWithChanges.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsNewUsers.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsNewUsers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsNewUsers.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsNewUsers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewInterface.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewInterface.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewInterface.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewInterface.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewProducer.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewProducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewProducer.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewProducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/debugVisualization.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/debugVisualization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/debugVisualization.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/debugVisualization.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCollapsedView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCollapsedView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCollapsedView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCollapsedView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCustomView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCustomView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCustomView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsCustomView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsDeletionView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsDeletionView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsDeletionView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsDeletionView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsInsertionView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsInsertionView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsInsertionView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsInsertionView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLineReplacementView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsSideBySideView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordReplacementView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/jumpToView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/jumpToView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/jumpToView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/jumpToView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/inlineEditsLongDistanceHint.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/inlineEditsLongDistanceHint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/inlineEditsLongDistanceHint.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/inlineEditsLongDistanceHint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistancePreviewEditor.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistancePreviewEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistancePreviewEditor.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistancePreviewEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistnaceWidgetPlacement.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistnaceWidgetPlacement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistnaceWidgetPlacement.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/longDistanceHint/longDistnaceWidgetPlacement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/originalEditorInlineDiffView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/theme.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/theme.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/theme.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/theme.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/flexBoxLayout.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/flexBoxLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/flexBoxLayout.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/flexBoxLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/towersLayout.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/towersLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/towersLayout.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/towersLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/utils.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/utils.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/utils/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/view.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/view.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/view.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/view.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineSuggestionsView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineSuggestionsView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineSuggestionsView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineCompletions/browser/view/inlineSuggestionsView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgress.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgress.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgress.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgress.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgressWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgressWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgressWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/inlineProgress/browser/inlineProgressWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLine.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLine.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLine.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLineCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLineCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLineCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLineCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/lineSelection/browser/lineSelection.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/lineSelection/browser/lineSelection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/lineSelection/browser/lineSelection.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/lineSelection/browser/lineSelection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/copyLinesCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/copyLinesCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/copyLinesCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/copyLinesCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/linesOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/moveLinesCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/sortLinesCommand.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/sortLinesCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/sortLinesCommand.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/linesOperations/browser/sortLinesCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/linkedEditing/browser/linkedEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/links/browser/getLinks.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/links/browser/getLinks.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/links/browser/getLinks.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/links/browser/getLinks.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/links/browser/links.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/links/browser/links.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/links/browser/links.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/links/browser/links.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/links/browser/links.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/links/browser/links.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/links/browser/links.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/links/browser/links.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/longLinesHelper/browser/longLinesHelper.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/longLinesHelper/browser/longLinesHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/longLinesHelper/browser/longLinesHelper.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/longLinesHelper/browser/longLinesHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/message/browser/messageController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScroll.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScrollController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScrollController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScrollController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/middleScroll/browser/middleScrollController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/multicursor/browser/multicursor.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/multicursor/browser/multicursor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/multicursor/browser/multicursor.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/multicursor/browser/multicursor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHints.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/provideSignatureHelp.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/provideSignatureHelp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/provideSignatureHelp.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/parameterHints/browser/provideSignatureHelp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/peekView/browser/media/peekViewWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/peekView/browser/media/peekViewWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/peekView/browser/media/peekViewWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/peekView/browser/media/peekViewWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/peekView/browser/peekView.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/peekView/browser/peekView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/peekView/browser/peekView.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/peekView/browser/peekView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderText.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/placeholderText/browser/placeholderTextContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/editorNavigationQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoLineQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoLineQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoLineQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoLineQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/quickAccess/browser/gotoSymbolQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/readOnlyMessage/browser/contribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/readOnlyMessage/browser/contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/readOnlyMessage/browser/contribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/readOnlyMessage/browser/contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/rename/browser/rename.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/rename/browser/rename.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/rename/browser/rename.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/rename/browser/rename.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/rename/browser/renameWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/sectionHeaders/browser/sectionHeaders.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/sectionHeaders/browser/sectionHeaders.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/sectionHeaders/browser/sectionHeaders.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/sectionHeaders/browser/sectionHeaders.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/documentSemanticTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/getSemanticTokens.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/getSemanticTokens.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/getSemanticTokens.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/getSemanticTokens.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/semanticTokens/common/semanticTokensConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/bracketSelections.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/bracketSelections.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/bracketSelections.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/bracketSelections.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/smartSelect.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/wordSelections.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/wordSelections.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/wordSelections.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/smartSelect/browser/wordSelections.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippet.md b/apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippet.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippet.md rename to apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippet.md diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetController2.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetController2.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetController2.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetController2.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetParser.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetParser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetParser.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetParser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetSession.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetVariables.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetVariables.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetVariables.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/snippet/browser/snippetVariables.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollElement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/completionModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/completionModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/completionModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/completionModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/media/suggest.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/media/suggest.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/media/suggest.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/media/suggest.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggest.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggest.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggest.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestAlternatives.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestCommitCharacters.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestCommitCharacters.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestCommitCharacters.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestCommitCharacters.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestInlineCompletions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestMemory.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestMemory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestMemory.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestMemory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestModel.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestModel.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestOvertypingCapturer.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestOvertypingCapturer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestOvertypingCapturer.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestOvertypingCapturer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordContextKey.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordContextKey.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordContextKey.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordContextKey.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordDistance.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordDistance.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordDistance.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/suggest/browser/wordDistance.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/symbolIcons/browser/symbolIcons.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/tokenization/browser/tokenization.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/tokenization/browser/tokenization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/tokenization/browser/tokenization.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/tokenization/browser/tokenization.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/bannerController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/highlightDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/textualHighlightProvider.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/textualHighlightProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/textualHighlightProvider.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/textualHighlightProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.css b/apps/review-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.css rename to apps/review-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts b/apps/review-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts rename to apps/review-desktop/code-oss/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/editor.all.ts b/apps/review-desktop/code-oss/src/vs/editor/editor.all.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/editor.all.ts rename to apps/review-desktop/code-oss/src/vs/editor/editor.all.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-dark.svg b/apps/review-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-dark.svg rename to apps/review-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-light.svg b/apps/review-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-light.svg rename to apps/review-desktop/code-oss/src/vs/editor/standalone/browser/iPadShowKeyboard/keyboard-light.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/monaco.d.ts b/apps/review-desktop/code-oss/src/vs/monaco.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/monaco.d.ts rename to apps/review-desktop/code-oss/src/vs/monaco.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/nls.ts b/apps/review-desktop/code-oss/src/vs/nls.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/nls.ts rename to apps/review-desktop/code-oss/src/vs/nls.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/browser/accessibilityService.ts b/apps/review-desktop/code-oss/src/vs/platform/accessibility/browser/accessibilityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/browser/accessibilityService.ts rename to apps/review-desktop/code-oss/src/vs/platform/accessibility/browser/accessibilityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleView.ts b/apps/review-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleView.ts rename to apps/review-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/common/accessibility.ts b/apps/review-desktop/code-oss/src/vs/platform/accessibility/common/accessibility.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibility/common/accessibility.ts rename to apps/review-desktop/code-oss/src/vs/platform/accessibility/common/accessibility.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/accessibilitySignalService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/break.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/break.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/break.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/break.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatEditModifiedFile.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatEditModifiedFile.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatEditModifiedFile.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatEditModifiedFile.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatUserActionRequired.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatUserActionRequired.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatUserActionRequired.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/chatUserActionRequired.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/clear.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/clear.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/clear.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/clear.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionApplied.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionApplied.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionApplied.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionApplied.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionTriggered.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionTriggered.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionTriggered.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/codeActionTriggered.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineDeleted.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineDeleted.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineDeleted.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineDeleted.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineInserted.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineInserted.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineInserted.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineInserted.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineModified.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineModified.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineModified.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/diffLineModified.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsKept.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsKept.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsKept.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsKept.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsUndone.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsUndone.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsUndone.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/editsUndone.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/error.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/error.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/error.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/error.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/foldedAreas.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/foldedAreas.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/foldedAreas.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/foldedAreas.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/format.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/format.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/format.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/format.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/nextEditSuggestion.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/nextEditSuggestion.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/nextEditSuggestion.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/nextEditSuggestion.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/progress.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/progress.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/progress.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/progress.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/quickFixes.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/quickFixes.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/quickFixes.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/quickFixes.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/requestSent.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/requestSent.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/requestSent.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/requestSent.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived1.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived1.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived1.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived1.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived2.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived2.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived2.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived2.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived3.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived3.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived3.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived3.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived4.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived4.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived4.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/responseReceived4.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/save.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/save.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/save.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/save.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/success.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/success.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/success.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/success.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskCompleted.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskCompleted.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskCompleted.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskCompleted.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskFailed.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskFailed.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskFailed.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/taskFailed.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalBell.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalBell.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalBell.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalBell.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalCommandSucceeded.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalCommandSucceeded.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalCommandSucceeded.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/terminalCommandSucceeded.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStarted.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStarted.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStarted.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStarted.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStopped.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStopped.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStopped.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/voiceRecordingStopped.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/warning.mp3 b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/warning.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/warning.mp3 rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/media/warning.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/progressAccessibilitySignalScheduler.ts b/apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/progressAccessibilitySignalScheduler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/progressAccessibilitySignalScheduler.ts rename to apps/review-desktop/code-oss/src/vs/platform/accessibilitySignal/browser/progressAccessibilitySignalScheduler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/action/common/action.ts b/apps/review-desktop/code-oss/src/vs/platform/action/common/action.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/action/common/action.ts rename to apps/review-desktop/code-oss/src/vs/platform/action/common/action.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/action/common/actionCommonCategories.ts b/apps/review-desktop/code-oss/src/vs/platform/action/common/actionCommonCategories.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/action/common/actionCommonCategories.ts rename to apps/review-desktop/code-oss/src/vs/platform/action/common/actionCommonCategories.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionList.ts b/apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionList.ts rename to apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionList.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.css b/apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.css rename to apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.ts b/apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.ts rename to apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidgetDropdown.ts b/apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidgetDropdown.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidgetDropdown.ts rename to apps/review-desktop/code-oss/src/vs/platform/actionWidget/browser/actionWidgetDropdown.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/common/actionWidget.ts b/apps/review-desktop/code-oss/src/vs/platform/actionWidget/common/actionWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actionWidget/common/actionWidget.ts rename to apps/review-desktop/code-oss/src/vs/platform/actionWidget/common/actionWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/actionViewItemService.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/actionViewItemService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/actionViewItemService.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/actionViewItemService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/actionWidgetDropdownActionViewItem.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/actionWidgetDropdownActionViewItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/actionWidgetDropdownActionViewItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/actionWidgetDropdownActionViewItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/buttonbar.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/buttonbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/buttonbar.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/buttonbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/floatingMenu.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/floatingMenu.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/floatingMenu.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/floatingMenu.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.css b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.css rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/menuEntryActionViewItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/toolbar.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/browser/toolbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/browser/toolbar.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/browser/toolbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/actions.contribution.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/common/actions.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/actions.contribution.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/common/actions.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/common/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/common/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/menuResetAction.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/common/menuResetAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/menuResetAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/common/menuResetAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/menuService.ts b/apps/review-desktop/code-oss/src/vs/platform/actions/common/menuService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/actions/common/menuService.ts rename to apps/review-desktop/code-oss/src/vs/platform/actions/common/menuService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentClientUri.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentClientUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentClientUri.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentClientUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostByokLm.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostByokLm.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostByokLm.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostByokLm.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetOperationService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetOperationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetOperationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetOperationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetSubscriptionService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetSubscriptionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetSubscriptionService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostChangesetSubscriptionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCheckpointService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCheckpointService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCheckpointService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCheckpointService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientByokLmChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientByokLmChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientByokLmChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientByokLmChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientProxyChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientProxyChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientProxyChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientProxyChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientResourceChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientResourceChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientResourceChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostClientResourceChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConnectionsService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConnectionsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConnectionsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConnectionsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConversationContext.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConversationContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConversationContext.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostConversationContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCustomizationConfig.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCustomizationConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCustomizationConfig.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostCustomizationConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostEnablementService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostEnablementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostEnablementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostEnablementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostFileSystemService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitStateService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitStateService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitStateService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostGitStateService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostMcpServer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostMcpServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostMcpServer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostMcpServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostPlanReview.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostPlanReview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostPlanReview.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostPlanReview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostResourceService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostResourceService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostResourceService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostResourceService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostReviewService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostReviewService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostReviewService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostReviewService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSessionType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSessionType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSessionType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostSessionType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostStarter.config.contribution.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostStarter.config.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostStarter.config.contribution.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostStarter.config.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostTelemetryEnv.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostTelemetryEnv.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostTelemetryEnv.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostTelemetryEnv.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostUri.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentHostUri.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentHostUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentModelByokMeta.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentModelByokMeta.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentModelByokMeta.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentModelByokMeta.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentModelPricing.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentModelPricing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentModelPricing.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentModelPricing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentPluginManager.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentPluginManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentPluginManager.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentPluginManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentServerTools.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentServerTools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentServerTools.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentServerTools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/agentService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/agentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/ahpJsonlLogger.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/ahpJsonlLogger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/ahpJsonlLogger.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/ahpJsonlLogger.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/annotationsUri.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/annotationsUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/annotationsUri.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/annotationsUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/changesetUri.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/changesetUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/changesetUri.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/changesetUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/claudeModelConfig.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/claudeModelConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/claudeModelConfig.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/claudeModelConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/claudeSessionConfigKeys.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/claudeSessionConfigKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/claudeSessionConfigKeys.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/claudeSessionConfigKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/codexSessionConfigKeys.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/codexSessionConfigKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/codexSessionConfigKeys.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/codexSessionConfigKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/commandLineHelpers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/commandLineHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/commandLineHelpers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/commandLineHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/copilotCliConfig.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/copilotCliConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/copilotCliConfig.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/copilotCliConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/customAgents.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/customAgents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/customAgents.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/customAgents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/diffComputeService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/diffComputeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/diffComputeService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/diffComputeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/fileEditDiff.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/fileEditDiff.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/fileEditDiff.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/fileEditDiff.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/githubEndpoints.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/githubEndpoints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/githubEndpoints.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/githubEndpoints.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCompletionAttachmentMeta.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCompletionAttachmentMeta.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCompletionAttachmentMeta.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCompletionAttachmentMeta.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCustomizationMeta.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCustomizationMeta.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCustomizationMeta.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentCustomizationMeta.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAnnotations.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAnnotations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAnnotations.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAnnotations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAttachments.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAttachments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAttachments.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentFeedbackAttachments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentToolCallMeta.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentToolCallMeta.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentToolCallMeta.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/agentToolCallMeta.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/browserViewAttachments.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/browserViewAttachments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/meta/browserViewAttachments.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/meta/browserViewAttachments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/openSessionLink.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/openSessionLink.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/openSessionLink.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/openSessionLink.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/otel/agentHostOTelService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/otel/agentHostOTelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/otel/agentHostOTelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/otel/agentHostOTelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/otlp/otlpLogEmitter.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/otlp/otlpLogEmitter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/otlp/otlpLogEmitter.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/otlp/otlpLogEmitter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/pendingRequestRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/pendingRequestRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/pendingRequestRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/pendingRequestRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/reasoningEffort.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/reasoningEffort.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/reasoningEffort.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/reasoningEffort.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/relayTransport.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/relayTransport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/relayTransport.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/relayTransport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostMetadata.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostMetadata.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostMetadata.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostMetadata.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/remoteAgentHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/resourceReadLogging.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/resourceReadLogging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/resourceReadLogging.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/resourceReadLogging.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sandboxConfigSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sandboxConfigSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sandboxConfigSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sandboxConfigSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sessionConfigKeys.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sessionConfigKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sessionConfigKeys.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sessionConfigKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sessionDataService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sessionDataService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sessionDataService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sessionDataService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sshConfigParsing.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sshConfigParsing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sshConfigParsing.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sshConfigParsing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sshRemoteAgentHost.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sshRemoteAgentHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/sshRemoteAgentHost.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/sshRemoteAgentHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/AGENTS.md b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/AGENTS.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/AGENTS.md rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/AGENTS.md diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/agentSubscription.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/agentSubscription.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/agentSubscription.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/agentSubscription.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/.ahp-version b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/.ahp-version similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/.ahp-version rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/.ahp-version diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/action-origin.generated.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/action-origin.generated.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/action-origin.generated.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/action-origin.generated.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-annotations/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-changeset/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-chat/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/notifications.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/notifications.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/notifications.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/notifications.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-otlp/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-resource-watch/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/notifications.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/notifications.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/notifications.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/notifications.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-root/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-session/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/reducer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/reducer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/reducer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/reducer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/channels-terminal/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/actions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/actions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/actions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/actions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/errors.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/errors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/errors.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/errors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/messages.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/messages.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/messages.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/messages.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/notifications.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/notifications.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/notifications.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/notifications.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/reducer-helpers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/reducer-helpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/reducer-helpers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/reducer-helpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/common/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/errors.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/errors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/errors.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/errors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/mcpAppDefaults.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/mcpAppDefaults.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/mcpAppDefaults.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/mcpAppDefaults.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/messages.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/messages.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/messages.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/messages.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/notifications.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/notifications.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/notifications.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/notifications.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/reducers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/reducers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/reducers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/reducers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/state.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/negotiation.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/negotiation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/negotiation.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/negotiation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/registry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/registry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/registry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocol/version/registry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocolUpgrade.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocolUpgrade.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/protocolUpgrade.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/protocolUpgrade.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionActions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionActions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionProtocol.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionProtocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionProtocol.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionReducers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionReducers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionReducers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionReducers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionState.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionState.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionTransport.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionTransport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionTransport.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/state/sessionTransport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/tunnelAgentHost.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/tunnelAgentHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/tunnelAgentHost.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/tunnelAgentHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/wslRemoteAgentHost.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/common/wslRemoteAgentHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/common/wslRemoteAgentHost.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/common/wslRemoteAgentHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/electron-main/electronAgentHostStarter.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/electron-main/electronAgentHostStarter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/electron-main/electronAgentHostStarter.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/electron-main/electronAgentHostStarter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/activeClientState.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/activeClientState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/activeClientState.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/activeClientState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentConfigurationService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentConfigurationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentConfigurationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentConfigurationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostAuthenticationService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostAuthenticationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostAuthenticationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostAuthenticationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBangCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBangCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBangCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBangCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBootstrap.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBootstrap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBootstrap.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostBootstrap.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetCoordinator.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetCoordinator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetCoordinator.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetCoordinator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetFileMonitorCoordinator.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetFileMonitorCoordinator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetFileMonitorCoordinator.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetFileMonitorCoordinator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetOperationService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetOperationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetOperationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetOperationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetStateCache.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetStateCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetStateCache.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetStateCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetSubscriptionService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetSubscriptionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetSubscriptionService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostChangesetSubscriptionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCheckpointService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCheckpointService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCheckpointService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCheckpointService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCommitOperationProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCompletions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCompletions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCompletions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostCompletions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostDiscardChangesOperationProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileCompletionProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileCompletionProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileCompletionProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileCompletionProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileMonitorService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileMonitorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileMonitorService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostFileMonitorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitHubEndpointService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitHubEndpointService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitHubEndpointService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitHubEndpointService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitStateService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitStateService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitStateService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostGitStateService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostHeadlessTerminal.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostHeadlessTerminal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostHeadlessTerminal.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostHeadlessTerminal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostLocalTurns.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostLocalTurns.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostLocalTurns.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostLocalTurns.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostMain.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostMain.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostProxyResolver.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostProxyResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostProxyResolver.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostProxyResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostPullRequestOperationProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRenameCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRenameCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRenameCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRenameCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRequestService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRequestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRequestService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRequestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRestrictedTelemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRestrictedTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRestrictedTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostRestrictedTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostReviewService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostReviewService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostReviewService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostReviewService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSessionTitleController.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSessionTitleController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSessionTitleController.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSessionTitleController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostShellUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostShellUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostShellUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostShellUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSkillCompletionProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSkillCompletionProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSkillCompletionProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSkillCompletionProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSlashCompletion.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSlashCompletion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSlashCompletion.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSlashCompletion.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostStateManager.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostStateManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostStateManager.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostStateManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostSyncOperationProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryReporter.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryReporter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryReporter.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryReporter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTelemetryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTerminalManager.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTerminalManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTerminalManager.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTerminalManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostToolCallTracker.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostToolCallTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostToolCallTracker.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostToolCallTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTurnTracker.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTurnTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTurnTracker.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostTurnTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostUpgradeChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostUpgradeChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostUpgradeChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostUpgradeChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostWorkspaceFiles.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostWorkspaceFiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentHostWorkspaceFiles.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentHostWorkspaceFiles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentPeerChats.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentPeerChats.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentPeerChats.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentPeerChats.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentPluginManager.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentPluginManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentPluginManager.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentPluginManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentSdkDownloader.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentSdkDownloader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentSdkDownloader.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentSdkDownloader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentSideEffects.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentSideEffects.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/agentSideEffects.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/agentSideEffects.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/appNodeModules.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/appNodeModules.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/appNodeModules.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/appNodeModules.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/byokLmBridgeRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/byokLmBridgeRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/byokLmBridgeRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/byokLmBridgeRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicBetas.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicBetas.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicBetas.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicBetas.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicErrors.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicErrors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicErrors.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/anthropicErrors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSdkService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSdkService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSdkService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSdkService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSession.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSession.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeAgentSession.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeCanUseTool.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeCanUseTool.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeCanUseTool.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeCanUseTool.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeFileEditObserver.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeFileEditObserver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeFileEditObserver.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeFileEditObserver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeInteractiveTools.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeInteractiveTools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeInteractiveTools.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeInteractiveTools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeMapSessionEvents.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeMapSessionEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeMapSessionEvents.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeMapSessionEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeModelId.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeModelId.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeModelId.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeModelId.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptQueue.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptQueue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptQueue.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptQueue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptResolver.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptResolver.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudePromptResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyAuth.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyAuth.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyAuth.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyAuth.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeProxyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeReplayMapper.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeReplayMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeReplayMapper.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeReplayMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkMessageRouter.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkMessageRouter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkMessageRouter.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkMessageRouter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkOptions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkOptions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkPipeline.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkPipeline.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkPipeline.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSdkPipeline.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeServerToolMcpServer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeServerToolMcpServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeServerToolMcpServer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeServerToolMcpServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionMetadataStore.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionMetadataStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionMetadataStore.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionMetadataStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionPermissionMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionPermissionMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionPermissionMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSessionPermissionMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentResolver.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentResolver.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentSignals.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentSignals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentSignals.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeSubagentSignals.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolCallRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolCallRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolCallRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolCallRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDenial.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDenial.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDenial.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDenial.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDisplay.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDisplay.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDisplay.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/claudeToolDisplay.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolMcpServer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolMcpServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolMcpServer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolMcpServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolResult.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolResult.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolResult.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeClientToolResult.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeJsonSchemaToZod.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeJsonSchemaToZod.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeJsonSchemaToZod.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeJsonSchemaToZod.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeSessionClientToolsModel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeSessionClientToolsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeSessionClientToolsModel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/clientTools/claudeSessionClientToolsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeBuiltinCommands.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeBuiltinCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeBuiltinCommands.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeBuiltinCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionClientCustomizationsModel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionClientCustomizationsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionClientCustomizationsModel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionClientCustomizationsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionCustomizationDiscovery.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionCustomizationDiscovery.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionCustomizationDiscovery.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/claudeSessionCustomizationDiscovery.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeAgentSkillScan.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeAgentSkillScan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeAgentSkillScan.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeAgentSkillScan.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeHookScan.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeHookScan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeHookScan.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeHookScan.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeMcpScan.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeMcpScan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeMcpScan.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeMcpScan.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeNativePluginScan.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeNativePluginScan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeNativePluginScan.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeNativePluginScan.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeRuleScan.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeRuleScan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeRuleScan.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/claude/customizations/scan/claudeRuleScan.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAgent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAgent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAgent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAgent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAppServerClient.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAppServerClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAppServerClient.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexAppServerClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexElicitationMapper.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexElicitationMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexElicitationMapper.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexElicitationMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexForkPlan.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexForkPlan.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexForkPlan.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexForkPlan.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexGuardianReview.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexGuardianReview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexGuardianReview.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexGuardianReview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMapAppServerEvents.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMapAppServerEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMapAppServerEvents.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMapAppServerEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMcpServers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMcpServers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMcpServers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexMcpServers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexPromptResolver.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexPromptResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexPromptResolver.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexPromptResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexProxyService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexProxyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexProxyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexProxyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexReplayMapper.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexReplayMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexReplayMapper.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexReplayMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionConfigKeys.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionConfigKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionConfigKeys.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionConfigKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionMetadataStore.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionMetadataStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionMetadataStore.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexSessionMetadataStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexShellCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexShellCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexShellCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexShellCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexUserInputMapper.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexUserInputMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexUserInputMapper.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/codexUserInputMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AbsolutePathBuf.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AbsolutePathBuf.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AbsolutePathBuf.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AbsolutePathBuf.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentMessageInputContent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentMessageInputContent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentMessageInputContent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentMessageInputContent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentPath.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentPath.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentPath.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AgentPath.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AmazonBedrockCredentialSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AmazonBedrockCredentialSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AmazonBedrockCredentialSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AmazonBedrockCredentialSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ApplyPatchApprovalParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ApplyPatchApprovalParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ApplyPatchApprovalParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ApplyPatchApprovalParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AuthMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AuthMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AuthMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/AuthMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientInfo.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientInfo.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientRequest.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientRequest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientRequest.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ClientRequest.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/CollaborationMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/CollaborationMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/CollaborationMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/CollaborationMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ContentItem.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ContentItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ContentItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ContentItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ConversationTextRole.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ConversationTextRole.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ConversationTextRole.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ConversationTextRole.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ExecCommandApprovalParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ExecCommandApprovalParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ExecCommandApprovalParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ExecCommandApprovalParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FileChange.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FileChange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FileChange.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FileChange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputBody.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputBody.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputBody.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputBody.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputContentItem.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputContentItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputContentItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FunctionCallOutputContentItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchMatchType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchMatchType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchMatchType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchMatchType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchResult.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchResult.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchResult.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchResult.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStopParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStopParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStopParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionStopParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/FuzzyFileSearchSessionUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetAuthStatusParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetAuthStatusParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetAuthStatusParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetAuthStatusParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetConversationSummaryParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetConversationSummaryParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetConversationSummaryParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GetConversationSummaryParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GitDiffToRemoteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GitDiffToRemoteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GitDiffToRemoteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/GitDiffToRemoteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ImageDetail.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ImageDetail.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ImageDetail.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ImageDetail.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeCapabilities.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeCapabilities.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeCapabilities.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeCapabilities.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InitializeParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InternalChatMessageMetadataPassthrough.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InternalChatMessageMetadataPassthrough.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InternalChatMessageMetadataPassthrough.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/InternalChatMessageMetadataPassthrough.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LegacyAppPathString.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LegacyAppPathString.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LegacyAppPathString.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LegacyAppPathString.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellExecAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellExecAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellExecAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellExecAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/LocalShellStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/McpServerInfo.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/McpServerInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/McpServerInfo.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/McpServerInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MessagePhase.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MessagePhase.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MessagePhase.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MessagePhase.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ModeKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ModeKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ModeKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ModeKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MultiAgentMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MultiAgentMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MultiAgentMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/MultiAgentMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ParsedCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ParsedCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ParsedCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ParsedCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Personality.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Personality.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Personality.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Personality.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/PlanType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/PlanType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/PlanType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/PlanType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/README.md b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/README.md rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/README.md diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeConversationVersion.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeConversationVersion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeConversationVersion.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeConversationVersion.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeOutputModality.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeOutputModality.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeOutputModality.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeOutputModality.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeVoice.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeVoice.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeVoice.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RealtimeVoice.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningEffort.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningEffort.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningEffort.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningEffort.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemContent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemContent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemContent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemContent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemReasoningSummary.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemReasoningSummary.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemReasoningSummary.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningItemReasoningSummary.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningSummary.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningSummary.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningSummary.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ReasoningSummary.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RequestId.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RequestId.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RequestId.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/RequestId.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Resource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Resource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Resource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Resource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceContent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceContent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceContent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceContent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceTemplate.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceTemplate.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceTemplate.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResourceTemplate.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResponseItem.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResponseItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResponseItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ResponseItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerRequest.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerRequest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerRequest.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ServerRequest.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Settings.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Settings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Settings.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Settings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/SubAgentSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/SubAgentSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/SubAgentSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/SubAgentSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadId.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadId.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadId.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadId.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadMemoryMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadMemoryMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadMemoryMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/ThreadMemoryMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Tool.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Tool.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Tool.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/Tool.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/WebSearchMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/serde_json/JsonValue.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/serde_json/JsonValue.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/serde_json/JsonValue.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/serde_json/JsonValue.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Account.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Account.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Account.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Account.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountLoginCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountLoginCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountLoginCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountLoginCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountRateLimitsUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountRateLimitsUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountRateLimitsUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountRateLimitsUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AccountUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ActivePermissionProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ActivePermissionProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ActivePermissionProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ActivePermissionProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AddCreditsNudgeCreditType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AddCreditsNudgeCreditType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AddCreditsNudgeCreditType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AddCreditsNudgeCreditType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextEntry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextEntry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalContextKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalFileSystemPermissions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalFileSystemPermissions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalFileSystemPermissions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalFileSystemPermissions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalNetworkPermissions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalNetworkPermissions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalNetworkPermissions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalNetworkPermissions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalPermissionProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalPermissionProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalPermissionProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalPermissionProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AgentMessageDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AgentMessageDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AgentMessageDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AgentMessageDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppBranding.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppBranding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppBranding.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppBranding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppInfo.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppInfo.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppListUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppListUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppListUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppListUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppMetadata.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppMetadata.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppMetadata.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppMetadata.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppReview.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppReview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppReview.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppReview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppScreenshot.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppScreenshot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppScreenshot.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppScreenshot.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ApprovalsReviewer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ApprovalsReviewer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ApprovalsReviewer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ApprovalsReviewer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppsListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppsListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppsListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AppsListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AskForApproval.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AskForApproval.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AskForApproval.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AskForApproval.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AttestationGenerateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AttestationGenerateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AttestationGenerateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AttestationGenerateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AutoReviewDecisionSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AutoReviewDecisionSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AutoReviewDecisionSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/AutoReviewDecisionSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ByteRange.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ByteRange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ByteRange.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ByteRange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CancelLoginAccountParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CancelLoginAccountParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CancelLoginAccountParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CancelLoginAccountParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CapabilityRootLocation.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CapabilityRootLocation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CapabilityRootLocation.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CapabilityRootLocation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshReason.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshReason.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshReason.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ChatgptAuthTokensRefreshReason.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CodexErrorInfo.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CodexErrorInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CodexErrorInfo.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CodexErrorInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentState.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentState.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentTool.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentTool.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentTool.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentTool.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentToolCallStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentToolCallStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentToolCallStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollabAgentToolCallStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollaborationModeListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollaborationModeListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollaborationModeListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CollaborationModeListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputStream.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputStream.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputStream.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecOutputStream.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecResizeParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecResizeParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecResizeParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecResizeParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminalSize.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminalSize.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminalSize.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminalSize.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecTerminateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecWriteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecWriteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecWriteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecWriteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionApprovalDecision.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionApprovalDecision.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionApprovalDecision.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionApprovalDecision.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionOutputDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionOutputDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionOutputDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionOutputDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionRequestApprovalResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandExecutionStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CommandMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigBatchWriteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigBatchWriteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigBatchWriteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigBatchWriteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigEdit.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigEdit.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigValueWriteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigValueWriteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigValueWriteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigValueWriteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigWarningNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigWarningNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigWarningNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConfigWarningNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConsumeAccountRateLimitResetCreditParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConsumeAccountRateLimitResetCreditParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConsumeAccountRateLimitResetCreditParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ConsumeAccountRateLimitResetCreditParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ContextCompactedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ContextCompactedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ContextCompactedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ContextCompactedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CreditsSnapshot.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CreditsSnapshot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CreditsSnapshot.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CreditsSnapshot.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CurrentTimeReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CurrentTimeReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CurrentTimeReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/CurrentTimeReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DeprecationNoticeNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DeprecationNoticeNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DeprecationNoticeNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DeprecationNoticeNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallOutputContentItem.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallOutputContentItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallOutputContentItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallOutputContentItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolCallStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolFunctionSpec.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolFunctionSpec.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolFunctionSpec.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolFunctionSpec.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceSpec.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceSpec.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceSpec.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceSpec.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceTool.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceTool.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceTool.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolNamespaceTool.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolSpec.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolSpec.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolSpec.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/DynamicToolSpec.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/EnvironmentAddParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/EnvironmentAddParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/EnvironmentAddParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/EnvironmentAddParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ErrorNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ErrorNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ErrorNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ErrorNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExecPolicyAmendment.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExecPolicyAmendment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExecPolicyAmendment.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExecPolicyAmendment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureEnablementSetParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureEnablementSetParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureEnablementSetParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureEnablementSetParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExperimentalFeatureListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigDetectParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigDetectParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigDetectParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigDetectParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeFailure.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeFailure.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeFailure.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeFailure.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeSuccess.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeSuccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeSuccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportItemTypeSuccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportProgressNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportProgressNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportProgressNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportProgressNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportTypeResult.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportTypeResult.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportTypeResult.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigImportTypeResult.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItem.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItemType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItemType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItemType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ExternalAgentConfigMigrationItemType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FeedbackUploadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FeedbackUploadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FeedbackUploadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FeedbackUploadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeApprovalDecision.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeApprovalDecision.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeApprovalDecision.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeApprovalDecision.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeOutputDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeOutputDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeOutputDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeOutputDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangePatchUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangePatchUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangePatchUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangePatchUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileChangeRequestApprovalResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemAccessMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemAccessMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemAccessMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemAccessMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemPath.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemPath.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemPath.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemPath.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSandboxEntry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSandboxEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSandboxEntry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSandboxEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSpecialPath.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSpecialPath.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSpecialPath.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileSystemSpecialPath.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileUpdateChange.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileUpdateChange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileUpdateChange.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FileUpdateChange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsChangedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsChangedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsChangedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsChangedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCopyParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCopyParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCopyParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCopyParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCreateDirectoryParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCreateDirectoryParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCreateDirectoryParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsCreateDirectoryParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsGetMetadataParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsGetMetadataParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsGetMetadataParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsGetMetadataParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadDirectoryParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadDirectoryParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadDirectoryParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadDirectoryParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadFileParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadFileParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadFileParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsReadFileParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsRemoveParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsRemoveParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsRemoveParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsRemoveParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsUnwatchParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsUnwatchParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsUnwatchParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsUnwatchParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWatchParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWatchParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWatchParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWatchParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWriteFileParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWriteFileParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWriteFileParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/FsWriteFileParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GetAccountResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GitInfo.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GitInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GitInfo.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GitInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GrantedPermissionProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GrantedPermissionProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GrantedPermissionProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GrantedPermissionProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReview.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReview.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianApprovalReviewStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianCommandSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianCommandSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianCommandSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianCommandSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianRiskLevel.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianRiskLevel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianRiskLevel.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianRiskLevel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianUserAuthorization.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianUserAuthorization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianUserAuthorization.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianUserAuthorization.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianWarningNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianWarningNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianWarningNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/GuardianWarningNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookEventName.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookEventName.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookEventName.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookEventName.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookExecutionMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookExecutionMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookExecutionMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookExecutionMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookHandlerType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookHandlerType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookHandlerType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookHandlerType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntryKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntryKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntryKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookOutputEntryKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookPromptFragment.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookPromptFragment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookPromptFragment.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookPromptFragment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunSummary.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunSummary.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunSummary.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookRunSummary.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookScope.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookScope.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookScope.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookScope.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookStartedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookStartedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookStartedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HookStartedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HooksListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HooksListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HooksListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/HooksListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewStartedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewStartedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewStartedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemGuardianApprovalReviewStartedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemStartedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemStartedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemStartedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ItemStartedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ListMcpServerStatusResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/LoginAccountParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/LoginAccountParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/LoginAccountParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/LoginAccountParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceAddParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceAddParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceAddParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceAddParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceRemoveParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceRemoveParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceRemoveParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceRemoveParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceUpgradeParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceUpgradeParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceUpgradeParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MarketplaceUpgradeParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpAuthStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpAuthStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpAuthStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpAuthStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationArrayType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationArrayType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationArrayType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationArrayType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationBooleanType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationConstOption.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationConstOption.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationConstOption.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationConstOption.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationLegacyTitledEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationLegacyTitledEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationLegacyTitledEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationLegacyTitledEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationMultiSelectEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationMultiSelectEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationMultiSelectEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationMultiSelectEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationNumberType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationObjectType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationObjectType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationObjectType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationObjectType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationPrimitiveSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationPrimitiveSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationPrimitiveSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationPrimitiveSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSingleSelectEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSingleSelectEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSingleSelectEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationSingleSelectEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringFormat.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringFormat.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringFormat.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringFormat.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationStringType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledEnumItems.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledEnumItems.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledEnumItems.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledEnumItems.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledMultiSelectEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledMultiSelectEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledMultiSelectEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledMultiSelectEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledSingleSelectEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledSingleSelectEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledSingleSelectEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationTitledSingleSelectEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledEnumItems.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledEnumItems.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledEnumItems.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledEnumItems.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledMultiSelectEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledMultiSelectEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledMultiSelectEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledMultiSelectEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledSingleSelectEnumSchema.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledSingleSelectEnumSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledSingleSelectEnumSchema.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpElicitationUntitledSingleSelectEnumSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpResourceReadResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerElicitationRequestResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerOauthLoginParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStartupState.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStartupState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStartupState.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStartupState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusDetail.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusDetail.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusDetail.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusDetail.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerStatusUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpServerToolCallResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallAppContext.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallAppContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallAppContext.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallAppContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallError.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallError.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallError.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallError.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallProgressNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallProgressNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallProgressNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallProgressNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallResult.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallResult.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallResult.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallResult.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/McpToolCallStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitation.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitation.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitationEntry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitationEntry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitationEntry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MemoryCitationEntry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MergeStrategy.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MergeStrategy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MergeStrategy.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MergeStrategy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MigrationDetails.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MigrationDetails.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MigrationDetails.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MigrationDetails.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MockExperimentalMethodParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MockExperimentalMethodParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MockExperimentalMethodParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/MockExperimentalMethodParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelProviderCapabilitiesReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelProviderCapabilitiesReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelProviderCapabilitiesReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelProviderCapabilitiesReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelRerouteReason.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelRerouteReason.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelRerouteReason.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelRerouteReason.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelReroutedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelReroutedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelReroutedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelReroutedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelSafetyBufferingUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelSafetyBufferingUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelSafetyBufferingUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelSafetyBufferingUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerificationNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerificationNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerificationNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ModelVerificationNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkAccess.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkAccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalContext.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalContext.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalProtocol.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalProtocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalProtocol.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkApprovalProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyAmendment.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyAmendment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyAmendment.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyAmendment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyRuleAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyRuleAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyRuleAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NetworkPolicyRuleAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NonSteerableTurnKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NonSteerableTurnKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NonSteerableTurnKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/NonSteerableTurnKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchApplyStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchApplyStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchApplyStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchApplyStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchChangeKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchChangeKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchChangeKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PatchChangeKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionGrantScope.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionGrantScope.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionGrantScope.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionGrantScope.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionProfileListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionProfileListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionProfileListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionProfileListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PlanDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PlanDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PlanDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PlanDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstallParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstallParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstallParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstallParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstalledParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstalledParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstalledParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginInstalledParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListMarketplaceKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListMarketplaceKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListMarketplaceKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListMarketplaceKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareCheckoutParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareCheckoutParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareCheckoutParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareCheckoutParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDeleteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDeleteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDeleteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDeleteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDiscoverability.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDiscoverability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDiscoverability.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareDiscoverability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSharePrincipalType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSharePrincipalType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSharePrincipalType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSharePrincipalType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareSaveParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareSaveParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareSaveParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareSaveParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTarget.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTarget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTarget.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTarget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTargetRole.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTargetRole.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTargetRole.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareTargetRole.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateDiscoverability.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateDiscoverability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateDiscoverability.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateDiscoverability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateTargetsParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateTargetsParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateTargetsParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginShareUpdateTargetsParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSkillReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSkillReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSkillReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginSkillReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginUninstallParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginUninstallParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginUninstallParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginUninstallParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginsMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginsMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginsMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/PluginsMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessExitedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessExitedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessExitedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessExitedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessKillParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessKillParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessKillParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessKillParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputStream.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputStream.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputStream.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessOutputStream.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessResizePtyParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessResizePtyParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessResizePtyParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessResizePtyParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessSpawnParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessSpawnParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessSpawnParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessSpawnParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessTerminalSize.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessTerminalSize.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessTerminalSize.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessTerminalSize.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessWriteStdinParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessWriteStdinParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessWriteStdinParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ProcessWriteStdinParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitReachedType.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitReachedType.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitReachedType.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitReachedType.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitSnapshot.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitSnapshot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitSnapshot.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitSnapshot.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitWindow.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitWindow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitWindow.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RateLimitWindow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RawResponseItemCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RawResponseItemCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RawResponseItemCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RawResponseItemCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryPartAddedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryPartAddedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryPartAddedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryPartAddedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryTextDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryTextDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryTextDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningSummaryTextDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningTextDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningTextDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningTextDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReasoningTextDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListOrder.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListOrder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListOrder.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListOrder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsRevokeParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsRevokeParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsRevokeParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlClientsRevokeParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlConnectionStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlConnectionStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlConnectionStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlConnectionStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlDisableParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlDisableParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlDisableParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlDisableParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlEnableParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlEnableParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlEnableParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlEnableParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStatusParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStatusParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStatusParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlPairingStatusParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlStatusChangedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlStatusChangedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlStatusChangedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RemoteControlStatusChangedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RequestPermissionProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RequestPermissionProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RequestPermissionProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/RequestPermissionProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewDelivery.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewDelivery.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewDelivery.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewDelivery.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewTarget.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewTarget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewTarget.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ReviewTarget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxPolicy.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxPolicy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxPolicy.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SandboxPolicy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SelectedCapabilityRoot.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SelectedCapabilityRoot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SelectedCapabilityRoot.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SelectedCapabilityRoot.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SendAddCreditsNudgeEmailParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SendAddCreditsNudgeEmailParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SendAddCreditsNudgeEmailParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SendAddCreditsNudgeEmailParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ServerRequestResolvedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ServerRequestResolvedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ServerRequestResolvedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ServerRequestResolvedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SessionSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsChangedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsChangedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsChangedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsChangedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsConfigWriteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsConfigWriteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsConfigWriteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsConfigWriteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsExtraRootsSetParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsExtraRootsSetParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsExtraRootsSetParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsExtraRootsSetParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SkillsListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SortDirection.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SortDirection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SortDirection.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SortDirection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SpendControlLimitSnapshot.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SpendControlLimitSnapshot.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SpendControlLimitSnapshot.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SpendControlLimitSnapshot.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubAgentActivityKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubAgentActivityKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubAgentActivityKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubAgentActivityKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubagentMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubagentMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubagentMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/SubagentMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TerminalInteractionNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TerminalInteractionNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TerminalInteractionNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TerminalInteractionNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextElement.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextElement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextElement.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextElement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextPosition.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextPosition.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextPosition.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextPosition.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextRange.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextRange.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextRange.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TextRange.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Thread.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Thread.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Thread.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Thread.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadActiveFlag.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadActiveFlag.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadActiveFlag.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadActiveFlag.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadApproveGuardianDeniedActionResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchiveParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchiveParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchiveParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchiveParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchivedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchivedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchivedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadArchivedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsCleanParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsCleanParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsCleanParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsCleanParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsTerminateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsTerminateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsTerminateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadBackgroundTerminalsTerminateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadClosedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadClosedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadClosedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadClosedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadCompactStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadCompactStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadCompactStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadCompactStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDecrementElicitationParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDecrementElicitationParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDecrementElicitationParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDecrementElicitationParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeleteParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeleteParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeleteParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeleteParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadDeletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkResponse.ts similarity index 96% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkResponse.ts index c39e56e5b..3e083cc3a 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkResponse.ts +++ b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadForkResponse.ts @@ -28,7 +28,7 @@ export type ThreadForkResponse = { */ instructionSources: Array, approvalPolicy: AskForApproval, /** - * Whiteboarder currently used for approval requests on this thread. + * Reviewer currently used for approval requests on this thread. */ approvalsReviewer: ApprovalsReviewer, /** diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoal.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoal.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalClearedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalGetParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalGetParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalGetParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalGetParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalSetParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalSetParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalSetParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalSetParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadGoalUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadIncrementElicitationParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadIncrementElicitationParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadIncrementElicitationParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadIncrementElicitationParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadInjectItemsParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadInjectItemsParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadInjectItemsParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadInjectItemsParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadItem.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadListResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadLoadedListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadLoadedListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadLoadedListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadLoadedListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMemoryModeSetParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMemoryModeSetParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMemoryModeSetParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMemoryModeSetParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataGitInfoUpdateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataGitInfoUpdateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataGitInfoUpdateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataGitInfoUpdateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataUpdateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataUpdateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataUpdateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadMetadataUpdateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadNameUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadNameUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadNameUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadNameUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadReadResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendAudioParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendAudioParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendAudioParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendAudioParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendSpeechParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendSpeechParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendSpeechParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendSpeechParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendTextParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendTextParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendTextParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAppendTextParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAudioChunk.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAudioChunk.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAudioChunk.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeAudioChunk.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeClosedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeClosedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeClosedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeClosedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeErrorNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeErrorNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeErrorNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeErrorNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeItemAddedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeItemAddedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeItemAddedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeItemAddedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeListVoicesParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeListVoicesParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeListVoicesParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeListVoicesParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeOutputAudioDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeOutputAudioDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeOutputAudioDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeOutputAudioDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeSdpNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeSdpNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeSdpNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeSdpNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartTransport.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartTransport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartTransport.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartTransport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStartedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStopParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStopParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStopParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeStopParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDeltaNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDeltaNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDeltaNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDeltaNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDoneNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDoneNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDoneNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRealtimeTranscriptDoneNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeInitialTurnsPageParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeInitialTurnsPageParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeInitialTurnsPageParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeInitialTurnsPageParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadResumeParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRollbackParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRollbackParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRollbackParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadRollbackParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSearchParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSearchParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSearchParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSearchParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSetNameParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSetNameParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSetNameParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSetNameParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettings.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettings.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdateParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdateParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdateParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdateParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSettingsUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadShellCommandParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadShellCommandParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadShellCommandParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadShellCommandParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSortKey.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSortKey.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSortKey.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSortKey.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSourceKind.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSourceKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSourceKind.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadSourceKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartSource.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartSource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartSource.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartSource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStartedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatusChangedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatusChangedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatusChangedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadStatusChangedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsage.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsage.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsageUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsageUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsageUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTokenUsageUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsItemsListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsItemsListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsItemsListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsItemsListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsListParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsListParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsListParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadTurnsListParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchiveParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchiveParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchiveParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchiveParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchivedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchivedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchivedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnarchivedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnsubscribeParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnsubscribeParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnsubscribeParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ThreadUnsubscribeParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TokenUsageBreakdown.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TokenUsageBreakdown.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TokenUsageBreakdown.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TokenUsageBreakdown.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputAnswer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputAnswer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputAnswer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputAnswer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputOption.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputOption.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputOption.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputOption.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputQuestion.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputQuestion.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputQuestion.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputQuestion.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputResponse.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputResponse.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputResponse.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/ToolRequestUserInputResponse.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Turn.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Turn.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Turn.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/Turn.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnDiffUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnDiffUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnDiffUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnDiffUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnEnvironmentParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnEnvironmentParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnEnvironmentParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnEnvironmentParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnError.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnError.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnError.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnError.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnInterruptParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnInterruptParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnInterruptParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnInterruptParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnItemsView.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnItemsView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnItemsView.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnItemsView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnModerationMetadataNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnModerationMetadataNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnModerationMetadataNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnModerationMetadataNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStep.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStep.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStep.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStep.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStepStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStepStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStepStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanStepStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanUpdatedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanUpdatedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanUpdatedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnPlanUpdatedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStartedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStatus.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStatus.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnSteerParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnSteerParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnSteerParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/TurnSteerParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/UserInput.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/UserInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/UserInput.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/UserInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WarningNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WarningNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WarningNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WarningNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WebSearchAction.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WebSearchAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WebSearchAction.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WebSearchAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupCompletedNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupCompletedNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupCompletedNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupCompletedNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupMode.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupMode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupMode.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupMode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupStartParams.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupStartParams.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupStartParams.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsSandboxSetupStartParams.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsWorldWritableWarningNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsWorldWritableWarningNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsWorldWritableWarningNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/codex/protocol/generated/v2/WindowsWorldWritableWarningNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/commandAutoApprover.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/commandAutoApprover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/commandAutoApprover.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/commandAutoApprover.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/agentHostSandboxEngine.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/agentHostSandboxEngine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/agentHostSandboxEngine.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/agentHostSandboxEngine.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/buildSessionEvents.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/buildSessionEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/buildSessionEvents.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/buildSessionEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokLmProxyService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokLmProxyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokLmProxyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokLmProxyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokOpenAiTranslation.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokOpenAiTranslation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokOpenAiTranslation.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/byokOpenAiTranslation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotAgentSession.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotBranchNameGenerator.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotBranchNameGenerator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotBranchNameGenerator.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotBranchNameGenerator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotGitProject.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotGitProject.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotGitProject.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotGitProject.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotPluginConverters.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotPluginConverters.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotPluginConverters.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotPluginConverters.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotRCP.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotRCP.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotRCP.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotRCP.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionLauncher.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionLauncher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionLauncher.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionLauncher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionWrapper.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionWrapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionWrapper.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSessionWrapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotShellTools.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotShellTools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotShellTools.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotShellTools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandCompletionProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandCompletionProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandCompletionProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandCompletionProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSlashCommandProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSystemNotification.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSystemNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSystemNotification.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotSystemNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotTokenFields.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotTokenFields.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotTokenFields.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotTokenFields.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotToolDisplay.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotToolDisplay.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotToolDisplay.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/copilotToolDisplay.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/mapSessionEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/pendingEditContentStore.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/pendingEditContentStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/pendingEditContentStore.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/pendingEditContentStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/AGENTS.md b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/AGENTS.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/AGENTS.md rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/AGENTS.md diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/allPrompts.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/allPrompts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/allPrompts.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/allPrompts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/anthropicPrompt.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/anthropicPrompt.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/anthropicPrompt.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/anthropicPrompt.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/promptRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/promptRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/promptRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/promptRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/systemMessage.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/systemMessage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/systemMessage.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/systemMessage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/toolInstructions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/toolInstructions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/toolInstructions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/prompts/toolInstructions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sandboxConfigForSdk.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sandboxConfigForSdk.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sandboxConfigForSdk.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sandboxConfigForSdk.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sessionCustomizationDiscovery.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sessionCustomizationDiscovery.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sessionCustomizationDiscovery.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/copilot/sessionCustomizationDiscovery.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/diffComputeService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/diffComputeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/diffComputeService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/diffComputeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/diffWorkerMain.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/diffWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/diffWorkerMain.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/diffWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/gitDiffContent.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/gitDiffContent.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/gitDiffContent.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/gitDiffContent.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/bangLocalCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/bangLocalCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/bangLocalCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/bangLocalCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommands.contribution.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommands.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommands.contribution.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/localChatCommands.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/renameLocalCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/renameLocalCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/renameLocalCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/localCommands/renameLocalCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/networkDiagnosticsService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/networkDiagnosticsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/networkDiagnosticsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/networkDiagnosticsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/osc633Parser.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/osc633Parser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/osc633Parser.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/osc633Parser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/otel/agentHostOTelService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/otel/agentHostOTelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/otel/agentHostOTelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/otel/agentHostOTelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/protocolServerHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/protocolServerHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/protocolServerHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/protocolServerHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionDataService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionDataService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionDataService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionDataService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionDatabase.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionDatabase.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionDatabase.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionDatabase.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionDiffAggregator.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionDiffAggregator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionDiffAggregator.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionDiffAggregator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionPermissions.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionPermissions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sessionPermissions.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sessionPermissions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentFeedbackServerTools.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentFeedbackServerTools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentFeedbackServerTools.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentFeedbackServerTools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentHostOctoKitService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentHostOctoKitService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentHostOctoKitService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentHostOctoKitService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentServerToolHost.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentServerToolHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentServerToolHost.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/agentServerToolHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/copilotApiService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/copilotApiService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/copilotApiService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/copilotApiService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/editChunkExtractor.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/editChunkExtractor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/editChunkExtractor.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/editChunkExtractor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalReporter.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalReporter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalReporter.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalReporter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalTracker.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalTracker.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/editSurvivalTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/fileEditTracker.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/fileEditTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/fileEditTracker.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/fileEditTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/forwardedChatError.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/forwardedChatError.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/forwardedChatError.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/forwardedChatError.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/loopbackProxyServer.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/loopbackProxyServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/loopbackProxyServer.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/loopbackProxyServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/mcpCustomizationController.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/mcpCustomizationController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/mcpCustomizationController.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/mcpCustomizationController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/persistSessionMetadata.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/persistSessionMetadata.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/persistSessionMetadata.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/persistSessionMetadata.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/serverToolGroups.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/serverToolGroups.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/serverToolGroups.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/serverToolGroups.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/sessionServerTools.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/sessionServerTools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/sessionServerTools.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/sessionServerTools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/shellCommandExecution.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/shellCommandExecution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/shared/shellCommandExecution.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/shared/shellCommandExecution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostHelpers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostHelpers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/tunnelAgentHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/tunnelAgentHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/tunnelAgentHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/tunnelAgentHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/tunnelHostMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/tunnelHostMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/tunnelHostMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/tunnelHostMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/webSocketTransport.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/webSocketTransport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/webSocketTransport.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/webSocketTransport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/workspacelessScratchDir.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/workspacelessScratchDir.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/workspacelessScratchDir.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/workspacelessScratchDir.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostHelpers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostHelpers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentHost/node/wslRemoteAgentHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/agentPlugins/common/pluginParsers.ts b/apps/review-desktop/code-oss/src/vs/platform/agentPlugins/common/pluginParsers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/agentPlugins/common/pluginParsers.ts rename to apps/review-desktop/code-oss/src/vs/platform/agentPlugins/common/pluginParsers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/assignment/common/assignment.ts b/apps/review-desktop/code-oss/src/vs/platform/assignment/common/assignment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/assignment/common/assignment.ts rename to apps/review-desktop/code-oss/src/vs/platform/assignment/common/assignment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts b/apps/review-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts rename to apps/review-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows.ts b/apps/review-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows.ts rename to apps/review-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/backup/common/backup.ts b/apps/review-desktop/code-oss/src/vs/platform/backup/common/backup.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/backup/common/backup.ts rename to apps/review-desktop/code-oss/src/vs/platform/backup/common/backup.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/backup/electron-main/backup.ts b/apps/review-desktop/code-oss/src/vs/platform/backup/electron-main/backup.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/backup/electron-main/backup.ts rename to apps/review-desktop/code-oss/src/vs/platform/backup/electron-main/backup.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/backup/electron-main/backupMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/backup/electron-main/backupMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/backup/electron-main/backupMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/backup/electron-main/backupMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/backup/node/backup.ts b/apps/review-desktop/code-oss/src/vs/platform/backup/node/backup.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/backup/node/backup.ts rename to apps/review-desktop/code-oss/src/vs/platform/backup/node/backup.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserChatToolReferenceNames.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserChatToolReferenceNames.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserChatToolReferenceNames.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserChatToolReferenceNames.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserHistory.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserHistory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserHistory.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserHistory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserPermissions.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserPermissions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserPermissions.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserPermissions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserView.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserView.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserViewGroup.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserViewGroup.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserViewGroup.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserViewGroup.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserViewTelemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserViewTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserViewTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserViewTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserViewUri.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserViewUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/browserViewUri.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/browserViewUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/cdp/proxy.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/cdp/proxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/cdp/proxy.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/cdp/proxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/cdp/types.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/cdp/types.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/cdp/types.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/cdp/types.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/cssHelpers.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/cssHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/cssHelpers.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/cssHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/playwrightService.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/common/playwrightService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/common/playwrightService.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/common/playwrightService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-browser/preload-browserView.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-browser/preload-browserView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-browser/preload-browserView.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-browser/preload-browserView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSession.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSession.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSession.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionHistory.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionHistory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionHistory.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionHistory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionPermissions.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionPermissions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionPermissions.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionPermissions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionRemote.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionRemote.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionRemote.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionRemote.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionTrust.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionTrust.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionTrust.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserSessionTrust.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserView.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserView.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewCDPTarget.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewCDPTarget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewCDPTarget.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewCDPTarget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewDebugger.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewDebugger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewDebugger.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewDebugger.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewEmulator.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewEmulator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewEmulator.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewEmulator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewFrameInspector.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewFrameInspector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewFrameInspector.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewFrameInspector.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroup.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroup.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroup.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroup.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroupMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroupMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroupMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewGroupMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewInspector.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewInspector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewInspector.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewInspector.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/electron-main/browserViewMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/browserViewGroupRemoteService.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/node/browserViewGroupRemoteService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/browserViewGroupRemoteService.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/node/browserViewGroupRemoteService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/playwrightChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/node/playwrightChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/playwrightChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/node/playwrightChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/playwrightService.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/node/playwrightService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/playwrightService.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/node/playwrightService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/playwrightTab.ts b/apps/review-desktop/code-oss/src/vs/platform/browserView/node/playwrightTab.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/browserView/node/playwrightTab.ts rename to apps/review-desktop/code-oss/src/vs/platform/browserView/node/playwrightTab.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/checksum/common/checksumService.ts b/apps/review-desktop/code-oss/src/vs/platform/checksum/common/checksumService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/checksum/common/checksumService.ts rename to apps/review-desktop/code-oss/src/vs/platform/checksum/common/checksumService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/checksum/node/checksumService.ts b/apps/review-desktop/code-oss/src/vs/platform/checksum/node/checksumService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/checksum/node/checksumService.ts rename to apps/review-desktop/code-oss/src/vs/platform/checksum/node/checksumService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/clipboard/common/clipboardService.ts b/apps/review-desktop/code-oss/src/vs/platform/clipboard/common/clipboardService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/clipboard/common/clipboardService.ts rename to apps/review-desktop/code-oss/src/vs/platform/clipboard/common/clipboardService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/commands/common/commands.ts b/apps/review-desktop/code-oss/src/vs/platform/commands/common/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/commands/common/commands.ts rename to apps/review-desktop/code-oss/src/vs/platform/commands/common/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configuration.ts b/apps/review-desktop/code-oss/src/vs/platform/configuration/common/configuration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configuration.ts rename to apps/review-desktop/code-oss/src/vs/platform/configuration/common/configuration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurationModels.ts b/apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurationModels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurationModels.ts rename to apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurationModels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurationRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurationRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurationRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurationRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurationService.ts b/apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurations.ts b/apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/configuration/common/configurations.ts rename to apps/review-desktop/code-oss/src/vs/platform/configuration/common/configurations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/browser/contextKeyService.ts b/apps/review-desktop/code-oss/src/vs/platform/contextkey/browser/contextKeyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/browser/contextKeyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextkey/browser/contextKeyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/common/contextkey.ts b/apps/review-desktop/code-oss/src/vs/platform/contextkey/common/contextkey.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/common/contextkey.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextkey/common/contextkey.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/common/contextkeys.ts b/apps/review-desktop/code-oss/src/vs/platform/contextkey/common/contextkeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/common/contextkeys.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextkey/common/contextkeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/common/scanner.ts b/apps/review-desktop/code-oss/src/vs/platform/contextkey/common/scanner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextkey/common/scanner.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextkey/common/scanner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuService.ts b/apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuService.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextMenuService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextView.ts b/apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextView.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextViewService.ts b/apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextViewService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/contextview/browser/contextViewService.ts rename to apps/review-desktop/code-oss/src/vs/platform/contextview/browser/contextViewService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/cssDev/node/cssDevService.ts b/apps/review-desktop/code-oss/src/vs/platform/cssDev/node/cssDevService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/cssDev/node/cssDevService.ts rename to apps/review-desktop/code-oss/src/vs/platform/cssDev/node/cssDevService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/dataChannel/browser/forwardingTelemetryService.ts b/apps/review-desktop/code-oss/src/vs/platform/dataChannel/browser/forwardingTelemetryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/dataChannel/browser/forwardingTelemetryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/dataChannel/browser/forwardingTelemetryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/dataChannel/common/dataChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/dataChannel/common/dataChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/dataChannel/common/dataChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/dataChannel/common/dataChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebug.ts b/apps/review-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebug.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebug.ts rename to apps/review-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebug.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebugIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebugIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebugIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/debug/common/extensionHostDebugIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/defaultAccount/common/defaultAccount.ts b/apps/review-desktop/code-oss/src/vs/platform/defaultAccount/common/defaultAccount.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/defaultAccount/common/defaultAccount.ts rename to apps/review-desktop/code-oss/src/vs/platform/defaultAccount/common/defaultAccount.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/common/diagnostics.ts b/apps/review-desktop/code-oss/src/vs/platform/diagnostics/common/diagnostics.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/common/diagnostics.ts rename to apps/review-desktop/code-oss/src/vs/platform/diagnostics/common/diagnostics.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/electron-browser/diagnosticsService.ts b/apps/review-desktop/code-oss/src/vs/platform/diagnostics/electron-browser/diagnosticsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/electron-browser/diagnosticsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/diagnostics/electron-browser/diagnosticsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/electron-main/diagnosticsMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/diagnostics/electron-main/diagnosticsMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/electron-main/diagnosticsMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/diagnostics/electron-main/diagnosticsMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/node/diagnosticsService.ts b/apps/review-desktop/code-oss/src/vs/platform/diagnostics/node/diagnosticsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/diagnostics/node/diagnosticsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/diagnostics/node/diagnosticsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/dialogs/common/dialogs.ts b/apps/review-desktop/code-oss/src/vs/platform/dialogs/common/dialogs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/dialogs/common/dialogs.ts rename to apps/review-desktop/code-oss/src/vs/platform/dialogs/common/dialogs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/dialogs/electron-browser/dialog.ts b/apps/review-desktop/code-oss/src/vs/platform/dialogs/electron-browser/dialog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/dialogs/electron-browser/dialog.ts rename to apps/review-desktop/code-oss/src/vs/platform/dialogs/electron-browser/dialog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/dialogs/electron-main/dialogMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/dialogs/electron-main/dialogMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/dialogs/electron-main/dialogMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/dialogs/electron-main/dialogMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/dnd/browser/dnd.ts b/apps/review-desktop/code-oss/src/vs/platform/dnd/browser/dnd.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/dnd/browser/dnd.ts rename to apps/review-desktop/code-oss/src/vs/platform/dnd/browser/dnd.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/download/common/download.ts b/apps/review-desktop/code-oss/src/vs/platform/download/common/download.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/download/common/download.ts rename to apps/review-desktop/code-oss/src/vs/platform/download/common/download.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/download/common/downloadService.ts b/apps/review-desktop/code-oss/src/vs/platform/download/common/downloadService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/download/common/downloadService.ts rename to apps/review-desktop/code-oss/src/vs/platform/download/common/downloadService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/editor/browser/editor.ts b/apps/review-desktop/code-oss/src/vs/platform/editor/browser/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/editor/browser/editor.ts rename to apps/review-desktop/code-oss/src/vs/platform/editor/browser/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/editor/common/editor.ts b/apps/review-desktop/code-oss/src/vs/platform/editor/common/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/editor/common/editor.ts rename to apps/review-desktop/code-oss/src/vs/platform/editor/common/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/encryption/common/encryptionService.ts b/apps/review-desktop/code-oss/src/vs/platform/encryption/common/encryptionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/encryption/common/encryptionService.ts rename to apps/review-desktop/code-oss/src/vs/platform/encryption/common/encryptionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/encryption/electron-main/encryptionMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/encryption/electron-main/encryptionMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/encryption/electron-main/encryptionMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/encryption/electron-main/encryptionMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/endpoint/common/licenseAgreement.ts b/apps/review-desktop/code-oss/src/vs/platform/endpoint/common/licenseAgreement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/endpoint/common/licenseAgreement.ts rename to apps/review-desktop/code-oss/src/vs/platform/endpoint/common/licenseAgreement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/common/argv.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/common/argv.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/common/argv.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/common/argv.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/common/environment.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/common/environment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/common/environment.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/common/environment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/common/environmentService.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/common/environmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/common/environmentService.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/common/environmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/electron-main/environmentMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/electron-main/environmentMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/electron-main/environmentMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/electron-main/environmentMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/argv.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/node/argv.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/argv.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/node/argv.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/argvHelper.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/node/argvHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/argvHelper.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/node/argvHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/environmentService.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/node/environmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/environmentService.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/node/environmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/stdin.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/node/stdin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/stdin.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/node/stdin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/userDataPath.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/node/userDataPath.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/userDataPath.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/node/userDataPath.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/wait.ts b/apps/review-desktop/code-oss/src/vs/platform/environment/node/wait.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/environment/node/wait.ts rename to apps/review-desktop/code-oss/src/vs/platform/environment/node/wait.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/allowedExtensionsService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/allowedExtensionsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/allowedExtensionsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/allowedExtensionsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionEnablementService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionEnablementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionEnablementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionEnablementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifest.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifest.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifest.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestServiceIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestServiceIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestServiceIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryManifestServiceIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionGalleryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagement.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagement.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionManagementUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionNls.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionNls.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionNls.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionNls.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionStorage.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionStorage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionStorage.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionStorage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionTipsService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionTipsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionTipsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionTipsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsScannerService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsScannerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/extensionsScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/implicitActivationEvents.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/implicitActivationEvents.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/implicitActivationEvents.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/implicitActivationEvents.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/electron-browser/extensionsProfileScannerService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/electron-browser/extensionsProfileScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/electron-browser/extensionsProfileScannerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/electron-browser/extensionsProfileScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionDownloader.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionDownloader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionDownloader.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionDownloader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionLifecycle.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionLifecycle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionLifecycle.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionLifecycle.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionManagementUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionSignatureVerificationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionTipsService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionTipsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionTipsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionTipsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsManifestCache.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsManifestCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsManifestCache.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsManifestCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsProfileScannerService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsProfileScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsProfileScannerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsProfileScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsScannerService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsScannerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsWatcher.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsWatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsWatcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionManagement/node/extensionsWatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendations.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendations.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendationsIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendationsIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendationsIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionRecommendations/common/extensionRecommendationsIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoaderService.ts b/apps/review-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoaderService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoaderService.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensionResourceLoader/common/extensionResourceLoaderService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensionHostStarter.ts b/apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensionHostStarter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensionHostStarter.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensionHostStarter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensionValidator.ts b/apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensionValidator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensionValidator.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensionValidator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensions.ts b/apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensions.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensionsApiProposals.ts b/apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensionsApiProposals.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/common/extensionsApiProposals.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensions/common/extensionsApiProposals.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/electron-main/extensionHostStarter.ts b/apps/review-desktop/code-oss/src/vs/platform/extensions/electron-main/extensionHostStarter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/extensions/electron-main/extensionHostStarter.ts rename to apps/review-desktop/code-oss/src/vs/platform/extensions/electron-main/extensionHostStarter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/externalServices/common/marketplace.ts b/apps/review-desktop/code-oss/src/vs/platform/externalServices/common/marketplace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/externalServices/common/marketplace.ts rename to apps/review-desktop/code-oss/src/vs/platform/externalServices/common/marketplace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/externalServices/common/serviceMachineId.ts b/apps/review-desktop/code-oss/src/vs/platform/externalServices/common/serviceMachineId.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/externalServices/common/serviceMachineId.ts rename to apps/review-desktop/code-oss/src/vs/platform/externalServices/common/serviceMachineId.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/externalTerminal/common/externalTerminal.ts b/apps/review-desktop/code-oss/src/vs/platform/externalTerminal/common/externalTerminal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/externalTerminal/common/externalTerminal.ts rename to apps/review-desktop/code-oss/src/vs/platform/externalTerminal/common/externalTerminal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/externalTerminal/electron-main/externalTerminal.ts b/apps/review-desktop/code-oss/src/vs/platform/externalTerminal/electron-main/externalTerminal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/externalTerminal/electron-main/externalTerminal.ts rename to apps/review-desktop/code-oss/src/vs/platform/externalTerminal/electron-main/externalTerminal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/externalTerminal/node/externalTerminalService.ts b/apps/review-desktop/code-oss/src/vs/platform/externalTerminal/node/externalTerminalService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/externalTerminal/node/externalTerminalService.ts rename to apps/review-desktop/code-oss/src/vs/platform/externalTerminal/node/externalTerminalService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/browser/htmlFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/files/browser/htmlFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/browser/htmlFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/browser/htmlFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/browser/webFileSystemAccess.ts b/apps/review-desktop/code-oss/src/vs/platform/files/browser/webFileSystemAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/browser/webFileSystemAccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/browser/webFileSystemAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProviderClient.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProviderClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProviderClient.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/diskFileSystemProviderClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/fileService.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/fileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/fileService.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/fileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/files.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/files.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/files.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/files.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/inMemoryFilesystemProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/inMemoryFilesystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/inMemoryFilesystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/inMemoryFilesystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/io.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/io.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/io.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/io.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/watcher.ts b/apps/review-desktop/code-oss/src/vs/platform/files/common/watcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/common/watcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/common/watcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts b/apps/review-desktop/code-oss/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/electron-main/diskFileSystemProviderServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProviderServer.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProviderServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProviderServer.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/diskFileSystemProviderServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/baseWatcher.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/baseWatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/baseWatcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/baseWatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsClient.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsClient.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcher.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcherClient.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcherClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcherClient.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcherClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcherMain.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcherMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcherMain.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcherMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcherStats.ts b/apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcherStats.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/files/node/watcher/watcherStats.ts rename to apps/review-desktop/code-oss/src/vs/platform/files/node/watcher/watcherStats.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/git/common/localGitService.ts b/apps/review-desktop/code-oss/src/vs/platform/git/common/localGitService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/git/common/localGitService.ts rename to apps/review-desktop/code-oss/src/vs/platform/git/common/localGitService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/git/node/localGitService.ts b/apps/review-desktop/code-oss/src/vs/platform/git/node/localGitService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/git/node/localGitService.ts rename to apps/review-desktop/code-oss/src/vs/platform/git/node/localGitService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/globalKeybindings/electron-main/globalKeybindingsMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/globalKeybindings/electron-main/globalKeybindingsMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/globalKeybindings/electron-main/globalKeybindingsMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/globalKeybindings/electron-main/globalKeybindingsMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/history/browser/contextScopedHistoryWidget.ts b/apps/review-desktop/code-oss/src/vs/platform/history/browser/contextScopedHistoryWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/history/browser/contextScopedHistoryWidget.ts rename to apps/review-desktop/code-oss/src/vs/platform/history/browser/contextScopedHistoryWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/history/browser/historyWidgetKeybindingHint.ts b/apps/review-desktop/code-oss/src/vs/platform/history/browser/historyWidgetKeybindingHint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/history/browser/historyWidgetKeybindingHint.ts rename to apps/review-desktop/code-oss/src/vs/platform/history/browser/historyWidgetKeybindingHint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hover.css b/apps/review-desktop/code-oss/src/vs/platform/hover/browser/hover.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hover.css rename to apps/review-desktop/code-oss/src/vs/platform/hover/browser/hover.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hover.ts b/apps/review-desktop/code-oss/src/vs/platform/hover/browser/hover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hover.ts rename to apps/review-desktop/code-oss/src/vs/platform/hover/browser/hover.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hoverService.ts b/apps/review-desktop/code-oss/src/vs/platform/hover/browser/hoverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hoverService.ts rename to apps/review-desktop/code-oss/src/vs/platform/hover/browser/hoverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hoverWidget.ts b/apps/review-desktop/code-oss/src/vs/platform/hover/browser/hoverWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/hoverWidget.ts rename to apps/review-desktop/code-oss/src/vs/platform/hover/browser/hoverWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/updatableHoverWidget.ts b/apps/review-desktop/code-oss/src/vs/platform/hover/browser/updatableHoverWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/hover/browser/updatableHoverWidget.ts rename to apps/review-desktop/code-oss/src/vs/platform/hover/browser/updatableHoverWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/imageResize/browser/imageResizeService.ts b/apps/review-desktop/code-oss/src/vs/platform/imageResize/browser/imageResizeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/imageResize/browser/imageResizeService.ts rename to apps/review-desktop/code-oss/src/vs/platform/imageResize/browser/imageResizeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/imageResize/common/imageResizeService.ts b/apps/review-desktop/code-oss/src/vs/platform/imageResize/common/imageResizeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/imageResize/common/imageResizeService.ts rename to apps/review-desktop/code-oss/src/vs/platform/imageResize/common/imageResizeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/descriptors.ts b/apps/review-desktop/code-oss/src/vs/platform/instantiation/common/descriptors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/descriptors.ts rename to apps/review-desktop/code-oss/src/vs/platform/instantiation/common/descriptors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/extensions.ts b/apps/review-desktop/code-oss/src/vs/platform/instantiation/common/extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/extensions.ts rename to apps/review-desktop/code-oss/src/vs/platform/instantiation/common/extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/graph.ts b/apps/review-desktop/code-oss/src/vs/platform/instantiation/common/graph.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/graph.ts rename to apps/review-desktop/code-oss/src/vs/platform/instantiation/common/graph.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/instantiation.ts b/apps/review-desktop/code-oss/src/vs/platform/instantiation/common/instantiation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/instantiation.ts rename to apps/review-desktop/code-oss/src/vs/platform/instantiation/common/instantiation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/instantiationService.ts b/apps/review-desktop/code-oss/src/vs/platform/instantiation/common/instantiationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/instantiationService.ts rename to apps/review-desktop/code-oss/src/vs/platform/instantiation/common/instantiationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/serviceCollection.ts b/apps/review-desktop/code-oss/src/vs/platform/instantiation/common/serviceCollection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/instantiation/common/serviceCollection.ts rename to apps/review-desktop/code-oss/src/vs/platform/instantiation/common/serviceCollection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/common/mainProcessService.ts b/apps/review-desktop/code-oss/src/vs/platform/ipc/common/mainProcessService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/common/mainProcessService.ts rename to apps/review-desktop/code-oss/src/vs/platform/ipc/common/mainProcessService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/common/services.ts b/apps/review-desktop/code-oss/src/vs/platform/ipc/common/services.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/common/services.ts rename to apps/review-desktop/code-oss/src/vs/platform/ipc/common/services.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/electron-browser/mainProcessService.ts b/apps/review-desktop/code-oss/src/vs/platform/ipc/electron-browser/mainProcessService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/electron-browser/mainProcessService.ts rename to apps/review-desktop/code-oss/src/vs/platform/ipc/electron-browser/mainProcessService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/electron-browser/services.ts b/apps/review-desktop/code-oss/src/vs/platform/ipc/electron-browser/services.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/ipc/electron-browser/services.ts rename to apps/review-desktop/code-oss/src/vs/platform/ipc/electron-browser/services.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/abstractKeybindingService.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/abstractKeybindingService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/abstractKeybindingService.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/abstractKeybindingService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/baseResolvedKeybinding.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/baseResolvedKeybinding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/baseResolvedKeybinding.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/baseResolvedKeybinding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/keybinding.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/keybinding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/keybinding.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/keybinding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/keybindingResolver.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/keybindingResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/keybindingResolver.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/keybindingResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/keybindingsRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/keybindingsRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/keybindingsRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/keybindingsRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/resolvedKeybindingItem.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/resolvedKeybindingItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/resolvedKeybindingItem.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/resolvedKeybindingItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts b/apps/review-desktop/code-oss/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts rename to apps/review-desktop/code-oss/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardConfig.ts b/apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardConfig.ts rename to apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayout.ts b/apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayout.ts rename to apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayoutService.ts b/apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayoutService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayoutService.ts rename to apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardLayoutService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardMapper.ts b/apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardMapper.ts rename to apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/common/keyboardMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/label/common/label.ts b/apps/review-desktop/code-oss/src/vs/platform/label/common/label.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/label/common/label.ts rename to apps/review-desktop/code-oss/src/vs/platform/label/common/label.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/languagePacks/common/languagePacks.ts b/apps/review-desktop/code-oss/src/vs/platform/languagePacks/common/languagePacks.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/languagePacks/common/languagePacks.ts rename to apps/review-desktop/code-oss/src/vs/platform/languagePacks/common/languagePacks.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/languagePacks/common/localizedStrings.ts b/apps/review-desktop/code-oss/src/vs/platform/languagePacks/common/localizedStrings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/languagePacks/common/localizedStrings.ts rename to apps/review-desktop/code-oss/src/vs/platform/languagePacks/common/localizedStrings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/languagePacks/node/languagePacks.ts b/apps/review-desktop/code-oss/src/vs/platform/languagePacks/node/languagePacks.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/languagePacks/node/languagePacks.ts rename to apps/review-desktop/code-oss/src/vs/platform/languagePacks/node/languagePacks.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/launch/electron-main/launchMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/launch/electron-main/launchMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/launch/electron-main/launchMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/launch/electron-main/launchMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/layout/browser/layoutService.ts b/apps/review-desktop/code-oss/src/vs/platform/layout/browser/layoutService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/layout/browser/layoutService.ts rename to apps/review-desktop/code-oss/src/vs/platform/layout/browser/layoutService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/layout/browser/zIndexRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/layout/browser/zIndexRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/layout/browser/zIndexRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/layout/browser/zIndexRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/lifecycle/common/lifecycle.ts b/apps/review-desktop/code-oss/src/vs/platform/lifecycle/common/lifecycle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/lifecycle/common/lifecycle.ts rename to apps/review-desktop/code-oss/src/vs/platform/lifecycle/common/lifecycle.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/lifecycle/electron-main/lifecycleMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/lifecycle/electron-main/lifecycleMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/lifecycle/electron-main/lifecycleMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/lifecycle/electron-main/lifecycleMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/lifecycle/node/sharedProcessLifecycleService.ts b/apps/review-desktop/code-oss/src/vs/platform/lifecycle/node/sharedProcessLifecycleService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/lifecycle/node/sharedProcessLifecycleService.ts rename to apps/review-desktop/code-oss/src/vs/platform/lifecycle/node/sharedProcessLifecycleService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/list/browser/listService.ts b/apps/review-desktop/code-oss/src/vs/platform/list/browser/listService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/list/browser/listService.ts rename to apps/review-desktop/code-oss/src/vs/platform/list/browser/listService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/browser/log.ts b/apps/review-desktop/code-oss/src/vs/platform/log/browser/log.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/browser/log.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/browser/log.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/bufferLog.ts b/apps/review-desktop/code-oss/src/vs/platform/log/common/bufferLog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/bufferLog.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/common/bufferLog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/log.ts b/apps/review-desktop/code-oss/src/vs/platform/log/common/log.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/log.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/common/log.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/logIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/log/common/logIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/logIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/common/logIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/logService.ts b/apps/review-desktop/code-oss/src/vs/platform/log/common/logService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/common/logService.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/common/logService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/electron-main/logIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/log/electron-main/logIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/electron-main/logIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/electron-main/logIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/electron-main/loggerService.ts b/apps/review-desktop/code-oss/src/vs/platform/log/electron-main/loggerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/electron-main/loggerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/electron-main/loggerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/node/loggerService.ts b/apps/review-desktop/code-oss/src/vs/platform/log/node/loggerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/node/loggerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/node/loggerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/log/node/spdlogLog.ts b/apps/review-desktop/code-oss/src/vs/platform/log/node/spdlogLog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/log/node/spdlogLog.ts rename to apps/review-desktop/code-oss/src/vs/platform/log/node/spdlogLog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/markdown/browser/markdownRenderer.ts b/apps/review-desktop/code-oss/src/vs/platform/markdown/browser/markdownRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/markdown/browser/markdownRenderer.ts rename to apps/review-desktop/code-oss/src/vs/platform/markdown/browser/markdownRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/markers/common/markerService.ts b/apps/review-desktop/code-oss/src/vs/platform/markers/common/markerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/markers/common/markerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/markers/common/markerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/markers/common/markers.ts b/apps/review-desktop/code-oss/src/vs/platform/markers/common/markers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/markers/common/markers.ts rename to apps/review-desktop/code-oss/src/vs/platform/markers/common/markers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/allowedMcpServersService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/allowedMcpServersService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/allowedMcpServersService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/allowedMcpServersService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifest.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifest.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifest.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestServiceIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestServiceIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestServiceIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryManifestServiceIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGalleryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGateway.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGateway.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpGateway.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpGateway.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagement.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagement.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementCli.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementCli.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementCli.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementCli.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpPlatformTypes.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpPlatformTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpPlatformTypes.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpPlatformTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpResourceScannerService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpResourceScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/mcpResourceScannerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/mcpResourceScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocol.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocol.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocolApps.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocolApps.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocolApps.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/modelContextProtocolApps.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/nativeMcpDiscoveryHelper.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/common/nativeMcpDiscoveryHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/common/nativeMcpDiscoveryHelper.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/common/nativeMcpDiscoveryHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewayService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewaySession.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewaySession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewaySession.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpGatewaySession.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpManagementService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/mcpManagementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/node/mcpManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/nativeMcpDiscoveryHelperService.ts b/apps/review-desktop/code-oss/src/vs/platform/mcp/node/nativeMcpDiscoveryHelperService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/mcp/node/nativeMcpDiscoveryHelperService.ts rename to apps/review-desktop/code-oss/src/vs/platform/mcp/node/nativeMcpDiscoveryHelperService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/common/menubar.ts b/apps/review-desktop/code-oss/src/vs/platform/menubar/common/menubar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/common/menubar.ts rename to apps/review-desktop/code-oss/src/vs/platform/menubar/common/menubar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/electron-browser/menubar.ts b/apps/review-desktop/code-oss/src/vs/platform/menubar/electron-browser/menubar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/electron-browser/menubar.ts rename to apps/review-desktop/code-oss/src/vs/platform/menubar/electron-browser/menubar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/electron-main/menubar.ts b/apps/review-desktop/code-oss/src/vs/platform/menubar/electron-main/menubar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/electron-main/menubar.ts rename to apps/review-desktop/code-oss/src/vs/platform/menubar/electron-main/menubar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/electron-main/menubarMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/menubar/electron-main/menubarMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/menubar/electron-main/menubarMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/menubar/electron-main/menubarMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnection.ts b/apps/review-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnection.ts rename to apps/review-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnectionIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnectionIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnectionIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/meteredConnection/common/meteredConnectionIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/electron-browser/meteredConnectionService.ts b/apps/review-desktop/code-oss/src/vs/platform/meteredConnection/electron-browser/meteredConnectionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/electron-browser/meteredConnectionService.ts rename to apps/review-desktop/code-oss/src/vs/platform/meteredConnection/electron-browser/meteredConnectionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionChannel.ts b/apps/review-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionChannel.ts rename to apps/review-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/meteredConnection/electron-main/meteredConnectionMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/native/common/native.ts b/apps/review-desktop/code-oss/src/vs/platform/native/common/native.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/native/common/native.ts rename to apps/review-desktop/code-oss/src/vs/platform/native/common/native.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/native/common/nativeHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/native/common/nativeHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/native/common/nativeHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/native/common/nativeHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/native/electron-main/auth.ts b/apps/review-desktop/code-oss/src/vs/platform/native/electron-main/auth.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/native/electron-main/auth.ts rename to apps/review-desktop/code-oss/src/vs/platform/native/electron-main/auth.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/native/electron-main/nativeHostMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/native/electron-main/nativeHostMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/native/electron-main/nativeHostMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/native/electron-main/nativeHostMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/networkFilter/common/domainMatcher.ts b/apps/review-desktop/code-oss/src/vs/platform/networkFilter/common/domainMatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/networkFilter/common/domainMatcher.ts rename to apps/review-desktop/code-oss/src/vs/platform/networkFilter/common/domainMatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/networkFilter/common/networkFilterService.ts b/apps/review-desktop/code-oss/src/vs/platform/networkFilter/common/networkFilterService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/networkFilter/common/networkFilterService.ts rename to apps/review-desktop/code-oss/src/vs/platform/networkFilter/common/networkFilterService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/networkFilter/common/settings.ts b/apps/review-desktop/code-oss/src/vs/platform/networkFilter/common/settings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/networkFilter/common/settings.ts rename to apps/review-desktop/code-oss/src/vs/platform/networkFilter/common/settings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/notification/common/notification.ts b/apps/review-desktop/code-oss/src/vs/platform/notification/common/notification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/notification/common/notification.ts rename to apps/review-desktop/code-oss/src/vs/platform/notification/common/notification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/observableMemento.ts b/apps/review-desktop/code-oss/src/vs/platform/observable/common/observableMemento.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/observableMemento.ts rename to apps/review-desktop/code-oss/src/vs/platform/observable/common/observableMemento.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/platformObservableUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/observable/common/platformObservableUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/platformObservableUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/observable/common/platformObservableUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/wrapInHotClass.ts b/apps/review-desktop/code-oss/src/vs/platform/observable/common/wrapInHotClass.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/wrapInHotClass.ts rename to apps/review-desktop/code-oss/src/vs/platform/observable/common/wrapInHotClass.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/wrapInReloadableClass.ts b/apps/review-desktop/code-oss/src/vs/platform/observable/common/wrapInReloadableClass.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/observable/common/wrapInReloadableClass.ts rename to apps/review-desktop/code-oss/src/vs/platform/observable/common/wrapInReloadableClass.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/opener/browser/link.css b/apps/review-desktop/code-oss/src/vs/platform/opener/browser/link.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/opener/browser/link.css rename to apps/review-desktop/code-oss/src/vs/platform/opener/browser/link.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/opener/browser/link.ts b/apps/review-desktop/code-oss/src/vs/platform/opener/browser/link.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/opener/browser/link.ts rename to apps/review-desktop/code-oss/src/vs/platform/opener/browser/link.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/opener/common/opener.ts b/apps/review-desktop/code-oss/src/vs/platform/opener/common/opener.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/opener/common/opener.ts rename to apps/review-desktop/code-oss/src/vs/platform/opener/common/opener.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/common/genAiAttributes.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/common/genAiAttributes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/common/genAiAttributes.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/common/genAiAttributes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/common/spanData.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/common/spanData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/common/spanData.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/common/spanData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/localOtlpReceiver.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/localOtlpReceiver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/localOtlpReceiver.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/localOtlpReceiver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonDecode.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonDecode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonDecode.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonDecode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonTypes.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonTypes.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/otlpJsonTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/outboundForwarder.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/outboundForwarder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/otlp/outboundForwarder.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/node/otlp/outboundForwarder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/sqlite/otelSqliteStore.ts b/apps/review-desktop/code-oss/src/vs/platform/otel/node/sqlite/otelSqliteStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/otel/node/sqlite/otelSqliteStore.ts rename to apps/review-desktop/code-oss/src/vs/platform/otel/node/sqlite/otelSqliteStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/copilotManagedSettings.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/copilotManagedSettings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/copilotManagedSettings.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/copilotManagedSettings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsService.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/fileManagedSettingsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/filePolicyService.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/filePolicyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/filePolicyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/filePolicyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/multiplexPolicyService.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/multiplexPolicyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/multiplexPolicyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/multiplexPolicyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/nativeManagedSettingsIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/nativeManagedSettingsIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/nativeManagedSettingsIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/nativeManagedSettingsIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/policy.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/policy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/policy.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/policy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/policyIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/common/policyIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/common/policyIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/common/policyIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/node/nativeManagedSettingsService.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/node/nativeManagedSettingsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/node/nativeManagedSettingsService.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/node/nativeManagedSettingsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/policy/node/nativePolicyService.ts b/apps/review-desktop/code-oss/src/vs/platform/policy/node/nativePolicyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/policy/node/nativePolicyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/policy/node/nativePolicyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/process/common/process.ts b/apps/review-desktop/code-oss/src/vs/platform/process/common/process.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/process/common/process.ts rename to apps/review-desktop/code-oss/src/vs/platform/process/common/process.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/process/electron-main/processMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/process/electron-main/processMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/process/electron-main/processMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/process/electron-main/processMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/product/common/product.ts b/apps/review-desktop/code-oss/src/vs/platform/product/common/product.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/product/common/product.ts rename to apps/review-desktop/code-oss/src/vs/platform/product/common/product.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/product/common/productService.ts b/apps/review-desktop/code-oss/src/vs/platform/product/common/productService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/product/common/productService.ts rename to apps/review-desktop/code-oss/src/vs/platform/product/common/productService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/common/profiling.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/common/profiling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/common/profiling.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/common/profiling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/common/profilingModel.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/common/profilingModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/common/profilingModel.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/common/profilingModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/common/profilingTelemetrySpec.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/common/profilingTelemetrySpec.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/common/profilingTelemetrySpec.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/common/profilingTelemetrySpec.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorker.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorker.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/electron-browser/profileAnalysisWorkerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-main/windowProfiling.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/electron-main/windowProfiling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/electron-main/windowProfiling.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/electron-main/windowProfiling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/node/profilingService.ts b/apps/review-desktop/code-oss/src/vs/platform/profiling/node/profilingService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/profiling/node/profilingService.ts rename to apps/review-desktop/code-oss/src/vs/platform/profiling/node/profilingService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/progress/common/progress.ts b/apps/review-desktop/code-oss/src/vs/platform/progress/common/progress.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/progress/common/progress.ts rename to apps/review-desktop/code-oss/src/vs/platform/progress/common/progress.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/protocol/electron-main/protocol.ts b/apps/review-desktop/code-oss/src/vs/platform/protocol/electron-main/protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/protocol/electron-main/protocol.ts rename to apps/review-desktop/code-oss/src/vs/platform/protocol/electron-main/protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/protocol/electron-main/protocolMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/protocol/electron-main/protocolMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/protocol/electron-main/protocolMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/protocol/electron-main/protocolMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/commandsQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/commandsQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/commandsQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/commandsQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/media/quickInput.css b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/media/quickInput.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/media/quickInput.css rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/media/quickInput.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/pickerQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/pickerQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/pickerQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/pickerQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickAccess.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickAccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInput.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInput.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputActions.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputActions.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputBox.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputBox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputBox.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputBox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputController.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputController.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputList.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputList.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputList.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputService.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputService.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/quickInputUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputDelegate.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputDelegate.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputDelegate.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputDelegate.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTree.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTree.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeAccessibilityProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeAccessibilityProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeAccessibilityProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeAccessibilityProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeController.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeController.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeFilter.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeFilter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeFilter.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeFilter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeRenderer.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeRenderer.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeSorter.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeSorter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeSorter.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickInputTreeSorter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickTree.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickTree.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/browser/tree/quickTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/common/quickAccess.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/common/quickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/common/quickAccess.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/common/quickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/common/quickInput.ts b/apps/review-desktop/code-oss/src/vs/platform/quickinput/common/quickInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/quickinput/common/quickInput.ts rename to apps/review-desktop/code-oss/src/vs/platform/quickinput/common/quickInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/registry/common/platform.ts b/apps/review-desktop/code-oss/src/vs/platform/registry/common/platform.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/registry/common/platform.ts rename to apps/review-desktop/code-oss/src/vs/platform/registry/common/platform.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/browser/browserSocketFactory.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/browser/browserSocketFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/browser/browserSocketFactory.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/browser/browserSocketFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/electronRemoteResources.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/electronRemoteResources.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/electronRemoteResources.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/electronRemoteResources.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/managedSocket.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/managedSocket.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/managedSocket.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/managedSocket.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteAgentConnection.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteAgentConnection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteAgentConnection.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteAgentConnection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteAgentEnvironment.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteAgentEnvironment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteAgentEnvironment.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteAgentEnvironment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteAuthorityResolver.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteAuthorityResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteAuthorityResolver.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteAuthorityResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteExtensionsScanner.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteExtensionsScanner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteExtensionsScanner.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteExtensionsScanner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteHosts.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteHosts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteHosts.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteHosts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteSocketFactoryService.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteSocketFactoryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/remoteSocketFactoryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/remoteSocketFactoryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/sharedProcessTunnelService.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/common/sharedProcessTunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/common/sharedProcessTunnelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/common/sharedProcessTunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/electron-browser/electronRemoteResourceLoader.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/electron-browser/electronRemoteResourceLoader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/electron-browser/electronRemoteResourceLoader.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/electron-browser/electronRemoteResourceLoader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/electron-browser/sharedProcessTunnelService.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/electron-browser/sharedProcessTunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/electron-browser/sharedProcessTunnelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/electron-browser/sharedProcessTunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/node/nodeSocketFactory.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/node/nodeSocketFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/node/nodeSocketFactory.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/node/nodeSocketFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remote/node/wsl.ts b/apps/review-desktop/code-oss/src/vs/platform/remote/node/wsl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remote/node/wsl.ts rename to apps/review-desktop/code-oss/src/vs/platform/remote/node/wsl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remoteTunnel/common/remoteTunnel.ts b/apps/review-desktop/code-oss/src/vs/platform/remoteTunnel/common/remoteTunnel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remoteTunnel/common/remoteTunnel.ts rename to apps/review-desktop/code-oss/src/vs/platform/remoteTunnel/common/remoteTunnel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts b/apps/review-desktop/code-oss/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/remoteTunnel/node/remoteTunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/request/common/request.ts b/apps/review-desktop/code-oss/src/vs/platform/request/common/request.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/request/common/request.ts rename to apps/review-desktop/code-oss/src/vs/platform/request/common/request.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/request/electron-utility/requestService.ts b/apps/review-desktop/code-oss/src/vs/platform/request/electron-utility/requestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/request/electron-utility/requestService.ts rename to apps/review-desktop/code-oss/src/vs/platform/request/electron-utility/requestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/request/node/proxy.ts b/apps/review-desktop/code-oss/src/vs/platform/request/node/proxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/request/node/proxy.ts rename to apps/review-desktop/code-oss/src/vs/platform/request/node/proxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/request/node/requestService.ts b/apps/review-desktop/code-oss/src/vs/platform/request/node/requestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/request/node/requestService.ts rename to apps/review-desktop/code-oss/src/vs/platform/request/node/requestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/sandboxHelperService.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/sandboxHelperService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/sandboxHelperService.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/sandboxHelperService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/settings.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/settings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/settings.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/settings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxCommandRules.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxCommandRules.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxCommandRules.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxCommandRules.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxEngine.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxEngine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxEngine.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxEngine.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxMxcRuntime.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxMxcRuntime.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxMxcRuntime.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxMxcRuntime.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxReadAllowList.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxReadAllowList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxReadAllowList.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxReadAllowList.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxRuntimeConfigurationPerOperation.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxRuntimeConfigurationPerOperation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxRuntimeConfigurationPerOperation.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxRuntimeConfigurationPerOperation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxService.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxService.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/common/terminalSandboxService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/electron-browser/sandboxHelperService.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/electron-browser/sandboxHelperService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/electron-browser/sandboxHelperService.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/electron-browser/sandboxHelperService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/electron-main/sandboxHelperService.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/electron-main/sandboxHelperService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/electron-main/sandboxHelperService.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/electron-main/sandboxHelperService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/node/sandboxHelper.ts b/apps/review-desktop/code-oss/src/vs/platform/sandbox/node/sandboxHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sandbox/node/sandboxHelper.ts rename to apps/review-desktop/code-oss/src/vs/platform/sandbox/node/sandboxHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/secrets/common/secrets.ts b/apps/review-desktop/code-oss/src/vs/platform/secrets/common/secrets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/secrets/common/secrets.ts rename to apps/review-desktop/code-oss/src/vs/platform/secrets/common/secrets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sharedProcess/common/sharedProcess.ts b/apps/review-desktop/code-oss/src/vs/platform/sharedProcess/common/sharedProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sharedProcess/common/sharedProcess.ts rename to apps/review-desktop/code-oss/src/vs/platform/sharedProcess/common/sharedProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts b/apps/review-desktop/code-oss/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts rename to apps/review-desktop/code-oss/src/vs/platform/sharedProcess/electron-main/sharedProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sharedProcess/node/sharedProcess.ts b/apps/review-desktop/code-oss/src/vs/platform/sharedProcess/node/sharedProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sharedProcess/node/sharedProcess.ts rename to apps/review-desktop/code-oss/src/vs/platform/sharedProcess/node/sharedProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/shell/node/shellEnv.ts b/apps/review-desktop/code-oss/src/vs/platform/shell/node/shellEnv.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/shell/node/shellEnv.ts rename to apps/review-desktop/code-oss/src/vs/platform/shell/node/shellEnv.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sign/common/abstractSignService.ts b/apps/review-desktop/code-oss/src/vs/platform/sign/common/abstractSignService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sign/common/abstractSignService.ts rename to apps/review-desktop/code-oss/src/vs/platform/sign/common/abstractSignService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sign/common/sign.ts b/apps/review-desktop/code-oss/src/vs/platform/sign/common/sign.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sign/common/sign.ts rename to apps/review-desktop/code-oss/src/vs/platform/sign/common/sign.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/sign/node/signService.ts b/apps/review-desktop/code-oss/src/vs/platform/sign/node/signService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/sign/node/signService.ts rename to apps/review-desktop/code-oss/src/vs/platform/sign/node/signService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/state/node/state.ts b/apps/review-desktop/code-oss/src/vs/platform/state/node/state.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/state/node/state.ts rename to apps/review-desktop/code-oss/src/vs/platform/state/node/state.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/state/node/stateService.ts b/apps/review-desktop/code-oss/src/vs/platform/state/node/stateService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/state/node/stateService.ts rename to apps/review-desktop/code-oss/src/vs/platform/state/node/stateService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/storage/common/storage.ts b/apps/review-desktop/code-oss/src/vs/platform/storage/common/storage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/storage/common/storage.ts rename to apps/review-desktop/code-oss/src/vs/platform/storage/common/storage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/storage/common/storageIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/storage/common/storageIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/storage/common/storageIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/storage/common/storageIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/storage/common/storageService.ts b/apps/review-desktop/code-oss/src/vs/platform/storage/common/storageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/storage/common/storageService.ts rename to apps/review-desktop/code-oss/src/vs/platform/storage/common/storageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/storage/electron-main/storageIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/storage/electron-main/storageIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/storage/electron-main/storageIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/storage/electron-main/storageIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/storage/electron-main/storageMain.ts b/apps/review-desktop/code-oss/src/vs/platform/storage/electron-main/storageMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/storage/electron-main/storageMain.ts rename to apps/review-desktop/code-oss/src/vs/platform/storage/electron-main/storageMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/storage/electron-main/storageMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/storage/electron-main/storageMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/storage/electron-main/storageMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/storage/electron-main/storageMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/1dsAppender.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/1dsAppender.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/1dsAppender.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/1dsAppender.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/commonProperties.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/commonProperties.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/commonProperties.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/commonProperties.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/errorTelemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/errorTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/errorTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/errorTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/gdprTypings.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/gdprTypings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/gdprTypings.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/gdprTypings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/languageModelToolTelemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/languageModelToolTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/languageModelToolTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/languageModelToolTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryLogAppender.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryLogAppender.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryLogAppender.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryLogAppender.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryService.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/common/telemetryUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/common/telemetryUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/electron-main/errorTelemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/electron-main/errorTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/electron-main/errorTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/electron-main/errorTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/electron-main/telemetryUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/electron-main/telemetryUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/electron-main/telemetryUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/electron-main/telemetryUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/1dsAppender.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/node/1dsAppender.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/1dsAppender.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/node/1dsAppender.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/customEndpointTelemetryService.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/node/customEndpointTelemetryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/customEndpointTelemetryService.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/node/customEndpointTelemetryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/telemetry.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/node/telemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/telemetry.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/node/telemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/telemetryUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/telemetry/node/telemetryUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/telemetry/node/telemetryUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/telemetry/node/telemetryUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/bufferMarkCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/bufferMarkCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/bufferMarkCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/bufferMarkCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/capabilities.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/capabilities.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/capabilities.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/capabilities.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/promptInputModel.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/promptInputModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/promptInputModel.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/promptInputModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/cwdDetectionCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/cwdDetectionCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/cwdDetectionCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/cwdDetectionCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/naiveCwdDetectionCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/naiveCwdDetectionCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/naiveCwdDetectionCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/naiveCwdDetectionCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/partialCommandDetectionCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/partialCommandDetectionCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/partialCommandDetectionCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/partialCommandDetectionCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/promptTypeDetectionCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/promptTypeDetectionCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/promptTypeDetectionCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/promptTypeDetectionCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/shellEnvDetectionCapability.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/shellEnvDetectionCapability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/shellEnvDetectionCapability.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/shellEnvDetectionCapability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/terminalCapabilityStore.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/terminalCapabilityStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/capabilities/terminalCapabilityStore.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/capabilities/terminalCapabilityStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/environmentVariable.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/environmentVariable.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/environmentVariable.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/environmentVariable.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableCollection.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableCollection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableCollection.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableCollection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableShared.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableShared.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableShared.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/environmentVariableShared.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/requestStore.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/requestStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/requestStore.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/requestStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminal.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminal.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalDataBuffering.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalDataBuffering.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalDataBuffering.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalDataBuffering.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalEnvironment.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalEnvironment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalEnvironment.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalEnvironment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalLogService.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalLogService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalLogService.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalLogService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalPlatformConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalProcess.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalProcess.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalProfiles.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalProfiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalProfiles.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalProfiles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalRecorder.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalRecorder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalRecorder.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalRecorder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalStrings.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalStrings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/terminalStrings.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/terminalStrings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/childProcessMonitor.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/childProcessMonitor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/childProcessMonitor.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/childProcessMonitor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/heartbeatService.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/heartbeatService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/heartbeatService.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/heartbeatService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/nodePtyHostStarter.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/nodePtyHostStarter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/nodePtyHostStarter.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/nodePtyHostStarter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyHost.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyHost.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyHostMain.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyHostMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyHostMain.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyHostMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyHostService.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyHostService.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyService.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/ptyService.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/ptyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/autoRepliesContribController.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/autoRepliesContribController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/autoRepliesContribController.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/autoRepliesContribController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/terminalAutoResponder.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/terminalAutoResponder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/terminalAutoResponder.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalContrib/autoReplies/terminalAutoResponder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalEnvironment.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalEnvironment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalEnvironment.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalEnvironment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalProcess.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalProcess.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalProfiles.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalProfiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/terminalProfiles.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/terminalProfiles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/windowsShellHelper.ts b/apps/review-desktop/code-oss/src/vs/platform/terminal/node/windowsShellHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/terminal/node/windowsShellHelper.ts rename to apps/review-desktop/code-oss/src/vs/platform/terminal/node/windowsShellHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/browser/defaultStyles.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/browser/defaultStyles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/browser/defaultStyles.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/browser/defaultStyles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/browser/iconsStyleSheet.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/browser/iconsStyleSheet.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/browser/iconsStyleSheet.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/browser/iconsStyleSheet.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colorRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colorRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colorRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colorRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colorUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colorUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colorUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colorUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/baseColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/baseColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/baseColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/baseColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/chartsColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/chartsColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/chartsColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/chartsColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/editorColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/editorColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/editorColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/editorColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/inputColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/inputColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/inputColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/inputColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/listColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/listColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/listColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/listColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/menuColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/menuColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/menuColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/menuColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/minimapColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/minimapColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/minimapColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/minimapColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/miscColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/miscColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/miscColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/miscColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/quickpickColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/quickpickColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/quickpickColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/quickpickColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/searchColors.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/searchColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/colors/searchColors.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/colors/searchColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/iconRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/iconRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/iconRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/iconRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/sizeRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/sizeRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/sizeRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/sizeRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/sizeUtils.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/sizeUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/sizeUtils.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/sizeUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/sizes/baseSizes.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/sizes/baseSizes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/sizes/baseSizes.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/sizes/baseSizes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/theme.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/theme.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/theme.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/theme.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/themeService.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/themeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/themeService.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/themeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/tokenClassificationRegistry.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/common/tokenClassificationRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/common/tokenClassificationRegistry.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/common/tokenClassificationRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainServiceImpl.ts b/apps/review-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainServiceImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainServiceImpl.ts rename to apps/review-desktop/code-oss/src/vs/platform/theme/electron-main/themeMainServiceImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/common/tunnel.ts b/apps/review-desktop/code-oss/src/vs/platform/tunnel/common/tunnel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/common/tunnel.ts rename to apps/review-desktop/code-oss/src/vs/platform/tunnel/common/tunnel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/common/tunnelProxy.ts b/apps/review-desktop/code-oss/src/vs/platform/tunnel/common/tunnelProxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/common/tunnelProxy.ts rename to apps/review-desktop/code-oss/src/vs/platform/tunnel/common/tunnelProxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/selfSignedCert.ts b/apps/review-desktop/code-oss/src/vs/platform/tunnel/node/selfSignedCert.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/selfSignedCert.ts rename to apps/review-desktop/code-oss/src/vs/platform/tunnel/node/selfSignedCert.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/sharedProcessTunnelService.ts b/apps/review-desktop/code-oss/src/vs/platform/tunnel/node/sharedProcessTunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/sharedProcessTunnelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/tunnel/node/sharedProcessTunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/tunnelProxy.ts b/apps/review-desktop/code-oss/src/vs/platform/tunnel/node/tunnelProxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/tunnelProxy.ts rename to apps/review-desktop/code-oss/src/vs/platform/tunnel/node/tunnelProxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/tunnelService.ts b/apps/review-desktop/code-oss/src/vs/platform/tunnel/node/tunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/tunnel/node/tunnelService.ts rename to apps/review-desktop/code-oss/src/vs/platform/tunnel/node/tunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedo.ts b/apps/review-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedo.ts rename to apps/review-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedoService.ts b/apps/review-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedoService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedoService.ts rename to apps/review-desktop/code-oss/src/vs/platform/undoRedo/common/undoRedoService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/darwinUpdateRecovery.ts b/apps/review-desktop/code-oss/src/vs/platform/update/common/darwinUpdateRecovery.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/darwinUpdateRecovery.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/common/darwinUpdateRecovery.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/update.config.contribution.ts b/apps/review-desktop/code-oss/src/vs/platform/update/common/update.config.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/update.config.contribution.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/common/update.config.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/update.ts b/apps/review-desktop/code-oss/src/vs/platform/update/common/update.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/update.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/common/update.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/updateIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/update/common/updateIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/common/updateIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/common/updateIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/abstractUpdateService.ts b/apps/review-desktop/code-oss/src/vs/platform/update/electron-main/abstractUpdateService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/abstractUpdateService.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/electron-main/abstractUpdateService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.darwin.ts b/apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.darwin.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.linux.ts b/apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.linux.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.snap.ts b/apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.snap.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.snap.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.snap.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.win32.ts b/apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.win32.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/update/electron-main/updateService.win32.ts rename to apps/review-desktop/code-oss/src/vs/platform/update/electron-main/updateService.win32.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentity.ts b/apps/review-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentity.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentity.ts rename to apps/review-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentity.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentityService.ts b/apps/review-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentityService.ts rename to apps/review-desktop/code-oss/src/vs/platform/uriIdentity/common/uriIdentityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/trustedDomains.ts b/apps/review-desktop/code-oss/src/vs/platform/url/common/trustedDomains.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/trustedDomains.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/common/trustedDomains.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/url.ts b/apps/review-desktop/code-oss/src/vs/platform/url/common/url.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/url.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/common/url.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/urlGlob.ts b/apps/review-desktop/code-oss/src/vs/platform/url/common/urlGlob.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/urlGlob.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/common/urlGlob.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/urlIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/url/common/urlIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/urlIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/common/urlIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/urlService.ts b/apps/review-desktop/code-oss/src/vs/platform/url/common/urlService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/common/urlService.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/common/urlService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/electron-main/electronUrlListener.ts b/apps/review-desktop/code-oss/src/vs/platform/url/electron-main/electronUrlListener.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/electron-main/electronUrlListener.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/electron-main/electronUrlListener.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/url/electron-main/url.ts b/apps/review-desktop/code-oss/src/vs/platform/url/electron-main/url.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/url/electron-main/url.ts rename to apps/review-desktop/code-oss/src/vs/platform/url/electron-main/url.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userData/common/fileUserDataProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/userData/common/fileUserDataProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userData/common/fileUserDataProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/userData/common/fileUserDataProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileStorageService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileStorageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileStorageService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/common/userDataProfileStorageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-browser/userDataProfileStorageService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-browser/userDataProfileStorageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-browser/userDataProfileStorageService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-browser/userDataProfileStorageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfileStorageIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfileStorageIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfileStorageIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfileStorageIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfilesHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfilesHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfilesHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/electron-main/userDataProfilesHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfile.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfile.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfileStorageService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfileStorageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfileStorageService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataProfile/node/userDataProfileStorageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/abstractJsonSynchronizer.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/abstractJsonSynchronizer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/abstractJsonSynchronizer.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/abstractJsonSynchronizer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/abstractSynchronizer.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/abstractSynchronizer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/abstractSynchronizer.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/abstractSynchronizer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/content.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/content.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/content.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/content.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/extensionsSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/globalStateSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/ignoredExtensions.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/ignoredExtensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/ignoredExtensions.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/ignoredExtensions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/keybindingsSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/mcpSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/mcpSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/mcpSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/mcpSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/promptsSync/promptsSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/settingsMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/settingsMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/settingsMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/settingsMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/settingsSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/settingsSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/settingsSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/settingsSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/snippetsSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/tasksSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/tasksSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/tasksSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/tasksSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataAutoSyncService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestMerge.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataProfilesManifestSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSync.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSync.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncAccount.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncAccount.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncAccount.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncAccount.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncEnablementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLocalStoreService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLog.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLog.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncLog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncMachines.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncMachines.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncMachines.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncMachines.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncResourceProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncServiceIpc.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/node/userDataAutoSyncService.ts b/apps/review-desktop/code-oss/src/vs/platform/userDataSync/node/userDataAutoSyncService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userDataSync/node/userDataAutoSyncService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userDataSync/node/userDataAutoSyncService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionService.ts b/apps/review-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionService.ts rename to apps/review-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionServiceImpl.ts b/apps/review-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionServiceImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionServiceImpl.ts rename to apps/review-desktop/code-oss/src/vs/platform/userInteraction/browser/userInteractionServiceImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/utilityProcess/common/utilityProcessWorkerService.ts b/apps/review-desktop/code-oss/src/vs/platform/utilityProcess/common/utilityProcessWorkerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/utilityProcess/common/utilityProcessWorkerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/utilityProcess/common/utilityProcessWorkerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts b/apps/review-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts rename to apps/review-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/common/webContentExtractor.ts b/apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/common/webContentExtractor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/common/webContentExtractor.ts rename to apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/common/webContentExtractor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/cdpAccessibilityDomain.ts b/apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/cdpAccessibilityDomain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/cdpAccessibilityDomain.ts rename to apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/cdpAccessibilityDomain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentCache.ts b/apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentCache.ts rename to apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentExtractorService.ts b/apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentExtractorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentExtractorService.ts rename to apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webContentExtractorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webPageLoader.ts b/apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webPageLoader.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webPageLoader.ts rename to apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/electron-main/webPageLoader.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts b/apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts rename to apps/review-desktop/code-oss/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerDescriptor.ts b/apps/review-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerDescriptor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerDescriptor.ts rename to apps/review-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerDescriptor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerService.ts b/apps/review-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerServiceImpl.ts b/apps/review-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerServiceImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerServiceImpl.ts rename to apps/review-desktop/code-oss/src/vs/platform/webWorker/browser/webWorkerServiceImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webview/common/mimeTypes.ts b/apps/review-desktop/code-oss/src/vs/platform/webview/common/mimeTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webview/common/mimeTypes.ts rename to apps/review-desktop/code-oss/src/vs/platform/webview/common/mimeTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webview/common/webviewManagerService.ts b/apps/review-desktop/code-oss/src/vs/platform/webview/common/webviewManagerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webview/common/webviewManagerService.ts rename to apps/review-desktop/code-oss/src/vs/platform/webview/common/webviewManagerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webview/common/webviewPortMapping.ts b/apps/review-desktop/code-oss/src/vs/platform/webview/common/webviewPortMapping.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webview/common/webviewPortMapping.ts rename to apps/review-desktop/code-oss/src/vs/platform/webview/common/webviewPortMapping.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webview/electron-main/webviewMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/webview/electron-main/webviewMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webview/electron-main/webviewMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/webview/electron-main/webviewMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts b/apps/review-desktop/code-oss/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts rename to apps/review-desktop/code-oss/src/vs/platform/webview/electron-main/webviewProtocolProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/window/common/window.ts b/apps/review-desktop/code-oss/src/vs/platform/window/common/window.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/window/common/window.ts rename to apps/review-desktop/code-oss/src/vs/platform/window/common/window.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/window/electron-browser/window.ts b/apps/review-desktop/code-oss/src/vs/platform/window/electron-browser/window.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/window/electron-browser/window.ts rename to apps/review-desktop/code-oss/src/vs/platform/window/electron-browser/window.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/window/electron-main/window.ts b/apps/review-desktop/code-oss/src/vs/platform/window/electron-main/window.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/window/electron-main/window.ts rename to apps/review-desktop/code-oss/src/vs/platform/window/electron-main/window.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowImpl.ts b/apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowImpl.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowImpl.ts rename to apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowImpl.ts index 6c8739830..cb98fa264 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowImpl.ts @@ -46,7 +46,7 @@ import { IInstantiationService } from '../../instantiation/common/instantiation. import { VSBuffer } from '../../../base/common/buffer.js'; import { errorHandler } from '../../../base/common/errors.js'; import { FocusMode } from '../../native/common/native.js'; -import { whiteboardBackgroundLaunch } from '../../../whiteboard/electron-main/whiteboardBackgroundLaunch.js'; +import { reviewBackgroundLaunch } from '../../../review/electron-main/reviewBackgroundLaunch.js'; import { Color } from '../../../base/common/color.js'; export interface IWindowCreationOptions { @@ -303,7 +303,7 @@ export abstract class BaseWindow extends Disposable implements IBaseWindow { // to reduce flicker from the default window size // to maximize or fullscreen, we only show after - whiteboardBackgroundLaunch.show(this._win); + reviewBackgroundLaunch.show(this._win); } } @@ -345,7 +345,7 @@ export abstract class BaseWindow extends Disposable implements IBaseWindow { focus(options?: { mode: FocusMode }): void { const mode = options?.mode ?? FocusMode.Transfer; - if (!whiteboardBackgroundLaunch.allowsFocus(mode)) { + if (!reviewBackgroundLaunch.allowsFocus(mode)) { return; } @@ -719,7 +719,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { } const options = instantiationService.invokeFunction(defaultBrowserWindowOptions, this.windowState, undefined, webPreferences); - whiteboardBackgroundLaunch.prepare(options); + reviewBackgroundLaunch.prepare(options); // Create the browser window mark('code/willCreateCodeBrowserWindow'); @@ -728,7 +728,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { this._id = this._win.id; this.setWin(this._win, options); - whiteboardBackgroundLaunch.attach(this._win); + reviewBackgroundLaunch.attach(this._win); // Apply some state after window creation this.applyState(this.windowState, hasMultipleDisplays); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windows.ts b/apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windows.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windows.ts rename to apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windows.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowsFinder.ts b/apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowsFinder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowsFinder.ts rename to apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowsFinder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowsMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowsMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowsMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowsMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowsStateHandler.ts b/apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowsStateHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/windows/electron-main/windowsStateHandler.ts rename to apps/review-desktop/code-oss/src/vs/platform/windows/electron-main/windowsStateHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/windows/node/windowTracker.ts b/apps/review-desktop/code-oss/src/vs/platform/windows/node/windowTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/windows/node/windowTracker.ts rename to apps/review-desktop/code-oss/src/vs/platform/windows/node/windowTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/canonicalUri.ts b/apps/review-desktop/code-oss/src/vs/platform/workspace/common/canonicalUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/canonicalUri.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspace/common/canonicalUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/editSessions.ts b/apps/review-desktop/code-oss/src/vs/platform/workspace/common/editSessions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/editSessions.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspace/common/editSessions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/virtualWorkspace.ts b/apps/review-desktop/code-oss/src/vs/platform/workspace/common/virtualWorkspace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/virtualWorkspace.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspace/common/virtualWorkspace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/workspace.ts b/apps/review-desktop/code-oss/src/vs/platform/workspace/common/workspace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/workspace.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspace/common/workspace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/workspaceTrust.ts b/apps/review-desktop/code-oss/src/vs/platform/workspace/common/workspaceTrust.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspace/common/workspaceTrust.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspace/common/workspaceTrust.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/common/workspaceIdentifier.ts b/apps/review-desktop/code-oss/src/vs/platform/workspaces/common/workspaceIdentifier.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/common/workspaceIdentifier.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspaces/common/workspaceIdentifier.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/common/workspaces.ts b/apps/review-desktop/code-oss/src/vs/platform/workspaces/common/workspaces.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/common/workspaces.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspaces/common/workspaces.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesHistoryMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts b/apps/review-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/node/workspaces.ts b/apps/review-desktop/code-oss/src/vs/platform/workspaces/node/workspaces.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/platform/workspaces/node/workspaces.ts rename to apps/review-desktop/code-oss/src/vs/platform/workspaces/node/workspaces.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-dark.svg b/apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-dark.svg rename to apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-hc-dark.svg b/apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-hc-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-hc-dark.svg rename to apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-hc-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-hc-light.svg b/apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-hc-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-hc-light.svg rename to apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-hc-light.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-light.svg b/apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-light.svg rename to apps/review-desktop/code-oss/src/vs/review/browser/media/review-letterpress-light.svg diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/media/review.css b/apps/review-desktop/code-oss/src/vs/review/browser/media/review.css new file mode 100644 index 000000000..140307e09 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/media/review.css @@ -0,0 +1,1249 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/* The workbench grid reserves a bottom gutter (`gutterBottom` in + review/browser/workbench.ts), so a strip of the workbench root stays exposed + below the editor. Without this rule it falls through to the stock + WORKBENCH_BACKGROUND (#252526 on dark) and reads as a band under the canvas. */ +.monaco-workbench.review-workbench { + background: var(--vscode-editor-background); +} + +.monaco-workbench.review-workbench.nomaineditorarea { + background-image: url("./review-letterpress-light.svg"); + background-position: center; + background-repeat: no-repeat; + background-size: 260px 260px; +} + +.monaco-workbench.review-workbench.nomaineditorarea.vs-dark { + background-image: url("./review-letterpress-dark.svg"); +} + +.monaco-workbench.review-workbench.nomaineditorarea.hc-light { + background-image: url("./review-letterpress-hc-light.svg"); +} + +.monaco-workbench.review-workbench.nomaineditorarea.hc-black { + background-image: url("./review-letterpress-hc-dark.svg"); +} + +/* KEEP IN SYNC WITH REVIEW_CHROME_HEIGHT in review/common/reviewChrome.ts. The + overlay must be as tall as the editor tab strip below it, or the window + controls and the navigation arrows stop aligning with the tab pills. */ +.monaco-workbench .part.titlebar.review-chrome-overlay { + position: absolute; + top: 0; + left: 0; + z-index: 100; + width: 100%; + height: 40px; + box-shadow: none; + pointer-events: none; + background: transparent; +} + +.monaco-workbench + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-left, +.monaco-workbench + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-right { + width: max-content !important; + min-width: 0; + flex: 0 0 auto !important; + padding-left: 0 !important; + pointer-events: auto; +} + +.monaco-workbench.linux + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-right { + margin-left: auto; +} + +/* The native macOS stoplights sit over the left container. Make its unused + area draggable, including the space between and around the stoplights. The + navigation control below removes itself from this drag region. */ +.monaco-workbench + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-left { + -webkit-app-region: drag; +} + +.monaco-workbench + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-right { + -webkit-app-region: no-drag; +} + +.monaco-workbench + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-drag-region { + left: var(--review-chrome-left-width, 0px); + right: var(--review-chrome-right-width, 0px); + width: auto; + display: none; + pointer-events: none; +} + +.monaco-workbench.nomaineditorarea + .part.titlebar.review-chrome-overlay + > .review-titlebar-container + > .titlebar-drag-region { + display: block; + pointer-events: auto; + -webkit-app-region: drag; +} + +.monaco-workbench + .part.editor + .editor-group-container + > .title + > .tabs-and-actions-container.review-chrome-tab-strip { + box-sizing: border-box; + padding-left: 6px; + padding-right: 6px; + user-select: none; + -webkit-app-region: drag; +} + +.monaco-workbench.review-tab-dragging + .part.editor + .editor-group-container + > .title + > .tabs-and-actions-container.review-chrome-tab-strip { + -webkit-app-region: no-drag; +} + +.monaco-workbench + .part.editor + .tabs-and-actions-container.review-chrome-tab-strip + .tabs-container { + -webkit-app-region: drag; +} + +.monaco-workbench.review-tab-dragging + .part.editor + .tabs-and-actions-container.review-chrome-tab-strip + .tabs-container { + -webkit-app-region: no-drag; +} + +.monaco-workbench + .part.editor + .editor-group-container + > .title + > .tabs-and-actions-container.review-chrome-inset { + padding-left: calc(var(--review-chrome-left-width, 0px) + 6px); + padding-right: calc(var(--review-chrome-right-width, 0px) + 6px); +} + +.monaco-workbench .part.editor .tabs-container > .tab, +.monaco-workbench .part.editor .tabs-container > .tabs-bar-add-tab, +.monaco-workbench .part.editor .tabs-and-actions-container > .editor-actions, +.monaco-workbench .part.editor .tabs-and-actions-container > .editor-layout-actions, +.monaco-workbench + .part.editor + .tabs-and-actions-container + > .monaco-scrollable-element + > .scrollbar { + -webkit-app-region: no-drag; +} + +/* --------------------------------------------------------------------------- + Review file explorer + + The explorer is the leftmost surface whenever it is visible, so the window + controls and the navigation arrows sit over its top row instead of over the + editor tab strip. Two rules follow from that: the explorer reserves one chrome + row for them, and the tab strip drops the traffic-light inset it would + otherwise need. + --------------------------------------------------------------------------- */ + +/* The grid sizes the `.split-view-view` wrapper, not the part inside it, and the + part is a static block. Without this the part grows to the list's content + height, the list never scrolls, and every row renders. */ +.monaco-workbench .part.review-explorer { + display: flex; + flex-direction: column; + height: 100%; + background-color: var(--vscode-editor-background); + /* An inset shadow rather than a border, so the tree keeps the full part width + and `ReviewExplorerPart.layout` needs no separator correction. */ + box-shadow: inset -1px 0 0 + var(--vscode-panel-border, var(--vscode-sideBar-border, transparent)); + overflow: hidden; +} + +/* The one chrome row keeps the editor tab-strip background, so the top of the + window reads as a single bar running across the tree and the tabs. The step + from that background down to the tree is the whole divider — deliberately no + bottom rule. + + A 1px rule here would be the only horizontal line at this edge: the editor tab + strip ends at the same y with no border and no shadow, because the Review pill + tabs carry no separators by design (see the pill-tab section below). A line on + just the tree half stops dead at the sash and reads as an unfinished stub. + + `ReviewExplorerPart` writes `--review-chrome-height` on this part and the + workbench layout writes `--review-explorer-width` on the inset tab strip + (never on the workbench root; see `publishReviewChromeInset`), so + REVIEW_CHROME_HEIGHT stays the only source. The fallbacks cover the frame + before the part first lays out. */ +.monaco-workbench .part.review-explorer > .review-explorer-chrome-spacer { + box-sizing: border-box; + height: var(--review-chrome-height, 40px); + flex-shrink: 0; + background-color: var(--vscode-editorGroupHeader-tabsBackground); + user-select: none; + -webkit-app-region: drag; +} + +/* Flex rather than `calc(100% - )`: the row above is the only fixed + height, so the tree takes whatever is left and the height is written once. */ +.monaco-workbench .part.review-explorer > .review-explorer-tree { + flex: 1; + min-height: 0; +} + +/* --------------------------------------------------------------------------- + The file-tree toggle + + The button always occupies its 22px slot, so the titlebar's left cluster keeps + a constant width. That matters because a ResizeObserver on the cluster feeds + `--review-chrome-left-width`, which the editor tab strip pads itself by — a + button that grew from 0 would slide every tab as it appeared. Only opacity and + transform animate here, so nothing reflows. + --------------------------------------------------------------------------- */ + +.monaco-workbench .review-titlebar-file-tree-toggle { + display: flex; + align-items: center; + justify-content: center; + width: 22px; + height: 22px; + margin-left: 4px; + border-radius: 5px; + flex-shrink: 0; + color: var(--vscode-icon-foreground); + /* Nothing to toggle until a file or diff tab is active. */ + opacity: 0; + transform: scale(0.8); + pointer-events: none; + /* The cluster around it drags the window; this button must not. */ + -webkit-app-region: no-drag; +} + +.monaco-workbench.review-explorer-available .review-titlebar-file-tree-toggle { + opacity: 1; + transform: none; + pointer-events: auto; + cursor: pointer; +} + +/* Reduced motion gets a straight cut: `monaco-enable-motion` is absent then, + because accessibility/browser/accessibilityService.ts toggles it from + `workbench.reduceMotion`. */ +.monaco-workbench.monaco-enable-motion .review-titlebar-file-tree-toggle { + transition: + opacity 120ms ease, + transform 120ms ease; +} + +.monaco-workbench .review-titlebar-file-tree-toggle:hover { + background-color: var(--vscode-toolbar-hoverBackground); +} + +.monaco-workbench .review-titlebar-file-tree-toggle:focus-visible { + outline: 1px solid var(--vscode-focusBorder); + outline-offset: -1px; +} + +/* One icon per state, picked here so the titlebar part needs no explorer state. */ +.monaco-workbench .review-titlebar-file-tree-toggle > .review-file-tree-icon-open, +.monaco-workbench.review-explorer-visible + .review-titlebar-file-tree-toggle + > .review-file-tree-icon-closed { + display: none; +} + +.monaco-workbench.review-explorer-visible + .review-titlebar-file-tree-toggle + > .review-file-tree-icon-open { + display: block; +} + +/* The tab strip pads itself past the traffic lights and the navigation arrows, + which is correct only while the editor is the leftmost surface. The tree now + covers that chrome, so the strip only has to clear whatever the tree does NOT + cover — subtract the tree's width rather than assuming it covers all of it. + + A flat `6px` would be wrong whenever the left cluster is wider than the tree. + The cluster counter-zooms (see `ReviewTitlebarPart.layout`), so zooming the + window out grows it in CSS pixels until it passes even the tree's 170px + minimum, and it would then sit over the first tab and swallow clicks as window + drags. `max()` keeps the plain 6px gutter in the normal case. */ +.monaco-workbench.review-explorer-visible + .part.editor + .editor-group-container + > .title + > .tabs-and-actions-container.review-chrome-inset { + padding-left: max( + 6px, + calc( + var(--review-chrome-left-width, 0px) + 6px - + var(--review-explorer-width, 0px) + ) + ); +} + +/* --------------------------------------------------------------------------- + Review pill tabs + + The tab row keeps the titlebar background and carries no separators, no + bottom border, and no per-tab top-border indicator. The active tab is a + raised pill. The other tabs are flat. + + Each rule below starts with `body` because it must outrank an upstream rule + of the same class count in multieditortabscontrol.css. + --------------------------------------------------------------------------- */ + +.monaco-workbench.review-workbench { + /* Each pill color mixes over the tab-strip background, so a theme change + carries into the pill. */ + /* Whiteboard: the active tab is a board-colored pill with a hairline, the + same surface and rule the canvas uses, so the tab reads as a piece of the + board lifted onto the tray. No drop shadow in either theme. */ + --review-tab-fill: var(--vscode-editor-background); + --review-tab-border: var(--vscode-panel-border); + --review-tab-hover-fill: color-mix( + in srgb, + #ffffff 4%, + var(--vscode-editorGroupHeader-tabsBackground) + ); + --review-tab-separator: var(--vscode-panel-border); + --review-tab-shadow: none; + --review-chrome-font: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, + monospace; +} + +/* The light themes use weaker mixes, so the pill stays subtle. */ +.monaco-workbench.review-workbench.vs, +.monaco-workbench.review-workbench.hc-light { + --review-tab-fill: var(--vscode-editor-background); + --review-tab-border: var(--vscode-panel-border); + --review-tab-hover-fill: color-mix( + in srgb, + #ffffff 40%, + var(--vscode-editorGroupHeader-tabsBackground) + ); + --review-tab-separator: var(--vscode-panel-border); + --review-tab-shadow: none; +} + +/* 28px pill + 6px above + 6px below = the 40px row. EditorTabsControl reports + the same 40px through EDITOR_TAB_HEIGHT.review. The tab-height variable is + an inline style on `.title`, so this rule redeclares it one level down. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + > .tabs-and-actions-container { + --editor-group-tab-height: 28px; + padding-top: 6px; + padding-bottom: 6px; +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title.compact-height + > .tabs-and-actions-container { + --editor-group-tab-height: 20px; +} + +/* No bottom border below the row. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title.title-border-bottom::after, +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + > .tabs-and-actions-container.tabs-border-bottom::after { + display: none; +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container { + gap: 4px; +} + +/* Flat by default. `redrawTabBorders` writes the separator as an inline + `border-right`, so only `!important` removes it. + + The pill carries no border at all: a 1px border would leave a 22px content + box inside the 24px tab, and the label line is `--editor-group-tab-height` + tall, so the icon and the name would sit 1px below the center. The active + pill draws its outline as an inset shadow instead, which costs no layout. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab { + border: none !important; + border-radius: 6px; + background-color: transparent; + box-shadow: none; + /* The whole inset. Upstream pads 10px on the left and nothing on the right, + which reads wider than the Paper design. */ + padding-left: 4px; + padding-right: 4px; +} + +/* Upstream shrinking tabs keep the label at its natural width, clip its flex + parent, and paint a gradient over the clipped edge. That treatment assumes + flat tabs. Inside Review's raised pill it becomes a dark block, and changing + only `text-overflow` cannot produce an ellipsis because the label itself + never gets narrower. + + Give the label the pill's available width instead. The browser then draws an + ellipsis only when the text is actually clipped. Remove the upstream + gradient in every tab state; theme rules can still assign its background, + but the pseudo-element has no box to paint. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab:is(.sizing-shrink, .sizing-fixed) + > .monaco-icon-label + > .monaco-icon-label-container { + flex: 1 1 auto; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab:is(.sizing-shrink, .sizing-fixed) + .monaco-icon-label-container::after { + content: none; + display: none; +} + +/* The raised pill. The first shadow is the 1px outline. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab.active { + background-color: var(--review-tab-fill); + box-shadow: + inset 0 0 0 1px var(--review-tab-border), + var(--review-tab-shadow); +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab:hover:not(.active) { + background-color: var(--review-tab-hover-fill); + box-shadow: none; +} + +/* The close button carries three insets of its own: a 28px column, a 16px + button centered in it, and 2px of padding around the glyph. Together they put + the glyph 10px inside the pill while the icon on the left sits at 4px. The + column hugs the glyph instead, so both sides read the same. The vertical + padding stays, so the hit target keeps its height. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab + > .tab-actions, +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab + > .tab-actions + > .monaco-action-bar { + width: 16px; +} + +/* The 28px column also held the gap after the name. Restore it as the 6px the + icon puts between itself and the name. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab + > .tab-actions { + margin-left: 6px; +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab + > .tab-actions + .action-label.codicon { + padding: 2px 0; +} + +/* Home carries no close button, but `sizing-fit` still stretches it to a fixed + 120px. That leaves ~30px of dead space on each side of the home icon and the + name, which reads as an off-center label. The pill hugs them instead. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab.sticky { + width: fit-content; +} + +/* Home is the one sticky tab, so it is always the last one before the review + tabs. A rule after it separates the two groups. `redrawTabBorders` draws that + rule as an inline border-right, which the flat rule above removes, so the + pseudo-element below draws it instead. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab.sticky:not(:last-child) { + margin-right: 8px; +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab.sticky:not(:last-child)::after { + content: ""; + position: absolute; + right: -7px; + top: 4px; + bottom: 4px; + width: 1px; + pointer-events: none; + background-color: var(--review-tab-separator); +} + +body + .monaco-workbench + .part.editor + > .content + .editor-group-container + > .editor-group-watermark-wrapper + .editor-group-watermark + .letterpress { + background-image: url("./review-letterpress-light.svg"); +} + +body + .monaco-workbench.vs-dark + .part.editor + > .content + .editor-group-container + .editor-group-watermark + .letterpress { + background-image: url("./review-letterpress-dark.svg"); +} + +body + .monaco-workbench.hc-light + .part.editor + > .content + .editor-group-container + .editor-group-watermark + .letterpress { + background-image: url("./review-letterpress-hc-light.svg"); +} + +body + .monaco-workbench.hc-black + .part.editor + > .content + .editor-group-container + .editor-group-watermark + .letterpress { + background-image: url("./review-letterpress-hc-dark.svg"); +} + +.monaco-workbench + .part.titlebar.review-chrome-overlay + .review-titlebar-container + .review-traffic-light-inset { + flex-shrink: 0; + -webkit-app-region: drag; +} + +/* The navigation control sits in .titlebar-left, after the traffic lights. + titlebarpart.css scopes every .command-center rule to `.titlebar-center > + .window-title >`, so the rules below restate the ones that still apply here. + The margin is the gap from the traffic lights. It is also the only left + padding in macOS fullscreen, where the inset collapses to zero. */ +.review-titlebar-container .review-titlebar-navigation { + display: flex; + align-items: center; + flex: 0 0 auto; + font-size: 12px; + margin-left: 8px; +} + +.review-titlebar-container .review-application-menu { + display: flex; + align-items: center; + justify-content: center; + align-self: center; + width: 30px; + height: 28px; + margin-left: 6px; + padding: 0; + border: 0; + border-radius: 4px; + color: inherit; + background: transparent; + cursor: pointer; + -webkit-app-region: no-drag; +} + +.review-titlebar-container .review-application-menu:hover { + background: var(--vscode-toolbar-hoverBackground); +} + +.review-titlebar-container .review-application-menu:focus-visible, +.review-titlebar-container .window-controls-container > button:focus-visible { + outline: 1px solid var(--vscode-focusBorder); + outline-offset: -2px; +} + +.review-titlebar-container .window-controls-container > button { + padding: 0; + border: 0; + background: transparent; + -webkit-app-region: no-drag; +} + +/* Equal space on each side of the arrows. + + `CodeWindow.updateWindowControls` moves the traffic lights itself: it calls + `setWindowButtonPosition({ x: floor((REVIEW_CHROME_HEIGHT - buttonHeight) / 2) + 1 })`. + At 40px with the 14px macOS Tahoe button that is x=14, and three 14px buttons + on the 20px macOS pitch end at 68. Change REVIEW_CHROME_HEIGHT and that + number moves. + + The arrow glyph carries 2px of side bearing inside its box, so the back arrow + starts drawing 19px after the last light. On the other side the tab strip + adds 6px of its own (`.review-chrome-inset`), so 8px here lands the Home tab + 19px after the forward arrow draws. */ +.monaco-workbench + .part.titlebar.review-chrome-overlay + .review-titlebar-navigation { + margin-left: 12px; + margin-right: 8px; +} + +/* Without no-drag the full-size .titlebar-drag-region takes the clicks and the + arrows stop working. */ +.review-titlebar-container .review-titlebar-navigation > .command-center { + z-index: 2500; + -webkit-app-region: no-drag; +} + +.review-titlebar-container .review-titlebar-navigation > .command-center.hide { + visibility: hidden; +} + +.review-titlebar-container + .review-titlebar-navigation + > .command-center + > .monaco-toolbar + > .monaco-action-bar + > .actions-container + > .action-item + > .action-label { + color: inherit; +} + +.review-canvas-part, +.review-canvas-part > .review-canvas-container, +.review-canvas-part .review-canvas-host { + width: 100%; + height: 100%; +} + +/* The canvas topbar dresses itself as workbench chrome and reads its colors and + its type ramp straight from the --vscode-* theme variables, but there is no + such variable for the workbench UI font: style.css hardcodes a stack per + platform and per language. `system-ui` resolves to the same platform UI face + without copying that matrix. The selector outranks the canvas stylesheet's own + default, which keeps the standalone browser build on its mono face. Every text + item in the topbar reads this token, so the bar shows one face throughout. */ +.review-canvas-host .review-app { + --chrome-font: var(--review-chrome-font, var(--font-mono)); +} + +/* Whiteboard: every label on the tray is set in the same mono face as the + canvas chrome. The faces ship with the canvas stylesheet, whose @font-face + rules are hoisted out of its @scope so they apply document-wide. */ +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab + .monaco-icon-label { + font-family: var(--review-chrome-font); + font-size: 12px; +} + +body + .monaco-workbench.review-workbench + .part.editor + > .content + .editor-group-container + > .title + .tabs-container + > .tab.active + .monaco-icon-label { + font-weight: 600; +} + +/* Multi-diff headers print a full Review path in one label. Keep the file name + visible in narrow panes by placing the ellipsis at the leading edge. */ +.review-path-label .monaco-icon-label-container { + direction: rtl; + text-align: left; +} + +.review-path-label .label-name { + unicode-bidi: plaintext; +} + +.review-multidiff-counts { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 0 4px; + font-size: 12px; + font-variant-numeric: tabular-nums; +} + +.review-multidiff-counts[hidden] { + display: none; +} + +.review-multidiff-additions { + color: var(--vscode-gitDecoration-addedResourceForeground); +} + +.review-multidiff-deletions { + color: var(--vscode-gitDecoration-deletedResourceForeground); +} + +.review-counts-folded .review-multidiff-additions { + color: var(--vscode-descriptionForeground); +} + +.review-multidiff-open-container { + display: inline-flex; + align-items: center; + margin: 0 3px; +} + +.review-multidiff-open-container[hidden] { + display: none; +} + +.review-multidiff-open.monaco-button { + display: inline-flex; + align-items: center; + gap: 6px; + width: auto; + min-width: 0; + height: 24px; + line-height: 22px; + padding: 0 9px; + border: 1px solid color-mix(in srgb, var(--vscode-icon-foreground) 20%, transparent); + border-radius: 5px; + background: color-mix(in srgb, var(--vscode-icon-foreground) 5%, transparent); + color: var(--vscode-icon-foreground); + font-size: 12px; + white-space: nowrap; +} + +.review-multidiff-open.monaco-button .codicon[class*="codicon-"] { + margin: 0; + font-size: 13px; +} + +.review-multidiff-open.monaco-button:hover { + background: var(--vscode-toolbar-hoverBackground); +} + +.review-files-editor, +.review-files-editor-tree, +.review-files-editor-diffs { + min-width: 0; + min-height: 0; + height: 100%; +} + +.review-files-editor { + width: 100%; + overflow: hidden; + background: var(--vscode-editor-background); +} + +/* The sidebar is one tray from the progress line to the last file: the tree + paints no ground of its own and inherits the tray behind it (see the + "Sidebar tone" board). Hover and selection come from the theme's list + colors, the well and the marker tint. */ +.review-files-editor-tree { + border-right: 1px solid var(--vscode-sideBar-border, transparent); +} + +.review-changed-files { + box-sizing: border-box; + display: flex; + flex-direction: column; + height: 100%; + min-height: 0; + font-family: var(--review-chrome-font, system-ui, sans-serif); +} + +.review-changed-files-tree { + flex: 1 1 auto; + min-height: 0; +} + +.review-changed-files-row { + box-sizing: border-box; + display: flex; + align-items: center; + gap: 6px; + height: 22px; + padding-right: 8px; +} + +.review-changed-files-icon { + flex: 0 0 16px; + width: 16px; + color: var(--vscode-icon-foreground); + text-align: center; +} + +.review-changed-files-label { + flex: 1 1 auto; + min-width: 0; + overflow: hidden; + font-weight: 400; + text-overflow: ellipsis; + white-space: nowrap; +} + +.review-changed-files-folder .review-changed-files-label { + margin-left: 7px; + font-weight: 600; +} + +.review-files-editor-diffs { + position: relative; + min-width: 0; + min-height: 0; + overflow: hidden; + background: var(--vscode-multiDiffEditor-background); +} + +.review-files-editor-diffs + .monaco-component.multiDiffEditor + .multiDiffEntry + > .header + > .header-content { + margin-top: 0; +} + +.review-files-editor-diffs + .monaco-component.multiDiffEditor + .multiDiffEntry + > .header + > .header-content + .file-path + .title { + font-size: 12px; +} + +.review-files-editor-diffs + .monaco-component.multiDiffEditor + .multiDiffEntry + > .header + > .header-content + > .actions { + padding: 0; +} + +.review-files-editor-diffs + .multiDiffEntry + > .header + > .header-content + > .actions.has-no-actions { + display: none; +} + +.review-canvas-part > .review-canvas-container { + display: grid; + grid-template-rows: minmax(0, 1fr); + overflow: hidden; +} + +.review-canvas-part .review-canvas-host { + position: relative; + min-height: 0; + overflow: hidden; + background: var(--vscode-editor-background); + -webkit-user-select: text; + user-select: text; +} + +/* Hosts fixedOverflowWidgets (hover, definition) for the inline peek editors. + Lives in the workbench container — inside .monaco-workbench so theme + variables apply, outside .review-canvas-root whose container-query + containment would re-anchor and clip position: fixed widgets. The widgets + position themselves against the viewport; z-index matches the workbench's + other overflow-widget hosts (scm, keybindings editor). */ +.review-overflow-widgets { + position: fixed; + top: 0; + left: 0; + z-index: 5000; +} + +/* The host carries tabindex="-1" so the canvas app can focus it programmatically + (desktop-entry's mount handle calls container.focus()). It is a document + surface rather than a control, and it is not tab-reachable, so suppress the + workbench-wide `[tabindex="-1"]:focus` ring that would otherwise trace the + whole pane -- the same treatment upstream gives editor group containers. */ +.monaco-workbench .review-canvas-part .review-canvas-host:focus { + outline: none; +} + +.review-reveal-line { + background: color-mix(in srgb, var(--vscode-foreground) 5%, transparent); + border-left: 2px solid var(--vscode-panel-border); +} + +/* Give commenting and folding separate hit targets in the Files view. */ +.review-files-editor .monaco-editor .margin-view-overlays .cldr:is( + .codicon-folding-expanded, + .codicon-folding-collapsed, + .codicon-folding-manual-expanded, + .codicon-folding-manual-collapsed +) { + margin-left: 30px; + width: 20px !important; +} + +.review-files-editor-diffs { position: relative; } +.review-files-editor-summary { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + border-bottom: 1px solid var(--vscode-sideBar-border, transparent); + color: var(--vscode-descriptionForeground); + font-size: 12px; + font-variant-numeric: tabular-nums; +} + +.review-files-editor-summary[hidden] { + display: none; +} + +.review-files-editor-summary-added { + color: var(--vscode-gitDecoration-addedResourceForeground); +} + +.review-files-editor-summary-removed { + color: var(--vscode-gitDecoration-deletedResourceForeground); +} + +.review-files-editor-summary-bar { + display: inline-flex; + gap: 1px; +} + +.review-files-editor-summary-block { + width: 8px; + height: 8px; + background: var(--vscode-editorWidget-border); +} + +.review-files-editor-summary-block.added { + background: var(--vscode-gitDecoration-addedResourceForeground); +} + +.review-files-editor-summary-block.removed { + background: var(--vscode-gitDecoration-deletedResourceForeground); +} + +.review-multidiff-note { + padding: 0 6px; + color: var(--vscode-descriptionForeground); + font-size: 12px; +} + +.review-multidiff-note[hidden] { + display: none; +} + +.review-structural-label-inline { + color: var(--vscode-editor-foldPlaceholderForeground); + font-style: italic; +} + +.review-structural-label-zone { + background-color: var(--vscode-editor-foldBackground); + color: var(--vscode-editor-foldPlaceholderForeground); +} + +.review-structural-label-zone pre { + margin: 0; + padding-left: 4ch; + font: inherit; + white-space: pre; +} + +.review-structural-stream-status:not([hidden]) { + position: absolute; + inset: 0; + z-index: 20; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 24px; + color: var(--vscode-descriptionForeground); + background: var(--vscode-editor-background); +} +.review-structural-stream-status.loading::before { + content: ""; + width: 14px; + height: 14px; + flex-shrink: 0; + border: 2px solid currentColor; + border-right-color: transparent; + border-radius: 50%; + animation: review-structural-loading 1s linear infinite; +} +@keyframes review-structural-loading { to { transform: rotate(360deg); } } +@media (prefers-reduced-motion: reduce) { + .review-structural-stream-status.loading::before { animation: none; } +} +.review-header-viewed { width: 16px; height: 16px; padding: 0; margin: 0 8px; border: 1px solid var(--vscode-descriptionForeground); border-radius: 3px; color: var(--vscode-editor-foreground); background: transparent; font: 12px/14px sans-serif; cursor: pointer; } +.review-header-viewed[aria-checked="true"], .review-counts-viewed { opacity: .45; } +.review-tree-counts { display:inline-flex; flex-shrink:0; gap:6px; margin-left:auto; padding-left:8px; padding-right:8px; font:11px/22px var(--review-chrome-font, monospace); font-variant-numeric:tabular-nums; } +.review-tree-added { color:var(--vscode-gitDecoration-addedResourceForeground); } +.review-tree-removed { color:var(--vscode-gitDecoration-deletedResourceForeground); } + +/* One disclosure glyph. The canvas draws it as an inline SVG (DisclosureChevron); + the workbench trees and the multi-diff headers use codicons, so their glyph is + swapped for the same 12px stroke path through a mask. The tree sets the + twistie's left padding to the row's indent; stock sizing is border-box, so + past the first level the padding eats the whole 16px box and the glyph + lands on the label. Content-box keeps the 16px glyph slot beside the + indent at every depth, so the chevron sits the same distance from its + label as a file mark does from its name. The file header button and the + section header toggle are keyed on their codicon name, down = open. */ +.review-workbench .monaco-tl-twistie.codicon-tree-item-expanded { + box-sizing: content-box; + width: 16px; + padding-right: 0; + justify-content: center; +} +.review-workbench .monaco-tl-twistie.codicon-tree-item-expanded::before, +.review-workbench .collapse-button .codicon-chevron-down::before, +.review-workbench .collapse-button .codicon-chevron-right::before, +.review-workbench .review-diff-group-toggle .codicon-chevron-down::before, +.review-workbench .review-diff-group-toggle .codicon-chevron-right::before { + content: ""; + display: block; + flex: none; + width: 12px; + height: 12px; + background: currentColor; + mask: url("data:image/svg+xml;utf8,") center / 12px 12px no-repeat; + transform: rotate(90deg); + transition: transform 120ms ease; +} +.review-workbench .monaco-tl-twistie.collapsed.codicon-tree-item-expanded::before, +.review-workbench .collapse-button .codicon-chevron-right::before, +.review-workbench .review-diff-group-toggle .codicon-chevron-right::before { + transform: rotate(0deg); +} + +/* File marks in the changed-files tree: status is one stroke beside the name, + never a boxed codicon. Plus, minus, dot, arrow, a ghost file for referenced + context, three dots while loading, a bang on error; viewed replaces the mark + with a check. Colors come from the theme's gitDecoration foregrounds (add, + del, warn amber, ink-muted). Folder rows keep an empty slot and paint nothing. */ +.review-workbench { + --review-mark-plus: url("data:image/svg+xml;utf8,"); + --review-mark-minus: url("data:image/svg+xml;utf8,"); + --review-mark-dot: url("data:image/svg+xml;utf8,"); + --review-mark-arrow: url("data:image/svg+xml;utf8,"); + --review-mark-file: url("data:image/svg+xml;utf8,"); + --review-mark-check: url("data:image/svg+xml;utf8,"); + --review-mark-fold: url("data:image/svg+xml;utf8,"); + --review-mark-dots: url("data:image/svg+xml;utf8,"); + --review-mark-bang: url("data:image/svg+xml;utf8,"); +} +.review-workbench .review-changed-files-icon[class*="review-changed-files-icon-"]::before, +.review-workbench .review-changed-files-icon.codicon-loading::before, +.review-workbench .review-changed-files-icon.codicon-error::before, +.review-workbench .review-file-viewed .review-changed-files-icon::before, +.review-workbench .review-file-folded .review-changed-files-icon::before { + content: ""; + display: block; + width: 16px; + height: 16px; + background: var(--review-mark-color, currentColor); + mask: var(--review-mark) center / 16px 16px no-repeat; + animation: none !important; +} +.review-workbench .review-changed-files-icon:not([hidden]) { display: flex; align-items: center; justify-content: center; } +.review-workbench .review-changed-files-icon-added { --review-mark: var(--review-mark-plus); --review-mark-color: var(--vscode-gitDecoration-addedResourceForeground); } +.review-workbench .review-changed-files-icon-deleted { --review-mark: var(--review-mark-minus); --review-mark-color: var(--vscode-gitDecoration-deletedResourceForeground); } +.review-workbench .review-changed-files-icon-modified { --review-mark: var(--review-mark-dot); --review-mark-color: var(--vscode-gitDecoration-modifiedResourceForeground); } +.review-workbench .review-changed-files-icon-renamed { --review-mark: var(--review-mark-arrow); --review-mark-color: var(--vscode-gitDecoration-renamedResourceForeground); } +.review-workbench .review-changed-files-icon-unchanged { --review-mark: var(--review-mark-file); --review-mark-color: var(--vscode-disabledForeground); } +.review-workbench .review-changed-files-icon.codicon-loading { --review-mark: var(--review-mark-dots); --review-mark-color: var(--vscode-descriptionForeground); } +.review-workbench .review-changed-files-icon.codicon-error { --review-mark: var(--review-mark-bang); --review-mark-color: var(--vscode-gitDecoration-deletedResourceForeground); } +.review-workbench .review-file-viewed { opacity: 1; color: var(--vscode-descriptionForeground); } +.review-workbench .review-file-viewed .review-changed-files-icon { --review-mark: var(--review-mark-check); --review-mark-color: var(--vscode-disabledForeground); } +/* Folded by default counts as done: the viewed treatment, with a fold mark. */ +.review-workbench .review-file-folded { opacity: 1; color: var(--vscode-descriptionForeground); } +.review-workbench .review-file-folded .review-changed-files-icon { --review-mark: var(--review-mark-fold); --review-mark-color: var(--vscode-disabledForeground); } + +/* Folds get out of the way: ghost ink on the code's own background, in the + chrome font. The theme sets the unchangedRegion background, foreground and + shadow. The row keeps Monaco's 24px height: its view zone and the handle + transforms assume it, and a shorter row rides up over the previous line. */ +.review-workbench .monaco-editor .diff-hidden-lines .center { + font: 11px/24px var(--review-chrome-font, monospace); +} +.review-workbench .monaco-editor .diff-hidden-lines .center:hover { + color: var(--vscode-descriptionForeground); +} + +/* The unfold glyph sits where the fold glyph will appear once the region is + open: in the glyph margin lane (an 18px square, the editor's line height) + at the top-left of the row, not centered under the line numbers and the + 24px row. Expand, and the collapse glyph lands under the same pointer. + Monaco centers the slot inline, hence the important. */ +.review-workbench .monaco-editor .diff-hidden-lines .center > div:first-child { + justify-content: flex-start !important; + align-items: flex-start !important; +} +.review-workbench .monaco-editor .diff-hidden-lines .center > div:first-child > a { + display: flex; + width: 18px; + height: 18px; + align-items: center; + justify-content: center; +} + +/* The canvas stylesheet resets every element to border-box, and the Diff + view's editors live inside the canvas. Monaco sizes the fold's drag + handles as content-box (4px tall plus 6px of transparent borders) and + offsets the whole widget by that sum, so a border-box handle is 4px short + and the fold row rides up over the previous line. */ +.monaco-editor .diff-hidden-lines .top, +.monaco-editor .diff-hidden-lines .bottom { + box-sizing: content-box; +} +.review-changed-files-label { flex:1; min-width:0; } +/* Left inset 10px and title gap 5px mirror the file header below it (5px + padding + 5px collapse-button margin, then 5px to the path), so the + section chevron and the file chevron sit on one vertical line. */ +.review-diff-group { height:48px; min-height:48px; box-sizing:border-box; display:flex; align-items:center; gap:12px; padding:12px 16px 4px 10px; border-top:1px solid var(--vscode-panel-border); background:var(--vscode-editor-background); color:var(--vscode-editor-foreground); } +.review-diff-group[hidden] { display:none; } +.review-diff-group-title { font-size:13px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } +.review-diff-group-counts { margin-left:auto; font:11px var(--vscode-editor-font-family, monospace); color:var(--vscode-descriptionForeground); white-space:nowrap; } +.review-diff-group.is-viewed > span { opacity:.45; } + +.review-diff-group-toggle { display:flex; align-items:center; gap:5px; min-width:0; border:0; padding:0; color:inherit; background:transparent; cursor:pointer; text-align:left; } +.review-diff-group-toggle:focus-visible { outline:1px solid var(--vscode-focusBorder); } + +/* The surrounding navigation owns the top edge of the diff pane. */ +.multi-diff-sticky-section .review-diff-group, +.review-files-editor-diffs .multiDiffEntry:first-child > .review-diff-group { + border-top: 0; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewApiEditorSerializer.test.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewApiEditorSerializer.test.ts new file mode 100644 index 000000000..e5c293b99 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewApiEditorSerializer.test.ts @@ -0,0 +1,111 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { Event } from "../../../../base/common/event.js"; +import { Registry } from "../../../../platform/registry/common/platform.js"; +import { EditorExtensions, EditorsOrder, type IEditorFactoryRegistry } from "../../../../workbench/common/editor.js"; +import { EditorGroupModel } from "../../../../workbench/common/editor/editorGroupModel.js"; +import { ReviewCanvasEditorTabsService } from "../../../services/reviewCanvasEditorTabsService.js"; +import { ReviewApiEditorSerializer } from "./reviewApiEditorSerializer.js"; +import { ReviewCanvasEditorInput } from "./reviewCanvasEditorInput.js"; + +test("native group restoration preserves both reviews, order and pinned source versions without duplicate tabs", async (t) => { + const inputs: ReviewCanvasEditorInput[] = []; + let tabs: ReviewCanvasEditorTabsService; + const instantiation = { + createInstance(ctor: any, ...args: any[]) { + if (ctor !== ReviewCanvasEditorInput) return new ctor(...args); + const input = new ReviewCanvasEditorInput(args[0], {} as never); + inputs.push(input); + return input; + }, + invokeFunction(fn: any) { + return fn({ get: () => tabs }); + }, + }; + const groups: EditorGroupModel[] = []; + const editors = { + onDidCloseEditor: Event.None, + async openEditor(input: ReviewCanvasEditorInput, options: any, group: EditorGroupModel) { + group.openEditor(input, { pinned: options.pinned, active: !options.inactive }); + }, + }; + const groupService = { groups, mainPart: { activeGroup: undefined as EditorGroupModel | undefined } }; + const createTabs = () => + new ReviewCanvasEditorTabsService(instantiation as never, editors as never, groupService as never); + tabs = createTabs(); + const registry = Registry.as(EditorExtensions.EditorFactory); + registry.start({ get: () => instantiation } as never); + const registration = registry.registerEditorSerializer(ReviewCanvasEditorInput.ID, ReviewApiEditorSerializer); + const config = { getValue: () => undefined, onDidChangeConfiguration: Event.None }; + const group = (state?: ReturnType) => + new EditorGroupModel(state, instantiation as never, config as never); + const left = group(), + right = group(); + t.after(() => { + registration.dispose(); + tabs.dispose(); + left.dispose(); + right.dispose(); + groups.forEach((group) => group.dispose()); + inputs.forEach((input) => input.dispose()); + }); + left.openEditor(tabs.inputFor({ kind: "home" }), { pinned: true, sticky: true }); + left.openEditor(tabs.inputFor({ kind: "api", reviewId: "a", title: "Review A" }), { pinned: true, active: true }); + left.openEditor(tabs.inputFor({ kind: "api-source", reviewId: "a", title: "Review A", selection: { reviewId: "a", kind: "version", version: 7 } }), { + pinned: true, + active: false, + }); + right.openEditor(tabs.inputFor({ kind: "api", reviewId: "b", title: "Review B" }), { pinned: true, active: true }); + const saved = [left.serialize(), right.serialize()]; + tabs.dispose(); + tabs = createTabs(); + groups.push(...saved.map((state) => group(state))); + groupService.mainPart.activeGroup = groups[1]; + assert.deepEqual( + groups.map((group) => group.getEditors(EditorsOrder.SEQUENTIAL).map((editor) => editor.getName())), + [["Home", "Review A", "Source — Review A (v7)"], ["Review B"]], + ); + assert.equal(groups[0]!.activeEditor!.getName(), "Review A"); + const restored = groups[0]!.activeEditor; + assert.equal(await tabs.openApiReview("a", "Renamed A"), restored); + assert.equal(groups[0]!.count, 3); + assert.equal(groups[0]!.stickyCount, 1); + assert.equal(groups[1]!.count, 1); + assert.equal(restored!.getName(), "Renamed A"); +}); + +test("invalid saved tabs are ignored instead of preventing the window from restoring", () => { + const serializer = new ReviewApiEditorSerializer(); + for (const value of [ + "invalid JSON", + "null", + '{"kind":"api"}', + '{"kind":"api-source","reviewId":"a","title":"A","version":-1}', + ]) { + assert.equal(serializer.deserialize({} as never, value), undefined); + } +}); + + +test("current Source tabs retain identity and main version tabs still restore", () => { + const inputs: ReviewCanvasEditorInput[] = []; + let tabs: ReviewCanvasEditorTabsService; + const instantiation = { + createInstance(_ctor: unknown, target: ConstructorParameters[0]) { + const input = new ReviewCanvasEditorInput(target, {} as never); + inputs.push(input); + return input; + }, + invokeFunction(fn: (accessor: { get(): ReviewCanvasEditorTabsService }) => unknown) { return fn({ get: () => tabs }); }, + }; + tabs = new ReviewCanvasEditorTabsService(instantiation as never, { onDidCloseEditor: Event.None } as never, {} as never); + try { + const serializer = new ReviewApiEditorSerializer(); + const restored = serializer.deserialize(instantiation as never, JSON.stringify({ kind: "api-source", reviewId: "a", title: "A", selection: { reviewId: "a", kind: "current" } })); + assert.equal(tabs.inputFor({ kind: "api-source", reviewId: "a", title: "A", selection: { reviewId: "a", kind: "current" } }), restored); + assert.notEqual(tabs.inputFor({ kind: "api-source", reviewId: "a", title: "A", selection: { reviewId: "a", kind: "version", version: 2 } }), restored); + const historical = serializer.deserialize(instantiation as never, JSON.stringify({ kind: "api-source", reviewId: "a", title: "A", version: 2 })); + assert.equal((historical as ReviewCanvasEditorInput).getName(), "Source — A (v2)"); + } finally { tabs.dispose(); inputs.forEach(input => input.dispose()); } +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewApiEditorSerializer.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewApiEditorSerializer.ts new file mode 100644 index 000000000..8255ad885 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewApiEditorSerializer.ts @@ -0,0 +1,37 @@ +import type { IInstantiationService } from "../../../../platform/instantiation/common/instantiation.js"; +import type { IEditorSerializer } from "../../../../workbench/common/editor.js"; +import type { EditorInput } from "../../../../workbench/common/editor/editorInput.js"; +import { IReviewCanvasEditorTabsService } from "../../../services/reviewCanvasEditorTabsService.js"; +import { ReviewCanvasEditorInput } from "./reviewCanvasEditorInput.js"; + +/** Let the workbench persist API tab order, groups and focus alongside other editors. */ +export class ReviewApiEditorSerializer implements IEditorSerializer { + canSerialize(editor: EditorInput) { + return editor instanceof ReviewCanvasEditorInput && + (editor.target.kind === "api" || editor.target.kind === "api-source" || editor.target.kind === "home"); + } + + serialize(editor: ReviewCanvasEditorInput) { + return this.canSerialize(editor) ? JSON.stringify(editor.target) : undefined; + } + + deserialize(instantiation: IInstantiationService, value: string) { + let target; + try { target = JSON.parse(value); } catch { return; } + if (!target || !["api", "api-source", "home"].includes(target.kind)) return; + if (target.kind !== "home" && (typeof target.reviewId !== "string" || typeof target.title !== "string")) return; + if (target.kind === "api-source") { + // Main already persists version-based Source tabs. Translate directly; + // intermediate development-only view/generation payloads need no adapter. + if (!target.selection && Number.isInteger(target.version) && target.version >= 0) + target = { kind: target.kind, reviewId: target.reviewId, title: target.title, + selection: { reviewId: target.reviewId, kind: "version", version: target.version } }; + const selection = target.selection; + if (!selection || selection.reviewId !== target.reviewId || + !["current", "version"].includes(selection.kind) || + (selection.kind === "version" && (!Number.isInteger(selection.version) || selection.version < 0))) return; + + } + return instantiation.invokeFunction(accessor => accessor.get(IReviewCanvasEditorTabsService).inputFor(target)); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasEditor.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasEditor.contribution.ts new file mode 100644 index 000000000..ca86405e3 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasEditor.contribution.ts @@ -0,0 +1,130 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from "../../../../base/common/event.js"; +import { Disposable } from "../../../../base/common/lifecycle.js"; +import { SyncDescriptor } from "../../../../platform/instantiation/common/descriptors.js"; +import { Registry } from "../../../../platform/registry/common/platform.js"; +import { EditorPaneDescriptor, IEditorPaneRegistry } from "../../../../workbench/browser/editor.js"; +import { + IWorkbenchContribution, + registerWorkbenchContribution2, + WorkbenchPhase, +} from "../../../../workbench/common/contributions.js"; +import { + EditorExtensions, + EditorResourceAccessor, + SideBySideEditor, + type IEditorFactoryRegistry, +} from "../../../../workbench/common/editor.js"; +import { IEditorGroupsService } from "../../../../workbench/services/editor/common/editorGroupsService.js"; +import { IEditorService } from "../../../../workbench/services/editor/common/editorService.js"; +import { IReviewApiCatalogService } from "../../../services/reviewApiCatalogService.js"; +import { IReviewCanvasEditorTabsService } from "../../../services/reviewCanvasEditorTabsService.js"; +import { IReviewDesktopConnectionService } from "../../../services/reviewDesktopConnectionService.js"; +import { ReviewApiEditorSerializer } from "./reviewApiEditorSerializer.js"; +import { ReviewCanvasEditorInput } from "./reviewCanvasEditorInput.js"; +import { ReviewCanvasEditorPane } from "./reviewCanvasPart.js"; +import { isReviewReadonlySource } from "../../../common/reviewReadonlySource.js"; + +Registry.as(EditorExtensions.EditorFactory).registerEditorSerializer( + ReviewCanvasEditorInput.ID, + ReviewApiEditorSerializer, +); + +Registry.as(EditorExtensions.EditorPane).registerEditorPane( + EditorPaneDescriptor.create(ReviewCanvasEditorPane, ReviewCanvasEditorPane.ID, "Review"), + [new SyncDescriptor(ReviewCanvasEditorInput)], +); + +class ReviewCanvasEditorContribution extends Disposable implements IWorkbenchContribution { + static readonly ID = "workbench.contrib.devfast.reviewCanvasEditor"; + + constructor( + @IEditorService private readonly editorService: IEditorService, + @IEditorGroupsService + private readonly editorGroupsService: IEditorGroupsService, + @IReviewDesktopConnectionService + private readonly desktopConnection: IReviewDesktopConnectionService, + @IReviewApiCatalogService private readonly apiCatalog: IReviewApiCatalogService, + @IReviewCanvasEditorTabsService + private readonly tabsService: IReviewCanvasEditorTabsService, + ) { + super(); + this._register(this.editorService.onDidActiveEditorChange(() => { + const editor = this.editorService.activeEditor; + const resource = EditorResourceAccessor.getCanonicalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY }); + if (editor && resource && isReviewReadonlySource(resource)) this.tabsService.registerReviewEditor(resource.authority, editor); + })); + this._register( + this.editorService.onDidCloseEditor(({ editor }) => { + if (!(editor instanceof ReviewCanvasEditorInput)) return; + if (editor.target.kind !== "api") { + void this.tabsService.openHome(true); + } + }), + ); + this._register( + apiCatalog.onDidCloseReview((uuid) => { + void this.tabsService.closeReview(uuid); + }), + ); + void this.initialize(); + } + + private async initialize(): Promise { + await this.editorGroupsService.whenRestored; + // Restored pinned source editors belong to the same review as their URI. + for (const group of this.editorGroupsService.groups) { + for (const editor of group.editors) { + const resource = EditorResourceAccessor.getCanonicalUri(editor, { + supportSideBySide: SideBySideEditor.PRIMARY, + }); + if (resource && isReviewReadonlySource(resource)) this.tabsService.registerReviewEditor(resource.authority, editor); + } + } + this.closeRestoredApiTabsMissingFromCatalog(); + await this.tabsService.openHome(!this.editorService.activeEditor); + await this.desktopConnection.initialize(); + await this.apiCatalog.initialize(); + } + + /** Restored API tabs may belong to reviews deleted or dismissed while the app was closed. */ + private closeRestoredApiTabsMissingFromCatalog(): void { + const restored = new Set( + this.editorGroupsService.groups.flatMap((group) => + group.editors.flatMap((editor) => + editor instanceof ReviewCanvasEditorInput && + (editor.target.kind === "api" || editor.target.kind === "api-source") + ? [editor.target.reviewId] + : [], + ), + ), + ); + if (restored.size === 0) return; + const reconcile = async () => { + // The managed tutorial is intentionally absent from the Home catalog. + const tutorial = await this.desktopConnection.getTutorialStatus().catch(() => undefined); + for (const reviewId of restored) { + if (reviewId === tutorial?.reviewUuid) continue; + const review = this.apiCatalog.reviews.find((review) => review.reviewId === reviewId); + if (!review || review.dismissedAt) void this.tabsService.closeReview(reviewId); + } + }; + if (this.apiCatalog.loaded) void reconcile(); + else + this._register( + Event.once(this.apiCatalog.onDidChange)(() => { + void reconcile(); + }), + ); + } +} + +registerWorkbenchContribution2( + ReviewCanvasEditorContribution.ID, + ReviewCanvasEditorContribution, + WorkbenchPhase.AfterRestored, +); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasEditorInput.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasEditorInput.ts new file mode 100644 index 000000000..2e18cd360 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasEditorInput.ts @@ -0,0 +1,117 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Codicon } from "../../../../base/common/codicons.js"; +import type { ThemeIcon } from "../../../../base/common/themables.js"; +import { URI } from "../../../../base/common/uri.js"; +import { localize } from "../../../../nls.js"; +import { + EditorInputCapabilities, + type GroupIdentifier, + type IUntypedEditorInput, +} from "../../../../workbench/common/editor.js"; +import { EditorInput } from "../../../../workbench/common/editor/editorInput.js"; +import { IEditorGroupsService } from "../../../../workbench/services/editor/common/editorGroupsService.js"; + +import { SCRATCHPAD_REVIEW_ID, type ReviewSourceSelection } from "../../../common/reviewProtocol.js"; +import { sourceSelectionIdentity } from "../../../common/reviewSourceView.js"; + +export type ReviewCanvasEditorTarget = + | { readonly kind: "home" } + | { readonly kind: "welcome" } + | { readonly kind: "settings" } + | { + readonly kind: "api-source"; + readonly reviewId: string; + readonly selection: ReviewSourceSelection; + readonly title: string; + } + | { readonly kind: "api"; readonly reviewId: string; readonly title: string }; + +export class ReviewCanvasEditorInput extends EditorInput { + static readonly ID = "workbench.editors.devfast.reviewCanvas"; + static readonly EDITOR_ID = "workbench.editor.devfast.reviewCanvas"; + + readonly resource: URI; + private _target: ReviewCanvasEditorTarget; + constructor( + target: ReviewCanvasEditorTarget, + @IEditorGroupsService + private readonly editorGroupsService: IEditorGroupsService, + ) { + super(); + this._target = target; + this.resource = URI.from({ + scheme: "devfast-review-canvas", + authority: target.kind, + path: + target.kind === "api-source" + ? `/${sourceSelectionIdentity(target.selection)}` + : target.kind === "api" + ? `/${target.reviewId}` + : `/${target.kind}`, + }); + } + + get target(): ReviewCanvasEditorTarget { + return this._target; + } + + setApiTitle(title: string): void { + if (this._target.kind !== "api" || this._target.title === title) return; + this._target = { ...this._target, title }; + this._onDidChangeLabel.fire(); + } + + override get typeId(): string { + return ReviewCanvasEditorInput.ID; + } + + override get editorId(): string { + return ReviewCanvasEditorInput.EDITOR_ID; + } + + override get capabilities(): EditorInputCapabilities { + let capabilities = + EditorInputCapabilities.Readonly | EditorInputCapabilities.Singleton | EditorInputCapabilities.ForceReveal; + if (this.target.kind === "home") { + capabilities |= EditorInputCapabilities.CannotClose; + } + return capabilities; + } + + override canMove(sourceGroup: GroupIdentifier, targetGroup: GroupIdentifier): true | string { + if ( + this.target.kind === "home" && + this.editorGroupsService.getPart(targetGroup) !== this.editorGroupsService.mainPart + ) { + return localize("reviewHomeCannotMove", "The Home tab cannot move to a separate window."); + } + return super.canMove(sourceGroup, targetGroup); + } + + override getName(): string { + if (this.target.kind === "api-source") return this.target.selection.kind === "current" ? `Source — ${this.target.title}` : `Source — ${this.target.title} (v${this.target.selection.version})`; + if (this.target.kind === "api") return this.target.title; + if (this.target.kind === "home") return "Home"; + if (this.target.kind === "welcome") return "Welcome"; + if (this.target.kind === "settings") return "Settings"; + return "Review"; + } + + override getIcon(): ThemeIcon | undefined { + if (this.target.kind === "home") return Codicon.home; + if (this.target.kind === "api-source") return Codicon.repo; + if (this.target.kind === "api" && this.target.reviewId === SCRATCHPAD_REVIEW_ID) return Codicon.edit; + return undefined; + } + + override matches(other: EditorInput | IUntypedEditorInput): boolean { + return ( + super.matches(other) || + (other instanceof ReviewCanvasEditorInput && other.resource.toString() === this.resource.toString()) + ); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasPart.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasPart.ts new file mode 100644 index 000000000..cb8cd7e85 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewCanvasPart.ts @@ -0,0 +1,1153 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { $, addDisposableListener, getWindow, type Dimension } from "../../../../base/browser/dom.js"; +import type { IHoverOptions, IHoverWidget } from "../../../../base/browser/ui/hover/hover.js"; +import { HoverPosition } from "../../../../base/browser/ui/hover/hoverWidget.js"; +import { createTrustedTypesPolicy } from "../../../../base/browser/trustedTypes.js"; +import type { CancellationToken } from "../../../../base/common/cancellation.js"; +import { Emitter } from "../../../../base/common/event.js"; +import { Disposable, DisposableStore, MutableDisposable, toDisposable } from "../../../../base/common/lifecycle.js"; +import { FileAccess } from "../../../../base/common/network.js"; +import type { ICursorPositionChangedEvent } from "../../../../editor/common/cursorEvents.js"; +import { ICommandService } from "../../../../platform/commands/common/commands.js"; +import { ConfigurationTarget, IConfigurationService } from "../../../../platform/configuration/common/configuration.js"; +import { TextEditorSelectionSource, type IEditorOptions } from "../../../../platform/editor/common/editor.js"; +import { IHoverService } from "../../../../platform/hover/browser/hover.js"; +import { createDecorator, IInstantiationService } from "../../../../platform/instantiation/common/instantiation.js"; +import { ILogService } from "../../../../platform/log/common/log.js"; +import { FocusMode } from "../../../../platform/native/common/native.js"; +import { INotificationService } from "../../../../platform/notification/common/notification.js"; +import { IProductService } from "../../../../platform/product/common/productService.js"; +import { IEditorProgressService, LongRunningOperation } from "../../../../platform/progress/common/progress.js"; +import { IStorageService, StorageScope, StorageTarget } from "../../../../platform/storage/common/storage.js"; +import { ITelemetryService } from "../../../../platform/telemetry/common/telemetry.js"; +import { ColorScheme } from "../../../../platform/theme/common/theme.js"; +import { IThemeService } from "../../../../platform/theme/common/themeService.js"; +import { Part } from "../../../../workbench/browser/part.js"; +import { EditorPane } from "../../../../workbench/browser/parts/editor/editorPane.js"; +import type { + IEditorControl, + IEditorOpenContext, + IEditorPaneSelection, + IEditorPaneSelectionChangeEvent, +} from "../../../../workbench/common/editor.js"; +import { EditorPaneSelectionChangeReason } from "../../../../workbench/common/editor.js"; +import type { IEditorGroup } from "../../../../workbench/services/editor/common/editorGroupsService.js"; +import { IHostService } from "../../../../workbench/services/host/browser/host.js"; +import { IWorkbenchLayoutService, Parts } from "../../../../workbench/services/layout/browser/layoutService.js"; +import { + REVIEW_KEYMAP_SETTING, + REVIEW_SOFTWARE_MAP_SETTING, + REVIEW_STRUCTURAL_DIFF_SETTING, + REVIEW_TELEMETRY_SETTING, +} from "../../../common/reviewConfigurationDefaults.js"; +import { resolveReviewSourceView, reviewSourceAnchor, type ReviewSourceView, type ReviewSourceSelection } from "../../../common/reviewProtocol.js"; +import type { + ReviewCanvasBridge, + ReviewCanvasContent, + ReviewCanvasDiagnostic, + ReviewCanvasHandle, + ReviewCanvasHomeSetup, + ReviewCanvasInstallContent, + ReviewCanvasModule, + ReviewCanvasOnboarding, + ReviewCanvasSettingsContent, + ReviewCanvasSetupActions, + ReviewCanvasTutorialBridge, + ReviewCliInstallStatus, + ReviewKeymapChoice, + ReviewRuntimeConfig, + ReviewSurfaceEvent, + ReviewTheme, + TutorialProgressV1, + TutorialStepId, +} from "../../../common/reviewProtocol.js"; +import { + parseReviewVerbRequest, + REVIEW_CANVAS_RESUME_EVENT, + REVIEW_TUTORIAL_PROGRESS_STORAGE_KEY, + REVIEW_TUTORIAL_STEP_IDS +} from "../../../common/reviewProtocol.js"; +import { IReviewVerbsService } from "../../../contrib/verbs/reviewVerbs.js"; +import { IReviewApiCatalogService } from "../../../services/reviewApiCatalogService.js"; +import { IReviewApiSourceService } from "../../../services/reviewApiSourceService.js"; +import { IReviewCanvasEditorTabsService } from "../../../services/reviewCanvasEditorTabsService.js"; +import { IReviewDesktopConnectionService } from "../../../services/reviewDesktopConnectionService.js"; +import { ReviewDiffViewService } from "../../../services/reviewDiffViewService.js"; +import { + ReviewEmbeddedEditorSelection, + reviewEmbeddedSelectionFromOptions, +} from "../../../services/reviewEmbeddedNavigation.js"; +import { ReviewEmbeddedEditors } from "../../../services/reviewEmbeddedEditors.js"; +import { IReviewTelemetryService } from "../../../services/reviewTelemetryService.js"; + +import "../../media/review.css"; +import { applyReviewThemeChoice, currentReviewThemeChoice } from "../../reviewThemeChoice.js"; +import { IReviewExplorerPartsService } from "../explorer/reviewExplorerPart.js"; +import { ReviewCanvasEditorInput } from "./reviewCanvasEditorInput.js"; + +interface ReviewCanvasAssetsModule extends ReviewCanvasModule { + readonly clearReviewViewState: (config: ReviewRuntimeConfig) => void; + readonly reviewWasmUrl: string; + readonly reviewStylesheetUrls: readonly string[]; +} + +interface ReviewCanvasGlobalThis { + __zod_globalConfig?: { + jitless?: boolean; + }; +} + +interface ReviewCanvasLoadLifecycle { + ready(): void; + reportDiagnostic(diagnostic: ReviewCanvasDiagnostic): void; +} + +type ReviewCanvasState = "home" | "connecting" | "active" | "completed" | "error"; + +const reviewCanvasPolicy = createTrustedTypesPolicy("reviewCanvas", { + createScriptURL: (value: string) => value, +}); + +const requestReviewApi: typeof fetch = (url, init) => fetch(url, init); + +function isTutorialStepId(step: unknown): step is TutorialStepId { + return typeof step === "string" && REVIEW_TUTORIAL_STEP_IDS.includes(step as TutorialStepId); +} +function embeddedSelectionChangeReason(event: ICursorPositionChangedEvent): EditorPaneSelectionChangeReason { + switch (event.source) { + case TextEditorSelectionSource.PROGRAMMATIC: + return EditorPaneSelectionChangeReason.PROGRAMMATIC; + case TextEditorSelectionSource.NAVIGATION: + return EditorPaneSelectionChangeReason.NAVIGATION; + case TextEditorSelectionSource.JUMP: + return EditorPaneSelectionChangeReason.JUMP; + default: + return EditorPaneSelectionChangeReason.USER; + } +} + +export class ReviewCanvasEditorPane extends EditorPane { + static readonly ID = ReviewCanvasEditorInput.EDITOR_ID; + + private readonly canvas = this._register(new MutableDisposable()); + private readonly surfaceEvents = this._register(new Emitter()); + private readonly _onDidChangeSelection = this._register(new Emitter()); + readonly onDidChangeSelection = this._onDidChangeSelection.event; + private readonly embeddedSelectionListeners = this._register(new MutableDisposable()); + private readonly themeEvents = this._register(new Emitter()); + private container: HTMLElement | null = null; + private canvasMount: HTMLElement | null = null; + private targetDocument: Document | null = null; + private apiContent: Extract | undefined; + private loadGeneration = 0; + private openingGeneration: number | undefined; + private readonly refreshProgress: LongRunningOperation; + private renderedInput: ReviewCanvasEditorInput | undefined; + private readyInput: ReviewCanvasEditorInput | undefined; + private assetsPromise: Promise | null = null; + private readonly modelSubscription = this._register(new MutableDisposable()); + private readonly inlineEditors: ReviewEmbeddedEditors; + private readonly diffViews: ReviewDiffViewService; + + constructor( + group: IEditorGroup, + @ITelemetryService telemetryService: ITelemetryService, + @IThemeService private readonly reviewThemeService: IThemeService, + @IStorageService private readonly storageService: IStorageService, + @IProductService private readonly productService: IProductService, + @IReviewDesktopConnectionService + private readonly desktopConnection: IReviewDesktopConnectionService, + @IReviewApiSourceService private readonly apiSource: IReviewApiSourceService, + @IReviewApiCatalogService private readonly apiCatalog: IReviewApiCatalogService, + @IReviewVerbsService private readonly verbs: IReviewVerbsService, + @IReviewCanvasEditorTabsService + private readonly tabsService: IReviewCanvasEditorTabsService, + @IReviewExplorerPartsService + private readonly explorerParts: IReviewExplorerPartsService, + @IInstantiationService + reviewInstantiationService: IInstantiationService, + @IHostService private readonly hostService: IHostService, + @IWorkbenchLayoutService + private readonly layoutService: IWorkbenchLayoutService, + @ICommandService private readonly commandService: ICommandService, + @IConfigurationService + private readonly configurationService: IConfigurationService, + @IReviewTelemetryService + private readonly reviewTelemetryService: IReviewTelemetryService, + @ILogService private readonly logService: ILogService, + @IHoverService private readonly hoverService: IHoverService, + @INotificationService private readonly notificationService: INotificationService, + @IEditorProgressService editorProgressService: IEditorProgressService, + ) { + super(ReviewCanvasEditorPane.ID, group, telemetryService, reviewThemeService, storageService); + this.inlineEditors = this._register(reviewInstantiationService.createInstance(ReviewEmbeddedEditors)); + this.refreshProgress = this._register(new LongRunningOperation(editorProgressService)); + this.diffViews = this._register( + reviewInstantiationService.createInstance(ReviewDiffViewService, this.inlineEditors), + ); + this._register( + verbs.onDidEmitSurfaceEvent((event) => { + if ( + event.event === "editorSelectionChanged" && + event.reviewId !== this.apiContent?.reviewId + ) + return; + this.surfaceEvents.fire(event); + }), + ); + this._register( + verbs.onDidRequestCanvasFocus(() => { + this.canvas.value?.focus(); + void this.hostService.focus(this.targetDocument?.defaultView ?? window); + }), + ); + this._register( + this.inlineEditors.onDidChangeActiveEditor(() => { + this._onDidChangeControl.fire(); + this.bindEmbeddedSelectionControl(); + }), + ); + this._register( + reviewThemeService.onDidColorThemeChange(() => { + const theme = this.colorScheme(); + this.themeEvents.fire(theme); + this.surfaceEvents.fire({ event: "themeChanged", theme }); + }), + ); + this._register(desktopConnection.onDidFail((error) => void this.renderFailure(error))); + this._register( + configurationService.onDidChangeConfiguration((event) => { + if ( + !event.affectsConfiguration(REVIEW_SOFTWARE_MAP_SETTING) && + !event.affectsConfiguration(REVIEW_STRUCTURAL_DIFF_SETTING) + ) + return; + if (this.apiContent) { + this.apiContent = { + ...this.apiContent, + structuralDiffEnabled: this.currentStructuralDiffEnabled(), + softwareMapEnabled: this.currentSoftwareMapEnabled(), + }; + this.canvas.value?.update(this.apiContent); + return; + } + }), + ); + } + + protected override createEditor(parent: HTMLElement): void { + parent.classList.add("review-canvas-part"); + this.targetDocument = parent.ownerDocument; + parent.ownerDocument.title = "Review"; + parent.ownerDocument.body.dataset["reviewCanvasMode"] = "renderer"; + const outer = $(".content.review-canvas-container"); + this.container = $(".review-canvas-host"); + this.container.tabIndex = -1; + this.canvasMount = $(".review-canvas-surface"); + this.container.appendChild(this.canvasMount); + outer.append(this.container); + parent.appendChild(outer); + // Inline peek editors promise fixedOverflowWidgets; their hover and + // definition widgets must be parented outside .review-canvas-root, + // whose container-query containment re-anchors and clips + // position: fixed descendants — but inside .monaco-workbench, where + // the --vscode-* theme variables that style hover widgets are scoped. + // One shared host serves every peek in this pane. + const overflowWidgets = $(".review-overflow-widgets.monaco-editor"); + this.layoutService.getContainer(getWindow(parent)).appendChild(overflowWidgets); + this._register(toDisposable(() => overflowWidgets.remove())); + this.diffViews.setOverflowWidgetsDomNode(overflowWidgets); + this.desktopConnection.attachControl(async (value) => { + const request = parseReviewVerbRequest(value); + if (request.name === "authoringCapabilities") { + return { ok: true, result: { softwareMapEnabled: this.currentSoftwareMapEnabled() } }; + } + if (request.name === "openApiReview") { + const response = await this.verbs.dispatch(request); + return response.ok ? { ok: true, result: { softwareMapEnabled: this.currentSoftwareMapEnabled() } } : response; + } + if (request.name === "focusWindow") { + await this.hostService.focus(this.targetDocument?.defaultView ?? window, { mode: FocusMode.Force }); + return { ok: true }; + } + return this.verbs.dispatch(request); + }); + void this.desktopConnection.initialize().catch((error) => this.renderError(error)); + } + + override async setInput( + input: ReviewCanvasEditorInput, + options: IEditorOptions | undefined, + context: IEditorOpenContext, + token: CancellationToken, + ): Promise { + const generation = ++this.loadGeneration; + this.refreshProgress.stop(); + this.openingGeneration = generation; + try { + await this.setReviewInput(input, options, context, token, generation); + } finally { + if (this.openingGeneration === generation) { + this.openingGeneration = undefined; + } + } + } + + private async setReviewInput( + input: ReviewCanvasEditorInput, + options: IEditorOptions | undefined, + context: IEditorOpenContext, + token: CancellationToken, + generation: number, + ): Promise { + await super.setInput(input, options, context, token); + this.restoreEmbeddedSelection(options); + try { + await this.desktopConnection.initialize(); + } catch (error) { + if (generation === this.loadGeneration && !token.isCancellationRequested) { + await this.renderError(error, generation); + } + return; + } + if (generation !== this.loadGeneration || token.isCancellationRequested) { + return; + } + if (input.target.kind === "api" && this.readyInput === input && this.renderedInput === input) { + this.canvasMount?.dispatchEvent(new globalThis.Event(REVIEW_CANVAS_RESUME_EVENT)); + return; + } + if (input.target.kind === "api-source") { + // The Source placeholder replaces the mount, so the reuse shortcuts + // above must not treat the previous review as still rendered. + this.renderedInput = input; + this.readyInput = undefined; + this.setCanvasState("home"); + await this.render({ kind: "source" }, generation); + return; + } + if (!(await this.resetCanvasForGeneration(generation))) { + return; + } + this.modelSubscription.clear(); + if (input.target.kind === "api") { + try { + const { reviewId } = input.target; + const [connection, assets] = await Promise.all([this.desktopConnection.getConnection(), this.loadAssets()]); + if (generation !== this.loadGeneration || token.isCancellationRequested) return; + this.renderedInput = input; + this.setCanvasState("active", reviewId); + void this.apiCatalog + .attention(reviewId, "view") + .catch((error) => this.logService.warn("[Review] Could not mark review viewed:", error)); + let sourceSelection: ReviewSourceSelection = { reviewId, kind: "current" }; + let sourceView: ReviewSourceView = resolveReviewSourceView({ reviewId, version: 0, pins: {} }); + const source = this.apiSource.canvas(() => sourceView, this.inlineEditors, this.diffViews); + const closeTutorial = () => void this.group.closeEditor(input); + const updateTutorial = (progress: TutorialProgressV1) => { + this.writeTutorialProgress(progress); + if (!this.apiContent) return; + this.apiContent = { + ...this.apiContent, + tutorial: this.createTutorialBridge(reviewId, progress, updateTutorial, closeTutorial), + }; + this.canvas.value?.update(this.apiContent); + }; + await this.render( + { + setTutorial: (enabled) => { + if ( + !this.apiContent || + generation !== this.loadGeneration || + enabled === Boolean(this.apiContent.tutorial) + ) + return; + this.apiContent = { + ...this.apiContent, + tutorial: enabled + ? this.createTutorialBridge(reviewId, this.readTutorialProgress(), updateTutorial, closeTutorial) + : undefined, + }; + this.canvas.value?.update(this.apiContent); + }, + kind: "api", + reviewId, + structuralDiffEnabled: this.currentStructuralDiffEnabled(), + softwareMapEnabled: this.currentSoftwareMapEnabled(), + setTitle: (title) => input.setApiTitle(title), + setSourceView: (selection, next) => { + sourceSelection = selection; + sourceView = next; + source.openStructuralComparison(); + }, + openSource: (source, range) => this.apiSource.open(source, range), + bridge: { + ...source, + ...this.sharedBridge(generation, () => { + this.readyInput = input; + }), + config: this.reviewRuntimeConfig( + { + ...connection, + reviewId: reviewId, + }, + assets, + ), + request: requestReviewApi, + post: async (request) => { + if (request.name === "openSourceTree") { + await this.tabsService.openApiSource(sourceSelection, input.getName()); + this.explorerParts.show(); + return { ok: true }; + } + if (request.name === "reveal") { + const range = { startLine: request.args.startLine, endLine: request.args.endLine }; + await this.apiSource.open( + { view: reviewSourceAnchor(sourceView, request.args.pins), file: request.args.path, side: request.args.side ?? "head" }, + range, + ); + return { ok: true }; + } + if (request.name === "openDiff") { + await this.apiSource.openDiff(sourceView, request.args.path); + return { ok: true }; + } + return this.verbs.dispatch(request); + }, + }, + }, + generation, + assets, + ); + } catch (error) { + if (generation === this.loadGeneration) await this.renderError(error, generation); + } + return; + } + if (input.target.kind === "home") { + this.renderedInput = input; + this.setCanvasState("home"); + const setup = await this.resolveHomeSetup(); + await this.apiCatalog.initialize(); + let emptyStateVisible = false; + /* The empty-list render suspends on the install fetch below, while + the list render has no await at all. The sequence number keeps a + suspended empty render from resuming after a later list render + and overwriting it with a stale snapshot. */ + let renderSeq = 0; + const renderHome = async () => { + const seq = ++renderSeq; + const reviews = this.apiCatalog.reviews; + const isEmpty = reviews.length === 0; + // Only the Welcome rail needs install status; the list must + // render without waiting on it. One fetch serves both the + // install card and the onboarding rail. + const install = isEmpty ? await this.resolveInstallContent() : undefined; + if (seq !== renderSeq) return; + if (isEmpty && !emptyStateVisible) { + this.reviewTelemetryService.capture("home_empty_state_viewed"); + } + emptyStateVisible = isEmpty; + const openReview = (uuid: string) => { + this.reviewTelemetryService.capture("review_opened", { + via: "home", + }); + const api = this.apiCatalog.reviews.find((review) => review.reviewId === uuid); + return api ? this.tabsService.openApiReview(uuid, api.title) : Promise.resolve(); + }; + return this.render( + { + kind: "home", + reviews, + openReview: (uuid) => void openReview(uuid), + deleteReview: (uuid) => this.apiCatalog.deleteReview(uuid), + dismissReview: (uuid) => this.apiCatalog.attention(uuid, "dismiss"), + restoreReview: (uuid) => this.apiCatalog.attention(uuid, "restore"), + openSourceTree: (uuid) => { + const api = this.apiCatalog.reviews.find((review) => review.reviewId === uuid); + if (api) { + void this.tabsService.openApiSource({ reviewId: api.reviewId, kind: "current" }, api.title).then(() => this.explorerParts.show()); + return; + } + }, + setup, + // Home shows the Welcome rail while the list is empty. + install, + setupActions: this.setupActions(), + onboarding: install ? this.resolveOnboarding(install.status) : undefined, + openTutorial: () => this.openTutorial(), + }, + generation, + ); + }; + // Home stays live while it is the rendered input: a deletion or a + // newly published review re-renders the list. render() drops stale + // generations once another input starts loading. + const subscriptions = new DisposableStore(); + subscriptions.add(this.desktopConnection.onDidChangeLists(() => void renderHome())); + subscriptions.add(this.apiCatalog.onDidChange(() => void renderHome())); + this.modelSubscription.value = subscriptions; + await renderHome(); + return; + } + if (input.target.kind === "welcome") { + void this.desktopConnection + .prepareTutorial() + .catch((error) => this.logService.warn("[Review] Tutorial preparation did not complete:", error)); + this.renderedInput = input; + this.setCanvasState("home"); + /* Same stale-resume guard as Home: the install fetch suspends, and + a later list event must win over an earlier suspended render. */ + let renderSeq = 0; + const renderWelcome = async () => { + const seq = ++renderSeq; + const install = await this.resolveInstallContent(); + if (seq !== renderSeq) return; + return this.render( + { + kind: "welcome", + install, + setupActions: this.setupActions(), + close: () => void this.group.closeEditor(input), + onboarding: install ? this.resolveOnboarding(install.status) : undefined, + openTutorial: () => this.openTutorial(), + }, + generation, + ); + }; + // The last step completes when a review publishes, which can happen + // while this tab sits open. + this.modelSubscription.value = this.desktopConnection.onDidChangeLists(() => void renderWelcome()); + await renderWelcome(); + return; + } + if (input.target.kind === "settings") { + this.renderedInput = input; + this.setCanvasState("home"); + const [settings, install] = await Promise.all([this.resolveSettingsContent(), this.resolveInstallContent()]); + await this.render({ kind: "settings", settings: { ...settings, install } }, generation); + return; + } + } + + override async clearInput(): Promise { + // Keep apiContent with the mounted canvas so resuming it preserves its review identity. + // render() replaces both when another input is shown. + this.refreshProgress.stop(); + await super.clearInput(); + } + + protected override setEditorVisible(visible: boolean): void { + super.setEditorVisible(visible); + if (!visible) this.refreshProgress.stop(); + } + + override focus(): void { + this.canvas.value?.focus(); + } + + showFind(): boolean { + const editor = this.inlineEditors.activeCodeEditor; + let seed: string | undefined; + if (editor?.hasTextFocus()) { + const model = editor.getModel(); + const selection = editor.getSelection(); + if (model && selection && !selection.isEmpty()) { + seed = model.getValueInRange(selection); + } + } + return this.canvas.value?.showFind(seed) ?? false; + } + + override getControl(): IEditorControl | undefined { + return this.inlineEditors; + } + + override setOptions(options: IEditorOptions | undefined): void { + super.setOptions(options); + this.restoreEmbeddedSelection(options); + } + + getSelection(): IEditorPaneSelection | undefined { + const editor = this.inlineEditors.selectionCodeEditor; + const position = editor?.getPosition(); + const model = editor?.getModel(); + if (!editor || !position || !model) return undefined; + const domNode = editor.getDomNode(); + const view = domNode?.closest(".review-files-editor") ? "diff" : "review"; + const section = domNode?.closest("[data-review-section]")?.dataset["reviewSection"]; + return new ReviewEmbeddedEditorSelection(editor, { + view, + path: model.uri.path.slice(1), + side: new URLSearchParams(model.uri.query).get("side") === "base" ? "base" : "head", + lineNumber: position.lineNumber, + column: position.column, + section, + }); + } + + private bindEmbeddedSelectionControl(): void { + const editor = this.inlineEditors.activeCodeEditor; + if (!editor) { + this.embeddedSelectionListeners.clear(); + return; + } + const store = new DisposableStore(); + store.add( + editor.onDidFocusEditorText(() => { + this._onDidChangeSelection.fire({ + reason: EditorPaneSelectionChangeReason.USER, + }); + }), + ); + store.add( + editor.onDidChangeCursorPosition((event) => + this._onDidChangeSelection.fire({ + reason: embeddedSelectionChangeReason(event), + }), + ), + ); + this.embeddedSelectionListeners.value = store; + } + + private restoreEmbeddedSelection(options: IEditorOptions | undefined): void { + const selection = reviewEmbeddedSelectionFromOptions(options); + if (!selection) return; + selection.restoreInCanvas(); + } + + /** + * Retargets the Toggle Inline View command at the in-tab diff. The diff + * editor commands duck-type this method on the active pane, so the Review + * tab answers for its embedded diff and no-ops in the other views. + */ + toggleRenderSideBySide(): void { + this.diffViews.toggleRenderSideBySide(); + } + + override layout(_dimension: Dimension): void { + // The canvas uses normal CSS flow and fills the editor pane. + } + + private setupActions(): ReviewCanvasSetupActions { + return { + load: () => this.loadInstallContent(), + installCli: async () => { await this.commandService.executeCommand("review.installCliInPath"); }, + }; + } + + private async resolveInstallContent(): Promise { + try { + return await this.loadInstallContent(); + } catch (error) { + this.logService.warn("Review agent setup status failed", error); + return undefined; + } + } + + private async loadInstallContent(): Promise { + const status = await this.desktopConnection.getCliInstallStatus(); + return { + status, + apply: async (request) => { + await this.desktopConnection.applyCliInstall(request); + return this.desktopConnection.getCliInstallStatus(); + }, + remove: async (request) => { + await this.desktopConnection.removeCliInstall(request); + return this.desktopConnection.getCliInstallStatus(); + }, + decline: async () => { + await this.desktopConnection.declineCliInstall(); + return this.desktopConnection.getCliInstallStatus(); + }, + skip: async () => { + await this.desktopConnection.skipCliInstallPrompts(); + return this.desktopConnection.getCliInstallStatus(); + }, + enablePrompts: async () => { + await this.desktopConnection.resetCliInstallPrompts(); + return this.desktopConnection.getCliInstallStatus(); + }, + }; + } + + private openTutorial(): void { + // The command opens and focuses the tutorial tab itself, and reports + // its own failures. Welcome stays open behind it: it is a hub the + // reader comes back to, not a one-shot wizard. + void this.commandService.executeCommand("review.openTutorial"); + } + + /** + * Settings state and actions for the Settings page. Every value lives in + * workbench configuration, apart from the retention window, which the review + * server owns. Extensions reuse the existing quick pick. + */ + private async resolveSettingsContent(): Promise { + // Settings must render even when the server preference cannot be read; + // the row then shows the default, off. + const scratchpadEnabled = await this.desktopConnection.readScratchpadEnabled().catch(() => false); + return { + telemetryEnabled: this.currentTelemetryEnabled(), + setTelemetryEnabled: async (enabled) => { + this.reviewTelemetryService.capture("setting_changed", { + setting: "telemetry_enabled", + enabled, + }); + if (!enabled) { + await this.reviewTelemetryService.flush(); + } + await this.configurationService.updateValue(REVIEW_TELEMETRY_SETTING, enabled, ConfigurationTarget.USER); + return this.currentTelemetryEnabled(); + }, + theme: currentReviewThemeChoice(this.configurationService, this.reviewThemeService), + setTheme: async (choice) => { + await applyReviewThemeChoice(this.configurationService, choice); + return currentReviewThemeChoice(this.configurationService, this.reviewThemeService); + }, + keymap: this.currentKeymap(), + setKeymap: async (choice) => { + this.reviewTelemetryService.capture("setting_changed", { + setting: "keymap", + enabled: true, + }); + await this.commandService.executeCommand("review.setKeymap", choice); + return this.currentKeymap(); + }, + softwareMapEnabled: this.currentSoftwareMapEnabled(), + setSoftwareMapEnabled: async (enabled) => { + this.reviewTelemetryService.capture("setting_changed", { + setting: "software_map_enabled", + enabled, + }); + await this.configurationService.updateValue(REVIEW_SOFTWARE_MAP_SETTING, enabled, ConfigurationTarget.USER); + return this.currentSoftwareMapEnabled(); + }, + scratchpadEnabled, + setScratchpadEnabled: async (enabled) => { + this.reviewTelemetryService.capture("setting_changed", { + setting: "scratchpad_enabled", + enabled, + }); + return this.desktopConnection.setScratchpadEnabled(enabled); + }, + structuralDiffEnabled: this.currentStructuralDiffEnabled(), + setStructuralDiffEnabled: async (enabled) => { + await this.configurationService.updateValue( + REVIEW_STRUCTURAL_DIFF_SETTING, + enabled, + ConfigurationTarget.USER, + ); + return this.currentStructuralDiffEnabled(); + }, + reloadWindow: async () => { await this.commandService.executeCommand("workbench.action.reloadWindow"); }, + diffrConfig: { + saveSummarizer: (input) => this.desktopConnection.saveDiffrSummarizer(input), + testSummarizer: (input) => this.desktopConnection.testDiffrSummarizer(input), + read: () => this.desktopConnection.readDiffrConfig(), + set: (key, value) => { + this.reviewTelemetryService.capture("setting_changed", { + setting: "diffr_config", + enabled: true, + }); + return this.desktopConnection.setDiffrConfigValue(key, value); + }, + }, + manageExtensions: () => void this.commandService.executeCommand("review.manageExtensions"), + }; + } + + private currentKeymap(): ReviewKeymapChoice { + return this.configurationService.getValue(REVIEW_KEYMAP_SETTING) ?? "none"; + } + + private currentStructuralDiffEnabled(): boolean { + return ( + this.configurationService.getValue( + REVIEW_STRUCTURAL_DIFF_SETTING, + ) === true + ); + } + + private currentSoftwareMapEnabled(): boolean { + return this.configurationService.getValue(REVIEW_SOFTWARE_MAP_SETTING) === true; + } + + // The setting ships as true, so only an explicit false means opted out. + private currentTelemetryEnabled(): boolean { + return this.configurationService.getValue(REVIEW_TELEMETRY_SETTING) !== false; + } + + /** + * Install status for the Home setup banner. Home must render even when the + * status endpoint fails, so a failure yields no banner. + */ + private async resolveHomeSetup(): Promise { + try { + return { + status: await this.desktopConnection.getCliInstallStatus(), + open: () => void this.tabsService.openWelcome(true), + }; + } catch { + return undefined; + } + } + + /** + * Step state for the Welcome rail, derived from the install status the + * caller already fetched, so one render costs one status round-trip. The + * rest is local: stored tutorial progress and the review list. + */ + private resolveOnboarding(status: ReviewCliInstallStatus): ReviewCanvasOnboarding { + const checked = new Set(this.readTutorialProgress().checked); + const steps = REVIEW_TUTORIAL_STEP_IDS.filter((step) => step !== "openMap" || this.currentSoftwareMapEnabled()); + return { + installed: status.agents.some((agent) => agent.installed), + tutorialChecked: steps.filter((step) => checked.has(step)).length, + tutorialTotal: steps.length, + // Drafts are filtered out of this list and the tutorial never + // joins it, so this counts only a real published review. + published: this.apiCatalog.reviews.length > 0, + }; + } + + private createTutorialBridge( + reviewUuid: string, + progress: TutorialProgressV1, + onChange: (progress: TutorialProgressV1) => void, + close: () => void, + ): ReviewCanvasTutorialBridge { + /* Mutations re-read stored progress instead of using the captured + snapshot: two events arriving before the re-rendered bridge lands + (hover then goto-definition) must not clobber each other. */ + const setStep = (step: TutorialStepId, checked: boolean) => { + if (!REVIEW_TUTORIAL_STEP_IDS.includes(step)) return; + const current = this.readTutorialProgress(); + if (current.checked.includes(step) === checked) return; + const values = new Set(current.checked); + if (checked) values.add(step); + else values.delete(step); + onChange({ ...current, checked: [...values] }); + }; + return { + content: { reviewUuid, progress, keymap: this.currentKeymap() }, + setStep, + dismiss: () => onChange({ ...this.readTutorialProgress(), dismissed: true }), + reopen: () => onChange({ ...this.readTutorialProgress(), dismissed: false }), + selectKeymap: async (keymap) => { + if (keymap !== "none" && keymap !== "vim" && keymap !== "emacs") { + throw new Error("Unsupported tutorial keymap choice."); + } + setStep("chooseKeymap", true); + try { + /* The keymap command may reload the window before its promise can + settle. Persist the completed step first so the restored tutorial + advances from the choice the user already made. */ + await this.commandService.executeCommand("review.setKeymap", keymap); + } catch (error) { + setStep("chooseKeymap", false); + throw error; + } + }, + close, + }; + } + + private readTutorialProgress(): TutorialProgressV1 { + const empty: TutorialProgressV1 = { + version: 1, + checked: [], + dismissed: false, + }; + const raw = this.storageService.get(REVIEW_TUTORIAL_PROGRESS_STORAGE_KEY, StorageScope.APPLICATION); + if (!raw) return empty; + try { + const value = JSON.parse(raw) as { + version?: unknown; + checked?: unknown; + dismissed?: unknown; + steps?: unknown; + }; + if ( + value.version !== 1 || + !Array.isArray(value.steps) || + !Array.isArray(value.checked) || + !value.checked.every(isTutorialStepId) || + typeof value.dismissed !== "boolean" + ) { + throw new Error("Invalid tutorial progress."); + } + const checked = new Set(value.checked); + const known = value.steps.filter(isTutorialStepId); + if (known.length > 0 && known.every((step) => checked.has(step))) { + for (const step of REVIEW_TUTORIAL_STEP_IDS) { + checked.add(step); + } + } + return { + version: 1, + checked: [...checked], + dismissed: value.dismissed, + }; + } catch { + this.writeTutorialProgress(empty); + return empty; + } + } + + private writeTutorialProgress(progress: TutorialProgressV1): void { + this.storageService.store( + REVIEW_TUTORIAL_PROGRESS_STORAGE_KEY, + // `steps` marks which step ids existed at write time, so a later + // release can tell a finished tour from one its new steps reopened. + JSON.stringify({ ...progress, steps: REVIEW_TUTORIAL_STEP_IDS }), + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + } + + private async renderFailure(error: Error): Promise { + this.refreshProgress.stop(); + const generation = ++this.loadGeneration; + if (await this.resetCanvasForGeneration(generation)) { + await this.renderError(error, generation); + } + } + + private async renderError(error: unknown, generation?: number): Promise { + const activeGeneration = generation ?? ++this.loadGeneration; + this.setCanvasState("error"); + await this.render( + { + kind: "error", + message: error instanceof Error ? error.message : String(error), + }, + activeGeneration, + ); + } + + private async render( + content: ReviewCanvasContent, + generation: number, + loadedAssets?: ReviewCanvasAssetsModule, + ): Promise { + if (!this.canvasMount) return; + const assets = loadedAssets ?? (await this.loadAssets()); + if (generation !== this.loadGeneration) return; + this.apiContent = content.kind === "api" ? content : undefined; + if (this.canvas.value) { + this.canvas.value.update(content); + } else { + this.canvas.value = assets.mountReviewCanvas(this.canvasMount, content); + } + } + + private loadAssets(): Promise { + this.assetsPromise ??= this.importAssets().catch((error) => { + this.assetsPromise = null; + throw error; + }); + return this.assetsPromise; + } + + private async importAssets(): Promise { + // Zod 4 probes the Function constructor unless its CSP-safe mode is set + // before the canvas module graph is evaluated. Chromium reports the caught + // probe as a Trusted Types violation, so configure the bundled authoring + // runtime before importing it instead of weakening the workbench policy. + const canvasGlobal = globalThis as ReviewCanvasGlobalThis; + canvasGlobal.__zod_globalConfig ??= {}; + canvasGlobal.__zod_globalConfig.jitless = true; + + const url = FileAccess.asBrowserUri("vs/review/canvas/canvas-loader.js").toString(true); + const trustedUrl = reviewCanvasPolicy?.createScriptURL(url) ?? (url as string); + const assets = (await import( + /* webpackIgnore: true */ trustedUrl as unknown as string + )) as ReviewCanvasAssetsModule; + if (typeof assets.mountReviewCanvas !== "function") { + throw new Error("Review canvas bundle has no mount function."); + } + await Promise.all(assets.reviewStylesheetUrls.map((stylesheet) => loadStylesheet(document, stylesheet))); + return assets; + } + + /** The bridge members every canvas shares; `onReady` runs once the mount reports ready. */ + private sharedBridge( + generation: number, + onReady: () => void, + lifecycle?: ReviewCanvasLoadLifecycle, + ): Pick< + ReviewCanvasBridge, + | "appSessionId" + | "subscribe" + | "currentTheme" + | "onDidChangeTheme" + | "currentDiffLayout" + | "setDiffLayout" + | "onDidChangeDiffLayout" + | "setupTooltip" + | "notify" + | "ready" + | "reportDiagnostic" + > { + return { + appSessionId: this.reviewTelemetryService.appSessionId, + subscribe: (listener) => this.surfaceEvents.event(listener), + currentTheme: () => this.colorScheme(), + onDidChangeTheme: (listener) => this.themeEvents.event(listener), + currentDiffLayout: () => this.diffViews.diffLayout.get(), + setDiffLayout: (layout) => this.diffViews.diffLayout.set(layout), + onDidChangeDiffLayout: (listener) => this.diffViews.diffLayout.onDidChange(listener), + notify: ({ kind, text }) => { + if (kind === "error") this.notificationService.error(text); + else this.notificationService.info(text); + }, + setupTooltip: (target, content) => { + const store = new DisposableStore(); + const hover = store.add(new MutableDisposable()); + const options: IHoverOptions = { + target, + content, + position: { hoverPosition: HoverPosition.ABOVE }, + appearance: { compact: true, showPointer: true }, + persistence: { hideOnKeyDown: true }, + }; + store.add(addDisposableListener(target, "mouseenter", () => { + if (target.getAttribute("aria-expanded") === "true") return; + hover.value = this.hoverService.showDelayedHover(options, { groupId: "review-topbar", reducedDelay: true }); + })); + store.add(addDisposableListener(target, "focus", () => { + if (!target.matches(":focus-visible") || target.getAttribute("aria-expanded") === "true") return; + hover.value = this.hoverService.showInstantHover(options); + })); + for (const event of ["blur", "pointerdown", "click", "keydown"]) { + store.add(addDisposableListener(target, event, () => hover.clear())); + } + return store; + }, + ready: () => { + if (generation !== this.loadGeneration || !this.targetDocument) return; + this.targetDocument.body.dataset["reviewCanvasReady"] = "true"; + onReady(); + }, + reportDiagnostic: (diagnostic) => { + if (generation === this.loadGeneration && diagnostic.level === "error") { + delete this.targetDocument?.body.dataset["reviewCanvasReady"]; + } + const method = diagnostic.level === "error" ? console.error : console.warn; + method(`[Review canvas ${diagnostic.source}] ${diagnostic.message}`, diagnostic.stack ?? ""); + lifecycle?.reportDiagnostic(diagnostic); + }, + }; + } + + private reviewRuntimeConfig( + connection: Pick, + assets: ReviewCanvasAssetsModule, + ): ReviewRuntimeConfig { + return { + ...connection, + wasmUrl: assets.reviewWasmUrl, + appVersion: this.productService.reviewVersion ?? this.productService.version, + theme: this.colorScheme(), + host: "desktop", + }; + } + + private async resetCanvasForGeneration(generation: number): Promise { + if (generation !== this.loadGeneration) { + return false; + } + this.readyInput = undefined; + this.inlineEditors.reset(); + this.diffViews.reset(); + return generation === this.loadGeneration; + } + + private setCanvasState(state: ReviewCanvasState, reviewId?: string): void { + if (!this.targetDocument) return; + this.targetDocument.body.dataset["reviewCanvasState"] = state; + if (state === "active" && reviewId) { + this.targetDocument.body.dataset["reviewId"] = reviewId; + delete this.targetDocument.body.dataset["reviewCanvasReady"]; + } else { + delete this.targetDocument.body.dataset["reviewId"]; + delete this.targetDocument.body.dataset["reviewCanvasReady"]; + } + } + + private colorScheme(): ReviewTheme { + const type = this.reviewThemeService.getColorTheme().type; + return type === ColorScheme.LIGHT || type === ColorScheme.HIGH_CONTRAST_LIGHT ? "light" : "dark"; + } +} + +class ReviewCanvasPlaceholderPart extends Part { + override readonly minimumWidth = 0; + override readonly maximumWidth = Number.POSITIVE_INFINITY; + override readonly minimumHeight = 0; + override readonly maximumHeight = Number.POSITIVE_INFINITY; + + constructor( + @IThemeService themeService: IThemeService, + @IStorageService storageService: IStorageService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + ) { + super( + Parts.REVIEW_CANVAS_PART, + { hasTitle: false, borderWidth: () => 0 }, + themeService, + storageService, + layoutService, + ); + } + + override create(parent: HTMLElement): void { + this.element = parent; + super.create(parent); + } + + protected override createContentArea(parent: HTMLElement): HTMLElement { + return parent; + } + + toJSON(): object { + return { type: Parts.REVIEW_CANVAS_PART }; + } +} + +export const IReviewCanvasPartsService = createDecorator("reviewCanvasPartsService"); + +export interface IReviewCanvasPartsService { + readonly _serviceBrand: undefined; +} + +export class ReviewCanvasParts extends Disposable implements IReviewCanvasPartsService { + declare readonly _serviceBrand: undefined; + + constructor(@IInstantiationService instantiationService: IInstantiationService) { + super(); + this._register(instantiationService.createInstance(ReviewCanvasPlaceholderPart)); + } +} + +function loadStylesheet(document: Document, url: string): Promise { + const existing = [...document.querySelectorAll('link[data-review-canvas-stylesheet="true"]')].find( + (link) => link.href === url, + ); + if (existing) return Promise.resolve(); + return new Promise((resolve, reject) => { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = url; + link.dataset["reviewCanvasStylesheet"] = "true"; + link.addEventListener("load", () => resolve(), { once: true }); + link.addEventListener("error", () => reject(new Error(`Review canvas stylesheet failed: ${url}`)), { once: true }); + document.head.appendChild(link); + }); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewFind.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewFind.contribution.ts new file mode 100644 index 000000000..0124ecad9 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/canvas/reviewFind.contribution.ts @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyCode, KeyMod } from "../../../../base/common/keyCodes.js"; +import { localize2 } from "../../../../nls.js"; +import { + Action2, + registerAction2, +} from "../../../../platform/actions/common/actions.js"; +import { ICommandService } from "../../../../platform/commands/common/commands.js"; +import type { ServicesAccessor } from "../../../../platform/instantiation/common/instantiation.js"; +import { KeybindingWeight } from "../../../../platform/keybinding/common/keybindingsRegistry.js"; +import { ActiveEditorContext } from "../../../../workbench/common/contextkeys.js"; +import { IEditorService } from "../../../../workbench/services/editor/common/editorService.js"; +import { ReviewCanvasEditorInput } from "./reviewCanvasEditorInput.js"; +import { ReviewCanvasEditorPane } from "./reviewCanvasPart.js"; + +const REVIEW_FIND_COMMAND_ID = "review.action.find"; + +class ReviewFindAction extends Action2 { + constructor() { + super({ + id: REVIEW_FIND_COMMAND_ID, + title: localize2("review.action.find", "Find in Review"), + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyCode.KeyF, + when: ActiveEditorContext.isEqualTo(ReviewCanvasEditorInput.EDITOR_ID), + }, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const pane = accessor.get(IEditorService).activeEditorPane; + if (pane instanceof ReviewCanvasEditorPane) { + if (pane.showFind()) return; + } + await accessor.get(ICommandService).executeCommand("actions.find"); + } +} + +registerAction2(ReviewFindAction); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/explorer/reviewExplorerPart.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/explorer/reviewExplorerPart.ts new file mode 100644 index 000000000..0b0900a57 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/explorer/reviewExplorerPart.ts @@ -0,0 +1,631 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { sourceTreeUri, sourceTreeSelection, sourceTreeRoot } from "../../../common/reviewSourceView.js"; + +import { $ } from "../../../../base/browser/dom.js"; +import type { IListVirtualDelegate } from "../../../../base/browser/ui/list/list.js"; +import type { IListAccessibilityProvider } from "../../../../base/browser/ui/list/listWidget.js"; +import type { IAsyncDataSource, ITreeNode, ITreeRenderer } from "../../../../base/browser/ui/tree/tree.js"; +import { Sequencer } from "../../../../base/common/async.js"; +import { compareFileNamesDefault } from "../../../../base/common/comparers.js"; +import { Disposable } from "../../../../base/common/lifecycle.js"; +import { basename, dirname, isEqual, isEqualOrParent } from "../../../../base/common/resources.js"; +import { URI } from "../../../../base/common/uri.js"; +import { localize } from "../../../../nls.js"; +import { + IConfigurationService, + type IConfigurationChangeEvent, +} from "../../../../platform/configuration/common/configuration.js"; +import { FILES_EXCLUDE_CONFIG, FileKind, type IFileStat } from "../../../../platform/files/common/files.js"; +import { IInstantiationService, createDecorator } from "../../../../platform/instantiation/common/instantiation.js"; +import { WorkbenchAsyncDataTree } from "../../../../platform/list/browser/listService.js"; +import { ILogService } from "../../../../platform/log/common/log.js"; +import { IStorageService, StorageScope, StorageTarget } from "../../../../platform/storage/common/storage.js"; +import { IThemeService } from "../../../../platform/theme/common/themeService.js"; +import { DEFAULT_LABELS_CONTAINER, ResourceLabels, type IResourceLabel } from "../../../../workbench/browser/labels.js"; +import { Part } from "../../../../workbench/browser/part.js"; +import { EditorResourceAccessor, SideBySideEditor } from "../../../../workbench/common/editor.js"; +import type { EditorInput } from "../../../../workbench/common/editor/editorInput.js"; +import { ResourceGlobMatcher } from "../../../../workbench/common/resources.js"; +import { createFileIconThemableTreeContainerScope } from "../../../../workbench/contrib/files/browser/views/explorerView.js"; +import type { IFilesConfiguration } from "../../../../workbench/contrib/files/common/files.js"; +import { IEditorGroupsService } from "../../../../workbench/services/editor/common/editorGroupsService.js"; +import { IEditorService } from "../../../../workbench/services/editor/common/editorService.js"; +import { IWorkbenchLayoutService, Parts } from "../../../../workbench/services/layout/browser/layoutService.js"; +import { REVIEW_CHROME_HEIGHT } from "../../../common/reviewChrome.js"; +import { + IReviewApiSourceService, + REVIEW_API_SOURCE_SCHEME, +} from "../../../services/reviewApiSourceService.js"; +import { IReviewApiCatalogService } from "../../../services/reviewApiCatalogService.js"; +import { IReviewCanvasEditorTabsService } from "../../../services/reviewCanvasEditorTabsService.js"; + +import "../../media/review.css"; +import { ReviewCanvasEditorInput } from "../canvas/reviewCanvasEditorInput.js"; + +/** The row height of one explorer entry, in CSS pixels. */ +const REVIEW_EXPLORER_ROW_HEIGHT = 22; + +const REVIEW_EXPLORER_TEMPLATE_ID = "review.explorer.entry"; + +/** + * Whether the tree belongs beside this editor input. + * + * The rule is the resource, not the pane: a tree accompanies anything showing a + * file from disk. Review's own surfaces — the canvas, the Diff (multi-file) view + * and Home — are all `ReviewCanvasEditorInput`, whose resource carries the + * `devfast-review-canvas` scheme, so they are excluded by construction. + * + * This used to be a whitelist of pane ids (`TEXT_FILE_EDITOR_ID`, + * `TEXT_DIFF_EDITOR_ID`). That was wrong: clicking an image or any other binary + * file *in the tree* opens a different pane, which fell outside the list and made + * the tree collapse itself out from under the click. + */ +function accompaniesEditor(input: EditorInput | undefined): boolean { + if (!input) { + return false; + } + + if (isSourceTab(input)) { + return true; + } + + const resource = EditorResourceAccessor.getCanonicalUri(input, { supportSideBySide: SideBySideEditor.PRIMARY }); + return resource?.scheme === REVIEW_API_SOURCE_SCHEME; +} + +/** The Source tab owns the current or version-selected repository tree. */ +function isSourceTab(input: EditorInput | undefined): boolean { + return input instanceof ReviewCanvasEditorInput && input.target.kind === "api-source"; +} + +interface IReviewExplorerTemplate { + readonly label: IResourceLabel; +} + +const reviewExplorerDelegate: IListVirtualDelegate = { + getHeight: () => REVIEW_EXPLORER_ROW_HEIGHT, + getTemplateId: () => REVIEW_EXPLORER_TEMPLATE_ID, +}; + +/** + * Resolves directory children on demand and remembers every stat it produced. + * + * `revealResource` walks that cache to expand a file's ancestors, so the cache + * is part of the contract rather than an optimization: a stat that never came + * back through here cannot be revealed. + * + * Children the `files.exclude` setting hides never leave this class, so they are + * absent from the tree and from the cache. Excluding here rather than in a + * `ITreeFilter` keeps one rule: what the data source returns is what the tree + * holds, which is what reveal can reach. + */ +class ReviewExplorerDataSource implements IAsyncDataSource { + private readonly stats = new Map(); + + constructor( + private readonly excludes: ResourceGlobMatcher, + private readonly logService: ILogService, + private readonly apiSource: IReviewApiSourceService, + ) { } + + hasChildren(element: URI | null | IFileStat): boolean { + if (element === null) { + return false; + } + return URI.isUri(element) ? true : element.isDirectory; + } + + async getChildren(element: URI | null | IFileStat): Promise { + if (element === null) { + return []; // no active review, so no tree + } + + const resource = URI.isUri(element) ? element : element.resource; + try { + const siblings = await this.apiSource.children(resource); + // One name set for the whole directory. A `files.exclude` `when` clause + // asks whether a sibling exists, and it is asked once per child, so + // scanning the sibling array each time would be quadratic. + const siblingNames = new Set(siblings.map((sibling) => basename(sibling.resource))); + const children = siblings.filter( + (child) => !this.excludes.matches(child.resource, (name) => siblingNames.has(name)), + ); + for (const child of children) { + this.stats.set(child.resource.path, child); + } + return children.sort(compareReviewExplorerStats); + } catch (error) { + // Keep other directories usable when a pinned source request fails. + this.logService.trace(`[review] explorer cannot resolve ${resource.fsPath}: ${error}`); + return []; + } + } + + statFor(resource: URI): IFileStat | undefined { + return this.stats.get(resource.path); + } + + reset(): void { + this.stats.clear(); + } +} + +function compareReviewExplorerStats(one: IFileStat, other: IFileStat): number { + if (one.isDirectory !== other.isDirectory) { + return one.isDirectory ? -1 : 1; + } + return compareFileNamesDefault(basename(one.resource), basename(other.resource)); +} + +class ReviewExplorerRenderer extends Disposable implements ITreeRenderer { + readonly templateId = REVIEW_EXPLORER_TEMPLATE_ID; + + private readonly labels: ResourceLabels; + + constructor(@IInstantiationService instantiationService: IInstantiationService) { + super(); + this.labels = this._register(instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER)); + } + + renderTemplate(container: HTMLElement): IReviewExplorerTemplate { + return { label: this.labels.create(container, { supportHighlights: true }) }; + } + + renderElement(node: ITreeNode, _index: number, template: IReviewExplorerTemplate): void { + template.label.setFile(node.element.resource, { + fileKind: node.element.isDirectory ? FileKind.FOLDER : FileKind.FILE, + fileDecorations: { colors: false, badges: false }, + // The tree already shows the path through its indentation, so the + // parent-folder description `setFile` adds by default is noise. + hidePath: true, + }); + } + + disposeTemplate(template: IReviewExplorerTemplate): void { + template.label.dispose(); + } +} + +const reviewExplorerAccessibilityProvider: IListAccessibilityProvider = { + getWidgetAriaLabel: () => localize("review.explorer.ariaLabel", "Review Files"), + getAriaLabel: (element: IFileStat) => basename(element.resource), +}; + +/** + * The read-only file tree that sits left of a full-screened reviewed file. + * + * Review reviews a pinned snapshot worktree, so this part deliberately is not + * the stock explorer view: it offers no rename, delete, cut/paste, new-file or + * drag-and-drop, and it never writes. It is a `WorkbenchAsyncDataTree` over + * `IFileService`, which keeps virtualization, keyboard navigation, type-ahead + * find, file icons and the `workbench.list.*` settings on stock components. + */ +export class ReviewExplorerPart extends Part { + override readonly minimumWidth = 170; + override readonly maximumWidth = 480; + override readonly minimumHeight = 0; + override readonly maximumHeight = Number.POSITIVE_INFINITY; + + /** + * Dragging the sash past half the minimum width collapses the leaf instead of + * pinning it at 170px. The split view calls `setVisible` to do that, so the + * collapse arrives as an ordinary part visibility change and + * `ReviewExplorerParts` records it as a user close. + */ + readonly snap = true; + + /** `null` while no review is active, which renders an empty tree. */ + private tree: WorkbenchAsyncDataTree | undefined; + private dataSource: ReviewExplorerDataSource | undefined; + private root: URI | undefined; + + /** Serializes reveals and re-roots so two walks cannot interleave expands. */ + private readonly sequencer = new Sequencer(); + + constructor( + @IThemeService themeService: IThemeService, + @IStorageService storageService: IStorageService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IEditorService private readonly editorService: IEditorService, + @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @ILogService private readonly logService: ILogService, + @IReviewApiSourceService private readonly apiSource: IReviewApiSourceService, + @IReviewApiCatalogService private readonly catalog: IReviewApiCatalogService, + @IReviewCanvasEditorTabsService private readonly tabsService: IReviewCanvasEditorTabsService, + ) { + super( + Parts.REVIEW_EXPLORER_PART, + { hasTitle: false, borderWidth: () => 0 }, + themeService, + storageService, + layoutService, + ); + } + + override create(parent: HTMLElement): void { + this.element = parent; + super.create(parent); + } + + protected override createContentArea(parent: HTMLElement): HTMLElement { + // Publish the chrome row height so review.css sizes the spacer from the same + // constant this part lays the tree out with, rather than a second literal. + parent.style.setProperty("--review-chrome-height", `${REVIEW_CHROME_HEIGHT}px`); + + // The macOS traffic lights float over the top-left of the window, and the + // explorer is the leftmost surface, so reserve the one chrome row for them + // and let the reserved strip drag the window. + parent.appendChild($(".review-explorer-chrome-spacer")); + + const workspaceTreeContainer = $(".review-explorer-tree.review-explorer-workspace-tree"); + parent.appendChild(workspaceTreeContainer); + this.createWorkspaceTree(workspaceTreeContainer); + + return parent; + } + + private createWorkspaceTree(treeContainer: HTMLElement): void { + this._register(createFileIconThemableTreeContainerScope(treeContainer, this.themeService)); + + // `ResourceGlobMatcher` owns the whole `files.exclude` story: per-folder + // expressions, the absolute-to-relative conversion the globs need, the + // configuration listener, and the workspace-folder listener. That last one is + // why nothing here has to rebuild the patterns when the active review + // changes the root. + const excludes = this._register( + this.instantiationService.createInstance( + ResourceGlobMatcher, + (folder?: URI) => this.configurationService.getValue({ resource: folder }).files?.exclude, + (event: IConfigurationChangeEvent) => event.affectsConfiguration(FILES_EXCLUDE_CONFIG), + ), + ); + + const dataSource = new ReviewExplorerDataSource(excludes, this.logService, this.apiSource); + this.dataSource = dataSource; + + // A settings change can hide a folder that is currently expanded, so rebuild + // every resolved level rather than trying to patch the tree in place. + this._register(excludes.onExpressionChange(() => this.refreshTree())); + + const renderer = this._register(this.instantiationService.createInstance(ReviewExplorerRenderer)); + const tree = this._register( + this.instantiationService.createInstance( + WorkbenchAsyncDataTree, + "ReviewExplorer", + treeContainer, + reviewExplorerDelegate, + [renderer], + dataSource, + { + identityProvider: { getId: (stat: IFileStat) => `${this.root?.toString()}/${stat.resource.path}` }, + accessibilityProvider: reviewExplorerAccessibilityProvider, + keyboardNavigationLabelProvider: { + getKeyboardNavigationLabel: (stat: IFileStat) => basename(stat.resource), + }, + multipleSelectionSupport: false, + // A repository root has too many folders to auto-expand any of them. + collapseByDefault: () => true, + }, + ), + ); + this.tree = tree; + + this._register( + tree.onDidOpen((event) => { + const stat = event.element; + if (!stat || stat.isDirectory) { + return; + } + + // Register the tab against the review it belongs to, so dismissing + // or deleting the review closes it — the same lifecycle the + // changed-files tree's diff tabs get from `reviewDiffTabs`. + const reviewId = stat.resource.scheme === REVIEW_API_SOURCE_SCHEME ? stat.resource.authority : undefined; + void Promise.resolve( + this.editorService.openEditor( + { + resource: stat.resource, + options: { + pinned: event.editorOptions.pinned, + preserveFocus: event.editorOptions.preserveFocus, + revealIfVisible: true, + }, + }, + this.editorGroupsService.mainPart.activeGroup, + ), + ).then((pane) => { + if (pane?.input && reviewId) { + this.tabsService.registerReviewEditor(reviewId, pane.input); + } + }); + }), + ); + + this._register(this.editorService.onDidActiveEditorChange(() => this.updateRoot())); + let revision: string | undefined; + this._register(this.catalog.onDidChange(() => { + if (!this.root || sourceTreeSelection(this.root).kind !== "current") return; + const review = this.catalog.reviews.find(review => review.reviewId === this.root!.authority); + const next = JSON.stringify([review?.reviewId, review?.version, review?.pins?.worktreeRevision]); + if (next === revision) return; + revision = next; + this.refreshTree(); + })); + + this.root = undefined; + this.updateRoot(); + } + + /** Re-resolves every expanded level, for when what the tree may show changes. */ + private refreshTree(): void { + if (!this.tree) { + return; + } + + this.sequencer + .queue(async () => { + this.dataSource?.reset(); + await this.tree?.updateChildren(undefined, true); + }) + .catch((error) => this.logService.trace(`[review] explorer cannot refresh: ${error}`)); + } + + private updateRoot(): void { + const input = this.editorService.activeEditor; + const resource = EditorResourceAccessor.getCanonicalUri(input, { supportSideBySide: SideBySideEditor.PRIMARY }); + const folder = + input instanceof ReviewCanvasEditorInput && input.target.kind === "api-source" + ? sourceTreeUri(input.target.selection) + : resource?.scheme === REVIEW_API_SOURCE_SCHEME + ? sourceTreeRoot(resource, this.root) + : undefined; + if (folder && this.root && isEqual(folder, this.root)) { + return; + } + + this.root = folder; + + this.sequencer + .queue(async () => { + const tree = this.tree; + if (!tree) { + return; + } + + this.dataSource?.reset(); + await tree.setInput(folder ?? null); + }) + .catch((error) => this.logService.trace(`[review] explorer cannot root at ${folder?.fsPath}: ${error}`)); + } + + /** + * Expands the tree down to `resource` and selects it. + * + * Every step is a no-op when it cannot be met — a resource outside the root, a + * missing ancestor stat — because the caller is an active-editor change, and a + * resource the tree does not hold is not a failure. + */ + revealResource(resource: URI | undefined): void { + const root = this.root; + if (resource && root && resource.scheme === REVIEW_API_SOURCE_SCHEME && sourceTreeRoot(resource, root).toString() === root.toString()) { + // A base-side or commit-scoped editor still belongs to the selected tree. + resource = resource.with({ scheme: root.scheme, query: root.query }); + } + if (!resource || !root || !isEqualOrParent(resource, root)) { + return; + } + + this.sequencer + .queue(async () => { + const tree = this.tree; + const dataSource = this.dataSource; + if (!tree || !dataSource || !this.root || !isEqual(this.root, root)) { + return; + } + + // Walk root -> resource so each expand resolves the level that holds the + // next ancestor. The data source records those stats as it goes, which is + // the only way the next step can find its element. + for (const ancestor of ancestorsBetween(root, resource)) { + const stat = dataSource.statFor(ancestor); + if (!stat) { + return; + } + await tree.expand(stat); + } + + const target = dataSource.statFor(resource); + if (!target) { + return; + } + + tree.setSelection([target]); + tree.setFocus([target]); + tree.reveal(target); + }) + .catch((error) => this.logService.trace(`[review] explorer cannot reveal ${resource.fsPath}: ${error}`)); + } + + setActiveResource(resource: URI | undefined): void { + this.revealResource(resource); + } + + override layout(width: number, height: number, top: number, left: number): void { + super.layout(width, height, top, left); + + const contentHeight = Math.max(0, height - REVIEW_CHROME_HEIGHT); + // Both trees, visible or not: a hidden tree that skipped layout would + // come back with stale zero dimensions and render no rows. + this.tree?.layout(contentHeight, width); + } + + toJSON(): object { + return { type: Parts.REVIEW_EXPLORER_PART }; + } +} + +/** + * The directories between `root` (exclusive) and `resource` (exclusive), nearest + * the root first. Expanding them in this order reveals `resource`. + */ +function ancestorsBetween(root: URI, resource: URI): URI[] { + const ancestors: URI[] = []; + let current = dirname(resource); + while (!isEqual(current, root)) { + ancestors.unshift(current); + const parent = dirname(current); + if (isEqual(parent, current)) { + return []; // walked past the root; nothing to expand + } + current = parent; + } + return ancestors; +} + +export const IReviewExplorerPartsService = createDecorator("reviewExplorerPartsService"); + +export interface IReviewExplorerPartsService { + readonly _serviceBrand: undefined; + + /** + * Closes the file tree when it is open, reopens it when it is closed. A no-op + * unless the active editor is one the tree accompanies. + */ + toggle(): void; + + /** + * Clears a sticky close so the tree accompanies the active editor. The + * "Open source tree" CTAs call this after opening the Source tab, so the + * CTA always reveals the tree even after the user dismissed it. + */ + show(): void; +} + +/** Marks the workbench while the tree has a tab to accompany, so the toolbar toggle can fade in. */ +const REVIEW_EXPLORER_AVAILABLE_CLASS = "review-explorer-available"; + +/** Remembers a close across reloads. Workspace-scoped: it is a per-review preference. */ +const REVIEW_EXPLORER_USER_CLOSED_KEY = "review.explorer.userClosed"; + +/** + * Creates the explorer part and owns its show/hide policy. + * + * The part is a grid leaf, so the grid — not the editor — decides how much room + * the file surface gets. This service is the only thing that toggles it. It is + * eager so the part registers itself before `renderWorkbench` looks it up. + * + * Visibility has two inputs: + * + * - `available` — the active editor shows a file from disk, per + * {@link accompaniesEditor}. Derived, never persisted, and what the toolbar + * toggle fades in on. + * - `userClosed` — the user dismissed the tree. This *is* persisted, because a + * close is a decision rather than derived state: it has to survive the next tab + * switch, the next session, and a reload. See the note in + * `common/reviewWorkbenchVisibility.ts`. + * + * The tree shows only when it is available and not closed. + */ +export class ReviewExplorerParts extends Disposable implements IReviewExplorerPartsService { + declare readonly _serviceBrand: undefined; + + private readonly part: ReviewExplorerPart; + + private available = false; + private userClosed: boolean; + + /** + * Set while this service is driving the grid, so the part-visibility listener + * below does not read our own `setPartHidden` back as a user action. + */ + private applying = false; + + constructor( + @IInstantiationService instantiationService: IInstantiationService, + @IEditorService private readonly editorService: IEditorService, + @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, + @IStorageService private readonly storageService: IStorageService, + ) { + super(); + this.part = this._register(instantiationService.createInstance(ReviewExplorerPart)); + this.userClosed = this.storageService.getBoolean(REVIEW_EXPLORER_USER_CLOSED_KEY, StorageScope.WORKSPACE, false); + + this._register(this.editorService.onDidActiveEditorChange(() => this.update())); + + // A sash drag past the snap threshold collapses the leaf through the grid, + // never through `toggle`. Treat any hide that arrives while the tree is + // available as the user closing it, so dragging it shut is as sticky as + // pressing the button. + this._register( + this.layoutService.onDidChangePartVisibility((event) => { + if (this.applying || event.partId !== Parts.REVIEW_EXPLORER_PART || !this.available) { + return; + } + this.setUserClosed(!event.visible); + }), + ); + + // The grid starts the leaf hidden on every launch, so a restored file + // editor needs this one run to bring it back. + this.update(); + } + + toggle(): void { + if (!this.available) { + return; + } + + this.setUserClosed(!this.userClosed); + this.update(); + } + + show(): void { + this.setUserClosed(false); + this.update(); + } + + private setUserClosed(userClosed: boolean): void { + if (this.userClosed === userClosed) { + return; + } + + this.userClosed = userClosed; + this.storageService.store( + REVIEW_EXPLORER_USER_CLOSED_KEY, + userClosed, + StorageScope.WORKSPACE, + StorageTarget.MACHINE, + ); + } + + private update(): void { + const input = this.editorService.activeEditor ?? undefined; + this.available = accompaniesEditor(input); + const visible = this.available && !this.userClosed; + + this.layoutService.mainContainer.classList.toggle(REVIEW_EXPLORER_AVAILABLE_CLASS, this.available); + + this.applying = true; + try { + this.layoutService.setPartHidden(!visible, Parts.REVIEW_EXPLORER_PART); + } finally { + this.applying = false; + } + + if (!visible) { + return; + } + + this.part.setActiveResource( + EditorResourceAccessor.getCanonicalUri(input, { + supportSideBySide: SideBySideEditor.PRIMARY, + }), + ); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/reviewLinuxTitlebar.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/reviewLinuxTitlebar.ts new file mode 100644 index 000000000..1e534652a --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/reviewLinuxTitlebar.ts @@ -0,0 +1,101 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from '../../../nls.js'; +import { Separator, toAction } from '../../../base/common/actions.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; +import { ThemeIcon } from '../../../base/common/themables.js'; +import { Codicon } from '../../../base/common/codicons.js'; +import { $, addDisposableListener, append, getWindowId } from '../../../base/browser/dom.js'; +import { renderIcon } from '../../../base/browser/ui/iconLabel/iconLabels.js'; +import { CodeWindow } from '../../../base/browser/window.js'; +import { ICommandService } from '../../../platform/commands/common/commands.js'; +import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js'; +import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; +import { IConfigurationService } from '../../../platform/configuration/common/configuration.js'; +import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js'; +import { INativeHostService } from '../../../platform/native/common/native.js'; +import { INotificationService } from '../../../platform/notification/common/notification.js'; +import { WindowControlsStyle, getWindowControlsStyle } from '../../../platform/window/common/window.js'; + +/** Linux has no macOS application menu. Keep its commands next to navigation. */ +export class ReviewLinuxTitlebar extends Disposable { + constructor( + left: HTMLElement, + controls: HTMLElement | undefined, + targetWindow: CodeWindow, + @ICommandService commandService: ICommandService, + @IContextMenuService contextMenuService: IContextMenuService, + @IKeybindingService keybindingService: IKeybindingService, + @IDialogService dialogService: IDialogService, + @IConfigurationService configurationService: IConfigurationService, + @INativeHostService nativeHostService: INativeHostService, + @INotificationService notificationService: INotificationService, + ) { + super(); + const menu = append(left, $('button.review-application-menu', { + type: 'button', title: localize('review.menu.title', "Review menu (F10)"), + 'aria-label': localize('review.menu.label', "Review menu"), 'aria-haspopup': 'menu', 'aria-expanded': 'false', + })); + append(menu, renderIcon(Codicon.menu)); + let dialogOpen = false; + this._register(dialogService.onWillShowDialog(() => { dialogOpen = true; })); + this._register(dialogService.onDidShowDialog(() => { dialogOpen = false; })); + const command = (id: string, label: string) => toAction({ id, label, run: () => commandService.executeCommand(id) }); + const showMenu = () => { + if (dialogOpen || menu.getAttribute('aria-expanded') === 'true') { return; } + menu.setAttribute('aria-expanded', 'true'); + contextMenuService.showContextMenu({ + getAnchor: () => menu, + autoSelectFirstItem: true, + getActions: () => [ + command('workbench.action.showCommands', localize('review.menu.commands', "Command Palette...")), + command('review.openSettings', localize('review.menu.settings', "Settings...")), + command('review.manageExtensions', localize('review.menu.extensions', "Manage Extensions...")), + command('review.openWelcome', localize('review.menu.welcome', "Getting Started...")), + new Separator(), + command('review.checkForUpdates', localize('review.menu.updates', "Check for Updates...")), + toAction({ id: 'review.about', label: localize('review.menu.about', "About Review"), run: () => dialogService.about() }), + new Separator(), + command('workbench.action.quit', localize('review.menu.quit', "Quit Review")), + ], + getKeyBinding: action => keybindingService.lookupKeybinding(action.id), + onHide: () => { menu.setAttribute('aria-expanded', 'false'); menu.focus(); }, + }); + }; + this._register(addDisposableListener(menu, 'click', showMenu)); + this._register(addDisposableListener(menu, 'keydown', event => { + if (event.key === 'ArrowDown') { event.preventDefault(); showMenu(); } + })); + this._register(addDisposableListener(targetWindow, 'keydown', event => { + if (event.key === 'F10' && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) { + event.preventDefault(); event.stopPropagation(); showMenu(); + } + }, true)); + if (!controls || getWindowControlsStyle(configurationService) !== WindowControlsStyle.CUSTOM) { return; } + const options = { targetWindowId: getWindowId(targetWindow) }; + const button = (label: string, icon: ThemeIcon, run: () => Promise, close = false) => { + const element = append(controls, $('button.window-icon', { type: 'button', 'aria-label': label, title: label })); + if (close) { element.classList.add('window-close'); } + append(element, renderIcon(icon)); + this._register(addDisposableListener(element, 'click', () => { void run().catch(error => notificationService.error(error)); })); + return element; + }; + button(localize('review.window.minimize', "Minimize"), Codicon.chromeMinimize, () => nativeHostService.minimizeWindow(options)); + let maximized = false; + const maximize = button(localize('review.window.maximize', "Maximize"), Codicon.chromeMaximize, + () => maximized ? nativeHostService.unmaximizeWindow(options) : nativeHostService.maximizeWindow(options)); + const updateMaximized = (value: boolean) => { + maximized = value; + maximize.replaceChildren(renderIcon(value ? Codicon.chromeRestore : Codicon.chromeMaximize)); + const label = value ? localize('review.window.restore', "Restore") : localize('review.window.maximize', "Maximize"); + maximize.title = label; maximize.setAttribute('aria-label', label); + }; + this._register(nativeHostService.onDidMaximizeWindow(id => { if (id === options.targetWindowId) { updateMaximized(true); } })); + this._register(nativeHostService.onDidUnmaximizeWindow(id => { if (id === options.targetWindowId) { updateMaximized(false); } })); + void nativeHostService.isMaximized(options).then(updateMaximized, error => notificationService.error(error)); + button(localize('review.window.close', "Close"), Codicon.chromeClose, () => nativeHostService.closeWindow(options), true); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/parts/reviewTitlebarPart.ts b/apps/review-desktop/code-oss/src/vs/review/browser/parts/reviewTitlebarPart.ts new file mode 100644 index 000000000..3767c54d9 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/parts/reviewTitlebarPart.ts @@ -0,0 +1,376 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import '../../../workbench/browser/parts/titlebar/media/titlebarpart.css'; +import '../media/review.css'; +import { localize } from '../../../nls.js'; +import { MultiWindowParts, Part } from '../../../workbench/browser/part.js'; +import { ITitleService } from '../../../workbench/services/title/browser/titleService.js'; +import { getWCOTitlebarAreaRect, getZoomFactor, isFullscreen, isWCOEnabled, onDidChangeFullscreen } from '../../../base/browser/browser.js'; +import { TitlebarStyle, WindowControlsStyle, getTitleBarStyle, getWindowControlsStyle, hasCustomTitlebar, hasNativeTitlebar } from '../../../platform/window/common/window.js'; +import { REVIEW_CHROME_HEIGHT } from '../../common/reviewChrome.js'; +import { IConfigurationService } from '../../../platform/configuration/common/configuration.js'; +import { DisposableStore, toDisposable } from '../../../base/common/lifecycle.js'; +import { IThemeService } from '../../../platform/theme/common/themeService.js'; +import { EDITOR_GROUP_HEADER_TABS_BACKGROUND, TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_INACTIVE_FOREGROUND } from '../../../workbench/common/theme.js'; +import { isLinux, isMacintosh, isNative, isWeb, platformLocale } from '../../../base/common/platform.js'; +import { $, addDisposableListener, append, getWindow, getWindowId, prepend } from '../../../base/browser/dom.js'; +import { renderIcon } from '../../../base/browser/ui/iconLabel/iconLabels.js'; +import { Codicon } from '../../../base/common/codicons.js'; +import { KeyCode } from '../../../base/common/keyCodes.js'; +import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js'; +import { ICommandService } from '../../../platform/commands/common/commands.js'; +import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; +import { Emitter, Event } from '../../../base/common/event.js'; +import { IStorageService } from '../../../platform/storage/common/storage.js'; +import { IWorkbenchLayoutService, Parts } from '../../../workbench/services/layout/browser/layoutService.js'; +import { IHostService } from '../../../workbench/services/host/browser/host.js'; +import { IEditorGroupsContainer } from '../../../workbench/services/editor/common/editorGroupsService.js'; +import { CodeWindow, mainWindow } from '../../../base/browser/window.js'; +import { safeIntl } from '../../../base/common/date.js'; +import { IAuxiliaryTitlebarPart, ITitleProperties, ITitleVariable, ITitlebarPart } from '../../../workbench/browser/parts/titlebar/titlebarPart.js'; +import { WindowTitle } from '../../../workbench/browser/parts/titlebar/windowTitle.js'; +import { CommandCenterControl } from '../../../workbench/browser/parts/titlebar/commandCenterControl.js'; +import { INativeHostService } from '../../../platform/native/common/native.js'; +import { getDefaultHoverDelegate } from '../../../base/browser/ui/hover/hoverDelegateFactory.js'; +import { ReviewLinuxTitlebar } from './reviewLinuxTitlebar.js'; + +/** + * The deliberately small Review titlebar. It owns the drag region and the macOS + * traffic-light inset while reusing VS Code's native navigation control. The + * navigation control sits at the left, directly after the traffic lights, where + * macOS applications put their back and forward arrows. The bar carries no + * product label: the branding lives in the macOS application menu. + */ +export class ReviewTitlebarPart extends Part implements ITitlebarPart { + + readonly minimumWidth = 0; + readonly maximumWidth = Number.POSITIVE_INFINITY; + + get minimumHeight(): number { + const wcoHeight = isWeb && isWCOEnabled() + ? getWCOTitlebarAreaRect(getWindow(this.element))?.height ?? 0 + : 0; + return Math.max(REVIEW_CHROME_HEIGHT, wcoHeight) / (this.preventZoom ? getZoomFactor(getWindow(this.element)) : 1); + } + + get maximumHeight(): number { return this.minimumHeight; } + + private readonly _onMenubarVisibilityChange = this._register(new Emitter()); + readonly onMenubarVisibilityChange = this._onMenubarVisibilityChange.event; + + private readonly _onWillDispose = this._register(new Emitter()); + readonly onWillDispose = this._onWillDispose.event; + + protected rootContainer!: HTMLElement; + protected windowControlsContainer: HTMLElement | undefined; + private leftContent!: HTMLElement; + private rightContent!: HTMLElement; + + get leftContainer(): HTMLElement { return this.leftContent; } + get rightContainer(): HTMLElement { return this.rightContent; } + get rightWindowControlsContainer(): HTMLElement | undefined { return this.windowControlsContainer; } + + private readonly titleBarStyle: TitlebarStyle; + private isInactive = false; + + constructor( + id: string, + targetWindow: CodeWindow, + @IConfigurationService protected readonly configurationService: IConfigurationService, + @IThemeService themeService: IThemeService, + @IStorageService storageService: IStorageService, + @IWorkbenchLayoutService protected override readonly layoutService: IWorkbenchLayoutService, + @IHostService hostService: IHostService, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @ICommandService private readonly commandService: ICommandService, + ) { + super(id, { hasTitle: false }, themeService, storageService, layoutService); + this.titleBarStyle = getTitleBarStyle(configurationService); + + const targetWindowId = getWindowId(targetWindow); + this._register(hostService.onDidChangeFocus(focused => this.setInactive(!focused))); + this._register(hostService.onDidChangeActiveWindow(windowId => this.setInactive(windowId !== targetWindowId))); + } + + private setInactive(inactive: boolean): void { + this.isInactive = inactive; + this.updateStyles(); + } + + updateProperties(_properties: ITitleProperties): void { } + registerVariables(_variables: ITitleVariable[]): void { } + updateOptions(_options: { compact: boolean }): void { } + + protected get paintsBackground(): boolean { return true; } + + protected override createContentArea(parent: HTMLElement): HTMLElement { + this.element = parent; + this.rootContainer = append(parent, $('.titlebar-container.review-titlebar-container')); + prepend(this.rootContainer, $('div.titlebar-drag-region')); + + this.leftContent = append(this.rootContainer, $('.titlebar-left')); + this.rightContent = append(this.rootContainer, $('.titlebar-right')); + + // The window controls come first so the traffic-light inset stays to the + // left of the navigation control that the block below appends. + if (!hasNativeTitlebar(this.configurationService, this.titleBarStyle)) { + let controlsLocation: 'left' | 'right' = isMacintosh ? 'left' : 'right'; + if (isMacintosh && isNative) { + const localeInfo = safeIntl.Locale(platformLocale).value; + if ((localeInfo as { textInfo?: { direction?: string } }).textInfo?.direction === 'rtl') { + controlsLocation = 'right'; + } + } + + if (isMacintosh && isNative && controlsLocation === 'left') { + const spacer = append(this.leftContent, $('div.window-controls-container.review-traffic-light-inset')); + const updateSpacer = () => { + const fullscreen = isFullscreen(mainWindow); + spacer.style.display = fullscreen ? 'none' : ''; + spacer.style.width = fullscreen ? '0' : '70px'; + }; + updateSpacer(); + this._register(onDidChangeFullscreen(windowId => { + if (windowId === getWindowId(mainWindow)) { + updateSpacer(); + } + })); + } else if (getWindowControlsStyle(this.configurationService) !== WindowControlsStyle.HIDDEN) { + const controlsParent = controlsLocation === 'left' ? this.leftContent : this.rightContent; + this.windowControlsContainer = append(controlsParent, $('div.window-controls-container')); + if (isWeb) { + append(controlsLocation === 'left' ? this.rightContent : this.leftContent, $('div.window-controls-container')); + } + if (isWCOEnabled()) { + this.windowControlsContainer.classList.add('wco-enabled'); + } + } + } + + if (isLinux && isNative) { + this._register(this.instantiationService.createInstance(ReviewLinuxTitlebar, this.leftContent, this.windowControlsContainer, getWindow(parent))); + } + const navigationContainer = append(this.leftContent, $('div.review-titlebar-navigation')); + const windowTitle = this._register(this.instantiationService.createInstance(WindowTitle, getWindow(parent))); + const navigationControl = this._register(this.instantiationService.createInstance( + CommandCenterControl, + windowTitle, + getDefaultHoverDelegate('mouse'), + )); + append(navigationContainer, navigationControl.element); + this.createFileTreeToggle(); + + this.updateStyles(); + return this.element; + } + + /** + * The file-tree toggle, right of the navigation arrows. + * + * The button holds a fixed 22px slot at all times, even with no tree to + * toggle. That keeps the left cluster a constant width, and the cluster width + * is what `--review-chrome-left-width` reports to the editor tab strip — so + * fading the button in never moves a tab. Both icons render here and CSS picks + * one, which keeps this part free of any explorer state subscription. + */ + private createFileTreeToggle(): void { + const toggle = append(this.leftContent, $('div.review-titlebar-file-tree-toggle', { + role: 'button', + tabindex: '0', + title: localize('review.toggleFileTree.tooltip', "Toggle File Tree"), + 'aria-label': localize('review.toggleFileTree.tooltip', "Toggle File Tree"), + })); + + append(toggle, renderIcon(Codicon.layoutSidebarLeft)).classList.add('review-file-tree-icon-open'); + append(toggle, renderIcon(Codicon.layoutSidebarLeftOff)).classList.add('review-file-tree-icon-closed'); + + const run = () => void this.commandService.executeCommand('review.toggleFileTree'); + this._register(addDisposableListener(toggle, 'click', run)); + this._register(addDisposableListener(toggle, 'keydown', event => { + const keyboardEvent = new StandardKeyboardEvent(event); + if (keyboardEvent.equals(KeyCode.Enter) || keyboardEvent.equals(KeyCode.Space)) { + keyboardEvent.preventDefault(); + keyboardEvent.stopPropagation(); + run(); + } + })); + } + + override updateStyles(): void { + super.updateStyles(); + if (!this.element) { + return; + } + + this.element.classList.toggle('inactive', this.isInactive); + this.element.style.backgroundColor = this.paintsBackground + ? this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND) || '' + : ''; + this.element.style.color = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_FOREGROUND : TITLE_BAR_ACTIVE_FOREGROUND) || ''; + } + + get hasZoomableElements(): boolean { return false; } + get preventZoom(): boolean { return true; } + + override layout(width: number, height: number): void { + if (hasCustomTitlebar(this.configurationService, this.titleBarStyle)) { + const zoomFactor = getZoomFactor(getWindow(this.element)); + this.element.style.setProperty('--zoom-factor', zoomFactor.toString()); + this.rootContainer.classList.toggle('counter-zoom', this.preventZoom); + } + super.layoutContents(width, height); + } + + focus(): void { } + toJSON(): object { return { type: Parts.TITLEBAR_PART }; } + + override dispose(): void { + this._onWillDispose.fire(); + super.dispose(); + } +} + +export class MainReviewTitlebarPart extends ReviewTitlebarPart { + protected override get paintsBackground(): boolean { return false; } + + override updateStyles(): void { + super.updateStyles(); + if (isLinux && this.element && this.nativeHostService) { + void this.nativeHostService.updateWindowControls({ + targetWindowId: getWindowId(mainWindow), + backgroundColor: this.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND) ?? undefined, + foregroundColor: this.element.style.color, + }); + } + } + + + override layout(width: number, height: number): void { + super.layout(width, height); + void this.nativeHostService.updateWindowControls({ + targetWindowId: getWindowId(mainWindow), + height: Math.round(REVIEW_CHROME_HEIGHT * getZoomFactor(mainWindow)) + }); + } + + private readonly _onDidChangeChromeInsets = this._register(new Emitter()); + readonly onDidChangeChromeInsets = this._onDidChangeChromeInsets.event; + + /** Left and right window-chrome cluster widths, in CSS pixels. */ + readonly chromeInsets = { left: 0, right: 0 }; + + protected override createContentArea(parent: HTMLElement): HTMLElement { + const element = super.createContentArea(parent); + // Written on this part, never the workbench root; see + // `publishReviewChromeInset` for why. + const updateChromeWidths = () => { + const left = this.leftContainer.getBoundingClientRect().width; + const right = this.rightContainer.getBoundingClientRect().width; + if (left === this.chromeInsets.left && right === this.chromeInsets.right) { + return; + } + this.chromeInsets.left = left; + this.chromeInsets.right = right; + this.element.style.setProperty('--review-chrome-left-width', `${left}px`); + this.element.style.setProperty('--review-chrome-right-width', `${right}px`); + this._onDidChangeChromeInsets.fire(); + }; + const observer = new ResizeObserver(updateChromeWidths); + observer.observe(this.leftContainer); + observer.observe(this.rightContainer); + this._register(toDisposable(() => observer.disconnect())); + updateChromeWidths(); + + return element; + } + + constructor( + @IConfigurationService configurationService: IConfigurationService, + @IThemeService themeService: IThemeService, + @IStorageService storageService: IStorageService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @IHostService hostService: IHostService, + @IInstantiationService instantiationService: IInstantiationService, + @ICommandService commandService: ICommandService, + @INativeHostService private readonly nativeHostService: INativeHostService, + ) { + super(Parts.TITLEBAR_PART, mainWindow, configurationService, themeService, storageService, layoutService, hostService, instantiationService, commandService); + } +} + +export class AuxiliaryReviewTitlebarPart extends ReviewTitlebarPart implements IAuxiliaryTitlebarPart { + private static counter = 1; + get height(): number { return this.minimumHeight; } + + constructor( + readonly container: HTMLElement, + private readonly mainTitlebar: ReviewTitlebarPart, + @IConfigurationService configurationService: IConfigurationService, + @IThemeService themeService: IThemeService, + @IStorageService storageService: IStorageService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @IHostService hostService: IHostService, + @IInstantiationService instantiationService: IInstantiationService, + @ICommandService commandService: ICommandService, + ) { + super(`workbench.parts.auxiliaryTitle.${AuxiliaryReviewTitlebarPart.counter++}`, getWindow(container), configurationService, themeService, storageService, layoutService, hostService, instantiationService, commandService); + } + + override get preventZoom(): boolean { + return getZoomFactor(getWindow(this.element)) < 1 || !this.mainTitlebar.hasZoomableElements; + } +} + +export class ReviewTitleService extends MultiWindowParts implements ITitleService { + declare _serviceBrand: undefined; + readonly mainPart: ReviewTitlebarPart; + readonly onMenubarVisibilityChange: Event; + + constructor( + @IInstantiationService protected readonly instantiationService: IInstantiationService, + @IStorageService storageService: IStorageService, + @IThemeService themeService: IThemeService, + ) { + super('workbench.reviewTitleService', themeService, storageService); + this.mainPart = this._register(this.instantiationService.createInstance(MainReviewTitlebarPart)); + this.onMenubarVisibilityChange = this.mainPart.onMenubarVisibilityChange; + this._register(this.registerPart(this.mainPart)); + } + + createAuxiliaryTitlebarPart(container: HTMLElement, _editorGroupsContainer: IEditorGroupsContainer, instantiationService: IInstantiationService): IAuxiliaryTitlebarPart { + const partContainer = $('.part.titlebar', { role: 'none' }); + partContainer.style.position = 'relative'; + container.insertBefore(partContainer, container.firstChild); + + const disposables = new DisposableStore(); + const part = instantiationService.createInstance(AuxiliaryReviewTitlebarPart, partContainer, this.mainPart); + disposables.add(this.registerPart(part)); + disposables.add(Event.runAndSubscribe(part.onDidChange, () => partContainer.style.height = `${part.height}px`)); + part.create(partContainer); + Event.once(part.onWillDispose)(() => disposables.dispose()); + return part; + } + + updateProperties(properties: ITitleProperties): void { + for (const part of this.parts) { + part.updateProperties(properties); + } + } + + registerVariables(variables: ITitleVariable[]): void { + for (const part of this.parts) { + part.registerVariables(variables); + } + } + + private _windowTitle: WindowTitle | undefined; + get windowTitle(): WindowTitle { + if (!this._windowTitle) { + this._windowTitle = this._register(this.instantiationService.createInstance(WindowTitle, mainWindow)); + } + return this._windowTitle; + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewChangedFilesTree.test.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewChangedFilesTree.test.ts new file mode 100644 index 000000000..762449ee5 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewChangedFilesTree.test.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import { createRequire, registerHooks } from 'node:module'; +import test from 'node:test'; + +import type { ReviewDiffFileWire, ReviewDiffProgressFile, StructuralLineCounts } from '../common/reviewProtocol.js'; + +// jsdom ships no types here; the DOM globals below are all this test reads from it. +const { JSDOM } = createRequire(import.meta.url)('jsdom'); +const dom = new JSDOM(''); +for (const key of ['window', 'document', 'HTMLElement', 'HTMLCanvasElement', 'Node', 'MutationObserver', 'Element', 'navigator', 'customElements', 'UIEvent', 'MouseEvent', 'KeyboardEvent'] as const) { + Object.defineProperty(globalThis, key, { configurable: true, value: dom.window[key] }); +} +dom.window.matchMedia = () => ({ matches: false, addEventListener() { }, removeEventListener() { } }) as never; +registerHooks({ load(url, context, next) { + return url.endsWith('.css') ? { format: 'module', source: '', shortCircuit: true } : next(url, context); +} }); +const { ChangedFilesTreeRenderer } = await import('./reviewChangedFilesTree.js'); + +const file = (path: string): ReviewDiffFileWire => ({ path, status: 'modified', additions: 3, deletions: 1 } as ReviewDiffFileWire); +const progress = (path: string, state: ReviewDiffProgressFile['state'], remaining: number): ReviewDiffProgressFile => ({ + path, state, remaining: { additions: remaining, deletions: 0 }, total: { additions: 3, deletions: 1 }, viewedRanges: [], changedRanges: [], +}); + +function row(state: ReviewDiffProgressFile['state'] | undefined, counts?: StructuralLineCounts) { + const path = 'src/a.ts'; + const renderer = new ChangedFilesTreeRenderer( + new Map(counts ? [[path, counts]] : []), + new Map(state ? [[path, progress(path, state, state === 'unread' ? 3 : 0)]] : []), + new Map(), + ); + const template = renderer.renderTemplate(document.createElement('div')); + renderer.renderElement({ element: { kind: 'file', name: 'a.ts', file: file(path) } } as never, 0, template); + return { row: template.row, counts: template.counts.textContent }; +} + +test('a folded file reads as done: greyed like a viewed one, "Folded" in place of its counts', () => { + const folded = row('folded'); + assert.equal(folded.counts, 'Folded'); + assert.ok(folded.row.classList.contains('review-file-folded')); + assert.ok(!folded.row.classList.contains('review-file-viewed')); +}); + +test('a viewed file says "Viewed" in place of its counts', () => { + const viewed = row('viewed'); + assert.equal(viewed.counts, 'Viewed'); + assert.ok(viewed.row.classList.contains('review-file-viewed')); +}); + +test('a file with changes left to read shows its remaining counts, not greyed', () => { + const unread = row('unread'); + assert.equal(unread.counts, '+3−0'); + assert.ok(!unread.row.classList.contains('review-file-folded')); + assert.ok(!unread.row.classList.contains('review-file-viewed')); +}); + +test('without progress, the structural counts show and nothing reads as folded', () => { + const pending = row(undefined, { added: 4, removed: 1 }); + assert.equal(pending.counts, '+4−1'); + assert.ok(!pending.row.classList.contains('review-file-folded')); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewChangedFilesTree.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewChangedFilesTree.ts new file mode 100644 index 000000000..d1f17cf9a --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewChangedFilesTree.ts @@ -0,0 +1,358 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { buildTree, type ChangedFileElement, type ChangedTreeElement } from "../common/reviewChangedFilesModel.js"; + +import { $, append } from "../../base/browser/dom.js"; +import type { IListVirtualDelegate } from "../../base/browser/ui/list/list.js"; +import { RenderIndentGuides } from "../../base/browser/ui/tree/abstractTree.js"; +import type { + ICompressedTreeElement, + ICompressedTreeNode, +} from "../../base/browser/ui/tree/compressedObjectTreeModel.js"; +import type { ICompressibleTreeRenderer } from "../../base/browser/ui/tree/objectTree.js"; +import { + ObjectTreeElementCollapseState, + type ITreeNode, +} from "../../base/browser/ui/tree/tree.js"; +import { Codicon } from "../../base/common/codicons.js"; +import { Emitter, type Event } from "../../base/common/event.js"; +import { Disposable } from "../../base/common/lifecycle.js"; +import { ThemeIcon } from "../../base/common/themables.js"; +import { localize } from "../../nls.js"; +import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; +import { WorkbenchCompressibleObjectTree } from "../../platform/list/browser/listService.js"; +import { registerColor } from "../../platform/theme/common/colorRegistry.js"; +import type { ReviewDiffFileWire, ReviewDiffProgressFile, StructuralLineCounts } from "../common/reviewProtocol.js"; + +registerColor( + "gitDecoration.addedResourceForeground", + { + light: "#587c0c", + dark: "#81b88b", + hcDark: "#a1e3ad", + hcLight: "#374e06", + }, + localize("review.gitDecoration.added", "Color for added file resources."), +); +registerColor( + "gitDecoration.modifiedResourceForeground", + { + light: "#895503", + dark: "#E2C08D", + hcDark: "#E2C08D", + hcLight: "#895503", + }, + localize("review.gitDecoration.modified", "Color for modified file resources."), +); +registerColor( + "gitDecoration.deletedResourceForeground", + { + light: "#ad0707", + dark: "#c74e39", + hcDark: "#c74e39", + hcLight: "#ad0707", + }, + localize("review.gitDecoration.deleted", "Color for deleted file resources."), +); +registerColor( + "gitDecoration.renamedResourceForeground", + { + light: "#007100", + dark: "#73C991", + hcDark: "#73C991", + hcLight: "#007100", + }, + localize("review.gitDecoration.renamed", "Color for renamed file resources."), +); + +const CHANGED_FILE_ROW_HEIGHT = 22; + +interface ChangedFilesTreeTemplate { + readonly row: HTMLElement; + readonly icon: HTMLElement; + readonly label: HTMLElement; + readonly counts: HTMLElement; +} + +class ChangedFilesTreeDelegate + implements IListVirtualDelegate +{ + getHeight(): number { + return CHANGED_FILE_ROW_HEIGHT; + } + + getTemplateId(): string { + return ChangedFilesTreeRenderer.TEMPLATE_ID; + } +} + +export class ChangedFilesTreeRenderer + implements + ICompressibleTreeRenderer< + ChangedTreeElement, + void, + ChangedFilesTreeTemplate + > +{ + static readonly TEMPLATE_ID = "review.changedFiles.entry"; + readonly templateId = ChangedFilesTreeRenderer.TEMPLATE_ID; + + constructor(private readonly counts: Map, private readonly progress: Map, private readonly states: Map) { } + + renderTemplate(container: HTMLElement): ChangedFilesTreeTemplate { + const row = append(container, $(".review-changed-files-row")); + const icon = append(row, $("span.review-changed-files-icon")); + icon.setAttribute("aria-hidden", "true"); + const label = append(row, $("span.review-changed-files-label")); + const counts = append(row, $("span.review-tree-counts")); + return { row, icon, label, counts }; + } + + renderElement( + node: ITreeNode, + _index: number, + template: ChangedFilesTreeTemplate, + ): void { + this.renderElements([node.element], template); + } + + renderCompressedElements( + node: ITreeNode>, + _index: number, + template: ChangedFilesTreeTemplate, + ): void { + this.renderElements(node.element.elements, template); + } + + disposeTemplate(_template: ChangedFilesTreeTemplate): void {} + + private renderElements( + elements: readonly ChangedTreeElement[], + template: ChangedFilesTreeTemplate, + ): void { + const element = elements[elements.length - 1]; + const isFile = element.kind === "file"; + + template.row.classList.toggle("review-changed-files-folder", !isFile); + const done = isFile ? this.progress.get(element.file.path)?.state : undefined; + // Folded files read as done, like viewed ones: greyed, with the reason in place of counts. + template.row.classList.toggle("review-file-viewed", done === "viewed"); + template.row.classList.toggle("review-file-folded", done === "folded"); + template.icon.hidden = !isFile; + template.icon.className = isFile + ? `review-changed-files-icon review-changed-files-icon-${element.file.status} ${ThemeIcon.asClassName(fileStatusIcon(element.file.status))}` + : "review-changed-files-icon"; + template.counts.hidden = !isFile; + template.counts.replaceChildren(); + template.counts.removeAttribute("title"); + if (isFile) { + const progress = this.progress.get(element.file.path); + const compact = (n: number) => new Intl.NumberFormat('en', { notation: 'compact', maximumFractionDigits: 1 }).format(n).toLowerCase(); + const additions = progress?.remaining.additions ?? this.counts.get(element.file.path)?.added; + const deletions = progress?.remaining.deletions ?? this.counts.get(element.file.path)?.removed; + if (element.file.status === 'unchanged') template.counts.textContent = 'Unchanged'; + else if (progress?.state === 'viewed') template.counts.textContent = 'Viewed'; + else if (progress?.state === 'folded') template.counts.textContent = 'Folded'; + else if (additions !== undefined && deletions !== undefined) { + const added = append(template.counts, $('span.review-tree-added')); added.textContent = `+${compact(additions)}`; + const removed = append(template.counts, $('span.review-tree-removed')); removed.textContent = `−${compact(deletions)}`; + } + template.counts.title = additions === undefined ? "Waiting for structural coverage" : element.file.status === "unchanged" ? "Referenced context; no changed lines" : progress?.state === "folded" ? `Folded by default; counted as done · Total +${progress.total.additions} −${progress.total.deletions}` : `Remaining +${additions} −${deletions} · Total +${progress?.total.additions ?? this.counts.get(element.file.path)?.added} −${progress?.total.deletions ?? this.counts.get(element.file.path)?.removed}`; + } + const state = isFile ? this.states.get(element.file.path) : undefined; + if (state) template.icon.className = `review-changed-files-icon codicon codicon-${state.status === "loading" ? "loading codicon-modifier-spin" : "error"}`; + template.row.title = state?.message ?? (state?.status === "loading" ? "Loading diff…" : ""); + template.row.setAttribute("aria-busy", String(state?.status === "loading")); + template.label.textContent = isFile + ? element.name + : elements.map((item) => item.name).join("/"); + } +} + +/** A Workbench-compressed tree over one Review's changed files. */ +export class ReviewChangedFilesTree extends Disposable { + private readonly _onDidOpenFile = this._register( + new Emitter(), + ); + readonly onDidOpenFile: Event = + this._onDidOpenFile.event; + + private readonly tree: WorkbenchCompressibleObjectTree< + ChangedTreeElement, + void + >; + private readonly fileElements = new Map(); + private files: readonly ReviewDiffFileWire[] = []; + private readonly states = new Map(); + private activePath: string | undefined; + private readonly counts = new Map(); + setCounts(path: string, counts: StructuralLineCounts): void { + const previous = this.counts.get(path); + this.counts.set(path, counts); + if (previous?.added !== counts.added || previous?.removed !== counts.removed) this.refreshFile(path); + } + private readonly progress = new Map(); + setProgressFiles(files: readonly ReviewDiffProgressFile[]): void { + const previous = new Map(this.progress); + this.progress.clear(); + for (const file of files) this.progress.set(file.path, file); + for (const path of new Set([...previous.keys(), ...this.progress.keys()])) { + const before = previous.get(path), after = this.progress.get(path); + if (before?.state !== after?.state || + before?.remaining.additions !== after?.remaining.additions || + before?.remaining.deletions !== after?.remaining.deletions || + before?.total.additions !== after?.total.additions || + before?.total.deletions !== after?.total.deletions) this.refreshFile(path); + } + } + + private refreshFile(path: string): void { + // The parameterless rerender only remeasures dynamic heights; these rows + // have fixed heights. Target the model node to refresh its rendered data. + const element = this.fileElements.get(path); + if (element) this.tree.rerender(element); + } + private syncingActiveFile = false; + + constructor( + container: HTMLElement, + @IInstantiationService instantiationService: IInstantiationService, + ) { + super(); + container.classList.add("review-changed-files"); + const treeContainer = append( + container, + $(".review-changed-files-tree"), + ); + const renderer = new ChangedFilesTreeRenderer(this.counts, this.progress, this.states); + this.tree = this._register( + instantiationService.createInstance( + WorkbenchCompressibleObjectTree, + "ReviewChangedFiles", + treeContainer, + new ChangedFilesTreeDelegate(), + [renderer], + { + accessibilityProvider: { + getAriaLabel: (element) => + element.kind === "file" ? element.file.path : element.path, + getWidgetAriaLabel: () => + localize("review.changedFiles.ariaLabel", "Changed files"), + }, + alwaysConsumeMouseWheel: false, + horizontalScrolling: false, + identityProvider: { + getId: (element) => + element.kind === "file" + ? element.file.path + : `dir:${element.path}`, + }, + indent: 12, + keyboardNavigationLabelProvider: { + getKeyboardNavigationLabel: (element) => element.name, + getCompressedNodeKeyboardNavigationLabel: (elements) => + elements.map((element) => element.name).join("/"), + }, + compressionEnabled: true, + multipleSelectionSupport: false, + openOnSingleClick: true, + renderIndentGuides: RenderIndentGuides.None, + }, + ), + ); + this._register( + this.tree.onDidOpen((event) => { + if (this.syncingActiveFile || event.element?.kind !== "file") return; + this._onDidOpenFile.fire(event.element.file); + }), + ); + this.refresh(); + } + + setFiles(files: readonly ReviewDiffFileWire[]): void { + const selectedElement = this.tree + .getSelection() + .find((element) => element?.kind === "file"); + const selectedPath = + selectedElement?.kind === "file" ? selectedElement.file.path : undefined; + this.files = files; + this.refresh(selectedPath); + } + + setFileState(path: string, status: "loading" | "error" | undefined, message?: string): void { + if (status) this.states.set(path, { status, message }); + else this.states.delete(path); + const element = this.fileElements.get(path); + if (element) this.tree.rerender(element); + } + + setActiveFile(path: string | undefined, reveal = true): void { + if (!reveal && this.activePath === path) return; + this.activePath = path; + this.syncSelection(path, reveal); + } + + layout(height: number, width: number): void { + this.tree.layout(Math.max(0, height), width); + } + + private refresh(selectedPath?: string): void { + const roots = buildTree(this.files); + this.fileElements.clear(); + collectFileElements(roots, this.fileElements); + this.tree.setChildren(null, toTreeElements(roots)); + this.syncSelection(this.activePath ?? selectedPath); + } + + private syncSelection(path: string | undefined, reveal = true): void { + const element = path ? this.fileElements.get(path) : undefined; + this.syncingActiveFile = true; + try { + this.tree.setSelection(element ? [element] : []); + this.tree.setFocus(element ? [element] : []); + if (element && reveal) this.tree.reveal(element); + } finally { + this.syncingActiveFile = false; + } + } +} + +function fileStatusIcon(status: ReviewDiffFileWire["status"]): ThemeIcon { + if (status === "unchanged") return Codicon.file; + if (status === "added") return Codicon.diffAdded; + if (status === "deleted") return Codicon.diffRemoved; + if (status === "renamed") return Codicon.diffRenamed; + return Codicon.diffModified; +} + +function toTreeElements( + elements: readonly ChangedTreeElement[], +): ICompressedTreeElement[] { + return elements.map((element) => + element.kind === "file" + ? { element, incompressible: true } + : { + element, + collapsible: true, + collapsed: ObjectTreeElementCollapseState.PreserveOrExpanded, + children: toTreeElements(element.children), + }, + ); +} + +function collectFileElements( + elements: readonly ChangedTreeElement[], + target: Map, +): void { + for (const element of elements) { + if (element.kind === "file") { + target.set(element.file.path, element); + } else { + collectFileElements(element.children, target); + } + } +} + diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewCommunity.contribution.test.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewCommunity.contribution.test.ts new file mode 100644 index 000000000..8ab90f27e --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewCommunity.contribution.test.ts @@ -0,0 +1,97 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import type { IConfirmation, IConfirmationResult } from '../../platform/dialogs/common/dialogs.js'; +import { REVIEW_DISCORD_URL } from '../common/reviewProtocol.js'; +import { setFirstRunReloadPending } from '../common/reviewFirstRunReload.js'; +import { DISMISSED_KEY, ReviewCommunityContribution } from './reviewCommunity.contribution.js'; + +const settle = () => new Promise(resolve => setImmediate(resolve)); + +function setup(answer: Promise, reviews: Array<{ kind?: "scratchpad" }> = [{}, {}], dismissed = false) { + const catalog = { reviews, initialize: async () => { } }; + const asked: IConfirmation[] = []; + const stored: Array<{ key: string; value: unknown }> = []; + const opened: unknown[] = []; + const invite = () => new ReviewCommunityContribution( + { confirm: (confirmation: IConfirmation) => { asked.push(confirmation); return answer; } } as never, + { getBoolean: () => dismissed, store: (key: string, value: unknown) => { stored.push({ key, value }); dismissed = Boolean(value); } } as never, + { open: async (target: unknown) => { opened.push(target); return true; } } as never, + catalog as never, + ); + return { asked, stored, opened, invite, catalog }; +} + +test('skips the invitation when the first-run seeding reload is pending', async () => { + setFirstRunReloadPending(true); + const { asked, stored, invite } = setup(new Promise(() => { })); + invite(); + await settle(); + assert.deepEqual(asked, [], 'the reload would discard the invitation'); + assert.deepEqual(stored, []); +}); + +for (const confirmed of [false, true]) { + test(`permanently dismisses the invitation after ${confirmed ? 'joining' : 'declining'}`, async () => { + setFirstRunReloadPending(false); + const { asked, stored, opened, invite } = setup(Promise.resolve({ confirmed })); + invite(); + await settle(); + assert.equal(asked.length, 1); + assert.deepEqual(stored, [{ key: DISMISSED_KEY, value: true }]); + assert.deepEqual(opened, confirmed ? [REVIEW_DISCORD_URL] : []); + invite(); + await settle(); + assert.equal(asked.length, 1, 'subsequent launches must not ask again'); + }); +} + +for (const reviews of [[], [{}], [{}, { kind: "scratchpad" as const }]]) { + test(`skips the invitation with fewer than two reviews: ${JSON.stringify(reviews)}`, async () => { + setFirstRunReloadPending(false); + const { asked, invite } = setup(Promise.resolve({ confirmed: false }), reviews); + invite(); + await settle(); + assert.equal(asked.length, 0); + }); +} + +test('waits until the next launch after the second review is created', async () => { + setFirstRunReloadPending(false); + const { asked, invite, catalog } = setup(Promise.resolve({ confirmed: false }), [{}]); + invite(); + await settle(); + catalog.reviews.push({}); + await settle(); + assert.equal(asked.length, 0); + invite(); + await settle(); + assert.equal(asked.length, 1); +}); + +test('waits for the catalog to load before checking eligibility', async () => { + setFirstRunReloadPending(false); + const { asked, invite, catalog } = setup(Promise.resolve({ confirmed: false }), []); + let loaded!: () => void; + catalog.initialize = () => new Promise(resolve => { loaded = resolve; }); + invite(); + await settle(); + assert.equal(asked.length, 0); + catalog.reviews.push({}, {}, {}); + loaded(); + await settle(); + assert.equal(asked.length, 1); +}); + +test('respects permanent dismissal after two reviews', async () => { + setFirstRunReloadPending(false); + const { asked, invite } = setup(Promise.resolve({ confirmed: false }), [{}, {}], true); + invite(); + await settle(); + assert.equal(asked.length, 0); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewCommunity.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewCommunity.contribution.ts new file mode 100644 index 000000000..6e5e923a0 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewCommunity.contribution.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { onUnexpectedError } from '../../base/common/errors.js'; +import { IDialogService } from '../../platform/dialogs/common/dialogs.js'; +import { IOpenerService } from '../../platform/opener/common/opener.js'; +import { IStorageService, StorageScope, StorageTarget } from '../../platform/storage/common/storage.js'; +import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../workbench/common/contributions.js'; +import { isFirstRunReloadPending } from '../common/reviewFirstRunReload.js'; +import { REVIEW_DISCORD_URL } from '../common/reviewProtocol.js'; +import { IReviewApiCatalogService } from '../services/reviewApiCatalogService.js'; + +export const DISMISSED_KEY = 'review.community.dontShowAgain'; + +export class ReviewCommunityContribution implements IWorkbenchContribution { + + static readonly ID = 'workbench.contrib.devfast.reviewCommunity'; + + constructor( + @IDialogService dialogService: IDialogService, + @IStorageService storageService: IStorageService, + @IOpenerService openerService: IOpenerService, + @IReviewApiCatalogService catalogService: IReviewApiCatalogService, + ) { + if (storageService.getBoolean(DISMISSED_KEY, StorageScope.APPLICATION, false)) { + return; + } + + this.invite(dialogService, storageService, openerService, catalogService).catch(onUnexpectedError); + } + + private async invite(dialogService: IDialogService, storageService: IStorageService, openerService: IOpenerService, catalogService: IReviewApiCatalogService): Promise { + if (await isFirstRunReloadPending()) { + return; // the seeding reload would discard both the question and the answer + } + await catalogService.initialize(); + if (catalogService.reviews.filter(review => review.kind !== 'scratchpad').length < 2) { + return; + } + const result = await dialogService.confirm({ + type: 'info', + message: 'Join the Review community', + detail: 'Meet the team, ask questions, and share feedback in the /dev/fast Discord. You can also join anytime using the Discord link next to Report a bug.', + primaryButton: 'Join Discord', + cancelButton: 'Not now', + }); + storageService.store(DISMISSED_KEY, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + if (result.confirmed) { + await openerService.open(REVIEW_DISCORD_URL, { openExternal: true }); + } + } +} + +registerWorkbenchContribution2(ReviewCommunityContribution.ID, ReviewCommunityContribution, WorkbenchPhase.AfterRestored); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewPaneCompositePartService.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewPaneCompositePartService.ts new file mode 100644 index 000000000..5aa3ccf5e --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewPaneCompositePartService.ts @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from '../../base/common/event.js'; +import { InstantiationType, registerSingleton } from '../../platform/instantiation/common/extensions.js'; +import type { IProgressIndicator } from '../../platform/progress/common/progress.js'; +import { Extensions as PaneCompositeExtensions, type PaneCompositeDescriptor } from '../../workbench/browser/panecomposite.js'; +import type { IPaneComposite } from '../../workbench/common/panecomposite.js'; +import { ViewContainerLocation } from '../../workbench/common/views.js'; +import { Parts, type SINGLE_WINDOW_PARTS } from '../../workbench/services/layout/browser/layoutService.js'; +import { IPaneCompositePartService } from '../../workbench/services/panecomposite/browser/panecomposite.js'; + +/** Supplies the pane-composite contract without creating chrome that Review does not show. */ +class ReviewPaneCompositePartService implements IPaneCompositePartService { + declare readonly _serviceBrand: undefined; + + readonly onDidPaneCompositeOpen = Event.None; + readonly onDidPaneCompositeClose = Event.None; + + getRegistryId(location: ViewContainerLocation): string { + switch (location) { + case ViewContainerLocation.Sidebar: + return PaneCompositeExtensions.Viewlets; + case ViewContainerLocation.Panel: + return PaneCompositeExtensions.Panels; + case ViewContainerLocation.AuxiliaryBar: + return PaneCompositeExtensions.Auxiliary; + } + } + + getPartId(location: ViewContainerLocation): SINGLE_WINDOW_PARTS { + switch (location) { + case ViewContainerLocation.Sidebar: + return Parts.SIDEBAR_PART; + case ViewContainerLocation.Panel: + return Parts.PANEL_PART; + case ViewContainerLocation.AuxiliaryBar: + return Parts.AUXILIARYBAR_PART; + } + } + + openPaneComposite(_id: string | undefined, _location: ViewContainerLocation, _focus?: boolean): Promise { + return Promise.resolve(undefined); + } + + getActivePaneComposite(_location: ViewContainerLocation): IPaneComposite | undefined { return undefined; } + getPaneComposite(_id: string, _location: ViewContainerLocation): PaneCompositeDescriptor | undefined { return undefined; } + getPaneComposites(_location: ViewContainerLocation): PaneCompositeDescriptor[] { return []; } + getPinnedPaneCompositeIds(_location: ViewContainerLocation): string[] { return []; } + getVisiblePaneCompositeIds(_location: ViewContainerLocation): string[] { return []; } + getPaneCompositeIds(_location: ViewContainerLocation): string[] { return []; } + getProgressIndicator(_id: string, _location: ViewContainerLocation): IProgressIndicator | undefined { return undefined; } + hideActivePaneComposite(_location: ViewContainerLocation): void { } + getLastActivePaneCompositeId(_location: ViewContainerLocation): string { return ''; } +} + +registerSingleton(IPaneCompositePartService, ReviewPaneCompositePartService, InstantiationType.Delayed); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewTheme.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewTheme.contribution.ts new file mode 100644 index 000000000..c6eef657f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewTheme.contribution.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize, localize2 } from '../../nls.js'; +import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../platform/actions/common/actions.js'; +import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; +import type { ServicesAccessor } from '../../platform/instantiation/common/instantiation.js'; +import { IQuickInputService, type IQuickPickItem } from '../../platform/quickinput/common/quickInput.js'; +import { IThemeService } from '../../platform/theme/common/themeService.js'; +import { type ReviewThemeChoice, applyReviewThemeChoice, currentReviewThemeChoice } from './reviewThemeChoice.js'; + +interface IReviewThemeQuickPickItem extends IQuickPickItem { + readonly choice: ReviewThemeChoice; +} + +class SelectReviewThemeAction extends Action2 { + constructor() { + super({ + id: 'review.selectTheme', + title: localize2('review.selectTheme', "Review: Theme"), + f1: true + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + const quickInputService = accessor.get(IQuickInputService); + const themeService = accessor.get(IThemeService); + const currentChoice = currentReviewThemeChoice(configurationService, themeService); + const items: IReviewThemeQuickPickItem[] = [ + { choice: 'light', label: localize('review.theme.light', "Light"), picked: currentChoice === 'light' }, + { choice: 'dark', label: localize('review.theme.dark', "Dark"), picked: currentChoice === 'dark' }, + { choice: 'system', label: localize('review.theme.system', "System"), picked: currentChoice === 'system' } + ]; + + const picked = await quickInputService.pick(items, { + title: localize('review.theme.title', "Review: Theme"), + placeHolder: localize('review.theme.placeholder', "Select a theme") + }); + if (!picked) { + return; + } + + await applyReviewThemeChoice(configurationService, picked.choice); + } +} + +registerAction2(SelectReviewThemeAction); + +MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { + command: { + id: 'review.selectTheme', + title: localize('review.selectTheme.menu', "Theme...") + }, + order: 0 +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/reviewThemeChoice.ts b/apps/review-desktop/code-oss/src/vs/review/browser/reviewThemeChoice.ts new file mode 100644 index 000000000..61ec9b935 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/reviewThemeChoice.ts @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ConfigurationTarget, IConfigurationService } from '../../platform/configuration/common/configuration.js'; +import { ColorScheme } from '../../platform/theme/common/theme.js'; +import { IThemeService } from '../../platform/theme/common/themeService.js'; + +/** + * The theme choice, shared by the `review.selectTheme` quick pick and the + * Settings canvas tab. This module registers nothing, so the canvas part can + * import it without pulling in a contribution. + */ + +const REVIEW_DARK_THEME = 'Review Dark'; +const REVIEW_LIGHT_THEME = 'Review Light'; + +export type ReviewThemeChoice = 'dark' | 'light' | 'system'; + +export function currentReviewThemeChoice(configurationService: IConfigurationService, themeService: IThemeService): ReviewThemeChoice { + if (configurationService.getValue('window.autoDetectColorScheme')) { + return 'system'; + } + + // The theme service applies a theme change asynchronously, so a read taken + // right after applyReviewThemeChoice still reports the previous theme. The + // configured name is authoritative whenever it names a Review theme. + const configured = configurationService.getValue('workbench.colorTheme'); + if (configured === REVIEW_LIGHT_THEME) { + return 'light'; + } + if (configured === REVIEW_DARK_THEME) { + return 'dark'; + } + + const type = themeService.getColorTheme().type; + return type === ColorScheme.LIGHT || type === ColorScheme.HIGH_CONTRAST_LIGHT ? 'light' : 'dark'; +} + +export async function applyReviewThemeChoice(configurationService: IConfigurationService, choice: ReviewThemeChoice): Promise { + switch (choice) { + case 'dark': + await configurationService.updateValue('window.autoDetectColorScheme', false, ConfigurationTarget.USER); + await configurationService.updateValue('workbench.colorTheme', REVIEW_DARK_THEME, ConfigurationTarget.USER); + break; + case 'light': + await configurationService.updateValue('window.autoDetectColorScheme', false, ConfigurationTarget.USER); + await configurationService.updateValue('workbench.colorTheme', REVIEW_LIGHT_THEME, ConfigurationTarget.USER); + break; + case 'system': + await configurationService.updateValue('window.autoDetectColorScheme', true, ConfigurationTarget.USER); + await configurationService.updateValue('workbench.preferredDarkColorTheme', REVIEW_DARK_THEME, ConfigurationTarget.USER); + await configurationService.updateValue('workbench.preferredLightColorTheme', REVIEW_LIGHT_THEME, ConfigurationTarget.USER); + break; + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/browser/workbench.ts b/apps/review-desktop/code-oss/src/vs/review/browser/workbench.ts new file mode 100644 index 000000000..407a0aed8 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/browser/workbench.ts @@ -0,0 +1,2073 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import '../../workbench/browser/style.js'; +import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../base/common/lifecycle.js'; +import { Emitter, Event, setGlobalLeakWarningThreshold } from '../../base/common/event.js'; +import { Dimension, IDimension, addDisposableListener, getActiveDocument, getActiveElement, getClientArea, getWindowId, getWindows, isAncestorUsingFlowTo, isHTMLElement, runWhenWindowIdle, size } from '../../base/browser/dom.js'; +import { DeferredPromise, RunOnceScheduler } from '../../base/common/async.js'; +import { isChrome, isFirefox, isFullscreen, isSafari, onDidChangeFullscreen } from '../../base/browser/browser.js'; +import { mark } from '../../base/common/performance.js'; +import { onUnexpectedError, setUnexpectedErrorHandler } from '../../base/common/errors.js'; +import { ReviewErrorReportLimiter } from '../common/reviewErrorReport.js'; +import { IReviewTelemetryService } from '../services/reviewTelemetryService.js'; +import { isLinux, isMacintosh, isNative, isWeb, isWindows } from '../../base/common/platform.js'; +import { IPartVisibilityChangeEvent, IWorkbenchLayoutService, MULTI_WINDOW_PARTS, PanelAlignment, Parts, Position, SINGLE_WINDOW_PARTS } from '../../workbench/services/layout/browser/layoutService.js'; +import { ILayoutOffsetInfo } from '../../platform/layout/browser/layoutService.js'; +import { Part } from '../../workbench/browser/part.js'; +import { Direction, ISerializableView, ISerializedGrid, ISerializedLeafNode, ISerializedNode, IViewSize, Orientation, SerializableGrid } from '../../base/browser/ui/grid/grid.js'; +import { IEditorGroupsService } from '../../workbench/services/editor/common/editorGroupsService.js'; +import { IEditorService } from '../../workbench/services/editor/common/editorService.js'; +import { IPaneCompositePartService } from '../../workbench/services/panecomposite/browser/panecomposite.js'; +import { IViewDescriptorService, ViewContainerLocation } from '../../workbench/common/views.js'; +import { ILogService } from '../../platform/log/common/log.js'; +import { IInstantiationService, ServicesAccessor, refineServiceDecorator } from '../../platform/instantiation/common/instantiation.js'; +import { ITitleService } from '../../workbench/services/title/browser/titleService.js'; +import { CodeWindow, mainWindow } from '../../base/browser/window.js'; +import { coalesce } from '../../base/common/arrays.js'; +import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; +import { InstantiationService } from '../../platform/instantiation/common/instantiationService.js'; +import { getSingletonServiceDescriptors } from '../../platform/instantiation/common/extensions.js'; +import { ILifecycleService, LifecyclePhase, WillShutdownEvent } from '../../workbench/services/lifecycle/common/lifecycle.js'; +import { IStorageService, StorageScope, StorageTarget, WillSaveStateReason } from '../../platform/storage/common/storage.js'; +import { IConfigurationChangeEvent, IConfigurationService } from '../../platform/configuration/common/configuration.js'; +import { IHostService } from '../../workbench/services/host/browser/host.js'; +import { IDialogService } from '../../platform/dialogs/common/dialogs.js'; +import { INotificationService } from '../../platform/notification/common/notification.js'; +import { NotificationService } from '../../workbench/services/notification/common/notificationService.js'; +import { IHoverService, WorkbenchHoverDelegate } from '../../platform/hover/browser/hover.js'; +import { setHoverDelegateFactory } from '../../base/browser/ui/hover/hoverDelegateFactory.js'; +import { setBaseLayerHoverDelegate } from '../../base/browser/ui/hover/hoverDelegate2.js'; +import { Registry } from '../../platform/registry/common/platform.js'; +import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from '../../workbench/common/contributions.js'; +import { EditorExtensions, IEditorFactoryRegistry, IEditorWillOpenEvent } from '../../workbench/common/editor.js'; +import { setARIAContainer } from '../../base/browser/ui/aria/aria.js'; +import { FontMeasurements } from '../../editor/browser/config/fontMeasurements.js'; +import { createBareFontInfoFromRawSettings } from '../../editor/common/config/fontInfoFromSettings.js'; +import { toErrorMessage } from '../../base/common/errorMessage.js'; +import { WorkbenchContextKeysHandler } from '../../workbench/browser/contextkeys.js'; +import { PixelRatio } from '../../base/browser/pixelRatio.js'; +import { AccessibilityProgressSignalScheduler } from '../../platform/accessibilitySignal/browser/progressAccessibilitySignalScheduler.js'; +import { setProgressAccessibilitySignalScheduler } from '../../base/browser/ui/progressbar/progressAccessibilitySignal.js'; +import { AccessibleViewRegistry } from '../../platform/accessibility/browser/accessibleViewRegistry.js'; +import { NotificationAccessibleView } from '../../workbench/browser/parts/notifications/notificationAccessibleView.js'; +import { NotificationsCenter } from '../../workbench/browser/parts/notifications/notificationsCenter.js'; +import { NotificationsAlerts } from '../../workbench/browser/parts/notifications/notificationsAlerts.js'; +import { NotificationsStatus } from '../../workbench/browser/parts/notifications/notificationsStatus.js'; +import { registerNotificationCommands } from '../../workbench/browser/parts/notifications/notificationsCommands.js'; +import { NotificationsToasts } from '../../workbench/browser/parts/notifications/notificationsToasts.js'; +import { IMarkdownRendererService } from '../../platform/markdown/browser/markdownRenderer.js'; +import { EditorMarkdownCodeBlockRenderer } from '../../editor/browser/widget/markdownRenderer/browser/editorMarkdownCodeBlockRenderer.js'; +import { SyncDescriptor } from '../../platform/instantiation/common/descriptors.js'; +import { MainReviewTitlebarPart, ReviewTitleService } from './parts/reviewTitlebarPart.js'; +import { IContextKeyService, RawContextKey } from '../../platform/contextkey/common/contextkey.js'; +import { IsReviewWindowContext } from '../../workbench/common/contextkeys.js'; +import { + NotificationsPosition, + NotificationsSettings, + getNotificationsPosition +} from '../../workbench/common/notifications.js'; +import { IReviewCanvasPartsService } from './parts/canvas/reviewCanvasPart.js'; +import { IReviewExplorerPartsService } from './parts/explorer/reviewExplorerPart.js'; +import { initialReviewPartVisibility } from '../common/reviewWorkbenchVisibility.js'; +import { REVIEW_CHROME_HEIGHT } from '../common/reviewChrome.js'; + +const EDITOR_PART_MINIMUM_WIDTH = 300; +const EDITOR_PART_DEFAULT_WIDTH = 600; +const EXPLORER_PART_DEFAULT_WIDTH = 260; +const EditorMaximizedContext = new RawContextKey('editorMaximized', false); + +//#region ReviewWorkbench Options + +export interface IWorkbenchOptions { + /** + * Extra classes to be added to the workbench container. + */ + extraClasses?: string[]; +} + +//#endregion + +//#region Layout Classes + +enum LayoutClasses { + SIDEBAR_HIDDEN = 'nosidebar', + MAIN_EDITOR_AREA_HIDDEN = 'nomaineditorarea', + PANEL_HIDDEN = 'nopanel', + AUXILIARYBAR_HIDDEN = 'noauxiliarybar', + SESSIONS_HIDDEN = 'nosessionspart', + /** Positive polarity: the explorer is hidden on most tabs, so the class marks the exception. */ + EXPLORER_VISIBLE = 'review-explorer-visible', + STATUSBAR_HIDDEN = 'nostatusbar', + SHELL_GRADIENT_BACKGROUND = 'shell-gradient-background', + FULLSCREEN = 'fullscreen', + MAXIMIZED = 'maximized' +} + +//#endregion + +//#region Part Visibility State + +/** Visibility of each workbench part in the Agents window layout. */ +export interface IPartVisibilityState { + sidebar: boolean; + auxiliaryBar: boolean; + editor: boolean; + panel: boolean; + sessions: boolean; + explorer: boolean; +} + +interface IPartSizesState { + sidebar?: number; + auxiliaryBar?: number; + sessions?: number; + editor?: number; + panel?: number; + explorer?: number; +} + +//#endregion + +export interface IAgentWorkbenchLayoutService extends IWorkbenchLayoutService { + isEditorMaximized(): boolean; + setEditorMaximized(maximized: boolean): void; + + readonly onDidChangeEditorMaximized: Event; + + /** + * Suppresses the automatic editor part show/hide that normally fires from + * `editorService.onWillOpenEditor` / `onDidCloseEditor`. Use this around + * programmatic editor operations (e.g. applying a working set) so that the + * editor part visibility is not changed as a side-effect. Dispose the + * returned handle to release the suppression. Calls nest via a counter. + */ + suppressEditorPartAutoVisibility(): IDisposable; +} + +export const IAgentWorkbenchLayoutService = refineServiceDecorator(IWorkbenchLayoutService); + + +const REVIEW_CHROME_INSET_PROPERTIES = ['--review-chrome-left-width', '--review-chrome-right-width', '--review-explorer-width'] as const; +export class ReviewWorkbench extends Disposable implements IAgentWorkbenchLayoutService { + + declare readonly _serviceBrand: undefined; + + //#region Lifecycle Events + + private readonly _onWillShutdown = this._register(new Emitter()); + readonly onWillShutdown = this._onWillShutdown.event; + + private readonly _onDidShutdown = this._register(new Emitter()); + readonly onDidShutdown = this._onDidShutdown.event; + + //#endregion + + //#region Events + + private readonly _onDidChangeZenMode = this._register(new Emitter()); + readonly onDidChangeZenMode = this._onDidChangeZenMode.event; + + private readonly _onDidChangeMainEditorCenteredLayout = this._register(new Emitter()); + readonly onDidChangeMainEditorCenteredLayout = this._onDidChangeMainEditorCenteredLayout.event; + + private readonly _onDidChangePanelAlignment = this._register(new Emitter()); + readonly onDidChangePanelAlignment = this._onDidChangePanelAlignment.event; + + private readonly _onDidChangeWindowMaximized = this._register(new Emitter<{ windowId: number; maximized: boolean }>()); + readonly onDidChangeWindowMaximized = this._onDidChangeWindowMaximized.event; + + private readonly _onDidChangePanelPosition = this._register(new Emitter()); + readonly onDidChangePanelPosition = this._onDidChangePanelPosition.event; + + private readonly _onDidChangePartVisibility = this._register(new Emitter()); + readonly onDidChangePartVisibility = this._onDidChangePartVisibility.event; + + private readonly _onDidChangeNotificationsVisibility = this._register(new Emitter()); + readonly onDidChangeNotificationsVisibility = this._onDidChangeNotificationsVisibility.event; + + private readonly _onDidChangeAuxiliaryBarMaximized = this._register(new Emitter()); + readonly onDidChangeAuxiliaryBarMaximized = this._onDidChangeAuxiliaryBarMaximized.event; + + private readonly _onDidChangeEditorMaximized = this._register(new Emitter()); + readonly onDidChangeEditorMaximized = this._onDidChangeEditorMaximized.event; + + private readonly _onDidLayoutMainContainer = this._register(new Emitter()); + readonly onDidLayoutMainContainer = this._onDidLayoutMainContainer.event; + + private readonly _onDidLayoutActiveContainer = this._register(new Emitter()); + readonly onDidLayoutActiveContainer = this._onDidLayoutActiveContainer.event; + + private readonly _onDidLayoutContainer = this._register(new Emitter<{ container: HTMLElement; dimension: IDimension }>()); + readonly onDidLayoutContainer = this._onDidLayoutContainer.event; + + private readonly _onDidAddContainer = this._register(new Emitter<{ container: HTMLElement; disposables: DisposableStore }>()); + readonly onDidAddContainer = this._onDidAddContainer.event; + + private readonly _onDidChangeActiveContainer = this._register(new Emitter()); + readonly onDidChangeActiveContainer = this._onDidChangeActiveContainer.event; + + //#endregion + + //#region Properties + + readonly mainContainer = document.createElement('div'); + + get activeContainer(): HTMLElement { + return this.getContainerFromDocument(getActiveDocument()); + } + + get containers(): Iterable { + const containers: HTMLElement[] = []; + for (const { window } of getWindows()) { + containers.push(this.getContainerFromDocument(window.document)); + } + return containers; + } + + private getContainerFromDocument(targetDocument: Document): HTMLElement { + if (targetDocument === this.mainContainer.ownerDocument) { + return this.mainContainer; + } else { + // eslint-disable-next-line no-restricted-syntax + return targetDocument.body.getElementsByClassName('monaco-workbench')[0] as HTMLElement; + } + } + + private _mainContainerDimension!: IDimension; + get mainContainerDimension(): IDimension { return this._mainContainerDimension; } + + get activeContainerDimension(): IDimension { + return this.getContainerDimension(this.activeContainer); + } + + private getContainerDimension(container: HTMLElement): IDimension { + if (container === this.mainContainer) { + return this.mainContainerDimension; + } else { + return getClientArea(container); + } + } + + get mainContainerOffset(): ILayoutOffsetInfo { + return this.computeContainerOffset(); + } + + get activeContainerOffset(): ILayoutOffsetInfo { + return this.computeContainerOffset(); + } + + private computeContainerOffset(): ILayoutOffsetInfo { + let top = 0; + let quickPickTop = 0; + + if (this.isVisible(Parts.TITLEBAR_PART, mainWindow)) { + top = REVIEW_CHROME_HEIGHT; + quickPickTop = top; + } + + return { top, quickPickTop }; + } + + //#endregion + + //#region State + + private readonly parts = new Map(); + protected workbenchGrid!: SerializableGrid; + + protected sideBarPartView!: ISerializableView; + private panelPartView!: ISerializableView; + protected auxiliaryBarPartView!: ISerializableView; + protected editorPartView!: ISerializableView; + + protected sessionsPartView!: ISerializableView; + protected explorerPartView!: ISerializableView; + + /** The editor part container; the auxiliary bar is docked inside it. */ + protected _editorPartContainer: HTMLElement | undefined; + + protected readonly partVisibility: IPartVisibilityState = { + sidebar: true, + auxiliaryBar: true, + editor: false, + panel: false, + sessions: true, + explorer: false + }; + + private mainWindowFullscreen = false; + private readonly maximized = new Set(); + private _editorMaximized = false; + private _editorLastNonMaximizedVisibility: IPartVisibilityState | undefined; + private _editorLastNonMaximizedSize: IViewSize | undefined; + private _restoreAttachedEditorMaximizedOnShow = false; + protected _editorPartAutoVisibilitySuppressionCount = 0; + protected _hasAppliedInitialEditorSplit = false; + private readonly reviewChromeTabStrips: HTMLElement[] = []; + private readonly reviewChromeDragListeners = this._register(new DisposableStore()); + private readonly reviewChromeInsetScheduler = this._register(new RunOnceScheduler(() => this.updateReviewChromeInset(), 0)); + + private readonly restoredPromise = new DeferredPromise(); + readonly whenRestored = this.restoredPromise.p; + private restored = false; + + readonly openedDefaultEditors = false; + + protected _savedPartSizes: IPartSizesState = {}; + + //#endregion + + private static readonly _PART_VISIBILITY_KEY = 'workbench.sessions.partVisibility'; + private static readonly _PART_SIZES_KEY = 'workbench.sessions.partSizes'; + + //#region Services + + protected editorGroupService!: IEditorGroupsService; + private editorService!: IEditorService; + private paneCompositeService!: IPaneCompositePartService; + private viewDescriptorService!: IViewDescriptorService; + private storageService!: IStorageService; + + //#endregion + + constructor( + protected readonly parent: HTMLElement, + private readonly options: IWorkbenchOptions | undefined, + private readonly serviceCollection: ServiceCollection, + private readonly logService: ILogService + ) { + super(); + + // Sessions-scoped mobile viewport tweaks. These are applied here + // (rather than in the shared workbench.html) so that the regular + // code-web workbench — which does not handle safe-area insets — is + // not affected on notched mobile devices. + // The viewport `` tag is injected by the shared workbench.html, + // so we cannot use dom.ts `h()` to create it. Look it up by tag name + // and filter by the `name` attribute to avoid a selector query. + // eslint-disable-next-line no-restricted-syntax + const metaElements = mainWindow.document.head.getElementsByTagName('meta'); + let viewportMeta: HTMLMetaElement | undefined; + for (let i = 0; i < metaElements.length; i++) { + if (metaElements[i].name === 'viewport') { + viewportMeta = metaElements[i]; + break; + } + } + if (viewportMeta && !viewportMeta.content.includes('viewport-fit=')) { + viewportMeta.content = `${viewportMeta.content}, viewport-fit=cover`; + } + + // Perf: measure workbench startup time + mark('code/willStartWorkbench'); + + this.registerErrorHandler(logService); + } + + //#region Error Handling + + private registerErrorHandler(logService: ILogService): void { + // Increase stack trace limit for better errors stacks + if (!isFirefox) { + Error.stackTraceLimit = 100; + } + + // Listen on unhandled rejection events + // Note: intentionally not registered as disposable to handle + // errors that can occur during shutdown phase. + mainWindow.addEventListener('unhandledrejection', (event) => { + // See https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent + onUnexpectedError(event.reason); + + // Prevent the printing of this event to the console + event.preventDefault(); + }); + + // Listen on synchronous errors that never reach a promise. Without this + // they only reach the console, so they are invisible to the log and to + // telemetry alike. + mainWindow.addEventListener('error', (event) => { + onUnexpectedError(event.error ?? event.message); + }); + + // Install handler for unexpected errors + setUnexpectedErrorHandler(error => this.handleUnexpectedError(error, logService)); + } + + private previousUnexpectedError: { message: string | undefined; time: number } = { message: undefined, time: 0 }; + private handleUnexpectedError(error: unknown, logService: ILogService): void { + const message = toErrorMessage(error, true); + if (!message) { + return; + } + + const now = Date.now(); + if (message === this.previousUnexpectedError.message && now - this.previousUnexpectedError.time <= 1000) { + return; // Return if error message identical to previous and shorter than 1 second + } + + this.previousUnexpectedError.time = now; + this.previousUnexpectedError.message = message; + + // Log it + logService.error(message); + + // Report it + this.reportUnexpectedError(error); + } + + private readonly errorReportLimiter = new ReviewErrorReportLimiter(); + private workbenchInstantiationService: IInstantiationService | undefined; + private reviewTelemetryService: IReviewTelemetryService | undefined; + + /** + * Send the error to the loopback Review server, which strips the message and + * every stack frame outside the shipped bundle before anything leaves this + * machine. Errors raised before `startup()` have no service to report + * through and are dropped rather than buffered: buffering would hold raw + * messages before the telemetry setting can be read. + */ + private reportUnexpectedError(error: unknown): void { + this.errorReportLimiter.report(error, report => { + this.reviewTelemetryService ??= this.workbenchInstantiationService?.invokeFunction(accessor => accessor.get(IReviewTelemetryService)); + this.reviewTelemetryService?.capture('client_error', { + error_source: 'renderer_unexpected', + error_process: 'renderer', + }, report); + }); + } + + //#endregion + + //#region Startup + + startup(): IInstantiationService { + try { + // Configure emitter leak warning threshold + this._register(setGlobalLeakWarningThreshold(175)); + + // Services + const instantiationService = this.initServices(this.serviceCollection); + + // The error handler is installed in the constructor, long before any + // service exists. Keep the instantiation service here so it can + // resolve the telemetry service on the first error. + this.workbenchInstantiationService = instantiationService; + + instantiationService.invokeFunction(accessor => { + const lifecycleService = accessor.get(ILifecycleService); + const storageService = accessor.get(IStorageService); + const configurationService = accessor.get(IConfigurationService); + const hostService = accessor.get(IHostService); + const hoverService = accessor.get(IHoverService); + const dialogService = accessor.get(IDialogService); + const notificationService = accessor.get(INotificationService) as NotificationService; + const markdownRendererService = accessor.get(IMarkdownRendererService); + + // On web, the configuration service needs access to the + // instantiation service for dynamic configuration resolution. + if (isWeb && typeof (configurationService as IConfigurationService & { acquireInstantiationService?(i: IInstantiationService): void }).acquireInstantiationService === 'function') { + (configurationService as IConfigurationService & { acquireInstantiationService(i: IInstantiationService): void }).acquireInstantiationService(instantiationService); + } + + // Set code block renderer for markdown rendering + markdownRendererService.setDefaultCodeBlockRenderer(instantiationService.createInstance(EditorMarkdownCodeBlockRenderer)); + + // Default Hover Delegate must be registered before creating any workbench/layout components + setHoverDelegateFactory((placement, enableInstantHover) => instantiationService.createInstance(WorkbenchHoverDelegate, placement, { instantHover: enableInstantHover }, {})); + setBaseLayerHoverDelegate(hoverService); + + // Layout + this.initLayout(accessor); + + // Registries - this creates and registers all parts + Registry.as(WorkbenchExtensions.Workbench).start(accessor); + Registry.as(EditorExtensions.EditorFactory).start(accessor); + + // Context Keys + this._register(instantiationService.createInstance(WorkbenchContextKeysHandler)); + + // Editor Maximized Context Key + const editorMaximizedContext = EditorMaximizedContext.bindTo(accessor.get(IContextKeyService)); + this._register(this.onDidChangeEditorMaximized(() => { + editorMaximizedContext.set(this.isEditorMaximized()); + })); + + const contextKeyService = accessor.get(IContextKeyService); + + // Marks this window as Review so shared workbench contributions can + // opt out of chrome Review does not offer (split editors, the editor + // actions overflow menu). + IsReviewWindowContext.bindTo(contextKeyService).set(true); + + // Register Listeners + this.registerListeners(lifecycleService, storageService, configurationService, hostService, dialogService); + + // Render ReviewWorkbench + this.renderWorkbench(instantiationService, notificationService, storageService, configurationService); + + // ReviewWorkbench Layout + this.createWorkbenchLayout(); + + // ReviewWorkbench Management + this.createWorkbenchManagement(instantiationService); + + // Layout + this.layout(); + + // Restore + this.restore(lifecycleService); + }); + + return instantiationService; + } catch (error) { + onUnexpectedError(error); + + throw error; // rethrow because this is a critical issue we cannot handle properly here + } + } + + private initServices(serviceCollection: ServiceCollection): IInstantiationService { + // Layout Service + serviceCollection.set(IAgentWorkbenchLayoutService, this); + + // All Contributed Services + const contributedServices = getSingletonServiceDescriptors(); + for (const [id, descriptor] of contributedServices) { + serviceCollection.set(id, descriptor); + } + + // The Review titlebar is a workbench part, not a contributed native + // service. Install it after the registry has been materialized so a + // platform title-service registration cannot replace the custom part. + serviceCollection.set(ITitleService, new SyncDescriptor(ReviewTitleService, [])); + + const instantiationService = new InstantiationService(serviceCollection, true); + + // Wrap up + instantiationService.invokeFunction(accessor => { + const lifecycleService = accessor.get(ILifecycleService); + lifecycleService.phase = LifecyclePhase.Ready; + }); + + return instantiationService; + } + + private registerListeners(lifecycleService: ILifecycleService, storageService: IStorageService, configurationService: IConfigurationService, hostService: IHostService, dialogService: IDialogService): void { + // Configuration changes + this._register(configurationService.onDidChangeConfiguration(e => this.updateFontAliasing(e, configurationService))); + + // Font Info + if (isNative) { + this._register(storageService.onWillSaveState(e => { + if (e.reason === WillSaveStateReason.SHUTDOWN) { + this.storeFontInfo(storageService); + } + })); + } else { + this._register(lifecycleService.onWillShutdown(() => this.storeFontInfo(storageService))); + } + + // Part Sizes — persist current grid sizes so they are restored on reload + this._register(storageService.onWillSaveState(() => this._savePartSizes())); + + // Lifecycle + this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event))); + this._register(lifecycleService.onDidShutdown(() => { + this._onDidShutdown.fire(); + this.dispose(); + })); + + // Flush storage on window focus loss + this._register(hostService.onDidChangeFocus(focus => { + if (!focus) { + storageService.flush(); + } + })); + + // Dialogs showing/hiding + this._register(dialogService.onWillShowDialog(() => this.mainContainer.classList.add('modal-dialog-visible'))); + this._register(dialogService.onDidShowDialog(() => this.mainContainer.classList.remove('modal-dialog-visible'))); + } + + //#region Font Aliasing and Caching + + private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto' | undefined; + private updateFontAliasing(e: IConfigurationChangeEvent | undefined, configurationService: IConfigurationService) { + if (!isMacintosh) { + return; // macOS only + } + + if (e && !e.affectsConfiguration('workbench.fontAliasing')) { + return; + } + + const aliasing = configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>('workbench.fontAliasing'); + if (this.fontAliasing === aliasing) { + return; + } + + this.fontAliasing = aliasing; + + // Remove all + const fontAliasingValues: (typeof aliasing)[] = ['antialiased', 'none', 'auto']; + this.mainContainer.classList.remove(...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); + + // Add specific + if (fontAliasingValues.some(option => option === aliasing)) { + this.mainContainer.classList.add(`monaco-font-aliasing-${aliasing}`); + } + } + + private restoreFontInfo(storageService: IStorageService, configurationService: IConfigurationService): void { + const storedFontInfoRaw = storageService.get('editorFontInfo', StorageScope.APPLICATION); + if (storedFontInfoRaw) { + try { + const storedFontInfo = JSON.parse(storedFontInfoRaw); + if (Array.isArray(storedFontInfo)) { + FontMeasurements.restoreFontInfo(mainWindow, storedFontInfo); + } + } catch (err) { + /* ignore */ + } + } + + FontMeasurements.readFontInfo(mainWindow, createBareFontInfoFromRawSettings(configurationService.getValue('editor'), PixelRatio.getInstance(mainWindow).value)); + } + + private storeFontInfo(storageService: IStorageService): void { + const serializedFontInfo = FontMeasurements.serializeFontInfo(mainWindow); + if (serializedFontInfo) { + storageService.store('editorFontInfo', JSON.stringify(serializedFontInfo), StorageScope.APPLICATION, StorageTarget.MACHINE); + } + } + + /** + * Applies Review's runtime-derived initial visibility and removes the + * obsolete persisted visibility record. Part sizes remain independently + * persisted so an explicitly opened editor can reuse its last valid width. + */ + private _applyInitialPartVisibility(): void { + this.storageService.remove(ReviewWorkbench._PART_VISIBILITY_KEY, StorageScope.WORKSPACE); + Object.assign(this.partVisibility, initialReviewPartVisibility); + } + + private _loadPartSizes(storageService: IStorageService): IPartSizesState { + const raw = storageService.get(ReviewWorkbench._PART_SIZES_KEY, StorageScope.WORKSPACE); + if (raw) { + try { + return JSON.parse(raw); + } catch { + // Corrupted data — remove the bad key so we don't keep warning on every startup + storageService.remove(ReviewWorkbench._PART_SIZES_KEY, StorageScope.WORKSPACE); + } + } + return {}; + } + + private _savePartSizes(): void { + if (!this.workbenchGrid) { + return; + } + + // The editor-part grid node hosts the docked auxiliary bar in single-pane, so + // it is "visible" whenever the editor OR the detail is shown. Use the node's + // real visibility (not just `partVisibility.editor`) so a Detail-only session + // records its *current* collapsed node width — reading the stale cached visible + // size (wide) here would restore a wide node on reload and flicker the editor + // open via the width-based reveal-sync. Classic layout is unaffected + // (`_editorNodeVisible` returns `partVisibility.editor` there). + const editorNodeVisible = this.partVisibility.editor; + const editorGridWidth = this._persistedGridViewSize(this.editorPartView, 'width', editorNodeVisible); + let editorWidth = editorGridWidth; + + // A sub-minimum measurement is never a real user width: the editor may be + // hidden (single-pane returns the detail-only node minus the detail width, + // i.e. ~0), or the high-priority sessions part may have transiently squeezed + // the node below its minimum. Persisting it would rebuild the editor at its + // 300px minimum on reload and lose the last user-selected width. Preserve the + // last valid global width instead (or omit it so the default is used). The + // descriptor keeps the editor contribution at zero while the editor part is + // hidden, so keeping a valid width here is safe. + if (editorWidth === undefined || editorWidth < EDITOR_PART_MINIMUM_WIDTH) { + editorWidth = (this._savedPartSizes.editor !== undefined && this._savedPartSizes.editor >= EDITOR_PART_MINIMUM_WIDTH) + ? this._savedPartSizes.editor + : undefined; + } else { + // Track the latest good width so a later shutdown-time squeeze falls back to it. + this._savedPartSizes = { ...this._savedPartSizes, editor: editorWidth }; + } + + const sizes: IPartSizesState = { + sessions: this._persistedGridViewSize(this.sessionsPartView, 'width', this.partVisibility.sessions), + editor: editorWidth, + // The explorer is hidden on most tabs, so this is usually the grid's + // cached visible size — the width the user last dragged the sash to. + explorer: this._persistedGridViewSize(this.explorerPartView, 'width', this.partVisibility.explorer), + }; + + this.storageService.store(ReviewWorkbench._PART_SIZES_KEY, JSON.stringify(sizes), StorageScope.WORKSPACE, StorageTarget.MACHINE); + } + + //#endregion + + private renderWorkbench(instantiationService: IInstantiationService, notificationService: NotificationService, storageService: IStorageService, configurationService: IConfigurationService): void { + // ARIA & Signals + setARIAContainer(this.mainContainer); + setProgressAccessibilitySignalScheduler((msDelayTime: number, msLoopTime?: number) => instantiationService.createInstance(AccessibilityProgressSignalScheduler, msDelayTime, msLoopTime)); + + // Apply Review's fixed desktop visibility before the grid is built. + this._applyInitialPartVisibility(); + + // Load saved grid part sizes — these will be consumed when building the + // grid descriptor so editor/sidebar/auxbar/panel restore to their previous + // dimensions across reloads. + this._savedPartSizes = this._loadPartSizes(storageService); + + // State specific classes + const platformClass = isWindows ? 'windows' : isLinux ? 'linux' : 'mac'; + const workbenchClasses = coalesce([ + 'monaco-workbench', + 'review-workbench', + // LayoutClasses.SHELL_GRADIENT_BACKGROUND, + platformClass, + isWeb ? 'web' : undefined, + isChrome ? 'chromium' : isFirefox ? 'firefox' : isSafari ? 'safari' : undefined, + ...this.getLayoutClasses(), + ...(this.options?.extraClasses ? this.options.extraClasses : []) + ]); + + this.mainContainer.classList.add(...workbenchClasses); + + // Apply font aliasing + this.updateFontAliasing(undefined, configurationService); + + // Warm up font cache information before building up too many dom elements + this.restoreFontInfo(storageService, configurationService); + + // Review owns exactly one chrome part. Sidebar, panel, auxiliary bar, + // activity bar, status bar, and banner parts are never instantiated. + for (const { id, role, classes } of [ + { id: Parts.TITLEBAR_PART, role: 'none', classes: ['titlebar'] }, + ]) { + const partContainer = this.createPartContainer(id, role, classes); + + mark(`code/willCreatePart/${id}`); + this.getPart(id).create(partContainer); + mark(`code/didCreatePart/${id}`); + + partContainer.classList.add('review-chrome-overlay'); + this.mainContainer.appendChild(partContainer); + } + + // Create Editor Part (hidden by default) + this.createEditorPart(); + + // Create Sessions Part + this.createSessionsPart(); + + // Create Review Explorer Part (hidden until a file or diff tab is active) + this.createExplorerPart(); + + // Notification Handlers + this.createNotificationsHandlers(instantiationService, notificationService, configurationService); + + // Add ReviewWorkbench to DOM + this.parent.appendChild(this.mainContainer); + } + + private createNotificationsHandlers( + instantiationService: IInstantiationService, + notificationService: NotificationService, + configurationService: IConfigurationService + ): void { + // Instantiate Notification components + const notificationsCenter = this._register(instantiationService.createInstance(NotificationsCenter, this.mainContainer, notificationService.model)); + const notificationsToasts = this._register(instantiationService.createInstance(NotificationsToasts, this.mainContainer, notificationService.model)); + this._register(instantiationService.createInstance(NotificationsAlerts, notificationService.model)); + const notificationsStatus = this._register(instantiationService.createInstance(NotificationsStatus, notificationService.model)); + + // Visibility + this._register(notificationsCenter.onDidChangeVisibility(() => { + notificationsStatus.update(notificationsCenter.isVisible, notificationsToasts.isVisible); + notificationsToasts.update(notificationsCenter.isVisible); + })); + + this._register(notificationsToasts.onDidChangeVisibility(() => { + notificationsStatus.update(notificationsCenter.isVisible, notificationsToasts.isVisible); + })); + + // Register Commands + registerNotificationCommands(notificationsCenter, notificationsToasts, notificationService.model); + + // Register notification accessible view + AccessibleViewRegistry.register(new NotificationAccessibleView()); + + // The shared notification controllers apply a top-right inline offset based on the + // default workbench custom titlebar height. The sessions workbench has its own + // fixed chrome, so re-apply the sessions-specific top-right offset after they run. + this.registerSessionsNotificationOffsets(configurationService, notificationsCenter, notificationsToasts); + + // Register with Layout + this.registerNotifications({ + onDidChangeNotificationsVisibility: Event.map( + Event.any(notificationsToasts.onDidChangeVisibility, notificationsCenter.onDidChangeVisibility), + () => notificationsToasts.isVisible || notificationsCenter.isVisible + ) + }); + } + + private registerSessionsNotificationOffsets( + configurationService: IConfigurationService, + notificationsCenter: NotificationsCenter, + notificationsToasts: NotificationsToasts + ): void { + const applySessionsNotificationOffsets = () => { + const position = getNotificationsPosition(configurationService); + const notificationsCenterContainer = this.getWorkbenchChildByClassName('notifications-center'); + const notificationsToastsContainer = this.getWorkbenchChildByClassName('notifications-toasts'); + + if (position === NotificationsPosition.TOP_RIGHT) { + notificationsCenterContainer?.style.setProperty('top', '40px'); + notificationsToastsContainer?.style.setProperty('top', '40px'); + } + }; + + this._register(this.onDidLayoutMainContainer(() => applySessionsNotificationOffsets())); + this._register(notificationsCenter.onDidChangeVisibility(() => applySessionsNotificationOffsets())); + this._register(notificationsToasts.onDidChangeVisibility(() => applySessionsNotificationOffsets())); + this._register(configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(NotificationsSettings.NOTIFICATIONS_POSITION)) { + applySessionsNotificationOffsets(); + } + })); + } + + private getWorkbenchChildByClassName(className: string): HTMLElement | undefined { + for (const child of this.mainContainer.children) { + if (isHTMLElement(child) && child.classList.contains(className)) { + return child; + } + } + + return undefined; + } + + private createPartContainer(id: string, role: string, classes: string[]): HTMLElement { + const part = document.createElement('div'); + part.classList.add('part', ...classes); + part.id = id; + part.setAttribute('role', role); + return part; + } + + private createEditorPart(): void { + const editorPartContainer = document.createElement('div'); + editorPartContainer.classList.add('part', 'editor'); + editorPartContainer.id = Parts.EDITOR_PART; + editorPartContainer.setAttribute('role', 'main'); + this._editorPartContainer = editorPartContainer; + + mark('code/willCreatePart/workbench.parts.editor'); + this.getPart(Parts.EDITOR_PART).create(editorPartContainer, { restorePreviousState: true }); + mark('code/didCreatePart/workbench.parts.editor'); + + this.mainContainer.appendChild(editorPartContainer); + } + + private createSessionsPart(): void { + const sessionsPartContainer = document.createElement('div'); + sessionsPartContainer.classList.add('part', 'sessionspart', 'basepanel', 'right'); + sessionsPartContainer.id = Parts.SESSIONS_PART; + sessionsPartContainer.setAttribute('role', 'main'); + + mark(`code/willCreatePart/${Parts.SESSIONS_PART}`); + this.getPart(Parts.SESSIONS_PART).create(sessionsPartContainer); + mark(`code/didCreatePart/${Parts.SESSIONS_PART}`); + + this.mainContainer.appendChild(sessionsPartContainer); + } + + private createExplorerPart(): void { + const explorerPartContainer = document.createElement('div'); + explorerPartContainer.classList.add('part', 'review-explorer'); + explorerPartContainer.id = Parts.REVIEW_EXPLORER_PART; + explorerPartContainer.setAttribute('role', 'navigation'); + + mark(`code/willCreatePart/${Parts.REVIEW_EXPLORER_PART}`); + this.getPart(Parts.REVIEW_EXPLORER_PART).create(explorerPartContainer); + mark(`code/didCreatePart/${Parts.REVIEW_EXPLORER_PART}`); + + this.mainContainer.appendChild(explorerPartContainer); + } + + private restore(lifecycleService: ILifecycleService): void { + // Update perf marks + mark('code/didStartWorkbench'); + performance.measure('perf: workbench create & restore', 'code/didLoadWorkbenchMain', 'code/didStartWorkbench'); + + // Set lifecycle phase to `Restored` + lifecycleService.phase = LifecyclePhase.Restored; + + // Mark as restored + this.setRestored(); + + // Set lifecycle phase to `Eventually` after a short delay and when idle (min 2.5sec, max 5sec) + const eventuallyPhaseScheduler = this._register(new RunOnceScheduler(() => { + this._register(runWhenWindowIdle(mainWindow, () => lifecycleService.phase = LifecyclePhase.Eventually, 2500)); + }, 2500)); + eventuallyPhaseScheduler.schedule(); + } + + //#endregion + + //#region Initialization + + initLayout(accessor: ServicesAccessor): void { + // Services - accessing these triggers their instantiation + // which creates and registers the parts + this.editorGroupService = accessor.get(IEditorGroupsService); + this.editorService = accessor.get(IEditorService); + // Forces eager creation of the sessions part so it registers itself with the + // layout service before renderWorkbench() looks it up via getPart(). + accessor.get(IReviewCanvasPartsService); + // Same for the file explorer part, which also owns its own show/hide policy. + accessor.get(IReviewExplorerPartsService); + // The sidebar, panel, and auxiliary bar stay hidden in Review, but the + // part-visibility setters below still reach for this service; leaving it + // unassigned would throw the moment any of them ran. + this.paneCompositeService = accessor.get(IPaneCompositePartService); + this.storageService = accessor.get(IStorageService); + accessor.get(ITitleService); + + const editorMainPart = this.editorGroupService.mainPart; + this._register(editorMainPart.onDidLayout(() => this.reviewChromeInsetScheduler.schedule())); + const titlebarPart = this.getPart(Parts.TITLEBAR_PART); + if (titlebarPart instanceof MainReviewTitlebarPart) { + this._register(titlebarPart.onDidChangeChromeInsets(() => this.reviewChromeInsetScheduler.schedule())); + } + this._register(editorMainPart.onDidAddGroup(() => this.reviewChromeInsetScheduler.schedule())); + this._register(editorMainPart.onDidRemoveGroup(() => this.reviewChromeInsetScheduler.schedule())); + this._register(editorMainPart.onDidMoveGroup(() => this.reviewChromeInsetScheduler.schedule())); + + // Register layout listeners + this.registerLayoutListeners(); + + // Editor opens should only affect the main editor part when + // they actually target one of the main editor groups. Modal + // opens stay neutral. Programmatic opens that suppress auto + // visibility (e.g. working set application) are ignored. + // The base handler reveals a hidden editor for any such open; + this._register(this.editorService.onWillOpenEditor(e => this.revealEditorOnOpen(e))); + + // Hide editor part when last editor closes + this._register(this.editorService.onDidCloseEditor(() => this.handleDidCloseEditor())); + + // Initialize layout state (must be done before createWorkbenchLayout) + this._mainContainerDimension = getClientArea(this.parent, new Dimension(800, 600)); + // Establish runtime-derived visibility before the context keys handler is + // created. The editor becomes visible only in response to a real open. + this._applyInitialPartVisibility(); + } + + private areAllGroupsInMainPartEmpty(): boolean { + for (const group of this.editorGroupService.mainPart.groups) { + if (!group.isEmpty) { + return false; + } + } + return true; + } + + protected revealEditorOnOpen(e: IEditorWillOpenEvent): void { + if (this._editorPartAutoVisibilitySuppressionCount > 0) { + return; + } + + const group = this.editorGroupService.mainPart.groups.find(g => g.id === e.groupId); + if (!group) { + return; + } + + if (!this.partVisibility.editor) { + this.setEditorHidden(false); + this.restoreAttachedEditorMaximizedState(); + } + } + + private handleDidCloseEditor(): void { + if (this._editorPartAutoVisibilitySuppressionCount > 0 || !this.areAllGroupsInMainPartEmpty()) { + return; + } + + this._handleAllEditorsClosed(); + } + + suppressEditorPartAutoVisibility(): IDisposable { + this._editorPartAutoVisibilitySuppressionCount++; + let disposed = false; + return toDisposable(() => { + if (disposed) { + return; + } + disposed = true; + this._editorPartAutoVisibilitySuppressionCount--; + }); + } + + protected rememberAttachedEditorMaximizedState(): void { + this._restoreAttachedEditorMaximizedOnShow = this._editorMaximized && this.partVisibility.auxiliaryBar; + } + + private restoreAttachedEditorMaximizedState(): void { + const shouldRestore = this._restoreAttachedEditorMaximizedOnShow && this.partVisibility.auxiliaryBar; + this._restoreAttachedEditorMaximizedOnShow = false; + + if (shouldRestore) { + this.setEditorMaximized(true); + } + } + + //#region Layout helpers + + /** + * Handles a change in the editor-part grid view's visibility. In the classic + * layout the editor part is a standalone grid view, so its view visibility *is* + * the editor visibility — map it to `setEditorHidden` and raise the part event. + */ + protected _onEditorPartGridVisibilityChange(visible: boolean): void { + this.setEditorHidden(!visible); + this._onDidChangePartVisibility.fire({ partId: Parts.EDITOR_PART, visible }); + } + + protected get _isEditorPartAutoVisibilitySuppressed(): boolean { + return this._editorPartAutoVisibilitySuppressionCount > 0; + } + + /** Width the auxiliary bar occupies when visible (for max-editor-dimension math). */ + protected _auxiliaryBarLayoutWidth(): number { + return this.workbenchGrid ? this.workbenchGrid.getViewSize(this.auxiliaryBarPartView).width : 0; + } + + protected _auxiliaryBarViewSize(): IViewSize { + if (!this.workbenchGrid || !this.auxiliaryBarPartView) { + return { width: 0, height: 0 }; + } + return this.workbenchGrid.getViewSize(this.auxiliaryBarPartView); + } + + protected _setAuxiliaryBarViewSize(size: IViewSize): void { + if (this.auxiliaryBarPartView) { + this.workbenchGrid.resizeView(this.auxiliaryBarPartView, size); + } + } + + protected _resizeAuxiliaryBarBy(deltaWidth: number, deltaHeight: number): void { + if (!this.auxiliaryBarPartView) { + return; + } + const currentSize = this.workbenchGrid.getViewSize(this.auxiliaryBarPartView); + this.workbenchGrid.resizeView(this.auxiliaryBarPartView, { + width: currentSize.width + deltaWidth, + height: currentSize.height + deltaHeight + }); + } + + /** + * Reads a part's size from the workbench grid for persistence. For visible + * parts, the current view size; for hidden parts, the grid's cached visible + * size (the size it had the last time it was shown) so toggling visibility + * later restores the same dimensions. + */ + protected _persistedGridViewSize(view: ISerializableView, dimension: 'width' | 'height', visible: boolean): number | undefined { + if (visible) { + return this.workbenchGrid.getViewSize(view)[dimension]; + } + return this.workbenchGrid.getViewCachedVisibleSize(view); + } + + protected _applyEditorVisibility(hidden: boolean): void { + const shouldApplyEvenSplit = !hidden && !this._hasAppliedInitialEditorSplit; + + // Capture the main-area width (the sessions part occupies it fully while the + // editor is hidden) before revealing, so the even split can halve it. + const mainAreaWidth = this.workbenchGrid.getViewSize(this.sessionsPartView).width; + + this.workbenchGrid.setViewVisible(this.editorPartView, !hidden); + + if (shouldApplyEvenSplit) { + this._hasAppliedInitialEditorSplit = true; + this._applyEditorSplitSize(mainAreaWidth); + } + } + + protected _applyAuxiliaryBarVisibility(hidden: boolean): void { + // Skipped before the grid exists: during startup the layout controller (a + // BlockRestore contribution) runs before createWorkbenchLayout(), so the + // visibility is recorded in partVisibility and applied when the grid is built. + if (this.workbenchGrid) { + this.workbenchGrid.setViewVisible(this.auxiliaryBarPartView, !hidden); + } + } + + protected _handleAllEditorsClosed(): void { + if (this.partVisibility.editor) { + this.rememberAttachedEditorMaximizedState(); + this.setEditorHidden(true); + } + } + + //#endregion + + private registerLayoutListeners(): void { + // Fullscreen changes + this._register(onDidChangeFullscreen(windowId => { + if (windowId === getWindowId(mainWindow)) { + this.mainWindowFullscreen = isFullscreen(mainWindow); + this.updateFullscreenClass(); + this.layout(); + } + })); + + // Window resize — needed for device emulation and mobile viewport changes + const onWindowResize = () => this.layout(); + this._register(addDisposableListener(mainWindow, 'resize', onWindowResize)); + } + + private updateFullscreenClass(): void { + if (this.mainWindowFullscreen) { + this.mainContainer.classList.add(LayoutClasses.FULLSCREEN); + } else { + this.mainContainer.classList.remove(LayoutClasses.FULLSCREEN); + } + } + + /** + * Written on the tab strip that reads them, not the workbench root: a + * changed inherited custom property restyles every element below it, and + * with a canvas full of peek editors that was a ~200ms stall per explorer + * show, hide or sash move. + */ + private publishReviewChromeInset(tabStrip: HTMLElement): void { + const titlebarPart = this.getPart(Parts.TITLEBAR_PART); + const insets = titlebarPart instanceof MainReviewTitlebarPart ? titlebarPart.chromeInsets : { left: 0, right: 0 }; + const explorerWidth = this.isVisible(Parts.REVIEW_EXPLORER_PART) ? this.getSize(Parts.REVIEW_EXPLORER_PART).width : 0; + tabStrip.style.setProperty('--review-chrome-left-width', `${insets.left}px`); + tabStrip.style.setProperty('--review-chrome-right-width', `${insets.right}px`); + tabStrip.style.setProperty('--review-explorer-width', `${explorerWidth}px`); + } + + private updateReviewChromeInset(): void { + this.reviewChromeDragListeners.clear(); + this.mainContainer.classList.remove('review-tab-dragging'); + for (const tabStrip of this.reviewChromeTabStrips) { + tabStrip.classList.remove('review-chrome-tab-strip', 'review-chrome-inset'); + for (const property of REVIEW_CHROME_INSET_PROPERTIES) { + tabStrip.style.removeProperty(property); + } + } + this.reviewChromeTabStrips.length = 0; + + const editorPartContainer = this._editorPartContainer; + if (!editorPartContainer) { + return; + } + + let topLeftGroup: HTMLElement | undefined; + let topLeftRect: DOMRect | undefined; + const visibleGroups: { group: HTMLElement; rect: DOMRect }[] = []; + const groups = editorPartContainer.getElementsByClassName('editor-group-container'); + for (let index = 0; index < groups.length; index++) { + const group = groups[index]; + if (!isHTMLElement(group)) { + continue; + } + + const rect = group.getBoundingClientRect(); + if (rect.width === 0 || rect.height === 0) { + continue; + } + + visibleGroups.push({ group, rect }); + + if (!topLeftRect || rect.top < topLeftRect.top - 1 || (Math.abs(rect.top - topLeftRect.top) <= 1 && rect.left < topLeftRect.left)) { + topLeftGroup = group; + topLeftRect = rect; + } + } + + if (!topLeftGroup || !topLeftRect) { + return; + } + + const finishTabDrag = () => this.mainContainer.classList.remove('review-tab-dragging'); + + // Every top-row group shares window dragging. Only the leftmost group + // needs the navigation inset. + for (const { group, rect } of visibleGroups) { + if (Math.abs(rect.top - topLeftRect.top) > 1) { + continue; + } + + const tabStrip = group.querySelector(':scope > .title > .tabs-and-actions-container'); + if (!isHTMLElement(tabStrip)) { + continue; + } + + this.reviewChromeTabStrips.push(tabStrip); + tabStrip.classList.add('review-chrome-tab-strip'); + if (group === topLeftGroup) { + tabStrip.classList.add('review-chrome-inset'); + this.publishReviewChromeInset(tabStrip); + } + this.reviewChromeDragListeners.add(addDisposableListener(tabStrip, 'dragstart', () => this.mainContainer.classList.add('review-tab-dragging'))); + this.reviewChromeDragListeners.add(addDisposableListener(tabStrip, 'dragend', finishTabDrag)); + this.reviewChromeDragListeners.add(addDisposableListener(tabStrip, 'drop', finishTabDrag)); + } + } + + //#endregion + + //#region ReviewWorkbench Layout Creation + + createWorkbenchLayout(): void { + const editorPart = this.getPart(Parts.EDITOR_PART); + const sessionsPart = this.getPart(Parts.SESSIONS_PART); + const explorerPart = this.getPart(Parts.REVIEW_EXPLORER_PART); + + this.sessionsPartView = sessionsPart; + this.editorPartView = editorPart; + this.explorerPartView = explorerPart; + + const viewMap: { [key: string]: ISerializableView } = { + [Parts.SESSIONS_PART]: this.sessionsPartView, + [Parts.EDITOR_PART]: this.editorPartView, + [Parts.REVIEW_EXPLORER_PART]: this.explorerPartView + }; + + const fromJSON = ({ type }: { type: string }) => viewMap[type]; + const workbenchGrid = SerializableGrid.deserialize( + this.createGridDescriptor(), + { fromJSON }, + { proportionalLayout: false } + ); + + this.mainContainer.prepend(workbenchGrid.element); + this.mainContainer.setAttribute('role', 'application'); + this.workbenchGrid = workbenchGrid; + this.workbenchGrid.edgeSnapping = this.mainWindowFullscreen; + // If the editor is restored visible, it already has an established + // width, so a later reveal must not force an even split over it. + this._hasAppliedInitialEditorSplit = this.partVisibility.editor; + + for (const part of [sessionsPart, editorPart, explorerPart]) { + this._register(part.onDidVisibilityChange(visible => { + // A grid branch forwards its own show/hide to every child leaf, + // including leaves whose slot stays hidden. That notification + // describes the branch, not the part, so acting on it would reveal + // a part the grid still holds hidden. The grid is authoritative for + // every part it owns, and Review puts all of them in the grid. + if (this.workbenchGrid.isViewVisible(part) === !visible) { + return; + } + + if (part === editorPart) { + this._onEditorPartGridVisibilityChange(visible); + this.handleContainerDidLayout(this.mainContainer, this._mainContainerDimension); + return; + } + + if (part === sessionsPart) { + this.setSessionsHidden(!visible); + } + + if (part === explorerPart) { + this.setExplorerHidden(!visible); + } + + this._onDidChangePartVisibility.fire({ partId: part.getId(), visible }); + this.handleContainerDidLayout(this.mainContainer, this._mainContainerDimension); + })); + } + } + + createWorkbenchManagement(_instantiationService: IInstantiationService): void { } + + /** + * Creates the grid descriptor for the Agent Sessions layout. + * + * Structure (horizontal orientation): + * - Sidebar (left, spans full height from top to bottom) + * - Right section (vertical): + * - Titlebar (top of right section) + * - Top right (horizontal): Chat Bar | Editor | Auxiliary Bar + * - Panel (below chat, editor, and auxiliary bar) + */ + private createGridDescriptor(): ISerializedGrid { + const { width, height } = this._mainContainerDimension; + + return this.createDesktopGridDescriptor(width, height); + } + + /** + * Standard multi-part layout. Sidebar, panel, and auxiliary bar are hidden + * in the grid via partVisibility defaults. + */ + private createDesktopGridDescriptor(width: number, height: number): ISerializedGrid { + const savedEditorWidth = this._savedPartSizes.editor; + const editorSize = savedEditorWidth !== undefined && savedEditorWidth >= EDITOR_PART_MINIMUM_WIDTH ? savedEditorWidth : EDITOR_PART_DEFAULT_WIDTH; + const effectiveEditorWidth = this.partVisibility.editor ? editorSize : 0; + const sessionsWidth = this._savedPartSizes.sessions + ?? Math.max(0, width - effectiveEditorWidth); + const contentHeight = height; + + const sessionsNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.SESSIONS_PART }, + size: sessionsWidth, + visible: this.partVisibility.sessions + }; + + const editorNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.EDITOR_PART }, + size: effectiveEditorWidth, + visible: this.partVisibility.editor + }; + + // The explorer sits left of the editor. `partVisibility.explorer` is always + // false here — it is derived from the active editor, and no editor is + // restored yet — so the leaf carries only the width a later reveal uses. + const explorerNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.REVIEW_EXPLORER_PART }, + size: this._savedPartSizes.explorer ?? EXPLORER_PART_DEFAULT_WIDTH, + visible: this.partVisibility.explorer + }; + + const contentSection: ISerializedNode = { + type: 'branch', + data: [sessionsNode, explorerNode, editorNode], + size: contentHeight + }; + + const result: ISerializedGrid = { + root: { + type: 'branch', + size: width, + data: [contentSection] + }, + orientation: Orientation.VERTICAL, + width, + height + }; + + return result; + } + + //#endregion + + //#region Layout Methods + + layout(): void { + this._mainContainerDimension = getClientArea( + this.mainWindowFullscreen ? mainWindow.document.body : this.parent + ); + + this.logService.trace(`ReviewWorkbench#layout, height: ${this._mainContainerDimension.height}, width: ${this._mainContainerDimension.width}`); + + size(this.mainContainer, this._mainContainerDimension.width, this._mainContainerDimension.height); + + // A deliberate 10px breathing gap along the bottom edge, kept to match the window + // shape of stock VS Code. Review draws no part cards, so this is bare workbench + // ground rather than a margin around a card; review.css paints it with the editor + // background so it reads as one surface. + // + // The right edge takes no gutter: stock VS Code runs its parts flush to the window + // edge, and Review has no right-edge card to inset -- the card margins that would + // have needed one live under `.agent-sessions-workbench`, a class `workbenchClasses` + // never includes. + const gutterBottom = 10; + const gridWidth = this._mainContainerDimension.width; + const gridHeight = this._mainContainerDimension.height - gutterBottom; + + // Layout the grid widget + this.workbenchGrid.layout(gridWidth, gridHeight); + this.getPart(Parts.TITLEBAR_PART).layout(gridWidth, REVIEW_CHROME_HEIGHT, 0, 0); + this.updateReviewChromeInset(); + + // Emit as event + this.handleContainerDidLayout(this.mainContainer, this._mainContainerDimension); + } + + private handleContainerDidLayout(container: HTMLElement, dimension: IDimension): void { + this._onDidLayoutContainer.fire({ container, dimension }); + if (container === this.mainContainer) { + this._onDidLayoutMainContainer.fire(dimension); + } + if (container === this.activeContainer) { + this._onDidLayoutActiveContainer.fire(dimension); + } + } + + isFloatingPanelsEnabled(): boolean { + return false; // the agents window has its own floating card design + } + + getLayoutClasses(): string[] { + return coalesce([ + !this.partVisibility.sidebar ? LayoutClasses.SIDEBAR_HIDDEN : undefined, + !this.partVisibility.editor ? LayoutClasses.MAIN_EDITOR_AREA_HIDDEN : undefined, + !this.partVisibility.panel ? LayoutClasses.PANEL_HIDDEN : undefined, + !this.partVisibility.auxiliaryBar ? LayoutClasses.AUXILIARYBAR_HIDDEN : undefined, + !this.partVisibility.sessions ? LayoutClasses.SESSIONS_HIDDEN : undefined, + LayoutClasses.STATUSBAR_HIDDEN, // agents window never has a status bar + this.mainWindowFullscreen ? LayoutClasses.FULLSCREEN : undefined, + ]); + } + + //#endregion + + //#region Part Management + + registerPart(part: Part): IDisposable { + const id = part.getId(); + this.parts.set(id, part); + return toDisposable(() => this.parts.delete(id)); + } + + getPart(key: Parts): Part { + const part = this.parts.get(key); + if (!part) { + throw new Error(`Unknown part ${key}`); + } + return part; + } + + hasFocus(part: Parts): boolean { + const container = this.getContainer(mainWindow, part); + if (!container) { + return false; + } + + const activeElement = getActiveElement(); + if (!activeElement) { + return false; + } + + return isAncestorUsingFlowTo(activeElement, container); + } + + focusPart(part: MULTI_WINDOW_PARTS, targetWindow: Window): void; + focusPart(part: SINGLE_WINDOW_PARTS): void; + focusPart(part: Parts, targetWindow: Window = mainWindow): void { + switch (part) { + case Parts.EDITOR_PART: + this.editorGroupService.activeGroup.focus(); + break; + case Parts.PANEL_PART: + this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel)?.focus(); + break; + case Parts.SIDEBAR_PART: + this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar)?.focus(); + break; + case Parts.AUXILIARYBAR_PART: + this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar)?.focus(); + break; + case Parts.SESSIONS_PART: + // TODO: focus chat bar content once it is wired up + this.getPart(Parts.SESSIONS_PART).getContainer()?.focus(); + break; + default: { + const container = this.getContainer(targetWindow, part); + container?.focus(); + } + } + } + + focus(): void { + this.focusPart(Parts.SESSIONS_PART); + } + + //#endregion + + //#region Container Methods + + getContainer(targetWindow: Window): HTMLElement; + getContainer(targetWindow: Window, part: Parts): HTMLElement | undefined; + getContainer(targetWindow: Window, part?: Parts): HTMLElement | undefined { + if (typeof part === 'undefined') { + return this.getContainerFromDocument(targetWindow.document); + } + + if (targetWindow === mainWindow) { + return this.parts.get(part)?.getContainer(); + } + + // For auxiliary windows, only editor part is supported + if (part === Parts.EDITOR_PART) { + const container = this.getContainerFromDocument(targetWindow.document); + const partCandidate = this.editorGroupService.getPart(container); + if (partCandidate instanceof Part) { + return partCandidate.getContainer(); + } + } + + return undefined; + } + + whenContainerStylesLoaded(_window: CodeWindow): Promise | undefined { + return undefined; + } + + //#endregion + + //#region Part Visibility + + isActivityBarHidden(): boolean { + return true; // No activity bar in this layout + } + + isVisible(part: SINGLE_WINDOW_PARTS): boolean; + isVisible(part: MULTI_WINDOW_PARTS, targetWindow: Window): boolean; + isVisible(part: Parts, targetWindow?: Window): boolean { + switch (part) { + case Parts.TITLEBAR_PART: + return true; + case Parts.SIDEBAR_PART: + case Parts.AUXILIARYBAR_PART: + case Parts.PANEL_PART: + return false; + case Parts.EDITOR_PART: + return this.partVisibility.editor; + case Parts.SESSIONS_PART: + return this.partVisibility.sessions; + case Parts.REVIEW_EXPLORER_PART: + return this.partVisibility.explorer; + case Parts.ACTIVITYBAR_PART: + case Parts.STATUSBAR_PART: + case Parts.BANNER_PART: + default: + return false; + } + } + + setPartHidden(hidden: boolean, part: Parts): void { + switch (part) { + case Parts.SIDEBAR_PART: + this.setSideBarHidden(hidden); + break; + case Parts.AUXILIARYBAR_PART: + this.setAuxiliaryBarHidden(hidden); + break; + case Parts.EDITOR_PART: + this.setEditorHidden(hidden); + break; + case Parts.PANEL_PART: + this.setPanelHidden(hidden); + break; + case Parts.SESSIONS_PART: + this.setSessionsHidden(hidden); + break; + case Parts.REVIEW_EXPLORER_PART: + this.setExplorerHidden(hidden); + break; + } + } + + private setSideBarHidden(hidden: boolean): void { + if (this.partVisibility.sidebar === !hidden) { + return; + } + + this.partVisibility.sidebar = !hidden; + this.mainContainer.classList.toggle(LayoutClasses.SIDEBAR_HIDDEN, hidden); + + // Propagate to grid + this.workbenchGrid.setViewVisible( + this.sideBarPartView, + !hidden, + ); + + // If sidebar becomes hidden, also hide the current active pane composite + if (hidden && this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar)) { + this.paneCompositeService.hideActivePaneComposite(ViewContainerLocation.Sidebar); + } + + // If sidebar becomes visible, show last active Viewlet or default viewlet + if (!hidden && !this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar)) { + const viewletToOpen = this.paneCompositeService.getLastActivePaneCompositeId(ViewContainerLocation.Sidebar) ?? + this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id; + if (viewletToOpen) { + this.paneCompositeService.openPaneComposite(viewletToOpen, ViewContainerLocation.Sidebar); + } + } + } + + setAuxiliaryBarHidden(hidden: boolean): void { + if (this.partVisibility.auxiliaryBar === !hidden) { + return; + } + + if (hidden) { + this._restoreAttachedEditorMaximizedOnShow = false; + } + + this.partVisibility.auxiliaryBar = !hidden; + this.mainContainer.classList.toggle(LayoutClasses.AUXILIARYBAR_HIDDEN, hidden); + + this._applyAuxiliaryBarVisibility(hidden); + + // If auxiliary bar becomes hidden, also hide the current active pane composite + if (hidden && this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar)) { + this.paneCompositeService.hideActivePaneComposite(ViewContainerLocation.AuxiliaryBar); + } + + // If auxiliary bar becomes visible, show last active pane composite or default + if (!hidden && !this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar)) { + const paneCompositeToOpen = this.paneCompositeService.getLastActivePaneCompositeId(ViewContainerLocation.AuxiliaryBar) ?? + this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.AuxiliaryBar)?.id; + if (paneCompositeToOpen) { + this.paneCompositeService.openPaneComposite(paneCompositeToOpen, ViewContainerLocation.AuxiliaryBar); + } + } + + } + + setEditorHidden(hidden: boolean): void { + if (this.partVisibility.editor === !hidden) { + return; + } + + if (hidden && this._editorMaximized) { + this.setEditorMaximized(false); + } + + this.partVisibility.editor = !hidden; + this.mainContainer.classList.toggle(LayoutClasses.MAIN_EDITOR_AREA_HIDDEN, hidden); + + if (this.editorPartView) { + this._applyEditorVisibility(hidden); + } + } + + /** + * Sizes the editor part when it is first revealed from a hidden state, so it + * opens as a comfortable split with the sessions part rather than at its + * minimum/restored width. The default grid layout splits the main area evenly; + * layouts with different sizing (e.g. the single-pane side pane) override this. + */ + protected _applyEditorSplitSize(mainAreaWidth: number): void { + const targetEditorWidth = Math.max(EDITOR_PART_MINIMUM_WIDTH, Math.floor(mainAreaWidth / 2)); + const currentEditorSize = this.workbenchGrid.getViewSize(this.editorPartView); + this.workbenchGrid.resizeView(this.editorPartView, { + width: targetEditorWidth, + height: currentEditorSize.height + }); + } + + private setPanelHidden(hidden: boolean): void { + if (this.partVisibility.panel === !hidden) { + return; + } + + // If hiding and the panel is maximized, exit maximized state first + if (hidden && this.workbenchGrid.hasMaximizedView()) { + this.workbenchGrid.exitMaximizedView(); + } + + const panelHadFocus = !hidden || this.hasFocus(Parts.PANEL_PART); + + this.partVisibility.panel = !hidden; + this.mainContainer.classList.toggle(LayoutClasses.PANEL_HIDDEN, hidden); + + // Propagate to grid + this.workbenchGrid.setViewVisible( + this.panelPartView, + !hidden, + ); + + // If panel becomes hidden, also hide the current active pane composite + if (hidden && this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel)) { + this.paneCompositeService.hideActivePaneComposite(ViewContainerLocation.Panel); + + // Focus the chat bar when hiding the panel if it had focus + if (panelHadFocus) { + this.focusPart(Parts.SESSIONS_PART); + } + } + + // If panel becomes visible, show last active panel or default and focus it + if (!hidden) { + if (!this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel)) { + const panelToOpen = this.paneCompositeService.getLastActivePaneCompositeId(ViewContainerLocation.Panel) ?? + this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Panel)?.id; + if (panelToOpen) { + this.paneCompositeService.openPaneComposite(panelToOpen, ViewContainerLocation.Panel); + } + } + + this.focusPart(Parts.PANEL_PART); + } + } + + private setSessionsHidden(hidden: boolean): void { + // Review hosts Home, canvases, files, and diffs in the editor group. The + // sessions part stays registered as a hidden layout placeholder with no + // content, so showing it only adds dead space no Review command can + // collapse. See `initialReviewPartVisibility`. + if (!hidden) { + return; + } + + if (this.partVisibility.sessions === !hidden) { + return; + } + + this.partVisibility.sessions = !hidden; + this.mainContainer.classList.toggle(LayoutClasses.SESSIONS_HIDDEN, hidden); + + // Propagate to grid + this.workbenchGrid.setViewVisible(this.sessionsPartView, !hidden); + } + + /** + * Shows or hides the file explorer leaf. + * + * `ReviewExplorerParts` is the only caller: it derives the state from the + * active editor pane. A maximized editor owns the whole window, so a tab + * switch under it must not bring the explorer back. + */ + private setExplorerHidden(hidden: boolean): void { + if (!hidden && this._editorMaximized) { + return; + } + + if (this.partVisibility.explorer === !hidden) { + return; + } + + this.partVisibility.explorer = !hidden; + this.mainContainer.classList.toggle(LayoutClasses.EXPLORER_VISIBLE, !hidden); + + // The eager explorer service runs in initLayout(), before the grid exists. + // The descriptor reads partVisibility, so the state above still lands. + if (this.workbenchGrid) { + this.workbenchGrid.setViewVisible(this.explorerPartView, !hidden); + } + } + + //#endregion + + //#region Position Methods (Fixed - Not Configurable) + + getSideBarPosition(): Position { + return Position.LEFT; // Always left in this layout + } + + getPanelPosition(): Position { + return Position.BOTTOM; // Always bottom in this layout + } + + setPanelPosition(_position: Position): void { + // No-op: Panel position is fixed in this layout + } + + getPanelAlignment(): PanelAlignment { + return 'justify'; // Full width panel + } + + setPanelAlignment(_alignment: PanelAlignment): void { + // No-op: Panel alignment is fixed in this layout + } + + //#endregion + + //#region Size Methods + + getSize(part: Parts): IViewSize { + if (part === Parts.TITLEBAR_PART) { + return { width: this._mainContainerDimension.width, height: REVIEW_CHROME_HEIGHT }; + } + if (part === Parts.AUXILIARYBAR_PART) { + return this._auxiliaryBarViewSize(); + } + const view = this.getPartView(part); + if (!view) { + return { width: 0, height: 0 }; + } + return this.workbenchGrid.getViewSize(view); + } + + setSize(part: Parts, size: IViewSize): void { + if (part === Parts.AUXILIARYBAR_PART) { + this._setAuxiliaryBarViewSize(size); + return; + } + const view = this.getPartView(part); + if (view) { + this.workbenchGrid.resizeView(view, size); + } + } + + resizePart(part: Parts, sizeChangeWidth: number, sizeChangeHeight: number): void { + if (part === Parts.AUXILIARYBAR_PART) { + this._resizeAuxiliaryBarBy(sizeChangeWidth, sizeChangeHeight); + return; + } + const view = this.getPartView(part); + if (!view) { + return; + } + + const currentSize = this.workbenchGrid.getViewSize(view); + this.workbenchGrid.resizeView(view, { + width: currentSize.width + sizeChangeWidth, + height: currentSize.height + sizeChangeHeight + }); + } + + private getPartView(part: Parts): ISerializableView | undefined { + switch (part) { + case Parts.SIDEBAR_PART: + return this.sideBarPartView; + case Parts.AUXILIARYBAR_PART: + return this.auxiliaryBarPartView; + case Parts.EDITOR_PART: + return this.editorPartView; + case Parts.PANEL_PART: + return this.panelPartView; + case Parts.SESSIONS_PART: + return this.sessionsPartView; + case Parts.REVIEW_EXPLORER_PART: + return this.explorerPartView; + default: + return undefined; + } + } + + getMaximumEditorDimensions(_container: HTMLElement): IDimension { + // Return the available space for editor (excluding other parts) + const sidebarWidth = this.partVisibility.sidebar ? this.workbenchGrid.getViewSize(this.sideBarPartView).width : 0; + const auxiliaryBarWidth = this.partVisibility.auxiliaryBar + ? this._auxiliaryBarLayoutWidth() + : 0; + const panelHeight = this.partVisibility.panel ? this.workbenchGrid.getViewSize(this.panelPartView).height : 0; + return new Dimension( + this._mainContainerDimension.width - sidebarWidth - auxiliaryBarWidth, + this._mainContainerDimension.height - panelHeight + ); + } + + //#endregion + + //#region Unsupported Features (No-ops) + + toggleMaximizedPanel(): void { + // Review never adds a panel node to its fixed grid. + } + + isPanelMaximized(): boolean { + return false; + } + + toggleMaximizedAuxiliaryBar(): void { + // No-op: Maximize not supported in this layout + } + + setAuxiliaryBarMaximized(_maximized: boolean): boolean { + return false; // Maximize not supported + } + + isAuxiliaryBarMaximized(): boolean { + return false; // Maximize not supported + } + + isEditorMaximized(): boolean { + return this._editorMaximized; + } + + setEditorMaximized(maximized: boolean): void { + if (maximized === this._editorMaximized) { + return; + } + + if (maximized) { + // Save current visibility state + this._editorLastNonMaximizedVisibility = { + sidebar: this.partVisibility.sidebar, + auxiliaryBar: this.partVisibility.auxiliaryBar, + editor: this.partVisibility.editor, + panel: this.partVisibility.panel, + sessions: this.partVisibility.sessions, + explorer: this.partVisibility.explorer, + }; + + // Save the editor part size so it can be restored on un-maximize. + // While maximized the layout controller forces the auxiliary bar + // (Changes) visible, which shrinks the editor; without restoring the + // size the editor would not return to its previous width. + this._editorLastNonMaximizedSize = this.editorPartView + ? this.workbenchGrid.getViewSize(this.editorPartView) + : undefined; + + // Ensure editor is visible + if (!this.partVisibility.editor) { + this.setEditorHidden(false); + } + + // Hide all other content parts + if (this.partVisibility.sidebar) { + this.setSideBarHidden(true); + } + if (this.partVisibility.sessions) { + this.setSessionsHidden(true); + } + if (this.partVisibility.explorer) { + this.setExplorerHidden(true); + } + + this._editorMaximized = true; + } else { + const state = this._editorLastNonMaximizedVisibility; + const size = this._editorLastNonMaximizedSize; + this._editorLastNonMaximizedSize = undefined; + + // Restore previous visibility state, including the auxiliary bar + // (which the layout controller forced visible while maximized). + this.setSideBarHidden(!state?.sidebar); + this.setSessionsHidden(!state?.sessions); + this.setAuxiliaryBarHidden(!state?.auxiliaryBar); + + this._editorMaximized = false; + + // After the flag clears, so `setExplorerHidden` no longer refuses to show. + this.setExplorerHidden(!state?.explorer); + + // Restore the editor part width captured before maximizing. + if (this.editorPartView && size) { + this.workbenchGrid.resizeView(this.editorPartView, size); + } + } + + this._onDidChangeEditorMaximized.fire(); + } + + toggleZenMode(): void { + // No-op: Zen mode not supported in this layout + } + + toggleMenuBar(): void { + // No-op: Menu bar toggle not supported in this layout + } + + isMainEditorLayoutCentered(): boolean { + return false; // Centered layout not supported + } + + centerMainEditorLayout(_active: boolean): void { + // No-op: Centered layout not supported in this layout + } + + hasMainWindowBorder(): boolean { + return false; + } + + getMainWindowBorderRadius(): string | undefined { + return undefined; + } + + //#endregion + + //#region Window Maximized State + + isWindowMaximized(targetWindow: Window): boolean { + return this.maximized.has(getWindowId(targetWindow)); + } + + updateWindowMaximizedState(targetWindow: Window, maximized: boolean): void { + const windowId = getWindowId(targetWindow); + if (maximized) { + this.maximized.add(windowId); + if (targetWindow === mainWindow) { + this.mainContainer.classList.add(LayoutClasses.MAXIMIZED); + } + } else { + this.maximized.delete(windowId); + if (targetWindow === mainWindow) { + this.mainContainer.classList.remove(LayoutClasses.MAXIMIZED); + } + } + + this._onDidChangeWindowMaximized.fire({ windowId, maximized }); + } + + //#endregion + + //#region Neighbor Parts + + getVisibleNeighborPart(part: Parts, direction: Direction): Parts | undefined { + if (!this.workbenchGrid) { + return undefined; + } + + const view = this.getPartView(part); + if (!view) { + return undefined; + } + + const neighbor = this.workbenchGrid.getNeighborViews(view, direction, false); + if (neighbor.length === 0) { + return undefined; + } + + const neighborView = neighbor[0]; + + if (neighborView === this.sideBarPartView) { + return Parts.SIDEBAR_PART; + } + if (neighborView === this.auxiliaryBarPartView) { + return Parts.AUXILIARYBAR_PART; + } + if (neighborView === this.editorPartView) { + return Parts.EDITOR_PART; + } + if (neighborView === this.panelPartView) { + return Parts.PANEL_PART; + } + if (neighborView === this.sessionsPartView) { + return Parts.SESSIONS_PART; + } + if (neighborView === this.explorerPartView) { + return Parts.REVIEW_EXPLORER_PART; + } + + return undefined; + } + + //#endregion + + //#region Restore + + isRestored(): boolean { + return this.restored; + } + + setRestored(): void { + this.restored = true; + this.restoredPromise.complete(); + } + + //#endregion + + //#region Notifications Registration + + registerNotifications(delegate: { onDidChangeNotificationsVisibility: Event }): void { + this._register(delegate.onDidChangeNotificationsVisibility(visible => this._onDidChangeNotificationsVisibility.fire(visible))); + } + + //#endregion +} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/darwinUpdateRecovery.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/darwinUpdateRecovery.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/darwinUpdateRecovery.test.ts rename to apps/review-desktop/code-oss/src/vs/review/common/darwinUpdateRecovery.test.ts diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewAboutDialog.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewAboutDialog.test.ts new file mode 100644 index 000000000..1cbdc3ca8 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewAboutDialog.test.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { appendReviewInstallId } from './reviewAboutDialog.js'; + +test('appends the install id to visible and copied About details', () => { + const about = appendReviewInstallId({ + title: 'Review', + details: 'Version: 1', + detailsToCopy: 'Version: 1', + }, 'install-123'); + + assert.equal(about.details, 'Version: 1\ninstall id: install-123'); + assert.equal(about.detailsToCopy, 'Version: 1\ninstall id: install-123'); +}); + +test('keeps About useful when the install id is unavailable', () => { + const about = appendReviewInstallId({ + title: 'Review', + details: 'Version: 1', + detailsToCopy: 'Version: 1', + }, undefined); + + assert.equal(about.details, 'Version: 1\ninstall id: Unknown'); + assert.equal(about.detailsToCopy, 'Version: 1\ninstall id: Unknown'); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewAboutDialog.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewAboutDialog.ts new file mode 100644 index 000000000..80669d55c --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewAboutDialog.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface ReviewAboutDialogDetails { + readonly title: string; + readonly details: string; + readonly detailsToCopy: string; +} + +export function appendReviewInstallId( + about: ReviewAboutDialogDetails, + installationId: string | undefined, +): ReviewAboutDialogDetails { + const line = `install id: ${installationId || "Unknown"}`; + return { + ...about, + details: `${about.details}\n${line}`, + detailsToCopy: `${about.detailsToCopy}\n${line}`, + }; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewBootstrapBreadcrumb.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewBootstrapBreadcrumb.test.ts new file mode 100644 index 000000000..5ccee8f55 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewBootstrapBreadcrumb.test.ts @@ -0,0 +1,86 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +// This test lives under common/ because that is one of the three directories +// the Review unit-test glob covers; the module under test is in node/. + +import assert from "node:assert/strict"; +import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import test from "node:test"; + +import { + drainReviewBootstrapBreadcrumbs, + reviewBootstrapBreadcrumbPath, + writeReviewBootstrapBreadcrumb, +} from "../node/reviewBootstrapBreadcrumb.js"; + +function withTempUserData(body: (userDataPath: string) => void): void { + const root = mkdtempSync(path.join(tmpdir(), "review-breadcrumb-")); + try { + body(path.join(root, "user-data")); + } finally { + rmSync(root, { recursive: true, force: true }); + } +} + +test("a crash note round-trips and the file is then gone", () => { + withTempUserData(userDataPath => { + const error = new TypeError("cannot load main"); + error.stack = "TypeError: cannot load main\n at f (/app/out/vs/code/electron-main/main.js:1:1)"; + writeReviewBootstrapBreadcrumb(userDataPath, error, 1234); + + const drained = drainReviewBootstrapBreadcrumbs(userDataPath); + assert.equal(drained.length, 1); + assert.equal(drained[0].name, "TypeError"); + assert.equal(drained[0].message, "cannot load main"); + assert.equal(drained[0].t, 1234); + assert.match(drained[0].stack, /electron-main\/main\.js:1:1/); + assert.equal(existsSync(reviewBootstrapBreadcrumbPath(userDataPath)), false); + assert.deepEqual(drainReviewBootstrapBreadcrumbs(userDataPath), []); + }); +}); + +test("several crashes accumulate as separate lines", () => { + withTempUserData(userDataPath => { + writeReviewBootstrapBreadcrumb(userDataPath, new Error("first")); + writeReviewBootstrapBreadcrumb(userDataPath, new Error("second")); + assert.deepEqual( + drainReviewBootstrapBreadcrumbs(userDataPath).map(entry => entry.message), + ["first", "second"], + ); + }); +}); + +test("a crash loop cannot fill the disk", () => { + withTempUserData(userDataPath => { + writeReviewBootstrapBreadcrumb(userDataPath, new Error("first")); + const file = reviewBootstrapBreadcrumbPath(userDataPath); + writeFileSync(file, `${"x".repeat(70 * 1024)}\n`, "utf8"); + writeReviewBootstrapBreadcrumb(userDataPath, new Error("dropped")); + assert.equal(readFileSync(file, "utf8").includes("dropped"), false); + }); +}); + +test("recording a crash never raises one", () => { + assert.doesNotThrow(() => { + writeReviewBootstrapBreadcrumb("", undefined); + writeReviewBootstrapBreadcrumb("\0invalid", new Error("boom")); + }); + assert.deepEqual(drainReviewBootstrapBreadcrumbs("\0invalid"), []); +}); + +test("one unreadable line does not lose the others", () => { + withTempUserData(userDataPath => { + writeReviewBootstrapBreadcrumb(userDataPath, new Error("kept")); + const file = reviewBootstrapBreadcrumbPath(userDataPath); + writeFileSync(file, `not json\n${readFileSync(file, "utf8")}`, "utf8"); + assert.deepEqual( + drainReviewBootstrapBreadcrumbs(userDataPath).map(entry => entry.message), + ["kept"], + ); + }); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewCanvasReuse.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewCanvasReuse.ts new file mode 100644 index 000000000..6499cad35 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewCanvasReuse.ts @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface ReviewCanvasReuseCandidate { + readonly input: object; + readonly readyInput: object | undefined; + readonly model: object; + readonly renderedModel: object | null; + readonly modelState: "active" | "completed" | "unavailable"; +} + +export interface ReviewCanvasScrollSnapshot { + readonly input: object; + readonly model: object; + readonly scrollTop: number; +} + +function captureReviewCanvasScrollSnapshot( + input: object, + model: { readonly state: "active" | "completed" | "unavailable" }, + document: Document, +): ReviewCanvasScrollSnapshot | undefined { + if (model.state !== "active") return undefined; + const region = document.querySelector(".review-view-region"); + if (!region) return undefined; + return { input, model, scrollTop: region.scrollTop }; +} + +export function preserveReviewCanvasScrollSnapshot( + pending: ReviewCanvasScrollSnapshot | undefined, + input: object, + model: { readonly state: "active" | "completed" | "unavailable" }, + document: Document, +): ReviewCanvasScrollSnapshot | undefined { + return pending?.input === input && pending.model === model + ? pending + : captureReviewCanvasScrollSnapshot(input, model, document); +} + +export function canRestoreReviewCanvasScrollSnapshot( + snapshot: ReviewCanvasScrollSnapshot | undefined, + candidate: { + readonly input: object; + readonly model: object; + readonly modelState: "active" | "completed" | "unavailable"; + }, +): snapshot is ReviewCanvasScrollSnapshot { + return ( + candidate.modelState === "active" && + snapshot?.input === candidate.input && + snapshot.model === candidate.model + ); +} + +/** Reuse only the still-ready view owned by this exact input and model. */ +export function canReuseReviewCanvas( + candidate: ReviewCanvasReuseCandidate, +): boolean { + return ( + candidate.modelState === "active" && + candidate.input === candidate.readyInput && + candidate.model === candidate.renderedModel + ); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewChangedFilesModel.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewChangedFilesModel.ts new file mode 100644 index 000000000..45f041925 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewChangedFilesModel.ts @@ -0,0 +1,94 @@ +import type { ReviewDiffFileWire } from "./reviewProtocol.js"; + +export interface ChangedFileElement { + readonly kind: "file"; + readonly file: ReviewDiffFileWire; + readonly name: string; +} + +export interface ChangedFolderElement { + readonly kind: "folder"; + readonly name: string; + readonly path: string; + readonly children: ChangedTreeElement[]; +} + +export type ChangedTreeElement = ChangedFileElement | ChangedFolderElement; + +interface MutableFolder { + readonly name: string; + readonly path: string; + readonly folders: Map; + readonly files: ChangedFileElement[]; +} + +/** Returns changed files in the same folder-first order that the tree shows. */ +export function orderReviewDiffFiles( + files: readonly ReviewDiffFileWire[], +): readonly ReviewDiffFileWire[] { + const ordered: ReviewDiffFileWire[] = []; + collectFiles(buildTree(files), ordered); + return ordered; +} + +export function buildTree( + files: readonly ReviewDiffFileWire[], +): ChangedTreeElement[] { + const root: MutableFolder = { + name: "", + path: "", + folders: new Map(), + files: [], + }; + + for (const file of files) { + const segments = file.path.split("/").filter(Boolean); + const name = segments.pop() ?? file.path; + let folder = root; + for (const segment of segments) { + const path = folder.path ? `${folder.path}/${segment}` : segment; + let child = folder.folders.get(segment); + if (!child) { + child = { + name: segment, + path, + folders: new Map(), + files: [], + }; + folder.folders.set(segment, child); + } + folder = child; + } + folder.files.push({ kind: "file", file, name }); + } + + return folderChildren(root); +} + +function folderChildren(folder: MutableFolder): ChangedTreeElement[] { + const folders = [...folder.folders.values()] + .map((child): ChangedFolderElement => ({ + kind: "folder", + name: child.name, + path: child.path, + children: folderChildren(child), + })) + .sort((left, right) => left.name.localeCompare(right.name)); + const files = [...folder.files].sort((left, right) => + left.name.localeCompare(right.name), + ); + return [...folders, ...files]; +} + +function collectFiles( + elements: readonly ChangedTreeElement[], + target: ReviewDiffFileWire[], +): void { + for (const element of elements) { + if (element.kind === "file") { + target.push(element.file); + } else { + collectFiles(element.children, target); + } + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewChrome.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewChrome.ts new file mode 100644 index 000000000..b7e983cef --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewChrome.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * The height of the one Review chrome row, in CSS pixels. + * + * Review draws the titlebar as an overlay on the editor tab strip, so one + * height controls three things that must agree: the titlebar part, the macOS + * window controls, and the editor tab strip. 40px is a 28px tab pill plus 6px + * of padding above it and 6px below it. + * + * KEEP IN SYNC WITH: + * - `.review-chrome-overlay` and the pill metrics in + * `review/browser/media/review.css`. + * - `EditorTabsControl.EDITOR_TAB_HEIGHT.review` in + * `workbench/browser/parts/editor/editorTabsControl.ts`. + */ +export const REVIEW_CHROME_HEIGHT = 40; diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewCliInstall.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewCliInstall.test.ts new file mode 100644 index 000000000..98d778f88 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewCliInstall.test.ts @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import type { ReviewCliInstallStatus } from './reviewProtocol.js'; +import { reviewCliInstallResyncRequest } from './reviewCliInstall.js'; + +const baseStatus: ReviewCliInstallStatus = { + agents: [], + fingerprint: 'current', + stamp: null, + stale: true, + shim: { + path: '/home/test/.local/bin/review', + installed: false, + profileConfigured: false, + onPath: false, + }, + fff: { + serverName: 'fff', + corpusRoot: '/home/test/.dev/trace-search', + binary: { path: '/home/test/.local/bin/fff-mcp', installed: false }, + registrations: [], + }, + trace: { + enabled: false, + configured: false, + autoActivateRepositories: false, + envPath: '/home/test/.dev/trace.env', + settingsPath: '/home/test/.dev/trace-settings.json', + }, + cli: null, +}; + +test('resyncs a CLI-only installation', () => { + assert.deepEqual( + reviewCliInstallResyncRequest({ + ...baseStatus, + agents: [{ target: 'codex', present: true, installed: true }], + stamp: { + consent: 'granted', + targets: [], + shimPath: '/home/test/.local/bin/review', + updatedAt: '2026-09-02T00:00:00.000Z', + }, + }), + { targets: [], shim: true, autoUpdate: true }, + ); +}); + +test('falls back to installed skills for a legacy stamp without targets', () => { + assert.deepEqual( + reviewCliInstallResyncRequest({ + ...baseStatus, + agents: [{ target: 'codex', present: true, installed: true }], + stamp: { + consent: 'granted', + updatedAt: '2026-09-02T00:00:00.000Z', + }, + }), + { targets: ['codex'], shim: false, autoUpdate: true }, + ); +}); + +test('preserves an explicit CLI opt-out while resyncing skills', () => { + assert.deepEqual( + reviewCliInstallResyncRequest({ + ...baseStatus, + stamp: { + consent: 'granted', + targets: ['codex'], + updatedAt: '2026-09-02T00:00:00.000Z', + }, + }), + { targets: ['codex'], shim: false, autoUpdate: true }, + ); +}); + +test('skips resync when neither skills nor the CLI are managed', () => { + assert.equal(reviewCliInstallResyncRequest(baseStatus), undefined); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewCliInstall.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewCliInstall.ts new file mode 100644 index 000000000..7f74af15f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewCliInstall.ts @@ -0,0 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +export type { ReviewCliInstallResyncRequest } from './reviewProtocol.js'; +export { reviewCliInstallResyncRequest } from './reviewProtocol.js'; diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewCommandPalette.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewCommandPalette.test.ts new file mode 100644 index 000000000..fdf2635fa --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewCommandPalette.test.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { reviewCommandPaletteLabel } from './reviewCommandPalette.js'; + +test('uses the human-readable command title', () => { + assert.equal( + reviewCommandPaletteLabel('review.installCliInPath', { + title: { value: 'Review: Install CLI in PATH', original: 'Review: Install CLI in PATH' }, + }), + 'Review: Install CLI in PATH', + ); +}); + +test('includes a command category and removes icons', () => { + assert.equal( + reviewCommandPaletteLabel('extension.command', { + title: '$(zap) Run', + category: { value: 'Extension', original: 'Extension' }, + }), + 'Extension: Run', + ); +}); + +test('falls back to the command id when metadata is unavailable', () => { + assert.equal(reviewCommandPaletteLabel('internal.command', undefined), 'internal.command'); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewCommandPalette.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewCommandPalette.ts new file mode 100644 index 000000000..bc1f90096 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewCommandPalette.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { stripIcons } from '../../base/common/iconLabels.js'; +import { localize } from '../../nls.js'; +import type { ICommandAction } from '../../platform/action/common/action.js'; + +type CommandLabel = Pick; + +export function reviewCommandPaletteLabel(commandId: string, command: CommandLabel | undefined): string { + if (!command) { + return commandId; + } + + let label = typeof command.title === 'string' ? command.title : command.title.value; + const category = typeof command.category === 'string' ? command.category : command.category?.value; + if (category) { + label = localize('review.commandWithCategory', "{0}: {1}", category, label); + } + + return stripIcons(label) || commandId; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewConfiguration.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewConfiguration.ts new file mode 100644 index 000000000..afa01a274 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewConfiguration.ts @@ -0,0 +1,60 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Registers Review's configuration with the workbench. + * + * Importing this module pulls in the configuration registry, which constructs + * itself — and localizes — at module scope. That makes it unsafe anywhere the + * Electron main process can reach before `bootstrapESM()`; see the header of + * `reviewConfigurationDefaults.ts`. Renderer code reaches it through the bare + * side-effect import in `review.common.main.ts`. + * + * The setting keys and default values live in `reviewConfigurationDefaults.ts` + * and are deliberately *not* re-exported from here: a re-export would let a + * main-process consumer import data through this module and put the registry + * back on its import path. + */ +import { localize } from '../../nls.js'; +import { Registry } from '../../platform/registry/common/platform.js'; +import { ConfigurationScope, Extensions, type IConfigurationRegistry } from '../../platform/configuration/common/configurationRegistry.js'; +import { REVIEW_KEYMAPS, REVIEW_KEYMAP_SETTING, REVIEW_SOFTWARE_MAP_SETTING, REVIEW_STRUCTURAL_DIFF_SETTING, REVIEW_TELEMETRY_SETTING, curatedExtensionConfigurationDefaults, reviewConfigurationDefaults } from './reviewConfigurationDefaults.js'; + +const configurationRegistry = Registry.as(Extensions.Configuration); + +configurationRegistry.registerConfiguration({ + id: 'review', + title: localize('reviewConfigurationTitle', "Review"), + type: 'object', + scope: ConfigurationScope.APPLICATION, + properties: { + [REVIEW_KEYMAP_SETTING]: { + type: 'string', + enum: [...REVIEW_KEYMAPS], + default: 'none', + description: localize('review.keymap', "Select the curated keymap extension Review enables."), + }, + [REVIEW_TELEMETRY_SETTING]: { + type: 'boolean', + default: true, + description: localize('review.telemetry.enabled', "Send anonymous Review usage data."), + }, + [REVIEW_STRUCTURAL_DIFF_SETTING]: { + type: 'boolean', + default: true, + description: localize('review.experimental.structuralDiff.enabled', "Replace the standard diff view with structural diffs from diffr."), + }, + [REVIEW_SOFTWARE_MAP_SETTING]: { + type: 'boolean', + default: false, + description: localize('review.experimental.softwareMap.enabled', "Show the experimental Software Map view in reviews."), + }, + }, +}); + +configurationRegistry.registerDefaultConfigurations([ + { overrides: reviewConfigurationDefaults }, + { overrides: curatedExtensionConfigurationDefaults } +]); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewConfigurationDefaults.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewConfigurationDefaults.test.ts new file mode 100644 index 000000000..eaef6b036 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewConfigurationDefaults.test.ts @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { REVIEW_KEYMAP_SETTING, reviewConfigurationDefaults } from './reviewConfigurationDefaults.js'; + +test('turns off diff indicators for the indicator-free visual language', () => { + assert.equal(reviewConfigurationDefaults['diffEditor.renderIndicators'], false); +}); + +test('titles the window Review and enables the native navigation control', () => { + assert.equal(reviewConfigurationDefaults['window.title'], 'Review'); + assert.equal(reviewConfigurationDefaults['workbench.navigationControl.enabled'], true); +}); + +test('names the curated keymap setting review.keymap', () => { + assert.equal(REVIEW_KEYMAP_SETTING, 'review.keymap'); +}); + +test('keeps the VSCodium-derived opt-out defaults', () => { + assert.equal(reviewConfigurationDefaults['telemetry.telemetryLevel'], 'off'); + assert.equal(reviewConfigurationDefaults['telemetry.enableTelemetry'], false); + assert.equal(reviewConfigurationDefaults['telemetry.enableCrashReporter'], false); + assert.equal(reviewConfigurationDefaults['telemetry.editStats.enabled'], false); + assert.equal(reviewConfigurationDefaults['workbench.enableExperiments'], false); + assert.equal( + reviewConfigurationDefaults['workbench.commandPalette.experimental.enableNaturalLanguageSearch'], + false, + ); + assert.equal(reviewConfigurationDefaults['workbench.settings.enableNaturalLanguageSearch'], false); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewConfigurationDefaults.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewConfigurationDefaults.ts new file mode 100644 index 000000000..039f8d666 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewConfigurationDefaults.ts @@ -0,0 +1,139 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Review's configuration data: setting keys and default values, with no imports + * and no side effects. + * + * This module is deliberately import-free. `vs/review/node/reviewUserConfigImport.ts` + * reads these keys from the Electron main process, which `src/main.ts` reaches + * before `startup()` calls `bootstrapESM()` — the step that installs + * `globalThis._VSCODE_NLS_MESSAGES`. Anything imported here is evaluated inside + * that pre-bootstrap window, where a packaged build's mangled `localize(2488, null)` + * throws `!!! NLS MISSING: 2488 !!!` into a modal, before any window or log exists. + * + * Registration lives in `reviewConfiguration.ts`, which imports this file and owns + * the configuration-registry calls. Never add an import here, and never re-export + * these values from `reviewConfiguration.ts` — a re-export would put the + * configuration registry back on the main process's import path. + * + * Enforced by `scripts/main-bootstrap-imports.test.mjs`. + */ + +export const REVIEW_KEYMAP_SETTING = 'review.keymap'; +export const REVIEW_TELEMETRY_SETTING = 'review.telemetry.enabled'; +export const REVIEW_STRUCTURAL_DIFF_SETTING = 'review.experimental.structuralDiff.enabled'; +export const REVIEW_SOFTWARE_MAP_SETTING = 'review.experimental.softwareMap.enabled'; +export const REVIEW_KEYMAPS = ['none', 'vim', 'emacs'] as const; +export type ReviewKeymap = typeof REVIEW_KEYMAPS[number]; + +export const reviewConfigurationDefaults = { + [REVIEW_SOFTWARE_MAP_SETTING]: false, + [REVIEW_STRUCTURAL_DIFF_SETTING]: true, + [REVIEW_TELEMETRY_SETTING]: true, + 'telemetry.telemetryLevel': 'off', + 'telemetry.enableTelemetry': false, + 'telemetry.enableCrashReporter': false, + 'telemetry.editStats.enabled': false, + 'security.workspace.trust.enabled': false, + 'workbench.enableExperiments': false, + 'workbench.commandPalette.experimental.enableNaturalLanguageSearch': false, + 'workbench.settings.enableNaturalLanguageSearch': false, + 'window.autoDetectColorScheme': true, + 'workbench.colorTheme': 'Review Dark', + 'workbench.preferredDarkColorTheme': 'Review Dark', + 'workbench.preferredLightColorTheme': 'Review Light', + 'workbench.startupEditor': 'none', + 'workbench.activityBar.location': 'hidden', + 'workbench.statusBar.visible': false, + 'window.title': 'Review', + 'window.commandCenter': false, + 'workbench.navigationControl.enabled': true, + 'window.menuBarVisibility': 'hidden', + 'workbench.editor.showTabs': 'multiple', + 'workbench.editor.editorActionsLocation': 'hidden', + // Reduce tab widths when the row fills. The native tab control truncates the + // labels first. It keeps horizontal scrolling after tabs reach their minimum. + 'workbench.editor.tabSizing': 'shrink', + // Keep wheel, trackpad, keyboard, and active-tab scrolling. Hide only the + // scrollbar, which would otherwise sit across the bottom of the pill row. + 'workbench.editor.titleScrollbarVisibility': 'hidden', + // Home is the only sticky editor in Review. "compact" makes a sticky tab show + // its icon alone, so the Home pill lost its name. "normal" shows the home + // icon and the word "Home". + 'workbench.editor.pinnedTabSizing': 'normal', + // A sticky tab shows an unpin button in place of its close button. Home is + // always sticky and the reader cannot unpin it, so the button is dead chrome. + 'workbench.editor.tabActionUnpinVisibility': false, + 'workbench.layoutControl.enabled': false, + // Diffs and code peeks are Monaco editors, and Monaco takes its font from + // this setting rather than from CSS. Geist Mono is bundled with the canvas + // stylesheet (its @font-face rules are hoisted out of the canvas scope), so + // the editors share the chrome and code face of the whiteboard design. The + // tail is Monaco's own macOS default stack. + 'editor.fontFamily': '"Geist Mono", Menlo, Monaco, "Courier New", monospace', + 'editor.minimap.enabled': false, + 'diffEditor.renderIndicators': false, + 'breadcrumbs.enabled': false, + 'git.enabled': false, + // Retain read-only protection when opening a legacy Review-owned checkout. + // New review sources use immutable virtual documents; LSP targets are local files. + 'files.readonlyInclude': { '/**/.git/dev-fast/worktrees/**': true }, + // Keep read-only badges from crowding Review's compact file tabs. + 'workbench.editor.decorations.badges': false, + 'chat.disableAIFeatures': true, + 'extensions.ignoreRecommendations': true, + 'workbench.tips.enabled': false +} as const; + +/** + * Defaults that keep the curated built-in extensions quiet. + * + * Review ships no marketplace, so an extension that prompts to install or update + * something offers the reader a dead end. Every key here closes one such prompt. + * Keep this aligned with the curated groups in + * `scripts/curated-extensions.manifest.mjs`, whose contract test is + * `scripts/curated-extensions.test.mjs`. + */ +export const curatedExtensionConfigurationDefaults = { + // ms-python.python resolves the "Default" language server to Pylance, which is + // proprietary and can never ship here, then prompts to install it. ty is + // Review's Python language server and ignores this setting. + 'python.languageServer': 'None', + // Fetches A/B experiment payloads and prompts into them. + 'python.experiments.enabled': false, + // "Do you want to create a virtual environment?" on requirements.txt. + 'python.createEnvironment.trigger': 'off', + // "Configure a test framework?" on test files. + 'python.testing.promptToConfigure': false, + + // golang.go asks users to fill in a survey on a timer. + 'go.survey.prompt': false, + // Prompts to `go install` newer tools against a toolchain Review does not ship. + 'go.toolsManagement.checkForUpdates': 'off', + + // "This file is not linked to a Cargo project" — routine when the review is + // scoped to a subdirectory of a workspace. + 'rust-analyzer.showUnlinkedFileNotification': false, + 'rust-analyzer.notifications.cargoTomlNotFound': false, + 'rust-analyzer.showRequestFailedErrorNotification': false, + + // The Swift extension can offer to install Swiftly. Review uses the Swift + // toolchain that the user installed and made available on the shell PATH. + 'swift.disableSwiftlyInstallPrompt': true, + + // The .NET support extension must not send its own telemetry or expose AI + // tools. C# uses the system .NET SDK that Review resolves from the shell PATH. + 'dotnetAcquisitionExtension.enableTelemetry': false, + 'dotnetAcquisitionExtension.enableLanguageModelTools': false + + // charliermarsh.ruff already defaults `ruff.showNotifications` to "off". + // astral-sh.ty, vscodevim.vim and tuttieee.emacs-mcx contribute no prompts. +} as const; + +export const reviewAgentsWindowDefaultOverrides = { + 'window.title': reviewConfigurationDefaults['window.title'], + 'workbench.navigationControl.enabled': reviewConfigurationDefaults['workbench.navigationControl.enabled'], +} as const; diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewDesktopBootstrap.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewDesktopBootstrap.test.ts new file mode 100644 index 000000000..f7e60ef4f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewDesktopBootstrap.test.ts @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { + REVIEW_DESKTOP_CONNECTION_VERSION, + ReviewReadyEventReader, +} from './reviewDesktopBootstrap.js'; + +const credentials = { + token: 'token', + instanceId: 'instance', +}; + +test('carries the install id from the ready message', () => { + const reader = new ReviewReadyEventReader(credentials); + const connection = reader.push(`${JSON.stringify({ + event: 'ready', + version: REVIEW_DESKTOP_CONNECTION_VERSION, + url: 'http://127.0.0.1:4321', + ...credentials, + installationId: 'install-123', + })}\n`); + + assert.equal(connection?.installationId, 'install-123'); +}); + +test('accepts an older ready message without an install id', () => { + const reader = new ReviewReadyEventReader(credentials); + const connection = reader.push(`${JSON.stringify({ + event: 'ready', + version: REVIEW_DESKTOP_CONNECTION_VERSION, + url: 'http://127.0.0.1:4321', + ...credentials, + })}\n`); + + assert.equal(connection?.installationId, undefined); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewDesktopBootstrap.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewDesktopBootstrap.ts new file mode 100644 index 000000000..2288e1085 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewDesktopBootstrap.ts @@ -0,0 +1,164 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * The Review server runs in a utility process and announces the endpoint it + * bound as a single newline-delimited JSON object on stdout. The main process + * is the only party that knows the credentials it generated, so it validates + * that announcement here before handing a connection to any renderer. + */ +// Hand-maintained twin of REVIEW_DESKTOP_DISCOVERY_VERSION in +// @dev.fast/review-protocol. Version 3: the desktop serves prebuilt +// revisions instead of building them. +export const REVIEW_DESKTOP_CONNECTION_VERSION = 3; + +/** Main-process IPC channel the renderer asks for that endpoint on. */ +export const REVIEW_DESKTOP_CHANNEL = "review"; + +export interface ReviewDesktopConnection { + readonly version: number; + readonly url: string; + readonly token: string; + readonly instanceId: string; + readonly installationId?: string; + readonly cliPath?: string; + readonly cliVersion?: string; +} + +export interface ReviewDesktopCredentials { + readonly token: string; + readonly instanceId: string; +} + +/** + * The Review runtime is staged inside the application bundle at packaging time + * so an installed app never reaches back into a development checkout. + */ +const REVIEW_RUNTIME_SERVER_ENTRY = + "review-runtime/dist/server/desktop-host.js"; + +/** + * Resolves the server entry point. A development checkout may point at its own + * build output, but a packaged app must only ever use the runtime staged inside + * the bundle: honouring an environment override there would let an installed + * app be pointed at arbitrary code. + */ +export function resolveReviewServerEntry(input: { + readonly isBuilt: boolean; + readonly appRoot: string; + readonly serverEntryOverride?: string | undefined; + readonly join?: (...segments: string[]) => string; +}): string { + const join = input.join ?? ((...segments) => segments.join("/")); + if (!input.isBuilt && input.serverEntryOverride) { + return input.serverEntryOverride; + } + return join(input.appRoot, REVIEW_RUNTIME_SERVER_ENTRY); +} + +export class ReviewReadyEventReader { + private buffer = ""; + private done = false; + + constructor(private readonly credentials: ReviewDesktopCredentials) {} + + /** + * Feeds a stdout chunk and returns the connection once the ready event has + * been seen. Lines that are not the ready event are server logs and are + * ignored; a ready event that fails validation throws immediately so startup + * fails with a real reason instead of stalling until the readiness timeout. + */ + push(chunk: string): ReviewDesktopConnection | undefined { + if (this.done) return undefined; + this.buffer += chunk; + let newline = this.buffer.indexOf("\n"); + while (newline !== -1) { + const line = this.buffer.slice(0, newline).trim(); + this.buffer = this.buffer.slice(newline + 1); + const connection = this.readLine(line); + if (connection) { + this.done = true; + this.buffer = ""; + return connection; + } + newline = this.buffer.indexOf("\n"); + } + return undefined; + } + + private readLine(line: string): ReviewDesktopConnection | undefined { + if (!line.startsWith("{")) return undefined; + let parsed: unknown; + try { + parsed = JSON.parse(line); + } catch { + return undefined; + } + if (!isRecord(parsed) || parsed["event"] !== "ready") return undefined; + return this.validate(parsed); + } + + private validate(event: Record): ReviewDesktopConnection { + const version = event["version"]; + if (version !== REVIEW_DESKTOP_CONNECTION_VERSION) { + throw new Error( + `The Review server announced an unsupported discovery version: ${String(version)}.`, + ); + } + const url = event["url"]; + const token = event["token"]; + const instanceId = event["instanceId"]; + if ( + typeof url !== "string" || + typeof token !== "string" || + typeof instanceId !== "string" + ) { + throw new Error("The Review server ready event is malformed."); + } + if ( + token !== this.credentials.token || + instanceId !== this.credentials.instanceId + ) { + throw new Error( + "The Review server ready event carried unexpected credentials.", + ); + } + const cliPath = event["cliPath"]; + const cliVersion = event["cliVersion"]; + const installationId = event["installationId"]; + return { + version: REVIEW_DESKTOP_CONNECTION_VERSION, + url: loopbackOrigin(url), + token, + instanceId, + ...(typeof installationId === "string" && installationId + ? { installationId } + : {}), + ...(typeof cliPath === "string" && cliPath ? { cliPath } : {}), + ...(typeof cliVersion === "string" && cliVersion ? { cliVersion } : {}), + }; + } +} + +function loopbackOrigin(value: string): string { + let url: URL; + try { + url = new URL(value); + } catch { + throw new Error( + `The Review server must listen on http loopback, got ${value}.`, + ); + } + if (url.protocol !== "http:" || url.hostname !== "127.0.0.1" || !url.port) { + throw new Error( + `The Review server must listen on http loopback, got ${value}.`, + ); + } + return url.origin; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewErrorReport.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewErrorReport.test.ts new file mode 100644 index 000000000..5aba192ab --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewErrorReport.test.ts @@ -0,0 +1,90 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { CancellationError, ErrorNoTelemetry } from "../../base/common/errors.js"; +import { + packReviewError, + ReviewErrorReportLimiter, + type ReviewErrorReport, +} from "./reviewErrorReport.js"; + +function errorWithStack(message: string): Error { + const error = new TypeError(message); + error.stack = `TypeError: ${message}\n at f (/app/out/vs/review/browser/workbench.js:1:1)`; + return error; +} + +test("packReviewError keeps the name, message, and stack", () => { + const packed = packReviewError(errorWithStack("boom")); + assert.equal(packed?.name, "TypeError"); + assert.equal(packed?.message, "boom"); + assert.match(packed?.stack ?? "", /workbench\.js:1:1/); +}); + +test("packReviewError skips errors that say nothing about a defect", () => { + assert.equal(packReviewError(undefined), undefined); + assert.equal(packReviewError("boom"), undefined); + assert.equal(packReviewError({ name: "Error", message: "no stack" }), undefined); + const systemError = errorWithStack("EACCES") as Error & { code?: string }; + systemError.code = "EACCES"; + assert.equal(packReviewError(systemError), undefined); + const noTelemetry = new ErrorNoTelemetry("private"); + noTelemetry.stack = "CodeExpectedError\n at f (/app/out/vs/base/common/errors.js:1:1)"; + assert.equal(packReviewError(noTelemetry), undefined); + const cancelled = new CancellationError(); + cancelled.stack = "Canceled\n at f (/app/out/vs/base/common/errors.js:1:1)"; + assert.equal(packReviewError(cancelled), undefined); +}); + +test("packReviewError unwraps a loader error and an array stack", () => { + const packed = packReviewError({ + detail: { name: "SyntaxError", message: "bad", stack: ["SyntaxError: bad", " at f (/app/out/vs/code/x.js:2:2)"] }, + }); + assert.equal(packed?.name, "SyntaxError"); + assert.match(packed?.stack ?? "", /vs\/code\/x\.js:2:2/); +}); + +test("the limiter removes an immediate repeat but allows it later", () => { + let now = 1000; + const limiter = new ReviewErrorReportLimiter(30, () => now); + const sent: ReviewErrorReport[] = []; + const send = (report: ReviewErrorReport): void => { sent.push(report); }; + + limiter.report(errorWithStack("boom"), send); + limiter.report(errorWithStack("boom"), send); + assert.equal(sent.length, 1); + + now += 1001; + limiter.report(errorWithStack("boom"), send); + assert.equal(sent.length, 2); +}); + +test("the limiter caps a session and never lets a report raise an error", () => { + let now = 0; + const limiter = new ReviewErrorReportLimiter(3, () => (now += 5000)); + let sent = 0; + for (let index = 0; index < 10; index++) { + limiter.report(errorWithStack(`boom ${index}`), () => { sent++; }); + } + assert.equal(sent, 3); + + const guarded = new ReviewErrorReportLimiter(30, () => 0); + assert.doesNotThrow(() => { + guarded.report(errorWithStack("boom"), () => { throw new Error("reporting failed"); }); + }); +}); + +test("the limiter refuses to run inside itself", () => { + const limiter = new ReviewErrorReportLimiter(30, () => 0); + let depth = 0; + limiter.report(errorWithStack("outer"), () => { + depth++; + limiter.report(errorWithStack("inner"), () => { depth++; }); + }); + assert.equal(depth, 1); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewErrorReport.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewErrorReport.ts new file mode 100644 index 000000000..152a62447 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewErrorReport.ts @@ -0,0 +1,116 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationError, ErrorNoTelemetry } from "../../base/common/errors.js"; + +/** + * Shared error reporting rules for the Review workbench and the Review part of + * the Electron main process. + * + * The raw name, message, and stack packed here travel only to the loopback + * Review server on the same machine. That server replaces the message with a + * digest and keeps only the stack frames that resolve inside the shipped + * bundle; see packages/review/src/error-telemetry.ts. Nothing in + * this file is ever sent to a vendor as it stands. + * + * The filters mirror upstream `BaseErrorTelemetry._onErrorEvent`. They are + * reimplemented rather than imported because that module pulls the whole file + * service in behind it, and this one runs in the main process too. + */ + +export interface ReviewErrorReport { + readonly name: string; + readonly message: string; + readonly stack: string; +} + +/** + * Unwrap a loader error, then decide whether it is worth reporting. Errors with + * a system `code`, cancellations, errors marked as never-report, and errors + * without a stack are all skipped: none of them says anything about a defect in + * Review. + */ +export function packReviewError(error: unknown): ReviewErrorReport | undefined { + if (!error || typeof error !== 'object') { + return undefined; + } + let candidate = error as { code?: unknown; detail?: { stack?: unknown }; name?: unknown; message?: unknown; stack?: unknown }; + if (candidate.code) { + return undefined; + } + // Unwrap nested errors from the module loader, as upstream does. + if (candidate.detail && (candidate.detail as { stack?: unknown }).stack) { + candidate = candidate.detail as typeof candidate; + } + if (ErrorNoTelemetry.isErrorNoTelemetry(candidate as Error) || candidate instanceof CancellationError) { + return undefined; + } + // Array stacks come from workerServer.ts; upstream works around this too. + const stack = Array.isArray(candidate.stack) ? candidate.stack.join('\n') : candidate.stack; + if (typeof stack !== 'string' || stack.length === 0) { + return undefined; // an error without a stack is not useful telemetry + } + return { + name: typeof candidate.name === 'string' ? candidate.name : 'Error', + message: typeof candidate.message === 'string' ? candidate.message : '', + stack, + }; +} + +/** + * Keeps error reporting from becoming its own incident: it removes bursts of + * one repeating error, bounds the total per session, and refuses to run inside + * itself when reporting an error throws another one. + */ +export class ReviewErrorReportLimiter { + private static readonly REPEAT_WINDOW_MS = 1000; + + private previousKey: string | undefined; + private previousTime = 0; + private reported = 0; + private reporting = false; + + constructor( + private readonly maxPerSession = 30, + private readonly now: () => number = () => Date.now(), + ) { } + + /** + * Pack the error, decide whether it is worth reporting, and hand it to + * `send`. Re-entry is blocked, so an error raised inside `send` cannot start + * a second report, and nothing here ever throws: the callers sit on the + * error path itself, where a throw would escape into unrelated code. + */ + report(error: unknown, send: (report: ReviewErrorReport) => void): void { + if (this.reporting) { + return; + } + this.reporting = true; + try { + if (this.reported >= this.maxPerSession) { + return; + } + const packed = packReviewError(error); + if (!packed || this.isRepeat(packed)) { + return; + } + this.reported++; + send(packed); + } catch { + // Reporting an error must never raise one. + } finally { + this.reporting = false; + } + } + + private isRepeat(report: ReviewErrorReport): boolean { + const key = `${report.name}\n${report.stack.split('\n', 2).join('\n')}`; + const time = this.now(); + const repeat = key === this.previousKey && time - this.previousTime <= ReviewErrorReportLimiter.REPEAT_WINDOW_MS; + this.previousKey = key; + this.previousTime = time; + return repeat; + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewEventStream.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewEventStream.ts new file mode 100644 index 000000000..31d541231 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewEventStream.ts @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createParser } from "eventsource-parser"; + +import { type JsonValue, parseJsonText } from "./reviewProtocol.js"; + +const DEFAULT_MAX_EVENT_CHARACTERS = 1024 * 1024; +const EVENT_BOUNDARY = /(?:\r\n|\r|\n)(?:\r\n|\r|\n)/g; + +export interface ConsumeReviewEventStreamOptions { + readonly maxEventCharacters?: number; +} + +export async function consumeReviewEventStream( + stream: ReadableStream, + onValue: (value: JsonValue) => void | Promise, + signal: AbortSignal, + options: ConsumeReviewEventStreamOptions = {}, +): Promise { + const maxEventCharacters = + options.maxEventCharacters ?? DEFAULT_MAX_EVENT_CHARACTERS; + if (!Number.isSafeInteger(maxEventCharacters) || maxEventCharacters <= 0) { + throw new Error("maxEventCharacters must be a positive safe integer."); + } + + const reader = stream.getReader(); + const decoder = new TextDecoder(); + const sizeGuard = new IncompleteEventSizeGuard(maxEventCharacters); + const pendingPayloads: string[] = []; + const parser = createParser({ + onEvent: (event) => pendingPayloads.push(event.data), + onError: (error) => console.error(error), + }); + + const feed = (chunk: string): void => { + sizeGuard.push(chunk); + parser.feed(chunk); + }; + const drain = async (): Promise => { + while (pendingPayloads.length > 0) { + const payload = pendingPayloads.shift(); + if (payload === undefined) continue; + try { + await onValue(parseJsonText(payload)); + } catch (error) { + console.error(error); + } + } + }; + const cancelReader = (): void => { + void reader.cancel().catch(() => undefined); + }; + + signal.addEventListener("abort", cancelReader, { once: true }); + try { + while (!signal.aborted) { + const { value, done } = await reader.read(); + if (done) { + const trailing = decoder.decode(); + if (trailing) feed(trailing); + feed("\n\n"); + parser.reset(); + await drain(); + return; + } + + const decoded = decoder.decode(value, { stream: true }); + if (decoded) feed(decoded); + await drain(); + } + } finally { + signal.removeEventListener("abort", cancelReader); + await reader.cancel().catch(() => undefined); + } +} + +class IncompleteEventSizeGuard { + private unfinishedEvent = ""; + + constructor(private readonly maximum: number) {} + + push(chunk: string): void { + this.unfinishedEvent += chunk; + EVENT_BOUNDARY.lastIndex = 0; + + let eventStart = 0; + for ( + let match = EVENT_BOUNDARY.exec(this.unfinishedEvent); + match; + match = EVENT_BOUNDARY.exec(this.unfinishedEvent) + ) { + this.assertWithinLimit(match.index - eventStart); + eventStart = EVENT_BOUNDARY.lastIndex; + } + + this.unfinishedEvent = this.unfinishedEvent.slice(eventStart); + this.assertWithinLimit(this.unfinishedEvent.length); + } + + private assertWithinLimit(length: number): void { + if (length <= this.maximum) return; + throw new Error( + `Review event exceeded ${this.maximum} characters before its terminator.`, + ); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewFirstRunReload.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewFirstRunReload.ts new file mode 100644 index 000000000..763d16394 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewFirstRunReload.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Registry } from '../../platform/registry/common/platform.js'; +import { Extensions as WorkbenchExtensions, type IWorkbenchContributionsRegistry } from '../../workbench/common/contributions.js'; + +/** + * Seeding the keymap defaults reloads the window once on a fresh profile + * (reviewCuratedExtensions.contribution.ts). A startup prompt must skip itself + * when that reload is coming: the reload takes both the question and the + * answer with it, and a storage write after the shutdown close is dropped. + */ + +let pending: boolean | undefined; + +export function setFirstRunReloadPending(reloadPending: boolean): void { + pending = reloadPending; +} + +/** Resolves once the seeder has decided; a seeder that never ran means no reload. */ +export async function isFirstRunReloadPending(): Promise { + if (pending === undefined) { + await Registry.as(WorkbenchExtensions.Workbench).whenRestored; + } + return pending ?? false; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewLens.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewLens.test.ts new file mode 100644 index 000000000..4470324ed --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewLens.test.ts @@ -0,0 +1,36 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { lensContextGaps } from './reviewLens.js'; +import type { IDocumentDiff } from '../../editor/common/diff/documentDiffProvider.js'; + +const plain: IDocumentDiff = { changes: [], moves: [], identical: false, quitEarly: false }; +test('a lens keeps disjoint attachments and hides the intervening code', () => { + const gaps = lensContextGaps(plain, 100, 100, [ + { side: 'head', file: 'a.ts', fromLine: 20, toLine: 22 }, + { side: 'base', file: 'a.ts', fromLine: 70, toLine: 72 }, + ]); + assert.deepEqual(gaps.map(gap => [gap.originalStart, gap.originalCount]), [[1, 16], [26, 41], [76, 25]]); +}); +test('one-sided inserted ranges use correspondence without hiding their opposite context', () => { + const diff = { ...plain, sourceLineAlignment: Array.from({ length: 50 }, (_, i) => [null, i] as const) }; + const gaps = lensContextGaps(diff, 0, 50, [{ side: 'head', file: 'new.ts', fromLine: 20, toLine: 25 }]); + assert.deepEqual(gaps.map(gap => [gap.originalCount, gap.modifiedStart, gap.modifiedCount, gap.change]), [[0, 1, 16, 'inserted'], [0, 29, 22, 'inserted']]); +}); +test('structural folds within the lens survive, overlapping folds do not', () => { + const inside = { originalStart: 20, modifiedStart: 20, originalCount: 3, modifiedCount: 3, label: 'body' }; + const outside = { originalStart: 1, modifiedStart: 1, originalCount: 20, modifiedCount: 20 }; + const gaps = lensContextGaps({ ...plain, contextGaps: [inside, outside] }, 100, 100, [{ side: 'base', file: 'a', fromLine: 18, toLine: 28 }]); + assert.ok(gaps.includes(inside)); + assert.ok(!gaps.includes(outside)); +}); + +test('viewed folds never hide an unread counterpart, and do not overlap structural folds', async () => { + const { viewedContextGaps } = await import('./reviewLens.js'); + const range = (side: 'base' | 'head', fromLine: number, toLine: number) => ({ side, file: 'a.ts', fromLine, toLine }); + const changed = [range('base', 3, 5), range('head', 3, 5)]; + assert.deepEqual(viewedContextGaps(plain, 10, 10, [range('head', 3, 5)], changed), []); + const gaps = viewedContextGaps({ ...plain, contextGaps: [{ originalStart: 2, modifiedStart: 2, originalCount: 5, modifiedCount: 5, label: 'body' }] }, 10, 10, changed, changed); + assert.equal(gaps.length, 1); + assert.equal(gaps[0].label, 'Viewed'); + assert.equal(gaps[0].modifiedCount, 3); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewLens.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewLens.ts new file mode 100644 index 000000000..5c6ce7637 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewLens.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ +import type { IDocumentDiff, IDocumentContextGap } from '../../editor/common/diff/documentDiffProvider.js'; +import type { ReviewDiffLens } from './reviewProtocol.js'; + +/** Project pinned ranges onto the current diff's correspondence, never onto another revision. */ +export function lensContextGaps(diff: IDocumentDiff, originalCount: number, modifiedCount: number, ranges: ReviewDiffLens['ranges']): IDocumentContextGap[] { + const rows = alignmentRows(diff, originalCount, modifiedCount); + const visible = rows.map(row => ranges.some(range => { + const line = row[range.side === 'base' ? 0 : 1]; + return line !== null && line + 1 >= range.fromLine && line + 1 <= range.toLine; + })); + // Context follows alignment rows, keeping both sides synchronized around insertions. + const context = visible.map((_, index) => visible.slice(Math.max(0, index - 3), index + 4).some(Boolean)); + const gaps: IDocumentContextGap[] = []; + let left = 1, right = 1; + for (let index = 0; index < rows.length;) { + if (context[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; continue; } + const originalStart = left, modifiedStart = right; + while (index < rows.length && !context[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; } + gaps.push({ + originalStart, modifiedStart, originalCount: left - originalStart, modifiedCount: right - modifiedStart, label: 'Outside lens', breadcrumbs: false, + owner: left === originalStart ? 'head' : right === modifiedStart ? 'base' : 'both', change: gapChange(diff, originalStart, left, modifiedStart, right) + }); + } + // Keep structural folds only when fully within the visible slice; no overlapping bands. + const overlap = (a: IDocumentContextGap, b: IDocumentContextGap) => + (a.originalCount > 0 && b.originalCount > 0 && a.originalStart < b.originalStart + b.originalCount && b.originalStart < a.originalStart + a.originalCount) || + (a.modifiedCount > 0 && b.modifiedCount > 0 && a.modifiedStart < b.modifiedStart + b.modifiedCount && b.modifiedStart < a.modifiedStart + a.modifiedCount); + return [...gaps, ...(diff.contextGaps ?? []).filter(gap => !gaps.some(hidden => overlap(gap, hidden)))].sort((a, b) => a.originalStart - b.originalStart || a.modifiedStart - b.modifiedStart); +} + +export function alignmentRows(diff: IDocumentDiff, originalCount: number, modifiedCount: number): (readonly [number | null, number | null])[] { + const rows: (readonly [number | null, number | null])[] = []; + if (diff.sourceLineAlignment) rows.push(...diff.sourceLineAlignment); + else { + let left = 0, right = 0; + const append = (leftEnd: number, rightEnd: number) => { + while (left < leftEnd || right < rightEnd) rows.push([left < leftEnd ? left++ : null, right < rightEnd ? right++ : null]); + }; + for (const change of diff.changes) { + append(change.original.startLineNumber - 1, change.modified.startLineNumber - 1); + append(change.original.endLineNumberExclusive - 1, change.modified.endLineNumberExclusive - 1); + } + append(originalCount, modifiedCount); + } + return rows; +} + +/** A paired row folds only when none of its changed lines remain unread. */ +export function viewedContextGaps(diff: IDocumentDiff, originalCount: number, modifiedCount: number, viewed: ReviewDiffLens['ranges'], changed: ReviewDiffLens['ranges']): IDocumentContextGap[] { + const rows = alignmentRows(diff, originalCount, modifiedCount); + const contains = (ranges: ReviewDiffLens['ranges'], side: 0 | 1, line: number) => ranges.some(range => range.side === (side === 0 ? 'base' : 'head') && line + 1 >= range.fromLine && line + 1 <= range.toLine); + const hidden = rows.map(row => row.some((line, side) => line !== null && contains(viewed, side as 0 | 1, line)) && row.every((line, side) => line === null || !contains(changed, side as 0 | 1, line) || contains(viewed, side as 0 | 1, line))); + const gaps: IDocumentContextGap[] = []; + let left = 1, right = 1; + for (let index = 0; index < rows.length;) { + if (!hidden[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; continue; } + const originalStart = left, modifiedStart = right; + while (index < rows.length && hidden[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; } + gaps.push({ originalStart, modifiedStart, originalCount: left - originalStart, modifiedCount: right - modifiedStart, label: 'Viewed', breadcrumbs: false, owner: left === originalStart ? 'head' : right === modifiedStart ? 'base' : 'both', change: gapChange(diff, originalStart, left, modifiedStart, right) }); + } + const overlaps = (a: IDocumentContextGap, b: IDocumentContextGap) => + (a.originalCount > 0 && b.originalCount > 0 && a.originalStart < b.originalStart + b.originalCount && b.originalStart < a.originalStart + a.originalCount) || + (a.modifiedCount > 0 && b.modifiedCount > 0 && a.modifiedStart < b.modifiedStart + b.modifiedCount && b.modifiedStart < a.modifiedStart + a.modifiedCount); + return [...gaps, ...(diff.contextGaps ?? []).filter(gap => !gaps.some(viewed => overlaps(gap, viewed)))].sort((a, b) => a.originalStart - b.originalStart || a.modifiedStart - b.modifiedStart); +} + +/** Lens and viewed folds describe coverage, not a new diff; retain the provider's change status. */ +function gapChange(diff: IDocumentDiff, originalStart: number, originalEnd: number, modifiedStart: number, modifiedEnd: number): NonNullable { + const removed = diff.sourceLineAlignment?.some(([l, r]) => r === null && l !== null && l + 1 >= originalStart && l + 1 < originalEnd) || diff.changes.some(c => originalStart < originalEnd && !c.original.isEmpty && c.original.startLineNumber < originalEnd && c.original.endLineNumberExclusive > originalStart); + const added = diff.sourceLineAlignment?.some(([l, r]) => l === null && r !== null && r + 1 >= modifiedStart && r + 1 < modifiedEnd) || diff.changes.some(c => modifiedStart < modifiedEnd && !c.modified.isEmpty && c.modified.startLineNumber < modifiedEnd && c.modified.endLineNumberExclusive > modifiedStart); + return removed && added ? 'modified' : removed ? 'removed' : added ? 'inserted' : 'unchanged'; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewLensFiles.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewLensFiles.test.ts new file mode 100644 index 000000000..078dde627 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewLensFiles.test.ts @@ -0,0 +1,30 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { lensFiles } from './reviewLensFiles.js'; +import { lensContextGaps } from './reviewLens.js'; +import type { ReviewDiffFileWire, ReviewDiffLens } from './reviewProtocol.js'; + +const files: ReviewDiffFileWire[] = [{ path: 'renamed.ts', previousPath: 'old.ts', status: 'renamed', additions: 2, deletions: 1 }]; +const lens: ReviewDiffLens = { + id: 'lens', title: 'Context', reviewId: 'review', version: 1, ranges: [ + { file: 'old.ts', side: 'base', fromLine: 2, toLine: 5 }, + { file: 'context.ts', side: 'base', fromLine: 10, toLine: 12 }, + { file: 'context.ts', side: 'head', fromLine: 10, toLine: 12 }, + ] +}; + +test('diagram references add each unchanged file once, preserving rename identity', () => { + const result = lensFiles(files, lens); + assert.deepEqual(result, [...files, { path: 'context.ts', status: 'unchanged', additions: 0, deletions: 0 }]); + assert.equal(files.length, 1); +}); + +test('clearing the lens and whole-file glob lenses do not introduce context files', () => { + assert.equal(lensFiles(files), files); + assert.equal(lensFiles(files, { ...lens, wholeFiles: true }), files); +}); + +test('an identical file exposes the referenced slice with three surrounding lines', () => { + const gaps = lensContextGaps({ changes: [], moves: [], identical: true, quitEarly: false }, 30, 30, lens.ranges.filter(range => range.file === 'context.ts')); + assert.deepEqual(gaps.map(gap => [gap.originalStart, gap.originalCount, gap.modifiedStart, gap.modifiedCount]), [[1, 6, 1, 6], [16, 15, 16, 15]]); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewLensFiles.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewLensFiles.ts new file mode 100644 index 000000000..ec495494e --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewLensFiles.ts @@ -0,0 +1,14 @@ +import type { ReviewDiffFileWire, ReviewDiffLens } from './reviewProtocol.js'; + +/** Diagram evidence may provide context outside the comparison's changed-file list. */ +export function lensFiles(files: readonly ReviewDiffFileWire[], lens?: ReviewDiffLens): readonly ReviewDiffFileWire[] { + if (!lens || lens.wholeFiles) return files; + const known = new Set(files.flatMap(file => [file.path, ...(file.previousPath ? [file.previousPath] : [])])); + const context: ReviewDiffFileWire[] = []; + for (const range of lens.ranges) { + if (known.has(range.file)) continue; + known.add(range.file); + context.push({ path: range.file, status: 'unchanged', additions: 0, deletions: 0 }); + } + return [...files, ...context]; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewModuleCache.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewModuleCache.test.ts new file mode 100644 index 000000000..6736e6dbf --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewModuleCache.test.ts @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { ReviewModuleCache } from "./reviewModuleCache.js"; + +test("concurrent loads of one key share a single loader call", async () => { + const cache = new ReviewModuleCache(); + let calls = 0; + const loader = async () => { + calls += 1; + return "module"; + }; + const [first, second] = await Promise.all([ + cache.load("a", loader), + cache.load("a", loader), + ]); + assert.equal(first, "module"); + assert.equal(second, "module"); + assert.equal(calls, 1); + assert.equal(await cache.load("a", loader), "module"); + assert.equal(calls, 1); +}); + +test("a rejected load is evicted so the next caller retries", async () => { + const cache = new ReviewModuleCache(); + let calls = 0; + const loader = async () => { + calls += 1; + if (calls === 1) throw new Error("boom"); + return "recovered"; + }; + await assert.rejects(cache.load("a", loader), /boom/); + assert.equal(await cache.load("a", loader), "recovered"); + assert.equal(calls, 2); +}); + +test("a loader that throws synchronously rejects instead of throwing", async () => { + const cache = new ReviewModuleCache(); + await assert.rejects( + cache.load("a", () => { + throw new Error("sync"); + }), + /sync/, + ); +}); + +test("clear forces the next load to run the loader again", async () => { + const cache = new ReviewModuleCache(); + let calls = 0; + const loader = async () => ++calls; + assert.equal(await cache.load("a", loader), 1); + cache.clear(); + assert.equal(await cache.load("a", loader), 2); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewModuleCache.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewModuleCache.ts new file mode 100644 index 000000000..88a6f6280 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewModuleCache.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Caches in-flight and settled module loads by key. Concurrent callers share + * one promise, a fulfilled load stays cached until `clear()`, and a rejected + * load is evicted so the next caller retries. + */ +export class ReviewModuleCache { + private readonly entries = new Map>(); + + load(key: string, loader: () => Promise): Promise { + const cached = this.entries.get(key) as Promise | undefined; + if (cached) { + return cached; + } + + let pending: Promise; + pending = Promise.resolve() + .then(loader) + .catch((error) => { + if (this.entries.get(key) === pending) { + this.entries.delete(key); + } + throw error; + }); + this.entries.set(key, pending); + return pending; + } + + clear(): void { + this.entries.clear(); + } +} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardPaths.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewPaths.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardPaths.ts rename to apps/review-desktop/code-oss/src/vs/review/common/reviewPaths.ts diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewPeek.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewPeek.ts new file mode 100644 index 000000000..45f6ada22 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewPeek.ts @@ -0,0 +1,373 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { + ReviewDiffFileWire, + ReviewDiffSide, + ReviewInlineEditorRange, +} from "./reviewProtocol.js"; + +export const REVIEW_PEEK_MAX_VISIBLE_LINES = 18; +export const REVIEW_PEEK_LINE_HEIGHT = 20; +const REVIEW_PEEK_CONTEXT_LINES = 3; + +export type ReviewPeekHeightMode = "capped" | "content"; + +export interface ReviewPeekWindow { + startLine: number; + endLine: number; + lineCount: number; + visibleLineCount: number; + height: number; +} + +export interface ReviewPeekHiddenArea { + startLineNumber: number; + endLineNumber: number; +} + +export interface ReviewPeekLineMapping { + originalStartLine: number; + originalEndLineExclusive: number; + modifiedStartLine: number; + modifiedEndLineExclusive: number; +} + +export function reviewPeekSideAvailable( + status: ReviewDiffFileWire["status"] | undefined, + side: ReviewDiffSide, +): boolean { + return !( + (side === "base" && status === "added") || + (side === "head" && status === "deleted") + ); +} + +export function reviewPeekWindow( + totalLines: number, + startLine: number, + endLine: number, + heightMode: ReviewPeekHeightMode, + contextLines = REVIEW_PEEK_CONTEXT_LINES, +): ReviewPeekWindow { + if ( + !Number.isInteger(totalLines) || + totalLines <= 0 || + !Number.isInteger(startLine) || + !Number.isInteger(endLine) || + startLine <= 0 || + endLine < startLine || + endLine > totalLines || + !Number.isInteger(contextLines) || + contextLines < 0 + ) { + throw new Error("CodePeek range is outside the resolved file."); + } + const windowStart = Math.max(1, startLine - contextLines); + const windowEnd = Math.min(totalLines, endLine + contextLines); + const lineCount = windowEnd - windowStart + 1; + const visibleLineCount = + heightMode === "content" + ? lineCount + : Math.min(REVIEW_PEEK_MAX_VISIBLE_LINES, lineCount); + return { + startLine: windowStart, + endLine: windowEnd, + lineCount, + visibleLineCount, + height: visibleLineCount * REVIEW_PEEK_LINE_HEIGHT, + }; +} + +export function reviewPeekWindows( + totalLines: number, + ranges: readonly ReviewInlineEditorRange[], + heightMode: ReviewPeekHeightMode, + contextLines = REVIEW_PEEK_CONTEXT_LINES, +): ReviewPeekWindow[] { + if (ranges.length === 0) { + throw new Error("CodePeek requires at least one range."); + } + return mergeReviewPeekWindows( + ranges.map((range) => + reviewPeekWindow( + totalLines, + range.startLine, + range.endLine, + heightMode, + contextLines, + ), + ), + heightMode, + ); +} + +export function reviewPeekWindowsLineCount( + windows: readonly ReviewPeekWindow[], +): number { + return windows.reduce((total, window) => total + window.lineCount, 0); +} + +export function reviewPeekCappedHeight(measuredHeight: number): number { + return Math.min( + REVIEW_PEEK_MAX_VISIBLE_LINES * REVIEW_PEEK_LINE_HEIGHT, + Math.max(0, measuredHeight), + ); +} + +/** The subset of ICodeEditor that window measurement needs. */ +interface ReviewPeekRenderedEditor { + getModel(): unknown; + getTopForLineNumber(lineNumber: number, includeViewZones?: boolean): number; + getBottomForLineNumber(lineNumber: number, includeViewZones?: boolean): number; +} + +/** + * Total height of peek windows as actually rendered by an editor. Each + * window is measured independently so hidden gaps do not inflate the result. + * Wrapped lines and in-window view zones are included; alignment view zones + * outside the windows are excluded. Returns undefined when the editor cannot + * be measured yet. + */ +export function reviewPeekWindowsRenderedHeight( + editor: ReviewPeekRenderedEditor, + windows: readonly ReviewPeekWindow[], +): number | undefined { + if (!editor.getModel() || windows.length === 0) return undefined; + let height = 0; + for (const window of windows) { + // Monaco excludes view zones by default. Inline diffs render deleted + // lines as view zones, so they must count toward the window height. + const top = editor.getTopForLineNumber(window.startLine, true); + const bottom = editor.getBottomForLineNumber(window.endLine, true); + if (bottom <= top) return undefined; + height += bottom - top; + } + return height; +} +export function reviewPeekHiddenAreas( + totalLines: number, + windows: readonly ReviewPeekWindow[], +): ReviewPeekHiddenArea[] { + const hidden: ReviewPeekHiddenArea[] = []; + let nextVisibleLine = 1; + for (const window of windows) { + if (window.startLine > nextVisibleLine) { + hidden.push({ + startLineNumber: nextVisibleLine, + endLineNumber: window.startLine - 1, + }); + } + nextVisibleLine = Math.max(nextVisibleLine, window.endLine + 1); + } + if (nextVisibleLine <= totalLines) { + hidden.push({ + startLineNumber: nextVisibleLine, + endLineNumber: totalLines, + }); + } + return hidden; +} + +export function reviewPeekLineMappings( + patch: string, +): ReviewPeekLineMapping[] { + const mappings: ReviewPeekLineMapping[] = []; + let originalLine = 0; + let modifiedLine = 0; + let inHunk = false; + let changeStart: { original: number; modified: number } | undefined; + + const finishChange = () => { + if (!changeStart) return; + mappings.push({ + originalStartLine: changeStart.original, + originalEndLineExclusive: originalLine, + modifiedStartLine: changeStart.modified, + modifiedEndLineExclusive: modifiedLine, + }); + changeStart = undefined; + }; + + for (const row of patch.split(/\r?\n/)) { + const header = + /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(row); + if (header) { + finishChange(); + originalLine = Number(header[1]); + modifiedLine = Number(header[2]); + inHunk = true; + continue; + } + if (!inHunk) continue; + if (row.startsWith("\\ No newline at end of file")) continue; + const marker = row[0]; + if (marker === " ") { + finishChange(); + originalLine += 1; + modifiedLine += 1; + } else if (marker === "-" || marker === "+") { + changeStart ??= { original: originalLine, modified: modifiedLine }; + if (marker === "-") originalLine += 1; + else modifiedLine += 1; + } + } + finishChange(); + return mappings; +} + +function flipReviewPeekLineMappings( + mappings: readonly ReviewPeekLineMapping[], +): ReviewPeekLineMapping[] { + return mappings.map((mapping) => ({ + originalStartLine: mapping.modifiedStartLine, + originalEndLineExclusive: mapping.modifiedEndLineExclusive, + modifiedStartLine: mapping.originalStartLine, + modifiedEndLineExclusive: mapping.originalEndLineExclusive, + })); +} + +function mappedReviewPeekWindow( + destinationLineCount: number, + sourceWindow: ReviewPeekWindow, + mappings: readonly ReviewPeekLineMapping[], +): ReviewPeekWindow { + const startLine = clampLine( + mapReviewPeekLine(sourceWindow.startLine, mappings, "start"), + destinationLineCount, + ); + const endLine = Math.max( + startLine, + clampLine( + mapReviewPeekLine(sourceWindow.endLine, mappings, "end"), + destinationLineCount, + ), + ); + return reviewPeekWindow( + destinationLineCount, + startLine, + endLine, + "content", + 0, + ); +} + +function mappedReviewPeekWindows( + destinationLineCount: number, + sourceWindows: readonly ReviewPeekWindow[], + mappings: readonly ReviewPeekLineMapping[], +): ReviewPeekWindow[] { + return mergeReviewPeekWindows( + sourceWindows.map((window) => + mappedReviewPeekWindow(destinationLineCount, window, mappings), + ), + "content", + ); +} + +export function reviewPeekDiffWindows( + originalLineCount: number, + modifiedLineCount: number, + ranges: readonly ReviewInlineEditorRange[], + defaultSide: ReviewDiffSide, + baseToHeadMappings: readonly ReviewPeekLineMapping[], +): { + readonly original: readonly ReviewPeekWindow[]; + readonly modified: readonly ReviewPeekWindow[]; +} { + const baseRanges = ranges.filter( + (range) => (range.side ?? defaultSide) === "base", + ); + const headRanges = ranges.filter( + (range) => (range.side ?? defaultSide) === "head", + ); + const originalSelections = + baseRanges.length > 0 + ? reviewPeekWindows(originalLineCount, baseRanges, "content") + : []; + const modifiedSelections = + headRanges.length > 0 + ? reviewPeekWindows(modifiedLineCount, headRanges, "content") + : []; + const originalFromHead = mappedReviewPeekWindows( + originalLineCount, + modifiedSelections, + flipReviewPeekLineMappings(baseToHeadMappings), + ); + const modifiedFromBase = mappedReviewPeekWindows( + modifiedLineCount, + originalSelections, + baseToHeadMappings, + ); + return { + original: mergeReviewPeekWindows( + [...originalSelections, ...originalFromHead], + "content", + ), + modified: mergeReviewPeekWindows( + [...modifiedSelections, ...modifiedFromBase], + "content", + ), + }; +} + +function mergeReviewPeekWindows( + windows: readonly ReviewPeekWindow[], + heightMode: ReviewPeekHeightMode, +): ReviewPeekWindow[] { + const sorted = [...windows].sort( + (left, right) => left.startLine - right.startLine, + ); + const merged: ReviewPeekWindow[] = []; + for (const window of sorted) { + const previous = merged.at(-1); + if (!previous || window.startLine > previous.endLine + 1) { + merged.push(window); + continue; + } + const endLine = Math.max(previous.endLine, window.endLine); + const lineCount = endLine - previous.startLine + 1; + const visibleLineCount = + heightMode === "content" + ? lineCount + : Math.min(REVIEW_PEEK_MAX_VISIBLE_LINES, lineCount); + merged[merged.length - 1] = { + startLine: previous.startLine, + endLine, + lineCount, + visibleLineCount, + height: visibleLineCount * REVIEW_PEEK_LINE_HEIGHT, + }; + } + return merged; +} + +function mapReviewPeekLine( + line: number, + mappings: readonly ReviewPeekLineMapping[], + edge: "start" | "end", +): number { + const mapping = mappings.findLast( + (candidate) => candidate.originalStartLine <= line, + ); + if (!mapping) return line; + if (mapping.originalEndLineExclusive <= line) { + return ( + line - + mapping.originalEndLineExclusive + + mapping.modifiedEndLineExclusive + ); + } + return edge === "start" + ? mapping.modifiedStartLine + : Math.max( + mapping.modifiedStartLine, + mapping.modifiedEndLineExclusive - 1, + ); +} + +function clampLine(line: number, totalLines: number): number { + return Math.max(1, Math.min(line, totalLines)); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewReadonlySource.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewReadonlySource.ts new file mode 100644 index 000000000..651f8bb4b --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewReadonlySource.ts @@ -0,0 +1,8 @@ +import type { URI } from "../../base/common/uri.js"; + +export const REVIEW_LANGUAGE_SOURCE_SCHEME = "review-language-source"; + +/** These resources own presentation buffers, never workspace working copies. */ +export function isReviewReadonlySource(resource: URI | undefined): boolean { + return resource?.scheme === "review-api-source" || resource?.scheme === REVIEW_LANGUAGE_SOURCE_SCHEME || resource?.scheme === "devfast-review-unified"; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewReconnect.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewReconnect.test.ts new file mode 100644 index 000000000..caecd7496 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewReconnect.test.ts @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { + REVIEW_CLIENT_RECONNECT_DELAYS, + reconnectUntilAborted, +} from "./reviewReconnect.js"; + +function failing(times: number): (onConnected: () => void) => Promise { + let calls = 0; + return async () => { + calls += 1; + if (calls <= times) throw new Error(`failure ${calls}`); + }; +} + +test("walks the delay table between failures and returns once connect resolves", async () => { + const waits: number[] = []; + const errors: string[] = []; + await reconnectUntilAborted(new AbortController().signal, failing(3), { + onRetry: (error) => errors.push((error as Error).message), + wait: async (ms) => { + waits.push(ms); + }, + }); + assert.deepEqual(waits, REVIEW_CLIENT_RECONNECT_DELAYS.slice(0, 3)); + assert.deepEqual(errors, ["failure 1", "failure 2", "failure 3"]); +}); + +test("keeps retrying at the last delay when no exhaustion handler is given", async () => { + const waits: number[] = []; + const total = REVIEW_CLIENT_RECONNECT_DELAYS.length + 2; + await reconnectUntilAborted(new AbortController().signal, failing(total), { + wait: async (ms) => { + waits.push(ms); + }, + }); + const last = REVIEW_CLIENT_RECONNECT_DELAYS[REVIEW_CLIENT_RECONNECT_DELAYS.length - 1]; + assert.deepEqual(waits, [...REVIEW_CLIENT_RECONNECT_DELAYS, last, last]); +}); + +test("calls onExhausted with the last error once the table runs out", async () => { + const waits: number[] = []; + await assert.rejects( + reconnectUntilAborted( + new AbortController().signal, + failing(REVIEW_CLIENT_RECONNECT_DELAYS.length + 1), + { + onExhausted: (error) => { + throw new Error("exhausted", { cause: error }); + }, + wait: async (ms) => { + waits.push(ms); + }, + }, + ), + (error: Error) => + error.message === "exhausted" && + (error.cause as Error).message === + `failure ${REVIEW_CLIENT_RECONNECT_DELAYS.length + 1}`, + ); + assert.deepEqual(waits, [...REVIEW_CLIENT_RECONNECT_DELAYS]); +}); + +test("a successful connection restarts the delay table", async () => { + const waits: number[] = []; + let calls = 0; + await reconnectUntilAborted( + new AbortController().signal, + async (onConnected) => { + calls += 1; + if (calls === 1) throw new Error("first"); + if (calls === 2) { + onConnected(); + throw new Error("stream ended"); + } + }, + { + wait: async (ms) => { + waits.push(ms); + }, + }, + ); + const first = REVIEW_CLIENT_RECONNECT_DELAYS[0]; + assert.deepEqual(waits, [first, first]); +}); + +test("returns quietly when the signal aborts during a failure", async () => { + const controller = new AbortController(); + let waited = false; + await reconnectUntilAborted( + controller.signal, + async () => { + controller.abort(); + throw new Error("aborted mid-connect"); + }, + { + onRetry: () => assert.fail("must not retry after abort"), + wait: async () => { + waited = true; + }, + }, + ); + assert.equal(waited, false); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewReconnect.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewReconnect.ts new file mode 100644 index 000000000..e4ba32e45 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewReconnect.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +export const REVIEW_SERVER_RESTART_DELAYS = [250, 1_000, 2_000] as const; + +// Keep the renderer retrying after the utility host has scheduled its final +// restart. The replacement process still needs time to boot and attach its +// authenticated event streams after the host's delay has elapsed. +export const REVIEW_CLIENT_RECONNECT_DELAYS = [ + ...REVIEW_SERVER_RESTART_DELAYS, + 4_000, +] as const; + +export interface ReviewReconnectOptions { + /** Observes each failure before the next delay. */ + readonly onRetry?: (error: unknown) => void; + /** + * Called once every delay in the table has been used since the last + * successful connection. Omit it to keep retrying at the last delay. + */ + readonly onExhausted?: (error: unknown) => never; + readonly wait?: (ms: number) => Promise; +} + +/** + * Runs `connect` until it resolves or `signal` aborts, backing off through + * `REVIEW_CLIENT_RECONNECT_DELAYS` between failures. `connect` receives an + * `onConnected` callback that restarts the delay table. + */ +export async function reconnectUntilAborted( + signal: AbortSignal, + connect: (onConnected: () => void) => Promise, + options: ReviewReconnectOptions = {}, +): Promise { + const wait = + options.wait ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + let attempt = 0; + while (!signal.aborted) { + try { + await connect(() => { + attempt = 0; + }); + return; + } catch (error) { + if (signal.aborted) return; + options.onRetry?.(error); + let delay = REVIEW_CLIENT_RECONNECT_DELAYS[attempt++]; + if (delay === undefined) { + options.onExhausted?.(error); + delay = + REVIEW_CLIENT_RECONNECT_DELAYS[ + REVIEW_CLIENT_RECONNECT_DELAYS.length - 1 + ]; + } + await wait(delay); + } + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewSourceView.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewSourceView.ts new file mode 100644 index 000000000..74963e25e --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewSourceView.ts @@ -0,0 +1,58 @@ +import { URI } from "../../base/common/uri.js"; +import { reviewSourcePinsFromQuery, reviewSourceQuery, type ReviewApiSourceLocation, type ReviewSourceSelection } from "./reviewProtocol.js"; + +export const REVIEW_API_SOURCE_SCHEME = "review-api-source"; + +export function apiSourceUri(target: ReviewApiSourceLocation, empty = false): URI { + const query = new URLSearchParams({ side: target.side }); + for (const [key, value] of Object.entries(reviewSourceQuery(target.view))) { + if (value !== undefined) query.set(key, String(value)); + } + if (target.view.generation) query.set("generation", target.view.generation); + if (empty) query.set("empty", "true"); + return URI.from({ scheme: REVIEW_API_SOURCE_SCHEME, authority: target.view.reviewId, path: `/${target.file}`, query: query.toString() }); +} + +/** Decode resolved read coordinates; generation only separates client models. */ +export function sourceLocation(resource: URI): ReviewApiSourceLocation { + const query = new URLSearchParams(resource.query); + const commit = query.get("commit") ?? undefined; + return { + view: Object.freeze({ + reviewId: resource.authority, + version: Number(query.get("version")), + generation: query.get("generation") ?? undefined, + commit, + pins: reviewSourcePinsFromQuery((key) => query.get(key)), + }), + side: query.get("side") === "base" ? "base" : "head", + file: resource.path.slice(1), + }; +} + +/** Tabs and directory nodes keep intent, never a resolved refresh token. */ +export const REVIEW_API_TREE_SCHEME = "review-api-tree"; + +export function sourceSelectionIdentity(selection: ReviewSourceSelection): string { + return `${selection.reviewId}/${selection.kind === "current" ? "current" : selection.version}`; +} + +export function sourceTreeUri(selection: ReviewSourceSelection, file = ""): URI { + return URI.from({ scheme: REVIEW_API_TREE_SCHEME, authority: selection.reviewId, + path: `/${file}`, query: selection.kind === "version" ? `version=${selection.version}` : "" }); +} + +export function sourceTreeSelection(resource: URI): ReviewSourceSelection { + const version = new URLSearchParams(resource.query).get("version"); + return version === null ? { reviewId: resource.authority, kind: "current" } + : { reviewId: resource.authority, kind: "version", version: Number(version) }; +} + +/** An open Source tab owns the tree while its files change revisions. */ +export function sourceTreeRoot(resource: URI, current?: URI): URI { + if (current && resource.authority === current.authority) { + const selection = sourceTreeSelection(current); + if (selection.kind === "current" || selection.version === sourceLocation(resource).view.version) return current; + } + return sourceTreeUri({ reviewId: resource.authority, kind: "version", version: sourceLocation(resource).view.version }); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewStructuralDiff.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewStructuralDiff.test.ts new file mode 100644 index 000000000..0af2fd2a5 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewStructuralDiff.test.ts @@ -0,0 +1,360 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; +import { projectInlineSourceAlignment, projectSplitSourceAlignment } from "../../editor/common/diff/sourceLineAlignment.js"; +import { + collapsedRegions, + hiddenLinesOf, + structuralContextGaps, + bandDetail, + structuralHighlights, + structuralRows, + utf16Column, + type StructuralFold, + type StructuralLeaf, + type StructuralRegion, + type StructuralTextDiff, +} from "./reviewStructuralDiff.js"; + +/** + * A leaf whose `id`, `alignment_id` and `fold_state_id` are all `id`. Tests pair two leaves by giving + * them one number on both sides, which repeats the `id` across sides as diffr never does; nothing here + * keys identity across sides, and the tests that tell the ids apart set them through `extra`. + */ +function leaf(id: number, start: number, end: number, extra: Partial = {}): StructuralLeaf { + return { id, alignment_id: id, fold_state_id: id, kind: "leaf", start: { line: start, column: 0 }, end: { line: end, column: 0 }, ...extra }; +} +function fold(id: number, children: StructuralRegion[], tags: string[] = ["context:body"]): StructuralFold { + const first = children[0], last = children[children.length - 1]; + return { id, fold_state_id: id, kind: "fold", start: first.start, end: last.end, tags, children }; +} +function text(lines: string[], regions: StructuralRegion[]) { + return { text: lines.join("\n") + "\n", regions }; +} +const stats = { textual: { added: 0, removed: 0 }, visible: { added: 0, removed: 0 } }; + +test("paired collapse removes hidden height without leaving padding for hidden anchors", () => { + const rows: [number | null, number | null][] = [ + [0, 0], + [1, 1], + [null, 2], + [2, 3], + [3, 4], + ]; + const segments = projectSplitSourceAlignment( + rows, + (l) => (l === 1 || l === 2 ? 0 : 20), + (r) => (r >= 1 && r <= 3 ? 0 : 20), + ); + assert.deepEqual( + segments.map((s) => [s.leftEnd, s.rightEnd, s.rightHeight - s.leftHeight]), + [ + [1, 1, 0], + [3, 4, 0], + [4, 5, 0], + ], + ); +}); + +test("a one-sided band's height is filled on the other side at the row that starts the fold, not past it", () => { + // Right-only row 1, then a right fold (rows 2..4) whose band is 50px and whose middle row pairs with left 1, then right-only row 5. + const rows: [number | null, number | null][] = [ + [0, 0], + [null, 1], + [null, 2], + [1, 3], + [null, 4], + [null, 5], + [2, 6], + ]; + const segments = projectSplitSourceAlignment( + rows, + (l) => (l === 1 ? 0 : 20), + (r) => (r === 2 ? 50 : r === 3 || r === 4 ? 0 : 20), + ); + // Fillers sit after a segment's last left line: after left 0 for row 1 and the band, then again after left 0 (left 1 is folded) for row 5. + assert.deepEqual( + segments.map((s) => [s.leftEnd, s.rightEnd, s.rightHeight - s.leftHeight]), + [ + [1, 3, 70], + [2, 5, 0], + [2, 6, 20], + [3, 7, 0], + ], + ); +}); + +test("leaves zip by alignment_id into rows: paired line for line, unpaired one-sided, trailing empty lines paired", () => { + // As diffr numbers them: every region has its own id; paired leaves share alignment and fold state. + const rhsLeaf = (id: number, alignment: number, start: number, end: number) => + leaf(id, start, end, { alignment_id: alignment, fold_state_id: alignment === 9 ? id : alignment - 1 }); + const diff: StructuralTextDiff = { + type: "text", structural_changes: { base: [], head: [] }, + stats, + lhs: text(["a", "b", "c", "d"], [leaf(0, 0, 1, { alignment_id: 1 }), leaf(1, 1, 2, { alignment_id: 2 }), leaf(2, 2, 4, { alignment_id: 3 })]), + rhs: text(["a", "x", "b", "c", "d"], [rhsLeaf(3, 1, 0, 1), rhsLeaf(4, 9, 1, 2), rhsLeaf(5, 2, 2, 3), rhsLeaf(6, 3, 3, 5)]), + }; + assert.deepEqual(structuralRows(diff), [ + [0, 0], + [null, 1], + [1, 2], + [2, 3], + [3, 4], + [4, 5], + ]); +}); + +test("one-sided files and nested folds still tile", () => { + const added: StructuralTextDiff = { + type: "text", structural_changes: { base: [], head: [] }, + stats, + rhs: text(["fn f() {", " 1", "}"], [fold(1, [leaf(2, 0, 1), leaf(3, 1, 2), leaf(4, 2, 3)])]), + }; + assert.deepEqual(structuralRows(added), [ + [null, 0], + [null, 1], + [null, 2], + [null, 3], + ]); +}); + + +test("structural coverage tints inserted lines without novel tokens, retaining UTF-16 token highlights", () => { + const diff: StructuralTextDiff = { + type: "text", structural_changes: { base: [[1, 2]], head: [[1, 4]] }, + stats, + lhs: text(["a", "b"], [leaf(1, 0, 1), leaf(2, 1, 2, { changed: [{ line: 1, start_column: 0, end_column: 1 }] })]), + rhs: text(["a", "b + é", "", "}"], [leaf(1, 0, 1), leaf(3, 1, 4, { changed: [{ line: 1, start_column: 2, end_column: 6 }] })]), + }; + const paint = structuralHighlights(diff); + assert.deepEqual(paint.originalLines, [2]); + assert.deepEqual(paint.modifiedLines, [2, 3, 4]); + assert.deepEqual(paint.modified, [{ startLineNumber: 2, startColumn: 3, endLineNumber: 2, endColumn: 6 }]); +}); + +test("fully novel lines retain line tint without token tint on either side", () => { + for (const changed of [ + [{ line: 0, start_column: 0, end_column: 13 }], + [{ line: 0, start_column: 1, end_column: 12 }], + [{ line: 0, start_column: 1, end_column: 6 }, { line: 0, start_column: 7, end_column: 12 }], + ]) { + const source = text(["\tconst café \t"], [leaf(1, 0, 1, { changed })]); + const paint = structuralHighlights({ type: "text", stats, structural_changes: { base: [[0, 1]], head: [[0, 1]] }, lhs: source, rhs: source }); + assert.deepEqual(paint.originalLines, [1]); + assert.deepEqual(paint.modifiedLines, [1]); + assert.deepEqual(paint.original, []); + assert.deepEqual(paint.modified, []); + } +}); + +test("Tree-sitter byte offsets convert to Monaco UTF-16 columns", () => { + assert.equal(utf16Column("a😀éz", 7), 5); +}); + + +test("a collapsed region hides every line it covers, fold or leaf; nested collapses are subsumed", () => { + const collapsed = { collapsed: true, label: "x" }; + const inner = fold(3, [leaf(4, 3, 4), leaf(5, 4, 6)]); + inner.visibility = collapsed; + const body = fold(2, [leaf(6, 2, 3), inner, leaf(7, 6, 8)]); + body.visibility = collapsed; + assert.deepEqual(hiddenLinesOf(body), { start: 2, end: 8 }); + assert.deepEqual(hiddenLinesOf(leaf(1, 0, 2, { visibility: collapsed })), { start: 0, end: 2 }); + assert.deepEqual(collapsedRegions([leaf(1, 0, 2, { visibility: collapsed }), body], (id) => id === 1 || id === 2 || id === 3).map((r) => r.fold_state_id), [1, 2]); + assert.deepEqual(collapsedRegions([leaf(1, 0, 2), body], (id) => id === 3).map((r) => r.fold_state_id), [3]); +}); + +test("every collapsed region becomes a labelled band: paired across sides, or one-sided at the aligned line", () => { + const pseudocode = "// pseudocode\nif not key: return None\nreturn call(key)"; + const gapL = leaf(1, 0, 40, { visibility: { collapsed: true, label: "40 unchanged lines" } }); + // The paired gap has an id of its own and pairs with the left one by alignment. + const gapR = leaf(11, 0, 40, { alignment_id: 1, fold_state_id: 1, visibility: { collapsed: true, label: "40 unchanged lines" } }); + // A body fold covers the body alone; the signature line is the leaf before it. + const removed = fold(2, [leaf(4, 41, 60)], ["deleted-bodies:function"]); + removed.visibility = { collapsed: true, label: "19 lines removed" }; + const added = fold(5, [leaf(7, 41, 70)], ["deleted-bodies:function"]); + added.visibility = { collapsed: true, label: pseudocode }; + const tailL = leaf(8, 60, 62), tailR = leaf(8, 70, 72); + const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); + const diff: StructuralTextDiff = { + type: "text", structural_changes: { base: [], head: [] }, + stats, + lhs: text(lines(62), [gapL, leaf(3, 40, 41), removed, tailL]), + rhs: text(lines(72), [gapR, leaf(6, 40, 41), added, tailR]), + }; + const gaps = structuralContextGaps(diff, (id) => id === 1 || id === 2 || id === 5); + assert.deepEqual(gaps, [ + { originalStart: 1, originalCount: 40, modifiedStart: 1, modifiedCount: 40, label: "40 unchanged lines", owner: "both", change: "unchanged", collapsed: true, foldStateId: 1, regionIds: [11, 1], breadcrumbs: true }, + // The removed body hides lines 42..60 on the left; its rows precede the added body's, so it anchors before them on the right. + { originalStart: 42, originalCount: 19, modifiedStart: 41, modifiedCount: 0, label: "19 lines removed", owner: "base", change: "removed", collapsed: true, foldStateId: 2, regionIds: [2], breadcrumbs: true }, + { originalStart: 61, originalCount: 0, modifiedStart: 42, modifiedCount: 29, label: pseudocode, owner: "head", change: "inserted", collapsed: true, foldStateId: 5, regionIds: [5], breadcrumbs: true }, + ]); + // A region the reader revealed stays a band, marked open, so the editor keeps a fold control on it. + const revealed = structuralContextGaps(diff, (id) => id === 2 || id === 5, (id) => (id === 1 ? false : id === 2 || id === 5 ? true : undefined)); + assert.deepEqual(revealed.map((g) => [g.foldStateId, g.collapsed]), [[1, false], [2, true], [5, true]]); + // A region the state never knew is not a band at all, and neither is one that never starts collapsed. + assert.deepEqual(structuralContextGaps(diff, (id) => id === 2 || id === 5).map((g) => g.foldStateId), [2, 5]); + assert.deepEqual(structuralContextGaps(diff, () => false, (id) => (id === 8 ? false : id === 2 ? true : undefined)).map((g) => g.foldStateId), [2]); + // A collapsed region without a label is named by its line count. + const unlabeled = leaf(9, 0, 3, { visibility: { collapsed: true, label: "" } }); + const small: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(3), [unlabeled]), rhs: text(lines(3), [unlabeled]) }; + assert.equal(structuralContextGaps(small, () => true)[0].label, "3 hidden lines"); +}); + +test("a band's detail drops diffr's pseudocode marker line and keeps one-line labels empty", () => { + assert.equal(bandDetail("// pseudocode\nx = 1\n y = 2"), "x = 1\n y = 2"); + assert.equal(bandDetail("# pseudocode\nreturn x"), "return x"); + assert.equal(bandDetail("first\nsecond"), "first\nsecond"); + assert.equal(bandDetail("19 lines removed"), ""); +}); + +test("a one-sided band also hides the opposite lines the zip aligned with it", () => { + // The lhs fold is unpaired (no rhs region shares its fold state), but its body leaf (3) pairs with an rhs leaf: the band spans both. + const body = fold(2, [leaf(4, 1, 6)], ["deleted-bodies:function"]); + body.visibility = { collapsed: true, label: "5 unchanged lines" }; + const rhsHead = leaf(3, 0, 1), rhsBody = leaf(4, 1, 6); + const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); + const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(6), [leaf(3, 0, 1), body]), rhs: text(lines(6), [rhsHead, rhsBody]) }; + const [gap] = structuralContextGaps(diff, (id) => id === 2); + assert.deepEqual(gap, { + originalStart: 2, originalCount: 5, modifiedStart: 2, modifiedCount: 5, + label: "5 unchanged lines", owner: "base", change: "unchanged", collapsed: true, foldStateId: 2, regionIds: [2], breadcrumbs: true, + }); +}); + +test("a one-sided band starts after the row before its fold and hides only the opposite lines inside its rows", () => { + const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); + // Right: a function whose body has an inserted run, a middle leaf paired with the left, and another inserted run. + const added = fold(20, [leaf(22, 3, 5), leaf(12, 5, 7), leaf(23, 7, 9)], ["deleted-bodies:function"]); + added.visibility = { collapsed: true, label: "// pseudocode\nreturn rows" }; + const inserted: StructuralTextDiff = { + type: "text", structural_changes: { base: [], head: [] }, + stats, + lhs: text(lines(6), [leaf(10, 0, 2), leaf(12, 2, 4), leaf(14, 4, 6)]), + rhs: text(lines(11), [leaf(10, 0, 2), leaf(21, 2, 3), added, leaf(14, 9, 11)]), + }; + assert.deepEqual(structuralRows(inserted).slice(0, 10), [ + [0, 0], [1, 1], [null, 2], [null, 3], [null, 4], [2, 5], [3, 6], [null, 7], [null, 8], [4, 9], + ]); + assert.deepEqual(structuralContextGaps(inserted, (id) => id === 20), [{ + originalStart: 3, originalCount: 2, modifiedStart: 4, modifiedCount: 6, + label: "// pseudocode\nreturn rows", owner: "head", change: "inserted", collapsed: true, foldStateId: 20, regionIds: [20], breadcrumbs: true, + }]); + // The mirror: a left-only function whose rows are all filler on the right, followed by a right-only line. + const removed = fold(20, [leaf(22, 3, 6)], ["deleted-bodies:function"]); + removed.visibility = { collapsed: true, label: "3 lines removed" }; + const deleted: StructuralTextDiff = { + type: "text", structural_changes: { base: [], head: [] }, + stats, + lhs: text(lines(8), [leaf(10, 0, 2), leaf(21, 2, 3), removed, leaf(14, 6, 8)]), + rhs: text(lines(5), [leaf(10, 0, 2), leaf(30, 2, 3), leaf(14, 3, 5)]), + }; + assert.deepEqual(structuralRows(deleted).slice(0, 8), [[0, 0], [1, 1], [2, null], [3, null], [4, null], [5, null], [null, 2], [6, 3]]); + assert.deepEqual(structuralContextGaps(deleted, (id) => id === 20), [{ + originalStart: 4, originalCount: 3, modifiedStart: 3, modifiedCount: 0, + label: "3 lines removed", owner: "base", change: "removed", collapsed: true, foldStateId: 20, regionIds: [20], breadcrumbs: true, + }]); +}); + +test("alignment and fold state are separate: the zip follows one, collapse follows the other", () => { + const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); + // A docstring (id 1) linked to its function under fold state 7 on the rhs. The matched + // functions have their own ids (2 and 5), share fold state 7, and their leaves pair by alignment. + const doc = { ...leaf(1, 0, 2, { visibility: { collapsed: true, label: "" } }), fold_state_id: 7 }; + const fnR = { ...fold(5, [leaf(4, 3, 6)]), fold_state_id: 7 }; + fnR.visibility = { collapsed: true, label: "3 hidden lines" }; + const fnL = { ...fold(2, [leaf(4, 1, 4)]), fold_state_id: 7 }; + fnL.visibility = { collapsed: true, label: "3 hidden lines" }; + const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(4), [leaf(3, 0, 1), fnL]), rhs: text(lines(6), [doc, leaf(3, 2, 3), fnR]) }; + // Rows pair the functions' leaves by alignment_id; the docstring is rhs-only. + assert.deepEqual(structuralRows(diff).slice(0, 3), [[null, 0], [null, 1], [0, 2]]); + // One toggle, fold state 7, hides both the docstring and the paired function. + const gaps = structuralContextGaps(diff, (id) => id === 7); + assert.deepEqual(gaps.map((g) => [g.change, g.foldStateId]).sort(), [["inserted", 7], ["unchanged", 7]]); + assert.deepEqual(gaps.find((g) => g.change === "unchanged"), { + originalStart: 2, originalCount: 3, modifiedStart: 4, modifiedCount: 3, + label: "3 hidden lines", owner: "both", change: "unchanged", collapsed: true, foldStateId: 7, regionIds: [5, 2], breadcrumbs: true, + }); + // With fold state 7 open, neither the docstring nor the function is a band. + assert.deepEqual(structuralContextGaps(diff, () => false), []); +}); + +test("a docstring bundled with its function shares one fold state and shows a bare count", () => { + const collapsed = { collapsed: true, label: "" }; + const doc = leaf(30, 0, 2, { tags: ["summarize:docstring"], visibility: collapsed }); + doc.fold_state_id = 40; + const body = fold(40, [leaf(42, 3, 6)], ["deleted-bodies:function"]); + body.visibility = { collapsed: true, label: "// pseudocode\nreturn x" }; + const lines = ["/// a", "/// b", "fn f() {", "x", "y", "}"]; + const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text([], []), rhs: text(lines, [doc, leaf(41, 2, 3), body]) }; + const open = new Set(); + const state = (id: number) => (id === 40 ? !open.has(id) : undefined); + const gaps = structuralContextGaps(diff, (id) => state(id) === true, state); + assert.deepEqual(gaps.map((g) => [g.foldStateId, g.breadcrumbs, g.collapsed]), [[40, false, true], [40, true, true]]); + open.add(40); + assert.deepEqual(structuralContextGaps(diff, (id) => state(id) === true, state).map((g) => g.collapsed), [false, false]); +}); + +test("a fold pairs through fold state, and a docstring fold only with a docstring fold", () => { + const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); + const collapsed = { collapsed: true, label: "" }; + // lhs: a docstring fold (0-3) linked to the function body (3-7). rhs: only the body (0-4), matched with the lhs body. + const docL: StructuralRegion = { ...fold(1, [leaf(2, 0, 3)], ["deleted-bodies:docstring"]), fold_state_id: 9, visibility: collapsed }; + const bodyL: StructuralRegion = { ...fold(4, [leaf(6, 4, 7)], ["deleted-bodies:function"]), fold_state_id: 9, visibility: { collapsed: true, label: "3 lines" } }; + const bodyR: StructuralRegion = { ...fold(7, [leaf(6, 1, 4)], ["deleted-bodies:function"]), fold_state_id: 9, visibility: { collapsed: true, label: "3 lines" } }; + const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(7), [docL, leaf(5, 3, 4), bodyL]), rhs: text(lines(4), [leaf(5, 0, 1), bodyR]) }; + const gaps = structuralContextGaps(diff, (id) => id === 9); + // A whole-node docstring fold covers every line it holds; the body fold starts below + // the signature leaf beside it. + assert.deepEqual(gaps.map((g) => [g.change, g.originalStart, g.originalCount, g.modifiedStart, g.modifiedCount, g.breadcrumbs]), [ + ["removed", 1, 3, 1, 0, false], + ["unchanged", 5, 3, 2, 3, true], + ]); + // Folds that share an id but not a fold state are not a pair. + const other: StructuralRegion = { ...bodyR, id: 4, fold_state_id: 10 }; + const unpaired: StructuralTextDiff = { ...diff, rhs: text(lines(4), [other]) }; + assert.deepEqual(structuralContextGaps(unpaired, (id) => id === 9 || id === 10).map((g) => g.owner).sort(), ["base", "base", "head"]); +}); + + +test("inline correspondence omits a large folded region rather than balancing its hidden sides", () => { + const rows: [number | null, number | null][] = [[0, 0], ...Array.from({ length: 100 }, (_, i): [number, null] => [i + 1, null]), [101, 1], [102, 2]]; + const result = projectInlineSourceAlignment(rows, l => l > 0 && l < 101 ? 0 : 20, () => 20, new Set([101]), new Set([1])); + assert.deepEqual(result, [{ leftStart: 101, leftEnd: 102, rightStart: 1, rightEnd: 2, leftHeight: 20, rightHeight: 20 }]); +}); + +test("inline correspondence retains removed code, changed pairs, and insertion order", () => { + const rows: [number | null, number | null][] = [[0, 0], [1, null], [null, 1], [2, 2], [3, 3]]; + const result = projectInlineSourceAlignment(rows, () => 20, r => r === 2 ? 40 : 20, new Set([2]), new Set([2])); + assert.deepEqual(result, [{ leftStart: 1, leftEnd: 3, rightStart: 1, rightEnd: 3, leftHeight: 40, rightHeight: 60 }]); +}); + +test("a folded changed pair separates inline original-code zones", () => { + const rows: [number, number][] = [[0, 0], [1, 1], [2, 2]]; + const result = projectInlineSourceAlignment(rows, l => l === 1 ? 0 : 20, r => r === 1 ? 0 : 20, new Set([0, 1, 2]), new Set([0, 1, 2])); + assert.deepEqual(result.map(s => [s.leftStart, s.leftEnd, s.rightStart, s.rightEnd]), [[0, 1, 0, 1], [2, 3, 2, 3]]); +}); + + +test("base-owned unchanged fold projects both ranges and retains its toggle identity after reveal", () => { + const base = fold(26, [leaf(16, 0, 1), fold(28, [leaf(17, 1, 4)]), leaf(18, 4, 5)]); + base.visibility = { collapsed: true, label: "5 unchanged lines" }; + const head = fold(334, [leaf(16, 0, 1), fold(336, [leaf(17, 1, 4)]), leaf(18, 4, 5)]); + const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(["a", "b", "c", "d", "e"], [base]), rhs: text(["a", "b", "c", "d", "e"], [head]) }; + for (const collapsed of [true, false, true]) { + const [gap] = structuralContextGaps(diff, () => collapsed, id => id === 26 ? collapsed : undefined); + assert.equal(gap.owner, "base"); assert.equal(gap.change, "unchanged"); + assert.equal(gap.originalCount, 5); assert.equal(gap.modifiedCount, 5); + assert.equal(gap.foldStateId, 26); assert.equal(gap.collapsed, collapsed); + } + // Paired leaves with changed spans are modified, regardless of fold ownership. + const l = base.children[0]; const r = head.children[0]; + if (l.kind !== "leaf" || r.kind !== "leaf") throw new Error("Expected leaves"); + l.changed = [{ line: 0, start_column: 0, end_column: 1 }]; r.changed = [{ line: 0, start_column: 0, end_column: 1 }]; + diff.structural_changes = { base: [[0, 1]], head: [[0, 1]] }; + assert.equal(structuralContextGaps(diff, id => id === 26)[0].change, "modified"); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewStructuralDiff.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewStructuralDiff.ts new file mode 100644 index 000000000..732b97b05 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewStructuralDiff.ts @@ -0,0 +1,285 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { structuralRows } from "./reviewProtocol.js"; +export { structuralRows } from "./reviewProtocol.js"; + +import type { + StructuralPairing, StructuralFileRef, StructuralRegion, StructuralSource, + StructuralDiff, +} from "./reviewProtocol.js"; +export type { + StructuralPairing, StructuralProblem, StructuralPos, StructuralSpan, + StructuralVisibility, StructuralRegion, StructuralSyntaxSpan, StructuralSource, + StructuralLineCounts, StructuralStats, StructuralDiff, StructuralFileRef, + StructuralFileChange, +} from "./reviewProtocol.js"; +export { STRUCTURAL_DIFF_WIRE_VERSION as STRUCTURAL_WIRE_VERSION } from "./reviewProtocol.js"; +export type { StructuralDiffEvent as StructuralEvent } from "./reviewProtocol.js"; +export type StructuralLeaf = Extract; +export type StructuralFold = Extract; +export type StructuralTextDiff = Extract; +export type StructuralBinaryDiff = Extract; + +/** Review keys a file by its head path, or its base path for a deletion. */ +export function structuralFilePath(file: StructuralPairing): string { + return file.rhs?.path ?? file.lhs!.path; +} + +/** The 0-based, half-open line span a region touches. An end at column 0 does not touch its end line. */ +export function regionLines(region: StructuralRegion): { start: number; end: number } { + return { start: region.start.line, end: region.end.column === 0 ? region.end.line : region.end.line + 1 }; +} + +export function structuralLeaves(regions: readonly StructuralRegion[] | undefined): StructuralLeaf[] { + const leaves: StructuralLeaf[] = []; + const walk = (region: StructuralRegion) => { + if (region.kind === "leaf") leaves.push(region); + else for (const child of region.children) walk(child); + }; + for (const region of regions ?? []) walk(region); + return leaves; +} + +export function utf16Column(text: string, byteColumn: number): number { + let bytes = 0, + units = 0; + for (const character of text) { + if (bytes >= byteColumn) break; + bytes += new TextEncoder().encode(character).length; + units += character.length; + } + return units + 1; +} + +/** + * Whole-line tint follows diffr’s structural coverage, matching change counts. + * Changed token spans supply the stronger tint within those lines. + */ +export function structuralHighlights(diff: StructuralTextDiff) { + function side(source: StructuralSource | undefined, ranges: readonly (readonly [number, number])[]) { + if (!source) return { spans: [], lines: [] }; + const lines = source.text.replace(/\r\n/g, "\n").split("\n"); + const changedLines: number[] = []; + for (const [start, end] of ranges) { + for (let line = start; line < end; line++) changedLines.push(line + 1); + } + const spans = []; + for (const leaf of structuralLeaves(source.regions)) { + for (const span of leaf.changed ?? []) { + spans.push({ + startLineNumber: span.line + 1, + startColumn: utf16Column(lines[span.line], span.start_column), + endLineNumber: span.line + 1, + endColumn: utf16Column(lines[span.line], span.end_column), + }); + } + } + // Keep coverage for counts, but reserve token tint for partially changed lines. + const byLine = new Map(); + for (const span of spans) { + const group = byLine.get(span.startLineNumber) ?? []; + group.push(span); + byLine.set(span.startLineNumber, group); + } + const fullyNovel = new Set(); + for (const [line, group] of byLine) { + let end = 0; + let unchanged = ""; + for (const span of group.sort((a, b) => a.startColumn - b.startColumn)) { + unchanged += lines[line - 1].slice(end, Math.max(end, span.startColumn - 1)); + end = Math.max(end, span.endColumn - 1); + } + unchanged += lines[line - 1].slice(end); + if (!unchanged.trim()) fullyNovel.add(line); + } + return { spans: spans.filter(span => !fullyNovel.has(span.startLineNumber)), lines: changedLines }; + } + const original = side(diff.lhs, diff.structural_changes.base); + const modified = side(diff.rhs, diff.structural_changes.head); + return { + original: original.spans, + modified: modified.spans, + originalLines: original.lines, + modifiedLines: modified.lines, + }; +} + +/** Tags are `:`; several plugins capture docstrings, each under its own prefix. */ +const isDocstring = (region: StructuralRegion) => region.tags?.some((tag) => tag.slice(tag.lastIndexOf(":") + 1) === "docstring") === true; + +/** A hidden band on one or both sides, one-based like Monaco's diff editor. */ +export interface StructuralGap { + originalStart: number; + modifiedStart: number; + originalCount: number; + modifiedCount: number; + label: string; + /** What the band hides: unchanged context, or lines that exist on one side only. */ + owner: "base" | "head" | "both"; + change: "unchanged" | "inserted" | "removed" | "modified"; + /** False for a region the reader revealed: it stays a band the editor can fold again. */ + collapsed: boolean; + /** The fold-state id of the region(s) this band hides; toggling the band toggles it. */ + foldStateId: number; + /** Label precedence: head first, then base. */ + regionIds: readonly number[]; + /** False for a bundled docstring: its band shows the bare count, no symbol names. */ + breadcrumbs: boolean; +} + +/** + * The text a band shows under its title. diffr prepends a ` pseudocode` + * line to a summary for terminals; the app has its own caption, so that line + * is dropped here. A one-line label has no detail. + */ +export function bandDetail(label: string): string { + const lines = label.split("\n"); + if (lines.length < 2) return ""; + const body = /^(\/\/|#|--|;|%)\s*pseudocode$/.test(lines[0].trim()) ? lines.slice(1) : lines; + return body.join("\n"); +} + +/** + * The lines a collapsed region hides on its side, zero-based half-open: every + * line it covers, fold or leaf. A fold covers its body alone — the line that + * opens the construct is the last line of the leaf before it — so a band + * hides exactly the fold's range, and the signature above it stays a row. + */ +export function hiddenLinesOf(region: StructuralRegion): { start: number; end: number } { + return regionLines(region); +} + +/** Collapsed regions of one side, outermost first; a collapsed descendant of a collapsed region is subsumed. `isCollapsed` answers for a fold-state id. */ +export function collapsedRegions( + regions: readonly StructuralRegion[] | undefined, + isCollapsed: (foldStateId: number) => boolean, +): StructuralRegion[] { + return knownRegions(regions, (id) => (isCollapsed(id) ? true : undefined)).map((r) => r.region); +} + +/** + * Regions of one side the state knows about, outermost first: collapsed ones + * and ones a reader revealed. A collapsed region subsumes its descendants; a + * revealed one still lists them, since a child may be collapsed on its own. + */ +export function knownRegions( + regions: readonly StructuralRegion[] | undefined, + state: (foldStateId: number) => boolean | undefined, +): { region: StructuralRegion; collapsed: boolean }[] { + const result: { region: StructuralRegion; collapsed: boolean }[] = []; + const walk = (region: StructuralRegion) => { + const known = state(region.fold_state_id); + const hides = hiddenLinesOf(region).end > hiddenLinesOf(region).start; + if (known === true) { + if (hides) result.push({ region, collapsed: true }); + return; + } + // Open, but a band by the wire's default: a reader revealed it, and the editor can fold it again. + if (known === false && hides && region.visibility?.collapsed === true) result.push({ region, collapsed: false }); + if (region.kind === "fold") for (const child of region.children) walk(child); + }; + for (const region of regions ?? []) walk(region); + return result; +} + +/** + * Every collapsed region as a diff-editor band. A region collapsed on both + * sides becomes one band: a leaf with the leaf sharing its `alignment_id`, a + * fold with the fold sharing its `fold_state_id` (a docstring only with a + * docstring, since a docstring shares its body's fold state). A region on one side only + * becomes a band on that side; the other side's range starts right after the + * row that precedes the region and covers only the opposite lines the zip put + * inside the region's rows, none when those rows are filler. + */ +export function structuralContextGaps( + diff: StructuralTextDiff, + isCollapsed: (foldStateId: number) => boolean, + state: (foldStateId: number) => boolean | undefined = (id) => (isCollapsed(id) ? true : undefined), +): StructuralGap[] { + const rows = structuralRows(diff); + const rowOfLeft = new Map(), rowOfRight = new Map(); + rows.forEach(([l, r], index) => { + if (l !== null) rowOfLeft.set(l, index); + if (r !== null) rowOfRight.set(r, index); + }); + // One-based start and count of the opposite range for lines hidden on `side`. Rows are monotone, so + // the opposite lines inside the region's rows follow the opposite line of the row before it. + const oppositeSpan = (side: 0 | 1, hidden: { start: number; end: number }): { start: number; count: number } => { + const other = side === 0 ? 1 : 0; + const rowOf = side === 0 ? rowOfLeft : rowOfRight; + const first = rowOf.get(hidden.start)!, last = rowOf.get(hidden.end - 1)!; + let before = -1; + for (let index = first - 1; index >= 0 && before === -1; index--) before = rows[index][other] ?? -1; + let count = 0; + for (let index = first; index <= last; index++) if (rows[index][other] !== null) count++; + return { start: before + 2, count }; + }; + const lhs = knownRegions(diff.lhs?.regions, state); + const rhs = knownRegions(diff.rhs?.regions, state); + // Leaves pair by alignment; folds pair by fold state, the only identity they share across sides. + const usedRhs = new Set(); + const pairs = (left: StructuralRegion, right: StructuralRegion) => { + if (left.kind === "leaf") return right.kind === "leaf" && right.alignment_id === left.alignment_id; + return right.kind === "fold" && right.fold_state_id === left.fold_state_id && isDocstring(right) === isDocstring(left); + }; + const counterpart = (left: StructuralRegion) => + rhs.find(({ region: right }) => !usedRhs.has(right) && pairs(left, right)); + const gaps: StructuralGap[] = []; + for (const { region: left, collapsed } of lhs) { + const hidden = hiddenLinesOf(left); + const partner = counterpart(left); + if (partner) { + usedRhs.add(partner.region); + const right = hiddenLinesOf(partner.region); + gaps.push({ + originalStart: hidden.start + 1, originalCount: hidden.end - hidden.start, + modifiedStart: right.start + 1, modifiedCount: right.end - right.start, + label: partner.region.visibility?.label || left.visibility?.label || "", + owner: "both", change: "unchanged", + collapsed: collapsed && partner.collapsed, + foldStateId: left.fold_state_id, regionIds: [partner.region.id, left.id], + breadcrumbs: !isDocstring(left) && !isDocstring(partner.region), + }); + continue; + } + const opposite = oppositeSpan(0, hidden); + gaps.push({ + originalStart: hidden.start + 1, originalCount: hidden.end - hidden.start, + modifiedStart: opposite.start, modifiedCount: opposite.count, + label: left.visibility?.label || "", owner: "base", change: "unchanged", collapsed, foldStateId: left.fold_state_id, regionIds: [left.id], + breadcrumbs: !isDocstring(left), + }); + } + for (const { region: right, collapsed } of rhs) { + if (usedRhs.has(right)) continue; + const hidden = hiddenLinesOf(right); + const opposite = oppositeSpan(1, hidden); + gaps.push({ + originalStart: opposite.start, originalCount: opposite.count, + modifiedStart: hidden.start + 1, modifiedCount: hidden.end - hidden.start, + label: right.visibility?.label || "", owner: "head", change: "unchanged", collapsed, foldStateId: right.fold_state_id, regionIds: [right.id], + breadcrumbs: !isDocstring(right), + }); + } + // Ownership says which fold state to toggle, never whether its contents were deleted. + const highlights = structuralHighlights(diff); + const removedLines = new Set(highlights.originalLines), addedLines = new Set(highlights.modifiedLines); + for (const [left, right] of rows) { + if (left !== null && right === null) removedLines.add(left + 1); + if (right !== null && left === null) addedLines.add(right + 1); + } + for (const gap of gaps) { + const removed = [...removedLines].some(line => line >= gap.originalStart && line < gap.originalStart + gap.originalCount); + const added = [...addedLines].some(line => line >= gap.modifiedStart && line < gap.modifiedStart + gap.modifiedCount); + gap.change = removed && added ? "modified" : removed ? "removed" : added ? "inserted" : "unchanged"; + } + gaps.sort((a, b) => (a.modifiedStart - b.modifiedStart) || (a.originalStart - b.originalStart)); + for (const gap of gaps) if (!gap.label) { + const count = Math.max(gap.originalCount, gap.modifiedCount); + gap.label = `${count} hidden line${count === 1 ? "" : "s"}`; + } + return gaps; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewTelemetryRequest.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewTelemetryRequest.test.ts new file mode 100644 index 000000000..c278659f2 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewTelemetryRequest.test.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { reviewTelemetryEventRequest } from "./reviewTelemetryRequest.js"; + +test("builds an authenticated JSON POST for a telemetry event", () => { + const request = reviewTelemetryEventRequest( + { token: "secret", appSessionId: "app-1" }, + { name: "review_presented" }, + ); + assert.equal(request.method, "POST"); + assert.deepEqual(request.headers, { + "content-type": "application/json", + "x-review-token": "secret", + "x-review-app-session-id": "app-1", + }); + assert.deepEqual(JSON.parse(String(request.body)), { name: "review_presented" }); + assert.equal(request.keepalive, false); +}); + +test("keepalive is opt-in", () => { + const request = reviewTelemetryEventRequest( + { token: "secret", appSessionId: "app-1" }, + { name: "x" }, + { keepalive: true }, + ); + assert.equal(request.keepalive, true); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewTelemetryRequest.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewTelemetryRequest.ts new file mode 100644 index 000000000..48cf3b01c --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewTelemetryRequest.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface ReviewTelemetryAuth { + readonly token: string; + readonly appSessionId: string; +} + +/** + * The POST every telemetry sender makes to a Review server `telemetry/event` + * endpoint; callers pick the URL and how the request is dispatched. + */ +export function reviewTelemetryEventRequest( + auth: ReviewTelemetryAuth, + event: unknown, + options: { readonly keepalive?: boolean } = {}, +): RequestInit { + return { + method: "POST", + headers: { + "content-type": "application/json", + "x-review-token": auth.token, + "x-review-app-session-id": auth.appSessionId, + }, + body: JSON.stringify(event), + keepalive: options.keepalive ?? false, + }; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewUpdateNotice.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewUpdateNotice.ts new file mode 100644 index 000000000..fa910772b --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewUpdateNotice.ts @@ -0,0 +1,119 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Decisions behind Review's update toasts, kept free of services so they can be + * tested directly. + * + * Everything here keys off the build's `commit`, never its version. Packaged + * `product.json` carries the Code OSS version (`1.129.1`) for every Review + * release, so it is identical before and after an update and cannot say whether + * one landed. Only `commit` changes. The release semver a human recognises + * ("0.0.7") exists solely in the update feed's `productVersion`, which is why it + * has to be captured from the update payload and stored rather than read back + * off the running product. + */ + +/** A downloaded update, staged and waiting for the restart that applies it. */ +export interface IReviewStagedUpdate { + /** `product.json` `commit` of the build that will be running after restart. */ + readonly targetCommit: string; + /** Release semver, e.g. "0.0.7". Absent if the feed omitted it. */ + readonly productVersion?: string; +} + +export function serializeStagedUpdate(staged: IReviewStagedUpdate): string { + return JSON.stringify(staged); +} + +/** + * Storage is user-writable and survives across versions, so treat anything + * unexpected as absent rather than throwing — this runs during workbench + * startup, where a parse error would be a far worse outcome than a missed toast. + */ +export function parseStagedUpdate(raw: string | undefined): IReviewStagedUpdate | undefined { + if (!raw) { + return undefined; + } + let parsed: unknown; + try { + parsed = JSON.parse(raw); + } catch { + return undefined; + } + if (typeof parsed !== 'object' || parsed === null) { + return undefined; + } + const { targetCommit, productVersion } = parsed as Record; + if (typeof targetCommit !== 'string' || !targetCommit) { + return undefined; + } + return { + targetCommit, + productVersion: typeof productVersion === 'string' && productVersion ? productVersion : undefined, + }; +} + +/** + * `IUpdate.version` is the target commit and `IUpdate.productVersion` the + * release semver — the update Worker documents that split, and the darwin + * service validates both fields separately. + */ +export function stagedUpdateFromReady(update: { version?: string; productVersion?: string } | undefined): IReviewStagedUpdate | undefined { + if (!update?.version) { + return undefined; + } + return { targetCommit: update.version, productVersion: update.productVersion }; +} + +export type ReviewUpdateNotice = + /** Nothing was staged; say nothing. */ + | { readonly kind: 'none' } + /** Something was staged but it is not what is running; drop it silently. */ + | { readonly kind: 'clear' } + /** The staged update is now running; announce it once. */ + | { readonly kind: 'announce'; readonly productVersion?: string }; + +/** + * Whether this launch is the first one after a staged update applied. + * + * A missing `currentCommit` means an unbuilt run, where updates are disabled + * outright — clear rather than announce, so a record left by a packaged build + * cannot produce a bogus toast in a development window. + */ +export function decideUpdateNotice( + staged: IReviewStagedUpdate | undefined, + currentCommit: string | undefined, +): ReviewUpdateNotice { + if (!staged) { + return { kind: 'none' }; + } + if (currentCommit && currentCommit === staged.targetCommit) { + return { kind: 'announce', productVersion: staged.productVersion }; + } + return { kind: 'clear' }; +} + +/** Whether a newly-ready update replaces whatever was staged before it. */ +export function supersedesStagedUpdate( + existing: IReviewStagedUpdate | undefined, + next: IReviewStagedUpdate, +): boolean { + return !existing || existing.targetCommit !== next.targetCommit; +} + +/** + * Whether to prompt for this update. + * + * Skipping is bound to the exact commit, so a later release still prompts. Note + * that skipping only silences the toast: Squirrel still installs the update on + * quit, which is why the staged record is written regardless. + */ +export function shouldPromptForUpdate( + next: IReviewStagedUpdate, + skippedCommit: string | undefined, +): boolean { + return !skippedCommit || skippedCommit !== next.targetCommit; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/common/reviewWorkbenchVisibility.ts b/apps/review-desktop/code-oss/src/vs/review/common/reviewWorkbenchVisibility.ts new file mode 100644 index 000000000..d6553b5e4 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/common/reviewWorkbenchVisibility.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Review hosts Home, review canvases, files, and diffs in one native editor + * group. The upstream agent sessions part stays hidden in this layout. + * + * `explorer` is never persisted. `ReviewExplorerParts` derives it from the + * active editor pane on every change, so the layout always starts it hidden and + * lets that service reassert it once the restored editor is known. + * + * A user *closing* the tree is a separate matter. That is a decision rather than + * derived state, so it has to survive the next tab switch and a reload. + * `ReviewExplorerParts` persists it on its own key (`review.explorer.userClosed`) + * and folds it into the derived value. No part visibility is stored here. + */ +export const initialReviewPartVisibility = { + sidebar: false, + auxiliaryBar: false, + editor: true, + panel: false, + sessions: false, + explorer: false, +} as const; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/terminalEnvironmentSecurity.test.ts b/apps/review-desktop/code-oss/src/vs/review/common/terminalEnvironmentSecurity.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/terminalEnvironmentSecurity.test.ts rename to apps/review-desktop/code-oss/src/vs/review/common/terminalEnvironmentSecurity.test.ts diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/explorer/reviewFileTree.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/explorer/reviewFileTree.contribution.ts new file mode 100644 index 000000000..190ae5d65 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/explorer/reviewFileTree.contribution.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize2 } from '../../../nls.js'; +import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js'; +import { Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; +import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; +import { KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js'; +import { IReviewExplorerPartsService } from '../../browser/parts/explorer/reviewExplorerPart.js'; + +/** + * Closes and reopens the file tree beside a reviewed file. + * + * `Cmd+B` matches VS Code's Toggle Primary Side Bar, and it is taken here on + * purpose. `ToggleSidebarVisibilityAction` in + * `workbench/browser/actions/layoutActions.ts` claims the same chord at + * `WorkbenchContrib`, and Review reaches that file transitively through + * `workbench/browser/workbench.contribution.js`. At equal weight the last rule + * registered wins, which is registration order rather than intent — so this asks + * for one more than `WorkbenchContrib` to win deterministically. + * + * The binding carries no `when` clause on purpose, so the chord can never reach + * the stock action. That action is not merely inert in Review: it flips + * `partVisibility.sidebar`, toggles the layout class, and then calls + * `setViewVisible` on `ReviewWorkbench.sideBarPartView`, which Review never + * assigns. It throws with the layout state already half-changed. So this action + * always takes the key and no-ops itself when there is no tree to toggle, rather + * than declining the key and handing it to something that breaks the window. + */ +class ToggleReviewFileTreeAction extends Action2 { + constructor() { + super({ + id: 'review.toggleFileTree', + title: localize2('review.toggleFileTree', "Review: Toggle File Tree"), + f1: true, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib + 1, + primary: KeyMod.CtrlCmd | KeyCode.KeyB, + }, + }); + } + + override run(accessor: ServicesAccessor): void { + accessor.get(IReviewExplorerPartsService).toggle(); + } +} + +registerAction2(ToggleReviewFileTreeAction); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/extensions/reviewCuratedExtensions.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/extensions/reviewCuratedExtensions.contribution.ts new file mode 100644 index 000000000..f1c787b89 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/extensions/reviewCuratedExtensions.contribution.ts @@ -0,0 +1,737 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize, localize2 } from '../../../nls.js'; +import { Codicon } from '../../../base/common/codicons.js'; +import { getErrorMessage } from '../../../base/common/errors.js'; +import { DisposableStore } from '../../../base/common/lifecycle.js'; +import { isLinux, isMacintosh } from '../../../base/common/platform.js'; +import { ThemeIcon } from '../../../base/common/themables.js'; +import { URI } from '../../../base/common/uri.js'; +import { ipcRenderer } from '../../../base/parts/sandbox/electron-browser/globals.js'; +import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../platform/actions/common/actions.js'; +import { CommandsRegistry, ICommandService } from '../../../platform/commands/common/commands.js'; +import { IConfigurationService, ConfigurationTarget } from '../../../platform/configuration/common/configuration.js'; +import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; +import { ExtensionType, type IExtensionIdentifier } from '../../../platform/extensions/common/extensions.js'; +import { + IExtensionManagementService, + IGlobalExtensionEnablementService, + type ILocalExtension +} from '../../../platform/extensionManagement/common/extensionManagement.js'; +import { areSameExtensions } from '../../../platform/extensionManagement/common/extensionManagementUtil.js'; +import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; +import { IMainProcessService } from '../../../platform/ipc/common/mainProcessService.js'; +import { ILogService } from '../../../platform/log/common/log.js'; +import { INotificationService } from '../../../platform/notification/common/notification.js'; +import { IProgressService, ProgressLocation } from '../../../platform/progress/common/progress.js'; +import { IQuickInputService, type IQuickPickItem } from '../../../platform/quickinput/common/quickInput.js'; +import { Registry } from '../../../platform/registry/common/platform.js'; +import { IStorageService, StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js'; +import { LifecyclePhase } from '../../../workbench/services/lifecycle/common/lifecycle.js'; +import { + Extensions as WorkbenchExtensions, + type IWorkbenchContribution, + type IWorkbenchContributionsRegistry +} from '../../../workbench/common/contributions.js'; +import { REVIEW_KEYMAP_SETTING, type ReviewKeymap } from '../../common/reviewConfigurationDefaults.js'; +import { REVIEW_DESKTOP_CHANNEL } from '../../common/reviewDesktopBootstrap.js'; +import { setFirstRunReloadPending } from '../../common/reviewFirstRunReload.js'; +import type { ReviewUserConfigImportResult } from '../../node/reviewUserConfigImport.js'; +import { IReviewTelemetryService } from '../../services/reviewTelemetryService.js'; +import { reviewOptionalExtensionCatalog } from '../../node/reviewOptionalExtensionCatalog.js'; +import { + installMissingOptionalExtensions, + OptionalExtensionInstallError, + optionalGroupMemberIds, + upgradeOptionalExtensionPins +} from './reviewOptionalExtensionManagement.js'; + +/** + * The curated bundled extensions Review materializes, mirroring + * apps/review-desktop/scripts/curated-extensions.manifest.mjs. A test in + * curated-extensions.test.mjs keeps the two lists in step. + * + * Only bundled extensions that are installed show up as individual rows. + * Optional groups always show so the user can consent to their download. + */ +const BUNDLED_EXTENSIONS: readonly { id: string; label: string }[] = [ + { id: 'ms-python.python', label: localize('review.curated.python', "Python") }, + { id: 'astral-sh.ty', label: localize('review.curated.ty', "Python type checking (ty)") }, + { id: 'charliermarsh.ruff', label: localize('review.curated.ruff', "Python lint and format (ruff)") }, + { id: 'vscodevim.vim', label: localize('review.curated.vim', "Vim keybindings") }, + { id: 'tuttieee.emacs-mcx', label: localize('review.curated.emacs', "Emacs keybindings") } +]; + +const OPTIONAL_GROUPS: readonly { group: string; label: string; detail?: string }[] = [ + { group: 'rust', label: localize('review.curated.rust', "Rust (rust-analyzer)") }, + { group: 'swift', label: localize('review.curated.swift', "Swift") }, + { + group: 'csharp', + label: localize('review.curated.csharp', "C#"), + detail: localize('review.curated.csharp.requiresDotnet', "Requires a system .NET SDK. Review does not download .NET.") + }, + { + group: 'go', + label: localize('review.curated.go', "Go"), + detail: localize('review.curated.go.installsTools', "Downloads the Go extension, which then installs gopls and vscgo with the Go toolchain on your machine (about 40 MB from proxy.golang.org).") + } +] as const; + +const ALL_CURATED_IDS = [ + ...BUNDLED_EXTENSIONS.map(extension => extension.id), + ...reviewOptionalExtensionCatalog.map(extension => extension.id) +]; + +type CuratedQuickPickItem = IQuickPickItem & ( + | { kind: 'bundled'; id: string } + | { kind: 'optional'; group: string } +); + +/** The two keymaps fight over the same keys, so only one may be on at a time. */ +const KEYMAP_EXTENSION_IDS: Readonly, string>> = { + vim: 'vscodevim.vim', + emacs: 'tuttieee.emacs-mcx', +}; +const KEYMAP_IDS = Object.values(KEYMAP_EXTENSION_IDS); + +const SEEDED_STORAGE_KEY = 'review.curatedExtensions.defaultsApplied.v2'; + +type ExtensionEnablementTrigger = 'user' | 'keymap' | 'startup_seed'; + +function isDisabled(disabled: readonly IExtensionIdentifier[], id: string): boolean { + return disabled.some(identifier => areSameExtensions(identifier, { id })); +} + +/** + * Applies the enable/disable choice. Extension enablement only takes effect when + * the extension host restarts, so callers offer a reload afterwards. Takes the + * services rather than a ServicesAccessor: callers reach this after awaits, and + * an accessor is only valid during the synchronous span of its invocation. + */ +export async function setCuratedExtensionsEnabled( + enablementService: IGlobalExtensionEnablementService, + extensionManagementService: IExtensionManagementService, + enabledIds: readonly string[], + reviewTelemetryService: IReviewTelemetryService, + trigger: ExtensionEnablementTrigger = 'user' +): Promise { + const installed = await extensionManagementService.getInstalled(); + const installedCurated = installed.filter(extension => + ALL_CURATED_IDS.some(id => areSameExtensions(extension.identifier, { id })) + ); + let changed = false; + + for (const extension of installedCurated) { + const extensionId = ALL_CURATED_IDS.find(id => areSameExtensions(extension.identifier, { id })); + if (!extensionId) { + continue; + } + let didChange: boolean; + if (enabledIds.some(id => areSameExtensions(extension.identifier, { id }))) { + didChange = await enablementService.enableExtension(extension.identifier); + if (didChange) { + reviewTelemetryService.capture('extension_enabled', { extension_id: extensionId, trigger }); + } + } else { + didChange = await enablementService.disableExtension(extension.identifier); + if (didChange) { + reviewTelemetryService.capture('extension_disabled', { extension_id: extensionId, trigger }); + } + } + changed ||= didChange; + } + return changed; +} + +/** + * Selects a keymap from the Settings tab. + * + * This touches the two keymap extensions only. `setCuratedExtensionsEnabled` + * takes the full enabled list, so passing one keymap id to it would disable + * rust-analyzer, Python, and Go. + * + * The extension enablement moves here rather than at the next launch, because + * CuratedExtensionDefaults reconciles enablement against `review.keymap` on + * startup and would force a surprise reload if the two disagreed. + */ +async function applyReviewKeymap(accessor: ServicesAccessor, keymap: ReviewKeymap): Promise { + const configurationService = accessor.get(IConfigurationService); + const enablementService = accessor.get(IGlobalExtensionEnablementService); + const commandService = accessor.get(ICommandService); + const dialogService = accessor.get(IDialogService); + const reviewTelemetryService = accessor.get(IReviewTelemetryService); + + if (configurationService.getValue(REVIEW_KEYMAP_SETTING) === keymap) { + return; + } + await configurationService.updateValue(REVIEW_KEYMAP_SETTING, keymap, ConfigurationTarget.USER); + + let changed = false; + for (const [candidate, id] of Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) { + const didChange = candidate === keymap + ? await enablementService.enableExtension({ id }) + : await enablementService.disableExtension({ id }); + if (didChange) { + reviewTelemetryService.capture(candidate === keymap ? 'extension_enabled' : 'extension_disabled', { + extension_id: id, + trigger: 'keymap' + }); + } + changed ||= didChange; + } + if (!changed) { + return; + } + + // The caller may be a page the user is still reading, so offer the reload + // rather than force it. + const reload = await dialogService.confirm({ + type: 'info', + message: localize('review.keymap.reload', "Reload Review to apply the keymap?"), + detail: localize('review.keymap.reloadDetail', "Keymap extensions only take effect after the extension host restarts."), + primaryButton: localize('review.keymap.reloadNow', "&&Reload"), + cancelButton: localize('review.keymap.reloadLater', "Later"), + }); + if (reload.confirmed) { + await reviewTelemetryService.flush(); + await commandService.executeCommand('workbench.action.reloadWindow'); + } +} + +CommandsRegistry.registerCommand('review.setKeymap', (accessor, keymap: ReviewKeymap) => + applyReviewKeymap(accessor, keymap) +); + +function findInstalled(installed: readonly ILocalExtension[], id: string): ILocalExtension | undefined { + return installed.find(extension => areSameExtensions(extension.identifier, { id })); +} + +function optionalDownloadSize(group: string, installed: readonly ILocalExtension[]): number { + const target = isMacintosh ? 'darwin-arm64' : isLinux ? 'linux-x64' : undefined; + return reviewOptionalExtensionCatalog + .filter(extension => extension.group === group && !findInstalled(installed, extension.id)) + .reduce((total, extension) => { + const targets = extension.targets as Readonly>; + const pin = targets['universal'] ?? (target ? targets[target] : undefined); + return total + (pin?.size ?? 0); + }, 0); +} + +function formatDownloadSize(bytes: number): string { + return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; +} + +function optionalExtensionLabel(extensionId: string): string { + const extension = reviewOptionalExtensionCatalog.find(candidate => candidate.id === extensionId); + const group = extension && OPTIONAL_GROUPS.find(candidate => candidate.group === extension.group); + if (!extension || !group) { + return extensionId; + } + return extension.role === 'support' + ? localize('review.curated.extensionSupport', "{0} support", group.label) + : group.label; +} + +async function stageRustAnalyzer( + mainProcessService: IMainProcessService, + logService: ILogService +): Promise { + try { + await mainProcessService.getChannel(REVIEW_DESKTOP_CHANNEL).call('stageRustAnalyzer'); + } catch (error) { + logService.error(`[Review extensions] Could not stage rust-analyzer: ${getErrorMessage(error)}`); + } +} + +class ManageCuratedExtensionsAction extends Action2 { + constructor() { + super({ + id: 'review.manageExtensions', + title: localize2('review.manageExtensions', "Manage Extensions..."), + f1: true + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const quickInputService = accessor.get(IQuickInputService); + const extensionManagementService = accessor.get(IExtensionManagementService); + const enablementService = accessor.get(IGlobalExtensionEnablementService); + const commandService = accessor.get(ICommandService); + const configurationService = accessor.get(IConfigurationService); + const dialogService = accessor.get(IDialogService); + const notificationService = accessor.get(INotificationService); + const progressService = accessor.get(IProgressService); + const mainProcessService = accessor.get(IMainProcessService); + const logService = accessor.get(ILogService); + const reviewTelemetryService = accessor.get(IReviewTelemetryService); + + let installed = await extensionManagementService.getInstalled(); + + const disabled = enablementService.getDisabledExtensions(); + const items: CuratedQuickPickItem[] = BUNDLED_EXTENSIONS + .filter(curated => findInstalled(installed, curated.id)) + .map(curated => ({ + kind: 'bundled', + id: curated.id, + label: curated.label, + description: curated.id, + picked: !isDisabled(disabled, curated.id) + })); + for (const optionalGroup of OPTIONAL_GROUPS) { + const members = optionalGroupMemberIds(optionalGroup.group); + const installedMembers = members + .map(id => findInstalled(installed, id)) + .filter((extension): extension is ILocalExtension => Boolean(extension)); + const primary = reviewOptionalExtensionCatalog.find(extension => + extension.group === optionalGroup.group && extension.role === 'primary' + ); + const downloadSize = optionalDownloadSize(optionalGroup.group, installed); + const userMembers = installedMembers.filter(extension => extension.type === ExtensionType.User); + items.push({ + kind: 'optional', + group: optionalGroup.group, + label: optionalGroup.label, + description: downloadSize > 0 + ? localize('review.curated.downloadSize', "Download {0}", formatDownloadSize(downloadSize)) + : localize('review.curated.installed', "Installed"), + detail: optionalGroup.detail, + picked: Boolean(primary && findInstalled(installed, primary.id)) && + installedMembers.every(extension => !isDisabled(disabled, extension.identifier.id)), + buttons: userMembers.length > 0 ? [{ + iconClass: ThemeIcon.asClassName(Codicon.trash), + tooltip: localize('review.curated.uninstall', "Uninstall this optional language group") + }] : undefined + }); + } + + const installedBefore = new Set(installed.map(extension => extension.identifier.id.toLowerCase())); + const initiallySelected = new Set(items.filter(item => item.picked).map(item => item)); + const picked = await new Promise(resolve => { + const disposables = new DisposableStore(); + const quickPick = disposables.add(quickInputService.createQuickPick()); + let accepted: readonly CuratedQuickPickItem[] | undefined; + + quickPick.canSelectMany = true; + quickPick.title = localize('review.curated.title', "Manage Extensions"); + quickPick.placeholder = localize('review.curated.placeholder', "Select language groups to download, install, or enable"); + quickPick.items = items; + quickPick.selectedItems = items.filter(item => item.picked); + + const updateAcceptLabel = (selected: readonly CuratedQuickPickItem[]): void => { + const selectedSet = new Set(selected); + const selectedGroups = new Set(selected + .filter((item): item is CuratedQuickPickItem & { kind: 'optional' } => item.kind === 'optional') + .map(item => item.group)); + const installCount = reviewOptionalExtensionCatalog.filter(extension => + selectedGroups.has(extension.group) && !installedBefore.has(extension.id.toLowerCase()) + ).length; + const hasOtherChanges = items.some(item => { + if (initiallySelected.has(item) === selectedSet.has(item)) { + return false; + } + return item.kind !== 'optional' || !selectedSet.has(item) || + !reviewOptionalExtensionCatalog.some(extension => + extension.group === item.group && !installedBefore.has(extension.id.toLowerCase()) + ); + }); + + quickPick.okLabel = installCount > 0 && !hasOtherChanges + ? installCount === 1 + ? localize('review.curated.installOneExtension', "Install 1 extension") + : localize('review.curated.installManyExtensions', "Install {0} extensions", installCount) + : localize('review.curated.saveExtensions', "Save"); + }; + + updateAcceptLabel(quickPick.selectedItems); + disposables.add(quickPick.onDidChangeSelection(updateAcceptLabel)); + disposables.add(quickPick.onDidAccept(() => { + accepted = quickPick.selectedItems.slice(); + quickPick.hide(); + })); + disposables.add(quickPick.onDidTriggerItemButton(context => { + if (context.item.kind !== 'optional') { + return; + } + const item = context.item; + void (async () => { + const confirmation = await dialogService.confirm({ + type: 'warning', + message: localize('review.curated.confirmUninstall', "Uninstall {0}?", item.label), + detail: localize('review.curated.confirmUninstallDetail', "Review will remove all user-installed members of this language group."), + primaryButton: localize('review.curated.uninstallNow', "&&Uninstall") + }); + if (!confirmation.confirmed) { + return; + } + try { + const members = optionalGroupMemberIds(item.group); + const userMembers = (await extensionManagementService.getInstalled(ExtensionType.User)) + .filter(extension => members.some(id => areSameExtensions(extension.identifier, { id }))); + for (const extension of userMembers) { + await extensionManagementService.uninstall(extension, { + donotIncludePack: true, + donotCheckDependents: true + }); + const extensionId = ALL_CURATED_IDS.find(id => areSameExtensions(extension.identifier, { id })); + if (extensionId) { + reviewTelemetryService.capture('extension_uninstalled', { + extension_id: extensionId, + trigger: 'user' + }); + } + } + if (userMembers.length > 0) { + await reviewTelemetryService.flush(); + await commandService.executeCommand('workbench.action.reloadWindow'); + } + } catch (error) { + notificationService.error(localize( + 'review.curated.uninstallFailed', + "Review could not uninstall the optional extension group: {0}", + getErrorMessage(error) + )); + } + })(); + })); + disposables.add(quickPick.onDidHide(() => { + resolve(accepted); + disposables.dispose(); + })); + quickPick.show(); + }); + if (!picked) { + return; + } + + const selectedOptionalGroups = picked + .filter((item): item is CuratedQuickPickItem & { kind: 'optional' } => item.kind === 'optional') + .map(item => item.group); + let newInstalls: readonly ILocalExtension[]; + try { + newInstalls = await progressService.withProgress({ + location: ProgressLocation.Notification, + title: localize('review.curated.installingLanguageSupport', "Adding language support..."), + delay: 0 + }, progress => installMissingOptionalExtensions({ + groups: selectedOptionalGroups, + installedIds: installedBefore, + download: async extensionId => { + progress.report({ + message: localize( + 'review.curated.downloadingExtension', + "Downloading {0}...", + optionalExtensionLabel(extensionId) + ) + }); + return ipcRenderer.invoke( + 'vscode:reviewDownloadOptionalExtension', + extensionId + ) as Promise; + }, + install: async (extensionId, vsixPath) => { + progress.report({ + message: localize( + 'review.curated.installingExtension', + "Installing {0}...", + optionalExtensionLabel(extensionId) + ) + }); + return extensionManagementService.install(URI.file(vsixPath), { + donotIncludePackAndDependencies: true, + installGivenVersion: true, + pinned: true + }); + }, + rollback: extension => extensionManagementService.uninstall(extension, { + donotIncludePack: true, + donotCheckDependents: true + }), + onInstalled: (extensionId, trigger, durationMs) => { + reviewTelemetryService.capture('extension_installed', { + extension_id: extensionId, + trigger, + duration_ms: durationMs + }); + }, + onInstallFailed: (extensionId, trigger, phase) => { + reviewTelemetryService.capture('extension_install_failed', { + extension_id: extensionId, + trigger, + phase + }); + }, + onRolledBack: extensionId => { + reviewTelemetryService.capture('extension_uninstalled', { + extension_id: extensionId, + trigger: 'rollback' + }); + } + }, 'user')); + } catch (error) { + if (error instanceof OptionalExtensionInstallError) { + for (const rollbackError of error.rollbackErrors) { + notificationService.error(localize( + 'review.curated.rollbackFailed', + "Review could not roll back an optional extension: {0}", + getErrorMessage(rollbackError) + )); + } + const message = error.phase === 'download' + ? localize('review.curated.downloadFailed', "Review could not download an optional extension: {0}", getErrorMessage(error.originalError)) + : localize('review.curated.installFailed', "Review could not install an optional extension: {0}", getErrorMessage(error.originalError)); + notificationService.error(message); + } else { + notificationService.error(getErrorMessage(error)); + } + return; + } + + installed = await extensionManagementService.getInstalled(); + if (newInstalls.some(extension => areSameExtensions(extension.identifier, { id: 'rust-lang.rust-analyzer' }))) { + await stageRustAnalyzer(mainProcessService, logService); + } + let enabledIds = picked + .filter((item): item is CuratedQuickPickItem & { kind: 'bundled' } => item.kind === 'bundled') + .map(item => item.id); + for (const group of selectedOptionalGroups) { + enabledIds.push(...optionalGroupMemberIds(group)); + } + const pickedKeymaps = enabledIds.filter(id => KEYMAP_IDS.includes(id)); + if (pickedKeymaps.length > 1) { + // Keep the one that was off before, i.e. the one being turned on now. + const newlyEnabled = pickedKeymaps.find(id => isDisabled(disabled, id)) ?? pickedKeymaps[0]; + enabledIds = enabledIds.filter(id => !KEYMAP_IDS.includes(id) || id === newlyEnabled); + } + + const keymap = (Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) + .find(([, id]) => enabledIds.includes(id))?.[0] ?? 'none'; + const enablementChanged = await setCuratedExtensionsEnabled( + enablementService, + extensionManagementService, + enabledIds, + reviewTelemetryService, + 'user' + ); + const keymapChanged = configurationService.getValue(REVIEW_KEYMAP_SETTING) !== keymap; + if (keymapChanged) { + await configurationService.updateValue(REVIEW_KEYMAP_SETTING, keymap, ConfigurationTarget.USER); + } + if (newInstalls.length > 0 || enablementChanged || keymapChanged) { + await reviewTelemetryService.flush(); + await commandService.executeCommand('workbench.action.reloadWindow'); + } + } +} + +registerAction2(ManageCuratedExtensionsAction); + +class ImportUserConfigAction extends Action2 { + constructor() { + super({ + id: 'review.importUserConfig', + title: localize2('review.importUserConfig', "Review: Import VS Code Settings and Keybindings..."), + f1: true, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const dialogService = accessor.get(IDialogService); + const commandService = accessor.get(ICommandService); + + try { + const preview = await ipcRenderer.invoke( + 'vscode:reviewImportUserConfig', + { mode: 'preview' }, + ) as ReviewUserConfigImportResult; + if (preview.status === 'disabled') { + await dialogService.info( + localize('review.importUserConfig.disabled', "VS Code settings import is disabled."), + localize('review.importUserConfig.disabledDetail', "Unset DEV_REVIEW_IMPORT_FROM=none and restart Review to enable imports."), + ); + return; + } + if (preview.status === 'not-found' || !preview.source) { + await dialogService.info( + localize('review.importUserConfig.notFound', "No VS Code settings were found."), + localize('review.importUserConfig.notFoundDetail', "Review checks Code, Code - Insiders, VSCodium, and Cursor's default profiles."), + ); + return; + } + + const overwriteDetail = preview.wouldOverwrite.length > 0 + ? localize( + 'review.importUserConfig.overwriteDetail', + "The following Review files will be overwritten:\n{0}", + preview.wouldOverwrite.join('\n'), + ) + : localize( + 'review.importUserConfig.createDetail', + "Review will create settings files under its user profile. Source:\n{0}", + preview.source, + ); + const confirmation = await dialogService.confirm({ + type: 'warning', + message: localize('review.importUserConfig.confirm', "Import VS Code settings and keybindings?"), + detail: overwriteDetail, + primaryButton: localize('review.importUserConfig.import', "Import"), + }); + if (!confirmation.confirmed) { + return; + } + + const result = await ipcRenderer.invoke( + 'vscode:reviewImportUserConfig', + { mode: 'apply' }, + ) as ReviewUserConfigImportResult; + if (result.status !== 'imported') { + throw new Error(`Unexpected Review user-config import result: ${result.status}`); + } + + const reload = await dialogService.confirm({ + type: 'info', + message: localize('review.importUserConfig.complete', "VS Code settings and keybindings were imported."), + detail: localize('review.importUserConfig.reloadDetail', "Reload Review to apply keybindings and keymap extension changes."), + primaryButton: localize('review.importUserConfig.reload', "Reload"), + }); + if (reload.confirmed) { + await commandService.executeCommand('workbench.action.reloadWindow'); + } + } catch (error) { + await dialogService.error( + localize('review.importUserConfig.error', "Review could not import VS Code settings and keybindings."), + String(error), + ); + } + } +} + +registerAction2(ImportUserConfigAction); + +MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { + command: { + id: 'review.manageExtensions', + title: localize('review.manageExtensions.menu', "Manage Extensions...") + }, + order: 1 +}); + +/** + * Seeds the shipped keymap defaults once per profile. An imported review.keymap + * selects Vim or Emacs; otherwise both remain off. After that the user's choice + * in the picker wins. + */ +class CuratedExtensionDefaults implements IWorkbenchContribution { + constructor( + @IStorageService storageService: IStorageService, + @IGlobalExtensionEnablementService enablementService: IGlobalExtensionEnablementService, + @IConfigurationService configurationService: IConfigurationService, + @ICommandService commandService: ICommandService, + @IReviewTelemetryService reviewTelemetryService: IReviewTelemetryService, + ) { + const alreadySeeded = storageService.getBoolean(SEEDED_STORAGE_KEY, StorageScope.APPLICATION, false); + const keymap = configurationService.getValue(REVIEW_KEYMAP_SETTING); + const disabled = enablementService.getDisabledExtensions(); + const keymapStateMatches = (Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) + .every(([candidate, id]) => isDisabled(disabled, id) === (candidate !== keymap)); + // `applyKeymapDefault` reloads only when it actually flips an extension, which is + // exactly when the disabled set does not match the keymap yet. Record that now so + // first-run prompts skip themselves instead of being eaten by the reload. + setFirstRunReloadPending(!keymapStateMatches); + if (alreadySeeded && keymapStateMatches) { + return; + } + if (!alreadySeeded) { + storageService.store(SEEDED_STORAGE_KEY, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + } + void this.applyKeymapDefault(keymap, enablementService, commandService, reviewTelemetryService); + } + + private async applyKeymapDefault( + keymap: ReviewKeymap, + enablementService: IGlobalExtensionEnablementService, + commandService: ICommandService, + reviewTelemetryService: IReviewTelemetryService, + ): Promise { + let changed = false; + for (const [candidate, id] of Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) { + const didChange = candidate === keymap + ? await enablementService.enableExtension({ id }) + : await enablementService.disableExtension({ id }); + if (didChange) { + reviewTelemetryService.capture(candidate === keymap ? 'extension_enabled' : 'extension_disabled', { + extension_id: id, + trigger: 'startup_seed' + }); + } + changed ||= didChange; + } + if (changed) { + await reviewTelemetryService.flush(); + await commandService.executeCommand('workbench.action.reloadWindow'); + } + } +} + +class OptionalExtensionPinUpgrades implements IWorkbenchContribution { + constructor( + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, + @IMainProcessService private readonly mainProcessService: IMainProcessService, + @ILogService private readonly logService: ILogService, + @IReviewTelemetryService private readonly reviewTelemetryService: IReviewTelemetryService + ) { + void this.run().catch(error => { + this.logService.error(`[Review extensions] Could not check optional extension pins: ${getErrorMessage(error)}`); + }); + } + + private async run(): Promise { + const installed = await this.extensionManagementService.getInstalled(ExtensionType.User); + await upgradeOptionalExtensionPins({ + installed: installed.map(extension => ({ + id: extension.identifier.id, + version: extension.manifest.version + })), + download: extensionId => ipcRenderer.invoke( + 'vscode:reviewDownloadOptionalExtension', + extensionId + ) as Promise, + install: async (_extensionId, vsixPath) => { + await this.extensionManagementService.install(URI.file(vsixPath), { + donotIncludePackAndDependencies: true, + installGivenVersion: true, + pinned: true + }); + }, + stageRustAnalyzer: () => stageRustAnalyzer(this.mainProcessService, this.logService), + logError: (message, error) => { + this.logService.error(`[Review extensions] ${message}: ${getErrorMessage(error)}`); + }, + onInstalled: (extensionId, trigger, durationMs) => { + this.reviewTelemetryService.capture('extension_installed', { + extension_id: extensionId, + trigger, + duration_ms: durationMs + }); + }, + onInstallFailed: (extensionId, trigger, phase) => { + this.reviewTelemetryService.capture('extension_install_failed', { + extension_id: extensionId, + trigger, + phase + }); + } + }, 'auto_upgrade'); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( + CuratedExtensionDefaults, + LifecyclePhase.Restored +); +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( + OptionalExtensionPinUpgrades, + LifecyclePhase.Eventually +); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/extensions/reviewOptionalExtensionManagement.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/extensions/reviewOptionalExtensionManagement.ts new file mode 100644 index 000000000..66d7e5061 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/extensions/reviewOptionalExtensionManagement.ts @@ -0,0 +1,171 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { reviewOptionalExtensionCatalog } from '../../node/reviewOptionalExtensionCatalog.js'; +import * as semver from '../../../base/common/semver/semver.js'; + +export type OptionalExtensionInstallPhase = 'download' | 'install'; +export type OptionalExtensionInstallTrigger = 'user' | 'auto_upgrade'; + +export class OptionalExtensionInstallError extends Error { + constructor( + readonly phase: OptionalExtensionInstallPhase, + readonly extensionId: string, + readonly originalError: unknown, + readonly rollbackErrors: readonly unknown[] = [] + ) { + super(`Optional extension ${phase} failed`); + } +} + +export interface OptionalExtensionInstallCallbacks { + readonly onInstalled?: (extensionId: string, trigger: OptionalExtensionInstallTrigger, durationMs: number) => void; + readonly onInstallFailed?: (extensionId: string, trigger: OptionalExtensionInstallTrigger, phase: OptionalExtensionInstallPhase) => void; +} + +export interface OptionalExtensionInstallTransaction extends OptionalExtensionInstallCallbacks { + readonly groups: readonly string[]; + readonly installedIds: ReadonlySet; + readonly download: (extensionId: string) => Promise; + readonly install: (extensionId: string, vsixPath: string) => Promise; + readonly rollback: (installed: T) => Promise; + readonly onRolledBack?: (extensionId: string) => void; +} + +/** Support extensions install before the primary extension that activates them. */ +function compareOptionalExtensionInstallOrder( + left: { readonly role: string }, + right: { readonly role: string } +): number { + if (left.role === right.role) { + return 0; + } + return left.role === 'support' ? -1 : 1; +} + +export async function installMissingOptionalExtensions( + transaction: OptionalExtensionInstallTransaction, + trigger: OptionalExtensionInstallTrigger = 'user' +): Promise { + const requestedGroups = new Set(transaction.groups); + const missing = reviewOptionalExtensionCatalog.filter(extension => + requestedGroups.has(extension.group) && !transaction.installedIds.has(extension.id) + ); + if (missing.length === 0) { + return []; + } + + const downloads = new Map(); + const startedAt = new Map(); + await Promise.all(missing.map(async extension => { + startedAt.set(extension.id, Date.now()); + try { + downloads.set(extension.id, await transaction.download(extension.id)); + } catch (error) { + transaction.onInstallFailed?.(extension.id, trigger, 'download'); + throw new OptionalExtensionInstallError('download', extension.id, error); + } + })); + + const installed: { readonly extensionId: string; readonly local: T }[] = []; + const installOrder = [...missing].sort(compareOptionalExtensionInstallOrder); + try { + for (const extension of installOrder) { + const vsixPath = downloads.get(extension.id); + if (!vsixPath) { + throw new Error(`Missing verified VSIX path for ${extension.id}`); + } + try { + const local = await transaction.install(extension.id, vsixPath); + installed.push({ extensionId: extension.id, local }); + transaction.onInstalled?.(extension.id, trigger, Date.now() - (startedAt.get(extension.id) ?? Date.now())); + } catch (error) { + transaction.onInstallFailed?.(extension.id, trigger, 'install'); + throw new OptionalExtensionInstallError('install', extension.id, error); + } + } + return installed.map(entry => entry.local); + } catch (error) { + const rollbackErrors: unknown[] = []; + for (const entry of installed.reverse()) { + try { + await transaction.rollback(entry.local); + transaction.onRolledBack?.(entry.extensionId); + } catch (rollbackError) { + rollbackErrors.push(rollbackError); + } + } + if (error instanceof OptionalExtensionInstallError) { + throw new OptionalExtensionInstallError(error.phase, error.extensionId, error.originalError, rollbackErrors); + } + throw error; + } +} + +export function optionalGroupMemberIds(group: string): readonly string[] { + return reviewOptionalExtensionCatalog + .filter(extension => extension.group === group) + .map(extension => extension.id); +} + +export interface InstalledOptionalExtensionPin { + readonly id: string; + readonly version: string; +} + +export interface OptionalExtensionPinUpgradeTransaction extends OptionalExtensionInstallCallbacks { + readonly installed: readonly InstalledOptionalExtensionPin[]; + readonly download: (extensionId: string) => Promise; + readonly install: (extensionId: string, vsixPath: string) => Promise; + readonly stageRustAnalyzer: () => Promise; + readonly logError: (message: string, error: unknown) => void; +} + +export async function upgradeOptionalExtensionPins( + transaction: OptionalExtensionPinUpgradeTransaction, + trigger: OptionalExtensionInstallTrigger = 'auto_upgrade' +): Promise { + const installed = new Map(transaction.installed.map(extension => [extension.id.toLowerCase(), extension.version])); + const changed: string[] = []; + for (const group of new Set(reviewOptionalExtensionCatalog.map(extension => extension.group))) { + const primary = reviewOptionalExtensionCatalog.find(extension => extension.group === group && extension.role === 'primary'); + if (!primary || !installed.has(primary.id)) { + continue; + } + + const members = reviewOptionalExtensionCatalog + .filter(extension => extension.group === group) + .sort(compareOptionalExtensionInstallOrder); + for (const extension of members) { + const currentVersion = installed.get(extension.id); + if (currentVersion && !semver.lt(currentVersion, extension.version)) { + continue; + } + const startedAt = Date.now(); + let vsixPath: string; + try { + vsixPath = await transaction.download(extension.id); + } catch (error) { + transaction.onInstallFailed?.(extension.id, trigger, 'download'); + transaction.logError(`Could not update optional extension ${extension.id}`, error); + break; + } + try { + await transaction.install(extension.id, vsixPath); + installed.set(extension.id, extension.version); + changed.push(extension.id); + transaction.onInstalled?.(extension.id, trigger, Date.now() - startedAt); + if (extension.id === 'rust-lang.rust-analyzer') { + await transaction.stageRustAnalyzer(); + } + } catch (error) { + transaction.onInstallFailed?.(extension.id, trigger, 'install'); + transaction.logError(`Could not update optional extension ${extension.id}`, error); + break; + } + } + } + return changed; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/install/reviewCliInstall.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/install/reviewCliInstall.contribution.ts new file mode 100644 index 000000000..581d31766 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/install/reviewCliInstall.contribution.ts @@ -0,0 +1,338 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { isCancellationError } from "../../../base/common/errors.js"; +import { isLinux, isMacintosh } from "../../../base/common/platform.js"; +import { localize, localize2 } from "../../../nls.js"; +import { Action2, registerAction2 } from "../../../platform/actions/common/actions.js"; +import { IDialogService } from "../../../platform/dialogs/common/dialogs.js"; +import type { ServicesAccessor } from "../../../platform/instantiation/common/instantiation.js"; +import { INativeHostService } from "../../../platform/native/common/native.js"; +import { INotificationService } from "../../../platform/notification/common/notification.js"; +import { Registry } from "../../../platform/registry/common/platform.js"; +import { IStorageService, StorageScope } from "../../../platform/storage/common/storage.js"; +import { + Extensions as WorkbenchExtensions, + type IWorkbenchContribution, + type IWorkbenchContributionsRegistry, +} from "../../../workbench/common/contributions.js"; +import { INativeWorkbenchEnvironmentService } from "../../../workbench/services/environment/electron-browser/environmentService.js"; +import { LifecyclePhase } from "../../../workbench/services/lifecycle/common/lifecycle.js"; +import { reviewCliInstallResyncRequest } from "../../common/reviewCliInstall.js"; +import { + type ReviewCliInstallStatus, + type ReviewCliInstallTarget, + REVIEW_TUTORIAL_PROGRESS_STORAGE_KEY, +} from "../../common/reviewProtocol.js"; +import { IReviewCanvasEditorTabsService } from "../../services/reviewCanvasEditorTabsService.js"; +import { IReviewDesktopConnectionService } from "../../services/reviewDesktopConnectionService.js"; + +const TARGET_LABELS: Readonly> = { + claude: "Claude Code", + codex: "Codex", + cursor: "Cursor", + opencode: "OpenCode", + pi: "Pi", +}; + +function formatTargets(targets: readonly ReviewCliInstallTarget[]): string { + return targets.map((target) => TARGET_LABELS[target]).join(", "); +} + +/** + * The macOS app bundle that contains this build, derived from the resources + * path inside it. Development runs live outside a bundle and return undefined. + */ +function macAppBundlePath(appRoot: string): string | undefined { + const marker = appRoot.indexOf(".app/"); + return marker === -1 ? undefined : appRoot.slice(0, marker + ".app".length); +} + +class OpenWelcomeAction extends Action2 { + constructor() { + super({ + id: "review.openWelcome", + title: localize2("review.welcome", "Review: Welcome..."), + f1: true, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + await accessor.get(IReviewCanvasEditorTabsService).openWelcome(true); + } +} + +registerAction2(OpenWelcomeAction); + +class OpenTutorialAction extends Action2 { + constructor() { + super({ + id: "review.openTutorial", + title: localize2("review.openTutorial", "Review: Open Tutorial..."), + f1: true, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const notificationService = accessor.get(INotificationService); + const desktopConnection = accessor.get(IReviewDesktopConnectionService); + const tabsService = accessor.get(IReviewCanvasEditorTabsService); + try { + const opened = await desktopConnection.openTutorial(); + await tabsService.openApiReview(opened.reviewUuid, opened.title); + } catch (error) { + notificationService.error( + localize("review.tutorial.failed", "Review could not open the tutorial: {0}", String(error)), + ); + } + } +} + +registerAction2(OpenTutorialAction); + +class InstallReviewCliInPathAction extends Action2 { + constructor() { + super({ + id: "review.installCliInPath", + title: localize2("review.installCliInPath", "Review: Install CLI in PATH"), + f1: true, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const nativeHostService = accessor.get(INativeHostService); + const notificationService = accessor.get(INotificationService); + const desktopConnection = accessor.get(IReviewDesktopConnectionService); + try { + if (isMacintosh) { + await nativeHostService.uninstallShellCommand({ commandName: "review", symlinkOnly: true }); + } + const installed = await desktopConnection.applyCliInstall({ targets: [], shim: true }); + notificationService.info( + localize( + "review.cliInstall.installed", + "Review installed the CLI at {0}. New terminals can use the review command.", + installed.shimPath ?? "~/.local/bin/review", + ), + ); + } catch (error) { + if (isCancellationError(error)) { + return; + } + notificationService.error( + localize("review.cliInstall.failed", "Review could not install the CLI in PATH: {0}", String(error)), + ); + } + } +} + +registerAction2(InstallReviewCliInPathAction); + +/** + * Removes everything the app installed on this machine: the tutorial, the + * agent skills, the review terminal command, and the consent stamp. It then + * points at the app bundle so the user can move it to the Trash. Other Review + * data stays untouched. Resetting the stamp makes a later reinstall start as + * a first run. + */ +class UninstallReviewDesktopAction extends Action2 { + constructor() { + super({ + id: "review.uninstallApp", + title: localize2("review.uninstallApp", "Review: Uninstall Review Desktop..."), + f1: true, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const dialogService = accessor.get(IDialogService); + const environmentService = accessor.get(INativeWorkbenchEnvironmentService); + const nativeHostService = accessor.get(INativeHostService); + const desktopConnection = accessor.get(IReviewDesktopConnectionService); + const storageService = accessor.get(IStorageService); + + const status = await desktopConnection.getCliInstallStatus(); + const targets = status.agents.filter((agent) => agent.installed).map((agent) => agent.target); + const fffTargets = status.stamp?.fffRegistrations?.map((registration) => registration.target) ?? []; + const removalTargets = [...new Set([...targets, ...fffTargets])]; + const detail = [ + targets.length > 0 + ? localize( + "review.uninstall.skills", + "Removes the Review skills and unchanged app-managed MCP connections for {0}.", + formatTargets(targets), + ) + : localize("review.uninstall.noSkills", "No agent skills are installed."), + status.stamp?.shimPath + ? localize("review.uninstall.shim", "Removes the review terminal command at {0}.", status.stamp.shimPath) + : localize("review.uninstall.noShim", "The review terminal command is not installed."), + fffTargets.length > 0 + ? localize( + "review.uninstall.fff", + "Removes unchanged fff registrations that Review created. The shared FFF binary stays installed.", + ) + : localize("review.uninstall.noFff", "No fff registrations are managed by Review."), + status.stamp?.traceManaged + ? localize( + "review.uninstall.trace", + "Disables trace capture and restores hook paths for known repositories. R2 credentials stay on disk.", + ) + : localize("review.uninstall.noTrace", "Trace capture is not managed by Review."), + localize("review.uninstall.tutorial", "Removes the bundled tutorial repository and Review."), + localize("review.uninstall.keepsData", "Your reviews and their history stay on disk."), + ].join("\n"); + const { confirmed } = await dialogService.confirm({ + message: localize("review.uninstall.confirm", "Remove everything Review Desktop installed on this machine?"), + detail, + primaryButton: localize("review.uninstall.remove", "&&Remove"), + }); + if (!confirmed) { + return; + } + + // The tutorial is disposable state: a failed delete must not stop + // the shim and skills removal the user just confirmed. + let tutorialError: unknown; + try { + await desktopConnection.deleteTutorial(); + storageService.remove(REVIEW_TUTORIAL_PROGRESS_STORAGE_KEY, StorageScope.APPLICATION); + } catch (error) { + tutorialError = error; + } + try { + await desktopConnection.removeCliInstall({ + targets: removalTargets, + shim: true, + fff: true, + ...(status.stamp?.traceManaged ? { trace: true } : {}), + }); + await desktopConnection.resetCliInstallPrompts(); + if (tutorialError) { + await dialogService.error( + localize("review.uninstall.tutorialFailed", "Review could not remove the tutorial data at ~/.dev/tutorial."), + String(tutorialError), + ); + } + } catch (error) { + await dialogService.error( + localize("review.uninstall.failed", "Review could not remove the installed skills and command."), + String(error), + ); + return; + } + + if (isLinux) { + await dialogService.info( + localize("review.uninstall.linuxDone", "Review’s user-installed integrations were removed."), + localize( + "review.uninstall.linuxFinish", + "To remove the app, quit Review and run sudo apt remove dev-fast-review on Ubuntu, or sudo pacman -R dev-fast-review on Omarchy / Arch. Your reviews and settings stay on disk.", + ), + ); + return; + } + + const bundlePath = macAppBundlePath(environmentService.appRoot); + if (bundlePath) { + const { confirmed: reveal } = await dialogService.confirm({ + message: localize("review.uninstall.done", "The installed skills and command were removed."), + detail: localize( + "review.uninstall.finish", + "To finish, quit Review Desktop and move {0} to the Trash.", + bundlePath, + ), + primaryButton: localize("review.uninstall.reveal", "&&Show in Finder"), + cancelButton: localize("review.uninstall.close", "Close"), + }); + if (reveal) { + await nativeHostService.showItemInFolder(bundlePath); + } + } else { + await dialogService.info( + localize("review.uninstall.done", "The installed skills and command were removed."), + localize("review.uninstall.finishDev", "This is a development build, so there is no app bundle to remove."), + ); + } + } +} + +registerAction2(UninstallReviewDesktopAction); + +/** + * First-run onboarding and silent re-sync. Consent lives in the server's + * install stamp (~/.dev/review-desktop/state/cli-install.json), not workbench + * storage, so the CLI and the app read one source of truth: + * - no stamp: open no tab; empty Home renders the Welcome rail, and + * Preferences > Getting Started reaches the same pane when Home has + * reviews to list instead; + * - granted + stale CLI fingerprint or skill version: re-sync silently after an app update; + * - declined or skipped: never open automatically (the menu action stays available). + * + * Dev sessions (`pnpm dev`, isBuilt false) never auto-open. + */ +class ReviewCliInstallStartup implements IWorkbenchContribution { + constructor( + @INativeWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService, + @INotificationService private readonly notificationService: INotificationService, + @IReviewDesktopConnectionService private readonly reviewDesktopConnectionService: IReviewDesktopConnectionService, + ) { + if (!environmentService.isBuilt) { + return; + } + void this.check().catch((error) => { + this.notificationService.warn( + localize( + "review.cliInstall.updateFailed", + "Review could not update its agent skills or CLI: {0}. Retry from Getting Started, or restart Review.", + String(error), + ), + ); + }); + } + + private async check(): Promise { + const status = await this.reviewDesktopConnectionService.getCliInstallStatus(); + if (status.stamp?.consent === "declined") { + return; + } + if (status.stamp?.consent === "skipped") { + return; + } + if (status.stamp?.consent === "granted") { + if (status.stale) { + await this.resync(status); + } + return; + } + // First run needs no tab: with no reviews to list, Home already renders + // the Welcome rail, so opening one here would show it twice. + } + + private async resync(status: ReviewCliInstallStatus): Promise { + const request = reviewCliInstallResyncRequest(status); + if (!request) { + return; + } + await this.reviewDesktopConnectionService.applyCliInstall(request); + const message = + request.targets.length === 0 + ? localize("review.cliInstall.resyncedCli", "Review updated the installed CLI.") + : request.shim + ? localize( + "review.cliInstall.resynced", + "Review updated the CLI, agent skills, and MCP connections. Restart your agent or reconnect MCP to load the changes.", + ) + : localize( + "review.cliInstall.resyncedSkills", + "Review updated the agent skills and MCP connections. Restart your agent or reconnect MCP to load the changes.", + ); + this.notificationService.status(message, { hideAfter: 10_000 }); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( + ReviewCliInstallStartup, + LifecyclePhase.Restored, +); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/quickaccess/reviewQuickAccess.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/quickaccess/reviewQuickAccess.contribution.ts new file mode 100644 index 000000000..b5c9acc70 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/quickaccess/reviewQuickAccess.contribution.ts @@ -0,0 +1,79 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationToken } from '../../../base/common/cancellation.js'; +import { localize } from '../../../nls.js'; +import { MenuRegistry, registerAction2 } from '../../../platform/actions/common/actions.js'; +import { CommandsRegistry, ICommandService } from '../../../platform/commands/common/commands.js'; +import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; +import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; +import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js'; +import { AbstractCommandsQuickAccessProvider, type ICommandQuickPick } from '../../../platform/quickinput/browser/commandsQuickAccess.js'; +import { Extensions, type IQuickAccessRegistry } from '../../../platform/quickinput/common/quickAccess.js'; +import { Registry } from '../../../platform/registry/common/platform.js'; +import { ITelemetryService } from '../../../platform/telemetry/common/telemetry.js'; +import { ShowAllCommandsAction } from '../../../workbench/contrib/quickaccess/browser/commandsQuickAccess.js'; +import { IExtensionService } from '../../../workbench/services/extensions/common/extensions.js'; +import { reviewCommandPaletteLabel } from '../../common/reviewCommandPalette.js'; + +const FOREIGN_COMMAND = /chat|debug|extension|git|keybinding|mcp|notebook|preference|profile|remote|scm|setting|sync|task|terminal|test|update/i; + +export class ReviewCommandsQuickAccessProvider extends AbstractCommandsQuickAccessProvider { + constructor( + @IInstantiationService instantiationService: IInstantiationService, + @IKeybindingService keybindingService: IKeybindingService, + @ICommandService commandService: ICommandService, + @ITelemetryService telemetryService: ITelemetryService, + @IDialogService dialogService: IDialogService, + @IExtensionService private readonly extensionService: IExtensionService, + ) { + super({ showAlias: false }, instantiationService, keybindingService, commandService, telemetryService, dialogService); + } + + protected override async getCommandPicks(token: CancellationToken): Promise { + if (token.isCancellationRequested) return []; + await this.extensionService.whenInstalledExtensionsRegistered(); + if (token.isCancellationRequested) return []; + const extensionCommands = new Set( + this.extensionService.extensions.flatMap(extension => + extension.contributes?.commands?.map(command => command.command) ?? [] + ) + ); + return [...CommandsRegistry.getCommands().keys()] + .filter(commandId => commandId.startsWith('review.') || extensionCommands.has(commandId) || !FOREIGN_COMMAND.test(commandId)) + .sort((left, right) => left.localeCompare(right)) + .map(commandId => ({ + commandId, + label: reviewCommandPaletteLabel(commandId, MenuRegistry.getCommand(commandId)), + })); + } + + protected override hasAdditionalCommandPicks(_filter: string, _token: CancellationToken): boolean { + return false; + } + + protected override async getAdditionalCommandPicks( + _allPicks: ICommandQuickPick[], + _picksSoFar: ICommandQuickPick[], + _filter: string, + _token: CancellationToken, + ): Promise { + return []; + } +} + +Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ + ctor: ReviewCommandsQuickAccessProvider, + prefix: ReviewCommandsQuickAccessProvider.PREFIX, + contextKey: 'inCommandsPicker', + placeholder: localize('reviewCommandsQuickAccessPlaceholder', 'Type the name of an editor or Review command to run.'), + helpEntries: [{ + description: localize('reviewCommandsQuickAccess', 'Show and run Review commands'), + commandId: ShowAllCommandsAction.ID, + commandCenterOrder: 20 + }] +}); + +registerAction2(ShowAllCommandsAction); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/settings/reviewSettings.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/settings/reviewSettings.contribution.ts new file mode 100644 index 000000000..2be4db250 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/settings/reviewSettings.contribution.ts @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize2 } from '../../../nls.js'; +import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js'; +import { Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; +import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; +import { KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js'; +import { IReviewCanvasEditorTabsService } from '../../services/reviewCanvasEditorTabsService.js'; + +/** + * Opens the Settings canvas tab. Review does not register the stock settings + * editor, so this tab is the only settings surface in the app. + */ +class OpenReviewSettingsAction extends Action2 { + constructor() { + super({ + id: 'review.openSettings', + title: localize2('review.openSettings', "Review: Settings..."), + f1: true, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyCode.Comma, + }, + }); + } + + override async run(accessor: ServicesAccessor): Promise { + await accessor.get(IReviewCanvasEditorTabsService).openSettings(true); + } +} + +registerAction2(OpenReviewSettingsAction); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/sharing/reviewSharing.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/sharing/reviewSharing.contribution.ts new file mode 100644 index 000000000..b063b7dd9 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/sharing/reviewSharing.contribution.ts @@ -0,0 +1,110 @@ +import { Disposable } from "../../../base/common/lifecycle.js"; +import { URI } from "../../../base/common/uri.js"; +import { localize2 } from "../../../nls.js"; +import { Action2, registerAction2 } from "../../../platform/actions/common/actions.js"; +import type { ServicesAccessor } from "../../../platform/instantiation/common/instantiation.js"; +import { + INotificationService, + Severity, +} from "../../../platform/notification/common/notification.js"; +import { IProgressService, ProgressLocation } from "../../../platform/progress/common/progress.js"; +import { IQuickInputService } from "../../../platform/quickinput/common/quickInput.js"; +import { IURLService, type IURLHandler } from "../../../platform/url/common/url.js"; +import { + registerWorkbenchContribution2, + WorkbenchPhase, +} from "../../../workbench/common/contributions.js"; +import { ReviewApiClient } from "../../common/reviewProtocol.js"; +import { IReviewCanvasEditorTabsService } from "../../services/reviewCanvasEditorTabsService.js"; +import { IReviewDesktopConnectionService } from "../../services/reviewDesktopConnectionService.js"; + +async function openShare( + url: string, + session: IReviewDesktopConnectionService, + tabs: IReviewCanvasEditorTabsService, + notifications: INotificationService, + progress: IProgressService, +) { + try { + const client = new ReviewApiClient(await session.getConnection()); + await progress.withProgress({ location: ProgressLocation.Notification, title: "Opening shared review" }, async (reporter) => { + const started = await client.post<{ reviewId: string }>("/sharing/import", { url }); + for (;;) { + const status = await client.read<{ stage: string; title?: string; error?: string }>(`/sharing/import/${started.reviewId}`); + if (status.stage === "error") throw new Error(status.error ?? "Could not open the shared review."); + if (status.stage === "ready") { + await tabs.openApiReview(started.reviewId, status.title ?? "Shared review"); + return; + } + const message = status.stage === "fetching" + ? "Fetching pinned GitHub commits…" + : status.stage === "validating" + ? "Preparing pinned source…" + : "Downloading review resources…"; + reporter.report({ message }); + await new Promise((resolve) => setTimeout(resolve, 500)); + } + }); + } catch (error) { + notifications.prompt( + Severity.Error, + error instanceof Error ? error.message : "Could not open the shared review.", + [{ label: "Retry", run: () => openShare(url, session, tabs, notifications, progress) }], + ); + } +} + +class SharedReviewUrlHandler extends Disposable implements IURLHandler { + constructor( + @IURLService urls: IURLService, + @IReviewDesktopConnectionService private readonly session: IReviewDesktopConnectionService, + @IReviewCanvasEditorTabsService private readonly tabs: IReviewCanvasEditorTabsService, + @INotificationService private readonly notifications: INotificationService, + @IProgressService private readonly progress: IProgressService, + ) { + super(); + this._register(urls.registerHandler(this)); + } + async handleURL(uri: URI): Promise { + if (uri.authority !== "share") return false; + try { + const origin = new URLSearchParams(uri.query).get("origin") ?? "https://app.dev.fast"; + const url = new URL(`/s${uri.path}`, origin); + url.hash = uri.fragment; + await openShare(url.href, this.session, this.tabs, this.notifications, this.progress); + } catch { + this.notifications.error("Invalid Review share link."); + } + return true; + } +} +registerWorkbenchContribution2( + "review.sharing.urls", + SharedReviewUrlHandler, + WorkbenchPhase.BlockRestore, +); +registerAction2( + class extends Action2 { + constructor() { + super({ + id: "review.openSharedReview", + title: localize2("review.openSharedReview", "Open Shared Review"), + f1: true, + }); + } + async run(accessor: ServicesAccessor) { + const session = accessor.get(IReviewDesktopConnectionService), + tabs = accessor.get(IReviewCanvasEditorTabsService), + notifications = accessor.get(INotificationService), + progress = accessor.get(IProgressService); + const url = await accessor + .get(IQuickInputService) + .input({ + prompt: "Paste a Review share link", + placeHolder: "https://app.dev.fast/s/…", + ignoreFocusLost: true, + }); + if (url) await openShare(url, session, tabs, notifications, progress); + } + }, +); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewLspTelemetry.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewLspTelemetry.contribution.ts new file mode 100644 index 000000000..25efce45f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewLspTelemetry.contribution.ts @@ -0,0 +1,272 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { RunOnceScheduler } from '../../../base/common/async.js'; +import { Disposable, DisposableStore } from '../../../base/common/lifecycle.js'; +import type { ICodeEditor } from '../../../editor/browser/editorBrowser.js'; +import { MouseTargetType } from '../../../editor/browser/editorBrowser.js'; +import { ICodeEditorService } from '../../../editor/browser/services/codeEditorService.js'; +import { ContentHoverController } from '../../../editor/contrib/hover/browser/contentHoverController.js'; +import { ClickLinkGesture } from '../../../editor/contrib/gotoSymbol/browser/link/clickLinkGesture.js'; +import { ILanguageFeaturesService } from '../../../editor/common/services/languageFeatures.js'; +import type { ITextModel } from '../../../editor/common/model.js'; +import { ModelDecorationInjectedTextOptions } from '../../../editor/common/model/textModel.js'; +import { IModelService } from '../../../editor/common/services/model.js'; +import { ICommandService } from '../../../platform/commands/common/commands.js'; +import { Registry } from '../../../platform/registry/common/platform.js'; +import { + Extensions as WorkbenchExtensions, + type IWorkbenchContribution, + type IWorkbenchContributionsRegistry, +} from '../../../workbench/common/contributions.js'; +import { IExtensionService } from '../../../workbench/services/extensions/common/extensions.js'; +import { LifecyclePhase } from '../../../workbench/services/lifecycle/common/lifecycle.js'; +import { ReviewEmbeddedEditors } from '../../services/reviewEmbeddedEditors.js'; +import { IReviewTelemetryService } from '../../services/reviewTelemetryService.js'; + +const HOVER_DWELL_MS = 1_000; +const HOVER_VISIBILITY_POLL_MS = 100; +const LS_ACTIVATION_WAIT_MS = 10_000; + +const LANGUAGE_MAP: Record = { + typescript: 'typescript', + typescriptreact: 'typescript', + javascript: 'javascript', + javascriptreact: 'javascript', + python: 'python', + go: 'go', + rust: 'rust', + swift: 'swift', + csharp: 'csharp', + json: 'json', + jsonc: 'json', + css: 'css', + scss: 'css', + less: 'css', + html: 'html', + markdown: 'markdown', + yaml: 'yaml', + toml: 'toml', + shellscript: 'shell', + sql: 'sql', +}; + +function toLspLanguage(languageId: string): string { + return Object.prototype.hasOwnProperty.call(LANGUAGE_MAP, languageId) + ? LANGUAGE_MAP[languageId] + : 'other'; +} + +const LSP_COMMANDS: Record = { + 'editor.action.revealDefinition': 'goto_definition', + 'editor.action.revealDefinitionAside': 'goto_definition', + 'editor.action.goToDeclaration': 'goto_definition', + 'editor.action.revealDeclaration': 'goto_definition', + 'editor.action.peekDefinition': 'peek_definition', + 'editor.action.peekDeclaration': 'peek_definition', + 'editor.action.previewDeclaration': 'peek_definition', + 'editor.action.goToTypeDefinition': 'goto_type_definition', + 'editor.action.peekTypeDefinition': 'goto_type_definition', + 'editor.action.goToImplementation': 'goto_implementation', + 'editor.action.peekImplementation': 'goto_implementation', + 'editor.action.goToReferences': 'references', + 'editor.action.referenceSearch.trigger': 'references', + 'editor.action.findReferences': 'references', + 'editor.action.rename': 'rename', + 'editor.action.formatDocument': 'format', + 'editor.action.formatSelection': 'format', + 'editor.action.quickFix': 'code_action', + 'editor.action.showHover': 'hover', + 'editor.action.showDefinitionPreviewHover': 'hover', + 'workbench.action.gotoSymbol': 'symbol_search', +}; + +const LS_EXTENSIONS: Record = { + python: 'astral-sh.ty', + go: 'golang.go', + rust: 'rust-lang.rust-analyzer', + swift: 'swiftlang.swift-vscode', + csharp: 'muhammad-sammy.csharp', +}; + +class ReviewLspTelemetryContribution extends Disposable implements IWorkbenchContribution { + private readonly editorStores = new Map(); + private readonly lastCommandHover = new WeakMap(); + private readonly scheduledLsGroups = new Set(); + + constructor( + @ICommandService commandService: ICommandService, + @ICodeEditorService private readonly codeEditorService: ICodeEditorService, + @ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService, + @IModelService modelService: IModelService, + @IExtensionService private readonly extensionService: IExtensionService, + @IReviewTelemetryService private readonly telemetryService: IReviewTelemetryService, + ) { + super(); + this._register(commandService.onDidExecuteCommand(event => { + const feature = Object.prototype.hasOwnProperty.call(LSP_COMMANDS, event.commandId) + ? LSP_COMMANDS[event.commandId] + : undefined; + if (!feature) { + return; + } + const editor = this.activeEditor(); + const model = editor?.getModel(); + if (!editor || !model) { + return; + } + if (feature === 'hover') { + this.lastCommandHover.set(editor, Date.now()); + } + this.captureLspUsed(editor, model, feature, 'command'); + })); + + for (const editor of codeEditorService.listCodeEditors()) { + this.trackEditor(editor); + } + this._register(codeEditorService.onCodeEditorAdd(editor => this.trackEditor(editor))); + this._register(codeEditorService.onCodeEditorRemove(editor => this.untrackEditor(editor))); + + for (const model of modelService.getModels()) { + this.scheduleLsHealth(model); + } + this._register(modelService.onModelAdded(model => this.scheduleLsHealth(model))); + this._register(modelService.onModelLanguageChanged(({ model }) => this.scheduleLsHealth(model))); + } + + private activeEditor(): ICodeEditor | null { + return this.codeEditorService.getFocusedCodeEditor() ?? this.codeEditorService.getActiveCodeEditor(); + } + + private trackEditor(editor: ICodeEditor): void { + if (this.editorStores.has(editor)) { + return; + } + const store = new DisposableStore(); + this.editorStores.set(editor, store); + this._register(store); + + const hoverController = ContentHoverController.get(editor); + if (hoverController) { + this.trackHover(editor, hoverController, store); + } + + const clickLinkGesture = store.add(new ClickLinkGesture(editor)); + store.add(clickLinkGesture.onExecute(event => { + const model = editor.getModel(); + const position = event.target.position; + if ( + !model + || !position + || !event.isLeftClick + || !event.isNoneOrSingleMouseDown + || !event.hasTriggerModifier + || event.target.type !== MouseTargetType.CONTENT_TEXT + || event.target.detail.injectedText?.options instanceof ModelDecorationInjectedTextOptions + || !model.getWordAtPosition(position) + || !this.languageFeaturesService.definitionProvider.has(model) + ) { + return; + } + this.captureLspUsed(editor, model, 'goto_definition', 'mouse'); + })); + } + + private trackHover(editor: ICodeEditor, controller: ContentHoverController, store: DisposableStore): void { + let captured = false; + const dwell = store.add(new RunOnceScheduler(() => { + if (!controller.isHoverVisible) { + captured = false; + return; + } + captured = true; + if (Date.now() - (this.lastCommandHover.get(editor) ?? 0) >= HOVER_DWELL_MS) { + const model = editor.getModel(); + if (model) { + this.captureLspUsed(editor, model, 'hover', 'mouse'); + } + } + visibilityPoll.schedule(HOVER_VISIBILITY_POLL_MS); + }, HOVER_DWELL_MS)); + const visibilityPoll = store.add(new RunOnceScheduler(() => { + if (controller.isHoverVisible) { + visibilityPoll.schedule(HOVER_VISIBILITY_POLL_MS); + return; + } + captured = false; + }, HOVER_VISIBILITY_POLL_MS)); + const resetIfHidden = () => { + if (controller.isHoverVisible) { + return; + } + dwell.cancel(); + visibilityPoll.cancel(); + captured = false; + }; + + store.add(controller.onHoverContentsChanged(() => { + if (!controller.isHoverVisible) { + resetIfHidden(); + return; + } + if (!captured) { + dwell.schedule(HOVER_DWELL_MS); + } + })); + store.add(editor.onMouseMove(resetIfHidden)); + store.add(editor.onMouseLeave(resetIfHidden)); + store.add(editor.onMouseDown(resetIfHidden)); + store.add(editor.onDidScrollChange(resetIfHidden)); + store.add(editor.onDidChangeModel(resetIfHidden)); + } + + private untrackEditor(editor: ICodeEditor): void { + this.editorStores.get(editor)?.dispose(); + this.editorStores.delete(editor); + } + + private captureLspUsed(editor: ICodeEditor, model: ITextModel, feature: string, via: string): void { + this.telemetryService.capture('lsp_used', { + feature, + via, + language: toLspLanguage(model.getLanguageId()), + editor_kind: this.editorKind(editor), + }); + } + + private editorKind(editor: ICodeEditor): string { + if (ReviewEmbeddedEditors.owns(editor)) { + return 'inline_peek'; + } + for (const diffEditor of this.codeEditorService.listDiffEditors()) { + if (diffEditor.getOriginalEditor() === editor || diffEditor.getModifiedEditor() === editor) { + return 'diff'; + } + } + return 'files_tab'; + } + + private scheduleLsHealth(model: ITextModel): void { + const group = toLspLanguage(model.getLanguageId()); + const extensionId = LS_EXTENSIONS[group]; + if (!extensionId || this.scheduledLsGroups.has(group)) { + return; + } + this.scheduledLsGroups.add(group); + const timer = new RunOnceScheduler(() => { + const status = this.extensionService.getExtensionsStatus()[extensionId]; + this.telemetryService.capture('ls_activated', { + group, + ok: status?.activationTimes !== undefined && status.runningLocation !== null, + }); + }, LS_ACTIVATION_WAIT_MS); + this._register(timer); + timer.schedule(); + } +} + +Registry.as( + WorkbenchExtensions.Workbench, +).registerWorkbenchContribution(ReviewLspTelemetryContribution, LifecyclePhase.Eventually); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewTelemetry.contribution.test.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewTelemetry.contribution.test.ts new file mode 100644 index 000000000..04f646dfb --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewTelemetry.contribution.test.ts @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import type { IPromptChoice, IPromptOptions } from '../../../platform/notification/common/notification.js'; +import { setFirstRunReloadPending } from '../../common/reviewFirstRunReload.js'; +import { NOTICE_STORAGE_KEY, ReviewTelemetryNotice } from './reviewTelemetry.contribution.js'; + +const settle = () => new Promise(resolve => setImmediate(resolve)); + +function setup() { + const stored: Array<{ key: string; value: unknown }> = []; + const prompts: Array<{ choices: IPromptChoice[]; options?: IPromptOptions }> = []; + const settingsOpened: unknown[] = []; + const notice = () => new ReviewTelemetryNotice( + { getBoolean: () => false, store: (key: string, value: unknown) => stored.push({ key, value }) } as never, + { + prompt: (_severity: unknown, _message: string, choices: IPromptChoice[], options?: IPromptOptions) => { + prompts.push({ choices, options }); + return { close() { } }; + }, + } as never, + { openSettings: async (preview: unknown) => { settingsOpened.push(preview); } } as never, + ); + return { stored, prompts, settingsOpened, notice }; +} + +test('keeps the telemetry notice unspent until the reader answers it', async () => { + setFirstRunReloadPending(false); + const { stored, prompts, notice } = setup(); + notice(); + await settle(); + assert.equal(prompts.length, 1, 'the notice is shown'); + assert.deepEqual(stored, [], 'showing the notice does not record it as seen'); + // A non-sticky Info toast is purged without closing the notification, so `onCancel` + // would never fire and the notice would return on every launch. + assert.equal(prompts[0].options?.sticky, true); + prompts[0].options?.onCancel?.(); + assert.deepEqual(stored, [{ key: NOTICE_STORAGE_KEY, value: true }]); +}); + +test('spends the notice when the reader opens Settings', async () => { + setFirstRunReloadPending(false); + const { stored, prompts, settingsOpened, notice } = setup(); + notice(); + await settle(); + prompts[0].choices[0].run(); + assert.deepEqual(stored, [{ key: NOTICE_STORAGE_KEY, value: true }]); + assert.deepEqual(settingsOpened, [true]); +}); + +test('skips the telemetry notice when the first-run seeding reload is pending', async () => { + setFirstRunReloadPending(true); + const { stored, prompts, notice } = setup(); + notice(); + await settle(); + assert.deepEqual(prompts, [], 'a pending reload would take the notice with it'); + assert.deepEqual(stored, []); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewTelemetry.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewTelemetry.contribution.ts new file mode 100644 index 000000000..011328a61 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/telemetry/reviewTelemetry.contribution.ts @@ -0,0 +1,82 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from '../../../nls.js'; +import { onUnexpectedError } from '../../../base/common/errors.js'; +import Severity from '../../../base/common/severity.js'; +import { INotificationService } from '../../../platform/notification/common/notification.js'; +import { Registry } from '../../../platform/registry/common/platform.js'; +import { IStorageService, StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js'; +import { + Extensions as WorkbenchExtensions, + type IWorkbenchContribution, + type IWorkbenchContributionsRegistry, +} from '../../../workbench/common/contributions.js'; +import { LifecyclePhase } from '../../../workbench/services/lifecycle/common/lifecycle.js'; +import { isFirstRunReloadPending } from '../../common/reviewFirstRunReload.js'; +import { IReviewCanvasEditorTabsService } from '../../services/reviewCanvasEditorTabsService.js'; + +export const NOTICE_STORAGE_KEY = 'review.telemetry.noticeShown.v1'; + +export class ReviewTelemetryNotice implements IWorkbenchContribution { + constructor( + @IStorageService storageService: IStorageService, + @INotificationService notificationService: INotificationService, + @IReviewCanvasEditorTabsService tabsService: IReviewCanvasEditorTabsService, + ) { + if ( + storageService.getBoolean( + NOTICE_STORAGE_KEY, + StorageScope.APPLICATION, + false, + ) + ) { + return; + } + this.show(storageService, notificationService, tabsService).catch(onUnexpectedError); + } + + private async show( + storageService: IStorageService, + notificationService: INotificationService, + tabsService: IReviewCanvasEditorTabsService, + ): Promise { + if (await isFirstRunReloadPending()) { + return; // the seeding reload would take the notice with it + } + // Spend the notice only once the reader answers it: a reload before then removes + // the notice, and a flag written up front never brings it back. + const markShown = () => storageService.store( + NOTICE_STORAGE_KEY, + true, + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + notificationService.prompt( + Severity.Info, + localize( + 'review.telemetry.notice', + "Review sends anonymous usage data. You can change this in Settings.", + ), + [{ + label: localize( + 'review.telemetry.openSettings', + "Open Settings", + ), + // Review does not register the stock settings editor, so the + // Settings canvas tab is where this setting lives. + run: () => { + markShown(); + void tabsService.openSettings(true); + }, + }], + { sticky: true, onCancel: markShown }, + ); + } +} + +Registry.as( + WorkbenchExtensions.Workbench, +).registerWorkbenchContribution(ReviewTelemetryNotice, LifecyclePhase.Restored); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/update/reviewUpdate.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/update/reviewUpdate.contribution.ts new file mode 100644 index 000000000..ec93d8b6f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/update/reviewUpdate.contribution.ts @@ -0,0 +1,280 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Review's update surface: two toasts, and a command to check on demand. + * + * Review deliberately omits the stock `workbench/contrib/update` — its title bar + * entry depends on the chat service, which Review does not register. This is the + * whole replacement: tell the reader when an update is waiting on a restart, and + * confirm once it has landed. + * + * Linux announces an available package and opens system update instructions. + * Squirrel on macOS installs a staged update whenever the app quits, with or without the + * toast, so the prompt is an invitation to restart now, not a gate on updating. + */ + +import { localize, localize2 } from '../../../nls.js'; +import { toAction } from '../../../base/common/actions.js'; +import { Disposable } from '../../../base/common/lifecycle.js'; +import { isLinux } from '../../../base/common/platform.js'; +import Severity from '../../../base/common/severity.js'; +import { Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; +import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; +import { ILogService } from '../../../platform/log/common/log.js'; +import { INotificationService, type INotificationHandle } from '../../../platform/notification/common/notification.js'; +import { IProductService } from '../../../platform/product/common/productService.js'; +import { IStorageService, StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js'; +import { + darwinFailedUpdateNoticeId, + DARWIN_FAILED_UPDATE_STORAGE_KEY, + parseDarwinFailedUpdate, + shouldAnnounceDarwinFailedUpdate, +} from '../../../platform/update/common/darwinUpdateRecovery.js'; +import { IUpdateService, StateType, type State } from '../../../platform/update/common/update.js'; +import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../workbench/common/contributions.js'; +import { + decideUpdateNotice, + parseStagedUpdate, + serializeStagedUpdate, + shouldPromptForUpdate, + stagedUpdateFromReady, + supersedesStagedUpdate, + type IReviewStagedUpdate, +} from '../../common/reviewUpdateNotice.js'; + +/** The update downloaded and waiting for a restart. */ +const STAGED_UPDATE_STORAGE_KEY = 'review.update.staged.v1'; +/** Target commit the reader asked not to be prompted about again. */ +const SKIPPED_UPDATE_STORAGE_KEY = 'review.update.skipped.v1'; +/** Failed update attempt that Review already announced. */ +const FAILED_UPDATE_NOTICE_STORAGE_KEY = 'review.update.failedNotice.v1'; + +class ReviewUpdateNotifications extends Disposable { + + static readonly ID = 'review.update.notifications'; + + /** The visible "ready to install" toast, kept so a re-fire cannot stack duplicates. */ + private readyHandle: INotificationHandle | undefined; + /** Which commit `readyHandle` is about. */ + private readyCommit: string | undefined; + + constructor( + @IUpdateService private readonly updateService: IUpdateService, + @INotificationService private readonly notificationService: INotificationService, + @IStorageService private readonly storageService: IStorageService, + @IProductService private readonly productService: IProductService, + @ILogService private readonly logService: ILogService, + ) { + super(); + + this.announceFailedUpdate(); + this.announceCompletedUpdate(); + this._register(this.storageService.onDidChangeValue( + StorageScope.APPLICATION, + DARWIN_FAILED_UPDATE_STORAGE_KEY, + this._store, + )(() => this.announceFailedUpdate())); + + this._register(this.updateService.onStateChange(state => { + this.announceFailedUpdate(); + this.onStateChange(state); + })); + // The channel client replays its initial state, but reading it directly + // keeps this correct regardless of when the contribution is created. + this.onStateChange(this.updateService.state); + } + + private announceFailedUpdate(): void { + const failure = parseDarwinFailedUpdate( + this.storageService.get(DARWIN_FAILED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION), + ); + const announcedNoticeId = this.storageService.get( + FAILED_UPDATE_NOTICE_STORAGE_KEY, + StorageScope.APPLICATION, + ); + if (!shouldAnnounceDarwinFailedUpdate(failure, this.productService.commit, announcedNoticeId)) { + return; + } + + this.storageService.store( + FAILED_UPDATE_NOTICE_STORAGE_KEY, + darwinFailedUpdateNoticeId(failure), + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + this.logService.error(`[ReviewUpdate] update failed (${failure.targetCommit})`); + this.notificationService.notify({ + severity: Severity.Error, + message: localize('review.update.installFailed', "Update failed"), + }); + } + + /** + * If this launch is the first one on a build we staged, say so — once. + * + * The record is cleared whether or not it matched: a record for some other + * build is stale (a hand-installed DMG, or an abandoned update) and should + * disappear silently rather than linger and fire later. + */ + private announceCompletedUpdate(): void { + const staged = parseStagedUpdate( + this.storageService.get(STAGED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION), + ); + const notice = decideUpdateNotice(staged, this.productService.commit); + if (notice.kind === 'none') { + return; + } + + this.storageService.remove(STAGED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION); + if (notice.kind === 'clear') { + return; + } + + // The update landed, so any skip recorded against it is spent. + this.storageService.remove(SKIPPED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION); + this.logService.info(`[ReviewUpdate] running the staged update (${this.productService.commit})`); + this.notificationService.notify({ + severity: Severity.Info, + message: notice.productVersion + ? localize('review.update.applied', "Review updated to {0}.", notice.productVersion) + : localize('review.update.applied.unknownVersion', "Review has been updated."), + }); + } + + /** + * Linux rests at `AvailableForDownload`; macOS prompts at `Ready`. + * + * On macOS the flow is Idle → CheckingForUpdates → Downloading → Downloaded → + * Ready, and the last two are set back to back, so `Downloaded` is never a + * resting state. `AvailableForDownload` occurs only on a metered connection + * and resolves itself on the next check once off metered, so surfacing it + * would add a download-progress story for a state that clears on its own. + */ + private onStateChange(state: State): void { + if (isLinux && state.type === StateType.AvailableForDownload) { + if (this.readyCommit === state.update.version && this.readyHandle) { return; } + this.readyHandle?.close(); + this.readyCommit = state.update.version; + this.readyHandle = this.notificationService.notify({ + severity: Severity.Info, + message: localize('review.update.linuxAvailable', "Review {0} is available. Update with your system package manager, then reopen Review.", state.update.productVersion ?? ''), + actions: { primary: [toAction({ + id: 'review.update.instructions', label: localize('review.update.instructions', "Update Instructions"), + run: () => this.updateService.downloadUpdate(true), + })] }, + }); + const handle = this.readyHandle; + this._register(handle.onDidClose(() => { + if (this.readyHandle === handle) { this.readyHandle = undefined; this.readyCommit = undefined; } + })); + return; + } + if (state.type !== StateType.Ready) { + return; + } + + const next = stagedUpdateFromReady(state.update); + if (!next) { + this.logService.warn('[ReviewUpdate] update is ready but carries no commit; nothing to record'); + return; + } + + // Record before considering the prompt: the update installs on quit even + // when skipped, so the post-restart toast must still be able to fire. + const staged = parseStagedUpdate( + this.storageService.get(STAGED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION), + ); + if (supersedesStagedUpdate(staged, next)) { + this.storageService.store( + STAGED_UPDATE_STORAGE_KEY, + serializeStagedUpdate(next), + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + } + + const skipped = this.storageService.get(SKIPPED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION); + if (!shouldPromptForUpdate(next, skipped)) { + return; + } + if (this.readyHandle && this.readyCommit === next.targetCommit) { + return; + } + + this.showReadyNotification(next); + } + + private showReadyNotification(next: IReviewStagedUpdate): void { + // A newer update superseded whatever was on screen. + this.readyHandle?.close(); + + const handle = this.notificationService.notify({ + severity: Severity.Info, + // Waits for a decision rather than expiring unseen. + sticky: true, + message: next.productVersion + ? localize('review.update.ready', "Review {0} is ready to install.", next.productVersion) + : localize('review.update.ready.unknownVersion', "A Review update is ready to install."), + actions: { + primary: [ + toAction({ + id: 'review.update.restart', + label: localize('review.update.restart', "Restart to Update"), + run: () => { + void this.updateService.quitAndInstall(); + }, + }), + toAction({ + id: 'review.update.skip', + label: localize('review.update.skip', "Skip This Version"), + run: () => { + this.storageService.store( + SKIPPED_UPDATE_STORAGE_KEY, + next.targetCommit, + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + }, + }), + ], + }, + }); + + this.readyHandle = handle; + this.readyCommit = next.targetCommit; + this._register(handle.onDidClose(() => { + this.readyHandle = undefined; + this.readyCommit = undefined; + })); + } +} + +/** + * Checking on demand. Without this the only trigger is the scheduled check, 30 + * seconds after startup and hourly after that. An explicit check also bypasses + * the metered-connection path, so macOS can download immediately; Linux still uses the package manager. + */ +class ReviewCheckForUpdatesAction extends Action2 { + + constructor() { + super({ + id: 'review.checkForUpdates', + title: localize2('review.checkForUpdates', "Check for Updates..."), + f1: true, + }); + } + + async run(accessor: ServicesAccessor): Promise { + await accessor.get(IUpdateService).checkForUpdates(true); + } +} + +registerAction2(ReviewCheckForUpdatesAction); +registerWorkbenchContribution2( + ReviewUpdateNotifications.ID, + ReviewUpdateNotifications, + WorkbenchPhase.AfterRestored, +); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewApiSelection.test.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewApiSelection.test.ts new file mode 100644 index 000000000..b01f86927 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewApiSelection.test.ts @@ -0,0 +1,29 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { URI } from "../../../base/common/uri.js"; +import { Selection } from "../../../editor/common/core/selection.js"; +import { apiSourceUri } from "../../services/reviewApiSourceService.js"; +import { apiSelectionEvent } from "./reviewApiSelection.js"; + +test("API diff selections retain side, version and commit without a legacy session", () => { + for (const side of ["base", "head"] as const) { + const resource = apiSourceUri({ view: { reviewId: "review-a", version: 7, commit: "selected-commit" }, side, file: "src/[route].ts" }); + for (const selection of [new Selection(2, 1, 4, 1), new Selection(4, 1, 2, 1)]) { + assert.deepEqual(apiSelectionEvent(resource, selection, { x: 70, y: 140 }), { + event: "editorSelectionChanged", reviewId: "review-a", anchor: { x: 70, y: 140 }, + path: "src/[route].ts", sideContext: side, isEmpty: false, + range: { fromLine: 2, toLine: 3 }, + apiSource: { reviewId: "review-a", version: 7, commit: "selected-commit" }, + }); + } + assert.equal(apiSelectionEvent(resource, new Selection(2, 1, 2, 1))?.isEmpty, true); + } +}); + +test("empty diff sides and unrelated resources cannot produce source-copy actions", () => { + const empty = apiSourceUri({ view: { reviewId: "review-a", version: 0 }, side: "base", file: "new.ts" }, true); + const selection = new Selection(1, 1, 2, 1); + assert.equal(apiSelectionEvent(empty, selection), undefined); + assert.equal(apiSelectionEvent(URI.file("/tmp/file.ts"), selection), undefined); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewApiSelection.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewApiSelection.ts new file mode 100644 index 000000000..b76655afc --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewApiSelection.ts @@ -0,0 +1,30 @@ +import type { URI } from "../../../base/common/uri.js"; +import type { Selection } from "../../../editor/common/core/selection.js"; +import type { ReviewSurfaceEvent } from "../../common/reviewProtocol.js"; +import { apiSourceTarget } from "../../services/reviewApiSourceService.js"; + +/** API-backed editors carry their pins in the URI and have no legacy session. */ +export function apiSelectionEvent( + resource: URI, + selection: Selection, + anchor?: { x: number; y: number }, +): Extract | undefined { + const source = apiSourceTarget(resource); + if (!source || new URLSearchParams(resource.query).has("empty")) return undefined; + const start = selection.getStartPosition(); + const end = selection.getEndPosition(); + const apiSource: NonNullable["apiSource"]> = { + reviewId: source.view.reviewId, version: source.view.version, commit: source.view.commit, + }; + // A source at its own pins says so; one that inherits carries no pins key. + if (source.view.pins) apiSource.pins = source.view.pins; + return { + event: "editorSelectionChanged", reviewId: source.view.reviewId, anchor, + path: source.file, sideContext: source.side, isEmpty: selection.isEmpty(), + range: { + fromLine: start.lineNumber, + toLine: Math.max(start.lineNumber, end.lineNumber - (end.column === 1 && end.lineNumber > start.lineNumber ? 1 : 0)), + }, + apiSource, + }; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewDiffSelection.test.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewDiffSelection.test.ts new file mode 100644 index 000000000..8d2fd7dbe --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewDiffSelection.test.ts @@ -0,0 +1,40 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { selectedMonacoDiff } from './reviewDiffSelection.js'; + +const model = (...lines: string[]) => ({ getLineCount: () => lines.length, getLineContent: (line: number) => { assert.ok(line >= 1 && line <= lines.length); return lines[line - 1]; } }); +const replacement = { originalStartLineNumber: 2, originalEndLineNumber: 2, modifiedStartLineNumber: 2, modifiedEndLineNumber: 3 }; + +test('copy from either pane retains both sides of a replacement and rename paths', () => { + for (const side of ['base', 'head'] as const) { + const diff = selectedMonacoDiff(model('before', 'old', 'after'), model('before', 'new', 'extra', 'after'), [replacement], side, 2, 2, 'old.ts', 'new.ts'); + assert.deepEqual(diff, { oldPath: 'old.ts', newPath: 'new.ts', oldStart: 2, newStart: 2, rows: [{ kind: 'deleted', text: 'old' }, { kind: 'added', text: 'new' }, { kind: 'added', text: 'extra' }] }); + } +}); + +test('context after a replacement retains correct base/head offsets', () => { + const diff = selectedMonacoDiff(model('before', 'old', 'after'), model('before', 'new', 'extra', 'after'), [replacement], 'head', 4, 4, 'a.ts', 'a.ts'); + assert.equal(diff?.oldStart, 3); assert.equal(diff?.newStart, 4); + assert.deepEqual(diff?.rows, [{ kind: 'unchanged', text: 'after' }]); +}); + +test('added and deleted files use zero-count opposite sides', () => { + const addition = { originalStartLineNumber: 0, originalEndLineNumber: 0, modifiedStartLineNumber: 1, modifiedEndLineNumber: 2 }; + const added = selectedMonacoDiff(model(''), model('a', 'b'), [addition], 'head', 1, 2, '', 'new.ts'); + assert.equal(added?.oldStart, 0); assert.deepEqual(added?.rows.map(row => row.kind), ['added', 'added']); + const removed = selectedMonacoDiff(model('a', 'b'), model(''), [{ originalStartLineNumber: 1, originalEndLineNumber: 2, modifiedStartLineNumber: 0, modifiedEndLineNumber: 0 }], 'base', 1, 2, 'old.ts', ''); + assert.equal(removed?.newStart, 0); assert.deepEqual(removed?.rows.map(row => row.kind), ['deleted', 'deleted']); +}); + +test('selection crossing a deletion includes it, adjacent context alone does not', () => { + const change = { originalStartLineNumber: 2, originalEndLineNumber: 2, modifiedStartLineNumber: 1, modifiedEndLineNumber: 0 }; + const select = (from: number, to: number) => selectedMonacoDiff(model('a', 'removed', 'b'), model('a', 'b'), [change], 'head', from, to, 'a', 'a'); + assert.deepEqual(select(1, 2)?.rows.map(row => row.kind), ['unchanged', 'deleted', 'unchanged']); + assert.deepEqual(select(2, 2)?.rows, [{ kind: 'unchanged', text: 'b' }]); +}); + +test('partial selection of a newly added file copies only selected lines', () => { + const diff = selectedMonacoDiff(model(''), model('a', 'b', 'c'), [{ originalStartLineNumber: 0, originalEndLineNumber: 0, modifiedStartLineNumber: 1, modifiedEndLineNumber: 3 }], 'head', 2, 2, '', 'new.ts'); + assert.equal(diff?.newStart, 2); + assert.deepEqual(diff?.rows, [{ kind: 'added', text: 'b' }]); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewDiffSelection.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewDiffSelection.ts new file mode 100644 index 000000000..f2784a66f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewDiffSelection.ts @@ -0,0 +1,45 @@ +import type { ILineChange } from '../../../editor/common/diff/legacyLinesDiffComputer.js'; +import type { ReviewSurfaceEvent } from '../../common/reviewProtocol.js'; + +type SelectedDiff = NonNullable['selectedDiff']>; +interface Lines { getLineCount(): number; getLineContent(line: number): string } + +/** Expand intersected replacements to both sides so the copied excerpt is a real diff. */ +export function selectedMonacoDiff(original: Lines, modified: Lines, changes: readonly Omit[], side: 'base' | 'head', from: number, to: number, oldPath: string, newPath: string): SelectedDiff | undefined { + const result: SelectedDiff = { oldPath, newPath, oldStart: 0, newStart: 0, rows: [] }; + let oldLine = 1, newLine = 1; + const begin = (oldStart: number, newStart: number) => { + if (!result.rows.length) { result.oldStart = oldStart; result.newStart = newStart; } + }; + const context = (count: number) => { + const line = side === 'base' ? oldLine : newLine; + const first = Math.max(0, from - line), last = Math.min(count - 1, to - line); + if (first <= last) { + begin(oldLine + first, newLine + first); + for (let offset = first; offset <= last; offset++) result.rows.push({ kind: 'unchanged', text: original.getLineContent(oldLine + offset) }); + } + oldLine += count; newLine += count; + }; + for (const change of changes) { + const oldStart = change.originalEndLineNumber === 0 ? change.originalStartLineNumber + 1 : change.originalStartLineNumber; + const newStart = change.modifiedEndLineNumber === 0 ? change.modifiedStartLineNumber + 1 : change.modifiedStartLineNumber; + const oldCount = change.originalEndLineNumber === 0 ? 0 : change.originalEndLineNumber - oldStart + 1; + const newCount = change.modifiedEndLineNumber === 0 ? 0 : change.modifiedEndLineNumber - newStart + 1; + context(Math.max(0, Math.min(oldStart - oldLine, newStart - newLine))); + const start = side === 'base' ? oldStart : newStart; + const count = side === 'base' ? oldCount : newCount; + // A one-sided change belongs only when the selection crosses its insertion point. + if (count ? from <= start + count - 1 && to >= start : from < start && to >= start) { + const selectedOldStart = !newCount && side === 'base' ? Math.max(oldStart, from) : oldStart; + const selectedOldEnd = !newCount && side === 'base' ? Math.min(oldStart + oldCount, to + 1) : oldStart + oldCount; + const selectedNewStart = !oldCount && side === 'head' ? Math.max(newStart, from) : newStart; + const selectedNewEnd = !oldCount && side === 'head' ? Math.min(newStart + newCount, to + 1) : newStart + newCount; + begin(oldCount ? selectedOldStart : oldStart - 1, newCount ? selectedNewStart : newStart - 1); + for (let line = selectedOldStart; line < selectedOldEnd; line++) result.rows.push({ kind: 'deleted', text: original.getLineContent(line) }); + for (let line = selectedNewStart; line < selectedNewEnd; line++) result.rows.push({ kind: 'added', text: modified.getLineContent(line) }); + } + oldLine = oldStart + oldCount; newLine = newStart + newCount; + } + context(Math.max(0, Math.min(oldPath ? original.getLineCount() - oldLine + 1 : 0, newPath ? modified.getLineCount() - newLine + 1 : 0))); + return result.rows.length ? result : undefined; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewVerbs.ts b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewVerbs.ts new file mode 100644 index 000000000..4002ab434 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/contrib/verbs/reviewVerbs.ts @@ -0,0 +1,177 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { encodeBase64 } from "../../../base/common/buffer.js"; +import { Emitter, Event } from "../../../base/common/event.js"; +import { Disposable, DisposableStore } from "../../../base/common/lifecycle.js"; +import { type ICodeEditor, type IDiffEditor } from "../../../editor/browser/editorBrowser.js"; +import { ICodeEditorService } from "../../../editor/browser/services/codeEditorService.js"; +import { createDecorator } from "../../../platform/instantiation/common/instantiation.js"; +import { IOpenerService } from "../../../platform/opener/common/opener.js"; +import { IHostService } from "../../../workbench/services/host/browser/host.js"; +import { + type JsonValue, + parseReviewVerbRequest, + REVIEW_DISCORD_URL, + type ReviewSurfaceEvent, + type ReviewVerbResponse, + type ReviewView, +} from "../../common/reviewProtocol.js"; +import { IReviewApiCatalogService } from "../../services/reviewApiCatalogService.js"; +import { IReviewCanvasEditorTabsService } from "../../services/reviewCanvasEditorTabsService.js"; +import { apiSourceTarget } from "../../services/reviewApiSourceService.js"; +import { selectedMonacoDiff } from "./reviewDiffSelection.js"; +import { apiSelectionEvent } from "./reviewApiSelection.js"; + +export const IReviewVerbsService = createDecorator("reviewVerbsService"); + +export interface IReviewVerbsService { + readonly _serviceBrand: undefined; + readonly onDidEmitSurfaceEvent: Event; + readonly onDidRequestCanvasFocus: Event; + dispatch(value: JsonValue): Promise; +} + +export class ReviewVerbsService extends Disposable implements IReviewVerbsService { + declare readonly _serviceBrand: undefined; + + private readonly _onDidEmitSurfaceEvent = this._register(new Emitter()); + readonly onDidEmitSurfaceEvent = this._onDidEmitSurfaceEvent.event; + private readonly _onDidRequestCanvasFocus = this._register(new Emitter()); + readonly onDidRequestCanvasFocus = this._onDidRequestCanvasFocus.event; + + private readonly selectionEditors = new Map(); + + constructor( + @ICodeEditorService private readonly codeEditorService: ICodeEditorService, + @IReviewCanvasEditorTabsService + private readonly tabsService: IReviewCanvasEditorTabsService, + @IHostService private readonly hostService: IHostService, + @IOpenerService private readonly openerService: IOpenerService, + @IReviewApiCatalogService + private readonly apiCatalog: IReviewApiCatalogService, + ) { + super(); + for (const editor of this.codeEditorService.listCodeEditors()) this.trackSelection(editor); + for (const diff of this.codeEditorService.listDiffEditors()) this.trackDiffSelection(diff); + this._register(this.codeEditorService.onDiffEditorAdd(diff => this.trackDiffSelection(diff))); + this._register(this.codeEditorService.onCodeEditorAdd((editor) => this.trackSelection(editor))); + this._register( + this.codeEditorService.onCodeEditorRemove((editor) => { + this.selectionEditors.get(editor.getId())?.dispose(); + this.selectionEditors.delete(editor.getId()); + }), + ); + } + + private trackDiffSelection(diff: IDiffEditor): void { + const subscription = diff.onDidUpdateDiff(() => { + this.emitSelection(diff.getOriginalEditor()); + this.emitSelection(diff.getModifiedEditor()); + }); + const disposed = diff.onDidDispose(() => { subscription.dispose(); disposed.dispose(); }); + this._register(subscription); + this._register(disposed); + } + + private trackSelection(editor: ICodeEditor): void { + if (this.selectionEditors.has(editor.getId())) return; + const store = this._register(new DisposableStore()); + this.selectionEditors.set(editor.getId(), store); + store.add(editor.onDidChangeCursorSelection(() => this.emitSelection(editor))); + store.add(editor.onDidFocusEditorText(() => this.emitSelection(editor))); + store.add(editor.onDidScrollChange(() => this.emitSelection(editor))); + } + + private emitSelection(editor: ICodeEditor): void { + if (!editor.hasTextFocus()) return; + const model = editor.getModel(); + const selection = editor.getSelection(); + if (!model || !selection) return; + const start = selection.getStartPosition(); + const end = selection.getEndPosition(); + const fromLine = start.lineNumber; + const toLine = Math.max(fromLine, end.lineNumber - (end.column === 1 && end.lineNumber > fromLine ? 1 : 0)); + const rect = editor.getDomNode()?.getBoundingClientRect(); + const position = editor.getScrolledVisiblePosition(selection.getPosition()); + const anchor = rect && position ? { x: rect.left + position.left, y: rect.top + position.top } : undefined; + const apiSelection = apiSelectionEvent(model.uri, selection, anchor); + if (apiSelection) { + const diff = this.codeEditorService.listDiffEditors().find(diff => diff.getOriginalEditor() === editor || diff.getModifiedEditor() === editor); + const models = diff?.getModel(); + const changes = diff?.getLineChanges(); + if (models && changes && !selection.isEmpty()) { + const oldSource = apiSourceTarget(models.original.uri); + const newSource = apiSourceTarget(models.modified.uri); + if (oldSource && newSource) apiSelection.selectedDiff = selectedMonacoDiff( + models.original, models.modified, changes, apiSelection.sideContext, fromLine, toLine, + new URLSearchParams(models.original.uri.query).has("empty") ? "" : oldSource.file, + new URLSearchParams(models.modified.uri.query).has("empty") ? "" : newSource.file, + ); + } + this._onDidEmitSurfaceEvent.fire(apiSelection); + return; + } + } + + async dispatch(value: JsonValue): Promise { + try { + const request = parseReviewVerbRequest(value); + switch (request.name) { + case "joinDiscord": + await this.openerService.open(REVIEW_DISCORD_URL, { openExternal: true }); + break; + case "showReviewView": + await this.showReviewView(request.args.view); + break; + case "openSourceTree": + case "openDiff": + case "reveal": + case "openReviewRevision": + throw new Error("This action requires a pinned review canvas."); + case "focusCanvas": + this._onDidRequestCanvasFocus.fire(); + break; + case "captureScreenshot": + return { ok: true, result: await this.captureScreenshot() }; + case "openReview": { + const review = this.apiCatalog.reviews.find((review) => review.reviewId === request.args.reviewUuid); + if (!review) throw new Error("Review not found."); + await this.tabsService.openApiReview(review.reviewId, review.title, request.args.active); + break; + } + case "openApiReview": + await this.tabsService.openApiReview(request.args.reviewId, request.args.title); + break; + } + return { ok: true }; + } catch (error) { + return { + ok: false, + error: error instanceof Error ? error.message : String(error), + }; + } + } + + private async captureScreenshot(): Promise<{ dataUrl: string } | undefined> { + try { + const screenshot = await this.hostService.getScreenshot(); + if (!screenshot) return undefined; + return { + dataUrl: `data:image/jpeg;base64,${encodeBase64(screenshot)}`, + }; + } catch { + return undefined; + } + } + + /** + * The dispatcher reveals the Review tab before asking the app to show a view. + */ + private async showReviewView(view: ReviewView): Promise { + this._onDidRequestCanvasFocus.fire(); + this._onDidEmitSurfaceEvent.fire({ event: "showReviewView", view }); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-browser/review.main.ts b/apps/review-desktop/code-oss/src/vs/review/electron-browser/review.main.ts new file mode 100644 index 000000000..92d1beb30 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-browser/review.main.ts @@ -0,0 +1,407 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from '../../nls.js'; +import product from '../../platform/product/common/product.js'; +import { INativeWindowConfiguration, IWindowsConfiguration } from '../../platform/window/common/window.js'; +import { NativeWindow } from '../../workbench/electron-browser/window.js'; +import { setFullscreen } from '../../base/browser/browser.js'; +import { domContentLoaded } from '../../base/browser/dom.js'; +import { onUnexpectedError } from '../../base/common/errors.js'; +import { URI } from '../../base/common/uri.js'; +import { INativeWorkbenchEnvironmentService, NativeWorkbenchEnvironmentService } from '../../workbench/services/environment/electron-browser/environmentService.js'; +import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; +import { ILogService, ILoggerService, LogLevel } from '../../platform/log/common/log.js'; +import { NativeWorkbenchStorageService } from '../../workbench/services/storage/electron-browser/storageService.js'; +import { IAnyWorkspaceIdentifier, IWorkspaceContextService, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, reviveIdentifier } from '../../platform/workspace/common/workspace.js'; +import { IWorkbenchConfigurationService } from '../../workbench/services/configuration/common/configuration.js'; +import { IStorageService } from '../../platform/storage/common/storage.js'; +import { Disposable } from '../../base/common/lifecycle.js'; +import { ISharedProcessService } from '../../platform/ipc/electron-browser/services.js'; +import { IMainProcessService } from '../../platform/ipc/common/mainProcessService.js'; +import { SharedProcessService } from '../../workbench/services/sharedProcess/electron-browser/sharedProcessService.js'; +import { RemoteAuthorityResolverService } from '../../platform/remote/electron-browser/remoteAuthorityResolverService.js'; +import { IRemoteAuthorityResolverService, RemoteConnectionType } from '../../platform/remote/common/remoteAuthorityResolver.js'; +import { RemoteAgentService } from '../../workbench/services/remote/electron-browser/remoteAgentService.js'; +import { IRemoteAgentService } from '../../workbench/services/remote/common/remoteAgentService.js'; +import { FileService } from '../../platform/files/common/fileService.js'; +import { IFileService } from '../../platform/files/common/files.js'; +import { RemoteFileSystemProviderClient } from '../../workbench/services/remote/common/remoteFileSystemProviderClient.js'; +import { ISignService } from '../../platform/sign/common/sign.js'; +import { IProductService } from '../../platform/product/common/productService.js'; +import { IUriIdentityService } from '../../platform/uriIdentity/common/uriIdentity.js'; +import { UriIdentityService } from '../../platform/uriIdentity/common/uriIdentityService.js'; +import { INativeKeyboardLayoutService, NativeKeyboardLayoutService } from '../../workbench/services/keybinding/electron-browser/nativeKeyboardLayoutService.js'; +import { ElectronIPCMainProcessService } from '../../platform/ipc/electron-browser/mainProcessService.js'; +import { LoggerChannelClient } from '../../platform/log/common/logIpc.js'; +import { ProxyChannel } from '../../base/parts/ipc/common/ipc.js'; +import { NativeLogService } from '../../workbench/services/log/electron-browser/logService.js'; +import { WorkspaceTrustEnablementService, WorkspaceTrustManagementService } from '../../workbench/services/workspaces/common/workspaceTrust.js'; +import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService } from '../../platform/workspace/common/workspaceTrust.js'; +import { safeStringify } from '../../base/common/objects.js'; +import { IUtilityProcessWorkerWorkbenchService, UtilityProcessWorkerWorkbenchService } from '../../workbench/services/utilityProcess/electron-browser/utilityProcessWorkerWorkbenchService.js'; +import { isCI, isMacintosh, isTahoeOrNewer } from '../../base/common/platform.js'; +import { Schemas } from '../../base/common/network.js'; +import { DiskFileSystemProvider } from '../../workbench/services/files/electron-browser/diskFileSystemProvider.js'; +import { FileUserDataProvider } from '../../platform/userData/common/fileUserDataProvider.js'; +import { IUserDataProfilesService, reviveProfile } from '../../platform/userDataProfile/common/userDataProfile.js'; +import { UserDataProfilesService } from '../../platform/userDataProfile/common/userDataProfileIpc.js'; +import { PolicyChannelClient } from '../../platform/policy/common/policyIpc.js'; +import { NativeManagedSettingsChannelClient } from '../../platform/policy/common/nativeManagedSettingsIpc.js'; +import { IFileManagedSettingsService, INativeManagedSettingsService } from '../../platform/policy/common/copilotManagedSettings.js'; +import { FileManagedSettingsChannelClient } from '../../platform/policy/common/fileManagedSettingsIpc.js'; +import { IPolicyService } from '../../platform/policy/common/policy.js'; +import { UserDataProfileService } from '../../workbench/services/userDataProfile/common/userDataProfileService.js'; +import { IUserDataProfileService } from '../../workbench/services/userDataProfile/common/userDataProfile.js'; +import { BrowserSocketFactory } from '../../platform/remote/browser/browserSocketFactory.js'; +import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from '../../platform/remote/common/remoteSocketFactoryService.js'; +import { ElectronRemoteResourceLoader } from '../../platform/remote/electron-browser/electronRemoteResourceLoader.js'; +import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; +import { applyZoom } from '../../platform/window/electron-browser/window.js'; +import { mainWindow } from '../../base/browser/window.js'; +import { IDefaultAccountService } from '../../platform/defaultAccount/common/defaultAccount.js'; +import { AccountPolicyService, IAccountPolicyGateService } from '../../workbench/services/policies/common/accountPolicyService.js'; +import { MultiplexPolicyService } from '../../platform/policy/common/multiplexPolicyService.js'; +import { ReviewWorkbench } from '../browser/workbench.js'; +import { IWorkspaceEditingService } from '../../workbench/services/workspaces/common/workspaceEditing.js'; +import { ReviewConfigurationService } from '../services/configuration/browser/configurationService.js'; +import { ConfigurationCache } from '../../workbench/services/configuration/common/configurationCache.js'; +import { ReviewWorkspaceContextService } from '../services/workspace/browser/workspaceContextService.js'; +import { getWorkspaceIdentifier } from '../../platform/workspaces/common/workspaceIdentifier.js'; +import { ReviewDefaultAccountService } from '../services/reviewDefaultAccountService.js'; +import { reviewAgentsWindowDefaultOverrides } from '../common/reviewConfigurationDefaults.js'; + +export class ReviewMain extends Disposable { + + constructor( + private readonly configuration: INativeWindowConfiguration + ) { + super(); + + this.init(); + } + + private init(): void { + + // Massage configuration file URIs + this.reviveUris(); + + // Apply fullscreen early if configured + setFullscreen(!!this.configuration.fullscreen, mainWindow); + } + + private reviveUris() { + + // Workspace + const workspace = reviveIdentifier(this.configuration.workspace); + if (isWorkspaceIdentifier(workspace) || isSingleFolderWorkspaceIdentifier(workspace)) { + this.configuration.workspace = workspace; + } + + // Files + const filesToWait = this.configuration.filesToWait; + const filesToWaitPaths = filesToWait?.paths; + for (const paths of [filesToWaitPaths, this.configuration.filesToOpenOrCreate, this.configuration.filesToDiff, this.configuration.filesToMerge]) { + if (Array.isArray(paths)) { + for (const path of paths) { + if (path.fileUri) { + path.fileUri = URI.revive(path.fileUri); + } + } + } + } + + if (filesToWait) { + filesToWait.waitMarkerFileUri = URI.revive(filesToWait.waitMarkerFileUri); + } + } + + async open(): Promise { + + // Init services and wait for DOM to be ready in parallel + const [services] = await Promise.all([this.initServices(), domContentLoaded(mainWindow)]); + + // Apply zoom level early + this.applyWindowZoomLevel(services.configurationService); + + // Create Agentic Workbench + const workbench = new ReviewWorkbench(mainWindow.document.body, { + extraClasses: this.getExtraClasses(), + }, services.serviceCollection, services.logService); + + // Listeners + this.registerListeners(workbench, services.storageService); + + // Startup + const instantiationService = workbench.startup(); + + // Window + this._register(instantiationService.createInstance(NativeWindow)); + + } + + private applyWindowZoomLevel(configurationService: IConfigurationService) { + let zoomLevel: number | undefined = undefined; + if (this.configuration.isCustomZoomLevel && typeof this.configuration.zoomLevel === 'number') { + zoomLevel = this.configuration.zoomLevel; + } else { + const windowConfig = configurationService.getValue(); + zoomLevel = typeof windowConfig.window?.zoomLevel === 'number' ? windowConfig.window.zoomLevel : 0; + } + + applyZoom(zoomLevel, mainWindow); + } + + private getExtraClasses(): string[] { + if (isMacintosh && isTahoeOrNewer(this.configuration.os.release)) { + return ['macos-tahoe']; + } + + return []; + } + + private registerListeners(workbench: ReviewWorkbench, storageService: NativeWorkbenchStorageService): void { + + // Workbench Lifecycle + this._register(workbench.onWillShutdown(event => event.join(storageService.close(), { id: 'join.closeStorage', label: localize('join.closeStorage', "Saving UI state") }))); + this._register(workbench.onDidShutdown(() => this.dispose())); + } + + private async initServices(): Promise<{ serviceCollection: ServiceCollection; logService: ILogService; storageService: NativeWorkbenchStorageService; configurationService: ReviewConfigurationService }> { + const serviceCollection = new ServiceCollection(); + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // + // NOTE: Please do NOT register services here. Use `registerSingleton()` + // from `workbench.common.main.ts` if the service is shared between + // desktop and web. + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + + // Main Process + const mainProcessService = this._register(new ElectronIPCMainProcessService(this.configuration.windowId)); + serviceCollection.set(IMainProcessService, mainProcessService); + + // Product + const productService: IProductService = { _serviceBrand: undefined, ...product }; + serviceCollection.set(IProductService, productService); + + // Environment + const environmentService = new NativeWorkbenchEnvironmentService(this.configuration, productService); + serviceCollection.set(INativeWorkbenchEnvironmentService, environmentService); + + // Logger + const loggers = this.configuration.loggers.map(loggerResource => ({ ...loggerResource, resource: URI.revive(loggerResource.resource) })); + const loggerService = new LoggerChannelClient(this.configuration.windowId, this.configuration.logLevel, environmentService.windowLogsPath, loggers, mainProcessService.getChannel('logger')); + serviceCollection.set(ILoggerService, loggerService); + + // Log + const logService = this._register(new NativeLogService(loggerService, environmentService)); + serviceCollection.set(ILogService, logService); + if (isCI) { + logService.info('workbench#open()'); // marking workbench open helps to diagnose flaky integration/smoke tests + } + if (logService.getLevel() === LogLevel.Trace) { + logService.trace('workbench#open(): with configuration', safeStringify({ ...this.configuration, nls: undefined /* exclude large property */ })); + } + + // Default Account + const defaultAccountService = this._register(new ReviewDefaultAccountService()); + serviceCollection.set(IDefaultAccountService, defaultAccountService); + + // Policies + let policyService: IPolicyService; + const policyChannel = this.configuration.policiesData ? this._register(new PolicyChannelClient(this.configuration.policiesData, mainProcessService.getChannel('policy'))) : undefined; + const nativeManagedSettings = this._register(new NativeManagedSettingsChannelClient(mainProcessService.getChannel('nativeManagedSettings'))); + serviceCollection.set(INativeManagedSettingsService, nativeManagedSettings); + const fileManagedSettings = this._register(new FileManagedSettingsChannelClient(mainProcessService.getChannel('fileManagedSettings'))); + serviceCollection.set(IFileManagedSettingsService, fileManagedSettings); + const accountPolicy = this._register(new AccountPolicyService(logService, defaultAccountService, policyChannel, nativeManagedSettings, fileManagedSettings)); + if (policyChannel) { + policyService = this._register(new MultiplexPolicyService([policyChannel, accountPolicy], logService)); + } else { + policyService = accountPolicy; + } + serviceCollection.set(IPolicyService, policyService); + serviceCollection.set(IAccountPolicyGateService, accountPolicy); + + // Shared Process + const sharedProcessService = new SharedProcessService(this.configuration.windowId, logService); + serviceCollection.set(ISharedProcessService, sharedProcessService); + + // Utility Process Worker + const utilityProcessWorkerWorkbenchService = new UtilityProcessWorkerWorkbenchService(this.configuration.windowId, logService, mainProcessService); + serviceCollection.set(IUtilityProcessWorkerWorkbenchService, utilityProcessWorkerWorkbenchService); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // + // NOTE: Please do NOT register services here. Use `registerSingleton()` + // from `workbench.common.main.ts` if the service is shared between + // desktop and web. + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + + // Sign + const signService = ProxyChannel.toService(mainProcessService.getChannel('sign')); + serviceCollection.set(ISignService, signService); + + // Files + const fileService = this._register(new FileService(logService)); + serviceCollection.set(IFileService, fileService); + + // Remote + const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, new ElectronRemoteResourceLoader(environmentService.window.id, mainProcessService, fileService)); + serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); + + // Local Files + const diskFileSystemProvider = this._register(new DiskFileSystemProvider(mainProcessService, utilityProcessWorkerWorkbenchService, logService, loggerService)); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + + // URI Identity + const uriIdentityService = new UriIdentityService(fileService); + serviceCollection.set(IUriIdentityService, uriIdentityService); + + // User Data Profiles + const userDataProfilesService = new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home).with({ scheme: environmentService.userRoamingDataHome.scheme }), mainProcessService.getChannel('userDataProfiles')); + serviceCollection.set(IUserDataProfilesService, userDataProfilesService); + const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.profile, userDataProfilesService.profilesHome.scheme)); + serviceCollection.set(IUserDataProfileService, userDataProfileService); + + // Use FileUserDataProvider for user data to + // enable atomic read / write operations. + fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))); + + // Remote Agent + const remoteSocketFactoryService = new RemoteSocketFactoryService(); + remoteSocketFactoryService.register(RemoteConnectionType.WebSocket, new BrowserSocketFactory(null)); + serviceCollection.set(IRemoteSocketFactoryService, remoteSocketFactoryService); + const remoteAgentService = this._register(new RemoteAgentService(remoteSocketFactoryService, userDataProfileService, environmentService, productService, remoteAuthorityResolverService, signService, logService)); + serviceCollection.set(IRemoteAgentService, remoteAgentService); + + // Remote Files + this._register(RemoteFileSystemProviderClient.register(remoteAgentService, fileService, logService)); + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // + // NOTE: Please do NOT register services here. Use `registerSingleton()` + // from `workbench.common.main.ts` if the service is shared between + // desktop and web. + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + const workspaceIdentifier = getWorkspaceIdentifier(environmentService.agentSessionsWorkspace); + const workspaceContextService = new ReviewWorkspaceContextService(workspaceIdentifier, uriIdentityService); + + // Workspace + serviceCollection.set(IWorkspaceContextService, workspaceContextService); + serviceCollection.set(IWorkspaceEditingService, workspaceContextService); + + const [configurationService, storageService] = await Promise.all([ + this.createConfigurationService(workspaceContextService, userDataProfileService, uriIdentityService, fileService, logService, policyService, environmentService).then(configurationService => { + + // Configuration + serviceCollection.set(IWorkbenchConfigurationService, configurationService); + + return configurationService; + }), + + this.createStorageService(workspaceIdentifier, environmentService, userDataProfileService, userDataProfilesService, mainProcessService).then(service => { + + // Storage + serviceCollection.set(IStorageService, service); + + return service; + }), + + this.createKeyboardLayoutService(mainProcessService).then(service => { + + // KeyboardLayout + serviceCollection.set(INativeKeyboardLayoutService, service); + + return service; + }) + ]); + + // Workspace Trust Service + const workspaceTrustEnablementService = new WorkspaceTrustEnablementService(configurationService, environmentService); + serviceCollection.set(IWorkspaceTrustEnablementService, workspaceTrustEnablementService); + + const workspaceTrustManagementService = new WorkspaceTrustManagementService(configurationService, remoteAuthorityResolverService, storageService, uriIdentityService, environmentService, workspaceContextService, workspaceTrustEnablementService, fileService); + serviceCollection.set(IWorkspaceTrustManagementService, workspaceTrustManagementService); + + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // + // NOTE: Please do NOT register services here. Use `registerSingleton()` + // from `workbench.common.main.ts` if the service is shared between + // desktop and web. + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + + return { serviceCollection, logService, storageService, configurationService }; + } + + private async createConfigurationService( + workspaceContextService: ReviewWorkspaceContextService, + userDataProfileService: IUserDataProfileService, + uriIdentityService: IUriIdentityService, + fileService: FileService, + logService: ILogService, + policyService: IPolicyService, + environmentService: INativeWorkbenchEnvironmentService, + ): Promise { + const configurationCache = new ConfigurationCache([Schemas.file, Schemas.vscodeUserData], environmentService, fileService); + const configurationService = new ReviewConfigurationService(userDataProfileService, workspaceContextService, uriIdentityService, fileService, policyService, logService, configurationCache, environmentService, { defaultOverrides: reviewAgentsWindowDefaultOverrides }); + try { + await configurationService.initialize(); + } catch (error) { + onUnexpectedError(error); + } + + return configurationService; + } + + private async createStorageService(workspace: IAnyWorkspaceIdentifier, environmentService: INativeWorkbenchEnvironmentService, userDataProfileService: IUserDataProfileService, userDataProfilesService: IUserDataProfilesService, mainProcessService: IMainProcessService): Promise { + const storageService = new NativeWorkbenchStorageService(workspace, userDataProfileService, userDataProfilesService, mainProcessService, environmentService); + + try { + await storageService.initialize(); + + return storageService; + } catch (error) { + onUnexpectedError(error); + + return storageService; + } + } + + private async createKeyboardLayoutService(mainProcessService: IMainProcessService): Promise { + const keyboardLayoutService = new NativeKeyboardLayoutService(mainProcessService); + + try { + await keyboardLayoutService.initialize(); + + return keyboardLayoutService; + } catch (error) { + onUnexpectedError(error); + + return keyboardLayoutService; + } + } +} + +export interface IDesktopMain { + main(configuration: INativeWindowConfiguration): Promise; +} + +export function main(configuration: INativeWindowConfiguration): Promise { + const workbench = new ReviewMain(configuration); + + return workbench.open(); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewBackgroundLaunch.test.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewBackgroundLaunch.test.ts new file mode 100644 index 000000000..cf8beaed6 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewBackgroundLaunch.test.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { FocusMode } from "../../platform/native/common/native.js"; +import { ReviewBackgroundLaunch } from "./reviewBackgroundLaunch.js"; + +const background = { DEV_FAST_REVIEW_DESKTOP_BACKGROUND: "1" }; + +function fakeWindow() { + const calls: string[] = []; + let onFocus: (() => void) | undefined; + return { + calls, + focusFromUser: () => onFocus?.(), + win: { + show: () => calls.push("show"), + showInactive: () => calls.push("showInactive"), + once: (_event: "focus", listener: () => void) => { onFocus = listener; }, + }, + }; +} + +test("a normal launch leaves window creation and focus alone", () => { + const launch = new ReviewBackgroundLaunch({}); + const options = { show: true }; + const { win, calls } = fakeWindow(); + launch.prepare(options); + launch.attach(win); + launch.show(win); + assert.equal(options.show, true); + assert.deepEqual(calls, ["show"]); + assert.equal(launch.allowsFocus(FocusMode.Transfer), true); +}); + +test("a background launch shows the first window inactive and swallows focus until the user clicks", () => { + const launch = new ReviewBackgroundLaunch(background); + const options = { show: true }; + const { win, calls, focusFromUser } = fakeWindow(); + launch.prepare(options); + assert.equal(options.show, false); + launch.attach(win); + assert.deepEqual(calls, ["showInactive"]); + assert.equal(launch.allowsFocus(FocusMode.Transfer), false); + assert.equal(launch.allowsFocus(FocusMode.Notify), true); + focusFromUser(); + assert.equal(launch.suppressesFocus, false); + assert.equal(launch.allowsFocus(FocusMode.Transfer), true); + launch.show(win); + assert.deepEqual(calls, ["showInactive", "show"]); +}); + +test("a window that upstream shows later is shown inactive there instead", () => { + const launch = new ReviewBackgroundLaunch(background); + const options = { show: false }; // maximized or fullscreen restore + const { win, calls } = fakeWindow(); + launch.prepare(options); + launch.attach(win); + assert.deepEqual(calls, []); + launch.show(win); + assert.deepEqual(calls, ["showInactive"]); +}); + +test("a forced focus releases the gate", () => { + const launch = new ReviewBackgroundLaunch(background); + assert.equal(launch.allowsFocus(FocusMode.Force), true); + assert.equal(launch.suppressesFocus, false); +}); + +test("only the value 1 marks a background launch", () => { + assert.equal(new ReviewBackgroundLaunch({ DEV_FAST_REVIEW_DESKTOP_BACKGROUND: "0" }).suppressesFocus, false); + assert.equal(new ReviewBackgroundLaunch({ DEV_FAST_REVIEW_DESKTOP_BACKGROUND: "" }).suppressesFocus, false); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewBackgroundLaunch.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewBackgroundLaunch.ts new file mode 100644 index 000000000..299c90f65 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewBackgroundLaunch.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { FocusMode } from "../../platform/native/common/native.js"; + +/** "1" on `review app` launches without --focus. */ +export const REVIEW_DESKTOP_BACKGROUND_ENV = "DEV_FAST_REVIEW_DESKTOP_BACKGROUND"; + +interface BackgroundWindow { + show(): void; + showInactive(): void; + once(event: "focus", listener: () => void): unknown; +} + +/** + * Shows the first window inactive and swallows focus until the user focuses a + * window or a forced focus arrives. Releases once per process. + */ +export class ReviewBackgroundLaunch { + private pending: boolean; + private showInactiveOnCreate = false; + + constructor(env: NodeJS.ProcessEnv = process.env) { + this.pending = env[REVIEW_DESKTOP_BACKGROUND_ENV] === "1"; + } + + get suppressesFocus(): boolean { + return this.pending; + } + + /** Defers the initial show to `attach`, which shows the window inactive. */ + prepare(options: { show?: boolean }): void { + if (!this.pending || options.show === false) return; + options.show = false; + this.showInactiveOnCreate = true; + } + + attach(win: BackgroundWindow): void { + if (!this.pending) return; + if (this.showInactiveOnCreate) win.showInactive(); + win.once("focus", () => this.release()); + } + + /** show() activates the app on macOS. */ + show(win: BackgroundWindow | null | undefined): void { + if (this.pending) win?.showInactive(); + else win?.show(); + } + + allowsFocus(mode: FocusMode): boolean { + if (!this.pending) return true; + if (mode === FocusMode.Force) { + this.release(); + return true; + } + return mode === FocusMode.Notify; + } + + private release(): void { + this.pending = false; + this.showInactiveOnCreate = false; + } +} + +export const reviewBackgroundLaunch = new ReviewBackgroundLaunch(); diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewDesktopChannel.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewDesktopChannel.ts new file mode 100644 index 000000000..d32e387f2 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewDesktopChannel.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from "../../base/common/event.js"; +import { IServerChannel } from "../../base/parts/ipc/common/ipc.js"; +import type { ReviewDesktopConnection } from "../common/reviewDesktopBootstrap.js"; +import type { ReviewDesktopHost } from "./reviewDesktopHost.js"; + +export { REVIEW_DESKTOP_CHANNEL } from "../common/reviewDesktopBootstrap.js"; + +/** + * Hands the renderer the endpoint the main process validated. Bootstrap details + * deliberately do not travel through the window configuration or the process + * environment: the main process is the only owner of the server credentials. + */ +export class ReviewDesktopChannel implements IServerChannel { + constructor(private readonly host: ReviewDesktopHost) {} + + listen(): Event { + return Event.None as Event; + } + + async call(_context: string, command: string): Promise { + if (command === "getConnection") { + const connection: ReviewDesktopConnection = await this.host.whenConnected(); + return connection as T; + } + if (command === "stageRustAnalyzer") { + this.host.stageRustAnalyzer(); + return undefined as T; + } + throw new Error(`Unknown Review Desktop channel call: ${command}`); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewDesktopHost.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewDesktopHost.ts new file mode 100644 index 000000000..425e4caee --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewDesktopHost.ts @@ -0,0 +1,151 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable, toDisposable } from "../../base/common/lifecycle.js"; +import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; +import { IEnvironmentMainService } from "../../platform/environment/electron-main/environmentMainService.js"; +import { ILifecycleMainService } from "../../platform/lifecycle/electron-main/lifecycleMainService.js"; +import { ILogService } from "../../platform/log/common/log.js"; +import { IProductService } from "../../platform/product/common/productService.js"; +import { getResolvedShellEnv } from "../../platform/shell/node/shellEnv.js"; +import { IApplicationStorageMainService } from "../../platform/storage/electron-main/storageMainService.js"; +import { NullTelemetryService } from "../../platform/telemetry/common/telemetryUtils.js"; +import { IUpdateService } from "../../platform/update/common/update.js"; +import { UtilityProcess } from "../../platform/utilityProcess/electron-main/utilityProcess.js"; +import type { ReviewDesktopConnection } from "../common/reviewDesktopBootstrap.js"; +import { REVIEW_TELEMETRY_SETTING } from "../common/reviewConfigurationDefaults.js"; +import { ReviewMainErrorTelemetry } from "./reviewMainErrorTelemetry.js"; +import { ReviewServerSupervisor } from "./reviewServerSupervisor.js"; +import { + darwinShipItLogPath, + ReviewUpdateTelemetry, +} from "./reviewUpdateTelemetry.js"; + +/** + * Binds the embedded Review server's lifetime to the application's. All of the + * supervision logic lives in `ReviewServerSupervisor`, which holds no Electron + * dependency so it stays testable; this class only supplies the platform. + */ +export class ReviewDesktopHost extends Disposable { + private readonly supervisor: ReviewServerSupervisor; + private terminating = false; + + private readonly onTerminationSignal = () => { + if (this.terminating) return; + this.terminating = true; + void this.lifecycleMainService.kill(0); + }; + + constructor( + @IConfigurationService + private readonly configurationService: IConfigurationService, + @ILogService private readonly logService: ILogService, + @ILifecycleMainService + private readonly lifecycleMainService: ILifecycleMainService, + @IEnvironmentMainService + private readonly environmentMainService: IEnvironmentMainService, + @IProductService private readonly productService: IProductService, + @IUpdateService private readonly updateService: IUpdateService, + @IApplicationStorageMainService + private readonly applicationStorageMainService: IApplicationStorageMainService, + ) { + super(); + let resolvedEnvironment: Promise | undefined; + this.supervisor = this._register( + new ReviewServerSupervisor({ + appRoot: this.environmentMainService.appRoot, + isBuilt: this.environmentMainService.isBuilt, + userExtensionsPath: this.environmentMainService.extensionsPath, + appVersion: + this.productService.reviewVersion ?? this.productService.version, + appUrlProtocol: this.productService.urlProtocol, + serverEntryOverride: process.env["DEV_FAST_REVIEW_SERVER_ENTRY"], + resolveEnvironment: () => + (resolvedEnvironment ??= getResolvedShellEnv( + this.configurationService, + this.logService, + this.environmentMainService.args, + process.env, + )), + logInfo: (message) => this.logService.info(message), + logError: (message) => this.logService.error(message), + createProcess: () => + new UtilityProcess( + this.logService, + NullTelemetryService, + this.lifecycleMainService, + ), + telemetryEnabled: + this.configurationService.getValue(REVIEW_TELEMETRY_SETTING) !== + false, + }), + ); + this._register( + this.configurationService.onDidChangeConfiguration((event) => { + if (!event.affectsConfiguration(REVIEW_TELEMETRY_SETTING)) return; + this.supervisor.setTelemetryEnabled( + this.configurationService.getValue( + REVIEW_TELEMETRY_SETTING, + ) !== false, + ); + }), + ); + this._register( + this.lifecycleMainService.onWillShutdown((event) => { + event.join("reviewDesktopHost", this.supervisor.stop()); + }), + ); + // Main-process errors report through the embedded server, so they pass the + // same opt-out checks and the same redaction step as every other event. + const errorTelemetry = new ReviewMainErrorTelemetry({ + whenConnected: () => this.whenConnected(), + isTelemetryEnabled: () => + this.configurationService.getValue(REVIEW_TELEMETRY_SETTING) !== + false, + userDataPath: this.environmentMainService.userDataPath, + logError: (message) => this.logService.error(message), + }); + this._register(toDisposable(() => errorTelemetry.dispose())); + this._register( + new ReviewUpdateTelemetry({ + updateService: this.updateService, + storageService: this.applicationStorageMainService, + telemetry: errorTelemetry, + isTelemetryEnabled: () => + this.configurationService.getValue( + REVIEW_TELEMETRY_SETTING, + ) !== false, + shipItLogPath: this.productService.darwinBundleIdentifier + ? darwinShipItLogPath( + this.environmentMainService.userHome.fsPath, + this.productService.darwinBundleIdentifier, + ) + : undefined, + logError: (message) => this.logService.error(message), + }), + ); + process.once("SIGINT", this.onTerminationSignal); + process.once("SIGTERM", this.onTerminationSignal); + this.supervisor.start(); + } + + /** + * Resolves once the embedded server has announced a validated endpoint. The + * renderer awaits this instead of reading bootstrap environment variables. + */ + whenConnected(): Promise { + return this.supervisor.whenConnected(); + } + + stageRustAnalyzer(): void { + this.supervisor.stageRustAnalyzer(); + } + + override dispose(): void { + process.off("SIGINT", this.onTerminationSignal); + process.off("SIGTERM", this.onTerminationSignal); + super.dispose(); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMainErrorTelemetry.test.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMainErrorTelemetry.test.ts new file mode 100644 index 000000000..09136b8ea --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMainErrorTelemetry.test.ts @@ -0,0 +1,48 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { ReviewMainErrorTelemetry } from "./reviewMainErrorTelemetry.js"; + +test("posts named main-process telemetry through the embedded server", async () => { + const requests: RequestInit[] = []; + const telemetry = new ReviewMainErrorTelemetry({ + whenConnected: async () => ({ + version: 3, + url: "http://127.0.0.1:1234/__progressive-review", + token: "secret", + instanceId: "instance", + }), + isTelemetryEnabled: () => true, + fetchImpl: async (_input, init) => { + requests.push(init ?? {}); + return new Response(null, { status: 204 }); + }, + }); + telemetry.capture( + "update_failed", + { phase: "download", message_source: "electron" }, + { + name: "UpdateDownloadError", + message: "Download failed", + stack: "Update lifecycle telemetry", + }, + ); + await new Promise((resolve) => setImmediate(resolve)); + + assert.equal(requests.length, 1); + assert.deepEqual(JSON.parse(String(requests[0].body)), { + name: "update_failed", + properties: { phase: "download", message_source: "electron" }, + error: { + name: "UpdateDownloadError", + message: "Download failed", + stack: "Update lifecycle telemetry", + }, + }); + telemetry.dispose(); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMainErrorTelemetry.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMainErrorTelemetry.ts new file mode 100644 index 000000000..7c4daa98c --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMainErrorTelemetry.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { errorHandler } from "../../base/common/errors.js"; +import { generateUuid } from "../../base/common/uuid.js"; +import type { ReviewDesktopConnection } from "../common/reviewDesktopBootstrap.js"; +import { + ReviewErrorReportLimiter, + type ReviewErrorReport, +} from "../common/reviewErrorReport.js"; +import { reviewTelemetryEventRequest } from "../common/reviewTelemetryRequest.js"; +import { drainReviewBootstrapBreadcrumbs } from "../node/reviewBootstrapBreadcrumb.js"; + +export interface ReviewMainErrorTelemetryOptions { + /** Resolves with the loopback endpoint and token of the embedded server. */ + readonly whenConnected: () => Promise; + /** Reads `review.telemetry.enabled` at the moment of the error. */ + readonly isTelemetryEnabled: () => boolean; + /** + * The Electron user data directory, where a crash that happened before the + * last launch could start leaves its note. Omit it to skip that check. + */ + readonly userDataPath?: string; + readonly logError?: (message: string) => void; + readonly fetchImpl?: typeof fetch; + readonly maxQueued?: number; +} + +const DEFAULT_MAX_QUEUED = 20; +const MAX_BOOTSTRAP_REPORTS = 5; + +interface PendingReviewTelemetryEvent { + readonly name: string; + readonly properties: Readonly>; + readonly error?: ReviewErrorReport; +} + +/** + * Reports Electron main-process telemetry through the embedded Review server. + * + * The upstream `ErrorTelemetry` already routes `uncaughtException` and + * `unhandledRejection` into `onUnexpectedError`, so listening on the shared + * error handler covers every main-process error without touching a vendored + * file. + * + * The report goes to the loopback server, never straight to a vendor. That is + * deliberate: the server holds the opt-out checks and the redaction step, and a + * direct call from here would bypass both. + */ +export class ReviewMainErrorTelemetry { + readonly appSessionId = generateUuid(); + + private readonly limiter = new ReviewErrorReportLimiter(); + private readonly queued: PendingReviewTelemetryEvent[] = []; + private readonly unbind: () => void; + private connection: ReviewDesktopConnection | undefined; + private disposed = false; + + constructor(private readonly options: ReviewMainErrorTelemetryOptions) { + this.unbind = errorHandler.addListener((error) => this.report(error)); + this.queueBootstrapBreadcrumbs(); + void this.options + .whenConnected() + .then((connection) => { + this.connection = connection; + this.drain(); + }) + .catch(() => undefined); + } + + /** Report an error that Review packed itself, such as a startup crash note. */ + send(errorSource: string, report: ReviewErrorReport): void { + this.capture( + "client_error", + { + error_source: errorSource, + error_process: "main", + }, + report, + ); + } + + /** Queue a named Review telemetry event for the embedded server. */ + capture( + name: string, + properties: Readonly> = {}, + error?: ReviewErrorReport, + ): void { + if (this.disposed) return; + const pending = { name, properties, error }; + if (this.connection) { + this.post(pending); + return; + } + this.queued.push(pending); + // The connection never resolves when the server cannot start, so the cap is + // what bounds this queue. + if (this.queued.length > (this.options.maxQueued ?? DEFAULT_MAX_QUEUED)) { + this.queued.shift(); + } + } + + dispose(): void { + this.disposed = true; + this.queued.length = 0; + this.unbind(); + } + + private report(error: unknown): void { + if (this.disposed) return; + this.limiter.report(error, (report) => + this.send("main_unexpected", report), + ); + } + + /** + * Pick up a crash that happened before the last launch could start. The note + * file is always deleted, whether or not these entries are ever sent, so an + * opted-out user never accumulates one. + */ + private queueBootstrapBreadcrumbs(): void { + const userDataPath = this.options.userDataPath; + if (!userDataPath) return; + try { + for (const breadcrumb of drainReviewBootstrapBreadcrumbs( + userDataPath, + ).slice(0, MAX_BOOTSTRAP_REPORTS)) { + this.send("bootstrap", { + name: breadcrumb.name, + message: breadcrumb.message, + stack: breadcrumb.stack, + }); + } + } catch { + // A crash note must never keep the app from starting. + } + } + + private drain(): void { + for (const pending of this.queued.splice(0)) this.post(pending); + } + + private post(pending: PendingReviewTelemetryEvent): void { + const connection = this.connection; + if (!connection) return; + // Read the setting at send time, not at construction: a user may turn + // telemetry off between the two. + if (!this.options.isTelemetryEnabled()) return; + const send = this.options.fetchImpl ?? fetch; + try { + void send( + `${connection.url}/telemetry/event`, + reviewTelemetryEventRequest( + { token: connection.token, appSessionId: this.appSessionId }, + { + name: pending.name, + properties: pending.properties, + error: pending.error, + }, + ), + ).catch(() => undefined); + } catch (error) { + this.options.logError?.( + `[Review Desktop] could not report a main-process telemetry event: ${error}`, + ); + } + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMenubar.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMenubar.ts new file mode 100644 index 000000000..b9e592182 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewMenubar.ts @@ -0,0 +1,372 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { app, BrowserWindow, Menu, MenuItem } from "electron"; +import { RunOnceScheduler } from "../../base/common/async.js"; +import { CancellationToken } from "../../base/common/cancellation.js"; +import { Disposable } from "../../base/common/lifecycle.js"; +import { isMacintosh } from "../../base/common/platform.js"; +import { localize } from "../../nls.js"; +import { + ILifecycleMainService, + LifecycleMainPhase, +} from "../../platform/lifecycle/electron-main/lifecycleMainService.js"; +import { ILogService } from "../../platform/log/common/log.js"; +import type { IMenubarData } from "../../platform/menubar/common/menubar.js"; +import type { IMenubarMainService } from "../../platform/menubar/electron-main/menubarMainService.js"; +import { INativeHostMainService } from "../../platform/native/electron-main/nativeHostMainService.js"; +import { IProductService } from "../../platform/product/common/productService.js"; +import type { INativeRunActionInWindowRequest } from "../../platform/window/common/window.js"; +import { IWindowsMainService } from "../../platform/windows/electron-main/windows.js"; +import { + IUpdateService, + StateType, +} from "../../platform/update/common/update.js"; + +function labelsOf(menu: Menu): string { + return menu.items + .map((item) => { + if (item.type === "separator") return "---"; + // A submenu hides its items from the log, and the log is the only record + // of the native menu the user got. + const nested = item.submenu?.items.length + ? ` (${labelsOf(item.submenu)})` + : ""; + return `${item.label}${nested}`; + }) + .join(" | "); +} + +/** + * Review's native macOS menu bar. + * + * Stock Code OSS builds its menu from `IMenubarData` that the renderer's + * `MenubarControl` pushes over the `menubar` channel. Review replaces the + * workbench and never creates that control, so `Menubar` only ever installed an + * empty menu. This service owns the menu in the main process instead: it needs + * no renderer state, which also keeps "Check for Updates..." working while the + * renderer's `IUpdateService` stays a stub. + * + * The menu is deliberately small — the three menus a Mac application must have. + * Everything else in Review is reachable from the command palette. + */ +export class ReviewMenubarMainService + extends Disposable + implements IMenubarMainService +{ + declare readonly _serviceBrand: undefined; + + private readonly scheduler = this._register( + new RunOnceScheduler(() => this.install(), 0), + ); + + constructor( + @ILifecycleMainService lifecycleMainService: ILifecycleMainService, + @IUpdateService private readonly updateService: IUpdateService, + @INativeHostMainService + private readonly nativeHostMainService: INativeHostMainService, + @IProductService private readonly productService: IProductService, + @IWindowsMainService + private readonly windowsMainService: IWindowsMainService, + @ILogService private readonly logService: ILogService, + ) { + super(); + + lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => { + if (this._store.isDisposed) return; + + this.configureAboutPanel(); + this.install(); + + // The update item's label is the update state in disguise, so every + // state change reinstalls the menu. + this._register(this.updateService.onStateChange(() => this.schedule())); + }); + } + + /** + * Fills in the stock macOS About panel. It is a native window, so it needs no + * renderer and it opens even when every window is closed. + */ + private configureAboutPanel(): void { + if (!isMacintosh) return; + + const { reviewVersion, version, commit } = this.productService; + + // `version` is the Code OSS base version, which means nothing to a reader. + // Show Review's own release number and keep the base version in the credits. + app.setAboutPanelOptions({ + applicationName: this.productService.nameLong, + applicationVersion: reviewVersion ?? version, + // macOS prints this in parentheses after the version. The commit is what + // the update feed matches on, so it is the build identity that matters. + version: commit ? commit.substring(0, 10) : "", + copyright: localize("review.about.copyright", "Copyright © 2026 /dev/fast"), + credits: localize("review.about.codeOss", "Code OSS {0}", version), + }); + } + + /** + * No-op. The renderer keeps `menubarService` registered, so the channel must + * stay answerable, but Review never sends menu data. + */ + async updateMenubar( + _windowId: number, + _menus: IMenubarData, + ): Promise {} + + private schedule(): void { + // Electron cannot mutate a live menu, so every change reinstalls the whole + // menu. Buffer overlapping changes into one rebuild. + if (!this.scheduler.isScheduled()) { + this.scheduler.schedule(); + } + } + + private install(): void { + if (!isMacintosh) { + // Review hides the menu bar on Windows and Linux + // (`window.menuBarVisibility`), so there is nothing to install there. + Menu.setApplicationMenu(null); + return; + } + + const applicationMenu = this.createApplicationMenu(); + const menubar = new Menu(); + menubar.append( + new MenuItem({ + label: this.productService.nameShort, + submenu: applicationMenu, + }), + ); + const editMenuItem = new MenuItem({ + label: localize("review.menu.edit", "Edit"), + role: "editMenu", + }); + editMenuItem.submenu?.insert( + 2, + new MenuItem({ + label: localize("review.menu.find", "Find"), + accelerator: "Command+F", + // Show the standard shortcut in the native menu, but let the focused + // renderer resolve it. Tree, webview, notebook, source, and + // Review each own a context-specific Find command. + registerAccelerator: false, + click: () => this.runActionInFocusedWindow("review.action.find"), + }), + ); + menubar.append(editMenuItem); + menubar.append( + new MenuItem({ + label: localize("review.menu.window", "Window"), + role: "windowMenu", + }), + ); + + Menu.setApplicationMenu(menubar); + + // The menu is native, so this log is the only record of what the user got. + // It also names the update item, which is the update state in disguise. + this.logService.info( + `reviewMenubar#install - menus [${labelsOf(menubar)}], application menu [${labelsOf(applicationMenu)}]`, + ); + } + + private createApplicationMenu(): Menu { + const name = this.productService.nameLong; + const menu = new Menu(); + + menu.append( + new MenuItem({ + label: localize("review.menu.about", "About {0}", name), + role: "about", + }), + ); + + for (const item of this.createUpdateMenuItems()) { + menu.append(item); + } + + // The macOS settings slot. Every item runs the same renderer action as its + // command palette entry. Electron consumes the accelerator before the web + // contents, so the workbench keybinding on review.openSettings and this + // item cannot both fire. + const preferences = new Menu(); + preferences.append( + new MenuItem({ + label: localize("review.menu.settings", "Settings..."), + accelerator: "Command+,", + click: () => this.runActionInFocusedWindow("review.openSettings"), + }), + ); + // The Welcome pane stays reachable after Home fills with reviews: first + // run opens no tab of its own, so this is the durable path back. + preferences.append( + new MenuItem({ + label: localize("review.menu.gettingStarted", "Getting Started..."), + click: () => this.runActionInFocusedWindow("review.openWelcome"), + }), + ); + preferences.append(new MenuItem({ type: "separator" })); + preferences.append( + new MenuItem({ + label: localize( + "review.menu.uninstall", + "Uninstall Review Desktop...", + ), + click: () => this.runActionInFocusedWindow("review.uninstallApp"), + }), + ); + + menu.append(new MenuItem({ type: "separator" })); + menu.append( + new MenuItem({ + label: localize("review.menu.preferences", "Preferences"), + submenu: preferences, + }), + ); + + menu.append(new MenuItem({ type: "separator" })); + menu.append( + new MenuItem({ + label: localize("review.menu.services", "Services"), + role: "services", + submenu: [], + }), + ); + menu.append(new MenuItem({ type: "separator" })); + menu.append( + new MenuItem({ + label: localize("review.menu.hide", "Hide {0}", name), + role: "hide", + }), + ); + menu.append( + new MenuItem({ + label: localize("review.menu.hideOthers", "Hide Others"), + role: "hideOthers", + }), + ); + menu.append( + new MenuItem({ + label: localize("review.menu.showAll", "Show All"), + role: "unhide", + }), + ); + menu.append(new MenuItem({ type: "separator" })); + menu.append( + new MenuItem({ + label: localize("review.menu.quit", "Quit {0}", name), + accelerator: "Command+Q", + click: () => this.nativeHostMainService.quit(undefined), + }), + ); + + return menu; + } + + /** + * Runs a renderer command in the focused (or last active) window, mirroring + * stock `Menubar#runActionInRenderer`. Review has no auxiliary windows, so + * the focused Electron window maps straight to a workbench window. + */ + private runActionInFocusedWindow(commandId: string): void { + const focused = BrowserWindow.getFocusedWindow(); + const window = focused + ? this.windowsMainService.getWindowById(focused.id) + : this.windowsMainService.getLastActiveWindow(); + if (!window) { + this.logService.info( + `reviewMenubar#runActionInFocusedWindow - no window for ${commandId}`, + ); + return; + } + const payload: INativeRunActionInWindowRequest = { + id: commandId, + from: "menu", + }; + window.sendWhenReady("vscode:runAction", CancellationToken.None, payload); + } + + /** + * The update item, mirroring stock Code OSS's app menu. Updates are disabled + * out of sources, so this contributes nothing to a development run. + */ + private createUpdateMenuItems(): MenuItem[] { + switch (this.updateService.state.type) { + case StateType.Idle: + return [ + new MenuItem({ + label: localize("review.menu.checkForUpdates", "Check for Updates..."), + // Detached so the menu closes before the check's dialog can open. + click: () => + setTimeout(() => { + this.updateService.checkForUpdates(true).catch((error) => { + this.logService.error( + "reviewMenubar#checkForUpdates failed", + error, + ); + }); + }, 0), + }), + ]; + + case StateType.CheckingForUpdates: + return [ + new MenuItem({ + label: localize( + "review.menu.checkingForUpdates", + "Checking for Updates...", + ), + enabled: false, + }), + ]; + + case StateType.Downloading: + case StateType.Overwriting: + return [ + new MenuItem({ + label: localize( + "review.menu.downloadingUpdate", + "Downloading Update...", + ), + enabled: false, + }), + ]; + + case StateType.Updating: + return [ + new MenuItem({ + label: localize( + "review.menu.installingUpdate", + "Installing Update...", + ), + enabled: false, + }), + ]; + + case StateType.Ready: + return [ + new MenuItem({ + label: localize("review.menu.restartToUpdate", "Restart to Update"), + click: () => { + this.updateService.quitAndInstall().catch((error) => { + this.logService.error( + "reviewMenubar#quitAndInstall failed", + error, + ); + }); + }, + }), + ]; + + // Disabled, Uninitialized, and the macOS-unreachable download states + // contribute nothing. + default: + return []; + } + } + +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewServerSupervisor.test.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewServerSupervisor.test.ts new file mode 100644 index 000000000..7532c1cbb --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewServerSupervisor.test.ts @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { createReviewServerEnvironment } from './reviewServerSupervisor.js'; + +test('the trusted product version overrides inherited environment values', () => { + const environment = createReviewServerEnvironment({ + applicationEnvironment: { + DEV_FAST_REVIEW_APP_VERSION: '0.0.1', + PATH: '/application/bin', + }, + resolvedEnvironment: { + DEV_FAST_REVIEW_APP_VERSION: '99.0.0', + PATH: '/login/bin', + }, + appVersion: '0.0.16', + serverEntry: '/review/server.js', + port: 4321, + token: 'token', + instanceId: 'instance', + appPid: 1234, + telemetryEnabled: true, + }); + + assert.equal(environment.PATH, '/login/bin'); + assert.equal(environment.DEV_FAST_REVIEW_APP_VERSION, '0.0.16'); + assert.equal(environment.DEV_FAST_REVIEW_SERVER_ENTRY, '/review/server.js'); + assert.equal(environment.DEV_FAST_REVIEW_SERVER_PORT, '4321'); + assert.equal(environment.DEV_FAST_REVIEW_TELEMETRY_DISABLED, undefined); +}); + +for (const protocol of ['dev-fast-review', 'dev-fast-review-preview']) { + test(`the app protocol overrides the shell protocol (${protocol})`, () => { + const environment = createReviewServerEnvironment({ + applicationEnvironment: { DEV_FAST_REVIEW_APP_URL_PROTOCOL: 'inherited' }, + resolvedEnvironment: { DEV_FAST_REVIEW_APP_URL_PROTOCOL: 'shell' }, + appVersion: '0.0.16', + appUrlProtocol: protocol, + serverEntry: '/review/server.js', + port: 4321, + token: 'token', + instanceId: 'instance', + appPid: 1234, + telemetryEnabled: true, + }); + assert.equal(environment.DEV_FAST_REVIEW_APP_URL_PROTOCOL, protocol); + }); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewServerSupervisor.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewServerSupervisor.ts new file mode 100644 index 000000000..650193d26 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewServerSupervisor.ts @@ -0,0 +1,414 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { randomBytes, randomUUID } from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { DeferredPromise, timeout } from "../../base/common/async.js"; +import { Event } from "../../base/common/event.js"; +import { + Disposable, + DisposableStore, + IDisposable, +} from "../../base/common/lifecycle.js"; +import { join } from "../../base/common/path.js"; +import * as semver from "../../base/common/semver/semver.js"; +import { + type ReviewDesktopConnection, + ReviewReadyEventReader, + resolveReviewServerEntry, +} from "../common/reviewDesktopBootstrap.js"; +import { REVIEW_SERVER_RESTART_DELAYS } from "../common/reviewReconnect.js"; + +/** + * The slice of `UtilityProcess` the supervisor drives. Depending on this rather + * than the concrete class keeps the supervisor free of any Electron import, so + * its readiness, restart, and credential-stability behaviour can be tested. + */ +export interface IReviewServerProcess extends IDisposable { + readonly onStdout: Event; + readonly onStderr: Event; + readonly onExit: Event<{ readonly code: number; readonly signal: string }>; + readonly onCrash: Event<{ readonly code: number; readonly reason: string }>; + start(configuration: { + readonly type: string; + readonly name: string; + readonly entryPoint: string; + readonly parentLifecycleBound?: number; + readonly env?: Record; + }): boolean; + postMessage(message: unknown): unknown; + kill(): void; +} + +export interface ReviewServerSupervisorOptions { + readonly appRoot: string; + readonly appVersion: string; + readonly appUrlProtocol?: string; + readonly isBuilt: boolean; + readonly serverEntryOverride?: string | undefined; + readonly readyTimeout?: number; + readonly appPid?: number; + readonly resolveEnvironment?: () => Promise; + readonly logInfo: (message: string) => void; + readonly logError: (message: string) => void; + readonly createProcess: () => IReviewServerProcess; + readonly telemetryEnabled?: boolean; + readonly userExtensionsPath?: string; +} + +export function createReviewServerEnvironment(options: { + readonly applicationEnvironment: NodeJS.ProcessEnv; + readonly resolvedEnvironment: NodeJS.ProcessEnv; + readonly appVersion: string; + readonly appUrlProtocol?: string; + readonly serverEntry: string; + readonly port: number; + readonly token: string; + readonly instanceId: string; + readonly appPid: number; + readonly telemetryEnabled: boolean; + readonly rustAnalyzerSource?: string; +}): Record { + return { + ...options.applicationEnvironment, + ...options.resolvedEnvironment, + DEV_FAST_REVIEW_SERVER_ENTRY: options.serverEntry, + DEV_FAST_REVIEW_SERVER_PORT: String(options.port), + DEV_FAST_REVIEW_SERVER_TOKEN: options.token, + DEV_FAST_REVIEW_INSTANCE_ID: options.instanceId, + DEV_FAST_REVIEW_APP_PID: String(options.appPid), + DEV_FAST_REVIEW_APP_VERSION: options.appVersion, + DEV_FAST_REVIEW_APP_URL_PROTOCOL: options.appUrlProtocol, + DEV_FAST_REVIEW_DESKTOP_HOST_AUTOSTART: "1", + DEV_FAST_REVIEW_TELEMETRY_DISABLED: options.telemetryEnabled + ? undefined + : "1", + // The app's own Electron binary doubles as the CLI's Node runtime + // (ELECTRON_RUN_AS_NODE), so an installed `review` command never + // depends on a system Node. + DEV_FAST_REVIEW_CLI_RUNTIME: process.execPath, + DEV_FAST_REVIEW_RUST_ANALYZER: options.rustAnalyzerSource, + }; +} + +function executableName(): string { + return process.platform === "win32" ? "rust-analyzer.exe" : "rust-analyzer"; +} + +function isExecutableFile(file: string): boolean { + try { + if (!fs.statSync(file).isFile()) return false; + fs.accessSync(file, fs.constants.X_OK); + return true; + } catch { + return false; + } +} + +function resolveInstalledRustAnalyzer(userExtensionsPath: string | undefined): string | undefined { + if (!userExtensionsPath) return undefined; + const candidates: { version: string; executable: string }[] = []; + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(userExtensionsPath, { withFileTypes: true }); + } catch { + return undefined; + } + for (const entry of entries) { + if (!entry.isDirectory() || !entry.name.startsWith("rust-lang.rust-analyzer-")) { + continue; + } + const directory = path.join(userExtensionsPath, entry.name); + try { + const manifest = JSON.parse(fs.readFileSync(path.join(directory, "package.json"), "utf8")) as { version?: unknown }; + if (typeof manifest.version !== "string" || !semver.valid(manifest.version)) { + continue; + } + const executable = path.join(directory, "server", executableName()); + if (isExecutableFile(executable)) { + candidates.push({ version: manifest.version, executable }); + } + } catch { + // Ignore incomplete extension directories left by interrupted installs. + } + } + candidates.sort((left, right) => semver.rcompare(left.version, right.version)); + return candidates[0]?.executable; +} + +function resolveRustAnalyzerSource(options: { + readonly userExtensionsPath?: string; + readonly appRoot: string; + readonly isBuilt: boolean; +}): string | undefined { + const installed = resolveInstalledRustAnalyzer(options.userExtensionsPath); + if (installed) return installed; + if (options.isBuilt) return undefined; + const developmentFallback = path.join( + options.appRoot, + "extensions", + "rust-lang.rust-analyzer", + "server", + executableName(), + ); + return isExecutableFile(developmentFallback) ? developmentFallback : undefined; +} + +/** + * Owns the embedded Review server's lifetime: resolving its entry point, + * minting its credentials, waiting for it to announce a validated endpoint, and + * restarting it without moving that endpoint. + */ +export class ReviewServerSupervisor extends Disposable { + private serverProcess: IReviewServerProcess | undefined; + private processListeners = new DisposableStore(); + private restartTimer: ReturnType | undefined; + private restartCount = 0; + private stopping = false; + private telemetryEnabled: boolean; + + /** + * Credentials are minted once and reused for the life of the application, so + * a restart keeps every renderer's existing connection valid. The port is + * chosen by the OS on first start and then pinned for the same reason. + */ + private readonly token = randomBytes(32).toString("base64url"); + private readonly instanceId = randomUUID(); + private port = 0; + + private readonly connected = new DeferredPromise(); + private readonly readyTimeout: number; + + constructor(private readonly options: ReviewServerSupervisorOptions) { + super(); + this.readyTimeout = options.readyTimeout ?? 30_000; + this.telemetryEnabled = options.telemetryEnabled !== false; + } + + setTelemetryEnabled(enabled: boolean): void { + this.telemetryEnabled = enabled; + this.serverProcess?.postMessage({ type: "telemetry-setting", enabled }); + } + + stageRustAnalyzer(): void { + const sourcePath = resolveRustAnalyzerSource(this.options); + if (!sourcePath) { + this.options.logError("[Review Desktop] no installed rust-analyzer source is available to stage."); + return; + } + if (!this.serverProcess) { + this.options.logError("[Review Desktop] the Review server is unavailable for rust-analyzer staging."); + return; + } + this.serverProcess.postMessage({ type: "stage-rust-analyzer", path: sourcePath }); + } + + /** Resolves once the server has announced an endpoint this process trusts. */ + whenConnected(): Promise { + return this.connected.p; + } + + start(): void { + if (this.stopping) return; + let resolution: Promise | undefined; + try { + resolution = this.options.resolveEnvironment?.(); + } catch (error) { + this.handleEnvironmentResolutionFailure(error); + return; + } + if (!resolution) { + this.startWithEnvironment({}); + return; + } + void resolution.then( + (environment) => this.startWithEnvironment(environment), + (error) => this.handleEnvironmentResolutionFailure(error), + ); + } + + private handleEnvironmentResolutionFailure(error: unknown): void { + const reason = error instanceof Error ? error.message : String(error); + this.options.logError( + `[Review Desktop] unable to resolve the login-shell environment; starting with the application environment: ${reason}`, + ); + this.startWithEnvironment({}); + } + + private startWithEnvironment( + resolvedEnvironment: NodeJS.ProcessEnv, + ): void { + if (this.stopping) return; + const serverEntry = resolveReviewServerEntry({ + isBuilt: this.options.isBuilt, + appRoot: this.options.appRoot, + serverEntryOverride: this.options.serverEntryOverride, + join, + }); + this.processListeners.dispose(); + this.processListeners = new DisposableStore(); + const serverProcess = this.options.createProcess(); + this.serverProcess = serverProcess; + this.processListeners.add(serverProcess); + + const reader = new ReviewReadyEventReader({ + token: this.token, + instanceId: this.instanceId, + }); + let ready = false; + this.processListeners.add( + serverProcess.onStdout((value) => { + this.options.logInfo(`[Review server] ${value.trimEnd()}`); + if (ready) return; + this.armReadyTimeout(); + let connection: ReviewDesktopConnection | undefined; + try { + connection = reader.push(value); + } catch (error) { + this.failStartup(error); + return; + } + if (!connection) return; + ready = true; + this.port = Number(new URL(connection.url).port); + this.restartCount = 0; + if (!this.connected.isSettled) { + this.options.logInfo( + `[Review Desktop] server ready at ${connection.url}`, + ); + void this.connected.complete(connection); + } + }), + ); + this.processListeners.add( + serverProcess.onStderr((value) => + this.options.logError(`[Review server] ${value.trimEnd()}`), + ), + ); + + let terminated = false; + const onTerminated = (detail: string) => { + if (terminated) return; + terminated = true; + this.options.logError( + `[Review Desktop] server host terminated: ${detail}`, + ); + this.serverProcess = undefined; + this.processListeners.dispose(); + if (this.stopping) return; + if (!ready && !this.connected.isSettled) { + this.options.logError( + "[Review Desktop] server host exited before announcing an endpoint.", + ); + } + const delay = REVIEW_SERVER_RESTART_DELAYS[this.restartCount++]; + if (delay === undefined) { + this.failStartup( + new Error( + "The Review server exhausted its restart budget without becoming ready.", + ), + ); + return; + } + this.restartTimer = setTimeout(() => this.start(), delay); + }; + this.processListeners.add( + serverProcess.onExit((event) => + onTerminated( + `exit ${event.code ?? "unknown"} (${event.signal ?? "no signal"})`, + ), + ), + ); + this.processListeners.add( + serverProcess.onCrash((event) => + onTerminated(`${event.reason} (${event.code ?? "unknown"})`), + ), + ); + + const appPid = this.options.appPid ?? process.pid; + const rustAnalyzerSource = resolveRustAnalyzerSource(this.options); + const environment = createReviewServerEnvironment({ + applicationEnvironment: process.env, + resolvedEnvironment, + appVersion: this.options.appVersion, + appUrlProtocol: this.options.appUrlProtocol, + serverEntry, + port: this.port, + token: this.token, + instanceId: this.instanceId, + appPid, + telemetryEnabled: this.telemetryEnabled, + rustAnalyzerSource, + }); + const started = serverProcess.start({ + type: "review-desktop-host", + name: "Review Desktop host", + entryPoint: "vs/review/electron-utility/reviewDesktopHostMain", + parentLifecycleBound: appPid, + env: environment, + }); + if (!started) { + onTerminated("launch failed"); + return; + } + if (!this.connected.isSettled) this.armReadyTimeout(); + } + + private readyTimeoutEpoch = 0; + + private armReadyTimeout(): void { + const epoch = ++this.readyTimeoutEpoch; + void timeout(this.readyTimeout).then(() => { + if (epoch !== this.readyTimeoutEpoch || this.stopping || this.connected.isSettled) return; + this.failStartup( + new Error( + `The Review server did not become ready within ${this.readyTimeout}ms.`, + ), + ); + }); + } + + private failStartup(error: unknown): void { + const reason = error instanceof Error ? error : new Error(String(error)); + this.options.logError(`[Review Desktop] ${reason.message}`); + if (!this.connected.isSettled) this.connected.error(reason); + } + + async stop(): Promise { + if (this.stopping) return; + this.stopping = true; + if (this.restartTimer) clearTimeout(this.restartTimer); + const serverProcess = this.serverProcess; + if (!serverProcess) return; + serverProcess.postMessage({ type: "shutdown" }); + await Promise.race([ + new Promise((resolve) => { + const store = new DisposableStore(); + store.add( + serverProcess.onExit(() => { + store.dispose(); + resolve(); + }), + ); + store.add( + serverProcess.onCrash(() => { + store.dispose(); + resolve(); + }), + ); + }), + timeout(2_000), + ]); + serverProcess.kill(); + this.processListeners.dispose(); + this.serverProcess = undefined; + } + + override dispose(): void { + void this.stop(); + super.dispose(); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateDialog.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateDialog.ts new file mode 100644 index 000000000..d10542e1c --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateDialog.ts @@ -0,0 +1,88 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from "../../base/common/lifecycle.js"; +import { localize } from "../../nls.js"; +import { IDialogMainService } from "../../platform/dialogs/electron-main/dialogMainService.js"; +import { ILogService } from "../../platform/log/common/log.js"; +import { + IUpdateService, + StateType, +} from "../../platform/update/common/update.js"; + +/** + * Reports the outcome of an explicit "Check for Updates..." with a native + * dialog. + * + * Stock Code OSS reports this from the workbench (`UpdateContribution`) and + * keeps `NotAvailableUpdateDialog` only for the windowless case. Review's + * renderer registers a no-op `IUpdateService`, so a native dialog is the whole + * feedback path here — with a window open or not. + * + * Only explicit checks report. Background checks stay silent, matching stock. + */ +export class ReviewUpdateDialog extends Disposable { + private awaitingExplicitResult = false; + + constructor( + @IUpdateService updateService: IUpdateService, + @IDialogMainService private readonly dialogMainService: IDialogMainService, + @ILogService private readonly logService: ILogService, + ) { + super(); + + this._register( + updateService.onStateChange((state) => { + if (state.type === StateType.CheckingForUpdates) { + this.awaitingExplicitResult = state.explicit; + return; + } + + if (!this.awaitingExplicitResult) { + return; + } + this.awaitingExplicitResult = false; + + // Only a check that found nothing, or failed, needs a dialog. A found + // update tells its own story: macOS downloads it and the menu item + // becomes "Restart to Update". + if (state.type !== StateType.Idle) { + return; + } + + if (state.error) { + this.show( + "error", + localize( + "review.update.failed", + "Could not check for updates. Please try again later.", + ), + state.error, + ); + return; + } + + if (state.notAvailable) { + this.show( + "info", + localize( + "review.update.noUpdatesAvailable", + "There are currently no updates available.", + ), + ); + } + }), + ); + } + + private show(type: "info" | "error", message: string, detail?: string): void { + this.logService.info(`reviewUpdateDialog#show - ${type}: ${message}`); + this.dialogMainService + .showMessageBox({ type, message, detail }) + .catch((error) => { + this.logService.error("reviewUpdateDialog#show failed", error); + }); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateTelemetry.test.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateTelemetry.test.ts new file mode 100644 index 000000000..048a55046 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateTelemetry.test.ts @@ -0,0 +1,325 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import { appendFile, mkdtemp, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import test from "node:test"; + +import { Emitter } from "../../base/common/event.js"; +import { toDisposable } from "../../base/common/lifecycle.js"; +import { + DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, +} from "../../platform/update/common/darwinUpdateRecovery.js"; +import { + State, + type IUpdateService, + type State as UpdateState, + UpdateType, +} from "../../platform/update/common/update.js"; +import { + StorageScope, + type IStorageValueChangeEvent, +} from "../../platform/storage/common/storage.js"; +import type { IApplicationStorageMainService } from "../../platform/storage/electron-main/storageMainService.js"; +import type { ReviewMainErrorTelemetry } from "./reviewMainErrorTelemetry.js"; +import { + extractDarwinShipItFailureMessage, + readDarwinShipItFailure, + ReviewUpdateTelemetry, +} from "./reviewUpdateTelemetry.js"; + +const attempt = { + sourceCommit: "source", + targetCommit: "target", + productVersion: "0.0.27", + attemptedAt: 100, + attemptId: "12345678-1234-1234-1234-123456789abc", + shipItLogOffset: 4096, +}; + +test("extracts only the last concise ShipIt NSError summary", () => { + const log = [ + 'Installation error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied" UserInfo={private=/Users/alice/repo}', + "retrying", + 'Installation error: Error Domain=SQRLInstallerErrorDomain Code=-1 "Failed to copy bundle file:///Users/alice/Review.app to directory file:///Applications" UserInfo={private=secret}', + ].join("\n"); + const message = extractDarwinShipItFailureMessage(log); + assert.equal( + message, + 'Error Domain=SQRLInstallerErrorDomain Code=-1 "Failed to copy bundle file:///Users/alice/Review.app to directory file:///Applications"', + ); + assert.equal(message?.includes("UserInfo"), false); + assert.equal(message?.includes("private=secret"), false); +}); + +test("uses the bounded ShipIt retry summary when NSError parsing fails", () => { + assert.equal( + extractDarwinShipItFailureMessage( + "details\nToo many attempts to install, aborting update\n", + ), + "Too many attempts to install, aborting update", + ); +}); + +test("reads only ShipIt output appended after the matching attempt", async () => { + const directory = await mkdtemp(join(tmpdir(), "review-shipit-")); + const path = join(directory, "ShipIt_stderr.log"); + try { + const oldError = + 'Installation error: Error Domain=OldDomain Code=1 "Old failure"\n'; + await writeFile(path, oldError, "utf8"); + await appendFile( + path, + 'Installation error: Error Domain=NewDomain Code=13 "Permission denied" UserInfo={private=secret}\n', + "utf8", + ); + assert.deepEqual(await readDarwinShipItFailure(path, oldError.length), { + message: 'Error Domain=NewDomain Code=13 "Permission denied"', + source: "shipit", + }); + } finally { + await rm(directory, { recursive: true, force: true }); + } +}); + +test("reports staged, immediate failure, and terminal update events", async () => { + const harness = createHarness(); + const telemetry = new ReviewUpdateTelemetry(harness.options); + await turn(); + + harness.storage.storeValue( + DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, + JSON.stringify(attempt), + ); + harness.update.setState( + State.Ready( + { version: attempt.targetCommit, productVersion: attempt.productVersion }, + false, + false, + ), + ); + harness.update.setState( + State.Ready( + { version: attempt.targetCommit, productVersion: attempt.productVersion }, + false, + false, + ), + ); + + harness.update.setState(State.CheckingForUpdates(false)); + harness.update.setState( + State.Idle(UpdateType.Archive, "Feed unavailable", undefined, "request"), + ); + + harness.storage.storeValue( + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, + JSON.stringify({ kind: "applied", attempt, resolvedAt: 600 }), + ); + await turn(); + + assert.deepEqual( + harness.events.map((event) => event.name), + ["update_started", "update_failed", "update_completed"], + ); + assert.deepEqual(harness.events[1], { + name: "update_failed", + properties: { phase: "check", message_source: "request" }, + error: { + name: "UpdateCheckError", + message: "Feed unavailable", + stack: "Update lifecycle telemetry", + }, + }); + assert.deepEqual(harness.events[2].properties, { + update_attempt_id: attempt.attemptId, + target_version: attempt.productVersion, + duration_ms: 500, + }); + assert.equal( + harness.storage.getValue(DARWIN_UPDATE_OUTCOME_STORAGE_KEY), + undefined, + ); + telemetry.dispose(); +}); + +test("reports an install failure with the matched ShipIt message", async () => { + const harness = createHarness({ + outcome: { kind: "failed", attempt, resolvedAt: 700 }, + readInstallFailure: async () => ({ + message: 'Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"', + source: "shipit", + }), + }); + const telemetry = new ReviewUpdateTelemetry(harness.options); + await turn(); + + assert.deepEqual(harness.events, [ + { + name: "update_failed", + properties: { + update_attempt_id: attempt.attemptId, + target_version: attempt.productVersion, + duration_ms: 600, + phase: "install", + message_source: "shipit", + }, + error: { + name: "UpdateInstallError", + message: 'Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"', + stack: "Update lifecycle telemetry", + }, + }, + ]); + telemetry.dispose(); +}); + +test("consumes disabled lifecycle records without reporting them later", async () => { + let enabled = false; + const harness = createHarness({ + enabled: () => enabled, + outcome: { kind: "applied", attempt, resolvedAt: 600 }, + }); + const telemetry = new ReviewUpdateTelemetry(harness.options); + await turn(); + assert.deepEqual(harness.events, []); + assert.equal( + harness.storage.getValue(DARWIN_UPDATE_OUTCOME_STORAGE_KEY), + undefined, + ); + + harness.storage.storeValue( + DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, + JSON.stringify(attempt), + ); + harness.update.setState( + State.Ready( + { version: attempt.targetCommit, productVersion: attempt.productVersion }, + false, + false, + ), + ); + assert.deepEqual(harness.events, []); + + enabled = true; + harness.update.setState( + State.Ready( + { version: attempt.targetCommit, productVersion: attempt.productVersion }, + false, + false, + ), + ); + assert.deepEqual(harness.events, []); + telemetry.dispose(); +}); + +function createHarness(options?: { + readonly enabled?: () => boolean; + readonly outcome?: unknown; + readonly readInstallFailure?: () => Promise<{ + message: string; + source: "shipit"; + }>; +}) { + const storage = new FakeStorage(); + if (options?.outcome) { + storage.storeValue( + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, + JSON.stringify(options.outcome), + ); + } + const update = new FakeUpdateService(); + const events: Array<{ + name: string; + properties: Readonly>; + error?: unknown; + }> = []; + const telemetry = { + capture(name: string, properties: Record, error?: unknown) { + events.push({ name, properties, error }); + }, + } as unknown as ReviewMainErrorTelemetry; + return { + storage, + update, + events, + options: { + updateService: update as unknown as IUpdateService, + storageService: storage as unknown as IApplicationStorageMainService, + telemetry, + isTelemetryEnabled: options?.enabled ?? (() => true), + shipItLogPath: "/tmp/ShipIt_stderr.log", + readInstallFailure: options?.readInstallFailure, + }, + }; +} + +class FakeUpdateService { + private readonly emitter = new Emitter(); + readonly onStateChange = this.emitter.event; + state: UpdateState = State.Idle(UpdateType.Archive); + + setState(state: UpdateState): void { + this.state = state; + this.emitter.fire(this.state); + } +} + +class FakeStorage { + readonly whenReady = Promise.resolve(); + private readonly values = new Map(); + private readonly emitters = new Map>(); + + getValue(key: string): string | undefined { + return this.values.get(key); + } + + storeValue(key: string, value: string): void { + this.values.set(key, value); + this.fire(key); + } + + get(key: string): string | undefined { + return this.values.get(key); + } + + store(key: string, value: string): void { + this.storeValue(key, value); + } + + remove(key: string): void { + this.values.delete(key); + this.fire(key); + } + + flush(): Promise { + return Promise.resolve(); + } + + onDidChangeValue(_scope: StorageScope, key: string | undefined) { + if (!key) return () => toDisposable(() => undefined); + let emitter = this.emitters.get(key); + if (!emitter) { + emitter = new Emitter(); + this.emitters.set(key, emitter); + } + return emitter.event; + } + + private fire(key: string): void { + this.emitters.get(key)?.fire({ + key, + scope: StorageScope.APPLICATION, + target: undefined, + external: false, + }); + } +} + +async function turn(): Promise { + await new Promise((resolve) => setImmediate(resolve)); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateTelemetry.ts b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateTelemetry.ts new file mode 100644 index 000000000..f4c6d353f --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-main/reviewUpdateTelemetry.ts @@ -0,0 +1,310 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { open } from "node:fs/promises"; +import { join } from "node:path"; + +import { Disposable, DisposableStore } from "../../base/common/lifecycle.js"; +import { + DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, + parseDarwinUpdateAttempt, + parseDarwinUpdateOutcomeRecord, + type IDarwinUpdateAttempt, +} from "../../platform/update/common/darwinUpdateRecovery.js"; +import { + type IUpdateService, + type State, + StateType, +} from "../../platform/update/common/update.js"; +import { + StorageScope, + StorageTarget, +} from "../../platform/storage/common/storage.js"; +import type { IApplicationStorageMainService } from "../../platform/storage/electron-main/storageMainService.js"; +import type { ReviewMainErrorTelemetry } from "./reviewMainErrorTelemetry.js"; + +const UPDATE_STARTED_STORAGE_KEY = "review/update/telemetry/started.v1"; +const MAX_SHIPIT_LOG_BYTES = 64 * 1024; +const INSTALL_FALLBACK_MESSAGE = + "The downloaded update did not replace the running application."; + +export type ReviewUpdateFailurePhase = "check" | "download" | "install"; +export type ReviewUpdateMessageSource = + | "electron" + | "request" + | "shipit" + | "fallback"; + +interface ReviewUpdateTelemetryOptions { + readonly updateService: IUpdateService; + readonly storageService: IApplicationStorageMainService; + readonly telemetry: ReviewMainErrorTelemetry; + readonly isTelemetryEnabled: () => boolean; + readonly shipItLogPath?: string; + readonly readInstallFailure?: ( + path: string, + offset: number | undefined, + ) => Promise<{ message: string; source: ReviewUpdateMessageSource }>; + readonly logError?: (message: string) => void; +} + +/** + * Converts updater state and persisted Darwin restart outcomes into the three + * Review update lifecycle events. Raw ShipIt output never leaves this module. + */ +export class ReviewUpdateTelemetry extends Disposable { + private lastState: State; + + constructor(private readonly options: ReviewUpdateTelemetryOptions) { + super(); + this.lastState = options.updateService.state; + this._register( + options.updateService.onStateChange((state) => { + this.onStateChange(state); + this.lastState = state; + }), + ); + + const storageListeners = this._register(new DisposableStore()); + const onOutcomeChanged = options.storageService.onDidChangeValue( + StorageScope.APPLICATION, + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, + storageListeners, + ); + this._register(onOutcomeChanged(() => void this.processOutcome())); + + void options.storageService.whenReady + .then(() => { + if (options.updateService.state.type === StateType.Ready) { + this.recordStarted(); + } + return this.processOutcome(); + }) + .catch((error) => + options.logError?.( + `[Review Desktop] could not process update telemetry: ${error}`, + ), + ); + } + + private onStateChange(state: State): void { + if (state.type === StateType.Ready) { + this.recordStarted(); + return; + } + if (state.type !== StateType.Idle || !state.error) { + return; + } + const phase = updateFailurePhase(this.lastState); + if (!phase || !this.options.isTelemetryEnabled()) { + return; + } + this.captureFailure( + phase, + state.errorSource ?? "electron", + state.error, + ); + } + + private recordStarted(): void { + const attempt = parseDarwinUpdateAttempt( + this.options.storageService.get( + DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, + StorageScope.APPLICATION, + ), + ); + if (!attempt?.attemptId || !attempt.productVersion) { + return; + } + const lastStarted = this.options.storageService.get( + UPDATE_STARTED_STORAGE_KEY, + StorageScope.APPLICATION, + ); + if (lastStarted === attempt.attemptId) { + return; + } + + // Mark it observed even when telemetry is disabled. Enabling telemetry + // later must not send an event for an earlier update. + this.options.storageService.store( + UPDATE_STARTED_STORAGE_KEY, + attempt.attemptId, + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + void this.options.storageService.flush().catch(() => undefined); + if (!this.options.isTelemetryEnabled()) { + return; + } + this.options.telemetry.capture("update_started", { + update_attempt_id: attempt.attemptId, + target_version: attempt.productVersion, + }); + } + + private async processOutcome(): Promise { + const raw = this.options.storageService.get( + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, + StorageScope.APPLICATION, + ); + const outcome = parseDarwinUpdateOutcomeRecord(raw); + if (!outcome) { + return; + } + + // Consume first for both consent states, so a crash or later opt-in cannot + // turn this into a duplicate or retroactive event. + this.options.storageService.remove( + DARWIN_UPDATE_OUTCOME_STORAGE_KEY, + StorageScope.APPLICATION, + ); + void this.options.storageService.flush().catch(() => undefined); + + const { attempt } = outcome; + if ( + !attempt.attemptId || + !attempt.productVersion || + !this.options.isTelemetryEnabled() + ) { + return; + } + const properties = lifecycleProperties(attempt, outcome.resolvedAt); + if (outcome.kind === "applied") { + this.options.telemetry.capture("update_completed", properties); + return; + } + + const failure = await this.readInstallFailure(attempt.shipItLogOffset); + this.captureFailure("install", failure.source, failure.message, properties); + } + + private async readInstallFailure( + offset: number | undefined, + ): Promise<{ message: string; source: ReviewUpdateMessageSource }> { + const path = this.options.shipItLogPath; + if (!path) { + return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; + } + try { + return await ( + this.options.readInstallFailure ?? readDarwinShipItFailure + )(path, offset); + } catch { + return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; + } + } + + private captureFailure( + phase: ReviewUpdateFailurePhase, + source: ReviewUpdateMessageSource, + message: string, + properties: Readonly> = {}, + ): void { + this.options.telemetry.capture( + "update_failed", + { ...properties, phase, message_source: source }, + { + name: `Update${phase[0].toUpperCase()}${phase.slice(1)}Error`, + message, + stack: "Update lifecycle telemetry", + }, + ); + } +} + +export function darwinShipItLogPath( + userHomePath: string, + bundleIdentifier: string, +): string { + return join( + userHomePath, + "Library", + "Caches", + `${bundleIdentifier}.ShipIt`, + "ShipIt_stderr.log", + ); +} + +export function extractDarwinShipItFailureMessage( + appendedLog: string, +): string | undefined { + const lines = appendedLog.split(/\r?\n/); + for (let index = lines.length - 1; index >= 0; index--) { + const line = lines[index]; + const marker = line.lastIndexOf("Installation error:"); + if (marker < 0) continue; + const error = line.slice(marker + "Installation error:".length).trim(); + const summary = error.match( + /Error Domain=([A-Za-z0-9._-]{1,80}) Code=(-?\d{1,10}) "([^"\r\n]{1,2000})"/, + ); + if (summary) { + return `Error Domain=${summary[1]} Code=${summary[2]} "${summary[3]}"`; + } + } + for (let index = lines.length - 1; index >= 0; index--) { + if (lines[index].includes("Too many attempts to install, aborting update")) { + return "Too many attempts to install, aborting update"; + } + } + return undefined; +} + +export async function readDarwinShipItFailure( + path: string, + offset: number | undefined, +): Promise<{ message: string; source: ReviewUpdateMessageSource }> { + if (offset === undefined) { + return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; + } + const file = await open(path, "r"); + try { + const size = (await file.stat()).size; + if (size < offset) { + return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; + } + const start = Math.max(offset, size - MAX_SHIPIT_LOG_BYTES); + const length = size - start; + if (length <= 0) { + return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; + } + const buffer = Buffer.alloc(length); + const { bytesRead } = await file.read(buffer, 0, length, start); + const message = extractDarwinShipItFailureMessage( + buffer.subarray(0, bytesRead).toString("utf8"), + ); + return message + ? { message, source: "shipit" } + : { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; + } finally { + await file.close(); + } +} + +function updateFailurePhase( + previous: State, +): Exclude | undefined { + if (previous.type === StateType.CheckingForUpdates) { + return "check"; + } + if ( + previous.type === StateType.Downloading || + previous.type === StateType.Overwriting + ) { + return "download"; + } + return undefined; +} + +function lifecycleProperties( + attempt: IDarwinUpdateAttempt, + resolvedAt: number, +): Record { + return { + update_attempt_id: attempt.attemptId!, + target_version: attempt.productVersion!, + duration_ms: Math.max(0, resolvedAt - attempt.attemptedAt), + }; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/electron-utility/reviewDesktopHostMain.ts b/apps/review-desktop/code-oss/src/vs/review/electron-utility/reviewDesktopHostMain.ts new file mode 100644 index 000000000..ad135b152 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/electron-utility/reviewDesktopHostMain.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { pathToFileURL } from "node:url"; + +const serverEntry = process.env["DEV_FAST_REVIEW_SERVER_ENTRY"]; +if (!serverEntry) { + throw new Error("DEV_FAST_REVIEW_SERVER_ENTRY is required."); +} + +await import(pathToFileURL(serverEntry).href); diff --git a/apps/review-desktop/code-oss/src/vs/review/node/reviewBootstrapBreadcrumb.ts b/apps/review-desktop/code-oss/src/vs/review/node/reviewBootstrapBreadcrumb.ts new file mode 100644 index 000000000..f23895827 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/node/reviewBootstrapBreadcrumb.ts @@ -0,0 +1,102 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { appendFileSync, mkdirSync, readFileSync, rmSync, statSync } from 'node:fs'; +import * as path from 'node:path'; + +/** + * Records a crash that happens before Review can start. + * + * `src/main.ts` runs before the message table, the service collection, and the + * embedded server exist. A failure there leaves no log and no window: Review + * Desktop 0.0.4 shipped exactly that and could not launch. So this module does + * the least it can — one line of JSON in a file — and the next launch reports + * it through the normal, opted-in path. + * + * Constraints that keep it safe to import from `src/main.ts`: + * - Node built-ins only. No `localize`, no registry, no other module. The + * bootstrap import test walks this file and fails on any of those. + * - Synchronous, because the process is about to die. + * - Never throws. A failure to record a crash must not become the crash. + * + * Writing a local file is not telemetry, so no consent check applies here. The + * consent check happens when the next launch tries to send the line. + */ + +const BREADCRUMB_FILE = 'review-bootstrap-errors.jsonl'; +const MAX_FILE_BYTES = 64 * 1024; +const MAX_STACK_LENGTH = 8 * 1024; + +export interface ReviewBootstrapBreadcrumb { + readonly t: number; + readonly name: string; + readonly message: string; + readonly stack: string; +} + +export function reviewBootstrapBreadcrumbPath(userDataPath: string): string { + return path.join(userDataPath, BREADCRUMB_FILE); +} + +/** Append one crash note. Silent on every failure. */ +export function writeReviewBootstrapBreadcrumb(userDataPath: string, error: unknown, now: number = Date.now()): void { + try { + const file = reviewBootstrapBreadcrumbPath(userDataPath); + let size = 0; + try { + size = statSync(file).size; + } catch { + size = 0; // no file yet + } + if (size >= MAX_FILE_BYTES) { + return; // a crash loop must not fill the disk + } + const candidate = error as { name?: unknown; message?: unknown; stack?: unknown } | undefined; + const breadcrumb: ReviewBootstrapBreadcrumb = { + t: now, + name: typeof candidate?.name === 'string' ? candidate.name : 'Error', + message: typeof candidate?.message === 'string' ? candidate.message : String(error), + stack: typeof candidate?.stack === 'string' ? candidate.stack.slice(0, MAX_STACK_LENGTH) : '', + }; + mkdirSync(userDataPath, { recursive: true }); + appendFileSync(file, `${JSON.stringify(breadcrumb)}\n`, 'utf8'); + } catch { + // Recording a crash must never raise one. + } +} + +/** + * Read every recorded crash and delete the file. The file goes whether or not + * the caller reports the entries, so an opted-out user never accumulates one. + */ +export function drainReviewBootstrapBreadcrumbs(userDataPath: string): ReviewBootstrapBreadcrumb[] { + const file = reviewBootstrapBreadcrumbPath(userDataPath); + let contents: string; + try { + contents = readFileSync(file, 'utf8'); + } catch { + return []; + } + try { + rmSync(file, { force: true }); + } catch { + // A file we cannot delete is capped by MAX_FILE_BYTES anyway. + } + const breadcrumbs: ReviewBootstrapBreadcrumb[] = []; + for (const line of contents.split('\n')) { + if (!line) { + continue; + } + try { + const parsed = JSON.parse(line) as ReviewBootstrapBreadcrumb; + if (parsed && typeof parsed.stack === 'string') { + breadcrumbs.push(parsed); + } + } catch { + // One unreadable line must not lose the others. + } + } + return breadcrumbs; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/node/reviewOptionalExtensionCatalog.ts b/apps/review-desktop/code-oss/src/vs/review/node/reviewOptionalExtensionCatalog.ts new file mode 100644 index 000000000..d67bd4ff5 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/node/reviewOptionalExtensionCatalog.ts @@ -0,0 +1,101 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +// This module is imported by src/main.ts before bootstrapESM() installs the NLS +// table. Keep it free of workbench registries, configuration, and localization. + +export const reviewOptionalExtensionCatalog = [ + { + id: 'rust-lang.rust-analyzer', + role: 'primary', + group: 'rust', + version: '0.4.2990', + targets: { + 'darwin-arm64': { + url: 'https://open-vsx.org/api/rust-lang/rust-analyzer/darwin-arm64/0.4.2990/file/rust-lang.rust-analyzer-0.4.2990@darwin-arm64.vsix', + sha256: 'e068ebb88f705491856b91cdbf8b7ead40c22d50f2c24df70e345c889c2b0111', + size: 15445156 + }, + 'linux-x64': { + url: 'https://open-vsx.org/api/rust-lang/rust-analyzer/linux-x64/0.4.2990/file/rust-lang.rust-analyzer-0.4.2990@linux-x64.vsix', + sha256: '317cb128e8caf2495b955ef6612d828fef809187ac445242116ad8e2e32382ff', + size: 16313907 + } + } + }, + { + id: 'swiftlang.swift-vscode', + role: 'primary', + group: 'swift', + version: '2.17.20260702', + targets: { + universal: { + url: 'https://open-vsx.org/api/swiftlang/swift-vscode/2.17.20260702/file/swiftlang.swift-vscode-2.17.20260702.vsix', + sha256: '64fcca2666e033c3934ceeb98b13ff73e30071d32e0795bec891652814ef947b', + size: 14779649 + } + } + }, + { + id: 'llvm-vs-code-extensions.lldb-dap', + role: 'support', + group: 'swift', + version: '0.7.20260804', + targets: { + universal: { + url: 'https://open-vsx.org/api/llvm-vs-code-extensions/lldb-dap/0.7.20260804/file/llvm-vs-code-extensions.lldb-dap-0.7.20260804.vsix', + sha256: '69dad4f902a1a9d96403205e209a9aef760189c93d687e02f568a753148c537f', + size: 819802 + } + } + }, + { + id: 'muhammad-sammy.csharp', + role: 'primary', + group: 'csharp', + version: '2.145.21-g154a82fd27', + targets: { + 'darwin-arm64': { + url: 'https://open-vsx.org/api/muhammad-sammy/csharp/darwin-arm64/2.145.21-g154a82fd27/file/muhammad-sammy.csharp-2.145.21-g154a82fd27@darwin-arm64.vsix', + sha256: '93f61e8b6938cbe8ecda8768bfaf08abed9789db9461177d3d0ab59ccda2528d', + size: 75096042 + }, + 'linux-x64': { + url: 'https://open-vsx.org/api/muhammad-sammy/csharp/linux-x64/2.145.21-g154a82fd27/file/muhammad-sammy.csharp-2.145.21-g154a82fd27@linux-x64.vsix', + sha256: '78bc006683cc998e9fd1a6f2760d8cb3da63096464a217bbd192ecfb490a5516', + size: 78144854 + } + } + }, + { + id: 'golang.go', + role: 'primary', + group: 'go', + version: '0.56.0', + targets: { + universal: { + url: 'https://open-vsx.org/api/golang/Go/0.56.0/file/golang.Go-0.56.0.vsix', + sha256: '9f5959fb17ba0a8dbd804387ddda50975fcaa9dd5267aa33eaaa89912072aacb', + size: 621478 + } + } + }, + { + id: 'ms-dotnettools.vscode-dotnet-runtime', + role: 'support', + group: 'csharp', + version: '3.1.0', + targets: { + universal: { + url: 'https://open-vsx.org/api/ms-dotnettools/vscode-dotnet-runtime/3.1.0/file/ms-dotnettools.vscode-dotnet-runtime-3.1.0.vsix', + sha256: '10fd1e1693a81e2c68f0382ae3cfcf0784c5f3e0da002dd4bfd322575b46941e', + size: 1458566 + } + } + } +] as const; + +export type ReviewOptionalExtension = (typeof reviewOptionalExtensionCatalog)[number]; +export type ReviewOptionalExtensionTarget = keyof ReviewOptionalExtension['targets']; diff --git a/apps/review-desktop/code-oss/src/vs/review/node/reviewOptionalExtensionInstaller.ts b/apps/review-desktop/code-oss/src/vs/review/node/reviewOptionalExtensionInstaller.ts new file mode 100644 index 000000000..1c828d4f2 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/node/reviewOptionalExtensionInstaller.ts @@ -0,0 +1,254 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +// src/main.ts imports this module before bootstrapESM() installs the NLS table. +// Keep it limited to Node modules and the import-free catalog. +import { createHash, randomUUID } from 'node:crypto'; +import { createReadStream, createWriteStream } from 'node:fs'; +import { mkdir, rename, rm, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { Readable, Transform } from 'node:stream'; +import { pipeline } from 'node:stream/promises'; +import { reviewOptionalExtensionCatalog } from './reviewOptionalExtensionCatalog.js'; + +const DOWNLOAD_CHANNEL = 'vscode:reviewDownloadOptionalExtension'; +const MAX_REDIRECTS = 10; + +type ReviewNetResponse = Readable & { + readonly statusCode: number; + readonly statusMessage?: string; + readonly headers: Readonly>; +}; + +export interface ReviewNetRequest { + on(event: 'redirect', listener: ( + statusCode: number, + method: string, + redirectUrl: string, + responseHeaders: Readonly> + ) => void): this; + once(event: 'response', listener: (response: ReviewNetResponse) => void): this; + once(event: 'error', listener: (error: Error) => void): this; + followRedirect(): void; + abort(): void; + end(): void; +} + +export type ReviewNetRequestFactory = (options: { + readonly method: 'GET'; + readonly url: string; + readonly redirect: 'manual'; +}) => unknown; + +export interface ReviewValidatedIpcMain { + handle(channel: string, listener: (event: unknown, extensionId: unknown) => Promise): unknown; +} + +export interface ReviewOptionalExtensionInstallerOptions { + readonly userDataPath: string; + readonly platform: NodeJS.Platform | string; + readonly arch: string; + readonly request: ReviewNetRequestFactory; + readonly catalog?: readonly ReviewOptionalExtensionCatalogEntry[]; +} + +export interface ReviewOptionalExtensionTargetPin { + readonly url: string; + readonly sha256: string; + readonly size: number; +} + +export interface ReviewOptionalExtensionCatalogEntry { + readonly id: string; + readonly role: 'primary' | 'support'; + readonly group: string; + readonly version: string; + readonly targets: Readonly>; +} + +function supportedTarget(platform: string, arch: string): 'darwin-arm64' | 'linux-x64' | undefined { + if (platform === 'darwin' && arch === 'arm64') { + return 'darwin-arm64'; + } + if (platform === 'linux' && arch === 'x64') { + return 'linux-x64'; + } + return undefined; +} + +async function sha256File(file: string): Promise { + const hash = createHash('sha256'); + for await (const chunk of createReadStream(file)) { + hash.update(chunk); + } + return hash.digest('hex'); +} + +async function isFile(file: string): Promise { + try { + return (await stat(file)).isFile(); + } catch { + return false; + } +} + +export class ReviewOptionalExtensionInstaller { + private readonly cacheDirectory: string; + private readonly inflight = new Map>(); + private readonly catalog: readonly ReviewOptionalExtensionCatalogEntry[]; + + constructor(private readonly options: ReviewOptionalExtensionInstallerOptions) { + this.cacheDirectory = path.resolve(options.userDataPath, 'optional-extensions', 'cache'); + this.catalog = options.catalog ?? reviewOptionalExtensionCatalog; + } + + async download(extensionId: string): Promise { + const extension = this.catalog.find(candidate => candidate.id === extensionId); + if (!extension) { + throw new Error(`Unknown optional extension: ${extensionId}`); + } + + const target = supportedTarget(this.options.platform, this.options.arch); + if (!target) { + throw new Error(`Optional extensions do not support ${this.options.platform}/${this.options.arch}`); + } + const targetPin = extension.targets['universal'] ?? extension.targets[target]; + if (!targetPin) { + throw new Error(`${extension.id} has no optional extension pin for ${target}`); + } + + const targetKey = extension.targets['universal'] ? 'universal' : target; + const inflightKey = `${extension.id}@${extension.version}:${targetKey}`; + const existing = this.inflight.get(inflightKey); + if (existing) { + return existing; + } + + const pending = this.ensureVerifiedVsix(extension.id, extension.version, targetKey, targetPin); + this.inflight.set(inflightKey, pending); + try { + return await pending; + } finally { + if (this.inflight.get(inflightKey) === pending) { + this.inflight.delete(inflightKey); + } + } + } + + private async ensureVerifiedVsix( + extensionId: string, + version: string, + target: string, + pin: { readonly url: string; readonly sha256: string; readonly size: number } + ): Promise { + await mkdir(this.cacheDirectory, { recursive: true }); + const suffix = target === 'universal' ? '' : `@${target}`; + const cached = path.resolve(this.cacheDirectory, `${extensionId}-${version}${suffix}.vsix`); + + if (await isFile(cached)) { + if (await sha256File(cached) === pin.sha256) { + return cached; + } + await rm(cached, { force: true }); + } + + const partial = `${cached}.${process.pid}.${randomUUID()}.part`; + try { + const actualHash = await this.downloadToPartial(pin.url, partial); + if (actualHash !== pin.sha256) { + throw new Error( + `${extensionId} checksum mismatch: expected ${pin.sha256}, received ${actualHash}` + ); + } + await rename(partial, cached); + return cached; + } catch (error) { + await rm(partial, { force: true }); + throw error; + } + } + + private async downloadToPartial(initialUrl: string, partial: string): Promise { + const response = await this.request(initialUrl); + if (response.statusCode !== 200) { + response.resume(); + throw new Error(`GET ${initialUrl} failed with ${response.statusCode} ${response.statusMessage ?? ''}`.trim()); + } + + const hash = createHash('sha256'); + const hashingStream = new Transform({ + transform(chunk, _encoding, callback) { + hash.update(chunk); + callback(null, chunk); + } + }); + await pipeline(response, hashingStream, createWriteStream(partial, { flags: 'wx' })); + return hash.digest('hex'); + } + + private request(initialUrl: string): Promise { + return new Promise((resolve, reject) => { + const request = this.options.request({ method: 'GET', url: initialUrl, redirect: 'manual' }) as ReviewNetRequest; + let redirects = 0; + let settled = false; + const fail = (error: Error) => { + if (settled) { + return; + } + settled = true; + reject(error); + request.abort(); + }; + request.on('redirect', (_statusCode, method, redirectUrl) => { + redirects++; + if (redirects > MAX_REDIRECTS) { + fail(new Error(`GET ${initialUrl} exceeded ${MAX_REDIRECTS} redirects`)); + return; + } + const redirected = new URL(redirectUrl); + if (method !== 'GET') { + fail(new Error(`Refused optional extension redirect with method ${method}`)); + return; + } + if (redirected.protocol !== 'https:') { + fail(new Error(`Refused optional extension redirect to ${redirected.protocol}`)); + return; + } + // Electron cancels a manual redirect unless this call happens inside + // the redirect event. Validate first, then follow it synchronously. + request.followRedirect(); + }); + request.once('response', response => { + if (!settled) { + settled = true; + resolve(response); + } else { + response.resume(); + } + }); + request.once('error', error => { + if (!settled) { + settled = true; + reject(error); + } + }); + request.end(); + }); + } +} + +export function registerReviewOptionalExtensionInstaller( + ipcMain: ReviewValidatedIpcMain, + options: ReviewOptionalExtensionInstallerOptions +): ReviewOptionalExtensionInstaller { + const installer = new ReviewOptionalExtensionInstaller(options); + ipcMain.handle(DOWNLOAD_CHANNEL, async (_event, extensionId) => { + if (typeof extensionId !== 'string' || extensionId.length === 0) { + throw new Error('Optional extension downloads require one extension ID'); + } + return installer.download(extensionId); + }); + return installer; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/node/reviewUserConfigImport.test.ts b/apps/review-desktop/code-oss/src/vs/review/node/reviewUserConfigImport.test.ts new file mode 100644 index 000000000..567c1e2b7 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/node/reviewUserConfigImport.test.ts @@ -0,0 +1,265 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from 'assert'; +import { mkdirSync, mkdtempSync, readFileSync, rmSync, utimesSync, writeFileSync } from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import { afterEach, describe, test } from 'node:test'; +import { + curatedExtensionConfigurationDefaults, + reviewConfigurationDefaults, +} from '../common/reviewConfigurationDefaults.js'; +import { importReviewUserConfig } from './reviewUserConfigImport.js'; + +describe('ReviewUserConfigImport', () => { + const fixtures: string[] = []; + + afterEach(() => { + for (const fixture of fixtures.splice(0)) { + rmSync(fixture, { recursive: true, force: true }); + } + }); + + function createFixture(): { root: string; sourceRoot: string; sourceUser: string; target: string } { + const root = mkdtempSync(path.join(os.tmpdir(), 'review-user-config-')); + fixtures.push(root); + const sourceRoot = path.join(root, 'source'); + const sourceUser = path.join(sourceRoot, 'User'); + const target = path.join(root, 'target'); + mkdirSync(sourceUser, { recursive: true }); + return { root, sourceRoot, sourceUser, target }; + } + + test('imports JSONC keybindings verbatim and filters hardened settings', () => { + const fixture = createFixture(); + const keybindings = '[\n\t// Keep this chord and its comment.\n\t{ "key": "ctrl+k ctrl+r", "command": "review.refresh" },\n]\n'; + writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), keybindings); + writeFileSync(path.join(fixture.sourceUser, 'settings.json'), `{ + // User-facing editor and keymap settings survive. + "editor.fontSize": 15, + "vim.useSystemClipboard": true, + "telemetry.telemetryLevel": "all", + "extensions.autoUpdate": true, + "workbench.statusBar.visible": true, + // Would re-arm the install prompt for an extension Review cannot ship. + "python.languageServer": "Pylance", + }`); + + const extensionsDir = path.join(fixture.sourceRoot, 'extensions'); + mkdirSync(path.join(extensionsDir, 'vscodevim.vim-1.32.4'), { recursive: true }); + writeFileSync(path.join(extensionsDir, 'extensions.json'), JSON.stringify([ + { identifier: { id: 'vscodevim.vim' } }, + ])); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + now: () => new Date('2026-07-29T12:00:00.000Z'), + }); + + assert.strictEqual(result.status, 'imported'); + assert.strictEqual(result.keymap, 'vim'); + assert.strictEqual( + readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), + keybindings, + ); + const settings = JSON.parse(readFileSync(path.join(fixture.target, 'User', 'settings.json'), 'utf8')); + assert.deepStrictEqual(settings, { + 'editor.fontSize': 15, + 'vim.useSystemClipboard': true, + 'review.keymap': 'vim', + }); + assert.deepStrictEqual( + JSON.parse(readFileSync(path.join(fixture.target, 'User', '.review-import.json'), 'utf8')), + { + version: 1, + source: fixture.sourceUser, + importedAt: '2026-07-29T12:00:00.000Z', + keymap: 'vim', + }, + ); + }); + + test('does not import twice after writing the stamp', () => { + const fixture = createFixture(); + writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[]\n'); + const options = { + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + }; + assert.strictEqual(importReviewUserConfig(options).status, 'imported'); + writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[{ "key": "x", "command": "x" }]\n'); + + const second = importReviewUserConfig(options); + assert.strictEqual(second.status, 'skipped'); + assert.strictEqual(second.reason, 'stamp-exists'); + assert.strictEqual(readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), '[]\n'); + }); + + test('never clobbers a pre-existing keybindings file on startup', () => { + const fixture = createFixture(); + writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[{ "key": "source" }]\n'); + mkdirSync(path.join(fixture.target, 'User'), { recursive: true }); + writeFileSync(path.join(fixture.target, 'User', 'keybindings.json'), '[{ "key": "mine" }]\n'); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + }); + + assert.strictEqual(result.status, 'skipped'); + assert.strictEqual(result.reason, 'keybindings-exists'); + assert.strictEqual( + readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), + '[{ "key": "mine" }]\n', + ); + }); + + test('never clobbers a pre-existing settings file on startup', () => { + const fixture = createFixture(); + writeFileSync(path.join(fixture.sourceUser, 'settings.json'), '{ "editor.fontSize": 22 }\n'); + mkdirSync(path.join(fixture.target, 'User'), { recursive: true }); + const targetSettings = path.join(fixture.target, 'User', 'settings.json'); + writeFileSync(targetSettings, '{ "editor.fontSize": 11, "workbench.colorTheme": "MyTheme" }\n'); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + }); + + assert.strictEqual(result.status, 'skipped'); + assert.strictEqual(result.reason, 'settings-exists'); + assert.strictEqual( + readFileSync(targetSettings, 'utf8'), + '{ "editor.fontSize": 11, "workbench.colorTheme": "MyTheme" }\n', + ); + }); + + test('maps a Code Insiders override to its exact extensions directory', () => { + const fixture = createFixture(); + const insidersUser = path.join(fixture.root, 'Code - Insiders', 'User'); + mkdirSync(insidersUser, { recursive: true }); + writeFileSync(path.join(insidersUser, 'settings.json'), '{ "editor.fontSize": 15 }\n'); + mkdirSync(path.join(fixture.root, '.vscode-insiders', 'extensions', 'vscodevim.vim-1.32.4'), { recursive: true }); + mkdirSync(path.join(fixture.root, '.vscode', 'extensions', 'tuttieee.emacs-mcx-0.40.0'), { recursive: true }); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: insidersUser }, + homeDir: fixture.root, + }); + + assert.strictEqual(result.status, 'imported'); + assert.strictEqual(result.source, insidersUser); + assert.strictEqual(result.keymap, 'vim'); + }); + + test('previews manual overwrites without changing them', () => { + const fixture = createFixture(); + writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[]\n'); + mkdirSync(path.join(fixture.target, 'User'), { recursive: true }); + const targetKeybindings = path.join(fixture.target, 'User', 'keybindings.json'); + writeFileSync(targetKeybindings, '[{ "key": "mine" }]\n'); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + mode: 'preview', + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + }); + + assert.strictEqual(result.status, 'ready'); + assert.deepStrictEqual(result.wouldOverwrite, [targetKeybindings]); + assert.strictEqual(readFileSync(targetKeybindings, 'utf8'), '[{ "key": "mine" }]\n'); + + const applied = importReviewUserConfig({ + userDataPath: fixture.target, + mode: 'apply', + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + }); + assert.strictEqual(applied.status, 'imported'); + assert.strictEqual(readFileSync(targetKeybindings, 'utf8'), '[]\n'); + }); + + test('chooses the most recently modified VS Code-family default profile', () => { + const fixture = createFixture(); + const configRoot = path.join(fixture.root, 'config'); + const codeUser = path.join(configRoot, 'Code', 'User'); + const cursorUser = path.join(configRoot, 'Cursor', 'User'); + mkdirSync(codeUser, { recursive: true }); + mkdirSync(cursorUser, { recursive: true }); + writeFileSync(path.join(codeUser, 'keybindings.json'), '[{ "key": "code" }]\n'); + writeFileSync(path.join(cursorUser, 'keybindings.json'), '[{ "key": "cursor" }]\n'); + utimesSync(path.join(codeUser, 'keybindings.json'), new Date(1_000), new Date(1_000)); + utimesSync(path.join(cursorUser, 'keybindings.json'), new Date(2_000), new Date(2_000)); + utimesSync(codeUser, new Date(1_000), new Date(1_000)); + utimesSync(cursorUser, new Date(2_000), new Date(2_000)); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + platform: 'linux', + env: { XDG_CONFIG_HOME: configRoot }, + homeDir: fixture.root, + }); + + assert.strictEqual(result.source, cursorUser); + assert.strictEqual( + readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), + '[{ "key": "cursor" }]\n', + ); + }); + + test('no Review hardening default survives an import', () => { + // An imported setting beats a default, so any key Review pins here that + // arrives from the user's old profile silently un-hardens the app. + const fixture = createFixture(); + const hardened = [ + ...Object.keys(reviewConfigurationDefaults), + ...Object.keys(curatedExtensionConfigurationDefaults), + ]; + assert.ok(hardened.length > 0); + const imported: Record = { 'editor.fontSize': 15 }; + for (const key of hardened) { + imported[key] = `imported:${key}`; + } + writeFileSync( + path.join(fixture.sourceUser, 'settings.json'), + JSON.stringify(imported, undefined, '\t'), + ); + + const result = importReviewUserConfig({ + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: fixture.sourceRoot }, + homeDir: fixture.root, + }); + + assert.strictEqual(result.status, 'imported'); + const settings = JSON.parse( + readFileSync(path.join(fixture.target, 'User', 'settings.json'), 'utf8'), + ) as Record; + assert.deepStrictEqual( + hardened.filter(key => key in settings), + [], + ); + // The filter has to be the hardened key set, not a blanket refusal. + assert.strictEqual(settings['editor.fontSize'], 15); + }); + + test('honours the import opt-out', () => { + const fixture = createFixture(); + const result = importReviewUserConfig({ + userDataPath: fixture.target, + env: { DEV_REVIEW_IMPORT_FROM: 'none' }, + homeDir: fixture.root, + }); + assert.strictEqual(result.status, 'disabled'); + }); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/node/reviewUserConfigImport.ts b/apps/review-desktop/code-oss/src/vs/review/node/reviewUserConfigImport.ts new file mode 100644 index 000000000..8dda38b48 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/node/reviewUserConfigImport.ts @@ -0,0 +1,345 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, copyFileSync } from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import { parse, type ParseError } from '../../base/common/json.js'; +// Setting keys come from the import-free defaults module, never from +// `reviewConfiguration.js`: this runs in the main process before bootstrapESM(), +// so reaching the configuration registry behind it would throw +// `!!! NLS MISSING: !!!` in a packaged build. See reviewConfigurationDefaults.ts. +import { curatedExtensionConfigurationDefaults, reviewConfigurationDefaults, type ReviewKeymap } from '../common/reviewConfigurationDefaults.js'; + +export const REVIEW_USER_CONFIG_IMPORT_VERSION = 1; + +export type { ReviewKeymap }; +export type ReviewUserConfigImportMode = 'startup' | 'preview' | 'apply'; + +export interface ReviewUserConfigImportOptions { + readonly userDataPath: string; + readonly mode?: ReviewUserConfigImportMode; + readonly homeDir?: string; + readonly platform?: NodeJS.Platform; + readonly env?: NodeJS.ProcessEnv; + readonly now?: () => Date; + readonly log?: (message: string) => void; +} + +export interface ReviewUserConfigImportResult { + readonly status: 'disabled' | 'not-found' | 'skipped' | 'ready' | 'imported'; + readonly source?: string; + readonly keymap: ReviewKeymap; + readonly files: readonly string[]; + readonly wouldOverwrite: readonly string[]; + readonly reason?: 'stamp-exists' | 'keybindings-exists' | 'settings-exists'; + readonly defaultProfileOnly?: boolean; +} + +interface SourceCandidate { + readonly userDir: string; + readonly extensionsDir?: string; + readonly modifiedAt: number; +} + +interface PreparedImport { + readonly source: SourceCandidate; + readonly keymap: ReviewKeymap; + readonly keybindings?: string; + readonly settings?: Record; + readonly defaultProfileOnly: boolean; +} + +const BLOCKED_SETTING_PREFIXES = [ + 'telemetry.', + 'update.', + 'extensions.', + 'chat.', + 'github.', + 'workbench.enableExperiments', + 'security.workspace.trust.', + 'remote.', +] as const; + +const BLOCKED_SETTING_KEYS = new Set([ + ...Object.keys(reviewConfigurationDefaults), + // An imported setting beats a default, so a VS Code user who runs Pylance + // would carry `python.languageServer: "Pylance"` in and re-arm the install + // prompt for an extension Review cannot ship. The same holds for every other + // prompt these defaults close. + ...Object.keys(curatedExtensionConfigurationDefaults), +]); + +const SOURCE_INSTALLS = [ + { name: 'Code', extensionsHome: '.vscode' }, + { name: 'Code - Insiders', extensionsHome: '.vscode-insiders' }, + { name: 'VSCodium', extensionsHome: '.vscode-oss' }, + { name: 'Cursor', extensionsHome: '.cursor' }, +] as const; + +const KEYMAP_EXTENSIONS: Readonly, string>> = { + vim: 'vscodevim.vim', + emacs: 'tuttieee.emacs-mcx', +}; + +function existingMtime(target: string): number { + try { + return statSync(target).mtimeMs; + } catch { + return 0; + } +} + +function sourceModifiedAt(userDir: string): number { + return Math.max( + existingMtime(userDir), + existingMtime(path.join(userDir, 'keybindings.json')), + existingMtime(path.join(userDir, 'settings.json')), + ); +} + +function isUsableSource(userDir: string): boolean { + return existsSync(path.join(userDir, 'keybindings.json')) || existsSync(path.join(userDir, 'settings.json')); +} + +function extensionDirectoryForOverride(userDir: string, homeDir: string): string | undefined { + const installName = path.basename(path.dirname(userDir)).toLowerCase(); + for (const install of SOURCE_INSTALLS) { + if (installName === install.name.toLowerCase()) { + return path.join(homeDir, install.extensionsHome, 'extensions'); + } + } + + const fixtureStyleExtensions = path.join(path.dirname(userDir), 'extensions'); + return existsSync(fixtureStyleExtensions) ? fixtureStyleExtensions : undefined; +} + +function discoverSource(options: ReviewUserConfigImportOptions): SourceCandidate | 'disabled' | undefined { + const env = options.env ?? process.env; + const homeDir = options.homeDir ?? os.homedir(); + const override = env['DEV_REVIEW_IMPORT_FROM']; + + if (override?.toLowerCase() === 'none') { + return 'disabled'; + } + + if (override) { + const expanded = path.resolve(override); + const userDir = path.basename(expanded) === 'User' ? expanded : path.join(expanded, 'User'); + if (!isUsableSource(userDir)) { + return undefined; + } + return { + userDir, + extensionsDir: extensionDirectoryForOverride(userDir, homeDir), + modifiedAt: sourceModifiedAt(userDir), + }; + } + + const configRoot = options.platform === 'darwin' || (options.platform === undefined && process.platform === 'darwin') + ? path.join(homeDir, 'Library', 'Application Support') + : path.resolve(env['XDG_CONFIG_HOME'] ?? path.join(homeDir, '.config')); + + const candidates = SOURCE_INSTALLS + .map(install => { + const userDir = path.join(configRoot, install.name, 'User'); + return { + userDir, + extensionsDir: path.join(homeDir, install.extensionsHome, 'extensions'), + modifiedAt: sourceModifiedAt(userDir), + }; + }) + .filter(candidate => isUsableSource(candidate.userDir)) + .sort((left, right) => right.modifiedAt - left.modifiedAt); + + return candidates[0]; +} + +function extensionIdsFromMetadata(extensionsDir: string): Set | undefined { + const metadataPath = path.join(extensionsDir, 'extensions.json'); + if (!existsSync(metadataPath)) { + return undefined; + } + + const errors: ParseError[] = []; + const value = parse(readFileSync(metadataPath, 'utf8'), errors); + if (errors.length > 0 || !Array.isArray(value)) { + return new Set(); + } + + const ids = new Set(); + for (const entry of value) { + if (!entry || typeof entry !== 'object') { + continue; + } + const identifier = (entry as { identifier?: unknown }).identifier; + const id = identifier && typeof identifier === 'object' + ? (identifier as { id?: unknown }).id + : (entry as { id?: unknown }).id; + if (typeof id === 'string') { + ids.add(id.toLowerCase()); + } + } + return ids; +} + +function detectKeymap(extensionsDir: string | undefined): ReviewKeymap { + if (!extensionsDir || !existsSync(extensionsDir)) { + return 'none'; + } + + const metadataIds = extensionIdsFromMetadata(extensionsDir); + const candidates: { keymap: Exclude; modifiedAt: number }[] = []; + for (const entry of readdirSync(extensionsDir, { withFileTypes: true })) { + if (!entry.isDirectory()) { + continue; + } + const normalizedName = entry.name.toLowerCase(); + for (const [keymap, extensionId] of Object.entries(KEYMAP_EXTENSIONS) as [Exclude, string][]) { + if (!normalizedName.startsWith(`${extensionId}-`)) { + continue; + } + if (metadataIds && !metadataIds.has(extensionId)) { + continue; + } + candidates.push({ + keymap, + modifiedAt: existingMtime(path.join(extensionsDir, entry.name)), + }); + } + } + + candidates.sort((left, right) => right.modifiedAt - left.modifiedAt); + return candidates[0]?.keymap ?? 'none'; +} + +function shouldImportSetting(key: string): boolean { + if (BLOCKED_SETTING_KEYS.has(key)) { + return false; + } + return !BLOCKED_SETTING_PREFIXES.some(prefix => key.startsWith(prefix)); +} + +function filterReviewUserSettings(settings: Record): Record { + return Object.fromEntries(Object.entries(settings).filter(([key]) => shouldImportSetting(key))); +} + +function readSettings(settingsPath: string): Record | undefined { + if (!existsSync(settingsPath)) { + return undefined; + } + + const errors: ParseError[] = []; + const value = parse(readFileSync(settingsPath, 'utf8'), errors); + if (errors.length > 0 || !value || typeof value !== 'object' || Array.isArray(value)) { + throw new Error(`Cannot import invalid VS Code settings from ${settingsPath}`); + } + return filterReviewUserSettings(value as Record); +} + +function prepareImport(source: SourceCandidate, log: (message: string) => void): PreparedImport { + const profilesDir = path.join(source.userDir, 'profiles'); + const defaultProfileOnly = existsSync(profilesDir); + if (defaultProfileOnly) { + log(`Review user-config import found profiles under ${profilesDir}; importing the default profile only.`); + } + + const keymap = detectKeymap(source.extensionsDir); + const keybindingsPath = path.join(source.userDir, 'keybindings.json'); + const settings = readSettings(path.join(source.userDir, 'settings.json')); + if (settings && keymap !== 'none') { + settings['review.keymap'] = keymap; + } + + return { + source, + keymap, + keybindings: existsSync(keybindingsPath) ? keybindingsPath : undefined, + settings: settings ?? (keymap !== 'none' ? { 'review.keymap': keymap } : undefined), + defaultProfileOnly, + }; +} + +function targetFiles(prepared: PreparedImport, userDir: string): string[] { + const files: string[] = []; + if (prepared.keybindings) { + files.push(path.join(userDir, 'keybindings.json')); + } + if (prepared.settings) { + files.push(path.join(userDir, 'settings.json')); + } + files.push(path.join(userDir, '.review-import.json')); + return files; +} + +function writeImport(prepared: PreparedImport, userDir: string, now: () => Date): string[] { + mkdirSync(userDir, { recursive: true }); + const files = targetFiles(prepared, userDir); + if (prepared.keybindings) { + copyFileSync(prepared.keybindings, path.join(userDir, 'keybindings.json')); + } + if (prepared.settings) { + writeFileSync(path.join(userDir, 'settings.json'), `${JSON.stringify(prepared.settings, null, '\t')}\n`, 'utf8'); + } + writeFileSync(path.join(userDir, '.review-import.json'), `${JSON.stringify({ + version: REVIEW_USER_CONFIG_IMPORT_VERSION, + source: prepared.source.userDir, + importedAt: now().toISOString(), + keymap: prepared.keymap, + }, null, '\t')}\n`, 'utf8'); + return files; +} + +export function importReviewUserConfig(options: ReviewUserConfigImportOptions): ReviewUserConfigImportResult { + const mode = options.mode ?? 'startup'; + const targetUserDir = path.join(options.userDataPath, 'User'); + const stampPath = path.join(targetUserDir, '.review-import.json'); + const keybindingsPath = path.join(targetUserDir, 'keybindings.json'); + const settingsPath = path.join(targetUserDir, 'settings.json'); + const log = options.log ?? (() => undefined); + + if (mode === 'startup' && existsSync(stampPath)) { + return { status: 'skipped', keymap: 'none', files: [], wouldOverwrite: [], reason: 'stamp-exists' }; + } + if (mode === 'startup' && existsSync(keybindingsPath)) { + return { status: 'skipped', keymap: 'none', files: [], wouldOverwrite: [], reason: 'keybindings-exists' }; + } + if (mode === 'startup' && existsSync(settingsPath)) { + return { status: 'skipped', keymap: 'none', files: [], wouldOverwrite: [], reason: 'settings-exists' }; + } + + const source = discoverSource(options); + if (source === 'disabled') { + return { status: 'disabled', keymap: 'none', files: [], wouldOverwrite: [] }; + } + if (!source) { + return { status: 'not-found', keymap: 'none', files: [], wouldOverwrite: [] }; + } + + const prepared = prepareImport(source, log); + const files = targetFiles(prepared, targetUserDir); + const wouldOverwrite = files.filter(file => existsSync(file)); + if (mode === 'preview') { + return { + status: 'ready', + source: source.userDir, + keymap: prepared.keymap, + files, + wouldOverwrite, + defaultProfileOnly: prepared.defaultProfileOnly, + }; + } + + const written = writeImport(prepared, targetUserDir, options.now ?? (() => new Date())); + log(`Review imported VS Code settings and keybindings from ${source.userDir}.`); + return { + status: 'imported', + source: source.userDir, + keymap: prepared.keymap, + files: written, + wouldOverwrite, + defaultProfileOnly: prepared.defaultProfileOnly, + }; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/review.common.main.ts b/apps/review-desktop/code-oss/src/vs/review/review.common.main.ts new file mode 100644 index 000000000..42e449fb9 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/review.common.main.ts @@ -0,0 +1,285 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Review's curated workbench manifest. Keep this list explicit: importing the +// stock or Sessions manifests re-registers the chrome and product surfaces that +// Review intentionally does not ship. + +import { Event } from "../base/common/event.js"; +import { Disposable, type IDisposable } from "../base/common/lifecycle.js"; +import type { URI } from "../base/common/uri.js"; +import "../editor/editor.all.js"; +import { getColorRegistry } from "../platform/theme/common/colorUtils.js"; +import { agentsPanelBackground } from "../workbench/common/agentTheme.js"; +import { PANEL_BACKGROUND } from "../workbench/common/theme.js"; + +getColorRegistry().updateDefaultColor(PANEL_BACKGROUND, agentsPanelBackground); + +// Core editor/workbench API. +import "../workbench/api/browser/viewsExtensionPoint.js"; +import "../workbench/api/common/configurationExtensionPoint.js"; +import "../workbench/browser/actions/listCommands.js"; +import "../workbench/browser/actions/navigationActions.js"; +import "../workbench/browser/actions/quickAccessActions.js"; +import "../workbench/browser/actions/textInputActions.js"; +import "../workbench/browser/actions/widgetNavigationCommands.js"; +import "../workbench/browser/actions/windowActions.js"; +import "../workbench/browser/actions/workspaceActions.js"; +import "../workbench/browser/actions/workspaceCommands.js"; +import "../workbench/browser/parts/editor/diffEditor.workbench.contribution.js"; +import "../workbench/browser/parts/editor/editor.contribution.js"; +import "../workbench/browser/workbench.contribution.js"; +import "../workbench/services/actions/common/menusExtensionPoint.js"; +import "./reviewExtensionHost.contribution.js"; +// Core services required by editors, language features, webviews, and files. +import { OpenerService } from "../editor/browser/services/openerService.js"; +import "../editor/common/services/languageFeaturesService.js"; +import { IMarkerDecorationsService } from "../editor/common/services/markerDecorations.js"; +import { MarkerDecorationsService } from "../editor/common/services/markerDecorationsService.js"; +import "../editor/common/services/semanticTokensStylingService.js"; +import { ITextResourceConfigurationService } from "../editor/common/services/textResourceConfiguration.js"; +import { TextResourceConfigurationService } from "../editor/common/services/textResourceConfigurationService.js"; +import "../editor/common/services/treeViewsDndService.js"; +import "../platform/actions/common/actions.contribution.js"; +import { ContextKeyService } from "../platform/contextkey/browser/contextKeyService.js"; +import { IContextKeyService } from "../platform/contextkey/common/contextkey.js"; +import { IContextViewService } from "../platform/contextview/browser/contextView.js"; +import { ContextViewService } from "../platform/contextview/browser/contextViewService.js"; +import { IDownloadService } from "../platform/download/common/download.js"; +import { DownloadService } from "../platform/download/common/downloadService.js"; +import { AllowedExtensionsService } from "../platform/extensionManagement/common/allowedExtensionsService.js"; +import { GlobalExtensionEnablementService } from "../platform/extensionManagement/common/extensionEnablementService.js"; +import { + IAllowedExtensionsService, + IGlobalExtensionEnablementService, +} from "../platform/extensionManagement/common/extensionManagement.js"; +import { + ExtensionStorageService, + IExtensionStorageService, +} from "../platform/extensionManagement/common/extensionStorage.js"; +import "../platform/hover/browser/hoverService.js"; +import { InstantiationType, registerSingleton } from "../platform/instantiation/common/extensions.js"; +import { IListService, ListService } from "../platform/list/browser/listService.js"; +import { IMarkerService } from "../platform/markers/common/markers.js"; +import { MarkerService } from "../platform/markers/common/markerService.js"; +import { IOpenerService } from "../platform/opener/common/opener.js"; +import "../platform/undoRedo/common/undoRedoService.js"; +import { + IgnoredExtensionsManagementService, + IIgnoredExtensionsManagementService, +} from "../platform/userDataSync/common/ignoredExtensions.js"; +import { IUserDataSyncLogService } from "../platform/userDataSync/common/userDataSync.js"; +import { UserDataSyncLogService } from "../platform/userDataSync/common/userDataSyncLog.js"; +import "../platform/userInteraction/browser/userInteractionServiceImpl.js"; +import { IWebWorkerService } from "../platform/webWorker/browser/webWorkerService.js"; +import { WebWorkerService } from "../platform/webWorker/browser/webWorkerServiceImpl.js"; +import { + ChatContextPickService, + IChatContextPickService, +} from "../workbench/contrib/chat/browser/attachments/chatContextPickService.js"; +import { type IChatWidget, IChatWidgetService } from "../workbench/contrib/chat/browser/chat.js"; +import type { IChatEditorOptions } from "../workbench/contrib/chat/browser/widgetHosts/editor/chatEditor.js"; +import type { ChatAgentLocation } from "../workbench/contrib/chat/common/constants.js"; +import "../workbench/contrib/output/browser/output.contribution.js"; +import "../workbench/services/activity/browser/activityService.js"; +import "../workbench/services/authentication/browser/authenticationAccessService.js"; +import "../workbench/services/authentication/browser/authenticationExtensionsService.js"; +import "../workbench/services/authentication/browser/authenticationService.js"; +import "../workbench/services/authentication/browser/authenticationUsageService.js"; +import "../workbench/services/commands/common/commandService.js"; +import "../workbench/services/configuration/common/jsonEditingService.js"; +import "../workbench/services/dataChannel/browser/dataChannelService.js"; +import "../workbench/services/decorations/browser/decorationsService.js"; +import "../workbench/services/dialogs/common/dialogService.js"; +import "../workbench/services/editor/browser/codeEditorService.js"; +import "../workbench/services/editor/browser/editorPaneService.js"; +import "../workbench/services/editor/browser/editorResolverService.js"; +import "../workbench/services/editor/browser/editorService.js"; +import "../workbench/services/editor/common/customEditorLabelService.js"; +import type { PreferredGroup } from "../workbench/services/editor/common/editorService.js"; +import "../workbench/services/extensionManagement/browser/builtinExtensionsScannerService.js"; +import "../workbench/services/extensionManagement/browser/extensionEnablementService.js"; +import "../workbench/services/extensionManagement/common/extensionFeaturesManagemetService.js"; +import "../workbench/services/extensionManagement/common/extensionGalleryService.js"; +import "../workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.js"; +import "../workbench/services/extensionRecommendations/common/workspaceExtensionsConfig.js"; +import "../workbench/services/extensions/browser/extensionUrlHandler.js"; +import "../workbench/services/extensions/common/extensionManifestPropertiesService.js"; +import "../workbench/services/filesConfiguration/common/filesConfigurationService.js"; +import "../workbench/services/history/browser/historyService.js"; +import "../workbench/services/inlineCompletions/common/inlineCompletionsUnification.js"; +import "../workbench/services/keybinding/browser/keybindingService.js"; +import "../workbench/services/keybinding/common/keybindingEditing.js"; +import "../workbench/services/label/common/labelService.js"; +import "../workbench/services/language/common/languageService.js"; +import "../workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.js"; +import "../workbench/services/log/common/defaultLogLevels.js"; +import "../workbench/services/model/common/modelService.js"; +import "../workbench/services/notification/common/notificationService.js"; +import "../workbench/services/preferences/browser/preferencesService.js"; +import "../workbench/services/progress/browser/progressService.js"; +import "../workbench/services/quickinput/browser/quickInputService.js"; +import "../workbench/services/remote/common/remoteExtensionsScanner.js"; +import "../workbench/services/textfile/common/textEditorService.js"; +import "../workbench/services/textMate/browser/textMateTokenizationFeature.contribution.js"; +import "../workbench/services/textmodelResolver/common/textModelResolverService.js"; +import "../workbench/services/textresourceProperties/common/textResourcePropertiesService.js"; +import "../workbench/services/themes/browser/workbenchThemeService.js"; +import "../workbench/services/treeSitter/browser/treeSitter.contribution.js"; +import "../workbench/services/untitled/common/untitledTextEditorService.js"; +import "../workbench/services/userActivity/browser/userActivityBrowser.js"; +import "../workbench/services/userActivity/common/userActivityService.js"; +import "../workbench/services/userAttention/browser/userAttentionBrowser.js"; +import "../workbench/services/userDataProfile/browser/userDataProfileImportExportService.js"; +import "../workbench/services/userDataProfile/browser/userDataProfileManagement.js"; +import "../workbench/services/userDataProfile/common/remoteUserDataProfiles.js"; +import "../workbench/services/userDataSync/browser/userDataSyncWorkbenchService.js"; +import "../workbench/services/userDataSync/common/userDataSyncUtil.js"; +import "../workbench/services/views/browser/viewDescriptorService.js"; +import "../workbench/services/views/browser/viewsService.js"; +import "../workbench/services/workingCopy/common/workingCopyEditorService.js"; +import "../workbench/services/workingCopy/common/workingCopyFileService.js"; +import "../workbench/services/workingCopy/common/workingCopyService.js"; +import "../workbench/services/workspaces/common/canonicalUriService.js"; +import "../workbench/services/workspaces/common/editSessionIdentityService.js"; + +class ReviewChatWidgetService implements IChatWidgetService { + declare readonly _serviceBrand: undefined; + + readonly lastFocusedWidget = undefined; + readonly onDidAddWidget = Event.None; + readonly onDidBackgroundSession = Event.None; + readonly onDidChangeFocusedWidget = Event.None; + readonly onDidChangeFocusedSession = Event.None; + + reveal(_widget: IChatWidget, _preserveFocus?: boolean): Promise { + return Promise.resolve(false); + } + + revealWidget(_preserveFocus?: boolean): Promise { + return Promise.resolve(undefined); + } + + getAllWidgets(): readonly IChatWidget[] { + return []; + } + + getWidgetByInputUri(_uri: URI): undefined { + return undefined; + } + + openSession(_sessionResource: URI): Promise; + openSession(_sessionResource: URI, _target?: PreferredGroup, _options?: IChatEditorOptions): Promise; + openSession(): Promise { + return Promise.resolve(undefined); + } + + getWidgetBySessionResource(_sessionResource: URI): undefined { + return undefined; + } + + getWidgetsByLocations(_location: ChatAgentLocation): readonly IChatWidget[] { + return []; + } + + register(_newWidget: IChatWidget): IDisposable { + return Disposable.None; + } +} + +registerSingleton(IUserDataSyncLogService, UserDataSyncLogService, InstantiationType.Delayed); +registerSingleton(IAllowedExtensionsService, AllowedExtensionsService, InstantiationType.Delayed); +registerSingleton(IIgnoredExtensionsManagementService, IgnoredExtensionsManagementService, InstantiationType.Delayed); +registerSingleton(IGlobalExtensionEnablementService, GlobalExtensionEnablementService, InstantiationType.Delayed); +registerSingleton(IExtensionStorageService, ExtensionStorageService, InstantiationType.Delayed); +registerSingleton(IContextViewService, ContextViewService, InstantiationType.Delayed); +registerSingleton(IListService, ListService, InstantiationType.Delayed); +registerSingleton(IMarkerDecorationsService, MarkerDecorationsService, InstantiationType.Delayed); +registerSingleton(IMarkerService, MarkerService, InstantiationType.Delayed); +registerSingleton(IContextKeyService, ContextKeyService, InstantiationType.Delayed); +registerSingleton(IChatContextPickService, ChatContextPickService, InstantiationType.Delayed); +registerSingleton(IChatWidgetService, ReviewChatWidgetService, InstantiationType.Delayed); +registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService, InstantiationType.Delayed); +registerSingleton(IDownloadService, DownloadService, InstantiationType.Delayed); +registerSingleton(IOpenerService, OpenerService, InstantiationType.Delayed); +registerSingleton(IWebWorkerService, WebWorkerService, InstantiationType.Delayed); + +// Curated contributions: editor/files/theme/webview/outline/logs only. +import "../workbench/contrib/bulkEdit/browser/bulkEditService.js"; +import "../workbench/contrib/files/browser/fileActions.contribution.js"; +import "../workbench/contrib/files/browser/files.contribution.js"; +import "../workbench/contrib/logs/common/logs.contribution.js"; +import "./browser/parts/canvas/reviewCanvasEditor.contribution.js"; +import "./browser/parts/canvas/reviewFind.contribution.js"; +import "./browser/reviewCommunity.contribution.js"; +import "./browser/reviewTheme.contribution.js"; +import "./contrib/explorer/reviewFileTree.contribution.js"; +import "./contrib/extensions/reviewCuratedExtensions.contribution.js"; +import "./contrib/install/reviewCliInstall.contribution.js"; +import "./contrib/quickaccess/reviewQuickAccess.contribution.js"; +import "./contrib/settings/reviewSettings.contribution.js"; +import "./contrib/telemetry/reviewLspTelemetry.contribution.js"; +import "./contrib/telemetry/reviewTelemetry.contribution.js"; +// editor.all instantiates RenameSymbolProcessor; keep its service-only peer. +import "../workbench/contrib/accessibility/browser/accessibility.contribution.js"; +import "../workbench/contrib/accessibilitySignals/browser/accessibilitySignal.contribution.js"; +import "../workbench/contrib/codeActions/browser/codeActions.contribution.js"; +import "../workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.js"; +import "../workbench/contrib/codeEditor/browser/workbenchReferenceSearch.js"; +import "../workbench/contrib/commands/common/commands.contribution.js"; +import { IDebugService } from "../workbench/contrib/debug/common/debug.js"; +import { IDebugVisualizerService } from "../workbench/contrib/debug/common/debugVisualizers.js"; +import { NullDebugService, NullDebugVisualizerService } from "../workbench/contrib/debug/common/nullDebugService.js"; +import "../workbench/contrib/folding/browser/folding.contribution.js"; +import "../workbench/contrib/format/browser/format.contribution.js"; +import "../workbench/contrib/inlineCompletions/browser/renameSymbolTrackerService.js"; +import "../workbench/contrib/keybindings/browser/keybindings.contribution.js"; +import "../workbench/contrib/list/browser/list.contribution.js"; +import "../workbench/contrib/opener/browser/opener.contribution.js"; +import "../workbench/contrib/sash/browser/sash.contribution.js"; +import "../workbench/contrib/search/browser/searchQuickAccess.contribution.js"; +import "../workbench/contrib/snippets/browser/snippets.service.contribution.js"; +import "../workbench/contrib/speech/browser/speech.contribution.js"; +import "../workbench/contrib/themes/browser/themes.contribution.js"; +import "../workbench/contrib/webview/browser/webview.contribution.js"; +import "../workbench/contrib/webviewPanel/browser/webviewPanel.contribution.js"; +import "../workbench/contrib/workspace/browser/workspace.contribution.js"; +import "../workbench/services/outline/browser/outlineService.js"; +registerSingleton(IDebugService, NullDebugService, InstantiationType.Delayed); +registerSingleton(IDebugVisualizerService, NullDebugVisualizerService, InstantiationType.Delayed); +// Sessions supplies the native fixed-grid shell; Review replaces its session +// model, setup flow, and content part and deliberately imports no Agents UI. +import "../workbench/browser/parts/editor/editorParts.js"; +import { IReviewCanvasPartsService, ReviewCanvasParts } from "./browser/parts/canvas/reviewCanvasPart.js"; +import { IReviewExplorerPartsService, ReviewExplorerParts } from "./browser/parts/explorer/reviewExplorerPart.js"; +import "./browser/reviewPaneCompositePartService.js"; +import "./common/reviewConfiguration.js"; +import { IReviewVerbsService, ReviewVerbsService } from "./contrib/verbs/reviewVerbs.js"; +import { IReviewApiCatalogService, ReviewApiCatalogService } from "./services/reviewApiCatalogService.js"; +import { IReviewApiSourceService, ReviewApiSourceService } from "./services/reviewApiSourceService.js"; +import { + IReviewCanvasEditorTabsService, + ReviewCanvasEditorTabsService, +} from "./services/reviewCanvasEditorTabsService.js"; +import { + IReviewDesktopConnectionService, + ReviewDesktopConnectionService, +} from "./services/reviewDesktopConnectionService.js"; +import { IReviewTelemetryService, ReviewTelemetryService } from "./services/reviewTelemetryService.js"; +import "./services/reviewWorkbenchServices.js"; +import "./services/reviewLocalLanguageFeatures.js"; + +registerSingleton(IReviewDesktopConnectionService, ReviewDesktopConnectionService, InstantiationType.Eager); +registerSingleton(IReviewTelemetryService, ReviewTelemetryService, InstantiationType.Delayed); + +registerSingleton(IReviewCanvasEditorTabsService, ReviewCanvasEditorTabsService, InstantiationType.Delayed); + +registerSingleton(IReviewApiSourceService, ReviewApiSourceService, InstantiationType.Delayed); +registerSingleton(IReviewApiCatalogService, ReviewApiCatalogService, InstantiationType.Delayed); +registerSingleton(IReviewVerbsService, ReviewVerbsService, InstantiationType.Delayed); +registerSingleton(IReviewCanvasPartsService, ReviewCanvasParts, InstantiationType.Eager); +registerSingleton(IReviewExplorerPartsService, ReviewExplorerParts, InstantiationType.Eager); + +import "./contrib/sharing/reviewSharing.contribution.js"; diff --git a/apps/review-desktop/code-oss/src/vs/review/review.desktop.main.ts b/apps/review-desktop/code-oss/src/vs/review/review.desktop.main.ts new file mode 100644 index 000000000..fa25394db --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/review.desktop.main.ts @@ -0,0 +1,81 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Desktop-only service manifest. Product contributions such as chat, SCM, +// terminal, tasks, remote, surveys, profiles, and settings editors are +// intentionally absent. +// +// Updates are the exception: the update service is wired so Review can surface +// its own two toasts (see contrib/update). The stock update contribution stays +// out — its title bar entry requires the chat service, which Review omits. +import './review.common.main.js'; +import './electron-browser/review.main.js'; +import '../workbench/electron-browser/desktop.contribution.js'; +import '../workbench/electron-browser/parts/dialogs/dialog.contribution.js'; + +import '../workbench/services/textfile/electron-browser/nativeTextFileService.js'; +import '../workbench/services/dialogs/electron-browser/fileDialogService.js'; +import '../workbench/services/workspaces/electron-browser/workspacesService.js'; +import '../workbench/services/menubar/electron-browser/menubarService.js'; +import '../workbench/services/update/electron-browser/updateService.js'; +import '../workbench/services/url/electron-browser/urlService.js'; +import '../workbench/services/lifecycle/electron-browser/lifecycleService.js'; +import '../workbench/services/host/electron-browser/nativeHostService.js'; +import '../platform/meteredConnection/electron-browser/meteredConnectionService.js'; +import '../workbench/services/request/electron-browser/requestService.js'; +import '../workbench/services/clipboard/electron-browser/clipboardService.js'; +import '../workbench/services/contextmenu/electron-browser/contextmenuService.js'; +import '../workbench/services/configurationResolver/electron-browser/configurationResolverService.js'; +import '../workbench/services/accessibility/electron-browser/accessibilityService.js'; +import '../workbench/services/keybinding/electron-browser/nativeKeyboardLayout.js'; +import '../workbench/services/path/electron-browser/pathService.js'; +import '../workbench/services/themes/electron-browser/nativeHostColorSchemeService.js'; +import '../workbench/services/extensionManagement/electron-browser/extensionManagementService.js'; +import '../workbench/services/encryption/electron-browser/encryptionService.js'; +import '../workbench/services/imageResize/electron-browser/imageResizeService.js'; +import '../workbench/services/secrets/electron-browser/secretStorageService.js'; +import '../workbench/services/localization/electron-browser/languagePackService.js'; +import '../workbench/services/telemetry/electron-browser/telemetryService.js'; +import '../workbench/services/extensions/electron-browser/extensionHostStarter.js'; +import '../platform/extensionResourceLoader/common/extensionResourceLoaderService.js'; +import '../workbench/services/localization/electron-browser/localeService.js'; +import '../workbench/services/extensions/electron-browser/extensionsScannerService.js'; +import '../workbench/services/extensionManagement/electron-browser/extensionManagementServerService.js'; +import '../workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.js'; +import '../workbench/services/userDataSync/electron-browser/userDataSyncService.js'; +import '../workbench/services/userDataSync/browser/userDataSyncEnablementService.js'; +import '../workbench/services/timer/electron-browser/timerService.js'; +import '../workbench/services/environment/electron-browser/shellEnvironmentService.js'; +import '../workbench/services/integrity/electron-browser/integrityService.js'; +import '../workbench/services/workingCopy/electron-browser/workingCopyBackupService.js'; +import '../workbench/services/checksum/electron-browser/checksumService.js'; +import '../workbench/services/files/electron-browser/elevatedFileService.js'; +import '../workbench/services/search/electron-browser/searchService.js'; +import '../workbench/services/workingCopy/electron-browser/workingCopyHistoryService.js'; +import '../workbench/services/extensions/electron-browser/nativeExtensionService.js'; +import '../platform/userDataProfile/electron-browser/userDataProfileStorageService.js'; +import '../workbench/services/auxiliaryWindow/electron-browser/auxiliaryWindowService.js'; +import '../platform/extensionManagement/electron-browser/extensionsProfileScannerService.js'; +import '../platform/sandbox/electron-browser/sandboxHelperService.js'; +import '../workbench/services/process/electron-browser/processService.js'; +import '../platform/remote/electron-browser/sharedProcessTunnelService.js'; +import '../workbench/services/tunnel/electron-browser/tunnelService.js'; +import '../workbench/contrib/debug/electron-browser/extensionHostDebugService.js'; +import '../platform/diagnostics/electron-browser/diagnosticsService.js'; + +import { registerSingleton } from '../platform/instantiation/common/extensions.js'; +import { IUserDataInitializationService, UserDataInitializationService } from '../workbench/services/userData/browser/userDataInit.js'; +import { SyncDescriptor } from '../platform/instantiation/common/descriptors.js'; +registerSingleton(IUserDataInitializationService, new SyncDescriptor(UserDataInitializationService, [[]], true)); + +import '../workbench/contrib/logs/electron-browser/logs.contribution.js'; +import '../workbench/contrib/files/electron-browser/fileActions.contribution.js'; +import '../workbench/contrib/codeEditor/electron-browser/codeEditor.contribution.js'; +import '../workbench/services/themes/electron-browser/themes.contribution.js'; +import '../workbench/contrib/webview/electron-browser/webview.contribution.js'; +import '../workbench/contrib/splash/electron-browser/splash.contribution.js'; +import './contrib/update/reviewUpdate.contribution.js'; + +export { main } from './electron-browser/review.main.js'; diff --git a/apps/review-desktop/code-oss/src/vs/review/reviewExtensionHost.contribution.ts b/apps/review-desktop/code-oss/src/vs/review/reviewExtensionHost.contribution.ts new file mode 100644 index 000000000..86026f159 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/reviewExtensionHost.contribution.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IInstantiationService } from '../platform/instantiation/common/instantiation.js'; +import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from '../workbench/common/contributions.js'; +import { LanguageConfigurationFileHandler } from '../workbench/contrib/codeEditor/common/languageConfigurationExtensionPoint.js'; +import { JSONValidationExtensionPoint } from '../workbench/api/common/jsonValidationExtensionPoint.js'; +import { StatusBarItemsExtensionPoint } from '../workbench/api/browser/statusBarExtensionPoint.js'; +import { CSSExtensionPoint } from '../workbench/services/themes/browser/cssExtensionPoint.js'; +import { ColorExtensionPoint } from '../workbench/services/themes/common/colorExtensionPoint.js'; +import { IconExtensionPoint } from '../workbench/services/themes/common/iconExtensionPoint.js'; +import { TokenClassificationExtensionPoints } from '../workbench/services/themes/common/tokenClassificationExtensionPoint.js'; + +// Review exposes the generic editor/document/provider bridge. The stock Node +// extension host eagerly initializes a small set of additional API services; +// Review registers explicit unsupported peers for those APIs rather than +// pulling their terminal/task/authentication/chat product graphs into the app. +import './reviewExtensionHostUnsupportedApiPeers.js'; +import '../workbench/api/browser/mainThreadLocalization.js'; +import '../workbench/api/browser/mainThreadBulkEdits.js'; +import '../workbench/api/browser/mainThreadClipboard.js'; +import '../workbench/api/browser/mainThreadCommands.js'; +import '../workbench/api/browser/mainThreadConfiguration.js'; +import '../workbench/api/browser/mainThreadConsole.js'; +import '../workbench/api/browser/mainThreadDebugService.js'; +import '../workbench/api/browser/mainThreadDecorations.js'; +import '../workbench/api/browser/mainThreadDiagnostics.js'; +import '../workbench/api/browser/mainThreadDialogs.js'; +import '../workbench/api/browser/mainThreadDocumentContentProviders.js'; +import '../workbench/api/browser/mainThreadDocuments.js'; +import '../workbench/api/browser/mainThreadDocumentsAndEditors.js'; +import '../workbench/api/browser/mainThreadEditor.js'; +import '../workbench/api/browser/mainThreadEditors.js'; +import '../workbench/api/browser/mainThreadEditorTabs.js'; +import '../workbench/api/browser/mainThreadErrors.js'; +import '../workbench/api/browser/mainThreadExtensionService.js'; +import '../workbench/api/browser/mainThreadFileSystem.js'; +import '../workbench/api/browser/mainThreadFileSystemEventService.js'; +import '../workbench/api/browser/mainThreadLanguageFeatures.js'; +import '../workbench/api/browser/mainThreadLanguages.js'; +import '../workbench/api/browser/mainThreadLogService.js'; +import '../workbench/api/browser/mainThreadMessageService.js'; +import '../workbench/api/browser/mainThreadOutputService.js'; +import '../workbench/api/browser/mainThreadProgress.js'; +import '../workbench/api/browser/mainThreadQuickOpen.js'; +import '../workbench/api/browser/mainThreadRemoteConnectionData.js'; +import '../workbench/api/browser/mainThreadSaveParticipant.js'; +import '../workbench/api/browser/mainThreadSearch.js'; +import '../workbench/api/browser/mainThreadStatusBar.js'; +import '../workbench/api/browser/mainThreadStorage.js'; +import '../workbench/api/browser/mainThreadTelemetry.js'; +import '../workbench/api/browser/mainThreadTheming.js'; +import '../workbench/api/browser/mainThreadTreeViews.js'; +import '../workbench/api/browser/mainThreadDownloadService.js'; +import '../workbench/api/browser/mainThreadWindow.js'; +import '../workbench/api/browser/mainThreadWorkspace.js'; +import '../workbench/api/browser/mainThreadLabelService.js'; +import '../workbench/api/browser/mainThreadSecretState.js'; + +class ReviewExtensionPoints implements IWorkbenchContribution { + static readonly ID = 'review.contrib.extensionPoints'; + + constructor(@IInstantiationService instantiationService: IInstantiationService) { + instantiationService.createInstance(JSONValidationExtensionPoint); + instantiationService.createInstance(ColorExtensionPoint); + instantiationService.createInstance(IconExtensionPoint); + instantiationService.createInstance(TokenClassificationExtensionPoints); + instantiationService.createInstance(LanguageConfigurationFileHandler); + instantiationService.createInstance(StatusBarItemsExtensionPoint); + instantiationService.createInstance(CSSExtensionPoint); + } +} + +registerWorkbenchContribution2(ReviewExtensionPoints.ID, ReviewExtensionPoints, WorkbenchPhase.BlockStartup); diff --git a/apps/review-desktop/code-oss/src/vs/review/reviewExtensionHostUnsupportedApiPeers.ts b/apps/review-desktop/code-oss/src/vs/review/reviewExtensionHostUnsupportedApiPeers.ts new file mode 100644 index 000000000..a733405de --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/reviewExtensionHostUnsupportedApiPeers.ts @@ -0,0 +1,100 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { UriComponents } from '../base/common/uri.js'; +import { MainContext } from '../workbench/api/common/extHost.protocol.js'; +import { extHostNamedCustomer, IExtHostContext } from '../workbench/services/extensions/common/extHostCustomers.js'; + +function unavailable(api: string): Promise { + return Promise.reject(new Error(`Review does not expose the ${api} API`)); +} + +@extHostNamedCustomer(MainContext.MainThreadAuthentication) +export class ReviewMainThreadAuthentication { + constructor(_context: IExtHostContext) { } + dispose(): void { } + $registerAuthenticationProvider(): Promise { return Promise.resolve(); } + $unregisterAuthenticationProvider(): Promise { return Promise.resolve(); } + $ensureProvider(): Promise { return Promise.resolve(); } + $sendDidChangeSessions(): Promise { return Promise.resolve(); } + $getSession(): Promise { return Promise.resolve(undefined); } + $getAccounts(): Promise { return Promise.resolve([]); } + $removeSession(): Promise { return Promise.resolve(); } + $waitForUriHandler(expectedUri: UriComponents): Promise { return Promise.resolve(expectedUri); } + $showContinueNotification(): Promise { return Promise.resolve(false); } + $showDeviceCodeModal(): Promise { return Promise.resolve(false); } + $promptForClientRegistration(): Promise { return Promise.resolve(undefined); } + $promptForResourceClientSecret(): Promise { return Promise.resolve(undefined); } + $registerDynamicAuthenticationProvider(): Promise { return Promise.resolve(); } + $setSessionsForDynamicAuthProvider(): Promise { return Promise.resolve(); } + $sendDidChangeDynamicProviderInfo(): Promise { return Promise.resolve(); } +} + +@extHostNamedCustomer(MainContext.MainThreadTerminalService) +export class ReviewMainThreadTerminalService { + constructor(_context: IExtHostContext) { } + dispose(): void { } + $createTerminal(): Promise { return unavailable('terminal'); } + $dispose(): void { } + $hide(): void { } + $sendText(): void { } + $show(): void { } + $registerProcessSupport(): void { } + $registerProfileProvider(): void { } + $unregisterProfileProvider(): void { } + $registerCompletionProvider(): void { } + $unregisterCompletionProvider(): void { } + $registerQuickFixProvider(): void { } + $unregisterQuickFixProvider(): void { } + $setEnvironmentVariableCollection(): void { } + $startSendingDataEvents(): void { } + $stopSendingDataEvents(): void { } + $startSendingCommandEvents(): void { } + $stopSendingCommandEvents(): void { } + $startLinkProvider(): void { } + $stopLinkProvider(): void { } + $sendProcessData(): void { } + $sendProcessReady(): void { } + $sendProcessProperty(): void { } + $sendProcessExit(): void { } +} + +@extHostNamedCustomer(MainContext.MainThreadTask) +export class ReviewMainThreadTask { + constructor(_context: IExtHostContext) { } + dispose(): void { } + $createTaskId(): Promise { return unavailable('task'); } + $registerTaskProvider(): Promise { return Promise.resolve(); } + $unregisterTaskProvider(): Promise { return Promise.resolve(); } + $fetchTasks(): Promise { return Promise.resolve([]); } + $getTaskExecution(): Promise { return unavailable('task'); } + $executeTask(): Promise { return unavailable('task'); } + $terminateTask(): Promise { return Promise.resolve(); } + $registerTaskSystem(): void { } + $customExecutionComplete(): Promise { return Promise.resolve(); } + $registerSupportedExecutions(): Promise { return Promise.resolve(); } +} + +@extHostNamedCustomer(MainContext.MainThreadLanguageModelTools) +export class ReviewMainThreadLanguageModelTools { + constructor(_context: IExtHostContext) { } + dispose(): void { } + $getTools(): Promise { return Promise.resolve([]); } + $acceptToolProgress(): void { } + $invokeTool(): Promise { return unavailable('language model tools'); } + $countTokensForInvocation(): Promise { return unavailable('language model tools'); } + $registerTool(): void { } + $registerToolWithDefinition(): void { } + $unregisterTool(): void { } +} + +@extHostNamedCustomer(MainContext.MainThreadUrls) +export class ReviewMainThreadUrls { + constructor(_context: IExtHostContext) { } + dispose(): void { } + $registerUriHandler(): Promise { return Promise.resolve(); } + $unregisterUriHandler(): Promise { return Promise.resolve(); } + $createAppUri(uri: UriComponents): Promise { return Promise.resolve(uri); } +} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/configuration/browser/configurationService.ts b/apps/review-desktop/code-oss/src/vs/review/services/configuration/browser/configurationService.ts similarity index 98% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/configuration/browser/configurationService.ts rename to apps/review-desktop/code-oss/src/vs/review/services/configuration/browser/configurationService.ts index 2cb1be23a..fce61e9f6 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/configuration/browser/configurationService.ts +++ b/apps/review-desktop/code-oss/src/vs/review/services/configuration/browser/configurationService.ts @@ -36,7 +36,7 @@ import { IBrowserWorkbenchEnvironmentService } from '../../../../workbench/servi // Import to register configuration contributions import '../../../../workbench/services/configuration/browser/configurationService.js'; -class WhiteboardDefaultConfiguration extends DefaultConfiguration { +class ReviewDefaultConfiguration extends DefaultConfiguration { constructor( cacheScope: string, configurationCache: IConfigurationCache, @@ -59,7 +59,7 @@ class WhiteboardDefaultConfiguration extends DefaultConfiguration { } -export class WhiteboardConfigurationService extends Disposable implements IWorkbenchConfigurationService { +export class ReviewConfigurationService extends Disposable implements IWorkbenchConfigurationService { declare readonly _serviceBrand: undefined; @@ -96,7 +96,7 @@ export class WhiteboardConfigurationService extends Disposable implements IWorkb super(); this.settingsResource = userDataProfileService.currentProfile.settingsResource; - this.defaultConfiguration = this._register(new WhiteboardDefaultConfiguration(userDataProfileService.currentProfile.id, configurationCache, environmentService, logService, options.defaultOverrides ?? {})); + this.defaultConfiguration = this._register(new ReviewDefaultConfiguration(userDataProfileService.currentProfile.id, configurationCache, environmentService, logService, options.defaultOverrides ?? {})); this.policyConfiguration = policyService instanceof NullPolicyService ? new NullPolicyConfiguration() : this._register(new PolicyConfiguration(this.defaultConfiguration, policyService, logService)); this.initAgentsWindowReadOnlyKeys(); this.userConfiguration = this._register(new UserConfiguration(userDataProfileService.currentProfile.settingsResource, userDataProfileService.currentProfile.tasksResource, userDataProfileService.currentProfile.mcpResource, { exclude: [...this.agentsWindowReadOnlyKeys] }, fileService, uriIdentityService, logService)); @@ -457,7 +457,7 @@ class ConfigurationEditing { constructor( private readonly fileService: IFileService, - private readonly configurationService: WhiteboardConfigurationService, + private readonly configurationService: ReviewConfigurationService, ) { } write(settingsResource: URI, path: JSONPath, value: unknown): Promise { diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewApiCatalogService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewApiCatalogService.ts new file mode 100644 index 000000000..5646445af --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewApiCatalogService.ts @@ -0,0 +1,112 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; +import { REVIEW_STRUCTURAL_DIFF_SETTING } from "../common/reviewConfigurationDefaults.js"; +import { Emitter, type Event } from "../../base/common/event.js"; +import { Disposable, toDisposable } from "../../base/common/lifecycle.js"; +import { generateUuid } from "../../base/common/uuid.js"; +import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; +import { ILogService } from "../../platform/log/common/log.js"; +import { ReviewApiClient, type ReviewApiSummary } from "../common/reviewProtocol.js"; +import { IReviewDesktopConnectionService } from "./reviewDesktopConnectionService.js"; + +export const IReviewApiCatalogService = createDecorator("reviewApiCatalogService"); +export interface IReviewApiCatalogService { + readonly _serviceBrand: undefined; + readonly reviews: readonly ReviewApiSummary[]; + /** True once the first list arrived; an empty list is then real, not a failed load. */ + readonly loaded: boolean; + readonly onDidChange: Event; + readonly onDidCloseReview: Event; + initialize(): Promise; + attention(reviewId: string, action: "view" | "dismiss" | "restore"): Promise; + deleteReview(reviewId: string): Promise; +} + +/** A live API list for Home and tab restoration; no legacy review sessions. */ +export class ReviewApiCatalogService extends Disposable implements IReviewApiCatalogService { + declare readonly _serviceBrand: undefined; + private readonly changed = this._register(new Emitter()); + readonly onDidChange = this.changed.event; + private readonly closed = this._register(new Emitter()); + readonly onDidCloseReview = this.closed.event; + reviews: ReviewApiSummary[] = []; + loaded = false; + private client?: ReviewApiClient; + private started?: Promise; + private connectionAbort?: AbortController; + + constructor( + @IReviewDesktopConnectionService private readonly session: IReviewDesktopConnectionService, + @ILogService private readonly log: ILogService, + @IConfigurationService private readonly configuration: IConfigurationService, + ) { + super(); + this._register(configuration.onDidChangeConfiguration(event => { + if (!event.affectsConfiguration(REVIEW_STRUCTURAL_DIFF_SETTING) || !this.started) return; + this.connectionAbort?.abort(); + this.started = undefined; + this.reviews = this.reviews.map(review => ({ ...review, diffStats: null })); + this.changed.fire(); + void this.initialize().catch(error => this.log.warn("[Review] Catalog mode change failed:", error)); + })); + } + + initialize(): Promise { + // A failed first list must not stick: Home and the next command retry it. + if (!this.started) { + const pending = this.connect().catch((error) => { + if (this.started === pending) this.started = undefined; + throw error; + }); + this.started = pending; + } + return this.started; + } + + private async connect(): Promise { + const abort = new AbortController(); + this.connectionAbort = abort; + const mode = this.configuration.getValue(REVIEW_STRUCTURAL_DIFF_SETTING) === false ? "textual" : "structural"; + const client = new ReviewApiClient(await this.session.getConnection()); + this._register(toDisposable(() => abort.abort())); + const accept = (reviews: ReviewApiSummary[]) => { + if (abort.signal.aborted) return; + const previous = this.reviews; + this.reviews = reviews; + this.loaded = true; + this.changed.fire(); + for (const review of previous) { + const next = this.reviews.find((next) => next.reviewId === review.reviewId); + if (!next || (!review.dismissedAt && next.dismissedAt)) this.closed.fire(review.reviewId); + } + }; + // Surface a failed first list instead of reporting an empty catalog: + // tab restoration would otherwise drop every persisted API tab. + accept(await client.read(`?mode=${mode}`, abort.signal)); + this.client = client; + void client.follow(null, abort.signal, accept, (error) => + this.log.warn("[Review] API review list disconnected:", error), + mode, + ); + } + + async attention(reviewId: string, action: "view" | "dismiss" | "restore"): Promise { + await this.initialize(); + await this.client!.post("/commands", { + commandId: generateUuid(), + operation: { type: "attention", reviewId, action }, + }); + } + + async deleteReview(reviewId: string): Promise { + await this.initialize(); + await this.client!.post("/commands", { + commandId: generateUuid(), + operation: { type: "delete", reviewId }, + }); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewApiSourceService.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewApiSourceService.test.ts new file mode 100644 index 000000000..ed0b51d64 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewApiSourceService.test.ts @@ -0,0 +1,241 @@ +import { sourceLocation, sourceTreeUri, sourceTreeRoot } from "../common/reviewSourceView.js"; +import assert from "node:assert/strict"; +import test from "node:test"; + +import { URI } from "../../base/common/uri.js"; +import type { ITextModelContentProvider } from "../../editor/common/services/resolverService.js"; +import { apiSourceUri, ReviewApiSourceService } from "./reviewApiSourceService.js"; +import type { ReviewDiffViewSource } from "./reviewDiffViewService.js"; +import { resolveReviewSourceView, reviewSourceAnchor, reviewSourceComparison } from "../common/reviewProtocol.js"; +import type { ReviewDiffLens } from "../common/reviewProtocol.js"; + +const view = (version: number) => resolveReviewSourceView({ reviewId: "review-a", version, pins: {} }); + +function setup() { + let provider: ITextModelContentProvider; + let disposed = 0; + const models = new Map(); + const opened: Array<{ original: { resource: URI }; modified: { resource: URI } }> = []; + const editor = { resource: URI.parse("review-api-source://review-a/file") }; + const registered: string[] = []; + const service = new ReviewApiSourceService( + { + getConnection: async () => ({ serverUrl: "http://localhost:5570", token: "secret" }), + } as never, + { + registerTextModelContentProvider: (scheme: string, value: ITextModelContentProvider) => { + if (scheme === "review-api-source") provider = value; + return { dispose() { } }; + }, + createModelReference: async (uri: URI) => ({ + object: { textEditorModel: await provider.provideTextContent(uri) }, + dispose: () => disposed++, + }), + } as never, + { + getModel: (uri: URI) => models.get(uri.toString()), + createModel: (text: string, _: unknown, uri: URI) => { + const model = { uri, text, getLineCount: () => text.split("\n").length }; + models.set(uri.toString(), model); + return model; + }, + } as never, + { createByFilepathOrFirstLine: () => ({ languageId: "typescript" }) } as never, + { + openEditor: async (input: (typeof opened)[number]) => { + opened.push(input); + return { input: editor }; + }, + } as never, + { + registerReviewEditor(reviewId: string) { + registered.push(reviewId); + }, + } as never, + {} as never, + ); + return { + service, + models, + opened, + registered, + disposed: () => disposed, + readModel: (uri: URI) => provider.provideTextContent(uri), + }; +} + +test("a document diff retains its pinned comparison even if the review advances before loading", async (t) => { + const { service, readModel } = setup(); + t.after(() => service.dispose()); + t.mock.method(globalThis, "fetch", async (value: string, init: RequestInit) => { + const url = new URL(value); + assert.equal(new Headers(init.headers).get("x-review-token"), "secret"); + assert.equal(url.searchParams.get("version"), "3"); + if (url.pathname.endsWith("/diff")) return Response.json([]); + assert.equal(url.searchParams.get("side"), "base"); + assert.equal(url.searchParams.get("file"), "src/[route].ts"); + return Response.json({ text: "old first line\nold second line" }); + }); + let version = 3; + let source!: ReviewDiffViewSource; + let lens!: ReviewDiffLens; + const canvas = service.canvas(() => view(version), {} as never, { + openComparison: () => undefined, + createDocument: (_: unknown, scope: ReviewDiffLens, input: ReviewDiffViewSource) => { lens = scope; source = input; return {}; }, + } as never); + canvas.inlineEditors.create({ path: "src/[route].ts", side: "base", ranges: [{ startLine: 2, endLine: 2 }] } as never); + version = 4; + const result = await source.load(undefined, lens); + assert.equal(result.entries.length, 1); + assert.equal(result.entries[0].file.status, "unchanged"); + const model = await readModel(result.entries[0].original!); + assert.equal(model!.getLineCount(), 2); + assert.equal(new URLSearchParams(model!.uri.query).get("version"), "3"); +}); + +test("diff entries keep rename paths and missing sides, even when the review advances during the read", async (t) => { + const { service } = setup(); + t.after(() => service.dispose()); + let version = 7; + let generation = "a".repeat(64); + t.mock.method(globalThis, "fetch", async (value: string) => { + const url = new URL(value); + assert.equal(url.searchParams.get("version"), "7"); + assert.equal(url.searchParams.get("commit"), "selected-commit"); + version = 8; + generation = "b".repeat(64); + return Response.json([ + { path: "new.ts", previousPath: "old.ts", status: "renamed", additions: 0, deletions: 0 }, + { path: "added.ts", status: "added", additions: 1, deletions: 0 }, + { path: "removed.ts", status: "deleted", additions: 0, deletions: 1 }, + ]); + }); + let source!: ReviewDiffViewSource; + const canvas = service.canvas( + () => resolveReviewSourceView({ reviewId: "review-a", version, pins: { worktreeRevision: generation } }), + {} as never, + { + openComparison: () => undefined, + create: (_: unknown, input: ReviewDiffViewSource) => { + source = input; + return {}; + }, + } as never, + ); + canvas.diffView.create({} as never); + const result = await source.load({ commit: "selected-commit" }); + assert.equal(result.entries.find(entry => entry.file.path === "new.ts")!.original!.path, "/old.ts"); + assert.equal(result.entries.find(entry => entry.file.path === "new.ts")!.modified!.path, "/new.ts"); + assert.equal(result.entries.find(entry => entry.file.path === "added.ts")!.original, undefined); + assert.equal(result.entries.find(entry => entry.file.path === "removed.ts")!.modified, undefined); + for (const entry of result.entries) { + assert.equal(new URLSearchParams(entry.goToFileResource.query).get("version"), "7"); + assert.equal(new URLSearchParams(entry.goToFileResource.query).get("commit"), "selected-commit"); + assert.equal(entry.goToFileResource.scheme, "review-api-source"); + assert.equal(new URLSearchParams(entry.goToFileResource.query).get("generation"), "a".repeat(64)); + assert.equal(new URLSearchParams(entry.goToFileResource.query).has("live"), false); + } +}); + +test("unavailable pinned files report the API error instead of falling back to disk", async (t) => { + const { service, readModel } = setup(); + t.after(() => service.dispose()); + t.mock.method(globalThis, "fetch", async () => Response.json({ error: "File is unavailable at the pinned commit." }, { status: 404 })); + await assert.rejects(Promise.resolve(readModel(apiSourceUri({ view: view(0), side: "head", file: "missing.ts" }))), /unavailable at the pinned commit/); +}); + +test("tree entries retain version, side and selected commit when opening a child", async (t) => { + const { service } = setup(); + t.after(() => service.dispose()); + t.mock.method(globalThis, "fetch", async (value: string) => { + const url = new URL(value); + assert.equal(url.pathname, "/reviews-api/review-a/tree"); + assert.equal(url.searchParams.get("path"), "src"); + assert.equal(url.searchParams.get("version"), "3"); + assert.equal(url.searchParams.get("side"), "base"); + assert.equal(url.searchParams.get("commit"), "chosen-commit"); + return Response.json([ + { path: "src/[route].ts", kind: "file" }, + { path: "src/lib", kind: "directory" }, + ]); + }); + const root = apiSourceUri({ view: reviewSourceComparison(view(3), "chosen-commit"), side: "base", file: "src" }); + const [file, folder] = await service.children(root); + assert.equal(file!.resource.path, "/src/[route].ts"); + assert.equal(file!.resource.query, root.query); + assert.equal(file!.readonly, true); + assert.equal(folder!.isDirectory, true); +}); + +test("opening a native diff preserves renames and empty sides at the selected version", async (t) => { + const { service, opened, registered } = setup(); + t.after(() => service.dispose()); + t.mock.method(globalThis, "fetch", async (value: string) => { + assert.equal(new URL(value).searchParams.get("version"), "3"); + return Response.json([ + { path: "new.ts", previousPath: "old.ts", status: "renamed", additions: 0, deletions: 0 }, + { path: "added.ts", status: "added", additions: 1, deletions: 0 }, + { path: "removed.ts", status: "deleted", additions: 0, deletions: 1 }, + ]); + }); + for (const file of ["new.ts", "added.ts", "removed.ts"]) await service.openDiff(view(3), file); + assert.equal(opened[0]!.original.resource.path, "/old.ts"); + assert.equal(opened[0]!.modified.resource.path, "/new.ts"); + assert.equal(new URLSearchParams(opened[1]!.original.resource.query).get("empty"), "true"); + assert.equal(new URLSearchParams(opened[2]!.modified.resource.query).get("empty"), "true"); + assert.deepEqual(registered, ["review-a", "review-a", "review-a"]); + for (const entry of opened) + for (const side of [entry.original, entry.modified]) { + assert.equal(side.resource.scheme, "review-api-source"); + assert.equal(new URLSearchParams(side.resource.query).get("version"), "3"); + } + await assert.rejects(service.openDiff(view(3), "unchanged.ts"), /not changed/); + assert.equal(opened.length, 3); +}); + + +test("a refreshed current tree keeps its root when a file from the newer version opens", async t => { + const { service } = setup(); + t.after(() => service.dispose()); + let version = 3; + const root = sourceTreeUri({ reviewId: "review-a", kind: "current" }); + t.mock.method(globalThis, "fetch", async (value: string) => { + const url = new URL(value); + if (url.pathname.endsWith("/tree")) { + assert.equal(url.searchParams.get("version"), String(version)); + return Response.json([{ path: "src", kind: "directory" }, { path: "file.ts", kind: "file" }]); + } + assert.equal(url.searchParams.has("version"), false); + return Response.json({ reviewId: "review-a", version, pins: { worktreeRevision: String(version).repeat(64) } }); + }); + const first = await service.children(root); + version = 4; + const refreshed = await service.children(root); + assert.equal(first[0]!.resource.toString(), refreshed[0]!.resource.toString()); + assert.notEqual(first[1]!.resource.toString(), refreshed[1]!.resource.toString()); + assert.equal(new URLSearchParams(refreshed[1]!.resource.query).get("version"), "4"); + assert.equal(sourceTreeRoot(refreshed[1]!.resource, root).toString(), root.toString()); + const fixed = sourceTreeUri({ reviewId: "review-a", kind: "version", version: 3 }); + assert.notEqual(sourceTreeRoot(refreshed[1]!.resource, fixed).toString(), fixed.toString()); +}); + +test("a source at its own pins keeps them through its URI and reads them back from the server", async t => { + const { service, readModel } = setup(); + t.after(() => service.dispose()); + const pins = { repositoryId: "repo-b", head: "b".repeat(40) }; + const anchored = reviewSourceAnchor(reviewSourceComparison(view(3), "c".repeat(40)), pins); + assert.equal(anchored.commit, undefined); + const uri = apiSourceUri({ view: anchored, side: "head", file: "src/a.ts" }); + assert.deepEqual(sourceLocation(uri), { view: { reviewId: "review-a", version: 3, generation: undefined, commit: undefined, pins }, side: "head", file: "src/a.ts" }); + const inherited = sourceLocation(apiSourceUri({ view: view(3), side: "head", file: "src/a.ts" })); + assert.equal(inherited.view.pins, undefined); + t.mock.method(globalThis, "fetch", async (value: string) => { + const url = new URL(value); + assert.equal(url.searchParams.get("repositoryId"), "repo-b"); + assert.equal(url.searchParams.get("head"), pins.head); + assert.equal(url.searchParams.has("base"), false); + return Response.json({ text: "at own pins" }); + }); + const model = await readModel(uri); + assert.equal((model as unknown as { text: string }).text, "at own pins"); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewApiSourceService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewApiSourceService.ts new file mode 100644 index 000000000..c71b01890 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewApiSourceService.ts @@ -0,0 +1,301 @@ +import { orderReviewDiffFiles } from "../common/reviewChangedFilesModel.js"; +import { lensFiles } from "../common/reviewLensFiles.js"; +import { StructuralDiffClient } from "./reviewStructuralDiffClient.js"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable, DisposableStore } from "../../base/common/lifecycle.js"; +import { URI } from "../../base/common/uri.js"; +import { ILanguageService } from "../../editor/common/languages/language.js"; +import type { ITextModel } from "../../editor/common/model.js"; +import { IModelService } from "../../editor/common/services/model.js"; +import { ITextModelService } from "../../editor/common/services/resolverService.js"; +import { IFileService, type IFileStat } from "../../platform/files/common/files.js"; +import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; +import { IEditorService } from "../../workbench/services/editor/common/editorService.js"; +import type { + ReviewInlineFindSpec, + ReviewDiffLens, + ReviewInlineEditorRange, + ReviewDiffFileWire, + ReviewInlineEditorFactory, + ReviewDiffViewFactory, + ReviewSourceEntry, + ReviewApiSourceLocation, +} from "../common/reviewProtocol.js"; +import { resolveReviewSourceView, reviewSourceAnchor, reviewSourceComparison, reviewSourceQuery, type ReviewSourceView } from "../common/reviewProtocol.js"; +import { REVIEW_LANGUAGE_SOURCE_SCHEME } from "../common/reviewReadonlySource.js"; +import { apiSourceUri, sourceLocation, sourceTreeUri, sourceTreeSelection, REVIEW_API_TREE_SCHEME, REVIEW_API_SOURCE_SCHEME } from "../common/reviewSourceView.js"; +import { IReviewCanvasEditorTabsService } from "./reviewCanvasEditorTabsService.js"; +import { IReviewDesktopConnectionService, reviewResponseError } from "./reviewDesktopConnectionService.js"; +import type { ReviewDiffViewService, ReviewDiffViewSource } from "./reviewDiffViewService.js"; +import type { ReviewEmbeddedEditors } from "./reviewEmbeddedEditors.js"; + +export { apiSourceUri, REVIEW_API_SOURCE_SCHEME } from "../common/reviewSourceView.js"; + +/** The query that distinguishes one comparison's diff models from another's. */ +function comparisonQuery(view: ReviewSourceView): string | undefined { + const params = new URLSearchParams(); + if (view.commit) params.set("commit", view.commit); + if (view.pins) { + params.set("repositoryId", view.pins.repositoryId); + params.set("head", view.pins.head); + if (view.pins.base) params.set("base", view.pins.base); + } + const query = params.toString(); + return query || undefined; +} + +export type ApiSourceTarget = ReviewApiSourceLocation; + +/** Recover the immutable source identity even when no legacy session is active. */ +export function apiSourceTarget(resource: URI): ApiSourceTarget | undefined { + if (resource.scheme !== REVIEW_API_SOURCE_SCHEME) return undefined; + const query = new URLSearchParams(resource.query); + const version = Number(query.get("version")); + const side = query.get("side"); + if ( + !resource.authority || + !query.has("version") || + !Number.isInteger(version) || + version < 0 || + (side !== "base" && side !== "head") + ) + return undefined; + return { + view: { reviewId: resource.authority, version, commit: query.get("commit") ?? undefined, generation: query.get("generation") ?? undefined }, + side, + file: resource.path.slice(1), + }; +} + +export const IReviewApiSourceService = createDecorator("reviewApiSourceService"); +export interface IReviewApiSourceService { + readonly _serviceBrand: undefined; + open(target: ApiSourceTarget, range?: ReviewInlineEditorRange): Promise; + children(resource: URI): Promise; + openDiff(view: ReviewSourceView, path: string): Promise; + canvas( + view: () => ReviewSourceView, + inline: ReviewEmbeddedEditors, + diff: ReviewDiffViewService, + ): { + inlineEditors: ReviewInlineEditorFactory; + diffView: ReviewDiffViewFactory; + openStructuralComparison(): void; + }; +} + +/** Resolve native or retained resources once; all review surfaces share this path. */ +export class ReviewApiSourceService extends Disposable implements IReviewApiSourceService { + declare readonly _serviceBrand: undefined; + + constructor( + @IReviewDesktopConnectionService private readonly session: IReviewDesktopConnectionService, + @ITextModelService models: ITextModelService, + @IModelService modelService: IModelService, + @ILanguageService languages: ILanguageService, + @IEditorService private readonly editors: IEditorService, + @IReviewCanvasEditorTabsService private readonly tabs: IReviewCanvasEditorTabsService, + @IFileService private readonly files: IFileService, + ) { + super(); + this._register( + models.registerTextModelContentProvider(REVIEW_API_SOURCE_SCHEME, { + provideTextContent: async (resource) => { + const existing = modelService.getModel(resource); + if (existing) return existing; + const query = new URLSearchParams(resource.query); + const target = sourceLocation(resource); + const body = query.has("empty") + ? { text: "" } + : await this.read<{ text: string; localPath?: string }>(target.view.reviewId, "/file", { ...reviewSourceQuery(target.view), side: target.side, file: target.file }); + const model = ( + modelService.getModel(resource) ?? + modelService.createModel( + body.text, + languages.createByFilepathOrFirstLine(resource, body.text.split("\n", 1)[0]), + resource, + ) + ); + if (body.localPath) { + this.followDisk(model, URI.file(body.localPath), async () => (await this.read<{ text: string }>(target.view.reviewId, "/file", { ...reviewSourceQuery(target.view), side: target.side, file: target.file })).text); + } + return model; + }, + }), + ); + this._register(models.registerTextModelContentProvider(REVIEW_LANGUAGE_SOURCE_SCHEME, { + provideTextContent: async resource => { + const existing = modelService.getModel(resource); + if (existing) return existing; + const local = URI.file(resource.path); + const read = async () => (await this.files.readFile(local)).value.toString(); + const model = modelService.createModel(await read(), languages.createByFilepathOrFirstLine(resource), resource); + this.followDisk(model, local, read); + return model; + }, + })); + } + + private followDisk(model: ITextModel, local: URI, read: () => Promise): void { + const owned = this._register(new DisposableStore()); + let revision = 0; + owned.add(this.files.watch(local)); + owned.add(this.files.onDidFilesChange(event => { + if (!event.affects(local)) return; + const request = ++revision; + void read().then(text => { + if (!model.isDisposed() && request === revision && model.getValue() !== text) model.setValue(text); + }).catch(() => { /* A missing file cannot supply fresh source. */ }); + })); + owned.add(model.onWillDispose(() => { this._store.delete(owned); owned.dispose(); })); + } + + private async read( + reviewId: string, + route: string, + query: Record, + ): Promise { + const { serverUrl, token } = await this.session.getConnection(); + const params = new URLSearchParams( + Object.entries(query) + .filter(([key, value]) => key !== "reviewId" && value !== undefined) + .map(([key, value]) => [key, String(value)]), + ); + const response = await fetch(`${serverUrl}/reviews-api/${encodeURIComponent(reviewId)}${route}?${params}`, { + headers: { "x-review-token": token }, + signal: AbortSignal.timeout(30_000), + }); + if (!response.ok) throw await reviewResponseError(response, `Could not read pinned source (${response.status}).`); + return response.json(); + } + + private async sourceResource(target: ApiSourceTarget, empty = false): Promise { + return apiSourceUri(target, empty); + } + + async open(target: ApiSourceTarget, range?: ReviewInlineEditorRange): Promise { + const pane = await this.editors.openEditor({ + resource: await this.sourceResource(target), + options: { + pinned: true, + ...(range + ? { + selection: { + startLineNumber: range.startLine, + startColumn: 1, + endLineNumber: range.endLine, + endColumn: Number.MAX_SAFE_INTEGER, + }, + } + : {}), + }, + }); + if (pane?.input) this.tabs.registerReviewEditor(target.view.reviewId, pane.input); + } + + async openDiff(view: ReviewSourceView, path: string): Promise { + const files = await this.read(view.reviewId, "/diff", reviewSourceQuery(view)); + const file = files.find((file) => file.path === path); + if (!file) throw new Error(`File is not changed in this review version: ${path}`); + const target = { view, file: path }; + const pane = await this.editors.openEditor({ + original: { + resource: await this.sourceResource({ ...target, file: file.previousPath ?? path, side: "base" }, file.status === "added"), + }, + modified: { resource: await this.sourceResource({ ...target, side: "head" }, file.status === "deleted") }, + options: { pinned: true }, + }); + if (pane?.input) this.tabs.registerReviewEditor(view.reviewId, pane.input); + } + + async children(resource: URI): Promise { + const selection = resource.scheme === REVIEW_API_TREE_SCHEME ? sourceTreeSelection(resource) : undefined; + let target: ApiSourceTarget; + if (selection) { + const snapshot = await this.read[0]>(selection.reviewId, "", { + full: "true", version: selection.kind === "version" ? selection.version : undefined, + }); + target = { view: resolveReviewSourceView(snapshot), side: "head", file: resource.path.slice(1) }; + } else { + target = sourceLocation(resource); + } + + const entries = await this.read(target.view.reviewId, "/tree", { + ...reviewSourceQuery(target.view), side: target.side, path: target.file, + }); + return entries.map((entry) => ({ + resource: selection && entry.kind === "directory" ? sourceTreeUri(selection, entry.path) : apiSourceUri({ ...target, file: entry.path }), + name: entry.path.split("/").at(-1)!, + isFile: entry.kind === "file", + isDirectory: entry.kind === "directory", + isSymbolicLink: false, + readonly: true, + children: undefined, + })); + } + + canvas(view: () => ReviewSourceView, inline: ReviewEmbeddedEditors, diff: ReviewDiffViewService) { + const comparisonGeneration = diff.comparisonGeneration; + const lists = new Map>(); + const files = (current: ReviewSourceView) => { + const key = JSON.stringify(reviewSourceQuery(current)); + let list = lists.get(key); + if (!list) { + list = this.read(current.reviewId, "/diff", reviewSourceQuery(current)); + list.catch(() => lists.delete(key)); + lists.set(key, list); + } + return list; + }; + const openComparison = (current: ReviewSourceView) => diff.openComparison( + JSON.stringify(reviewSourceQuery(current)), new StructuralDiffClient(this.session, current), comparisonGeneration, + ); + const makeSource = (getView: () => ReviewSourceView): ReviewDiffViewSource => ({ + files: scope => files(reviewSourceComparison(getView(), scope?.commit)), + load: async (scope, lens) => { + if (lens && (scope || lens.reviewId !== getView().reviewId)) throw new Error("A lens must use its review comparison."); + // Capture the comparison once; live checkout bytes may change during the load. + const current = reviewSourceComparison(getView(), scope?.commit); + const comparisonFiles = await files(current); + const entries = lens ? lensFiles(comparisonFiles, lens).filter(file => lens.ranges.some(range => + range.file === (range.side === "base" ? file.previousPath ?? file.path : file.path))) : orderReviewDiffFiles(comparisonFiles); + + return { + session: openComparison(current), + sourceUri: URI.from({ scheme: "review-api-diff", authority: current.reviewId, path: `/${current.version}/${current.generation ?? ""}`, query: comparisonQuery(current) }), + entries: await Promise.all(entries.map(async file => { + const original = file.status === "added" ? undefined : await this.sourceResource({ view: current, side: "base", file: file.previousPath ?? file.path }); + const modified = file.status === "deleted" ? undefined : await this.sourceResource({ view: current, side: "head", file: file.path }); + return { file, original, modified, goToFileResource: (modified ?? original)! }; + })), + }; + }, + }); + const diffSource = makeSource(view); + const documentScope = (spec: ReviewInlineFindSpec) => { + // A source with its own pins is read at them; the review comparison does not apply. + const current = spec.pins ? reviewSourceAnchor(view(), spec.pins) : reviewSourceComparison(view()); + const lens: ReviewDiffLens = { + id: "document:" + JSON.stringify([spec.path, spec.ranges, spec.pins]), title: spec.path, + reviewId: current.reviewId, version: current.version, + ranges: spec.ranges.map(range => ({ file: spec.path, side: range.side ?? spec.side, fromLine: range.startLine, toLine: range.endLine })), + }; + return { lens, source: makeSource(() => current) }; + }; + return { + openStructuralComparison: () => diff.structuralRenderingEnabled ? openComparison(reviewSourceComparison(view())) : undefined, + inlineEditors: { + create: (spec) => { const { lens, source } = documentScope(spec); return diff.createDocument(spec, lens, source); }, + find: async (spec, query) => { const { lens, source } = documentScope(spec); return { matchCount: (await diff.findDocument(lens, source, query)).length }; }, + } satisfies ReviewInlineEditorFactory, + diffView: { + create: (spec) => diff.create(spec, diffSource), + files: diffSource.files, + } satisfies ReviewDiffViewFactory, + }; + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewCanvasEditorTabsService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewCanvasEditorTabsService.ts new file mode 100644 index 000000000..941ef6377 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewCanvasEditorTabsService.ts @@ -0,0 +1,178 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from "../../base/common/lifecycle.js"; +import { createDecorator, IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; +import type { EditorInput } from "../../workbench/common/editor/editorInput.js"; +import { IEditorGroupsService } from "../../workbench/services/editor/common/editorGroupsService.js"; +import { IEditorService } from "../../workbench/services/editor/common/editorService.js"; +import { + ReviewCanvasEditorInput, + type ReviewCanvasEditorTarget, +} from "../browser/parts/canvas/reviewCanvasEditorInput.js"; + +import type { ReviewSourceSelection } from "../common/reviewProtocol.js"; +import { sourceSelectionIdentity } from "../common/reviewSourceView.js"; + +export const IReviewCanvasEditorTabsService = createDecorator( + "reviewCanvasEditorTabsService", +); + +export interface IReviewCanvasEditorTabsService { + readonly _serviceBrand: undefined; + inputFor(target: Extract): ReviewCanvasEditorInput; + openApiReview(reviewId: string, title: string, active?: boolean): Promise; + openApiSource(selection: ReviewSourceSelection, title: string): Promise; + openHome(active: boolean): Promise; + openWelcome(active: boolean): Promise; + openSettings(active: boolean): Promise; + registerReviewEditor(reviewUuid: string, input: EditorInput): void; + closeReview(reviewUuid: string): Promise; +} + +export class ReviewCanvasEditorTabsService extends Disposable implements IReviewCanvasEditorTabsService { + declare readonly _serviceBrand: undefined; + + private readonly inputs = new Map(); + private readonly reviewEditors = new Map>(); + + constructor( + @IInstantiationService + private readonly instantiationService: IInstantiationService, + @IEditorService private readonly editorService: IEditorService, + @IEditorGroupsService + private readonly editorGroupsService: IEditorGroupsService, + ) { + super(); + this._register( + this.editorService.onDidCloseEditor((event) => { + queueMicrotask(() => this.pruneReviewEditor(event.editor)); + }), + ); + } + + async openHome(active: boolean): Promise { + const input = await this.openSingleton({ kind: "home" }, active); + this.editorGroupsService.groups.find((group) => group.contains(input))?.stickEditor(input); + return input; + } + + inputFor( + target: Extract, + ): ReviewCanvasEditorInput { + const key = + target.kind === "home" + ? "home" + : target.kind === "api" + ? `api:${target.reviewId}` + : `api:${target.reviewId}:source:${sourceSelectionIdentity(target.selection)}`; + let input = this.inputs.get(key); + if (!input || input.isDisposed()) { + input = this.instantiationService.createInstance(ReviewCanvasEditorInput, target); + this.inputs.set(key, input); + } + if (target.kind !== "home") input.setApiTitle(target.title); + return input; + } + + async openApiReview(reviewId: string, title: string, active = true): Promise { + const input = this.inputFor({ kind: "api", reviewId, title }); + await this.openReviewInput(input, active); + return input; + } + + openWelcome(active: boolean): Promise { + return this.openSingleton({ kind: "welcome" }, active); + } + + async openApiSource(selection: ReviewSourceSelection, title: string): Promise { + const input = this.inputFor({ kind: "api-source", reviewId: selection.reviewId, selection, title }); + await this.openReviewInput(input, true); + return input; + } + + openSettings(active: boolean): Promise { + return this.openSingleton({ kind: "settings" }, active); + } + + /** One tab per non-review kind; `configure` runs before the tab opens. */ + private async openSingleton( + target: { kind: "home" } | { kind: "welcome" } | { kind: "settings" }, + active: boolean, + configure?: (input: ReviewCanvasEditorInput) => void, + ): Promise { + let input = this.inputs.get(target.kind); + if (!input || input.isDisposed()) { + input = this.instantiationService.createInstance(ReviewCanvasEditorInput, target); + this.inputs.set(target.kind, input); + } + configure?.(input); + // A control command may arrive while an Ask's loading pane has focus. + // Reuse the review's group instead of mounting a second canvas there. + const existingGroup = this.editorGroupsService.groups.find((group) => group.contains(input)); + const targetGroup = existingGroup === undefined ? this.editorGroupsService.mainPart.activeGroup : existingGroup; + await this.editorService.openEditor(input, { pinned: true, inactive: !active, revealIfVisible: true }, targetGroup); + return input; + } + + private async openReviewInput(input: ReviewCanvasEditorInput, active: boolean): Promise { + // A control command may arrive while an Ask's loading pane has focus. + // Reuse the review's group instead of mounting a second canvas there. + const existingGroup = this.editorGroupsService.groups.find((group) => group.contains(input)); + const targetGroup = existingGroup === undefined ? this.editorGroupsService.mainPart.activeGroup : existingGroup; + await this.editorService.openEditor(input, { pinned: true, inactive: !active, revealIfVisible: true }, targetGroup); + } + + async closeReview(reviewUuid: string): Promise { + const keys = [...this.inputs.keys()].filter( + (key) => + key === reviewUuid || + key === `api:${reviewUuid}` || + key.startsWith(`api:${reviewUuid}:source:`) || + key.startsWith(`${reviewUuid}@`), + ); + const reviewInputs = keys + .map((key) => this.inputs.get(key)) + .filter((input): input is ReviewCanvasEditorInput => Boolean(input && !input.isDisposed())); + const reviewEditors = [...(this.reviewEditors.get(reviewUuid) ?? [])]; + for (const key of keys) this.inputs.delete(key); + this.reviewEditors.delete(reviewUuid); + const editors = [ + ...reviewInputs.flatMap((input) => + this.editorGroupsService.groups + .filter((group) => group.contains(input)) + .map((group) => ({ editor: input, groupId: group.id })), + ), + ...reviewEditors.flatMap((editor) => + this.editorGroupsService.groups + .filter((group) => group.contains(editor)) + .map((group) => ({ editor, groupId: group.id })), + ), + ]; + if (editors.length === 0) return; + await this.editorService.closeEditors(editors); + } + + registerReviewEditor(reviewUuid: string, input: EditorInput): void { + let editors = this.reviewEditors.get(reviewUuid); + if (!editors) { + editors = new Set(); + this.reviewEditors.set(reviewUuid, editors); + } + editors.add(input); + } + + private pruneReviewEditor(input: EditorInput): void { + if (this.editorGroupsService.groups.some((group) => group.contains(input))) { + return; + } + for (const [reviewUuid, editors] of this.reviewEditors) { + editors.delete(input); + if (editors.size === 0) { + this.reviewEditors.delete(reviewUuid); + } + } + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewDefaultAccountService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewDefaultAccountService.ts new file mode 100644 index 000000000..28dae1a1b --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewDefaultAccountService.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ICopilotTokenInfo, IDefaultAccount, IDefaultAccountAuthenticationProvider, IPolicyData } from '../../base/common/defaultAccount.js'; +import { Event } from '../../base/common/event.js'; +import { Disposable } from '../../base/common/lifecycle.js'; +import { IDefaultAccountProvider, IDefaultAccountService, ManagedSettingsFetchStatus } from '../../platform/defaultAccount/common/defaultAccount.js'; + +/** + * Review has no account or Copilot surface. Keeping account startup inert also + * prevents the curated extension host from waiting for an authentication + * provider that Review intentionally does not expose. + */ +export class ReviewDefaultAccountService extends Disposable implements IDefaultAccountService { + declare readonly _serviceBrand: undefined; + + readonly onDidChangeDefaultAccount = Event.None; + readonly onDidChangePolicyData = Event.None; + readonly onDidChangeCopilotTokenInfo = Event.None; + readonly policyData: IPolicyData | null = null; + readonly currentDefaultAccount: IDefaultAccount | null = null; + readonly copilotTokenInfo: ICopilotTokenInfo | null = null; + readonly managedSettingsFetchStatus: ManagedSettingsFetchStatus = null; + readonly managedSettingsFetchedAt: number | null = null; + readonly managedSettingsRawResponse: unknown = null; + + getDefaultAccount(): Promise { return Promise.resolve(null); } + getDefaultAccountAuthenticationProvider(): IDefaultAccountAuthenticationProvider { + return { id: 'github', name: 'GitHub', enterprise: false }; + } + setDefaultAccountProvider(_provider: IDefaultAccountProvider): void { } + refresh(): Promise { return Promise.resolve(null); } + signIn(): Promise { return Promise.resolve(null); } + signOut(): Promise { return Promise.resolve(); } + resolveGitHubUrl(path: string): string { return `https://github.com/${path}`; } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewDesktopConnectionService.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewDesktopConnectionService.test.ts new file mode 100644 index 000000000..8a8c9d066 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewDesktopConnectionService.test.ts @@ -0,0 +1,157 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { ReviewDesktopConnectionService } from "./reviewDesktopConnectionService.js"; + +const uuid = "11111111-1111-4111-8111-111111111111"; +class TestStorage { + private readonly values = new Map(); + + getBoolean(key: string, _scope: unknown, fallback: boolean): boolean { + return this.values.get(key) ?? fallback; + } + + store(key: string, value: boolean): void { + this.values.set(key, value); + } + + remove(key: string): void { + this.values.delete(key); + } +} + +function serviceWith(storage = new TestStorage()): ReviewDesktopConnectionService { + const service = new ReviewDesktopConnectionService({} as never, storage as never); + Object.assign(service, { + connection: { + version: 1, + url: "http://127.0.0.1:5000", + token: "token", + instanceId: "instance", + }, + initializePromise: Promise.resolve(), + }); + return service; +} + +function mockFetch(t: { after(callback: () => void): void }, handler: typeof fetch): void { + const original = globalThis.fetch; + globalThis.fetch = handler; + t.after(() => { + globalThis.fetch = original; + }); +} + +test("install status shares concurrent scans and detects agents on subsequent checks", async (t) => { + const service = serviceWith(); + t.after(() => service.dispose()); + let requests = 0; + mockFetch(t, async () => { + requests += 1; + if (requests === 3) return Response.json({ error: "scan failed" }, { status: 500 }); + return Response.json({ + agents: [{ target: "codex", present: requests > 1, installed: false }], + fingerprint: "test", stamp: null, stale: false, + shim: { path: "/tmp/review", installed: false, profileConfigured: false, onPath: false }, + fff: { serverName: "fff", corpusRoot: "/tmp/traces", binary: { path: "/tmp/fff", installed: false }, registrations: [] }, + trace: { enabled: false, configured: false, autoActivateRepositories: false, envPath: "/tmp/env", settingsPath: "/tmp/settings" }, + cli: null, + }); + }); + + const [first, second] = await Promise.all([ + service.getCliInstallStatus(), + service.getCliInstallStatus(), + ]); + assert.equal(first.agents[0].present, false); + assert.equal(second.agents[0].present, false); + assert.equal(requests, 1); + assert.equal((await service.getCliInstallStatus()).agents[0].present, true); + assert.equal(requests, 2); + await assert.rejects(service.getCliInstallStatus(), /scan failed/); + assert.equal((await service.getCliInstallStatus()).agents[0].present, true); + assert.equal(requests, 4); +}); + +test("tutorial auto-prepare runs at most once per app process", async (t) => { + const service = serviceWith(); + let requests = 0; + mockFetch(t, async () => { + requests += 1; + return Response.json({ ok: true }); + }); + + const first = service.prepareTutorial(); + assert.strictEqual(service.prepareTutorial(), first); + await first; + await service.prepareTutorial(); + + assert.equal(requests, 1); + service.dispose(); +}); + +test("a failed tutorial auto-prepare is not retried on Welcome activation", async (t) => { + const service = serviceWith(); + let requests = 0; + mockFetch(t, async () => { + requests += 1; + return Response.json({ error: "no agent" }, { status: 409 }); + }); + + await assert.rejects(service.prepareTutorial(), /no agent/); + await service.prepareTutorial(); + + assert.equal(requests, 1); + service.dispose(); +}); + +test("tutorial deletion suppresses auto-prepare across restarts until explicit open", async (t) => { + const storage = new TestStorage(); + const requests: string[] = []; + mockFetch(t, async (input, init) => { + const url = String(input); + requests.push(`${init?.method ?? "GET"} ${url}`); + if (url.endsWith("/tutorial/open")) { + return Response.json({ + kind: "api", + reviewUuid: uuid, + title: "Tutorial", + }); + } + return Response.json({ ok: true }); + }); + + const deletingService = serviceWith(storage); + await deletingService.deleteTutorial(); + deletingService.dispose(); + + const suppressedService = serviceWith(storage); + await suppressedService.prepareTutorial(); + assert.equal(requests.length, 1); + await suppressedService.openTutorial(); + assert.equal(requests.length, 2); + assert.match(requests[1] ?? "", /POST .*\/tutorial\/open$/); + suppressedService.dispose(); + + const restoredService = serviceWith(storage); + await restoredService.prepareTutorial(); + assert.equal(requests.length, 3); + assert.match(requests[2] ?? "", /POST .*\/tutorial\/prepare$/); + restoredService.dispose(); +}); + +test("passes automatic skill updates to the server without enabling optional integrations", async (t) => { + const service = serviceWith(); + let requestBody: unknown; + mockFetch(t, async (_url, init) => { + requestBody = JSON.parse(String(init?.body)); + return Response.json({ ok: true, output: "updated" }); + }); + await service.applyCliInstall({ targets: ["codex"], shim: false, autoUpdate: true }); + assert.deepEqual(requestBody, { targets: ["codex"], shim: false, autoUpdate: true }); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewDesktopConnectionService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewDesktopConnectionService.ts new file mode 100644 index 000000000..ea1a94b51 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewDesktopConnectionService.ts @@ -0,0 +1,560 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter,Event } from "../../base/common/event.js"; +import { Disposable } from "../../base/common/lifecycle.js"; +import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; +import { IMainProcessService } from "../../platform/ipc/common/mainProcessService.js"; +import { IStorageService,StorageScope,StorageTarget } from "../../platform/storage/common/storage.js"; +import { +REVIEW_DESKTOP_CHANNEL, +REVIEW_DESKTOP_CONNECTION_VERSION, +type ReviewDesktopConnection, +} from "../common/reviewDesktopBootstrap.js"; +import { consumeReviewEventStream } from "../common/reviewEventStream.js"; +import { +type JsonValue, + type ReviewDiffrConfig, + type ReviewDiffrSummarizerInput, + isJsonObject, + parseReviewDiffrConfig, +parseReviewCliInstallApplyResponse, +parseReviewCliInstallStatus, +parseReviewDesktopVerbFrame, +parseReviewTutorialOpenResponse, +type ReviewCliInstallApplyResponse, +type ReviewCliInstallStatus, +type ReviewCliInstallTarget, +type ReviewTutorialOpenResponse, +type ReviewVerbResponse +} from "../common/reviewProtocol.js"; +import { reconnectUntilAborted } from "../common/reviewReconnect.js"; + +const REVIEW_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY = "review.tutorial.autoPrepareSuppressed.v1"; + +export interface ReviewServerConnection { + readonly serverUrl: string; + readonly token: string; +} + + +export const IReviewDesktopConnectionService = createDecorator( + "reviewDesktopConnectionService", +); + +export interface IReviewDesktopConnectionService { + readonly _serviceBrand: undefined; + readonly onDidFail: Event; + readonly onDidChangeLists: Event; + /** Fires at control-stream connection/disconnection boundaries, before reuse. */ + readonly onDidChangeConnection: Event; + initialize(): Promise; + getConnection(): Promise; + readDiffrConfig(): Promise; + saveDiffrSummarizer(input: ReviewDiffrSummarizerInput): Promise; + testDiffrSummarizer(input: ReviewDiffrSummarizerInput): Promise; + setDiffrConfigValue(key: string, value: JsonValue): Promise; + /** The scratchpad preference: a server preference, since `review install` reads it too. */ + readScratchpadEnabled(): Promise; + setScratchpadEnabled(enabled: boolean): Promise; + getTutorialStatus(): Promise<{ version: 1; reviewUuid: string | null }>; + prepareTutorial(): Promise; + openTutorial(): Promise; + deleteTutorial(): Promise; + getCliInstallStatus(): Promise; + applyCliInstall(request: { + autoUpdate?: boolean; + targets: readonly ReviewCliInstallTarget[]; + shim?: boolean; + fff?: boolean; + trace?: true | { endpoint?: string; bucket?: string; key?: string; secret?: string }; + }): Promise; + removeCliInstall(request: { + targets: readonly ReviewCliInstallTarget[]; + shim?: boolean; + fff?: boolean; + trace?: true; + }): Promise; + declineCliInstall(): Promise; + skipCliInstallPrompts(): Promise; + resetCliInstallPrompts(): Promise; + attachControl(dispatch: (value: JsonValue) => Promise): void; +} + +export class ReviewDesktopConnectionService extends Disposable implements IReviewDesktopConnectionService { + declare readonly _serviceBrand: undefined; + + private readonly _onDidChangeLists = this._register(new Emitter()); + readonly onDidChangeLists = this._onDidChangeLists.event; + private readonly _onDidFail = this._register(new Emitter()); + readonly onDidFail = this._onDidFail.event; + private readonly connectionChanged = this._register(new Emitter()); + readonly onDidChangeConnection = this.connectionChanged.event; + + private initializePromise: Promise | null = null; + private tutorialPreparePromise: Promise | undefined; + private tutorialPrepareAttempted = false; + private cliInstallStatusPromise: Promise | undefined; + private readonly controller = new AbortController(); + private controlAttached = false; + private controlDispatch: ((value: JsonValue) => Promise) | undefined; + /** + * The main process owns the embedded server's endpoint and credentials and + * publishes them only once it has validated the server's ready event. + */ + private connection: ReviewDesktopConnection | undefined; + private get serverUrl(): string { + return this.requireConnection().url; + } + private get token(): string { + return this.requireConnection().token; + } + private get instanceId(): string { + return this.requireConnection().instanceId; + } + + constructor( + @IMainProcessService + private readonly mainProcessService: IMainProcessService, + @IStorageService private readonly storageService: IStorageService, + ) { + super(); + } + + private requireConnection(): ReviewDesktopConnection { + if (!this.connection) { + throw new Error("The Review Desktop connection is not established yet."); + } + return this.connection; + } + + private async connect(): Promise { + if (this.connection) return; + const connection = (await this.mainProcessService + .getChannel(REVIEW_DESKTOP_CHANNEL) + .call("getConnection")) as ReviewDesktopConnection; + if (connection?.version !== REVIEW_DESKTOP_CONNECTION_VERSION) { + throw new Error(`Unsupported Review Desktop connection version: ${String(connection?.version)}.`); + } + this.connection = connection; + } + + initialize(): Promise { + this.initializePromise ??= this.initializeGlobalState().catch((error) => { + this.initializePromise = null; + throw error; + }); + return this.initializePromise; + } + + async getConnection(): Promise { + await this.initialize(); + return { serverUrl: this.serverUrl, token: this.token }; + } + + /** + * The dismissed review retention window. It is a server preference rather + * than a workbench setting because the reaper runs inside the review server. + * `null` means never reap. + */ + async readDiffrConfig(): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/diffr-config`, { + headers: this.authHeaders(), + signal: AbortSignal.timeout(30_000), + }); + await this.requireOk(response, "diffr configuration"); + return parseReviewDiffrConfig(await response.json()); + } + + async setDiffrConfigValue(key: string, value: JsonValue): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/diffr-config`, { + method: "PUT", + headers: { + ...this.authHeaders(), + "content-type": "application/json", + }, + body: JSON.stringify({ key, value }), + signal: AbortSignal.timeout(30_000), + }); + await this.requireOk(response, "diffr configuration"); + return parseReviewDiffrConfig(await response.json()); + } + + async readScratchpadEnabled(): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/preferences/scratchpad`, { + headers: this.authHeaders(), + signal: AbortSignal.timeout(30_000), + }); + await this.requireOk(response, "scratchpad preference"); + return parseScratchpadPreference(await response.json()); + } + + async setScratchpadEnabled(enabled: boolean): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/preferences/scratchpad`, { + method: "PUT", + headers: { ...this.authHeaders(), "content-type": "application/json" }, + body: JSON.stringify({ enabled }), + // Also installs or removes the scratchpad skill for every agent. + signal: AbortSignal.timeout(120_000), + }); + await this.requireOk(response, "scratchpad preference"); + return parseScratchpadPreference(await response.json()); + } + + async saveDiffrSummarizer(input: ReviewDiffrSummarizerInput): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/diffr-config/summarizer`, { + method: "PUT", + headers: { ...this.authHeaders(), "content-type": "application/json" }, + body: JSON.stringify(input), + signal: AbortSignal.timeout(120_000), + }); + await this.requireOk(response, "summary settings"); + return parseReviewDiffrConfig(await response.json()); + } + + async testDiffrSummarizer(input: ReviewDiffrSummarizerInput): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/diffr-config/summarizer/test`, { + method: "POST", + headers: { ...this.authHeaders(), "content-type": "application/json" }, + body: JSON.stringify(input), + signal: AbortSignal.timeout(95_000), + }); + await this.requireOk(response, "summary test"); + const result: unknown = await response.json(); + if (!isJsonObject(result) || typeof result.summary !== "string") throw new Error("Malformed summary test response."); + return result.summary; + } + + async getTutorialStatus(): Promise<{ version: 1; reviewUuid: string | null }> { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/tutorial/status`, { + headers: this.authHeaders(), + signal: AbortSignal.timeout(5_000), + }); + await this.requireOk(response, "Review tutorial status"); + const payload = (await response.json()) as { + version?: unknown; + reviewUuid?: unknown; + }; + if (payload.version !== 1 || (payload.reviewUuid !== null && typeof payload.reviewUuid !== "string")) { + throw new Error("Review tutorial status is invalid."); + } + return { version: 1, reviewUuid: payload.reviewUuid as string | null }; + } + + prepareTutorial(): Promise { + if (this.storageService.getBoolean(REVIEW_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY, StorageScope.APPLICATION, false)) { + return Promise.resolve(); + } + if (this.tutorialPreparePromise) return this.tutorialPreparePromise; + if (this.tutorialPrepareAttempted) return Promise.resolve(); + this.tutorialPrepareAttempted = true; + const operation = this.requestTutorialPreparation(); + this.tutorialPreparePromise = operation; + const clearOperation = () => { + if (this.tutorialPreparePromise === operation) { + this.tutorialPreparePromise = undefined; + } + }; + void operation.then(clearOperation, clearOperation); + return operation; + } + + private async requestTutorialPreparation(): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/tutorial/prepare`, { + method: "POST", + headers: this.authHeaders(), + signal: AbortSignal.timeout(120_000), + }); + await this.requireOk(response, "Review tutorial preparation"); + } + + async openTutorial(): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/tutorial/open`, { + method: "POST", + headers: this.authHeaders(), + signal: AbortSignal.timeout(120_000), + }); + await this.requireOk(response, "Review tutorial open"); + const payload = parseReviewTutorialOpenResponse(await response.json()); + this.tutorialPrepareAttempted = true; + this.storageService.remove(REVIEW_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY, StorageScope.APPLICATION); + return payload; + } + + async deleteTutorial(): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/tutorial`, { + method: "DELETE", + headers: this.authHeaders(), + signal: AbortSignal.timeout(30_000), + }); + await this.requireOk(response, "Review tutorial delete"); + this.tutorialPreparePromise = undefined; + this.tutorialPrepareAttempted = true; + this.storageService.store( + REVIEW_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY, + true, + StorageScope.APPLICATION, + StorageTarget.MACHINE, + ); + this._onDidChangeLists.fire(); + } + + /** Raises the server's own error message when it sends one. */ + private async requireOk(response: Response, what: string): Promise { + if (response.ok) { + return; + } + const payload = (await response.json().catch(() => ({}))) as { + error?: unknown; + }; + throw new Error(typeof payload.error === "string" ? payload.error : `${what} returned ${response.status}.`); + } + + async getCliInstallStatus(): Promise { + await this.initialize(); + this.cliInstallStatusPromise ??= (async () => { + const response = await fetch(`${this.serverUrl}/install/status`, { + headers: this.authHeaders(), + signal: AbortSignal.timeout(30_000), + }); + await this.requireOk(response, "Review install status"); + return parseReviewCliInstallStatus(await response.json()); + })().finally(() => { + this.cliInstallStatusPromise = undefined; + }); + return this.cliInstallStatusPromise; + } + + async applyCliInstall(request: { + autoUpdate?: boolean; + targets: readonly ReviewCliInstallTarget[]; + shim?: boolean; + fff?: boolean; + trace?: true | { endpoint?: string; bucket?: string; key?: string; secret?: string }; + }): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/install/apply`, { + method: "POST", + headers: { + ...this.authHeaders(), + "content-type": "application/json", + }, + body: JSON.stringify({ + targets: request.targets, + ...(request.autoUpdate ? { autoUpdate: true } : {}), + ...(request.shim !== undefined ? { shim: request.shim } : {}), + ...(request.fff ? { fff: true } : {}), + ...(request.trace !== undefined ? { trace: request.trace } : {}), + }), + signal: AbortSignal.timeout(120_000), + }); + const payload: JsonValue = await response.json().catch(() => ({})); + if (!response.ok) { + const detail = payload as { output?: unknown; error?: unknown }; + throw new Error( + typeof detail.output === "string" && detail.output + ? detail.output + : typeof detail.error === "string" + ? detail.error + : `Review install returned ${response.status}.`, + ); + } + return parseReviewCliInstallApplyResponse(payload); + } + + async removeCliInstall(request: { + targets: readonly ReviewCliInstallTarget[]; + shim?: boolean; + fff?: boolean; + trace?: true; + }): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/install/remove`, { + method: "POST", + headers: { + ...this.authHeaders(), + "content-type": "application/json", + }, + body: JSON.stringify({ + targets: request.targets, + ...(request.shim ? { shim: true } : {}), + ...(request.fff ? { fff: true } : {}), + ...(request.trace ? { trace: true } : {}), + }), + signal: AbortSignal.timeout(30_000), + }); + if (!response.ok) { + throw new Error(`Review install remove returned ${response.status}.`); + } + } + + async declineCliInstall(): Promise { + await this.postCliInstallVerb("decline"); + } + + async skipCliInstallPrompts(): Promise { + await this.postCliInstallVerb("skip"); + } + + async resetCliInstallPrompts(): Promise { + await this.postCliInstallVerb("reset"); + } + + private async postCliInstallVerb(verb: "decline" | "skip" | "reset"): Promise { + await this.initialize(); + const response = await fetch(`${this.serverUrl}/install/${verb}`, { + method: "POST", + headers: this.authHeaders(), + signal: AbortSignal.timeout(30_000), + }); + if (!response.ok) { + throw new Error(`Review install ${verb} returned ${response.status}.`); + } + } + + attachControl(dispatch: (value: JsonValue) => Promise): void { + this.controlDispatch = dispatch; + if (this.controlAttached) return; + this.controlAttached = true; + void this.initializeAndMaintainControl((value) => { + const current = this.controlDispatch; + return current + ? current(value) + : Promise.resolve({ + ok: false, + error: "Review Desktop control handler is unavailable.", + }); + }); + } + + override dispose(): void { + this.controller.abort(); + super.dispose(); + } + + private async initializeGlobalState(): Promise { + await this.connect(); + await this.waitForHealth(); + } + + private async initializeAndMaintainControl( + dispatch: (value: JsonValue) => Promise, + ): Promise { + await reconnectUntilAborted( + this.controller.signal, + async () => { + await this.initialize(); + await this.maintainControl(dispatch); + }, + { + onRetry: (error) => console.error("[Review Desktop] control channel stopped", error), + }, + ); + } + + private async waitForHealth(): Promise { + const deadline = Date.now() + 10_000; + while (Date.now() < deadline) { + try { + const response = await fetch(`${this.serverUrl}/health`, { + signal: AbortSignal.timeout(1_000), + }); + const value = (await response.json()) as { instanceId?: unknown }; + if (response.ok && value.instanceId === this.instanceId) return; + } catch { + // The utility host may still be starting. + } + await new Promise((resolve) => setTimeout(resolve, 100)); + } + throw new Error("The embedded Review server did not become healthy."); + } + + + private async maintainControl(dispatch: (value: JsonValue) => Promise): Promise { + await reconnectUntilAborted( + this.controller.signal, + async (onConnected) => { + await this.consumeControl(dispatch, onConnected); + if (this.controller.signal.aborted) return; + throw new Error("The Review Desktop control stream ended."); + }, + { + onExhausted: (error) => { + throw error; + }, + }, + ); + } + + private async consumeControl( + dispatch: (value: JsonValue) => Promise, + onConnected: () => void, + ): Promise { + const url = new URL("/control", this.serverUrl); + url.searchParams.set("token", this.token); + const response = await fetch(url, { signal: this.controller.signal }); + if (!response.ok || !response.body) { + throw new Error(`Desktop control returned ${response.status}.`); + } + this.connectionChanged.fire(); + onConnected(); + await consumeReviewEventStream( + response.body, + async (value) => { + const frame = parseReviewDesktopVerbFrame(value); + let verbResponse: ReviewVerbResponse; + try { + verbResponse = await dispatch(frame.request); + } catch (error) { + verbResponse = { + ok: false, + error: error instanceof Error ? error.message : String(error), + }; + } + await fetch(`${this.serverUrl}/control/result`, { + method: "POST", + headers: { + ...this.authHeaders(), + "content-type": "application/json", + }, + body: JSON.stringify({ + id: frame.id, + response: verbResponse, + }), + signal: this.controller.signal, + }); + }, + this.controller.signal, + ).finally(() => this.connectionChanged.fire()); + } + + private authHeaders(): Record { + return { "x-review-token": this.token }; + } +} + +export async function reviewResponseError(response: Response, fallback: string): Promise { + const payload = (await response.json().catch(() => null)) as { + error?: unknown; + } | null; + return new Error(typeof payload?.error === "string" && payload.error ? payload.error : fallback); +} + +function parseScratchpadPreference(value: unknown): boolean { + if (typeof value !== "object" || value === null || !("enabled" in value) || typeof value.enabled !== "boolean") { + throw new Error("scratchpad preference response is malformed."); + } + return value.enabled; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffLayout.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffLayout.test.ts new file mode 100644 index 000000000..2464149b2 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffLayout.test.ts @@ -0,0 +1,82 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { Emitter } from "../../base/common/event.js"; +import { + ConfigurationTarget, + type IConfigurationChangeEvent, +} from "../../platform/configuration/common/configuration.js"; +import type { ReviewDiffLayout } from "../common/reviewProtocol.js"; +import { ReviewDiffLayoutSetting } from "./reviewDiffLayout.js"; + +function createService() { + const values = new Map(); + const writes: Array<{ key: string; value: unknown; target: unknown }> = []; + const changes = new Emitter(); + const configurationService = { + getValue: (key: string) => values.get(key), + updateValue: async (key: string, value: unknown, target: unknown) => { + values.set(key, value); + writes.push({ key, value, target }); + changes.fire({ + affectsConfiguration: (section: string) => section === key, + } as IConfigurationChangeEvent); + }, + onDidChangeConfiguration: changes.event, + }; + const service = new ReviewDiffLayoutSetting(configurationService as never); + return { service, values, writes, changes }; +} + +test("side by side is the default and inline maps to unified", () => { + const { service, values } = createService(); + assert.equal(service.get(), "split"); + values.set("diffEditor.renderSideBySide", false); + assert.equal(service.get(), "unified"); +}); + +test("set writes the user setting and announces the new layout", async () => { + const { service, writes } = createService(); + const announced: ReviewDiffLayout[] = []; + service.onDidChange((layout) => announced.push(layout)); + + await service.set("unified"); + + assert.deepEqual(writes, [ + { + key: "diffEditor.renderSideBySide", + value: false, + target: ConfigurationTarget.USER, + }, + ]); + assert.deepEqual(announced, ["unified"]); + assert.equal(service.get(), "unified"); +}); + +test("toggle flips between the two layouts", async () => { + const { service, writes } = createService(); + await service.toggle(); + assert.equal(service.get(), "unified"); + await service.toggle(); + assert.equal(service.get(), "split"); + assert.deepEqual( + writes.map((write) => write.value), + [false, true], + ); +}); + +test("unrelated setting changes do not announce a layout", () => { + const { service, changes } = createService(); + const announced: ReviewDiffLayout[] = []; + service.onDidChange((layout) => announced.push(layout)); + changes.fire({ + affectsConfiguration: (section: string): boolean => + section === "editor.fontSize", + } as IConfigurationChangeEvent); + assert.deepEqual(announced, []); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffLayout.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffLayout.ts new file mode 100644 index 000000000..69698b2f3 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffLayout.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter } from "../../base/common/event.js"; +import { Disposable } from "../../base/common/lifecycle.js"; +import { + ConfigurationTarget, + IConfigurationService, +} from "../../platform/configuration/common/configuration.js"; +import type { ReviewDiffLayout } from "../common/reviewProtocol.js"; + +const RENDER_SIDE_BY_SIDE_KEY = "diffEditor.renderSideBySide"; + +/** + * The unified/split choice, kept as the stock diff-editor setting rather than + * widget-local state: every embedded diff (the multi-diff view and the inline + * editors) already reads it, the Toggle Inline View command already writes it, + * and the user setting is what makes the choice outlive the app. + */ +export class ReviewDiffLayoutSetting extends Disposable { + private readonly _onDidChange = this._register( + new Emitter(), + ); + readonly onDidChange = this._onDidChange.event; + + constructor( + @IConfigurationService + private readonly configurationService: IConfigurationService, + ) { + super(); + this._register( + configurationService.onDidChangeConfiguration((event) => { + if (event.affectsConfiguration(RENDER_SIDE_BY_SIDE_KEY)) { + this._onDidChange.fire(this.get()); + } + }), + ); + } + + get(): ReviewDiffLayout { + return this.configurationService.getValue( + RENDER_SIDE_BY_SIDE_KEY, + ) === false + ? "unified" + : "split"; + } + + set(layout: ReviewDiffLayout): Promise { + return this.configurationService.updateValue( + RENDER_SIDE_BY_SIDE_KEY, + layout === "split", + ConfigurationTarget.USER, + ); + } + + toggle(): Promise { + return this.set(this.get() === "split" ? "unified" : "split"); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffViewService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffViewService.ts new file mode 100644 index 000000000..645fbfb4c --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewDiffViewService.ts @@ -0,0 +1,395 @@ +import { orderReviewDiffFiles } from "../common/reviewChangedFilesModel.js"; +import { CancellationToken } from "../../base/common/cancellation.js"; +import { Range } from "../../editor/common/core/range.js"; +import { USUAL_WORD_SEPARATORS } from "../../editor/common/core/wordHelper.js"; +import { ITextModelService } from "../../editor/common/services/resolverService.js"; +import { IDiffProviderFactoryService } from "../../editor/browser/widget/diffEditor/diffProviderFactoryService.js"; +import { alignmentRows } from "../common/reviewLens.js"; +import type { ReviewInlineEditorSpec, ReviewInlineEditorHandle, ReviewFindQuery } from "../common/reviewProtocol.js"; +import { structuralChangeCounts } from "../common/reviewProtocol.js"; +import type { ReviewDiffProgress, ReviewDiffViewport } from "../common/reviewProtocol.js"; +import { lensRanges, withLens } from "./reviewLens.js"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter } from "../../base/common/event.js"; +import { Disposable, DisposableStore, isDisposable } from "../../base/common/lifecycle.js"; +import type { URI } from "../../base/common/uri.js"; +import type { ICodeEditor } from "../../editor/browser/editorBrowser.js"; +import type { IMultiDiffEditorViewState } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.js"; +import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; +import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; +import { REVIEW_STRUCTURAL_DIFF_SETTING } from "../common/reviewConfigurationDefaults.js"; +import type { + ReviewCommitScope, + ReviewDiffLens, + ReviewDiffFileWire, + ReviewDiffViewHandle, + ReviewDiffViewSpec, +} from "../common/reviewProtocol.js"; +import { ReviewDiffLayoutSetting } from "./reviewDiffLayout.js"; +import { markReviewEmbeddedEditor } from "./reviewEmbeddedNavigation.js"; +import { ReviewFilesDiffView, ReviewFilesEditorInput, type ReviewFilesEditorEntry } from "./reviewFilesDiffView.js"; +import { ReviewEmbeddedEditors } from "./reviewEmbeddedEditors.js"; + +import { createStructuralDiffEditors } from "./reviewStructuralDiff.js"; +import { StructuralDiffSession } from "./reviewStructuralDiffSession.js"; +import type { StructuralDiffStream } from "./reviewStructuralDiffClient.js"; + +export interface ReviewDiffViewSource { + load(scope?: ReviewCommitScope, lens?: ReviewDiffLens): Promise<{ + sourceUri: URI; entries: readonly ReviewFilesEditorEntry[]; + session?: StructuralDiffSession; + }>; + files(scope?: ReviewCommitScope): Promise; +} + +/** + * Mounts the changed-files diff UI inside the Review canvas. One instance + * belongs to one canvas pane, so its view-state cache and its live handles + * follow that pane's lifetime. + */ +export class ReviewDiffViewService extends Disposable { + private overflowWidgetsDomNode: HTMLElement | undefined; + private readonly handles = new Set(); + comparisonGeneration = 0; + private readonly sessions = new Map(); + readonly diffLayout: ReviewDiffLayoutSetting; + /** + * Scroll and expansion state per session document. The Diff view is a + * conditionally rendered React sibling: a toggle away disposes the widget, + * so the state must survive outside it. + */ + private readonly viewStates = new Map(); + + constructor( + private readonly inlineEditors: ReviewEmbeddedEditors, + @IInstantiationService + private readonly instantiationService: IInstantiationService, + ) { + super(); + this.diffLayout = this._register(instantiationService.createInstance(ReviewDiffLayoutSetting)); + } + + get structuralRenderingEnabled(): boolean { + return this.instantiationService.invokeFunction(a => a.get(IConfigurationService).getValue(REVIEW_STRUCTURAL_DIFF_SETTING) === true); + } + + /** Shared by every view of this comparison; reset/dispose follows the canvas lifetime. */ + openComparison(key: string, client: StructuralDiffStream, generation: number): StructuralDiffSession | undefined { + if (generation !== this.comparisonGeneration || !this.structuralRenderingEnabled) return undefined; + let session = this.sessions.get(key); + if (!session) { + session = new StructuralDiffSession(client); + this.sessions.set(key, session); + void session.start(); + } + return session; + } + + override dispose(): void { this.reset(); super.dispose(); } + + setOverflowWidgetsDomNode(node: HTMLElement): void { + this.overflowWidgetsDomNode = node; + } + + create(spec: ReviewDiffViewSpec, source: ReviewDiffViewSource): ReviewDiffViewHandle { + const handle = new DiffViewController( + spec, + this.instantiationService, + this.inlineEditors, + this.overflowWidgetsDomNode, + this.diffLayout, + this.viewStates, + () => this.handles.delete(handle), + source, + ); + this.handles.add(handle); + return handle; + } + + /** Document peeks use the same controller, providers and widget as the Diff tab. */ + createDocument(spec: ReviewInlineEditorSpec, lens: ReviewDiffLens, source: ReviewDiffViewSource): ReviewInlineEditorHandle { + const lifetime = new DisposableStore(); + const heightChanged = lifetime.add(new Emitter()); + let height = 400; + let generation = 0; + let matches: DocumentMatch[] = []; + const view = this.create({ + container: spec.container, lens, progress: spec.progress, + document: { + heightMode: spec.heightMode, + onDidChangeHeight: value => { height = value; heightChanged.fire(value); }, + onDidFocus: spec.onDidFocus, onDidOpen: spec.onDidOpen, + }, + }, source) as DiffViewController; + lifetime.add(view); + return { + get height() { return height; }, + setProgress: progress => view.setProgress(progress), + onDidChangeHeight: heightChanged.event, + onDidError: view.onDidError, + setActive: active => spec.container.classList.toggle("review-document-code-active", active), + setCollapsed: collapsed => view.setCollapsed(collapsed), + setFindQuery: async query => { + const request = ++generation; + const result = await this.findDocument(lens, source, query); + if (lifetime.isDisposed || request !== generation) return { matchCount: 0 }; + matches = result; + view.decorateMatches(matches); + return { matchCount: matches.length }; + }, + revealFindMatch: index => { + const match = matches[index]; + if (!match) return; + view.setCollapsed(false); + view.revealSource({ file: match.file, side: match.side, fromLine: match.range.startLineNumber, toLine: match.range.endLineNumber }); + view.decorateMatches(matches, index); + }, + clearActiveFindMatch: () => view.decorateMatches(matches), + clearFind: () => { generation++; matches = []; view.decorateMatches([]); }, + dispose: () => { generation++; lifetime.dispose(); }, + }; + } + + /** Search pinned models through the same diff provider; no synthetic text/model is built. */ + async findDocument(lens: ReviewDiffLens, source: ReviewDiffViewSource, query: ReviewFindQuery): Promise { + if (!query.text) return []; + const lifetime = new DisposableStore(); + try { + const data = await source.load(undefined, lens); + const entries = data.entries.filter(entry => lensRanges(lens, entry).length > 0); + const structural = data.session ? createStructuralDiffEditors(this.instantiationService, entries, lifetime, data.session) + : { instantiation: this.instantiationService, entries }; + const instantiation = withLens(structural.instantiation, structural.entries, lens, lifetime, () => undefined, () => ({ dispose() {} })); + const resolver = instantiation.invokeFunction(a => a.get(ITextModelService)); + const factory = instantiation.invokeFunction(a => a.get(IDiffProviderFactoryService)); + const matches: DocumentMatch[] = []; + for (const entry of structural.entries) { + const original = entry.original ? lifetime.add(await resolver.createModelReference(entry.original)).object.textEditorModel : undefined; + const modified = entry.modified ? lifetime.add(await resolver.createModelReference(entry.modified)).object.textEditorModel : undefined; + const provider = factory.createDiffProvider({ diffAlgorithm: "advanced" }); + if (isDisposable(provider)) lifetime.add(provider); + const diff = original && modified ? await provider.computeDiff(original, modified, { ignoreTrimWhitespace: false, maxComputationTimeMs: 0, computeMoves: false }, CancellationToken.None) : undefined; + const pairs = diff && original && modified ? new Map(alignmentRows(diff, original.getLineCount(), modified.getLineCount()).filter((row): row is [number, number] => row[0] !== null && row[1] !== null)) : new Map(); + for (const [side, model] of [["base", original], ["head", modified]] as const) { + if (!model) continue; + const ranges = lensRanges(lens, entry).filter(range => range.side === side); + const found = model.findMatches(query.text, false, query.isRegex, query.matchCase, query.wholeWord ? USUAL_WORD_SEPARATORS : null, false); + for (const match of found) { + const line = match.range.startLineNumber; + const outside = diff?.contextGaps?.some(gap => gap.label === "Outside lens" && line >= (side === "base" ? gap.originalStart : gap.modifiedStart) && line < (side === "base" ? gap.originalStart + gap.originalCount : gap.modifiedStart + gap.modifiedCount)); + if (outside || (!diff && !ranges.some(range => line >= range.fromLine && line <= range.toLine))) continue; + const headLine = pairs.get(line - 1); + if (side === "base" && headLine !== undefined && modified && match.range.startLineNumber === match.range.endLineNumber && model.getLineContent(line) === modified.getLineContent(headLine + 1)) continue; + matches.push({ file: side === "base" ? entry.file.previousPath ?? entry.file.path : entry.file.path, side, range: match.range }); + } + } + } + return matches; + } finally { lifetime.dispose(); } + } + + reset(): void { + this.comparisonGeneration++; + for (const handle of [...this.handles]) handle.dispose(); + this.handles.clear(); + this.viewStates.clear(); + for (const session of this.sessions.values()) session.dispose(); + this.sessions.clear(); + } + + toggleRenderSideBySide(): void { + void this.diffLayout.toggle(); + } +} + +interface DocumentMatch { + file: string; + side: "base" | "head"; + range: Range; +} + +class DiffViewController extends Disposable implements ReviewDiffViewHandle { + private readonly _onDidError = this._register(new Emitter()); + readonly onDidError = this._onDidError.event; + private readonly activeControlStore = this._register(new DisposableStore()); + private view: ReviewFilesDiffView | undefined; + private progress: ReviewDiffProgress | undefined; + private readonly progressChanged = this._register(new Emitter()); + private pendingSectionId: string | undefined; + private pendingSource: ReviewDiffLens['ranges'][number] | undefined; + setProgress(progress: ReviewDiffProgress): void { this.progress = progress; this.view?.setProgress(progress); this.progressChanged.fire(); } + revealSource(source: ReviewDiffLens['ranges'][number], sectionId?: string): void { this.pendingSource = source; this.pendingSectionId = sectionId; this.view?.revealSource(source, sectionId); } + private readonly _onDidScroll = this._register(new Emitter()); + readonly onDidScroll = this._onDidScroll.event; + sourceOffset(source: ReviewDiffLens['ranges'][number]): number | undefined { return this.view?.sourceOffset(source); } + private viewStateKey: string | undefined; + private adoptedEditors: readonly ICodeEditor[] = []; + private disposed = false; + private collapsed = false; + private matches: DocumentMatch[] = []; + private activeMatch: number | undefined; + private readonly findDecorations = this._register(new DisposableStore()); + setCollapsed(collapsed: boolean): void { this.collapsed = collapsed; this.view?.setCollapsed(collapsed); } + decorateMatches(matches: DocumentMatch[], active?: number): void { + this.matches = matches; this.activeMatch = active; + this.findDecorations.clear(); + const control = this.view?.getActiveControl(); + if (!control) return; + for (const [side, editor] of [["base", control.getOriginalEditor()], ["head", control.getModifiedEditor()]] as const) { + const collection = editor.createDecorationsCollection(matches.flatMap((match, index) => match.side === side ? [{ range: match.range, options: { description: "review-document-find", className: index === active ? "currentFindMatch" : "findMatch" } }] : [])); + this.findDecorations.add({ dispose: () => collection.clear() }); + } + } + + constructor( + private readonly spec: ReviewDiffViewSpec, + private readonly instantiationService: IInstantiationService, + private readonly inlineEditors: ReviewEmbeddedEditors, + private readonly overflowWidgetsDomNode: HTMLElement | undefined, + private readonly diffLayout: ReviewDiffLayoutSetting, + private readonly viewStates: Map, + private readonly onDispose: () => void, + private readonly source: ReviewDiffViewSource, + ) { + super(); + this.progress = spec.progress; + void this.initialize(); + } + + focus(): void { + this.view?.focus(); + } + + override dispose(): void { + if (this.disposed) return; + this.disposed = true; + this.captureViewState(); + // A view toggle disposes these editors. The composite must not keep one + // of them as its active editor afterwards. + for (const editor of this.adoptedEditors) { + this.inlineEditors.clearExternalActiveEditor(editor); + } + this.adoptedEditors = []; + this.view = undefined; + super.dispose(); + this.onDispose(); + } + + private async initialize(): Promise { + try { + const data = await this.source.load(this.spec.scope, this.spec.lens); + const { sourceUri, entries } = data; + const session = data.session; + const structuralEnabled = session !== undefined && this.instantiationService.invokeFunction(a => a.get(IConfigurationService).getValue(REVIEW_STRUCTURAL_DIFF_SETTING) === true); + this.viewStateKey = `${sourceUri.toString()}:${structuralEnabled}:${JSON.stringify(this.spec.lens ?? null)}`; + if (this.disposed) return; + const store = this._register(new DisposableStore()); + const structural = session && structuralEnabled ? createStructuralDiffEditors(this.instantiationService, entries, store, session) + : { instantiation: this.instantiationService, entries }; + + if (this.disposed) return; + const lens = this.spec.lens; + const sections = this.progress?.sections; + let selected = lens && sections?.length ? sections.flatMap(section => { + const matches = structural.entries.filter(entry => lensRanges({ ...lens, ranges: section.sources }, entry).length > 0); + return matches.map((entry, index) => ({ ...entry, sectionId: section.id, sectionStart: index === 0, original: entry.original?.with({ fragment: section.id }), modified: entry.modified?.with({ fragment: section.id }) })); + }) : lens ? structural.entries.filter(entry => lensRanges(lens, entry).length > 0) : structural.entries; + // File lenses have no authored sections; follow the same order as their file tree. + if (lens && !sections?.length) { + const byFile = new Map(selected.map(entry => [entry.file, entry])); + selected = orderReviewDiffFiles([...byFile.keys()]).map(file => byFile.get(file)!); + } + const instantiation = withLens(structural.instantiation, selected, lens, store, () => this.progress, this.progressChanged.event); + // The input owns the text-model references its view model resolves, so + // this handle disposes it alongside the view. + const input = store.add(instantiation.createInstance(ReviewFilesEditorInput, sourceUri, selected, + structuralEnabled, !!lens || !!this.spec.onToggleViewed)); + const view = store.add( + instantiation.createInstance( + ReviewFilesDiffView, + this.spec.container, + this.overflowWidgetsDomNode, + this.diffLayout, + this.spec.fileTreeContainer, this.spec.onToggleViewed, this.spec.onToggleSection, this.spec.document, + ), + ); + this.view = view; + if (this.progress) view.setProgress(this.progress); + if (structuralEnabled) view.startLoading(selected); + store.add(view.onDidChangeActiveControl(() => this.bindActiveControl(view))); + store.add(view.onDidScroll(() => this._onDidScroll.fire({ height: view.viewportHeight }))); + // A saved whole-list offset cannot be restored into a partial streamed list. + await view.setInput(input, structuralEnabled ? undefined : this.viewStates.get(this.viewStateKey), + ); + if (this.disposed) return; + this.bindActiveControl(view); + view.setCollapsed(this.collapsed); + if (this.pendingSource) view.revealSource(this.pendingSource, this.pendingSectionId); + if (!session) for (const entry of selected) view.fileCounts(entry.file.path, { added: entry.file.additions, removed: entry.file.deletions }); + if (session) this.observeSession(session, selected, view, store, structuralEnabled); + + } catch (error) { + if (this.disposed) return; + this._onDidError.fire(error instanceof Error ? error.message : String(error)); + } + } + + private observeSession(session: StructuralDiffSession, entries: readonly ReviewFilesEditorEntry[], view: ReviewFilesDiffView, store: DisposableStore, structuralEnabled: boolean): void { + const rendered = new Set(); + const annotationWarnings = new Set(); + const renderCurrentState = (change?: import("./reviewStructuralDiffSession.js").StructuralSessionChange) => { + if (this.disposed) return; + for (const entry of entries) { + const path = entry.file.path; + if (change && !change.files.has(path) && !change.labels.has(path)) continue; + const result = entry.file.status === "unchanged" ? {} : session.getFileResult(path); + if (result?.annotationError && !annotationWarnings.has(path)) { + annotationWarnings.add(path); + this._onDidError.fire(`Summary unavailable for ${path}: ${result.annotationError}`); + } + if (!result || rendered.has(path)) continue; + rendered.add(path); + if (structuralEnabled && result.hidden !== undefined) view.hideFile(path, result.hidden); + if (result.diff) view.fileCounts(path, result.diff.type === "text" ? structuralChangeCounts(result.diff.structural_changes) : { added: 0, removed: 0 }); + if (structuralEnabled) view.fileLoaded(path, result.error); + } + if (session.error) view.loadingFailed(session.error); + else if (session.complete) view.loadingFailed("diffr did not supply a result for this file."); + }; + store.add(session.onDidChange(renderCurrentState)); + renderCurrentState(); + } + + /** + * Joins the embedded diff's inner editors to the canvas composite. Find and + * the editor context keys act on the composite's active editor, so a focused + * inner editor has to become that editor. + */ + private bindActiveControl(view: ReviewFilesDiffView): void { + this.activeControlStore.clear(); + const diffEditor = view.getActiveControl(); + if (!diffEditor) return; + const editors: readonly ICodeEditor[] = [diffEditor.getOriginalEditor(), diffEditor.getModifiedEditor(), + ]; + this.adoptedEditors = editors; + for (const editor of editors) { + this.activeControlStore.add(markReviewEmbeddedEditor(editor)); + if (this.spec.document) ReviewEmbeddedEditors.markDocumentEditor(editor); + this.activeControlStore.add( + editor.onDidFocusEditorText(() => { this.inlineEditors.setExternalActiveEditor(editor); this.spec.document?.onDidFocus?.(); }), + ); + } + this.decorateMatches(this.matches, this.activeMatch); + } + + private captureViewState(): void { + const key = this.viewStateKey; + const state = this.view?.getViewState(); + if (!key || !state) return; + this.viewStates.set(key, state); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewEmbeddedEditors.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewEmbeddedEditors.ts new file mode 100644 index 000000000..db5e7cbba --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewEmbeddedEditors.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ +import { Emitter } from "../../base/common/event.js"; +import { Disposable } from "../../base/common/lifecycle.js"; +import type { ICodeEditor } from "../../editor/browser/editorBrowser.js"; +import type { ICompositeCodeEditor } from "../../editor/common/editorCommon.js"; + +/** Tracks focus and retained selections for all native editors embedded in a review. */ +export class ReviewEmbeddedEditors extends Disposable implements ICompositeCodeEditor { + private readonly changed = this._register(new Emitter()); + readonly onDidChangeActiveEditor = this.changed.event; + private active: ICodeEditor | undefined; + private selected: ICodeEditor | undefined; + private static readonly documentEditors = new WeakSet(); + + get activeCodeEditor(): ICodeEditor | undefined { return this.active; } + get selectionCodeEditor(): ICodeEditor | undefined { return this.active ?? this.selected; } + static owns(editor: ICodeEditor): boolean { return this.documentEditors.has(editor); } + static markDocumentEditor(editor: ICodeEditor): void { this.documentEditors.add(editor); } + + setExternalActiveEditor(editor: ICodeEditor | undefined): void { + if (editor) this.selected = editor; + if (this.active === editor) return; + this.active = editor; + this.changed.fire(this); + } + clearExternalActiveEditor(editor: ICodeEditor): void { + if (this.selected === editor) this.selected = undefined; + if (this.active === editor) this.setExternalActiveEditor(undefined); + } + reset(): void { this.selected = undefined; this.setExternalActiveEditor(undefined); } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewEmbeddedNavigation.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewEmbeddedNavigation.ts new file mode 100644 index 000000000..1d87eef86 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewEmbeddedNavigation.ts @@ -0,0 +1,184 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { IDisposable } from "../../base/common/lifecycle.js"; +import { + getWindow, + scheduleAtNextAnimationFrame, +} from "../../base/browser/dom.js"; +import { KeyCode, KeyMod } from "../../base/common/keyCodes.js"; +import type { ICodeEditor } from "../../editor/browser/editorBrowser.js"; +import { ICodeEditorService } from "../../editor/browser/services/codeEditorService.js"; +import { SymbolNavigationAnchor } from "../../editor/contrib/gotoSymbol/browser/goToCommands.js"; +import { EditorContextKeys } from "../../editor/common/editorContextKeys.js"; +import { Position } from "../../editor/common/core/position.js"; +import { CommandsRegistry, ICommandService } from "../../platform/commands/common/commands.js"; +import { ContextKeyExpr, RawContextKey } from "../../platform/contextkey/common/contextkey.js"; +import { + KeybindingsRegistry, + KeybindingWeight, +} from "../../platform/keybinding/common/keybindingsRegistry.js"; +import type { IEditorOptions } from "../../platform/editor/common/editor.js"; +import { IHistoryService } from "../../workbench/services/history/common/history.js"; +import { + EditorPaneSelectionCompareResult, + type IEditorPaneSelection, +} from "../../workbench/common/editor.js"; + +export const ReviewEmbeddedEditorFocus = new RawContextKey( + "reviewEmbeddedEditorFocus", + false, +); + +const reviewEmbeddedEditors = new WeakSet(); + +export interface ReviewEmbeddedNavigationLocation { + readonly view: "review" | "diff"; + readonly path: string; + readonly side: "base" | "head"; + readonly lineNumber: number; + readonly column: number; + readonly section?: string; +} + +interface ReviewEmbeddedEditorOptions extends IEditorOptions { + readonly reviewEmbeddedSelection?: ReviewEmbeddedEditorSelection; +} + +export function markReviewEmbeddedEditor(editor: ICodeEditor): IDisposable { + reviewEmbeddedEditors.add(editor); + const focus = ReviewEmbeddedEditorFocus.bindTo(editor.contextKeyService); + focus.set(true); + return { + dispose: () => { + reviewEmbeddedEditors.delete(editor); + focus.reset(); + }, + }; +} + +export class ReviewEmbeddedEditorSelection implements IEditorPaneSelection { + constructor( + readonly editor: ICodeEditor, + readonly location: ReviewEmbeddedNavigationLocation, + ) {} + + compare(other: IEditorPaneSelection): EditorPaneSelectionCompareResult { + if (!(other instanceof ReviewEmbeddedEditorSelection)) { + return EditorPaneSelectionCompareResult.DIFFERENT; + } + const left = this.location; + const right = other.location; + return left.view === right.view && + left.path === right.path && + left.side === right.side && + left.lineNumber === right.lineNumber && + left.column === right.column && + left.section === right.section + ? EditorPaneSelectionCompareResult.IDENTICAL + : EditorPaneSelectionCompareResult.DIFFERENT; + } + + restore(options: IEditorOptions): IEditorOptions { + return { + ...options, + reviewEmbeddedSelection: this, + } as ReviewEmbeddedEditorOptions; + } + + restoreInCanvas(): boolean { + const domNode = this.editor.getDomNode(); + if (!domNode?.isConnected || !this.editor.hasModel()) return false; + const restore = () => { + const position = new Position( + this.location.lineNumber, + this.location.column, + ); + const section = domNode.closest("[data-review-section]"); + section?.dispatchEvent(new CustomEvent("review-section-expand")); + domNode.scrollIntoView({ block: "center", inline: "nearest" }); + this.editor.setPosition(position, "review.navigationHistory"); + this.editor.revealPositionInCenterIfOutsideViewport(position); + this.editor.focus(); + }; + restore(); + scheduleAtNextAnimationFrame(getWindow(domNode), restore); + return true; + } + + log(): string { + const location = this.location; + return `${location.view}:${location.side}:${location.path}:${location.lineNumber}:${location.column}`; + } +} + +export function reviewEmbeddedSelectionFromOptions( + options: IEditorOptions | undefined, +): ReviewEmbeddedEditorSelection | undefined { + return (options as ReviewEmbeddedEditorOptions | undefined) + ?.reviewEmbeddedSelection; +} + +const goToDefinitionCommand = "review.action.embeddedGoToDefinition"; +const showReferencesCommand = "review.action.embeddedShowReferences"; + +CommandsRegistry.registerCommand(goToDefinitionCommand, (accessor) => { + runEmbeddedSymbolCommand( + accessor.get(ICodeEditorService), + accessor.get(IHistoryService), + accessor.get(ICommandService), + "editor.action.revealDefinition", + true, + ); +}); +CommandsRegistry.registerCommand(showReferencesCommand, (accessor) => { + runEmbeddedSymbolCommand( + accessor.get(ICodeEditorService), + accessor.get(IHistoryService), + accessor.get(ICommandService), + "editor.action.referenceSearch.trigger", + false, + ); +}); + +KeybindingsRegistry.registerKeybindingRule({ + id: goToDefinitionCommand, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyCode.F12, + when: ContextKeyExpr.and( + ReviewEmbeddedEditorFocus, + EditorContextKeys.editorTextFocus, + ), +}); +KeybindingsRegistry.registerKeybindingRule({ + id: showReferencesCommand, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.Shift | KeyCode.F12, + when: ContextKeyExpr.and( + ReviewEmbeddedEditorFocus, + EditorContextKeys.editorTextFocus, + ), +}); + +function runEmbeddedSymbolCommand( + codeEditorService: ICodeEditorService, + historyService: IHistoryService, + commandService: ICommandService, + commandId: string, + recordsHistory: boolean, +): void { + const editor = codeEditorService.getActiveCodeEditor(); + if (!editor || !reviewEmbeddedEditors.has(editor) || !editor.hasModel()) return; + const model = editor.getModel(); + const position = editor.getPosition(); + editor.focus(); + if (recordsHistory) { + historyService.addActiveEditorNavigation(); + } + void commandService.executeCommand( + commandId, + new SymbolNavigationAnchor(model, position), + ); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewFilesDiffView.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewFilesDiffView.ts new file mode 100644 index 000000000..3cd2ae631 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewFilesDiffView.ts @@ -0,0 +1,629 @@ +import type { ReviewDiffProgress, ReviewDiffLens, ReviewDiffViewSpec } from "../common/reviewProtocol.js"; +import { Range } from "../../editor/common/core/range.js"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import "../browser/media/review.css"; +import { $, append, Dimension } from "../../base/browser/dom.js"; +import { Orientation, SplitView } from "../../base/browser/ui/splitview/splitview.js"; +import { Emitter, Event } from "../../base/common/event.js"; +import { Disposable, toDisposable } from "../../base/common/lifecycle.js"; +import { autorun } from "../../base/common/observable.js"; +import { isEqual } from "../../base/common/resources.js"; +import { URI } from "../../base/common/uri.js"; +import { ElementSizeObserver } from "../../editor/browser/config/elementSizeObserver.js"; +import type { IDiffEditor } from "../../editor/browser/editorBrowser.js"; +import { MultiDiffEditorViewModel } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.js"; +import { MultiDiffEditorWidget } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.js"; +import type { IMultiDiffEditorViewState } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.js"; +import { IDiffEditorOptions } from "../../editor/common/config/editorOptions.js"; +import { ITextModelService } from "../../editor/common/services/resolverService.js"; +import { ITextResourceConfigurationService } from "../../editor/common/services/textResourceConfiguration.js"; +import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; +import { MultiDiffEditorInput } from "../../workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.js"; +import { + IMultiDiffSourceResolverService, + MultiDiffEditorItem, +} from "../../workbench/contrib/multiDiffEditor/browser/multiDiffSourceResolverService.js"; +import { IEditorGroupsService } from "../../workbench/services/editor/common/editorGroupsService.js"; +import { IEditorService } from "../../workbench/services/editor/common/editorService.js"; +import { ITextFileService } from "../../workbench/services/textfile/common/textfiles.js"; +import { ReviewChangedFilesTree } from "../browser/reviewChangedFilesTree.js"; +import { type ReviewDiffFileWire, type StructuralLineCounts } from "../common/reviewProtocol.js"; +import type { ReviewDiffLayoutSetting } from "./reviewDiffLayout.js"; +import { reviewMultiDiffLabelUris, ReviewMultiDiffUIElementFactory } from "./reviewMultiDiff.js"; + +const FILE_TREE_MINIMUM_WIDTH = 180; +const DIFF_MINIMUM_WIDTH = 320; +const FILE_TREE_COLLAPSE_WIDTH = FILE_TREE_MINIMUM_WIDTH + DIFF_MINIMUM_WIDTH; +const REVIEW_FILES_DIFF_EDITOR_OPTIONS = { + hideUnchangedRegions: { enabled: true }, + originalEditable: false, + readOnly: true, + glyphMargin: false, + lineNumbersMinChars: 3, + // A peek or diff on the page is read until it is clicked into; the current + // line highlight belongs to the cursor, not to the first revealed line. + renderLineHighlightOnlyWhenFocus: true, +} satisfies IDiffEditorOptions; + +export interface ReviewFilesEditorEntry { + readonly sectionId?: string; + readonly sectionStart?: boolean; + readonly file: ReviewDiffFileWire; + readonly original: URI | undefined; + readonly modified: URI | undefined; + readonly goToFileResource: URI; +} + +export class ReviewFilesEditorInput extends MultiDiffEditorInput { + static override readonly ID = "workbench.input.devfast.reviewFiles"; + static readonly EDITOR_ID = "workbench.editor.devfast.reviewFiles"; + + private readonly updateResources: (paths: ReadonlySet, loading: boolean) => void; + + setReadyFiles(paths: ReadonlySet, loading: boolean): void { + this.updateResources(paths, loading); + } + + constructor( + source: URI, + readonly entries: readonly ReviewFilesEditorEntry[], + readonly structural: boolean = false, + lens: boolean = false, + @ITextModelService textModelService: ITextModelService, + @ITextResourceConfigurationService + textResourceConfigurationService: ITextResourceConfigurationService, + @IInstantiationService instantiationService: IInstantiationService, + @IMultiDiffSourceResolverService + multiDiffSourceResolverService: IMultiDiffSourceResolverService, + @ITextFileService textFileService: ITextFileService, + ) { + const items = entries.map( + (entry) => + new MultiDiffEditorItem( + entry.original, + entry.modified, + entry.goToFileResource, + undefined, + undefined, + reviewMultiDiffLabelUris(entry.file), + // Every hidden line comes from the one fold model: diffr's regions, never the diff editor's own unchanged-region hiding. + // Every collapsed region diffr sends is a hidden-region band; the editor's own folding stays off. + (structural || lens) + ? { + ...REVIEW_FILES_DIFF_EDITOR_OPTIONS, + hideOriginalLineNumbers: entry.file.status === "added", + hideUnchangedRegions: { + enabled: true, + minimumLineCount: 1, + contextLineCount: 0, + }, + folding: false, + glyphMargin: true, + experimental: { useTrueInlineView: false }, + } + : { ...REVIEW_FILES_DIFF_EDITOR_OPTIONS, hideOriginalLineNumbers: entry.file.status === "added" }, + ), + ); + const changes = new Emitter(); + let current: readonly MultiDiffEditorItem[] = []; + let loading = items.length > 0; + const streamSource = { + isLoading: { get value() { return loading; }, onDidChange: changes.event }, + resources: { + get value() { + return current; + }, + onDidChange: changes.event, + }, + }; + super( + source, + "Files", + structural ? undefined : items, + true, + textModelService, + textResourceConfigurationService, + instantiationService, + structural + ? { + _serviceBrand: undefined, + registerResolver: (resolver) => + multiDiffSourceResolverService.registerResolver(resolver), + resolve: async () => streamSource, + } + : multiDiffSourceResolverService, + textFileService, + ); + this._register(changes); + this.updateResources = (paths, pending) => { + loading = pending; current = items.filter((_, index) => paths.has(entries[index].file.path)); + changes.fire(); + }; + } + + override get typeId(): string { + return ReviewFilesEditorInput.ID; + } + + override get editorId(): string { + return ReviewFilesEditorInput.EDITOR_ID; + } +} + +/** + * The changed-files diff UI — a file list beside a multi-diff widget — as a + * plain widget. It owns no editor pane, so the Review canvas can mount it into + * a container the app supplies. The container's size drives the layout: the + * canvas gives the host element its bounds through CSS, not through a pane + * layout call. + */ +export class ReviewFilesDiffView extends Disposable { + private readonly _onDidChangeActiveControl = this._register(new Emitter()); + readonly onDidChangeActiveControl = this._onDidChangeActiveControl.event; + private readonly _onDidScroll = this._register(new Emitter()); + /** The list scrolled or its topmost file changed. */ + readonly onDidScroll = this._onDidScroll.event; + private readonly diffContainer: HTMLElement; + + private readonly root: HTMLElement; + private readonly splitView: SplitView; + private readonly changedFilesTree: ReviewChangedFilesTree | undefined; + private readonly widget: MultiDiffEditorWidget; + private viewModel: MultiDiffEditorViewModel | undefined; + private input: ReviewFilesEditorInput | undefined; + private readonly readyFiles = new Set(); + private readonly fileStates = new Map(); + /** Full structural counts for views without persisted coverage. */ + private readonly streamStats = new Map< + string, + { counts: StructuralLineCounts; title: string } + >(); + private readonly headerFactory: ReviewMultiDiffUIElementFactory; + private readonly summary: HTMLElement; + /** Files the stream says start hidden, with the reason shown in their header. */ + private readonly hiddenFiles = new Map(); + private readonly hiddenApplied = new Set(); + private pendingPath: string | undefined; + private pendingSectionId: string | undefined; + private pendingSource: ReviewDiffLens["ranges"][number] | undefined; + private progress: ReviewDiffProgress | undefined; + private documentCollapsed = false; + private readonly initializedDocumentItems = new WeakSet(); + private readonly viewedApplied = new Map(); + private readonly streamStatus: HTMLElement; + + constructor( + private readonly container: HTMLElement, + overflowWidgetsDomNode: HTMLElement | undefined, + layout: ReviewDiffLayoutSetting, + private readonly fileTreeContainer: HTMLElement | undefined, + private readonly onToggleViewed: ((path: string, sectionId?: string) => void) | undefined, + private readonly onToggleSection: ((id: string) => void) | undefined, + private readonly document: ReviewDiffViewSpec["document"], + @IInstantiationService + private readonly reviewInstantiationService: IInstantiationService, + @IEditorService private readonly editorService: IEditorService, + @IEditorGroupsService + private readonly editorGroupService: IEditorGroupsService, + ) { + super(); + this.root = append(container, $(".review-files-editor")); + const fileTree = document ? container.ownerDocument.createElement("div") : append(this.fileTreeContainer ?? this.root, $(".review-files-editor-tree")); + const diffContainer = append(this.root, $(".review-files-editor-diffs")); + this.diffContainer = diffContainer; + if (document) fileTree.hidden = true; + + const factory = this.reviewInstantiationService.createInstance( + ReviewMultiDiffUIElementFactory, + () => + this.input + ? this.input.entries.map((entry) => ({ + original: entry.original, + modified: entry.modified, + additions: entry.file.status === "unchanged" ? undefined : this.entryProgress(entry)?.remaining.additions ?? (this.fileTreeContainer || this.document ? undefined : this.streamStats.get(entry.file.path)?.counts.added), + deletions: entry.file.status === "unchanged" ? undefined : this.entryProgress(entry)?.remaining.deletions ?? (this.fileTreeContainer || this.document ? undefined : this.streamStats.get(entry.file.path)?.counts.removed), + countsTitle: this.progressTitle(entry) ?? this.streamStats.get(entry.file.path)?.title, + viewedState: this.entryProgress(entry)?.state, + onToggleViewed: entry.file.status !== "unchanged" && this.onToggleViewed ? () => this.onToggleViewed!(entry.file.path, entry.sectionId) : undefined, + sectionId: entry.sectionId, + sectionCollapsed: !!entry.sectionId && this.collapsedSections.has(entry.sectionId), + onToggleSectionCollapsed: () => { if (entry.sectionId) { if (this.collapsedSections.has(entry.sectionId)) this.collapsedSections.delete(entry.sectionId); else this.collapsedSections.add(entry.sectionId); this.headerFactory.refreshHeaders(); } }, + section: entry.sectionStart ? this.progress?.sections?.find(section => section.id === entry.sectionId) : undefined, + onToggleSection: () => entry.sectionId && this.onToggleSection?.(entry.sectionId), + note: entry.file.status === "unchanged" ? "Unchanged" : this.hiddenFiles.get(entry.file.path), + onDidOpen: () => { + if (document?.onDidOpen) { document.onDidOpen(); return; } + void this.editorService.openEditor( + { + resource: entry.goToFileResource, + options: { pinned: true, revealIfVisible: true }, + }, + this.editorGroupService.mainPart.activeGroup, + ); + }, + })) + : [], + "auto", + // Hover and definition widgets must escape the canvas root, whose + // container-query containment clips position: fixed descendants. + overflowWidgetsDomNode, + false, + undefined, + ); + this.headerFactory = factory; + + this.widget = this._register( + this.reviewInstantiationService.createInstance(MultiDiffEditorWidget, diffContainer, factory, undefined), + ); + // The widget's own switch, not the per-item option refresh: it pins the + // width heuristic off, so the chosen layout is what renders at any width. + const applyLayout = () => this.widget.setRenderSideBySide(!document && layout.get() === "split"); + this._register(layout.onDidChange(applyLayout)); + applyLayout(); + if (document) { + this._register(this.widget.onDidChangeContentHeight(() => { + const height = Math.max(40, this.widget.getContentHeight()); + document.onDidChangeHeight(document.heightMode === "capped" ? Math.min(400, height) : height); + })); + } + this.streamStatus = append(diffContainer, + $(".review-structural-stream-status")); + this.streamStatus.setAttribute("role", "status"); + this.streamStatus.hidden = true; + this._register(this.widget.onDidChangeActiveControl(() => this._onDidChangeActiveControl.fire())); + this._register(this.widget.onDidScroll(() => this._onDidScroll.fire())); + this._register(this.widget.onDidChangeActiveItem(() => this.syncFileSelectionFromWidget())); + this.summary = append(fileTree, $(".review-files-editor-summary")); + this.summary.hidden = true; + this.changedFilesTree = document ? undefined : this._register( + this.reviewInstantiationService.createInstance(ReviewChangedFilesTree, fileTree), + ); + if (this.changedFilesTree) this._register( + this.changedFilesTree.onDidOpenFile((file) => { + const element = this.input?.entries.find((entry) => entry.file.path === file.path); + if (!element) return; + if (this.fileStates.has(file.path)) { + this.pendingPath = file.path; + this.showStreamStatus(); + return; + } + this.pendingPath = undefined; + this.showStreamStatus(); + this.reveal({ + original: element.original, + modified: element.modified, + }); + }), + ); + this.splitView = this._register( + new SplitView(this.root, { + orientation: Orientation.HORIZONTAL, + proportionalLayout: true, + }), + ); + if (!this.fileTreeContainer && !document) this.splitView.addView( + { + element: fileTree, + layout: (width, _offset, height) => { + fileTree.style.width = `${width}px`; + this.changedFilesTree?.layout((height ?? 0) - + (this.summary.hidden ? 0 : this.summary.offsetHeight), width, + ); + }, + maximumSize: 380, + minimumSize: FILE_TREE_MINIMUM_WIDTH, + onDidChange: Event.None, + }, + 260, + ); + this.splitView.addView( + { + element: diffContainer, + layout: (width, _offset, height) => { + diffContainer.style.width = `${width}px`; + this.widget.layout(new Dimension(width, height ?? 0)); + }, + maximumSize: Number.POSITIVE_INFINITY, + minimumSize: DIFF_MINIMUM_WIDTH, + onDidChange: Event.None, + }, + 740, + ); + + if (this.fileTreeContainer) { + const treeSize = this._register(new ElementSizeObserver(this.fileTreeContainer, undefined)); + this._register(treeSize.onDidChange(() => this.layout())); + treeSize.startObserving(); + this._register(toDisposable(() => fileTree.remove())); + } + const sizeObserver = this._register(new ElementSizeObserver(this.container, undefined)); + this._register(sizeObserver.onDidChange(() => this.layout())); + sizeObserver.startObserving(); + this.layout(); + // Registered last so it runs last: the widgets above tear their own DOM + // down, and they must do that while the tree is still attached. + this._register(toDisposable(() => this.root.remove())); + } + + async setInput(input: ReviewFilesEditorInput, viewState: IMultiDiffEditorViewState | undefined): Promise { + this.input = input; + this.changedFilesTree?.setFiles(Array.from(new Map(input.entries.map(entry => [entry.file.path, entry.file])).values())); + const viewModel = await input.getViewModel(); + if (this._store.isDisposed) return; + this.viewModel = viewModel; + // The canvas mounts this view without a user gesture, so the widget's + // first-change navigation must never take keyboard focus. + this.widget.setViewModel(viewModel, { preserveFocus: true, viewState, initialScrollPosition: this.document ? "top" : "firstChange" }); + this.changedFilesTree?.setFiles(Array.from(new Map(input.entries.map(entry => [entry.file.path, entry.file])).values())); + this.syncFileSelectionFromWidget(); + this._register( + autorun((reader) => { + const items = viewModel.items.read(reader); + if (this.document) for (const item of items) { + if (this.initializedDocumentItems.has(item)) continue; + this.initializedDocumentItems.add(item); + item.collapsed.set(this.documentCollapsed, undefined); + } + this.applyHiddenFiles(items); + this.applyViewedFiles(); + const entry = this.input?.entries.find( + (e) => e.file.path === this.pendingPath, + ); + if (!entry || !this.readyFiles.has(entry.file.path)) return; + if ( + !items.some( + (item) => + sameResource(item.originalUri, entry.original) && + sameResource(item.modifiedUri, entry.modified), + ) + ) + return; + this.pendingPath = undefined; + this.showStreamStatus(); + queueMicrotask(() => { + if (!this._store.isDisposed) { if (this.pendingSource) this.revealSource(this.pendingSource, this.pendingSectionId); else this.reveal(entry); } + }); + }), + ); + } + + startLoading(entries: readonly ReviewFilesEditorEntry[]): void { + this.changedFilesTree?.setFiles(Array.from(new Map(entries.map(entry => [entry.file.path, entry.file])).values())); + for (const entry of entries) { + this.fileStates.set(entry.file.path, "Loading diff…"); + this.changedFilesTree?.setFileState(entry.file.path, "loading"); + } + this.showStreamStatus(); + } + + fileLoaded( + path: string, + error?: string, + ): void { + if (error) { + this.fileStates.set(path, error); + this.changedFilesTree?.setFileState(path, "error", error); + } else { + this.fileStates.delete(path); + this.readyFiles.add(path); + this.changedFilesTree?.setFileState(path, undefined); + } + this.input?.setReadyFiles(this.readyFiles, [...this.fileStates.values()].some(state => state === "Loading diff…")); + this.showStreamStatus(); + } + + /** Coverage counts are independent of fold state. */ + fileCounts(path: string, counts: StructuralLineCounts): void { + this.streamStats.set(path, { + counts, + title: `Changes +${counts.added} −${counts.removed}`, + }); + if (!this.fileTreeContainer) this.changedFilesTree?.setCounts(path, counts); + this.headerFactory.refreshHeaders(); + this.renderSummary(); + } + + private renderSummary(): void { + if (this.fileTreeContainer) return; + const paths = new Set((this.input?.entries ?? []).map(entry => entry.file.path)); + const complete = [...paths].every(path => this.streamStats.has(path)); + const total = { added: 0, removed: 0 }; + for (const path of paths) { + const counts = this.streamStats.get(path)?.counts; + if (counts) { total.added += counts.added; total.removed += counts.removed; } + } + this.summary.replaceChildren(); + const files = append(this.summary, $("span.review-files-editor-summary-files")); + files.textContent = `${paths.size} files`; + if (complete) { + const format = new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }); + append(this.summary, $("span.review-files-editor-summary-added")).textContent = `+${format.format(total.added).toLowerCase()}`; + append(this.summary, $("span.review-files-editor-summary-removed")).textContent = `−${format.format(total.removed).toLowerCase()}`; + } else append(this.summary, $("span")).textContent = "Counting changes…"; + this.summary.title = complete ? `Changes +${total.added} −${total.removed}` : "Waiting for structural coverage"; + const wasHidden = this.summary.hidden; + this.summary.hidden = false; + if (wasHidden) this.layout(); + } + + /** A file the stream says starts collapsed, and why: its record's `visibility`. */ + hideFile(path: string, label: string): void { + this.hiddenFiles.set(path, label); + this.headerFactory.refreshHeaders(); + if (this.viewModel) this.applyHiddenFiles(this.viewModel.items.get()); + } + + /** GitHub's shape for a hidden file: the header stays, the body waits for a click. */ + private applyHiddenFiles( + items: readonly { + originalUri: URI | undefined; + modifiedUri: URI | undefined; + collapsed: { set(value: boolean, tx: undefined): void }; + }[], + ): void { + for (const entry of this.input?.entries ?? []) { + if ( + !this.hiddenFiles.has(entry.file.path) || + this.hiddenApplied.has(entry.file.path) + ) + continue; + const item = items.find( + (item) => + sameResource(item.originalUri, entry.original) && + sameResource(item.modifiedUri, entry.modified), + ); + if (!item) continue; + item.collapsed.set(true, undefined); + this.hiddenApplied.add(entry.file.path); + } + } + + private readonly collapsedSections = new Set(); + private readonly sectionViewed = new Map(); + private entryProgress(entry: ReviewFilesEditorEntry) { + return (entry.sectionId ? this.progress?.sections?.find(section => section.id === entry.sectionId)?.files : this.progress?.files)?.find(file => file.path === entry.file.path); + } + private progressTitle(entry: ReviewFilesEditorEntry): string | undefined { + const file = this.entryProgress(entry); + return file ? `Remaining +${file.remaining.additions} −${file.remaining.deletions} · Total +${file.total.additions} −${file.total.deletions}` : undefined; + } + setProgress(progress: ReviewDiffProgress): void { + this.progress = progress; + for (const section of progress.sections ?? []) { + const previous = this.sectionViewed.get(section.id); + if (section.state === 'viewed' && previous !== 'viewed') this.collapsedSections.add(section.id); + else if (previous === 'viewed' && section.state !== 'viewed') this.collapsedSections.delete(section.id); + this.sectionViewed.set(section.id, section.state); + } + + this.changedFilesTree?.setProgressFiles(progress.files); + this.headerFactory.refreshHeaders(); + this.applyViewedFiles(); + } + private applyViewedFiles(): void { + for (const entry of this.input?.entries ?? []) { + const file = this.entryProgress(entry); + if (!file) continue; + const key = `${entry.sectionId ?? ''}:${file.path}`; + const previous = this.viewedApplied.get(key); + if (previous === file.state) continue; + const item = this.viewModel?.items.get().find(item => sameResource(item.originalUri, entry.original) && sameResource(item.modifiedUri, entry.modified)); + if (!item) continue; + if (file.state === 'viewed') item.collapsed.set(true, undefined); + else if (previous === 'viewed' || this.progress?.changedPaths?.includes(file.path)) item.collapsed.set(false, undefined); + this.viewedApplied.set(key, file.state); + } + } + revealSource(source: ReviewDiffLens['ranges'][number], sectionId?: string): void { + const entry = this.input?.entries.find(entry => (!sectionId || entry.sectionId === sectionId) && (!entry.sectionId || this.progress?.sections?.find(section => section.id === entry.sectionId)?.sources.some(range => range.file === source.file && range.side === source.side && range.fromLine <= source.fromLine && range.toLine >= source.fromLine)) && source.file === (source.side === 'base' ? entry.file.previousPath ?? entry.file.path : entry.file.path)); + if (!entry) return; + if (entry.sectionId && this.collapsedSections.delete(entry.sectionId)) this.headerFactory.refreshHeaders(); + this.pendingSource = source; this.pendingSectionId = sectionId; + if (this.fileStates.has(entry.file.path)) { this.pendingPath = entry.file.path; return; } + this.viewModel?.items.get().find(item => sameResource(item.originalUri, entry.original) && sameResource(item.modifiedUri, entry.modified))?.collapsed.set(false, undefined); + this.widget.reveal(entry, { highlight: true, side: source.side === 'base' ? 'original' : 'modified', range: new Range(source.fromLine, 1, source.toLine, 1) }); + this.pendingSource = undefined; + } + + get viewportHeight(): number { return this.diffContainer.clientHeight; } + + /** + * Pixels from the reading line (the list's top edge) to the first line of + * `source`, negative once scrolled past. Rendered files measure their + * editor; the rest are placed by file order around the topmost file, a + * million pixels per file, which keeps them sorted and on the right side. + */ + sourceOffset(source: ReviewDiffLens['ranges'][number]): number | undefined { + const entries = this.input?.entries ?? []; + const pathOf = (entry: (typeof entries)[number]) => source.side === 'base' ? entry.file.previousPath ?? entry.file.path : entry.file.path; + const index = entries.findIndex(entry => pathOf(entry) === source.file); + if (index < 0) return undefined; + const entry = entries[index]!; + const resource = source.side === 'base' ? entry.original : entry.modified; + const editor = resource && this.widget.tryGetCodeEditor(resource)?.editor; + const node = editor?.getDomNode(); + if (editor && node) { + return node.getBoundingClientRect().top - this.diffContainer.getBoundingClientRect().top + + editor.getTopForLineNumber(source.fromLine) - editor.getScrollTop(); + } + const active = this.viewModel?.activeDiffItem.get(); + const activeIndex = active ? entries.findIndex(e => sameResource(active.modifiedUri, e.modified) && sameResource(active.originalUri, e.original)) : 0; + return (index - Math.max(0, activeIndex)) * 1_000_000 + source.fromLine; + } + + loadingFailed(message: string): void { + for (const [path, state] of this.fileStates) + if (state === "Loading diff…") this.fileLoaded(path, message); + this.showStreamStatus(); + } + + private showStreamStatus(): void { + const message = this.pendingPath + ? this.fileStates.get(this.pendingPath) + : undefined; + this.streamStatus.hidden = + (!message && this.readyFiles.size > 0) || this.fileStates.size === 0; + this.streamStatus.textContent = message + ? `${this.pendingPath}: ${message}` + : this.readyFiles.size === 0 + ? ([...this.fileStates.values()][0] ?? "") + : ""; + this.streamStatus.classList.toggle( + "loading", + [...this.fileStates.values()].some((s) => s === "Loading diff…"), + ); + } + + getViewState(): IMultiDiffEditorViewState | undefined { + return this.viewModel ? this.widget.getViewState() : undefined; + } + + getActiveControl(): IDiffEditor | undefined { + return this.widget.getActiveControl(); + } + + setCollapsed(collapsed: boolean): void { + this.documentCollapsed = collapsed; + for (const item of this.viewModel?.items.get() ?? []) item.collapsed.set(collapsed, undefined); + } + + focus(): void { + this.widget.getActiveControl()?.focus(); + } + + layout(): void { + const width = this.container.clientWidth; + const height = this.container.clientHeight; + if (width <= 0 || height <= 0) return; + + const fileTreeVisible = !this.fileTreeContainer && width >= FILE_TREE_COLLAPSE_WIDTH; + if (!this.fileTreeContainer && !this.document && this.splitView.isViewVisible(0) !== fileTreeVisible) { + this.splitView.setViewVisible(0, fileTreeVisible); + } + + this.splitView.layout(width, height); + if (this.fileTreeContainer) this.changedFilesTree?.layout(this.fileTreeContainer.clientHeight, this.fileTreeContainer.clientWidth); + } + private reveal(resource: { original: URI | undefined; modified: URI | undefined }): void { + this.widget.reveal(resource, { highlight: true }); + } + + private syncFileSelectionFromWidget(): void { + const resource = this.widget.getActiveItem(); + const input = this.input; + if (!resource || !input || this.pendingPath) return; + const index = input.entries.findIndex( + (entry) => sameResource(entry.original, resource.original) && sameResource(entry.modified, resource.modified), + ); + if (index === -1) return; + // Passive editor updates must not move a sidebar the reader scrolled independently. + this.changedFilesTree?.setActiveFile(input.entries[index].file.path, false); + } +} +function sameResource(left: URI | undefined, right: URI | undefined): boolean { + return left === undefined ? right === undefined : !!right && isEqual(left, right); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLanguageEnvironmentRequests.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLanguageEnvironmentRequests.test.ts new file mode 100644 index 000000000..d72864091 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLanguageEnvironmentRequests.test.ts @@ -0,0 +1,80 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { ReviewLanguageEnvironmentRequests } from "./reviewLanguageEnvironmentRequests.js"; +import { withCurrentLocalContext } from "./reviewLocalRequest.js"; + +const view = { reviewId: "review", version: 3 }; +const ready = { rootPath: "/project", identity: "first" }; +function deferred() { + let resolve!: (value: T) => void; + const promise = new Promise(done => { resolve = done; }); + return { promise, resolve }; +} + +test("simultaneous providers share one environment lookup across source refresh tokens", async () => { + const requests = new ReviewLanguageEnvironmentRequests(); + const response = deferred(); + let count = 0; + const load = () => { count++; return response.promise; }; + const wave = Array.from({ length: 20 }, (_, index) => requests.read("session", { ...view, generation: String(index) }, "head", load)); + await Promise.resolve(); + assert.equal(count, 1); + response.resolve(ready); + assert.deepEqual(await Promise.all(wave), Array(20).fill(ready)); + await requests.read("session", view, "head", load); + assert.equal(count, 2, "completed lookups are revalidated until lifecycle events are authoritative"); +}); + +test("a post-query check never joins an HTTP request that started before the provider finished", async () => { + const requests = new ReviewLanguageEnvironmentRequests(); + const first = deferred(); + const next = deferred(); + let count = 0; + const load = () => ++count === 1 ? first.promise : next.promise; + const before = requests.read("session", view, "head", load); + await Promise.resolve(); + const validations = Array.from({ length: 10 }, () => requests.read("session", view, "head", load, true)); + await Promise.resolve(); + assert.equal(count, 2); + first.resolve(ready); + assert.deepEqual(await before, ready); + next.resolve({ ...ready, identity: "replaced" }); + assert.ok((await Promise.all(validations)).every(result => result?.identity === "replaced")); +}); + +test("sessions, authored versions, sides and selected commits never share lookups", async () => { + const requests = new ReviewLanguageEnvironmentRequests(); + let count = 0; + const load = async () => ({ ...ready, identity: String(++count) }); + const results = await Promise.all([ + requests.read("one", view, "head", load), + requests.read("two", view, "head", load), + requests.read("one", { ...view, version: 4 }, "head", load), + requests.read("one", view, "base", load), + requests.read("one", { ...view, commit: "selected" }, "head", load), + requests.read("one", { ...view, reviewId: "other" }, "head", load), + ]); + assert.equal(new Set(results.map(result => result?.identity)).size, 6); +}); + +test("unavailable and failed lookups recover on the next query", async () => { + const requests = new ReviewLanguageEnvironmentRequests(); + assert.equal(await requests.read("session", view, "head", async () => undefined), undefined); + await assert.rejects(requests.read("session", view, "head", async () => { throw new Error("offline"); }), /offline/); + assert.deepEqual(await requests.read("session", view, "head", async () => ready), ready); +}); + +test("disconnect discards a pending response and a delayed provider even when identity is unchanged", async () => { + const requests = new ReviewLanguageEnvironmentRequests(); + const response = deferred(); + const pending = requests.read("session", view, "head", () => response.promise); + await Promise.resolve(); + const provider = deferred(); + const result = withCurrentLocalContext([{ getVersionId: () => 1, isDisposed: () => false }], { isCancellationRequested: false }, () => requests.generation, () => provider.promise); + requests.invalidate(); + response.resolve(ready); + provider.resolve("stale hover"); + assert.equal(await pending, undefined); + assert.equal(await result, undefined); + assert.deepEqual(await requests.read("session", view, "head", async () => ready), ready); +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLanguageEnvironmentRequests.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLanguageEnvironmentRequests.ts new file mode 100644 index 000000000..c6b8ce632 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLanguageEnvironmentRequests.ts @@ -0,0 +1,35 @@ +import type { ReviewLanguageEnvironment, ReviewSourceView } from "../common/reviewProtocol.js"; + +/** In-flight reuse only: the event channel does not yet order environment changes. */ +export class ReviewLanguageEnvironmentRequests { + private readonly pending = new Map }>(); + private epoch = 0; + + get generation(): number { return this.epoch; } + + invalidate(): void { + this.epoch++; + this.pending.clear(); + } + + read(session: string, view: ReviewSourceView, side: string, load: () => Promise, validate = false): Promise { + // Source generations separate display models, not language environments. + const key = JSON.stringify([session, view.reviewId, view.version, side, view.commit]); + const cached = this.pending.get(key); + // Post-provider validation must start AFTER that provider finished. A queued + // request can coalesce a wave of validations; an already-started one cannot. + if (cached && (!validate || !cached.started)) return cached.promise; + const epoch = this.epoch; + const entry = { started: false, promise: undefined! as Promise }; + entry.promise = Promise.resolve().then(async () => { + entry.started = true; + if (epoch !== this.epoch) return undefined; + const result = await load(); + return epoch === this.epoch ? result : undefined; + }).finally(() => { + if (this.pending.get(key) === entry) this.pending.delete(key); + }); + this.pending.set(key, entry); + return entry.promise; + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLens.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLens.ts new file mode 100644 index 000000000..8cc8a33d2 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLens.ts @@ -0,0 +1,68 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ +import { isDisposable, type DisposableStore } from '../../base/common/lifecycle.js'; +import { IDiffProviderFactoryService } from '../../editor/browser/widget/diffEditor/diffProviderFactoryService.js'; +import { IInstantiationService } from '../../platform/instantiation/common/instantiation.js'; +import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; +import { Event } from '../../base/common/event.js'; +import { alignmentRows, lensContextGaps, viewedContextGaps } from '../common/reviewLens.js'; +import type { ReviewDiffLens, ReviewDiffProgress } from '../common/reviewProtocol.js'; +import type { ReviewFilesEditorEntry } from './reviewFilesDiffView.js'; + +export function lensRanges(lens: ReviewDiffLens, entry: ReviewFilesEditorEntry): ReviewDiffLens['ranges'] { + return lens.ranges.filter(range => range.file === (range.side === 'base' ? entry.file.previousPath ?? entry.file.path : entry.file.path)); +} + +export function withLens(instantiation: IInstantiationService, entries: readonly ReviewFilesEditorEntry[], lens: ReviewDiffLens | undefined, lifetime: DisposableStore, progress: () => ReviewDiffProgress | undefined, onProgress: Event): IInstantiationService { + const delegate = instantiation.invokeFunction(a => a.get(IDiffProviderFactoryService)); + const factory: IDiffProviderFactoryService = { + _serviceBrand: undefined, + createDiffProvider(options) { + const provider = delegate.createDiffProvider(options); + if (isDisposable(provider)) lifetime.add(provider); + let activeEntry: ReviewFilesEditorEntry | undefined; + let previousScope: string | undefined; + const scope = () => { + if (!activeEntry) return undefined; + const snapshot = progress(); + const file = snapshot?.files.find(file => file.path === activeEntry!.file.path); + const section = snapshot?.sections?.find(section => section.id === activeEntry!.sectionId); + return JSON.stringify([file?.viewedRanges, file?.changedRanges, file?.unfoldRanges, section?.sources]); + }; + const relevantProgress = Event.filter(onProgress, () => { + const next = scope(); + if (next === previousScope) return false; + previousScope = next; + return true; + }); + return { + onDidChange: Event.any(provider.onDidChange, Event.debounce(relevantProgress, () => undefined, 16)), + async computeDiff(original, modified, options, token) { + let diff = await provider.computeDiff(original, modified, options, token); + const entry = entries.find(entry => entry.original?.toString() === original.uri.toString() || entry.modified?.toString() === modified.uri.toString()); + if (!entry) return diff; + activeEntry = entry; + previousScope = scope(); + // Both filtering and layout must use the same correspondence. Without diffr, + // project Monaco's existing mappings once; do not run a second matching algorithm. + if (!diff.sourceLineAlignment) diff = { ...diff, sourceLineAlignment: alignmentRows(diff, original.getLineCount(), modified.getLineCount()) }; + const file = progress()?.files.find(file => file.path === entry.file.path); + if (file && (!lens || lens.wholeFiles) && !diff.contextGaps) diff = { ...diff, contextGaps: lensContextGaps(diff, original.getLineCount(), modified.getLineCount(), file.changedRanges).map(gap => ({ ...gap, label: 'Unchanged' })) }; + if (file) diff = { ...diff, contextGaps: viewedContextGaps(diff, original.getLineCount(), modified.getLineCount(), file.viewedRanges, file.changedRanges) }; + if (file?.unfoldRanges?.length) diff = { + ...diff, contextGaps: diff.contextGaps?.map(gap => file.unfoldRanges!.some(range => { + const start = range.side === 'base' ? gap.originalStart : gap.modifiedStart; + const count = range.side === 'base' ? gap.originalCount : gap.modifiedCount; + return count > 0 && range.fromLine < start + count && range.toLine >= start; + }) ? { ...gap, collapsed: false } : gap) + }; + const section = progress()?.sections?.find(section => section.id === entry.sectionId); + return lens && !lens.wholeFiles ? { ...diff, contextGaps: lensContextGaps(diff, original.getLineCount(), modified.getLineCount(), lensRanges(section ? { ...lens, ranges: section.sources } : lens, entry)) } : diff; + }, + }; + }, + }; + return lifetime.add(instantiation.createChild(new ServiceCollection([IDiffProviderFactoryService, factory]))); +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLensProgress.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLensProgress.test.ts new file mode 100644 index 000000000..22d19b7e8 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLensProgress.test.ts @@ -0,0 +1,68 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { Emitter } from '../../base/common/event.js'; +import { DisposableStore } from '../../base/common/lifecycle.js'; +import { URI } from '../../base/common/uri.js'; +import { CancellationToken } from '../../base/common/cancellation.js'; +import type { IDiffProviderFactoryService } from '../../editor/browser/widget/diffEditor/diffProviderFactoryService.js'; +import { IDiffProviderFactoryService as Factory } from '../../editor/browser/widget/diffEditor/diffProviderFactoryService.js'; +import type { IInstantiationService } from '../../platform/instantiation/common/instantiation.js'; +import type { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; +import type { ReviewDiffProgress } from '../common/reviewProtocol.js'; +import type { ReviewFilesEditorEntry } from './reviewFilesDiffView.js'; +import { withLens } from './reviewLens.js'; + +test('progress invalidates only relevant file ranges and coalesces a burst', async () => { + const store = new DisposableStore(); + const progressChanged = store.add(new Emitter()); + const providerChanged = store.add(new Emitter()); + let factory!: IDiffProviderFactoryService; + const instantiation = { + invokeFunction: (fn: (accessor: { get(): unknown }) => unknown) => fn({ + get: () => ({ + createDiffProvider: () => ({ + onDidChange: providerChanged.event, computeDiff: async () => ({ + changes: [], moves: [], identical: true, quitEarly: false, sourceLineAlignment: [[0, 0]], contextGaps: [], + }) + }), + }) + }), + createChild: (services: ServiceCollection) => { + factory = services.get(Factory) as IDiffProviderFactoryService; + return { dispose() { } }; + }, + } as unknown as IInstantiationService; + const file = (path: string) => ({ + path, state: 'unread' as const, remaining: { additions: 1, deletions: 0 }, + total: { additions: 1, deletions: 0 }, viewedRanges: [], changedRanges: [], + }); + let progress: ReviewDiffProgress = { files: [file('a.ts'), file('b.ts')] }; + const original = URI.parse('test:/base/a.ts'), modified = URI.parse('test:/head/a.ts'); + const entry = { original, modified, file: { path: 'a.ts' } } as ReviewFilesEditorEntry; + withLens(instantiation, [entry], undefined, store, () => progress, progressChanged.event); + const provider = factory.createDiffProvider({}); + try { + await provider.computeDiff( + { uri: original, getLineCount: () => 1 } as Parameters[0], + { uri: modified, getLineCount: () => 1 } as Parameters[1], + { ignoreTrimWhitespace: false, maxComputationTimeMs: 0, computeMoves: false }, CancellationToken.None, + ); + let invalidations = 0; + store.add(provider.onDidChange(() => invalidations++)); + progress = { files: [file('a.ts'), { ...file('b.ts'), viewedRanges: [{ side: 'head', file: 'b.ts', fromLine: 1, toLine: 1 }] }] }; + progressChanged.fire(); + progress.files[0].remaining.additions = 0; + progressChanged.fire(); + await new Promise(resolve => setTimeout(resolve, 30)); + assert.equal(invalidations, 0, 'other files and counts do not alter this editor’s ranges'); + const notified = new Promise(resolve => { + const sub = provider.onDidChange(() => { sub.dispose(); resolve(); }); + }); + for (const toLine of [1, 2, 3]) { + progress.files[0].viewedRanges = [{ side: 'head', file: 'a.ts', fromLine: 1, toLine }]; + progressChanged.fire(); + } + await notified; + assert.equal(invalidations, 1); + } finally { store.dispose(); } +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalLanguageFeatures.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalLanguageFeatures.ts new file mode 100644 index 000000000..7f23a1cf3 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalLanguageFeatures.ts @@ -0,0 +1,281 @@ +import type { CancellationToken } from "../../base/common/cancellation.js"; +import { Disposable, DisposableStore, type IReference } from "../../base/common/lifecycle.js"; +import { URI } from "../../base/common/uri.js"; +import { Position } from "../../editor/common/core/position.js"; +import type { Hover, LocationLink } from "../../editor/common/languages.js"; +import type { ITextModel } from "../../editor/common/model.js"; +import { ILanguageFeaturesService } from "../../editor/common/services/languageFeatures.js"; +import { IModelService } from "../../editor/common/services/model.js"; +import { ITextModelService, type IResolvedTextEditorModel } from "../../editor/common/services/resolverService.js"; +import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from "../../editor/contrib/gotoSymbol/browser/goToSymbol.js"; +import { getHoversPromise } from "../../editor/contrib/hover/browser/getHover.js"; +import { IFileService } from "../../platform/files/common/files.js"; +import { ILogService } from "../../platform/log/common/log.js"; +import { registerWorkbenchContribution2, WorkbenchPhase } from "../../workbench/common/contributions.js"; +import { IExtensionService } from "../../workbench/services/extensions/common/extensions.js"; +import { ITextFileService } from "../../workbench/services/textfile/common/textfiles.js"; +import { IWorkspaceEditingService } from "../../workbench/services/workspaces/common/workspaceEditing.js"; +import { reviewSourceQuery, type ReviewLanguageEnvironment } from "../common/reviewProtocol.js"; +import { sourceLocation } from "../common/reviewSourceView.js"; +import { REVIEW_LANGUAGE_SOURCE_SCHEME } from "../common/reviewReadonlySource.js"; +import { REVIEW_API_SOURCE_SCHEME } from "./reviewApiSourceService.js"; +import { IReviewDesktopConnectionService } from "./reviewDesktopConnectionService.js"; +import { withCurrentLocalContext } from "./reviewLocalRequest.js"; +import { acquireReviewLanguageRoot } from "./reviewLocalWorkspace.js"; +import { ReviewLanguageEnvironmentRequests } from "./reviewLanguageEnvironmentRequests.js"; + +interface LocalSource { + identity: string; + root: URI; + reference: IReference; + dispose(): void; +} + +/** Review bytes remain pinned; language queries use the resolved project environment. */ +export class ReviewLocalLanguageFeatures extends Disposable { + static readonly ID = "review.localLanguageFeatures"; + private readonly sources = new Map }>(); + private readonly environments = new ReviewLanguageEnvironmentRequests(); + private readonly roots = new Map(); + private readonly uncertainRoots = new Set(); + private generation = 0; + + constructor( + @IReviewDesktopConnectionService private readonly connection: IReviewDesktopConnectionService, + @ITextModelService private readonly models: ITextModelService, + @IModelService modelService: IModelService, + @ILanguageFeaturesService private readonly languages: ILanguageFeaturesService, + @IExtensionService private readonly extensions: IExtensionService, + @IWorkspaceEditingService private readonly workspace: IWorkspaceEditingService, + @ITextFileService private readonly textFiles: ITextFileService, + @IFileService private readonly files: IFileService, + @ILogService private readonly log: ILogService, + ) { + super(); + this._register(connection.onDidChangeConnection(() => { + this.environments.invalidate(); + this.generation++; + for (const entry of this.sources.values()) { + this.uncertainRoots.add(URI.file(entry.rootPath).toString()); + void entry.pending.then(source => source?.dispose()); + } + this.sources.clear(); + })); + this._register(files.onDidFilesChange(event => { + if ([...this.roots.keys()].some(root => event.affects(URI.parse(root)))) this.generation++; + })); + // Warm language servers while source is being displayed, not at the first click. + const warm = (model: ITextModel) => { + if ([REVIEW_API_SOURCE_SCHEME, REVIEW_LANGUAGE_SOURCE_SCHEME].includes(model.uri.scheme)) void this.localSource(model); + }; + this._register(modelService.onModelAdded(warm)); + modelService.getModels().forEach(warm); + for (const scheme of [REVIEW_API_SOURCE_SCHEME, REVIEW_LANGUAGE_SOURCE_SCHEME]) { + const selector = { scheme, exclusive: true }; + this._register(languages.hoverProvider.register(selector, { provideHover: (model, position, token) => this.hover(model, position, token) })); + this._register(languages.definitionProvider.register(selector, { provideDefinition: (model, position, token) => this.locations(model, position, token, "definition") })); + } + // Unified hover/definition already delegate to the pinned side model. + for (const scheme of [REVIEW_API_SOURCE_SCHEME, REVIEW_LANGUAGE_SOURCE_SCHEME]) { + const target = { scheme, exclusive: true }; + this._register(languages.typeDefinitionProvider.register(target, { provideTypeDefinition: (model, position, token) => this.locations(model, position, token, "type") })); + this._register(languages.implementationProvider.register(target, { provideImplementation: (model, position, token) => this.locations(model, position, token, "implementation") })); + this._register(languages.referenceProvider.register(target, { + provideReferences: (model, position, context, token) => this.withSource(model, position, token, async (local, at, pinned) => { + const results = await Promise.all(languages.referenceProvider.ordered(local).map(provider => provider.provideReferences(local, at, context, token))); + return this.reviewLocations(pinned, results.flatMap(result => result ?? []), token); + }), + })); + } + } + + private async environment(model: ITextModel, validate = false): Promise { + const { serverUrl, token } = await this.connection.getConnection(); + const target = sourceLocation(model.uri); + return this.environments.read(JSON.stringify([serverUrl, token]), target.view, target.side, async () => { + const params = new URLSearchParams({ side: target.side }); + for (const [key, value] of Object.entries(reviewSourceQuery(target.view))) { + if (value !== undefined) params.set(key, String(value)); + } + const response = await fetch(`${serverUrl}/reviews-api/${encodeURIComponent(model.uri.authority)}/language-context?${params}`, { + headers: { "x-review-token": token }, signal: AbortSignal.timeout(10_000), + }); + return response.ok ? response.json() : undefined; + }, validate); + } + + private async localSource(model: ITextModel): Promise { + if (new URLSearchParams(model.uri.query).has("empty")) return undefined; + try { + const epoch = this.environments.generation; + const context = await this.environment(model); + if (epoch !== this.environments.generation || model.isDisposed()) return undefined; + const cached = this.sources.get(model); + if (cached && cached.identity === context?.identity && cached.rootPath === context.rootPath) return cached.pending; + if (cached) { + this.uncertainRoots.add(URI.file(cached.rootPath).toString()); + void cached.pending.then(source => source?.dispose()); + this.sources.delete(model); + this.generation++; + } + if (!context?.rootPath) return undefined; + const pending = this.acquire(model, { rootPath: context.rootPath, identity: context.identity }).catch(error => { + this.log.debug("[Review] Language model unavailable", error); + return undefined; + }); + const entry = { identity: context.identity, rootPath: context.rootPath, pending }; + this.sources.set(model, entry); + const result = await pending; + if (this.sources.get(model) !== entry || epoch !== this.environments.generation) { result?.dispose(); return undefined; } + if (!result) this.sources.delete(model); + return result; + } catch (error) { + const cached = this.sources.get(model); + if (cached) this.uncertainRoots.add(URI.file(cached.rootPath).toString()); + this.log.debug("[Review] Language environment unavailable", error); + return undefined; + } + } + + private async acquire(model: ITextModel, context: { rootPath: string; identity: string }): Promise { + const root = URI.file(context.rootPath); + const relative = model.uri.path.slice(1); + if (!relative || relative.split(/[\\/]/).some(part => part === "..")) return undefined; + const resource = model.uri.scheme === REVIEW_LANGUAGE_SOURCE_SCHEME ? URI.file(model.uri.path) : URI.joinPath(root, relative); + if (!await this.files.exists(resource) || model.isDisposed()) return undefined; + const owned = new DisposableStore(); + try { + owned.add(await acquireReviewLanguageRoot(this.workspace, root)); + this.roots.set(root.toString(), (this.roots.get(root.toString()) ?? 0) + 1); + owned.add({ + dispose: () => { + const count = (this.roots.get(root.toString()) ?? 1) - 1; + if (count > 0) this.roots.set(root.toString(), count); + else this.roots.delete(root.toString()); + } + }); + const reference = owned.add(await this.models.createModelReference(resource)); + owned.add(reference.object.textEditorModel.onDidChangeContent(() => this.generation++)); + owned.add(model.onWillDispose(() => { this.sources.delete(model); owned.dispose(); })); + if (model.isDisposed()) { owned.dispose(); return undefined; } + await this.extensions.activateByEvent(`onLanguage:${reference.object.textEditorModel.getLanguageId()}`); + if (model.isDisposed()) { owned.dispose(); return undefined; } + return { root, reference, identity: context.identity, dispose: () => owned.dispose() }; + } catch (error) { owned.dispose(); throw error; } + } + + private async withSource(model: ITextModel, position: Position, token: CancellationToken, run: (local: ITextModel, at: Position, review: ITextModel) => Promise): Promise { + if (token.isCancellationRequested || model.isDisposed()) return undefined; + if (model.uri.scheme === "file") return withCurrentLocalContext([model], token, () => this.generation, async () => run(model, position, model)); + const epoch = this.environments.generation; + const source = await this.localSource(model); + if (!source || token.isCancellationRequested || model.isDisposed()) return undefined; + const local = source.reference.object.textEditorModel; + if (!await this.files.exists(local.uri)) { this.uncertainRoots.add(source.root.toString()); return undefined; } + if (this.uncertainRoots.has(source.root.toString())) { + // An open dependency can outlive a removed checkout and miss subsequent + // watcher updates. Until watcher readiness is authoritative, revalidate + // clean native buffers before querying; never replace a dirty buffer. + const prefix = source.root.path.replace(/\/$/, "") + "/"; + await Promise.all(this.textFiles.files.models.filter(file => !file.isDirty() && file.resource.scheme === "file" && file.resource.path.startsWith(prefix)) + .map(file => this.textFiles.files.resolve(file.resource, { reload: { async: false } }))); + } + // Resolve current disk contents, preserving any unsaved local editor buffer. + await this.textFiles.files.resolve(local.uri, { reload: { async: false } }); + return withCurrentLocalContext([model, local], token, () => this.generation, async () => { + // The language server must see exactly the source displayed in the review. + if (!model.equalsTextBuffer(local.getTextBuffer())) return undefined; + const result = await run(local, position, model); + const current = await this.environment(model, true).catch(() => undefined); + if (epoch === this.environments.generation && current?.rootPath === source.root.fsPath && current.identity === source.identity) return result; + // Failed validation must also release the old workspace/watchers. Keeping + // them after deletion can leave the language server blind to later edits. + const cached = this.sources.get(model); + if (cached?.identity === source.identity && cached.rootPath === source.root.fsPath) { + this.uncertainRoots.add(source.root.toString()); + this.sources.delete(model); + void cached.pending.then(value => value?.dispose()); + this.generation++; + } + return undefined; + }); + } + + private hover(model: ITextModel, position: Position, token: CancellationToken): Promise { + return this.withSource(model, position, token, async (local, at) => { + const hovers = await getHoversPromise(this.languages.hoverProvider, local, at, token); + if (!hovers.length) return undefined; + const range = hovers[0].range; + if (!range) return undefined; + return { range, contents: hovers.flatMap(hover => hover.contents) }; + }); + } + + private async locations(model: ITextModel, position: Position, token: CancellationToken, kind: "definition" | "type" | "implementation"): Promise { + return this.withSource(model, position, token, async (local, at, pinned) => { + const results = kind === "definition" ? await getDefinitionsAtPosition(this.languages.definitionProvider, local, at, false, token) + : kind === "type" ? await getTypeDefinitionsAtPosition(this.languages.typeDefinitionProvider, local, at, false, token) + : await getImplementationsAtPosition(this.languages.implementationProvider, local, at, false, token); + return this.reviewLocations(pinned, results, token); + }); + } + + /** Keep navigation in the same saved version/side only when destination contents match. */ + private async reviewLocations(pinned: ITextModel, locations: T[], token: CancellationToken): Promise { + if (![REVIEW_API_SOURCE_SCHEME, REVIEW_LANGUAGE_SOURCE_SCHEME].includes(pinned.uri.scheme)) return locations; + const source = await this.sources.get(pinned)?.pending; + if (!source) return []; + const prefix = source.root.path.replace(/\/$/, "") + "/"; + // References often share a file. Resolve and compare each destination once per request. + const groups = new Map(); + for (const location of locations) { + const key = location.uri.toString(); + const group = groups.get(key) ?? []; + group.push(location); + groups.set(key, group); + } + const mapped = new Map(); + await Promise.all([...groups.values()].map(async group => { + const target = group[0].uri; + if (target.scheme !== "file") return; + const owned = new DisposableStore(); + try { + const local = owned.add(await this.models.createModelReference(target)).object.textEditorModel; + await this.textFiles.files.resolve(target, { reload: { async: false } }); + let original: ITextModel | undefined; + if (target.authority === source.root.authority && target.path.startsWith(prefix)) { + const candidate = pinned.uri.with({ scheme: REVIEW_API_SOURCE_SCHEME, path: "/" + target.path.slice(prefix.length) }); + try { original = owned.add(await this.models.createModelReference(candidate)).object.textEditorModel; } + catch { /* Dependencies and generated files may have no review counterpart. */ } + } + if (!original?.equalsTextBuffer(local.getTextBuffer())) { + const candidate = pinned.uri.with({ scheme: REVIEW_LANGUAGE_SOURCE_SCHEME, path: target.path }); + original = owned.add(await this.models.createModelReference(candidate)).object.textEditorModel; + } + const destination = original; + const results = await withCurrentLocalContext([original, local], token, () => this.generation, async () => { + if (!destination.equalsTextBuffer(local.getTextBuffer())) return []; + return group.map(location => [location, { ...location, uri: destination.uri }] as const); + }); + for (const [before, after] of results ?? []) mapped.set(before, after); + } catch { + // Missing destinations cannot be presented at the provider's coordinates. + } finally { + owned.dispose(); + } + })); + return locations.flatMap(location => { + const match = mapped.get(location); + return match ? [match] : []; + }); + } + + override dispose(): void { + this.environments.invalidate(); + for (const entry of this.sources.values()) void entry.pending.then(source => source?.dispose()); + this.sources.clear(); + super.dispose(); + } +} + +registerWorkbenchContribution2(ReviewLocalLanguageFeatures.ID, ReviewLocalLanguageFeatures, WorkbenchPhase.BlockRestore); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalRequest.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalRequest.test.ts new file mode 100644 index 000000000..1bb4e082c --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalRequest.test.ts @@ -0,0 +1,21 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { withCurrentLocalContext } from "./reviewLocalRequest.js"; + +for (const change of ["source", "dependency", "disposed", "cancelled", "none"] as const) { + test(`pending language result is ${change === "none" ? "returned" : "discarded"} after ${change}`, async () => { + let version = 1, generation = 1, disposed = false; + const token = { isCancellationRequested: false }; + let finish!: (value: string) => void; + const provider = new Promise(resolve => { finish = resolve; }); + const result = withCurrentLocalContext([ + { getVersionId: () => version, isDisposed: () => disposed }, + ], token, () => generation, () => provider); + if (change === "source") version++; + if (change === "dependency") generation++; + if (change === "disposed") disposed = true; + if (change === "cancelled") token.isCancellationRequested = true; + finish("definition from previous project state"); + assert.equal(await result, change === "none" ? "definition from previous project state" : undefined); + }); +} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalRequest.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalRequest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalRequest.ts rename to apps/review-desktop/code-oss/src/vs/review/services/reviewLocalRequest.ts diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalWorkspace.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalWorkspace.ts new file mode 100644 index 000000000..e1859a8f4 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewLocalWorkspace.ts @@ -0,0 +1,33 @@ +import { Queue } from "../../base/common/async.js"; +import type { IDisposable } from "../../base/common/lifecycle.js"; +import { URI } from "../../base/common/uri.js"; +import type { IWorkspaceEditingService } from "../../workbench/services/workspaces/common/workspaceEditing.js"; + +const sessions = new WeakMap; roots: Map }>(); + +/** Native live files and retained-source language adapters share folder ownership. */ +export async function acquireReviewLanguageRoot(workspace: IWorkspaceEditingService, root: URI): Promise { + let session = sessions.get(workspace); + if (!session) { + session = { queue: new Queue(), roots: new Map() }; + sessions.set(workspace, session); + } + const { queue, roots } = session; + const key = root.toString(); + await queue.queue(async () => { + if (!roots.has(key)) await workspace.addFolders([{ uri: root }]); + roots.set(key, (roots.get(key) ?? 0) + 1); + }); + let disposed = false; + return { + dispose() { + if (disposed) return; + disposed = true; + void queue.queue(async () => { + const count = (roots.get(key) ?? 1) - 1; + if (count > 0) roots.set(key, count); + else { roots.delete(key); await workspace.removeFolders([root]); } + }); + } + }; +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewMultiDiff.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewMultiDiff.ts new file mode 100644 index 000000000..ab94fda15 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewMultiDiff.ts @@ -0,0 +1,262 @@ +import { observableValue } from "../../base/common/observable.js"; +import type { ReviewDiffProgressState, ReviewDiffSection } from "../common/reviewProtocol.js"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Button } from "../../base/browser/ui/button/button.js"; +import { isEqual } from "../../base/common/resources.js"; +import { URI } from "../../base/common/uri.js"; +import type { + IResourceLabel, + IResourceHeaderMetadata, + IWorkbenchUIElementFactory, +} from "../../editor/browser/widget/multiDiffEditor/workbenchUIElementFactory.js"; +import type { IDiffCodeEditorWidgetOptions } from "../../editor/browser/widget/diffEditor/diffEditorWidget.js"; +import { FileKind } from "../../platform/files/common/files.js"; +import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; +import { ResourceLabel } from "../../workbench/browser/labels.js"; +import type { ReviewDiffFileWire } from "../common/reviewProtocol.js"; + +export interface ReviewMultiDiffHeaderEntry { + readonly original: URI | undefined; + readonly modified: URI | undefined; + readonly additions?: number; + readonly deletions?: number; + /** Why the file starts collapsed, e.g. "Generated file · hidden by default". */ + readonly note?: string; + /** Hover text for the counts: visible, structural and textual rows. */ + readonly countsTitle?: string; + readonly sectionId?: string; + readonly section?: ReviewDiffSection; + readonly sectionCollapsed?: boolean; + readonly onToggleSectionCollapsed?: () => void; + readonly onToggleSection?: () => void; + readonly onDidOpen?: () => void; + readonly viewedState?: ReviewDiffProgressState; + readonly onToggleViewed?: () => void; +} + +export class ReviewMultiDiffUIElementFactory + implements IWorkbenchUIElementFactory +{ + + get headerClickToCollapse(): boolean { + return !this.hideResourceHeader; + } + + + private readonly headers = new Set<() => void>(); + + /** Re-reads every live header's entry, for counts that change without the items changing. */ + refreshHeaders(): void { + for (const refresh of this.headers) refresh(); + } + + constructor( + private readonly entries: () => readonly ReviewMultiDiffHeaderEntry[], + readonly horizontalScrollbar: "auto" | "hidden", + readonly overflowWidgetsDomNode: HTMLElement | undefined, + readonly hideResourceHeader = false, + readonly codeEditorWidgetOptions: IDiffCodeEditorWidgetOptions | undefined, + @IInstantiationService + private readonly instantiationService: IInstantiationService, + ) {} + + getResourceSectionId(uris: Parameters[0]): string | undefined { + // Lens entries encode their section identity in both source URI fragments. + return uris?.modified?.fragment || uris?.original?.fragment || undefined; + } + + createResourceSectionHeader(element: HTMLElement, sticky = false) { + const height = observableValue(this, 0); + const bodyHidden = observableValue(this, false); + let uris: Parameters[0]; + const refresh = () => { + const entry = uris && this.entries().find(entry => sameResource(entry.original, uris!.original) && sameResource(entry.modified, uris!.modified)); + const section = sticky && entry?.sectionId + ? this.entries().find(candidate => candidate.sectionId === entry.sectionId && candidate.section)?.section + : entry?.section; + bodyHidden.set(entry?.sectionCollapsed ?? false, undefined); + element.replaceChildren(); element.className = 'review-diff-group'; element.hidden = !section; + height.set(section ? 48 : 0, undefined); + if (!section) return; + const toggle = document.createElement('button'); toggle.className = 'review-diff-group-toggle'; + toggle.setAttribute('aria-expanded', String(!entry?.sectionCollapsed)); + toggle.setAttribute('aria-label', `${entry?.sectionCollapsed ? 'Expand' : 'Collapse'} section: ${section.label}`); + toggle.onclick = () => entry?.onToggleSectionCollapsed?.(); + const chevron = document.createElement('span'); chevron.className = `codicon codicon-chevron-${entry?.sectionCollapsed ? 'right' : 'down'}`; + const title = document.createElement('span'); title.className = 'review-diff-group-title'; title.textContent = section.label; + const counts = document.createElement('span'); counts.className = 'review-diff-group-counts'; + counts.textContent = section.total.additions + section.total.deletions === 0 ? 'Unchanged' : section.state === 'viewed' ? '✓' : section.state === 'folded' ? 'Folded' : `+${compactCount(section.remaining.additions)} −${compactCount(section.remaining.deletions)}`; + counts.title = `Remaining +${section.remaining.additions} −${section.remaining.deletions} · Total +${section.total.additions} −${section.total.deletions}`; + const button = document.createElement('button'); button.className = 'review-header-viewed'; button.setAttribute('role', 'checkbox'); + button.setAttribute('aria-checked', section.state === 'partial' ? 'mixed' : String(section.state === 'viewed')); + button.setAttribute('aria-label', `${section.state === 'viewed' ? 'Mark unviewed' : 'Mark viewed'}: ${section.label}`); + button.textContent = section.state === 'viewed' ? '✓' : section.state === 'partial' ? '−' : ''; + button.hidden = section.total.additions + section.total.deletions === 0; + button.onclick = () => entry?.onToggleSection?.(); + element.classList.toggle('is-viewed', section.state === 'viewed'); + toggle.append(chevron, title); element.append(toggle, counts, button); + }; + this.headers.add(refresh); + return { height, bodyHidden, setUris: (value: typeof uris) => { uris = value; refresh(); }, dispose: () => { this.headers.delete(refresh); element.remove(); } }; + } + + createResourceLabel(element: HTMLElement): IResourceLabel { + element.classList.add("review-path-label"); + const label = this.instantiationService.createInstance( + ResourceLabel, + element, + {}, + ); + // A deleted file keeps a legible name: the tree's minus already says + // deleted, so the header never strikes the path through. + return { + setUri: (uri) => { + if (!uri) { + label.element.clear(); + return; + } + // `setFile` splits the URI into a file name and a folder. The header + // prints the whole path instead, and the CSS elides it from the left. + label.element.setResource( + { resource: uri, name: reviewMultiDiffLabelPath(uri) }, + { fileKind: FileKind.FILE, forceLabel: true }, + ); + }, + setLabel: (name, description, resource) => { + if (resource) { + label.element.setResource({ resource, name, description }); + } else { + label.element.setLabel(name, description); + } + }, + dispose() { + label.dispose(); + }, + }; + } + + createResourceHeaderMetadata(element: HTMLElement): IResourceHeaderMetadata { + const ownerDocument = element.ownerDocument; + const additions = ownerDocument.createElement("span"); + additions.className = "review-multidiff-additions"; + const deletions = ownerDocument.createElement("span"); + deletions.className = "review-multidiff-deletions"; + const counts = ownerDocument.createElement("span"); + counts.className = "review-multidiff-counts"; + counts.append(additions, deletions); + element.append(counts); + const note = ownerDocument.createElement("span"); + note.className = "review-multidiff-note"; + element.append(note); + + const openContainer = ownerDocument.createElement("span"); + openContainer.className = "review-multidiff-open-container"; + element.append(openContainer); + const open = new Button(openContainer, { + ariaLabel: "Open File", + title: "Open File", + supportIcons: true, + }); + open.label = "Open file"; + open.element.classList.add("review-multidiff-open"); + const viewed = ownerDocument.createElement("button"); + viewed.className = "review-header-viewed"; + viewed.setAttribute("role", "checkbox"); + element.append(viewed); + const toggleViewed = (event: MouseEvent) => { event.stopPropagation(); current?.onToggleViewed?.(); }; + viewed.addEventListener("click", toggleViewed); + let current: ReviewMultiDiffHeaderEntry | undefined; + let lastUris: Parameters[0]; + const openListener = open.onDidClick(() => current?.onDidOpen?.()); + const refresh = () => setUris(lastUris); + this.headers.add(refresh); + + const setUris: IResourceHeaderMetadata["setUris"] = (uris) => { + lastUris = uris; + current = uris + ? this.entries().find( + (entry) => + sameResource(entry.original, uris.original) && + sameResource(entry.modified, uris.modified), + ) + : undefined; + element.hidden = !current; + if (!current) return; + const hasCounts = + current.additions !== undefined && current.deletions !== undefined; + counts.hidden = !hasCounts; + if (hasCounts) { + additions.textContent = `+${compactCount(current.additions!)}`; + deletions.textContent = `−${compactCount(current.deletions!)}`; + counts.setAttribute( + "aria-label", + `${current.additions} lines added, ${current.deletions} lines removed`, + ); + } + counts.title = current.countsTitle ?? ""; + viewed.hidden = !current.onToggleViewed; + viewed.textContent = current.viewedState === "viewed" ? "✓" : current.viewedState === "partial" ? "−" : ""; + viewed.setAttribute("aria-checked", current.viewedState === "partial" ? "mixed" : String(current.viewedState === "viewed")); + viewed.title = current.viewedState === "viewed" ? "Mark unviewed and unfold" : "Mark visible scope viewed"; + viewed.setAttribute("aria-label", viewed.title); + counts.classList.toggle("review-counts-viewed", current.viewedState === "viewed" || current.viewedState === "folded"); + counts.classList.toggle("review-counts-folded", current.viewedState === "folded"); + if (current.viewedState === "viewed") { additions.textContent = "✓"; deletions.textContent = ""; } + else if (current.viewedState === "folded") { + // A hidden file's note already says why it is folded. + additions.textContent = "Folded"; deletions.textContent = ""; + counts.hidden ||= !!current.note; + } + + note.hidden = !current.note; + note.textContent = current.note ?? ""; + openContainer.hidden = !current.onDidOpen; + }; + return { + setUris, + dispose: () => { + this.headers.delete(refresh); + viewed.removeEventListener("click", toggleViewed); + openListener.dispose(); + open.dispose(); + element.replaceChildren(); + }, + }; + } +} + +function sameResource(left: URI | undefined, right: URI | undefined): boolean { + return left === undefined + ? right === undefined + : !!right && isEqual(left, right); +} + +export function reviewMultiDiffLabelUris(file: ReviewDiffFileWire): { + readonly original: URI | undefined; + readonly modified: URI | undefined; +} { + return { + original: + file.status === "added" + ? undefined + : reviewFileLabelUri(file.previousPath ?? file.path), + modified: + file.status === "deleted" + ? undefined + : reviewFileLabelUri(file.path), + }; +} + +function reviewFileLabelUri(path: string): URI { + return URI.from({ scheme: "file", path: `/${path}` }); +} + +function reviewMultiDiffLabelPath(uri: URI): string { + return uri.path.startsWith("/") ? uri.path.slice(1) : uri.path; +} + +const compactCount = (count: number) => new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }).format(count).toLowerCase(); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewSourceEditorInput.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewSourceEditorInput.ts new file mode 100644 index 000000000..6a599a271 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewSourceEditorInput.ts @@ -0,0 +1,12 @@ +import { EditorInputCapabilities } from "../../workbench/common/editor.js"; +import { TextResourceEditorInput } from "../../workbench/common/editor/textResourceEditorInput.js"; + +/** Virtual review buffers cannot delegate Save or Save As to a workspace file. */ +export class ReviewSourceEditorInput extends TextResourceEditorInput { + override get capabilities(): EditorInputCapabilities { + return EditorInputCapabilities.Readonly | EditorInputCapabilities.CanSplitInGroup; + } + override async save(): Promise { return undefined; } + override async saveAs(): Promise { return undefined; } + override async revert(): Promise { } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiff.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiff.ts new file mode 100644 index 000000000..66b414dce --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiff.ts @@ -0,0 +1,197 @@ +import type { IDocumentDiffProvider, IDocumentDiff } from "../../editor/common/diff/documentDiffProvider.js"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { StructuralDiffSession } from "./reviewStructuralDiffSession.js"; +import { IModelService } from "../../editor/common/services/model.js"; +import { ITextModelService } from "../../editor/common/services/resolverService.js"; +import { URI } from "../../base/common/uri.js"; +import { Event } from "../../base/common/event.js"; +import { DisposableStore } from "../../base/common/lifecycle.js"; +import { CancellationError } from "../../base/common/errors.js"; +import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; +import { ServiceCollection } from "../../platform/instantiation/common/serviceCollection.js"; +import { IDiffProviderFactoryService } from "../../editor/browser/widget/diffEditor/diffProviderFactoryService.js"; +import { ICodeEditorService } from "../../editor/browser/services/codeEditorService.js"; +import type { IDiffEditor } from "../../editor/browser/editorBrowser.js"; +import { LineRange } from "../../editor/common/core/ranges/lineRange.js"; +import { DetailedLineRangeMapping } from "../../editor/common/diff/rangeMapping.js"; +import { autorun, derived, type IObservable } from "../../base/common/observable.js"; +import type { UnchangedRegion } from "../../editor/browser/widget/diffEditor/diffEditorViewModel.js"; +import { + structuralContextGaps, + structuralRows, + structuralHighlights, +} from "../common/reviewStructuralDiff.js"; +import type { ReviewFilesEditorEntry } from "./reviewFilesDiffView.js"; + +/** View-owned Monaco providers and editor listeners; comparison state lives in session. */ +export function createStructuralDiffEditors( + instantiation: IInstantiationService, + entries: readonly ReviewFilesEditorEntry[], + lifetime: DisposableStore, + session: StructuralDiffSession, +): { instantiation: IInstantiationService; entries: readonly ReviewFilesEditorEntry[] } { + // Use pinned checkout resources so native language providers see real project files. + // Revision-only resources retain their virtual snapshot identity. + const modelService = instantiation.invokeFunction((a) => a.get(IModelService)); + const resolver = instantiation.invokeFunction((a) => a.get(ITextModelService)); + lifetime.add(resolver.registerTextModelContentProvider("review-structural-empty", { + provideTextContent: async uri => modelService.getModel(uri) ?? modelService.createModel("", null, uri), + })); + const resolvedEntries = entries.map(entry => ({ + ...entry, + original: entry.original ?? URI.from({ scheme: "review-structural-empty", path: "/base/" + entry.file.path, query: entry.modified!.toString() }), + modified: entry.modified ?? URI.from({ scheme: "review-structural-empty", path: "/head/" + entry.file.path, query: entry.original!.toString() }), + })); + const unchanged = new Set(entries.filter(e => e.file.status === "unchanged").map(e => e.file.path)); + const pairs = new Map(resolvedEntries.map(e => [e.original!.toString() + "\n" + e.modified!.toString(), e.file.path])); + const factory: IDiffProviderFactoryService = { + _serviceBrand: undefined, + createDiffProvider: () => new StructuralDiffProvider(session, pairs, unchanged), + }; + const child = lifetime.add( + instantiation.createChild(new ServiceCollection([IDiffProviderFactoryService, factory])), + ); + attachStructuralEditors(instantiation, resolvedEntries, session, lifetime); + return { instantiation: child, entries: resolvedEntries }; +} + +/** Adapts session snapshots and fold state to Monaco's diff interface. */ +export class StructuralDiffProvider implements IDocumentDiffProvider { + private path: string | undefined; + readonly onDidChange: Event; + constructor(private readonly session: StructuralDiffSession, private readonly pairs: ReadonlyMap, private readonly unchanged: ReadonlySet) { + this.onDidChange = Event.map(Event.filter(session.onDidChange, change => this.path !== undefined && change.files.has(this.path)), () => undefined); + } + async computeDiff(...[original, modified, _options, token]: Parameters): Promise { + if (token.isCancellationRequested) throw new CancellationError(); + const path = this.pairs.get(original.uri.with({ fragment: "" }).toString() + "\n" + modified.uri.with({ fragment: "" }).toString()); + this.path = path; + if (path !== undefined && this.unchanged.has(path)) { + if (original.getValue() !== modified.getValue()) throw new Error("Referenced context file changed; reload the review."); + return { changes: [], moves: [], identical: true, quitEarly: false }; + } + if (path !== undefined && this.session.getFileResult(path)?.diff?.type === "binary") { + return { changes: [], moves: [], identical: false, quitEarly: false, changeHighlights: { original: [], modified: [] } }; + } + const diff = path === undefined ? undefined : this.session.getTextDiff(path); + if (!diff) throw new Error("diffr did not supply a result for this file."); + const left = (diff.lhs?.text ?? "").replace(/\r\n/g, "\n"); + const right = (diff.rhs?.text ?? "").replace(/\r\n/g, "\n"); + if ( + original.getLinesContent().join("\n") !== left || + modified.getLinesContent().join("\n") !== right + ) { + throw new Error( + "diffr sources differ from Review's editor snapshots; reload the review.", + ); + } + const rows = structuralRows(diff); + // Changed-ness comes from the wire: a one-sided row, or a paired row whose line carries a changed span. + const highlights = structuralHighlights(diff); + const changedLeft = new Set(highlights.originalLines), changedRight = new Set(highlights.modifiedLines); + const changes: DetailedLineRangeMapping[] = []; + let l = 0, + r = 0; + let start: [number, number] | undefined; + const flush = () => { + if (start) + changes.push( + new DetailedLineRangeMapping( + new LineRange(start[0] + 1, l + 1), + new LineRange(start[1] + 1, r + 1), + undefined, + ), + ); + start = undefined; + }; + for (const [a, b] of rows) { + const changed = a === null || b === null || changedLeft.has(a + 1) || changedRight.has(b + 1); + if (changed) start ??= [l, r]; + else flush(); + if (a !== null) l = a + 1; + if (b !== null) r = b + 1; + } + flush(); + return { + changes, + moves: [], + identical: left === right, + quitEarly: false, + sourceLineAlignment: rows, + // Every collapsed region is a hidden-region band, labelled by the wire. + contextGaps: structuralContextGaps( + diff, + (id) => this.session.isRegionCollapsed(path!, id) === true, + (id) => this.session.isRegionCollapsed(path!, id), + ).map(gap => ({ + ...gap, labelObservable: derived(reader => { + for (const id of gap.regionIds) { + const label = this.session.regionLabel(path!, id).read(reader); + if (label) return label; + } + const count = Math.max(gap.originalCount, gap.modifiedCount); + return `${count} hidden line${count === 1 ? "" : "s"}`; + }) + })), + changeHighlights: highlights, + }; + } +} + +/** + * Keeps each structural diff editor's bands in step with the collapse state: + * a band a reader reveals (its arrows, or double-click) marks its fold state + * open, which covers both sides by construction, and the visible counts follow. + */ +function attachStructuralEditors( + instantiation: IInstantiationService, + entries: readonly ReviewFilesEditorEntry[], + session: StructuralDiffSession, + lifetime: DisposableStore, +): void { + const editors = instantiation.invokeFunction((a) => a.get(ICodeEditorService)); + const pairs = new Map(entries.map((e) => [e.original!.toString() + "\n" + e.modified!.toString(), e.file.path])); + function watch(editor: IDiffEditor) { + const store = lifetime.add(new DisposableStore()); + store.add(editor.onDidDispose(() => store.dispose())); + const widget = editor as unknown as { unchangedRegions?: IObservable }; + if (!widget.unchangedRegions) return; + let revealed = new Set(); + store.add( + autorun((reader) => { + const model = editor.getModel(); + const path = model && pairs.get(model.original.uri.with({ fragment: "" }).toString() + "\n" + model.modified.uri.with({ fragment: "" }).toString()); + const regions = widget.unchangedRegions!.read(reader); + if (!path || !session.getTextDiff(path)) return; + const gaps = structuralContextGaps(session.getTextDiff(path)!, (id) => session.isRegionCollapsed(path, id) === true, (id) => session.isRegionCollapsed(path, id)); + const next = new Set(); + const gapOf = (region: UnchangedRegion) => + gaps.find((g) => g.originalStart === region.originalLineNumber && g.modifiedStart === region.modifiedLineNumber && g.foldStateId === region.foldStateId); + for (const region of regions) { + const fullyShown = region.visibleLineCountTop.read(reader) + region.visibleLineCountBottom.read(reader) >= region.lineCount; + if (fullyShown) { + next.add(region); + if (revealed.has(region)) continue; + const gap = gapOf(region); + if (!gap) continue; + session.setRegionCollapsed(path, gap.foldStateId, false); + } else if (revealed.has(region)) { + // Monaco's own fold control closed a region we had marked open. + const gap = gapOf(region); + if (!gap) continue; + session.setRegionCollapsed(path, gap.foldStateId, true); + } + } + revealed = next; + }), + ); + } + + lifetime.add(editors.onDiffEditorAdd(watch)); + for (const editor of editors.listDiffEditors()) watch(editor); +} + diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffClient.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffClient.ts new file mode 100644 index 000000000..9b9d89524 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffClient.ts @@ -0,0 +1,48 @@ +import { decodeReviewStructuralDiffEvent, reviewSourceQuery, type ReviewSourceView } from "../common/reviewProtocol.js"; +import type { StructuralEvent } from "../common/reviewStructuralDiff.js"; +import type { IReviewDesktopConnectionService } from "./reviewDesktopConnectionService.js"; + +/** The transport seam: callers consume records, never Response objects or byte chunks. */ +export interface StructuralDiffStream { + streamComparison(signal: AbortSignal): AsyncIterable; +} + +export class StructuralDiffClient implements StructuralDiffStream { + constructor(private readonly connection: IReviewDesktopConnectionService, private readonly comparison: ReviewSourceView) { } + + async *streamComparison(signal: AbortSignal): AsyncGenerator { + const { serverUrl, token } = await this.connection.getConnection(); + signal.throwIfAborted(); + const query = new URLSearchParams(Object.entries(reviewSourceQuery(this.comparison)).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)])); + const response = await fetch(`${serverUrl}/reviews-api/${encodeURIComponent(this.comparison.reviewId)}/structural-diff?${query}`, { + headers: { "x-review-token": token }, signal, + }); + if (!response.ok) throw new Error((await response.json()).error ?? "Structural diff request failed."); + if (!response.body || !response.headers.get("content-type")?.includes("ndjson")) { + await response.body?.cancel(); + throw new Error("The Review host must be updated to stream structural diffs."); + } + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + try { + while (true) { + const chunk = await reader.read(); + buffer += decoder.decode(chunk.value, { stream: !chunk.done }); + const lines = buffer.split("\n"); + buffer = lines.pop()!; + if (chunk.done && buffer.trim()) { lines.push(buffer); buffer = ""; } + for (const line of lines) { + if (!line.trim()) continue; + const event = decodeReviewStructuralDiffEvent(line); + if (event.type === "error") throw new Error(event.message); + yield event; + } + if (chunk.done) break; + } + } finally { + await reader.cancel().catch(() => { }); + reader.releaseLock(); + } + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffSession.test.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffSession.test.ts new file mode 100644 index 000000000..05bd77faf --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffSession.test.ts @@ -0,0 +1,173 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { StructuralDiffSession } from './reviewStructuralDiffSession.js'; +import type { StructuralEvent } from '../common/reviewStructuralDiff.js'; + +const file = { rhs: { path: 'a.ts', oid: 'abc', mode: '100644' } }; +const start: StructuralEvent = { type: 'start', version: 4, lhs: { type: 'empty_tree' }, rhs: { type: 'revision', rev: 'head' }, files: [{ file, status: 'added' }] }; +const result: StructuralEvent = { type: 'file', file, diff: { type: 'text', structural_changes: { base: [], head: [[0, 1]] }, rhs: { text: 'a', regions: [{ kind: 'leaf', id: 1, fold_state_id: 2, alignment_id: 1, start: { line: 0, column: 0 }, end: { line: 0, column: 1 }, visibility: { collapsed: true } }] }, stats: { textual: { added: 1, removed: 0 }, visible: { added: 0, removed: 0 } } } }; +const complete: StructuralEvent = { type: 'complete', succeeded: 1, failed: 0 }; + +test('views detach and reattach without restarting a comparison or losing folds', async () => { + let requests = 0; + const session = new StructuralDiffSession({ async *streamComparison() { requests++; yield start; yield result; yield complete; } }); + try { + let observedFile = false; + const view = session.onDidChange(change => { if (change.files.has("a.ts")) observedFile = !!session.getFileResult("a.ts"); }); + await session.start(); + assert.equal(observedFile, true); + view.dispose(); + session.setRegionCollapsed('a.ts', 2, false); + await session.start(); + assert.equal(requests, 1); + assert.equal(session.isRegionCollapsed('a.ts', 2), false); + assert.equal(session.complete, true); + } finally { session.dispose(); } +}); + +test('closing the review aborts a running request and ignores late events', async () => { + let signal: AbortSignal | undefined; + let release!: () => void; + const gate = new Promise(resolve => release = resolve); + const session = new StructuralDiffSession({ async *streamComparison(s) { signal = s; yield start; await gate; yield result; } }); + const task = session.start(); + await Promise.resolve(); + session.dispose(); + assert.equal(signal?.aborted, true); + release(); await task; + assert.equal(session.getFileResult('a.ts'), undefined); +}); + +test('per-file failures and run abortion remain observable after the stream finishes', async () => { + const session = new StructuralDiffSession({ + async *streamComparison() { + yield start; + yield { type: 'file', file, error: { code: 'parse', message: 'bad file' } } as StructuralEvent; + yield { ...complete, aborted: { code: 'cancel', message: 'stopped' } } as StructuralEvent; + } + }); + try { await session.start(); assert.equal(session.getFileResult('a.ts')?.error, 'bad file'); assert.match(session.error!, /stopped/); } + finally { session.dispose(); } +}); + +test('truncation and missing manifest results are visible to later subscribers', async () => { + for (const events of [[start], [start, complete]]) { + const session = new StructuralDiffSession({ async *streamComparison() { yield* events; } }); + try { + await session.start(); + assert.equal(session.complete, true); + assert.ok(session.error || session.getFileResult('a.ts')?.error); + } finally { session.dispose(); } + } +}); + +test('deferred annotations retain source identity, counts and user fold choices', async () => { + let release!: () => void; + const gate = new Promise(resolve => release = resolve); + const session = new StructuralDiffSession({ + async *streamComparison() { + yield start; yield structuredClone(result); + await gate; + yield { type: 'annotations', file, annotations: [{ region_id: 1, label: 'summarized' }] } as StructuralEvent; + yield complete; + } + }); + const task = session.start(); + while (!session.getTextDiff('a.ts')) await new Promise(resolve => setTimeout(resolve, 0)); + try { + const initial = session.getTextDiff('a.ts')!; + assert.equal(session.complete, false); + session.setRegionCollapsed('a.ts', 2, false); + release(); await task; + assert.equal(session.getTextDiff('a.ts'), initial); + assert.equal(initial.rhs!.regions![0].visibility?.label, 'summarized'); + assert.equal(initial.rhs!.text, 'a'); + assert.deepEqual(initial.structural_changes, { base: [], head: [[0, 1]] }); + assert.equal(session.isRegionCollapsed('a.ts', 2), false); + assert.equal(session.error, undefined); + } finally { release(); session.dispose(); } +}); + +test('invalid annotation batches are atomic and enrichment failure keeps the initial diff usable', async () => { + for (const invalid of [false, true]) { + const session = new StructuralDiffSession({ + async *streamComparison() { + yield start; yield structuredClone(result); + yield { + type: 'annotations', file, + annotations: invalid ? [{ region_id: 1, label: 'must not apply' }, { region_id: 99, label: 'bad' }] : [], + error: invalid ? undefined : { code: 'enrichment_failed', message: 'offline' }, + } as StructuralEvent; + yield complete; + } + }); + try { + await session.start(); + assert.equal(session.getTextDiff('a.ts')!.rhs!.regions![0].visibility?.label, undefined); + assert.equal(session.isRegionCollapsed('a.ts', 2), true); + if (invalid) assert.match(session.error!, /Unknown annotation region/); + else { + assert.equal(session.getFileResult('a.ts')?.annotationError, 'offline'); + assert.equal(session.error, undefined); + } + } finally { session.dispose(); } + } +}); + +test('streamed labels update existing bands without invalidating either file provider', async () => { + const { StructuralDiffProvider } = await import('./reviewStructuralDiff.js'); + const { URI } = await import('../../base/common/uri.js'); + const { CancellationToken } = await import('../../base/common/cancellation.js'); + const other = { rhs: { path: 'b.ts', oid: 'def', mode: '100644' } }; + let release!: () => void; + const gate = new Promise(resolve => release = resolve); + const session = new StructuralDiffSession({ + async *streamComparison() { + yield { ...start, files: [...start.files, { file: other, status: 'added' as const }] }; + yield structuredClone(result); + yield { ...structuredClone(result), file: other }; + await gate; + yield { type: 'annotations', file, annotations: [{ region_id: 1, label: 'first' }] } as StructuralEvent; + yield { type: 'annotations', file, annotations: [{ region_id: 1, label: '// pseudocode\nfinal summary' }] } as StructuralEvent; + yield { ...complete, succeeded: 2 }; + } + }); + const task = session.start(); + const ready = new Promise(resolve => { + const sub = session.onDidChange(change => { if (change.files.has('b.ts')) { sub.dispose(); resolve(); } }); + }); + try { + await ready; + const models = (path: string) => [ + { uri: URI.parse(`test:/base/${path}`), getLinesContent: () => [''] }, + { uri: URI.parse(`test:/head/${path}`), getLinesContent: () => ['a'] }, + ] as const; + const a = models('a.ts'), b = models('b.ts'); + const pairs = new Map([[`${a[0].uri}\n${a[1].uri}`, 'a.ts'], [`${b[0].uri}\n${b[1].uri}`, 'b.ts']]); + const pa = new StructuralDiffProvider(session, pairs, new Set()); + const pb = new StructuralDiffProvider(session, pairs, new Set()); + const compute = (provider: typeof pa, pair: ReturnType) => provider.computeDiff( + pair[0] as Parameters[0], pair[1] as Parameters[1], + { ignoreTrimWhitespace: false, maxComputationTimeMs: 0, computeMoves: false }, CancellationToken.None, + ); + const diff = await compute(pa, a); + await compute(pb, b); + let invalidationsA = 0, invalidationsB = 0, labelBatches = 0; + const subscriptions = [pa.onDidChange(() => invalidationsA++), pb.onDidChange(() => invalidationsB++), + session.onDidChange(change => { if (change.labels.has('a.ts')) labelBatches++; })]; + const band = diff.contextGaps![0]; + release(); await task; + assert.equal(band.labelObservable!.get(), '// pseudocode\nfinal summary'); + assert.equal(invalidationsA, 0); + assert.equal(invalidationsB, 0); + assert.equal(labelBatches, 1, 'a burst publishes only the latest presentation state'); + const folded = new Promise(resolve => { + const sub = pa.onDidChange(() => { sub.dispose(); resolve(); }); + }); + session.setRegionCollapsed('a.ts', 2, false); + await folded; + assert.equal(invalidationsA, 1); + assert.equal(invalidationsB, 0, 'folding a file does not invalidate unrelated editors'); + subscriptions.forEach(sub => sub.dispose()); + } finally { release(); session.dispose(); await task; } +}); diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffSession.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffSession.ts new file mode 100644 index 000000000..069a0c07b --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewStructuralDiffSession.ts @@ -0,0 +1,186 @@ +import { RunOnceScheduler } from "../../base/common/async.js"; +import { observableValue, transaction, type IObservable, type ISettableObservable } from "../../base/common/observable.js"; +import { Emitter } from "../../base/common/event.js"; +import { Disposable } from "../../base/common/lifecycle.js"; +import { structuralFilePath, STRUCTURAL_WIRE_VERSION, type StructuralEvent, type StructuralRegion, type StructuralTextDiff } from "../common/reviewStructuralDiff.js"; +import type { StructuralDiff } from "../common/reviewProtocol.js"; +import type { StructuralDiffStream } from "./reviewStructuralDiffClient.js"; + +export interface StructuralFileResult { + diff?: StructuralDiff; + error?: string; + hidden?: string; + annotationError?: string; +} + +export interface StructuralSessionChange { + /** Files whose diff or fold state changed. */ + readonly files: ReadonlySet; + /** Files with new summary labels or summary errors; their diff is unchanged. */ + readonly labels: ReadonlySet; + readonly status: boolean; +} + +/** One comparison, owned by the review. Views only observe it and change fold state. */ +export class StructuralDiffSession extends Disposable { + private readonly changed = this._register(new Emitter()); + readonly onDidChange = this.changed.event; + private readonly pendingFiles = new Set(); + private readonly pendingLabels = new Set(); + private pendingStatus = false; + private readonly regions = new Map(); + private readonly labels = new Map>(); + private readonly pendingLabelValues = new Map(); + private readonly notification = this._register(new RunOnceScheduler(() => this.flushChanges(), 16)); + private readonly abort = new AbortController(); + private readonly results = new Map(); + private readonly folds = new Map(); + private manifest: Set | undefined; + private task: Promise | undefined; + private finished = false; + private disposed = false; + error: string | undefined; + get complete(): boolean { return this.finished; } + + constructor(private readonly client: StructuralDiffStream) { super(); } + + start(): Promise { return this.task ??= this.consume(); } + getFileResult(path: string): StructuralFileResult | undefined { return this.results.get(path); } + getTextDiff(path: string): StructuralTextDiff | undefined { + const diff = this.results.get(path)?.diff; + return diff?.type === "text" ? diff : undefined; + } + isRegionCollapsed(path: string, id: number): boolean | undefined { return this.folds.get(`${path}:${id}`); } + setRegionCollapsed(path: string, id: number, collapsed: boolean): void { + const key = `${path}:${id}`; + if (this.disposed || this.folds.get(key) === collapsed) return; + this.folds.set(key, collapsed); + this.notify(path); + } + + private async consume(): Promise { + try { + for await (const event of this.client.streamComparison(this.abort.signal)) { + if (this.disposed) return; + this.applyEvent(event); + } + if (!this.finished) throw new Error("diffr stream ended before completion."); + } catch (error) { + if (!this.disposed) { + this.error = error instanceof Error ? error.message : String(error); + this.finished = true; + this.notify(undefined, true); + } + } finally { + this.notification.cancel(); + if (!this.disposed) this.flushChanges(); + } + } + + private applyEvent(event: StructuralEvent): void { + if (this.finished) throw new Error("diffr emitted data after completion."); + if (!this.manifest) { + if (event.type !== "start" || event.version !== STRUCTURAL_WIRE_VERSION) throw new Error("Unsupported diffr stream protocol."); + this.acceptManifest(event); + } else if (event.type === "file") this.storeFileResult(event); + else if (event.type === "annotations") this.applyAnnotations(event); + else if (event.type === "complete") this.finishLoading(event); + else throw new Error(`Unexpected diffr event: ${event.type}`); + if (event.type === "file") this.notify(structuralFilePath(event.file)); + else if (event.type === "annotations") { + this.pendingLabels.add(structuralFilePath(event.file)); + this.notify(); + } else this.notify(undefined, true); + } + + /** Stable presentation state, shared by all editors displaying this region. */ + regionLabel(path: string, id: number): IObservable { + const key = `${path}:${id}`; + let label = this.labels.get(key); + if (!label) { + label = observableValue(this, this.regions.get(key)?.visibility?.label); + this.labels.set(key, label); + } + return label; + } + + private notify(path?: string, status = false): void { + if (path) this.pendingFiles.add(path); + this.pendingStatus ||= status; + if (!this.notification.isScheduled()) this.notification.schedule(); + } + + private flushChanges(): void { + if (!this.pendingFiles.size && !this.pendingLabels.size && !this.pendingStatus) return; + const change: StructuralSessionChange = { + files: new Set(this.pendingFiles), labels: new Set(this.pendingLabels), status: this.pendingStatus, + }; + const labels = new Map(this.pendingLabelValues); + this.pendingFiles.clear(); this.pendingLabels.clear(); this.pendingLabelValues.clear(); this.pendingStatus = false; + transaction(tx => { + for (const [key, value] of labels) this.labels.get(key)?.set(value, tx); + }); + this.changed.fire(change); + } + + private acceptManifest(event: Extract): void { + this.manifest = new Set(event.files.map(file => structuralFilePath(file.file))); + if (this.manifest.size !== event.files.length) throw new Error("diffr repeated a file in its manifest."); + } + + private storeFileResult(event: Extract): void { + const path = structuralFilePath(event.file); + if (!this.manifest!.has(path) || this.results.has(path)) throw new Error(`Unexpected or repeated diffr result: ${path}`); + if (event.error) { this.results.set(path, { error: event.error.message }); return; } + const diff = event.diff; + if (diff.type === "text") { + const seed = (region: StructuralRegion) => { + this.regions.set(`${path}:${region.id}`, region); + const key = `${path}:${region.fold_state_id}`; + if (!this.folds.has(key)) this.folds.set(key, region.visibility?.collapsed === true); + if (region.kind === "fold") region.children.forEach(seed); + }; + for (const side of [diff.lhs, diff.rhs]) side?.regions?.forEach(seed); + } + this.results.set(path, { + diff, + hidden: event.visibility?.collapsed ? event.visibility.label || "Hidden by default" : undefined + }); + } + + private applyAnnotations(event: Extract): void { + const path = structuralFilePath(event.file); + const result = this.results.get(path); + if (result?.diff?.type !== "text") throw new Error(`Annotations precede a text result: ${path}`); + // Validate the entire batch before applying it. Labels do not replace the + // source, correspondence, region identities, or the reader's fold choices. + for (const annotation of event.annotations) { + if (!this.regions.has(`${path}:${annotation.region_id}`)) throw new Error(`Unknown annotation region: ${annotation.region_id}`); + } + for (const annotation of event.annotations) { + const region = this.regions.get(`${path}:${annotation.region_id}`)!; + region.visibility = { ...region.visibility, label: annotation.label }; + this.pendingLabelValues.set(`${path}:${region.id}`, annotation.label); + } + result.annotationError = event.error?.message; + } + + private finishLoading(event: Extract): void { + for (const path of this.manifest!) if (!this.results.has(path)) { this.results.set(path, { error: "diffr did not supply a result for this file." }); this.pendingFiles.add(path); } + this.finished = true; + if (event.aborted) this.error = `diffr stopped early: ${event.aborted.message}`; + } + + override dispose(): void { + this.disposed = true; + this.abort.abort(); + this.results.clear(); + this.folds.clear(); + this.labels.clear(); + this.regions.clear(); + this.pendingFiles.clear(); + this.pendingLabels.clear(); + this.pendingLabelValues.clear(); + super.dispose(); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewTelemetryService.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewTelemetryService.ts new file mode 100644 index 000000000..d6a5ad687 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewTelemetryService.ts @@ -0,0 +1,127 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { generateUuid } from "../../base/common/uuid.js"; +import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; +import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; +import { IMainProcessService } from "../../platform/ipc/common/mainProcessService.js"; +import { ILifecycleService } from "../../workbench/services/lifecycle/common/lifecycle.js"; +import { + REVIEW_DESKTOP_CHANNEL, + type ReviewDesktopConnection, +} from "../common/reviewDesktopBootstrap.js"; +import { REVIEW_TELEMETRY_SETTING } from "../common/reviewConfigurationDefaults.js"; +import type { ReviewErrorReport } from "../common/reviewErrorReport.js"; +import { reviewTelemetryEventRequest } from "../common/reviewTelemetryRequest.js"; + +type ReviewTelemetryProperties = Record; + +interface QueuedReviewTelemetryEvent { + readonly name: string; + readonly properties: ReviewTelemetryProperties | undefined; + readonly error?: ReviewErrorReport; +} + +export const IReviewTelemetryService = createDecorator( + "reviewTelemetryService", +); + +export interface IReviewTelemetryService { + readonly _serviceBrand: undefined; + /** The per-window session id all workbench events carry. */ + readonly appSessionId: string; + /** + * Fire-and-forget. Never throws. Drops when telemetry is off. + * + * `error` carries the raw name, message, and stack beside the allowlisted + * properties, never inside them. It reaches only the loopback server on this + * machine, which replaces the message with a digest and keeps only the stack + * frames that resolve inside the shipped bundle. + */ + capture(name: string, properties?: ReviewTelemetryProperties, error?: ReviewErrorReport): void; + /** Best-effort flush. Resolves within approximately 500 ms. */ + flush(): Promise; +} + +export class ReviewTelemetryService implements IReviewTelemetryService { + declare readonly _serviceBrand: undefined; + readonly appSessionId = generateUuid(); + + private readonly queued: QueuedReviewTelemetryEvent[] = []; + private readonly inFlight = new Set>(); + private readonly connectionPromise: Promise; + private connection: ReviewDesktopConnection | undefined; + + constructor( + @IMainProcessService mainProcessService: IMainProcessService, + @IConfigurationService + private readonly configurationService: IConfigurationService, + @ILifecycleService lifecycleService: ILifecycleService, + ) { + this.connectionPromise = mainProcessService + .getChannel(REVIEW_DESKTOP_CHANNEL) + .call("getConnection") + .then((connection) => { + this.connection = connection; + this.drainQueue(); + return connection; + }) + .catch(() => undefined); + lifecycleService.onWillShutdown((event) => { + event.join(this.flush(), { + id: "reviewTelemetryService.flush", + label: "Sending Review telemetry", + }); + }); + } + + capture(name: string, properties?: ReviewTelemetryProperties, error?: ReviewErrorReport): void { + if (this.configurationService.getValue(REVIEW_TELEMETRY_SETTING) === false) { + return; + } + const event = { name, properties, ...(error ? { error } : {}) }; + if (this.connection) { + this.send(event); + return; + } + this.queued.push(event); + if (this.queued.length > 100) this.queued.shift(); + } + + async flush(): Promise { + const flushPending = async (): Promise => { + await this.connectionPromise; + this.drainQueue(); + await Promise.all([...this.inFlight]); + }; + await Promise.race([ + flushPending(), + new Promise((resolve) => setTimeout(resolve, 500)), + ]); + } + + private drainQueue(): void { + if (!this.connection) return; + for (const event of this.queued.splice(0)) this.send(event); + } + + private send(event: QueuedReviewTelemetryEvent): void { + const connection = this.connection; + if (!connection) return; + let request: Promise; + request = fetch( + `${connection.url}/telemetry/event`, + reviewTelemetryEventRequest( + { token: connection.token, appSessionId: this.appSessionId }, + event, + { keepalive: true }, + ), + ) + .then(() => undefined) + .catch(() => undefined) + .finally(() => this.inFlight.delete(request)); + this.inFlight.add(request); + } +} diff --git a/apps/review-desktop/code-oss/src/vs/review/services/reviewWorkbenchServices.ts b/apps/review-desktop/code-oss/src/vs/review/services/reviewWorkbenchServices.ts new file mode 100644 index 000000000..eb658971b --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/services/reviewWorkbenchServices.ts @@ -0,0 +1,143 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from '../../base/common/event.js'; +import { DisposableStore, toDisposable } from '../../base/common/lifecycle.js'; +import type { URI } from '../../base/common/uri.js'; +import { InstantiationType, registerSingleton } from '../../platform/instantiation/common/extensions.js'; +import type { IInstantiationService } from '../../platform/instantiation/common/instantiation.js'; +import { type IBannerItem, IBannerService } from '../../workbench/services/banner/browser/bannerService.js'; +import type { IAuxiliaryStatusbarPart, IStatusbarEntryContainer } from '../../workbench/browser/parts/statusbar/statusbarPart.js'; +import { IExtensionsWorkbenchService } from '../../workbench/contrib/extensions/common/extensions.js'; +import { + IMultiDiffSourceResolverService, + MultiDiffSourceResolverService, +} from '../../workbench/contrib/multiDiffEditor/browser/multiDiffSourceResolverService.js'; +import { + IQuickDiffModelService, + type QuickDiffModelOptions, +} from '../../workbench/contrib/scm/browser/quickDiffModel.js'; +import { + type IStatusbarEntry, + type IStatusbarEntryAccessor, + type IStatusbarEntryLocation, + type IStatusbarEntryPriority, + IStatusbarService, + type IStatusbarStyleOverride, + type StatusbarAlignment, +} from '../../workbench/services/statusbar/browser/statusbar.js'; + +/** Accepts status messages from editor services without creating stock chrome. */ +class ReviewStatusbarService implements IStatusbarService { + declare readonly _serviceBrand: undefined; + readonly onDidChangeEntryVisibility = Event.None as Event<{ id: string; visible: boolean }>; + + getPart(_container: HTMLElement): IStatusbarEntryContainer { return this; } + createAuxiliaryStatusbarPart(_container: HTMLElement, _instantiationService: IInstantiationService): IAuxiliaryStatusbarPart { + throw new Error('Review does not provide status bar parts'); + } + createScoped(_statusbarEntryContainer: IStatusbarEntryContainer, _disposables: DisposableStore): IStatusbarService { return this; } + addEntry( + _entry: IStatusbarEntry, + _id: string, + _alignment: StatusbarAlignment, + _priority?: number | IStatusbarEntryPriority | IStatusbarEntryLocation, + ): IStatusbarEntryAccessor { + return { update() { }, dispose() { } }; + } + isEntryVisible(_id: string): boolean { return false; } + updateEntryVisibility(_id: string, _visible: boolean): void { } + overrideEntry(_id: string, _override: Partial) { return toDisposable(() => { }); } + focus(_preserveEntryFocus?: boolean): void { } + focusNextEntry(): void { } + focusPreviousEntry(): void { } + isEntryFocused(): boolean { return false; } + overrideStyle(_style: IStatusbarStyleOverride) { return toDisposable(() => { }); } + dispose(): void { } +} + +class ReviewBannerService implements IBannerService { + declare readonly _serviceBrand: undefined; + focus(): void { } + focusNextAction(): void { } + focusPreviousAction(): void { } + hide(_id: string): void { } + show(_item: IBannerItem): void { } +} + +/** + * MainThreadTextEditors asks for quick-diff metadata while synchronizing every + * editor. Review has no SCM provider surface, so there are no quick diffs to + * expose and constructing the stock model would incorrectly require SCM. + */ +class ReviewQuickDiffModelService implements IQuickDiffModelService { + declare readonly _serviceBrand: undefined; + + createQuickDiffModelReference(_resource: URI, _options?: QuickDiffModelOptions): undefined { + return undefined; + } +} + +/** + * MainThreadExtensionService needs the extension-workbench token in order to + * complete the extension-host handshake. Review deliberately has no extension + * marketplace UI, so expose only the inert management surface while the stock + * extension scanner and language-provider APIs remain fully available. + */ +class ReviewExtensionsWorkbenchService implements IExtensionsWorkbenchService { + declare readonly _serviceBrand: undefined; + readonly onChange = Event.None as IExtensionsWorkbenchService['onChange']; + readonly onReset = Event.None as IExtensionsWorkbenchService['onReset']; + readonly local: IExtensionsWorkbenchService['local'] = []; + readonly installed: IExtensionsWorkbenchService['installed'] = []; + readonly outdated: IExtensionsWorkbenchService['outdated'] = []; + readonly whenInitialized = Promise.resolve(); + readonly onDidChangeExtensionsNotification = Event.None as IExtensionsWorkbenchService['onDidChangeExtensionsNotification']; + + queryLocal(): Promise { return Promise.resolve([]); } + queryGallery(..._args: unknown[]): Promise { return this.unavailable(); } + getExtensions(..._args: unknown[]): Promise { return Promise.resolve([]); } + getResourceExtensions(): Promise { return Promise.resolve([]); } + canInstall(): Promise { return Promise.resolve(true); } + install(..._args: unknown[]): Promise { return this.unavailable(); } + installInServer(): Promise { return this.unavailable(); } + downloadVSIX(): Promise { return this.unavailable(); } + uninstall(): Promise { return this.unavailable(); } + togglePreRelease(): Promise { return this.unavailable(); } + canSetLanguage(): boolean { return false; } + setLanguage(): Promise { return this.unavailable(); } + setEnablement(): Promise { return Promise.resolve(); } + isAutoUpdateEnabledFor(): boolean { return false; } + updateAutoUpdateEnablementFor(): Promise { return Promise.resolve(); } + shouldRequireConsentToUpdate(): Promise { return Promise.resolve(undefined); } + updateAutoUpdateForAllExtensions(): Promise { return Promise.resolve(); } + open(): Promise { return this.unavailable(); } + openSearch(): Promise { return this.unavailable(); } + getAutoUpdateValue(): 'off' { return 'off'; } + isAutoUpdateDelayed(): boolean { return false; } + getAutoUpdateDelayRemaining(): number { return 0; } + getAutoUpdateDelay(): number { return 0; } + checkForUpdates(): Promise { return Promise.resolve(); } + getExtensionRuntimeStatus(): undefined { return undefined; } + updateAll(): Promise { return Promise.resolve([]); } + updateRunningExtensions(): Promise { return Promise.resolve(); } + getExtensionsNotification(): undefined { return undefined; } + isExtensionIgnoredToSync(): boolean { return false; } + toggleExtensionIgnoredToSync(): Promise { return Promise.resolve(); } + toggleApplyExtensionToAllProfiles(): Promise { return Promise.resolve(); } + + private unavailable(): Promise { + return Promise.reject(new Error('Review does not expose extension management')); + } +} + +registerSingleton(IStatusbarService, ReviewStatusbarService, InstantiationType.Eager); +registerSingleton(IBannerService, ReviewBannerService, InstantiationType.Eager); +registerSingleton(IExtensionsWorkbenchService, ReviewExtensionsWorkbenchService, InstantiationType.Eager); +registerSingleton(IQuickDiffModelService, ReviewQuickDiffModelService, InstantiationType.Eager); +// The in-tab diff builds a MultiDiffEditorInput, which resolves its sources +// through this service. Review never imports the upstream multi-diff editor +// contribution, so this is its only registration. +registerSingleton(IMultiDiffSourceResolverService, MultiDiffSourceResolverService, InstantiationType.Delayed); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/workspace/browser/workspaceContextService.ts b/apps/review-desktop/code-oss/src/vs/review/services/workspace/browser/workspaceContextService.ts similarity index 97% rename from apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/workspace/browser/workspaceContextService.ts rename to apps/review-desktop/code-oss/src/vs/review/services/workspace/browser/workspaceContextService.ts index 59e0144dc..3ae683658 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/workspace/browser/workspaceContextService.ts +++ b/apps/review-desktop/code-oss/src/vs/review/services/workspace/browser/workspaceContextService.ts @@ -16,7 +16,7 @@ import { Disposable } from '../../../../base/common/lifecycle.js'; import { localize } from '../../../../nls.js'; -export class WhiteboardWorkspaceContextService extends Disposable implements IWorkspaceContextService, IWorkspaceEditingService { +export class ReviewWorkspaceContextService extends Disposable implements IWorkspaceContextService, IWorkspaceEditingService { declare readonly _serviceBrand: undefined; @@ -38,7 +38,7 @@ export class WhiteboardWorkspaceContextService extends Disposable implements IWo private readonly uriIdentityService: IUriIdentityService, ) { super(); - this.workspace = new Workspace(workspaceIdentifier.id, [], false, workspaceIdentifier.configPath, uri => uriIdentityService.extUri.ignorePathCasing(uri), localize('whiteboardWindow', "Whiteboard")); + this.workspace = new Workspace(workspaceIdentifier.id, [], false, workspaceIdentifier.configPath, uri => uriIdentityService.extUri.ignorePathCasing(uri), localize('reviewWindow', "Review")); } getCompleteWorkspace(): Promise { diff --git a/apps/review-desktop/code-oss/src/vs/review/workspaceTrustConfigurationFilter.test.ts b/apps/review-desktop/code-oss/src/vs/review/workspaceTrustConfigurationFilter.test.ts new file mode 100644 index 000000000..c9796e449 --- /dev/null +++ b/apps/review-desktop/code-oss/src/vs/review/workspaceTrustConfigurationFilter.test.ts @@ -0,0 +1,108 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) dev.fast. All rights reserved. + * Licensed under the MIT License. See LICENSE in the repository root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Behavioural guard for the CVE-2026-81376 / CVE-2026-70334 backport +// (upstream 0684cb5905a3f23156f45a28135326e09310ff4d). An untrusted workspace +// could express a restricted setting as a nested object instead of a dotted +// key and slip past the Restricted Mode filter. These assertions fail against +// the unpatched parser, so they prove the fix rather than merely detecting a +// change to it. See apps/review-desktop/UPSTREAM. + +import assert from "node:assert/strict"; +import test from "node:test"; + +import { ConfigurationModelParser } from "../platform/configuration/common/configurationModels.js"; +import { + ConfigurationScope, + Extensions as ConfigurationExtensions, + type IConfigurationRegistry, +} from "../platform/configuration/common/configurationRegistry.js"; +import { NullLogService } from "../platform/log/common/log.js"; +import { Registry } from "../platform/registry/common/platform.js"; + +Registry.as( + ConfigurationExtensions.Configuration, +).registerConfiguration({ + id: "reviewTrustFilterFixture", + type: "object", + properties: { + "reviewTrustFixture.restricted": { + type: "string", + restricted: true, + scope: ConfigurationScope.RESOURCE, + }, + "reviewTrustFixture.safe": { + type: "string", + scope: ConfigurationScope.RESOURCE, + }, + "reviewTrustFixture.object": { + type: "object", + scope: ConfigurationScope.RESOURCE, + }, + }, +}); + +function parseUntrusted(content: object) { + const parser = new ConfigurationModelParser("test", new NullLogService()); + parser.parse(JSON.stringify(content), { skipRestricted: true }); + return parser; +} + +test("filters a restricted setting written as a dotted key", () => { + const parsed = parseUntrusted({ + "reviewTrustFixture.restricted": "attacker", + "reviewTrustFixture.safe": "kept", + }); + + assert.equal( + parsed.configurationModel.getValue("reviewTrustFixture.restricted"), + undefined, + ); + assert.equal( + parsed.configurationModel.getValue("reviewTrustFixture.safe"), + "kept", + ); + assert.deepEqual(parsed.restrictedConfigurations, [ + "reviewTrustFixture.restricted", + ]); +}); + +test("filters the same setting written as a nested object", () => { + const parsed = parseUntrusted({ + reviewTrustFixture: { restricted: "attacker", safe: "kept" }, + }); + + assert.equal( + parsed.configurationModel.getValue("reviewTrustFixture.restricted"), + undefined, + ); + assert.equal( + parsed.configurationModel.getValue("reviewTrustFixture.safe"), + "kept", + ); + assert.deepEqual(parsed.restrictedConfigurations, [ + "reviewTrustFixture.restricted", + ]); +}); + +test("leaves an object-valued setting intact", () => { + const parsed = parseUntrusted({ + "reviewTrustFixture.object": { a: 1, b: { c: 2 } }, + }); + + assert.deepEqual( + parsed.configurationModel.getValue("reviewTrustFixture.object"), + { a: 1, b: { c: 2 } }, + ); +}); + +test("leaves unregistered nested values reachable", () => { + const parsed = parseUntrusted({ unregistered: { deep: { value: 5 } } }); + + assert.equal( + parsed.configurationModel.getValue("unregistered.deep.value"), + 5, + ); +}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadBulkEdits.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadBulkEdits.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadBulkEdits.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadBulkEdits.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadClipboard.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadClipboard.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadClipboard.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadClipboard.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConfiguration.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConsole.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConsole.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConsole.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadConsole.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDebugService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDebugService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDebugService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDebugService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDecorations.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDecorations.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDiagnostics.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDiagnostics.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDiagnostics.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDiagnostics.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDialogs.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDialogs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDialogs.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDialogs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentContentProviders.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocuments.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocuments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocuments.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocuments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDownloadService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDownloadService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDownloadService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadDownloadService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditorTabs.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditorTabs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditorTabs.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditorTabs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadErrors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadErrors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadErrors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadErrors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystem.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLabelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLabelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLabelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLabelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguages.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguages.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguages.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLanguages.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLocalization.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLocalization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLocalization.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLocalization.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLogService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLogService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLogService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadLogService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadMessageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadMessageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadMessageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadMessageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadOutputService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadOutputService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadOutputService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadOutputService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadProgress.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadProgress.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadProgress.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadProgress.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadQuickOpen.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadQuickOpen.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadQuickOpen.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadQuickOpen.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadRemoteConnectionData.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadRemoteConnectionData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadRemoteConnectionData.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadRemoteConnectionData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSecretState.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSecretState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSecretState.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadSecretState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStatusBar.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStatusBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStatusBar.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStatusBar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStorage.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStorage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStorage.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadStorage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTelemetry.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTheming.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTheming.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTheming.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTheming.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTreeViews.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTreeViews.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadTreeViews.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWindow.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWindow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWindow.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWindow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWorkspace.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWorkspace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWorkspace.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/mainThreadWorkspace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/statusBarExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/statusBarExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/statusBarExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/statusBarExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/browser/viewsExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/browser/viewsExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/browser/viewsExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/cache.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/cache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/cache.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/cache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/configurationExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/configurationExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/configurationExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/configurationExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHost.api.impl.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHost.api.impl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHost.api.impl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHost.api.impl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHost.common.services.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHost.common.services.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHost.common.services.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHost.common.services.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHost.protocol.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHost.protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHost.protocol.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHost.protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAgentEditorComments.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAgentEditorComments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAgentEditorComments.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAgentEditorComments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAiRelatedInformation.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAiRelatedInformation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAiRelatedInformation.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAiRelatedInformation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAiSettingsSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAiSettingsSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAiSettingsSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAiSettingsSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostApiCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostApiCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostApiCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostApiCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostApiDeprecationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostApiDeprecationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostApiDeprecationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostApiDeprecationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAuthentication.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAuthentication.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostAuthentication.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostAuthentication.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostBrowserTunnelProxy.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostBrowserTunnelProxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostBrowserTunnelProxy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostBrowserTunnelProxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostBrowsers.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostBrowsers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostBrowsers.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostBrowsers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostBulkEdits.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostBulkEdits.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostBulkEdits.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostBulkEdits.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatAgents2.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatAgents2.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatAgents2.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatAgents2.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatContext.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatContext.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatDebug.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatDebug.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatDebug.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatDebug.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatInputNotification.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatInputNotification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatInputNotification.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatInputNotification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatOutputRenderer.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatOutputRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatOutputRenderer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatOutputRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatQuota.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatQuota.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatQuota.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatQuota.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatSessions.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatSessions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatSessions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatSessions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatStatus.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostChatStatus.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostChatStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostClipboard.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostClipboard.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostClipboard.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostClipboard.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCodeInsets.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCodeInsets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCodeInsets.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCodeInsets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCodeMapper.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCodeMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCodeMapper.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCodeMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostComments.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostComments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostComments.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostComments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostConfiguration.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostConsoleForwarder.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostConsoleForwarder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostConsoleForwarder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostConsoleForwarder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCustomEditors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCustomEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostCustomEditors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostCustomEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDataChannels.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDataChannels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDataChannels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDataChannels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDebugService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDebugService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDebugService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDebugService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDecorations.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDecorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDecorations.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDecorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDiagnostics.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDiagnostics.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDiagnostics.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDiagnostics.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDialogs.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDialogs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDialogs.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDialogs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentContentProviders.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentContentProviders.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentContentProviders.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentContentProviders.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentData.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentData.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocuments.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocuments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocuments.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocuments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostEditorTabs.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostEditorTabs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostEditorTabs.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostEditorTabs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostEmbedding.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostEmbedding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostEmbedding.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostEmbedding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostEmbeddingVector.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostEmbeddingVector.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostEmbeddingVector.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostEmbeddingVector.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionActivator.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionActivator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionActivator.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionActivator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystem.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystem.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemConsumer.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemConsumer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemConsumer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemConsumer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemEventService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemEventService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemEventService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemEventService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemInfo.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemInfo.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostFileSystemInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostGitExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostGitExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostGitExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostGitExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostInitDataService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostInitDataService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostInitDataService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostInitDataService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostInteractive.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostInteractive.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostInteractive.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostInteractive.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLabelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLabelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLabelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLabelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageFeatures.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageFeatures.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageFeatures.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModelTools.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModelTools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModelTools.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModelTools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModels.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguageModels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguages.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguages.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLanguages.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLanguages.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLocalizationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLocalizationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLocalizationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLocalizationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLogService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLogService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLogService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLogService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLoggerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLoggerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostLoggerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostLoggerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostManagedSockets.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostManagedSockets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostManagedSockets.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostManagedSockets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMcp.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMcp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMcp.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMcp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMemento.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMemento.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMemento.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMemento.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMessageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMessageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMessageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMessageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMeteredConnection.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMeteredConnection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostMeteredConnection.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostMeteredConnection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebook.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebook.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebook.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebook.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocument.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocument.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocument.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocument.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocumentSaveParticipant.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocumentSaveParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocumentSaveParticipant.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocumentSaveParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocuments.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocuments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocuments.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookDocuments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookKernels.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookKernels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookKernels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookKernels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookRenderers.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookRenderers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookRenderers.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostNotebookRenderers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostOutput.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostOutput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostOutput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostOutput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostPower.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostPower.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostPower.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostPower.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostProfileContentHandler.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostProfileContentHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostProfileContentHandler.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostProfileContentHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostProgress.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostProgress.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostProgress.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostProgress.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostQuickDiff.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostQuickDiff.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostQuickDiff.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostQuickDiff.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostQuickOpen.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostQuickOpen.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostQuickOpen.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostQuickOpen.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostRequireInterceptor.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostRequireInterceptor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostRequireInterceptor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostRequireInterceptor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostRpcService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostRpcService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostRpcService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostRpcService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSCM.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSCM.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSCM.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSCM.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSecretState.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSecretState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSecretState.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSecretState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSecrets.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSecrets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSecrets.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSecrets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostShare.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostShare.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostShare.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostShare.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSpeech.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSpeech.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostSpeech.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostSpeech.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostStatusBar.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostStatusBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostStatusBar.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostStatusBar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostStorage.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostStorage.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostStorage.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostStorage.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostStoragePaths.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostStoragePaths.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostStoragePaths.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostStoragePaths.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTask.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTask.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTask.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTask.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTelemetry.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTestItem.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTestItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTestItem.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTestItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTesting.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTesting.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTesting.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTesting.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTestingPrivateApi.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTestingPrivateApi.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTestingPrivateApi.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTestingPrivateApi.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditors.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTextEditors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTheming.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTheming.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTheming.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTheming.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTimeline.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTimeline.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTimeline.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTimeline.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTreeViews.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTreeViews.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTreeViews.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTreeViews.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTunnelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTunnelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypeConverters.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypeConverters.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypeConverters.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypeConverters.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/codeActionKind.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/codeActionKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/codeActionKind.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/codeActionKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/diagnostic.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/diagnostic.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/diagnostic.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/diagnostic.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/es5ClassCompat.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/es5ClassCompat.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/es5ClassCompat.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/es5ClassCompat.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/location.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/location.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/location.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/location.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/markdownString.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/markdownString.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/markdownString.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/markdownString.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/notebooks.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/notebooks.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/notebooks.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/notebooks.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/position.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/position.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/position.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/position.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/range.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/range.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/range.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/range.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/selection.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/selection.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/selection.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/selection.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetString.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetString.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetString.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetString.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetTextEdit.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetTextEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetTextEdit.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/snippetTextEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/symbolInformation.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/symbolInformation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/symbolInformation.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/symbolInformation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/textEdit.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/textEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/textEdit.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/textEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/workspaceEdit.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/workspaceEdit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/workspaceEdit.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostTypes/workspaceEdit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostUriOpener.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostUriOpener.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostUriOpener.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostUriOpener.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostUriTransformerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostUriTransformerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostUriTransformerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostUriTransformerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostUrls.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostUrls.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostUrls.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostUrls.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostVariableResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostVariableResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostVariableResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostVariableResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebview.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebview.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebview.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebview.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewMessaging.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewMessaging.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewMessaging.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewMessaging.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewPanels.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewPanels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewPanels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewPanels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewView.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewView.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWebviewView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWindow.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWindow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWindow.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWindow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWorkspace.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWorkspace.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostWorkspace.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostWorkspace.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostXaaAuthProvider.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostXaaAuthProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extHostXaaAuthProvider.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extHostXaaAuthProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extensionHostMain.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/extensionHostMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/extensionHostMain.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/extensionHostMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/jsonValidationExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/shared/dataTransferCache.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/shared/dataTransferCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/shared/dataTransferCache.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/shared/dataTransferCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/shared/tasks.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/common/shared/tasks.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/common/shared/tasks.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/common/shared/tasks.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHost.node.services.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHost.node.services.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHost.node.services.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHost.node.services.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostAuthentication.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostAuthentication.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostAuthentication.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostAuthentication.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostBrowserTunnelProxy.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostBrowserTunnelProxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostBrowserTunnelProxy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostBrowserTunnelProxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostCLIServer.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostCLIServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostCLIServer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostCLIServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostConsoleForwarder.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostConsoleForwarder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostConsoleForwarder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostConsoleForwarder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostDebugService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostDebugService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostDebugService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostDebugService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostDiskFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostDiskFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostDiskFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostDiskFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostDownloadService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostDownloadService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostDownloadService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostDownloadService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostLoggerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostLoggerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostLoggerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostLoggerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostMcpNode.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostMcpNode.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostMcpNode.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostMcpNode.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostStoragePaths.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostStoragePaths.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostStoragePaths.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostStoragePaths.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostTask.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostTask.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostTask.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostTask.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostTerminalService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostTerminalService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostTerminalService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostTerminalService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostTunnelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostTunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostTunnelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostTunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostVariableResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostVariableResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extHostVariableResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extHostVariableResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extensionHostProcess.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/extensionHostProcess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/extensionHostProcess.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/extensionHostProcess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/loopbackServer.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/loopbackServer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/loopbackServer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/loopbackServer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/proxyResolver.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/node/proxyResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/node/proxyResolver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/node/proxyResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extHost.worker.services.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/worker/extHost.worker.services.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extHost.worker.services.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/worker/extHost.worker.services.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extHostConsoleForwarder.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/worker/extHostConsoleForwarder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extHostConsoleForwarder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/worker/extHostConsoleForwarder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extHostExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/worker/extHostExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extHostExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/worker/extHostExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorker.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorkerMain.ts b/apps/review-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorkerMain.ts rename to apps/review-desktop/code-oss/src/vs/workbench/api/worker/extensionHostWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/layoutActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/layoutActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/layoutActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/layoutActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/listCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/listCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/listCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/listCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/navigationActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/navigationActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/navigationActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/navigationActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/quickAccessActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/quickAccessActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/quickAccessActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/quickAccessActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/textInputActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/textInputActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/textInputActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/textInputActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/widgetNavigationCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/widgetNavigationCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/widgetNavigationCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/widgetNavigationCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/windowActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/windowActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/windowActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/windowActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/workspaceActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/workspaceActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/workspaceActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/workspaceActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/workspaceCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/actions/workspaceCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/actions/workspaceCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/actions/workspaceCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/animatedCounterWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/animatedCounterWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/animatedCounterWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/animatedCounterWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/codeeditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/codeeditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/codeeditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/codeeditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/composite.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/composite.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/composite.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/composite.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/contextkeys.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/contextkeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/contextkeys.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/contextkeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/dnd.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/dnd.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/dnd.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/dnd.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/editor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/editor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/labels.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/labels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/labels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/labels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/layout.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/layout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/layout.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/layout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/animatedCounterWidget.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/media/animatedCounterWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/animatedCounterWidget.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/media/animatedCounterWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/code-icon.svg b/apps/review-desktop/code-oss/src/vs/workbench/browser/media/code-icon.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/code-icon.svg rename to apps/review-desktop/code-oss/src/vs/workbench/browser/media/code-icon.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/floatingPanels.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/media/floatingPanels.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/floatingPanels.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/media/floatingPanels.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/part.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/media/part.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/part.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/media/part.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/style.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/media/style.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/media/style.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/media/style.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/panecomposite.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/panecomposite.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/panecomposite.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/panecomposite.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/part.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/part.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/part.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/part.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activityaction.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activityaction.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activityaction.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activityaction.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/media/auxiliaryBarPart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/media/auxiliaryBarPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/media/auxiliaryBarPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/auxiliarybar/media/auxiliaryBarPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/compositeBar.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/compositeBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/compositeBar.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/compositeBar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/compositeBarActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/compositeBarActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/compositeBarActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/compositeBarActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/compositePart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/compositePart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/compositePart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/compositePart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialog.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialog.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/binaryEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbs.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditor.workbench.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditor.workbench.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditor.workbench.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditor.workbench.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommandsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommandsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommandsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/diffEditorCommandsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 50910866f..87dd7b7ca 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -12,7 +12,7 @@ import { EditorPartMultipleEditorGroupsContext, ActiveEditorDirtyContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, EditorTabsVisibleContext, ActiveEditorLastInGroupContext, EditorPartMaximizedEditorGroupContext, MultipleEditorGroupsContext, InEditorZenModeContext, IsAuxiliaryWindowContext, ActiveCompareEditorCanSwapContext, MultipleEditorsSelectedInGroupContext, SplitEditorsVertically, ActiveEditorCannotCloseContext, - IsSessionsWindowContext, IsWhiteboardWindowContext, ActiveCustomEditorDiffCanToggleLayoutContext, ActiveCustomEditorTextDiffContext, EditorPartModalContext + IsSessionsWindowContext, IsReviewWindowContext, ActiveCustomEditorDiffCanToggleLayoutContext, ActiveCustomEditorTextDiffContext, EditorPartModalContext } from '../../../common/contextkeys.js'; import { SideBySideEditorInput, SideBySideEditorInputSerializer } from '../../../common/editor/sideBySideEditorInput.js'; import { TextResourceEditor } from './textResourceEditor.js'; @@ -488,7 +488,7 @@ appendEditorToolItem( title: localize('splitEditorRight', "Split Editor Right"), icon: Codicon.splitHorizontal }, - ContextKeyExpr.and(SplitEditorsVertically.negate(), IsSessionsWindowContext.toNegated(), IsWhiteboardWindowContext.toNegated()), + ContextKeyExpr.and(SplitEditorsVertically.negate(), IsSessionsWindowContext.toNegated(), IsReviewWindowContext.toNegated()), SPLIT_ORDER, { id: SPLIT_EDITOR_DOWN, @@ -503,7 +503,7 @@ appendEditorToolItem( title: localize('splitEditorDown', "Split Editor Down"), icon: Codicon.splitVertical }, - ContextKeyExpr.and(SplitEditorsVertically, IsSessionsWindowContext.toNegated(), IsWhiteboardWindowContext.toNegated()), + ContextKeyExpr.and(SplitEditorsVertically, IsSessionsWindowContext.toNegated(), IsReviewWindowContext.toNegated()), SPLIT_ORDER, { id: SPLIT_EDITOR_RIGHT, diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorAutoSave.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorAutoSave.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorAutoSave.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorAutoSave.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommandsContext.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommandsContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommandsContext.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorCommandsContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorConfiguration.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorDropTarget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorDropTarget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorDropTarget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupView.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPane.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPane.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPane.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPane.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPanes.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPanes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPanes.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPanes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorParts.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorParts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorParts.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorParts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPlaceholder.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPlaceholder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPlaceholder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorPlaceholder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorStatus.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorStatus.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTabsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTabsControl.ts similarity index 98% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTabsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTabsControl.ts index c465319a7..96271b33b 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTabsControl.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTabsControl.ts @@ -26,7 +26,7 @@ import { EditorPane } from './editorPane.js'; import { IEditorGroupMenuIds, IEditorGroupsView, IEditorGroupView, IEditorPartsView, IInternalEditorOpenOptions } from './editor.js'; import { IEditorCommandsContext, EditorResourceAccessor, IEditorPartOptions, SideBySideEditor, EditorsOrder, EditorInputCapabilities, IToolbarActions, GroupIdentifier, Verbosity } from '../../../common/editor.js'; import { EditorInput } from '../../../common/editor/editorInput.js'; -import { ResourceContextKey, ActiveEditorPinnedContext, ActiveEditorStickyContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, ActiveEditorFirstInGroupContext, ActiveEditorAvailableEditorIdsContext, applyAvailableEditorIds, ActiveEditorLastInGroupContext, ActiveEditorCannotCloseContext, IsWhiteboardWindowContext } from '../../../common/contextkeys.js'; +import { ResourceContextKey, ActiveEditorPinnedContext, ActiveEditorStickyContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, ActiveEditorFirstInGroupContext, ActiveEditorAvailableEditorIdsContext, applyAvailableEditorIds, ActiveEditorLastInGroupContext, ActiveEditorCannotCloseContext, IsReviewWindowContext } from '../../../common/contextkeys.js'; import { AnchorAlignment } from '../../../../base/browser/ui/contextview/contextview.js'; import { assertReturnsDefined } from '../../../../base/common/types.js'; import { isFirefox } from '../../../../base/browser/browser.js'; @@ -107,9 +107,9 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC // --editor-group-tab-height CSS value (24px / 14px) plus that 8px padding. styleOverride: 32 as const, // 24px tab + 4px top + 4px bottom padding styleOverrideCompact: 28 as const, // 20px tab + 4px top + 4px bottom padding (20px = minimum to fit 16px icon + 2px padding) - // Review pill tabs (review/browser/media/whiteboard.css) add 6px top + 6px + // Review pill tabs (review/browser/media/review.css) add 6px top + 6px // bottom padding to the tabs-and-actions-container. The total must equal - // WHITEBOARD_CHROME_HEIGHT, because the Review titlebar overlays this row. + // REVIEW_CHROME_HEIGHT, because the Review titlebar overlays this row. review: 40 as const, // 28px pill + 6px top + 6px bottom padding reviewCompact: 32 as const, // 20px pill + 6px top + 6px bottom padding }; @@ -355,7 +355,7 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC // Review has no editor management surface, so it drops the secondary // actions and with them the toolbar's "..." overflow button. Primary // actions (e.g. the diff layout toggle) still render. - const visibleSecondary = IsWhiteboardWindowContext.getValue(this.contextKeyService) ? [] : secondary; + const visibleSecondary = IsReviewWindowContext.getValue(this.contextKeyService) ? [] : secondary; editorActionsToolbar.setActions(prepareActions(primary), prepareActions(visibleSecondary)); this.editorActionsToolbarHasActions = primary.length > 0 || visibleSecondary.length > 0; @@ -585,7 +585,7 @@ export abstract class EditorTabsControl extends Themable implements IEditorTabsC return isCompact ? EditorTabsControl.EDITOR_TAB_HEIGHT.styleOverrideCompact : EditorTabsControl.EDITOR_TAB_HEIGHT.styleOverride; } // The Review workbench draws its own pill tabs with the same shape. - if (this.parent.classList.contains('tabs') && this.parent.closest('.whiteboard-workbench')) { + if (this.parent.classList.contains('tabs') && this.parent.closest('.review-workbench')) { return isCompact ? EditorTabsControl.EDITOR_TAB_HEIGHT.reviewCompact : EditorTabsControl.EDITOR_TAB_HEIGHT.review; } return isCompact ? EditorTabsControl.EDITOR_TAB_HEIGHT.compact : EditorTabsControl.EDITOR_TAB_HEIGHT.normal; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTitleControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTitleControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTitleControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTitleControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTypePicker.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTypePicker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTypePicker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorTypePicker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorWithViewState.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorWithViewState.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorWithViewState.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorWithViewState.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorsObserver.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorsObserver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorsObserver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/editorsObserver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/back-tb.png b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/back-tb.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/back-tb.png rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/back-tb.png diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editordroptarget.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editordroptarget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editordroptarget.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editordroptarget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorgroupview.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorgroupview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorgroupview.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorgroupview.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorplaceholder.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorplaceholder.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorplaceholder.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorplaceholder.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorquickaccess.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorquickaccess.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorquickaccess.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorquickaccess.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorstatus.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorstatus.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorstatus.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editorstatus.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortabscontrol.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortabscontrol.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortabscontrol.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortabscontrol.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortitlecontrol.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortitlecontrol.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortitlecontrol.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/editortitlecontrol.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/forward-tb.png b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/forward-tb.png similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/forward-tb.png rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/forward-tb.png diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-dark.svg b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-dark.svg rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcDark.svg b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcDark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcDark.svg rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcDark.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcLight.svg b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcLight.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcLight.svg rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-hcLight.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-light.svg b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-light.svg rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/letterpress-light.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/modalEditorPart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/modalEditorPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/modalEditorPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/modalEditorPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/sidebysideeditor.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/sidebysideeditor.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/sidebysideeditor.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/sidebysideeditor.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/modalEditorPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/modalEditorPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/modalEditorPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/modalEditorPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiRowEditorTabsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiRowEditorTabsControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiRowEditorTabsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/multiRowEditorTabsControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/noEditorTabsControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/sideBySideEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textCodeEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textCodeEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textCodeEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textCodeEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textDiffEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textDiffEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textDiffEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textResourceEditor.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textResourceEditor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/editor/textResourceEditor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/editor/textResourceEditor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/globalCompositeBar.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/globalCompositeBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/globalCompositeBar.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/globalCompositeBar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/media/compositepart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/media/compositepart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/media/compositepart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/media/compositepart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/media/paneCompositePart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/media/paneCompositePart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/media/paneCompositePart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/media/paneCompositePart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsCenter.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsList.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsList.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsList.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsList.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsToasts.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsToasts.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsToasts.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/media/notificationsToasts.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsAlerts.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsAlerts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsAlerts.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsAlerts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsList.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsList.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsList.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsToasts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositeBar.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositeBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositeBar.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositeBar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositePart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositePart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositePart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/paneCompositePart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/panel/media/panelpart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/panel/media/panelpart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/panel/media/panelpart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/panel/media/panelpart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/panel/panelPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/media/sidebarpart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/media/sidebarpart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/media/sidebarpart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/media/sidebarpart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/menubarControl.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/menubarControl.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/menubarControl.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/menubarControl.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/media/titlebarpart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/menubarControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/menubarControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/menubarControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/windowTitle.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/windowTitle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/windowTitle.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/titlebar/windowTitle.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/checkbox.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/checkbox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/checkbox.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/checkbox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/media/paneviewlet.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/media/paneviewlet.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/media/paneviewlet.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/media/paneviewlet.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/media/views.css b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/media/views.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/media/views.css rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/media/views.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/treeView.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/treeView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/treeView.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/treeView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewFilter.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewFilter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewFilter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewFilter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewMenuActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewMenuActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewMenuActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewMenuActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPane.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPane.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPane.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPane.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPaneContainer.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPaneContainer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPaneContainer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewPaneContainer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewsViewlet.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/views/viewsViewlet.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/views/viewsViewlet.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/visibleViewContainersTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/parts/visibleViewContainersTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/parts/visibleViewContainersTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/parts/visibleViewContainersTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/quickaccess.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/quickaccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/quickaccess.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/quickaccess.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/style.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/style.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/style.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/style.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/web.api.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/web.api.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/web.api.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/web.api.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/window.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/window.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/window.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/window.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/workbench.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/workbench.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/workbench.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/workbench.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/workbench.ts b/apps/review-desktop/code-oss/src/vs/workbench/browser/workbench.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/browser/workbench.ts rename to apps/review-desktop/code-oss/src/vs/workbench/browser/workbench.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/activity.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/activity.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/activity.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/activity.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/agentTheme.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/agentTheme.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/agentTheme.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/agentTheme.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/comments.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/comments.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/comments.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/comments.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/component.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/component.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/component.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/component.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/composite.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/composite.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/composite.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/composite.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/configuration.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/configuration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/configuration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/configuration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/contextkeys.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/contextkeys.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/contextkeys.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/contextkeys.ts index e8a92cd01..aa80b1955 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/contextkeys.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/common/contextkeys.ts @@ -34,7 +34,7 @@ export const TemporaryWorkspaceContext = new RawContextKey('temporaryWo export const IsSessionsWindowContext = new RawContextKey('isSessionsWindow', false, localize('isSessionsWindow', "Whether the current window is a agent sessions window.")); -export const IsWhiteboardWindowContext = new RawContextKey('isWhiteboardWindow', false, localize('isWhiteboardWindow', "Whether the current window is a Review window.")); +export const IsReviewWindowContext = new RawContextKey('isReviewWindow', false, localize('isReviewWindow', "Whether the current window is a Review window.")); export const HasWebFileSystemAccess = new RawContextKey('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access) diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/contributions.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/contributions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/contributions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/contributions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/dialogs.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/dialogs.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/dialogs.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/dialogs.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/binaryEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/binaryEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/binaryEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/binaryEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/diffEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/diffEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/diffEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/diffEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/diffEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/diffEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/diffEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/diffEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorGroupModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorGroupModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorGroupModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorGroupModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorOptions.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/editorOptions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/editorOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/filteredEditorGroupModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/filteredEditorGroupModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/filteredEditorGroupModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/filteredEditorGroupModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/resourceEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/resourceEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/resourceEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/resourceEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/sideBySideEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/sideBySideEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/sideBySideEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/sideBySideEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textDiffEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/textDiffEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textDiffEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/textDiffEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/textEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/textEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/editor/textResourceEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/memento.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/memento.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/memento.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/memento.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/notifications.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/notifications.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/notifications.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/notifications.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/panecomposite.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/panecomposite.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/panecomposite.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/panecomposite.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/resources.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/resources.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/resources.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/resources.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/theme.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/theme.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/theme.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/theme.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/common/views.ts b/apps/review-desktop/code-oss/src/vs/workbench/common/views.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/common/views.ts rename to apps/review-desktop/code-oss/src/vs/workbench/common/views.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibility.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityStatus.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityStatus.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityStatus.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibilityStatus.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewContributions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewContributions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewContributions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewContributions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewKeybindingResolver.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewKeybindingResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewKeybindingResolver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/accessibleViewKeybindingResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/editorAccessibilityHelp.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/editorAccessibilityHelp.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/editorAccessibilityHelp.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/editorAccessibilityHelp.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/common/accessibilityCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/common/accessibilityCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibility/common/accessibilityCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibility/common/accessibilityCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignal.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignal.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignal.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignal.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignalDebuggerContribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignalDebuggerContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignalDebuggerContribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/accessibilitySignalDebuggerContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/commands.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/commands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/commands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/commands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/openDiffEditorAnnouncement.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/openDiffEditorAnnouncement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/openDiffEditorAnnouncement.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/openDiffEditorAnnouncement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/saveAccessibilitySignal.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/saveAccessibilitySignal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/saveAccessibilitySignal.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/accessibilitySignals/browser/saveAccessibilitySignal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/daniel_neutral.mp3 b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/daniel_neutral.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/daniel_neutral.mp3 rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/daniel_neutral.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/kevin_neutral.mp3 b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/kevin_neutral.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/kevin_neutral.mp3 rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/kevin_neutral.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/maya_neutral.mp3 b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/maya_neutral.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/maya_neutral.mp3 rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/maya_neutral.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/sessions-icon.svg b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/sessions-icon.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/sessions-icon.svg rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/sessions-icon.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/victoria_neutral.mp3 b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/victoria_neutral.mp3 similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/victoria_neutral.mp3 rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/browser/media/victoria_neutral.mp3 diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoice.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoice.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoice.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoice.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoiceColors.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoiceColors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoiceColors.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/agentsVoiceColors.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/voiceTranscriptStore.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/voiceTranscriptStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/voiceTranscriptStore.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/agentsVoice/common/voiceTranscriptStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserView.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserView.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserView.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserView.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserZoomService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserZoomService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserZoomService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/browserView/common/browserZoomService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkCellEdits.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts similarity index 97% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts index 292415d77..ae2af6397 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts @@ -31,7 +31,7 @@ import { IWorkingCopyService } from '../../../services/workingCopy/common/workin import { OpaqueEdits, ResourceAttachmentEdit } from './opaqueEdits.js'; import { TextModelEditSource } from '../../../../editor/common/textModelEditSource.js'; import { isMacintosh } from '../../../../base/common/platform.js'; -import { isWhiteboardReadonlySource } from '../../../../whiteboard/common/whiteboardReadonlySource.js'; +import { isReviewReadonlySource } from '../../../../review/common/reviewReadonlySource.js'; import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; function liftEdits(edits: ResourceEdit[]): ResourceEdit[] { @@ -203,9 +203,9 @@ export class BulkEditService implements IBulkEditService { let edits = liftEdits(Array.isArray(editsIn) ? editsIn : editsIn.edits); // A command/code action originating in a review cannot edit workspace files. const source = (options?.editor ?? this._codeEditors.getFocusedCodeEditor() ?? this._codeEditors.getActiveCodeEditor())?.getModel()?.uri ?? this._editorService.activeEditor?.resource; - if (isWhiteboardReadonlySource(source) || edits.some(edit => - edit instanceof ResourceTextEdit && isWhiteboardReadonlySource(edit.resource) || - edit instanceof ResourceFileEdit && (isWhiteboardReadonlySource(edit.oldResource) || isWhiteboardReadonlySource(edit.newResource)))) { + if (isReviewReadonlySource(source) || edits.some(edit => + edit instanceof ResourceTextEdit && isReviewReadonlySource(edit.resource) || + edit instanceof ResourceFileEdit && (isReviewReadonlySource(edit.oldResource) || isReviewReadonlySource(edit.newResource)))) { return { ariaSummary: 'Review source is read-only. Open in workspace to edit.', isApplied: false }; } diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/bulkTextEdits.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/opaqueEdits.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/opaqueEdits.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/opaqueEdits.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/bulkEdit/browser/opaqueEdits.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/callHierarchy/common/callHierarchy.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/callHierarchy/common/callHierarchy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/callHierarchy/common/callHierarchy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/callHierarchy/common/callHierarchy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatClear.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatClear.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatClear.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatClear.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContext.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContext.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatQuickInputActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostAuth.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostAuth.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostAuth.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostAuth.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostFolderPickerActionItem.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostFolderPickerActionItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostFolderPickerActionItem.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostFolderPickerActionItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostGenericConfigChips.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostGenericConfigChips.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostGenericConfigChips.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostGenericConfigChips.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostImportConversationStore.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostImportConversationStore.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostImportConversationStore.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostImportConversationStore.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostNewSessionFolderService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostNewSessionFolderService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostNewSessionFolderService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostNewSessionFolderService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionReferenceAttachment.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionReferenceAttachment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionReferenceAttachment.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionReferenceAttachment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionUri.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionUri.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionWorkingDirectoryResolver.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionWorkingDirectoryResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionWorkingDirectoryResolver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionWorkingDirectoryResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSnapshotController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/importLocalConversationToAgentSession.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/importLocalConversationToAgentSession.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/importLocalConversationToAgentSession.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/importLocalConversationToAgentSession.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/media/agentHostChatInputPicker.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/media/agentHostChatInputPicker.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/media/agentHostChatInputPicker.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/media/agentHostChatInputPicker.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts index c2ca9af32..62e1654f5 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/stateToProgressAdapter.ts @@ -1727,7 +1727,7 @@ export function toolCallStateToInvocation(tc: ToolCallState, subAgentInvocationI // with `tool_start`. So no special-case for subagents is needed here.) const confirmationMessages: IToolConfirmationMessages = { title: isViewUnreviewedCommentsTool(tc.toolName) - ? localize('agentFeedback.whiteboardTitle', "Reveal unreviewed comments?") + ? localize('agentFeedback.reviewTitle', "Reveal unreviewed comments?") : stringOrMarkdownToString(tc.confirmationTitle, connectionAuthority) ?? tc.displayName, message: isViewUnreviewedCommentsTool(tc.toolName) ? localize('agentFeedback.reviewMessage', "Choose which comments to reveal to the agent. Unchecked comments stay hidden.") diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionApprovalModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionApprovalModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionApprovalModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionApprovalModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsPicker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentTitleBarStatusService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentTitleBarStatusService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentTitleBarStatusService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/experiments/agentTitleBarStatusService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentSessionHoverWidget.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentSessionHoverWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentSessionHoverWidget.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentSessionHoverWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/media/agentsessionsviewer.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/sessionTypeAvailability.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/sessionTypeAvailability.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/sessionTypeAvailability.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/agentSessions/sessionTypeAvailability.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentResolveService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentResolveService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentResolveService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentResolveService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgetRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgetRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgetRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgetRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatContextPickService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatContextPickService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatContextPickService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatContextPickService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatDynamicVariables.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatDynamicVariables.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatDynamicVariables.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatDynamicVariables.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatScreenshotContext.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatScreenshotContext.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatScreenshotContext.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatScreenshotContext.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatVariables.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatVariables.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatVariables.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/chatVariables.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chat.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chat.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chat.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chat.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorContextKeys.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorContextKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorContextKeys.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorContextKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingTextModelContentProviders.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatGoalSummaryService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatGoalSummaryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatGoalSummaryService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatGoalSummaryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageCarouselService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageCarouselService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageCarouselService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageCarouselService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageUtils.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageUtils.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatImageUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatOutputItemRenderer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatOutputItemRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatOutputItemRenderer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatOutputItemRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatResponseFileChangesService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatResponseFileChangesService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatResponseFileChangesService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatResponseFileChangesService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/media/chatSessionPickerActionItem.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/media/chatSessionPickerActionItem.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/media/chatSessionPickerActionItem.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSessions/media/chatSessionPickerActionItem.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-dark.svg b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-dark.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-dark.svg rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-dark.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-light.svg b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-light.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-light.svg rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/apple-light.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/github.svg b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/github.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/github.svg rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/github.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/google.svg b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/google.svg similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/google.svg rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatSetup/media/google.svg diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTerminalCommandPaste.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTerminalCommandPaste.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTerminalCommandPaste.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTerminalCommandPaste.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipCatalog.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipCatalog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipCatalog.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipCatalog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipEligibilityTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipEligibilityTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipEligibilityTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipEligibilityTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipStorageKeys.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipStorageKeys.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipStorageKeys.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/chatTipStorageKeys.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/contextContrib/chatContextService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/contextContrib/chatContextService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/contextContrib/chatContextService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/contextContrib/chatContextService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/copilotCliEventsUri.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/copilotCliEventsUri.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/copilotCliEventsUri.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/copilotCliEventsUri.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/media/chatTurnPills.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/media/chatTurnPills.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/media/chatTurnPills.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/media/chatTurnPills.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/planReviewFeedback/planReviewFeedbackService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/attachInstructionsAction.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptName.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/askForPromptSourceFolder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/promptFileRewriter.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/promptFileRewriter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/promptFileRewriter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/promptSyntax/promptFileRewriter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewWelcomeController.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewWelcomeController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewWelcomeController.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewWelcomeController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/viewsWelcome/chatViewsWelcome.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/micCaptureService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/micCaptureService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/micCaptureService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/micCaptureService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/ttsPlaybackService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/ttsPlaybackService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/ttsPlaybackService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/ttsPlaybackService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceGlow.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceGlow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceGlow.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceGlow.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceSessionController.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceSessionController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceSessionController.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceSessionController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceTelemetry.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceTelemetry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceTelemetry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceTelemetry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceToolDispatchService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceToolDispatchService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceToolDispatchService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/voiceClient/voiceToolDispatchService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentMarkdownRenderer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentMarkdownRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentMarkdownRenderer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentMarkdownRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAttachmentsContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAttachmentsContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAttachmentsContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAttachmentsContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAutoModeResolutionContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAutoModeResolutionContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAutoModeResolutionContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAutoModeResolutionContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleMarkdownContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleMarkdownContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleMarkdownContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleMarkdownContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollections.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollections.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollections.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollections.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentCodePools.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentCodePools.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentCodePools.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentCodePools.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentParts.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentParts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentParts.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatContentParts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDiffBlockPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDiffBlockPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDiffBlockPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDiffBlockPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatEditPillElement.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatEditPillElement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatEditPillElement.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatEditPillElement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorConfirmationPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorConfirmationPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorConfirmationPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorConfirmationPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatErrorContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExternalEditContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExternalEditContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExternalEditContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExternalEditContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animation.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animation.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animationRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animationRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animationRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/animationRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/blockAnimations.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/blockAnimations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/blockAnimations.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/animations/blockAnimations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/buffer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/buffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/buffer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/buffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/bufferRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/bufferRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/bufferRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/bufferRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/offBuffer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/offBuffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/offBuffer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/offBuffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/wordBuffer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/wordBuffer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/wordBuffer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/wordBuffer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/media/chatIncrementalRendering.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/media/chatIncrementalRendering.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/media/chatIncrementalRendering.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/media/chatIncrementalRendering.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownAnchorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownAnchorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownAnchorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownAnchorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownDecorationsRenderer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownDecorationsRenderer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownDecorationsRenderer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownDecorationsRenderer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownTableScrolling.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownTableScrolling.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownTableScrolling.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownTableScrolling.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpAuthenticationContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpAuthenticationContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpAuthenticationContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpAuthenticationContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersStartingContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersStartingContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersStartingContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersStartingContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatOutputPartStateCache.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatOutputPartStateCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatOutputPartStateCache.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatOutputPartStateCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPullRequestContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPullRequestContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPullRequestContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPullRequestContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSystemNotificationContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSystemNotificationContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSystemNotificationContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSystemNotificationContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTaskContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTaskContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTaskContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTaskContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingExternalResourcesWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingExternalResourcesWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingExternalResourcesWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingExternalResourcesWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolOutputContentSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolOutputContentSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolOutputContentSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolOutputContentSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTurnPillsPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTurnPillsPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTurnPillsPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTurnPillsPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAgentFeedbackReviewConfirmation.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAgentFeedbackReviewConfirmation.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAgentFeedbackReviewConfirmation.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAgentFeedbackReviewConfirmation.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAutoModeResolution.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAutoModeResolution.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAutoModeResolution.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatAutoModeResolution.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCodeBlockPill.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCodeBlockPill.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCodeBlockPill.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCodeBlockPill.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCollapsibleContentPart.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCollapsibleContentPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCollapsibleContentPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCollapsibleContentPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatConfirmationWidget.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatConfirmationWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatConfirmationWidget.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatConfirmationWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatDisabledClaudeHooksContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatDisabledClaudeHooksContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatDisabledClaudeHooksContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatDisabledClaudeHooksContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatExtensionsContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatExtensionsContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatExtensionsContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatExtensionsContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatHookContentPart.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatHookContentPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatHookContentPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatHookContentPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatInlineAnchorWidget.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatInlineAnchorWidget.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatInlineAnchorWidget.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatInlineAnchorWidget.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMarkdownPart.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMarkdownPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMarkdownPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMarkdownPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMcpServersInteractionContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMcpServersInteractionContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMcpServersInteractionContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatMcpServersInteractionContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPlanReview.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPlanReview.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPlanReview.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPlanReview.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPullRequestContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPullRequestContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPullRequestContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPullRequestContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSessionCreatedResult.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSessionCreatedResult.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSessionCreatedResult.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSessionCreatedResult.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSubagentContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSubagentContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSubagentContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatSubagentContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTerminalToolProgressPart.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTerminalToolProgressPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTerminalToolProgressPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTerminalToolProgressPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTipContent.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTipContent.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTipContent.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTipContent.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatToolConfirmationCarousel.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatToolConfirmationCarousel.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatToolConfirmationCarousel.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatToolConfirmationCarousel.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/codeBlockPart.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/codeBlockPart.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/codeBlockPart.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/codeBlockPart.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatAgentFeedbackReviewConfirmationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatAgentFeedbackReviewConfirmationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatAgentFeedbackReviewConfirmationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatAgentFeedbackReviewConfirmationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatInputOutputMarkdownProgressPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatInputOutputMarkdownProgressPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatInputOutputMarkdownProgressPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatInputOutputMarkdownProgressPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatResultListSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatResultListSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatResultListSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatResultListSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSandboxPrerequisiteConfirmationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSandboxPrerequisiteConfirmationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSandboxPrerequisiteConfirmationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSandboxPrerequisiteConfirmationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSessionCreatedResultSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSessionCreatedResultSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSessionCreatedResultSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSessionCreatedResultSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSimpleToolProgressPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSimpleToolProgressPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSimpleToolProgressPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSimpleToolProgressPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolOutputPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolOutputPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolOutputPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolOutputPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPostExecuteConfirmationPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPostExecuteConfirmationPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPostExecuteConfirmationPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPostExecuteConfirmationPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolProgressPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolProgressPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolProgressPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolProgressPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolStreamingSubPart.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolStreamingSubPart.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolStreamingSubPart.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolStreamingSubPart.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/media/toolRiskBadge.css b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/media/toolRiskBadge.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/media/toolRiskBadge.css rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/media/toolRiskBadge.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/terminalToolAutoExpand.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/terminalToolAutoExpand.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/terminalToolAutoExpand.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/terminalToolAutoExpand.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeHelper.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeHelper.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts index a23449f42..cf5e74e15 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts @@ -3252,7 +3252,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer('getConnection') + .getChannel(REVIEW_DESKTOP_CHANNEL) + .call('getConnection') .catch(() => undefined), ]); - const aboutDialogDetails = appendWhiteboardInstallId( + const aboutDialogDetails = appendReviewInstallId( createNativeAboutDialogDetails(this.productService, osProperties), connection?.installationId, ); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/electron-browser/parts/dialogs/dialogHandler.ts b/apps/review-desktop/code-oss/src/vs/workbench/electron-browser/parts/dialogs/dialogHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/electron-browser/parts/dialogs/dialogHandler.ts rename to apps/review-desktop/code-oss/src/vs/workbench/electron-browser/parts/dialogs/dialogHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/electron-browser/window.ts b/apps/review-desktop/code-oss/src/vs/workbench/electron-browser/window.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/electron-browser/window.ts rename to apps/review-desktop/code-oss/src/vs/workbench/electron-browser/window.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accessibility/common/accessibleViewInformationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/accessibility/common/accessibleViewInformationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accessibility/common/accessibleViewInformationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/accessibility/common/accessibleViewInformationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accessibility/electron-browser/accessibilityService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/accessibility/electron-browser/accessibilityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accessibility/electron-browser/accessibilityService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/accessibility/electron-browser/accessibilityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accounts/browser/defaultAccount.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/accounts/browser/defaultAccount.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accounts/browser/defaultAccount.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/accounts/browser/defaultAccount.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accounts/browser/managedSettings.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/accounts/browser/managedSettings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/accounts/browser/managedSettings.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/accounts/browser/managedSettings.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/actions/common/menusExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/actions/common/menusExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/actions/common/menusExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/activity/browser/activityService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/activity/browser/activityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/activity/browser/activityService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/activity/browser/activityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/activity/common/activity.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/activity/common/activity.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/activity/common/activity.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/activity/common/activity.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/aiSettingsSearch/common/aiSettingsSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/aiSettingsSearch/common/aiSettingsSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/aiSettingsSearch/common/aiSettingsSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/aiSettingsSearch/common/aiSettingsSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentContextFilter.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentContextFilter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentContextFilter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentContextFilter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentFilters.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentFilters.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentFilters.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentFilters.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/assignment/common/assignmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationAccessService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationAccessService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationAccessService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationAccessService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationExtensionsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationExtensionsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationExtensionsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationExtensionsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationUsageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationUsageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationUsageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/browser/authenticationUsageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/common/authentication.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/authentication/common/authentication.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/authentication/common/authentication.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/authentication/common/authentication.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/electron-browser/auxiliaryWindowService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/electron-browser/auxiliaryWindowService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/electron-browser/auxiliaryWindowService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/auxiliaryWindow/electron-browser/auxiliaryWindowService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/banner/browser/bannerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/banner/browser/bannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/banner/browser/bannerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/banner/browser/bannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/chat/common/chatEntitlementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/chat/common/chatEntitlementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/chat/common/chatEntitlementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/chat/common/chatEntitlementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/checksum/electron-browser/checksumService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/checksum/electron-browser/checksumService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/checksum/electron-browser/checksumService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/checksum/electron-browser/checksumService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/clipboard/electron-browser/clipboardService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/commands/common/commandService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/commands/common/commandService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/commands/common/commandService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/commands/common/commandService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/browser/configuration.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/browser/configuration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/browser/configuration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/browser/configuration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/browser/configurationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/browser/configurationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/browser/configurationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/browser/configurationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configuration.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configuration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configuration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configuration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationCache.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationCache.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationCache.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationCache.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationEditing.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationEditing.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationModels.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationModels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationModels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/configurationModels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditing.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditing.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditingService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditingService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditingService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configuration/common/jsonEditingService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverExpression.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverExpression.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverExpression.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverExpression.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/variableResolver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/variableResolver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/common/variableResolver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/electron-browser/configurationResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/electron-browser/configurationResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/configurationResolver/electron-browser/configurationResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/configurationResolver/electron-browser/configurationResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/contextmenu/electron-browser/contextmenuService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dataChannel/browser/dataChannelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/dataChannel/browser/dataChannelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dataChannel/browser/dataChannelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/dataChannel/browser/dataChannelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/decorations/browser/decorationsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/decorations/browser/decorationsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/decorations/browser/decorationsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/decorations/browser/decorationsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/decorations/common/decorations.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/decorations/common/decorations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/decorations/common/decorations.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/decorations/common/decorations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/browser/abstractFileDialogService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/common/dialogService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/common/dialogService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/common/dialogService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/common/dialogService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/electron-browser/fileDialogService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/electron-browser/fileDialogService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/dialogs/electron-browser/fileDialogService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/dialogs/electron-browser/fileDialogService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/driver/browser/driver.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/driver/browser/driver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/driver/browser/driver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/driver/browser/driver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/driver/common/driver.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/driver/common/driver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/driver/common/driver.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/driver/common/driver.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/codeEditorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/codeEditorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/codeEditorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/codeEditorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/editorPaneService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/editorPaneService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/editorPaneService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/editorPaneService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/editorResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/editorResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/editorResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/editorResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/editorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/editorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/browser/editorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/browser/editorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/customEditorLabelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/customEditorLabelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/customEditorLabelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/customEditorLabelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupColumn.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupColumn.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupColumn.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupColumn.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupFinder.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupFinder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupFinder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupFinder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorGroupsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorPaneService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorPaneService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorPaneService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorPaneService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/editor/common/editorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/editor/common/editorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/encryption/electron-browser/encryptionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/encryption/electron-browser/encryptionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/encryption/electron-browser/encryptionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/encryption/electron-browser/encryptionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/browser/environmentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/environment/browser/environmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/browser/environmentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/environment/browser/environmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/common/environmentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/environment/common/environmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/common/environmentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/environment/common/environmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/environmentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/environmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/environmentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/environmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/shellEnvironmentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/shellEnvironmentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/shellEnvironmentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/environment/electron-browser/shellEnvironmentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionBisect.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeatures.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeatures.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeatures.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeatures.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeaturesManagemetService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeaturesManagemetService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeaturesManagemetService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionFeaturesManagemetService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionGalleryService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionGalleryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionGalleryService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionGalleryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionsIcons.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionsIcons.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionsIcons.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/extensionsIcons.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/remoteExtensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/remoteExtensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/remoteExtensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/common/remoteExtensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/extensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/nativeExtensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/nativeExtensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/nativeExtensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/nativeExtensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/remoteExtensionManagementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/remoteExtensionManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/remoteExtensionManagementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionManagement/electron-browser/remoteExtensionManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionRecommendations.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionRecommendations.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionRecommendations.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/extensionRecommendations.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/abstractExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/abstractExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/abstractExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extHostCustomers.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extHostCustomers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extHostCustomers.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extHostCustomers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDevOptions.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDevOptions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDevOptions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionDevOptions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostEnv.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostEnv.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostEnv.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostEnv.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostKind.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostKind.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostKind.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostKind.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManagers.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManagers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManagers.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostManagers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProxy.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProxy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProxy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionHostProxy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionPoints.json b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionPoints.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionPoints.json rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionPoints.json diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocation.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocation.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocationTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocationTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocationTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionRunningLocationTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionStorageMigration.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionStorageMigration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionStorageMigration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionStorageMigration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensions.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensions.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsUtil.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/extensionsUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyCreateExtensionHostManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyCreateExtensionHostManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyCreateExtensionHostManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyCreateExtensionHostManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyPromise.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyPromise.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyPromise.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/lazyPromise.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/polyfillNestedWorker.protocol.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/polyfillNestedWorker.protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/polyfillNestedWorker.protocol.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/polyfillNestedWorker.protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/proxyIdentifier.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/proxyIdentifier.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/proxyIdentifier.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/proxyIdentifier.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteConsoleUtil.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteConsoleUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteConsoleUtil.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteConsoleUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/rpcProtocol.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/rpcProtocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/rpcProtocol.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/rpcProtocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/workspaceContains.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/workspaceContains.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/common/workspaceContains.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/common/workspaceContains.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionHostStarter.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionHostStarter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionHostStarter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionHostStarter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionsScannerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionsScannerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionsScannerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/extensionsScannerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/electron-browser/nativeExtensionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/worker/polyfillNestedWorker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/worker/polyfillNestedWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/worker/polyfillNestedWorker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/worker/polyfillNestedWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html b/apps/review-desktop/code-oss/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html rename to apps/review-desktop/code-oss/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/common/elevatedFileService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/files/common/elevatedFileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/common/elevatedFileService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/files/common/elevatedFileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/electron-browser/diskFileSystemProvider.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/files/electron-browser/diskFileSystemProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/electron-browser/diskFileSystemProvider.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/files/electron-browser/diskFileSystemProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/electron-browser/elevatedFileService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/files/electron-browser/elevatedFileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/electron-browser/elevatedFileService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/files/electron-browser/elevatedFileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/electron-browser/watcherClient.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/files/electron-browser/watcherClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/files/electron-browser/watcherClient.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/files/electron-browser/watcherClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/history/browser/historyService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/history/browser/historyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/history/browser/historyService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/history/browser/historyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/history/common/history.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/history/common/history.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/history/common/history.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/history/common/history.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/host/browser/host.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/host/browser/host.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/host/browser/host.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/host/browser/host.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/host/browser/toasts.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/host/browser/toasts.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/host/browser/toasts.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/host/browser/toasts.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/host/electron-browser/nativeHostService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/host/electron-browser/nativeHostService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/host/electron-browser/nativeHostService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/host/electron-browser/nativeHostService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/imageResize/electron-browser/imageResizeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/imageResize/electron-browser/imageResizeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/imageResize/electron-browser/imageResizeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/imageResize/electron-browser/imageResizeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/inlineCompletions/common/inlineCompletionsUnification.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/inlineCompletions/common/inlineCompletionsUnification.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/inlineCompletions/common/inlineCompletionsUnification.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/inlineCompletions/common/inlineCompletionsUnification.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/integrity/common/integrity.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/integrity/common/integrity.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/integrity/common/integrity.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/integrity/common/integrity.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/integrity/electron-browser/integrityService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/integrity/electron-browser/integrityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/integrity/electron-browser/integrityService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/integrity/electron-browser/integrityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keybindingService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keybindingService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keybindingService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dvorak.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dvorak.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dvorak.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dvorak.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/navigatorKeyboard.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/navigatorKeyboard.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/navigatorKeyboard.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/navigatorKeyboard.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/unboundCommands.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/unboundCommands.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/browser/unboundCommands.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/browser/unboundCommands.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/fallbackKeyboardMapper.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/fallbackKeyboardMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/fallbackKeyboardMapper.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/fallbackKeyboardMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingEditing.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingIO.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingIO.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingIO.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/keybindingIO.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/keymapInfo.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/keymapInfo.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/keymapInfo.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayout.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayout.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayout.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayout.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayoutService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayoutService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayoutService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/keybinding/electron-browser/nativeKeyboardLayoutService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/label/common/labelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/label/common/labelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/label/common/labelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/label/common/labelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/language/common/languageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/language/common/languageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/language/common/languageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/language/common/languageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorker.protocol.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/common/languageDetectionWorkerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/common/languageDetectionWorkerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageDetection/common/languageDetectionWorkerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/languageDetection/common/languageDetectionWorkerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageStatus/common/languageStatusService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/languageStatus/common/languageStatusService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/languageStatus/common/languageStatusService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/languageStatus/common/languageStatusService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/layout/browser/layoutService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/layout/browser/layoutService.ts similarity index 99% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/layout/browser/layoutService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/layout/browser/layoutService.ts index f57a7f83e..553dca2ca 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/layout/browser/layoutService.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/services/layout/browser/layoutService.ts @@ -26,8 +26,8 @@ export const enum Parts { PANEL_PART = 'workbench.parts.panel', AUXILIARYBAR_PART = 'workbench.parts.auxiliarybar', SESSIONS_PART = 'workbench.parts.sessions', - WHITEBOARD_CANVAS_PART = 'workbench.parts.sessions', - WHITEBOARD_EXPLORER_PART = 'workbench.parts.reviewexplorer', + REVIEW_CANVAS_PART = 'workbench.parts.sessions', + REVIEW_EXPLORER_PART = 'workbench.parts.reviewexplorer', EDITOR_PART = 'workbench.parts.editor', STATUSBAR_PART = 'workbench.parts.statusbar' } diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/browser/lifecycleService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycle.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycle.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycle.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycle.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycleService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycleService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycleService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/common/lifecycleService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/lifecycle/electron-browser/lifecycleService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/localization/common/locale.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/localization/common/locale.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/localization/common/locale.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/localization/common/locale.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/languagePackService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/languagePackService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/languagePackService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/languagePackService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/localeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/localeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/localeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/localization/electron-browser/localeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/log/common/defaultLogLevels.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/log/common/defaultLogLevels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/log/common/defaultLogLevels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/log/common/defaultLogLevels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/log/common/logConstants.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/log/common/logConstants.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/log/common/logConstants.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/log/common/logConstants.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/log/electron-browser/logService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/log/electron-browser/logService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/log/electron-browser/logService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/log/electron-browser/logService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/menubar/electron-browser/menubarService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/menubar/electron-browser/menubarService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/menubar/electron-browser/menubarService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/menubar/electron-browser/menubarService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/model/common/modelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/model/common/modelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/model/common/modelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/model/common/modelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/notebook/common/notebookDocumentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/notebook/common/notebookDocumentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/notebook/common/notebookDocumentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/notebook/common/notebookDocumentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/notification/common/notificationService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/notification/common/notificationService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/notification/common/notificationService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/notification/common/notificationService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/outline/browser/outline.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/outline/browser/outline.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/outline/browser/outline.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/outline/browser/outline.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/outline/browser/outlineService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/outline/browser/outlineService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/outline/browser/outlineService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/outline/browser/outlineService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/output/common/output.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/output/common/output.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/output/common/output.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/output/common/output.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/panecomposite/browser/panecomposite.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/panecomposite/browser/panecomposite.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/panecomposite/browser/panecomposite.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/panecomposite/browser/panecomposite.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/path/common/pathService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/path/common/pathService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/path/common/pathService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/path/common/pathService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/path/electron-browser/pathService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/path/electron-browser/pathService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/path/electron-browser/pathService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/path/electron-browser/pathService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/policies/common/accountPolicyService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/policies/common/accountPolicyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/policies/common/accountPolicyService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/policies/common/accountPolicyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/browser/preferencesService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/browser/preferencesService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/browser/preferencesService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/browser/preferencesService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferences.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferences.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferences.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferences.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesModels.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesModels.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesModels.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesModels.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesValidation.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesValidation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesValidation.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/preferences/common/preferencesValidation.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/process/electron-browser/processService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/process/electron-browser/processService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/process/electron-browser/processService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/process/electron-browser/processService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/progress/browser/media/progressService.css b/apps/review-desktop/code-oss/src/vs/workbench/services/progress/browser/media/progressService.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/progress/browser/media/progressService.css rename to apps/review-desktop/code-oss/src/vs/workbench/services/progress/browser/media/progressService.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/progress/browser/progressIndicator.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/progress/browser/progressIndicator.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/progress/browser/progressIndicator.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/progress/browser/progressIndicator.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/progress/browser/progressService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/progress/browser/progressService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/progress/browser/progressService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/progress/browser/progressService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/quickinput/browser/quickInputService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/quickinput/browser/quickInputService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/quickinput/browser/quickInputService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/quickinput/browser/quickInputService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteAgentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExplorerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExplorerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExplorerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteExtensionsScanner.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteFileSystemProviderClient.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteFileSystemProviderClient.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/remoteFileSystemProviderClient.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/remoteFileSystemProviderClient.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/tunnelModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/tunnelModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/common/tunnelModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/common/tunnelModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/electron-browser/remoteAgentService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/remote/electron-browser/remoteAgentService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/remote/electron-browser/remoteAgentService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/remote/electron-browser/remoteAgentService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/request/electron-browser/requestService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/request/electron-browser/requestService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/request/electron-browser/requestService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/request/electron-browser/requestService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/fileSearchManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/fileSearchManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/fileSearchManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/fileSearchManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/folderQuerySearchTree.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/folderQuerySearchTree.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/folderQuerySearchTree.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/folderQuerySearchTree.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/getFileResults.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/getFileResults.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/getFileResults.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/getFileResults.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/ignoreFile.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/ignoreFile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/ignoreFile.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/ignoreFile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/localFileSearchWorkerTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/queryBuilder.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/queryBuilder.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/queryBuilder.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/queryBuilder.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/search.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/search.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/search.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/search.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchExtConversionTypes.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchExtConversionTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchExtConversionTypes.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchExtConversionTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypes.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypes.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypes.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypesInternal.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypesInternal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypesInternal.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchExtTypesInternal.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchHelpers.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchHelpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchHelpers.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchHelpers.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/searchService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/searchService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/textSearchManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/common/textSearchManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/common/textSearchManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/common/textSearchManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/electron-browser/searchService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/electron-browser/searchService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/electron-browser/searchService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/electron-browser/searchService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/fileSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/fileSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/fileSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/fileSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/rawSearchService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/rawSearchService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/rawSearchService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/rawSearchService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepFileSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepFileSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepFileSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepFileSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchProvider.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchProvider.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchProvider.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchProvider.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchUtils.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchUtils.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepSearchUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/textSearchAdapter.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/textSearchAdapter.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/textSearchAdapter.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/textSearchAdapter.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/textSearchManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/node/textSearchManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/node/textSearchManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/node/textSearchManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearch.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearch.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearch.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearch.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearchMain.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearchMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearchMain.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/search/worker/localFileSearchMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/secrets/electron-browser/secretStorageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/secrets/electron-browser/secretStorageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/secrets/electron-browser/secretStorageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/secrets/electron-browser/secretStorageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/sharedProcess/electron-browser/sharedProcessService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/sharedProcess/electron-browser/sharedProcessService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/sharedProcess/electron-browser/sharedProcessService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/sharedProcess/electron-browser/sharedProcessService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/statusbar/browser/statusbar.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/statusbar/browser/statusbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/statusbar/browser/statusbar.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/statusbar/browser/statusbar.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/storage/electron-browser/storageService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/storage/electron-browser/storageService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/storage/electron-browser/storageService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/storage/electron-browser/storageService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchCommonProperties.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchCommonProperties.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchCommonProperties.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchCommonProperties.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchTelemetryUtils.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchTelemetryUtils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchTelemetryUtils.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/telemetry/common/workbenchTelemetryUtils.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/terminal/common/embedderTerminalService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/terminal/common/embedderTerminalService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/terminal/common/embedderTerminalService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/terminal/common/embedderTerminalService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/textMateWorkerTokenizerController.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/threadedBackgroundTokenizerFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.worker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerHost.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerTokenizer.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerTokenizer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerTokenizer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateWorkerTokenizer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/indexTransformer.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/indexTransformer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/indexTransformer.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/indexTransformer.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeature.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/textMateTokenizationFeatureImpl.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/textMateTokenizationSupport.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/tokenizationSupportWithLineLimit.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/tokenizationSupportWithLineLimit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/tokenizationSupportWithLineLimit.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/browser/tokenizationSupport/tokenizationSupportWithLineLimit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammarFactory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammars.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammars.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammars.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMGrammars.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMHelper.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMHelper.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMHelper.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMHelper.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/cgmanifest.json b/apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textMate/common/cgmanifest.json rename to apps/review-desktop/code-oss/src/vs/workbench/services/textMate/common/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/browser/textFileService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/browser/textFileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/browser/textFileService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/browser/textFileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/encoding.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/encoding.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/encoding.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/encoding.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textEditorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textEditorService.ts similarity index 96% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textEditorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textEditorService.ts index 78780cd6c..2a54fd399 100644 --- a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textEditorService.ts +++ b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textEditorService.ts @@ -24,8 +24,8 @@ import { IEditorResolverService, RegisteredEditorPriority } from '../../editor/c import { Disposable } from '../../../../base/common/lifecycle.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { onUnexpectedError } from '../../../../base/common/errors.js'; -import { isWhiteboardReadonlySource } from '../../../../whiteboard/common/whiteboardReadonlySource.js'; -import { WhiteboardSourceEditorInput } from '../../../../whiteboard/services/whiteboardSourceEditorInput.js'; +import { isReviewReadonlySource } from '../../../../review/common/reviewReadonlySource.js'; +import { ReviewSourceEditorInput } from '../../../../review/services/reviewSourceEditorInput.js'; export const ITextEditorService = createDecorator('textEditorService'); @@ -179,8 +179,8 @@ export class TextEditorService extends Disposable implements ITextEditorService const canonicalResource = this.uriIdentityService.asCanonicalUri(preferredResource); return this.createOrGetCached(canonicalResource, () => { - if (isWhiteboardReadonlySource(canonicalResource)) { - return this.instantiationService.createInstance(WhiteboardSourceEditorInput, canonicalResource, textResourceEditorInput.label, textResourceEditorInput.description, undefined, undefined); + if (isReviewReadonlySource(canonicalResource)) { + return this.instantiationService.createInstance(ReviewSourceEditorInput, canonicalResource, textResourceEditorInput.label, textResourceEditorInput.description, undefined, undefined); } // File diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textFileSaveParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textfiles.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textfiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/common/textfiles.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/common/textfiles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textresourceProperties/common/textResourcePropertiesService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/textresourceProperties/common/textResourcePropertiesService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/textresourceProperties/common/textResourcePropertiesService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/textresourceProperties/common/textResourcePropertiesService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/colorThemeCss.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/colorThemeCss.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/colorThemeCss.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/colorThemeCss.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/cssExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/cssExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/cssExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/cssExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/fileIconThemeData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/fileIconThemeData.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/fileIconThemeData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/productIconThemeData.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/productIconThemeData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/productIconThemeData.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/productIconThemeData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/workbenchThemeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/browser/workbenchThemeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/browser/workbenchThemeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/colorExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/colorExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/colorExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/colorExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeData.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeData.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeData.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeData.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeSchema.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeSchema.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/colorThemeSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/hostColorSchemeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/hostColorSchemeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/hostColorSchemeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/hostColorSchemeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/iconExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/iconExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/iconExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/iconExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/plistParser.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/plistParser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/plistParser.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/plistParser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/productIconThemeSchema.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/productIconThemeSchema.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/productIconThemeSchema.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/productIconThemeSchema.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/textMateScopeMatcher.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/textMateScopeMatcher.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/textMateScopeMatcher.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/textMateScopeMatcher.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/themeCompatibility.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/themeCompatibility.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/themeCompatibility.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/themeCompatibility.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/themeConfiguration.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/themeConfiguration.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/themeConfiguration.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/themeConfiguration.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/themeExtensionPoints.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/themeExtensionPoints.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/themeExtensionPoints.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/themeExtensionPoints.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/tokenClassificationExtensionPoint.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/tokenClassificationExtensionPoint.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/tokenClassificationExtensionPoint.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/tokenClassificationExtensionPoint.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/workbenchThemeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/workbenchThemeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/common/workbenchThemeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/common/workbenchThemeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/nativeHostColorSchemeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/nativeHostColorSchemeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/nativeHostColorSchemeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/nativeHostColorSchemeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/themes.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/themes.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/themes.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/themes/electron-browser/themes.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/timer/browser/timerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/timer/browser/timerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/timer/browser/timerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/timer/browser/timerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/timer/electron-browser/timerService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/timer/electron-browser/timerService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/timer/electron-browser/timerService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/timer/electron-browser/timerService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/title/browser/titleService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/title/browser/titleService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/title/browser/titleService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/title/browser/titleService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitter.contribution.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitter.contribution.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitter.contribution.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitter.contribution.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterLibraryService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterLibraryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterLibraryService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterLibraryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterThemeService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterThemeService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterThemeService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/treeSitter/browser/treeSitterThemeService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/tunnel/electron-browser/tunnelService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/tunnel/electron-browser/tunnelService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/tunnel/electron-browser/tunnelService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/tunnel/electron-browser/tunnelService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/untitled/common/untitledTextEditorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/update/browser/updateService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/update/browser/updateService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/update/browser/updateService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/update/browser/updateService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/update/electron-browser/updateService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/update/electron-browser/updateService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/update/electron-browser/updateService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/update/electron-browser/updateService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/url/browser/urlService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/url/browser/urlService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/url/browser/urlService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/url/browser/urlService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/url/electron-browser/urlService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/url/electron-browser/urlService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/url/electron-browser/urlService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/url/electron-browser/urlService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/browser/domActivityTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/browser/domActivityTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/browser/domActivityTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/browser/domActivityTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/browser/userActivityBrowser.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/browser/userActivityBrowser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/browser/userActivityBrowser.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/browser/userActivityBrowser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityRegistry.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userActivity/common/userActivityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userAttention/browser/userAttentionBrowser.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userAttention/browser/userAttentionBrowser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userAttention/browser/userAttentionBrowser.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userAttention/browser/userAttentionBrowser.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userAttention/common/userAttentionService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userAttention/common/userAttentionService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userAttention/common/userAttentionService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userAttention/common/userAttentionService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userData/browser/userDataInit.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userData/browser/userDataInit.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userData/browser/userDataInit.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userData/browser/userDataInit.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/extensionsResource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/globalStateResource.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/globalStateResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/globalStateResource.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/globalStateResource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/iconSelectBox.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/iconSelectBox.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/iconSelectBox.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/iconSelectBox.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/keybindingsResource.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/keybindingsResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/keybindingsResource.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/keybindingsResource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/settingsResource.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/settingsResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/settingsResource.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/settingsResource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/snippetsResource.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/snippetsResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/snippetsResource.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/snippetsResource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/tasksResource.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/tasksResource.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/tasksResource.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/tasksResource.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/remoteUserDataProfiles.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfile.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileIcons.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncEnablementService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncEnablementService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncEnablementService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncEnablementService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSync.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSync.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSync.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSync.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSyncUtil.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSyncUtil.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSyncUtil.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/common/userDataSyncUtil.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/utilityProcess/electron-browser/utilityProcessWorkerWorkbenchService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/utilityProcess/electron-browser/utilityProcessWorkerWorkbenchService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/utilityProcess/electron-browser/utilityProcessWorkerWorkbenchService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/utilityProcess/electron-browser/utilityProcessWorkerWorkbenchService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/browser/viewDescriptorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/views/browser/viewDescriptorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/browser/viewDescriptorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/views/browser/viewDescriptorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/browser/viewsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/views/browser/viewsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/browser/viewsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/views/browser/viewsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/common/viewContainerModel.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/views/common/viewContainerModel.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/common/viewContainerModel.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/views/common/viewContainerModel.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/common/viewsService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/views/common/viewsService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/views/common/viewsService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/views/common/viewsService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/abstractFileWorkingCopyManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/abstractFileWorkingCopyManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/abstractFileWorkingCopyManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/abstractFileWorkingCopyManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/fileWorkingCopy.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/fileWorkingCopy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/fileWorkingCopy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/fileWorkingCopy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/resourceWorkingCopy.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/resourceWorkingCopy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/resourceWorkingCopy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/resourceWorkingCopy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopySaveParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopy.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopy.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopy.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopy.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackup.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackup.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackup.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackup.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyBackupTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyEditorService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyEditorService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyEditorService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyEditorService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileOperationParticipant.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyFileService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistory.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistory.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistory.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistory.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyHistoryTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/common/workingCopyService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupTracker.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupTracker.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupTracker.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyBackupTracker.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyHistoryService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyHistoryService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyHistoryService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workingCopy/electron-browser/workingCopyHistoryService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/canonicalUriService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/canonicalUriService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/canonicalUriService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/canonicalUriService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/editSessionIdentityService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/editSessionIdentityService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/editSessionIdentityService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/editSessionIdentityService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceEditing.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceEditing.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceEditing.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceEditing.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceTrust.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceTrust.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceTrust.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/common/workspaceTrust.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts b/apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts rename to apps/review-desktop/code-oss/src/vs/workbench/services/workspaces/electron-browser/workspacesService.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/README.md b/apps/review-desktop/code-oss/src/vscode-dts/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/README.md rename to apps/review-desktop/code-oss/src/vscode-dts/README.md diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.activeComment.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.activeComment.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.activeComment.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.activeComment.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.agentEditorComments.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.agentEditorComments.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.agentEditorComments.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.agentEditorComments.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.agentSessionsWorkspace.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.agentSessionsWorkspace.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.agentSessionsWorkspace.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.agentSessionsWorkspace.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.agentsWindowConfiguration.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.agentsWindowConfiguration.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.agentsWindowConfiguration.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.agentsWindowConfiguration.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.aiRelatedInformation.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.aiSettingsSearch.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.aiSettingsSearch.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.aiSettingsSearch.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.aiSettingsSearch.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.aiTextSearchProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.aiTextSearchProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.aiTextSearchProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.aiTextSearchProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authIssuers.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authIssuers.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authIssuers.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authIssuers.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authLearnMore.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authLearnMore.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authLearnMore.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authLearnMore.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authProviderSpecific.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authSession.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authSession.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authSession.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authSession.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authSessionAudience.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authSessionAudience.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authSessionAudience.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authSessionAudience.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authenticationChallenges.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authenticationChallenges.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.authenticationChallenges.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.authenticationChallenges.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.browser.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.browser.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.browser.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.browser.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.canonicalUriProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatContextProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatContextProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatContextProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatContextProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatDebug.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatDebug.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatDebug.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatDebug.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatHooks.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatHooks.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatHooks.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatHooks.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatInputNotification.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatInputNotification.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatInputNotification.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatInputNotification.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatOutputRenderer.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatOutputRenderer.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatOutputRenderer.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatOutputRenderer.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatPromptFiles.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatPromptFiles.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatPromptFiles.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatPromptFiles.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceBinaryData.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceBinaryData.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceBinaryData.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceBinaryData.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceDiagnostic.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceDiagnostic.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceDiagnostic.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatReferenceDiagnostic.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionCustomizationProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionCustomizationProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionCustomizationProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionCustomizationProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatStatusItem.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatStatusItem.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatStatusItem.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatStatusItem.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatTab.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatTab.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.chatTab.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.chatTab.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionAI.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionAI.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionAI.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionAI.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionRanges.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionRanges.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionRanges.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.codeActionRanges.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReactor.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReactor.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReactor.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReactor.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReveal.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReveal.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReveal.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentReveal.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentThreadApplicability.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentThreadApplicability.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentThreadApplicability.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentThreadApplicability.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentingRangeHint.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentingRangeHint.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentingRangeHint.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentingRangeHint.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.commentsDraftState.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribAccessibilityHelpContent.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribAccessibilityHelpContent.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribAccessibilityHelpContent.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribAccessibilityHelpContent.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribChatEditorInlineGutterMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribChatEditorInlineGutterMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribChatEditorInlineGutterMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribChatEditorInlineGutterMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentsViewThreadMenus.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentsViewThreadMenus.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentsViewThreadMenus.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribCommentsViewThreadMenus.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDebugCreateConfiguration.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDebugCreateConfiguration.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDebugCreateConfiguration.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDebugCreateConfiguration.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDiffEditorGutterToolBarMenus.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDiffEditorGutterToolBarMenus.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDiffEditorGutterToolBarMenus.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribDiffEditorGutterToolBarMenus.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditSessions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditSessions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditSessions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditSessions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditorContentMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditorContentMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditorContentMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribEditorContentMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLanguageModelToolSets.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLanguageModelToolSets.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLanguageModelToolSets.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribLanguageModelToolSets.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMergeEditorMenus.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMergeEditorMenus.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMergeEditorMenus.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMergeEditorMenus.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMultiDiffEditorMenus.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMultiDiffEditorMenus.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMultiDiffEditorMenus.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribMultiDiffEditorMenus.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribRemoteHelp.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribRemoteHelp.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribRemoteHelp.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribRemoteHelp.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactGroupMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactGroupMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactGroupMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactGroupMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlArtifactMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryItemMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryItemMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryItemMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryItemMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryTitleMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryTitleMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryTitleMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlHistoryTitleMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlTitleMenu.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlTitleMenu.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlTitleMenu.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribSourceControlTitleMenu.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribStatusBarItems.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribStatusBarItems.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribStatusBarItems.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribStatusBarItems.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewContainerTitle.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewContainerTitle.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewContainerTitle.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewContainerTitle.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.css.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.css.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.css.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.css.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorDiffs.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorDiffs.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorDiffs.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorDiffs.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorMove.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorMove.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorMove.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorMove.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorPriority.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorPriority.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorPriority.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.customEditorPriority.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.dataChannels.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.dataChannels.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.dataChannels.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.dataChannels.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.debugVisualization.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.debugVisualization.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.debugVisualization.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.debugVisualization.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.defaultChatParticipant.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.defaultChatParticipant.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.defaultChatParticipant.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.defaultChatParticipant.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.devDeviceId.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.devDeviceId.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.devDeviceId.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.devDeviceId.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.diffCommand.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.diffCommand.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.diffCommand.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.diffCommand.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.diffContentOptions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.documentDiff.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.documentDiff.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.documentDiff.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.documentDiff.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.documentSyntaxHighlighting.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.documentSyntaxHighlighting.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.documentSyntaxHighlighting.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.documentSyntaxHighlighting.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.editorHoverVerbosityLevel.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.editorHoverVerbosityLevel.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.editorHoverVerbosityLevel.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.editorHoverVerbosityLevel.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.editorInsets.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.editorInsets.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.editorInsets.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.editorInsets.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.embeddings.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.embeddings.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.embeddings.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.embeddings.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.envIsConnectionMetered.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.envIsConnectionMetered.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.envIsConnectionMetered.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.envIsConnectionMetered.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.environmentPower.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.environmentPower.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.environmentPower.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.environmentPower.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionAffinity.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionAffinity.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionAffinity.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionAffinity.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionsAny.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionsAny.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionsAny.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.extensionsAny.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.externalUriOpener.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.externalUriOpener.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.externalUriOpener.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.externalUriOpener.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider2.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider2.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider2.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.fileSearchProvider2.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.findFiles2.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.findFiles2.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.findFiles2.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.findFiles2.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles2.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles2.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles2.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.findTextInFiles2.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.fsChunks.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.fsChunks.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.fsChunks.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.fsChunks.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.inlineCompletionsAdditions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.interactive.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.interactive.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.interactive.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.interactive.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.ipc.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.ipc.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.ipc.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.ipc.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelCapabilities.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelCapabilities.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelCapabilities.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelCapabilities.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelPricing.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelPricing.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelPricing.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelPricing.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelProxy.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelProxy.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelProxy.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelProxy.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelSystem.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelSystem.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelSystem.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelSystem.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelThinkingPart.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelThinkingPart.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelThinkingPart.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelThinkingPart.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolResultAudience.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolResultAudience.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolResultAudience.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolResultAudience.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolSupportsModel.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolSupportsModel.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolSupportsModel.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageModelToolSupportsModel.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageStatusText.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageStatusText.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.languageStatusText.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.languageStatusText.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.markdownAlertSyntax.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.markdownAlertSyntax.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.markdownAlertSyntax.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.markdownAlertSyntax.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpServerDefinitions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpServerDefinitions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpServerDefinitions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpServerDefinitions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpToolDefinitions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpToolDefinitions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpToolDefinitions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.mcpToolDefinitions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.nativeWindowHandle.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.nativeWindowHandle.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.nativeWindowHandle.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.nativeWindowHandle.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.newSymbolNamesProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.newSymbolNamesProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.newSymbolNamesProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.newSymbolNamesProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookCellExecution.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookCellExecution.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookCellExecution.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookCellExecution.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookExecution.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookExecution.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookExecution.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookExecution.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookLiveShare.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookLiveShare.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookLiveShare.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookLiveShare.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMime.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMime.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMime.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookMime.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookReplDocument.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookReplDocument.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookReplDocument.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookReplDocument.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookVariableProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookVariableProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookVariableProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.notebookVariableProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.portsAttributes.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.portsAttributes.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.portsAttributes.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.portsAttributes.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.profileContentHandlers.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.profileContentHandlers.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.profileContentHandlers.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.profileContentHandlers.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.quickDiffProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.quickDiffProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.quickDiffProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.quickDiffProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickItemTooltip.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickItemTooltip.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickItemTooltip.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickItemTooltip.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.remoteCodingAgents.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.remoteCodingAgents.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.remoteCodingAgents.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.remoteCodingAgents.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.resolvers.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.resolvers.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.resolvers.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.resolvers.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmActionButton.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmActionButton.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmActionButton.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmActionButton.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmArtifactProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmArtifactProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmArtifactProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmArtifactProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmMultiDiffEditor.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmMultiDiffEditor.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmMultiDiffEditor.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmMultiDiffEditor.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmProviderOptions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmProviderOptions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmProviderOptions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmProviderOptions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmTextDocument.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmTextDocument.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmTextDocument.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmTextDocument.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmValidation.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmValidation.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.scmValidation.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.scmValidation.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.shareProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.shareProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.shareProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.shareProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.speech.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.speech.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.speech.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.speech.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.statusBarItemTooltip.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.statusBarItemTooltip.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.statusBarItemTooltip.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.statusBarItemTooltip.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputMultiDiff.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputMultiDiff.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputMultiDiff.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputMultiDiff.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskExecutionTerminal.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskExecutionTerminal.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskExecutionTerminal.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskExecutionTerminal.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskPresentationGroup.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskPresentationGroup.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskPresentationGroup.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskPresentationGroup.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskProblemMatcherStatus.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskProblemMatcherStatus.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskProblemMatcherStatus.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskProblemMatcherStatus.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskRunOptions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskRunOptions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.taskRunOptions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.taskRunOptions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.telemetry.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.telemetry.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.telemetry.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.telemetry.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalCompletionProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDataWriteEvent.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalDimensions.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalExecuteCommandEvent.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalExecuteCommandEvent.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalExecuteCommandEvent.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalExecuteCommandEvent.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalQuickFixProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalSelection.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalSelection.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalSelection.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalSelection.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalShellEnv.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalShellEnv.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalShellEnv.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalShellEnv.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalTitle.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalTitle.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalTitle.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.terminalTitle.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.testObserver.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.testObserver.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.testObserver.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.testObserver.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.testRelatedCode.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.testRelatedCode.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.testRelatedCode.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.testRelatedCode.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textDocumentChangeReason.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textDocumentChangeReason.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textDocumentChangeReason.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textDocumentChangeReason.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textEditorDiffInformation.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textEditorDiffInformation.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textEditorDiffInformation.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textEditorDiffInformation.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchComplete2.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchComplete2.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchComplete2.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchComplete2.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider2.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider2.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider2.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.textSearchProvider2.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.timeline.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.timeline.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.timeline.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.timeline.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tokenInformation.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tokenInformation.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tokenInformation.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tokenInformation.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.toolInvocationApproveCombination.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.toolInvocationApproveCombination.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.toolInvocationApproveCombination.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.toolInvocationApproveCombination.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.toolProgress.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.toolProgress.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.toolProgress.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.toolProgress.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeItemMarkdownLabel.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeItemMarkdownLabel.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeItemMarkdownLabel.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeItemMarkdownLabel.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewMarkdownMessage.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewMarkdownMessage.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewMarkdownMessage.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewMarkdownMessage.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewReveal.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewReveal.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewReveal.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.treeViewReveal.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnelFactory.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnelFactory.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnelFactory.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnelFactory.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnels.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnels.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnels.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.tunnels.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.valueSelectionInQuickPick.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.valueSelectionInQuickPick.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.valueSelectionInQuickPick.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.valueSelectionInQuickPick.d.ts diff --git a/apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.workspaceTrust.d.ts b/apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.workspaceTrust.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/src/vscode-dts/vscode.proposed.workspaceTrust.d.ts rename to apps/review-desktop/code-oss/src/vscode-dts/vscode.proposed.workspaceTrust.d.ts diff --git a/apps/whiteboard-desktop/code-oss/test/.mocharc.json b/apps/review-desktop/code-oss/test/.mocharc.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/.mocharc.json rename to apps/review-desktop/code-oss/test/.mocharc.json diff --git a/apps/whiteboard-desktop/code-oss/test/README.md b/apps/review-desktop/code-oss/test/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/README.md rename to apps/review-desktop/code-oss/test/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/automation/.gitignore b/apps/review-desktop/code-oss/test/automation/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/.gitignore rename to apps/review-desktop/code-oss/test/automation/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/automation/.npmignore b/apps/review-desktop/code-oss/test/automation/.npmignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/.npmignore rename to apps/review-desktop/code-oss/test/automation/.npmignore diff --git a/apps/whiteboard-desktop/code-oss/test/automation/README.md b/apps/review-desktop/code-oss/test/automation/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/README.md rename to apps/review-desktop/code-oss/test/automation/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/automation/package-lock.json b/apps/review-desktop/code-oss/test/automation/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/package-lock.json rename to apps/review-desktop/code-oss/test/automation/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/automation/package.json b/apps/review-desktop/code-oss/test/automation/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/package.json rename to apps/review-desktop/code-oss/test/automation/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/activityBar.ts b/apps/review-desktop/code-oss/test/automation/src/activityBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/activityBar.ts rename to apps/review-desktop/code-oss/test/automation/src/activityBar.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/agentsWindow.ts b/apps/review-desktop/code-oss/test/automation/src/agentsWindow.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/agentsWindow.ts rename to apps/review-desktop/code-oss/test/automation/src/agentsWindow.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/application.ts b/apps/review-desktop/code-oss/test/automation/src/application.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/application.ts rename to apps/review-desktop/code-oss/test/automation/src/application.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/chat.ts b/apps/review-desktop/code-oss/test/automation/src/chat.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/chat.ts rename to apps/review-desktop/code-oss/test/automation/src/chat.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/code.ts b/apps/review-desktop/code-oss/test/automation/src/code.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/code.ts rename to apps/review-desktop/code-oss/test/automation/src/code.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/debug.ts b/apps/review-desktop/code-oss/test/automation/src/debug.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/debug.ts rename to apps/review-desktop/code-oss/test/automation/src/debug.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/editor.ts b/apps/review-desktop/code-oss/test/automation/src/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/editor.ts rename to apps/review-desktop/code-oss/test/automation/src/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/editors.ts b/apps/review-desktop/code-oss/test/automation/src/editors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/editors.ts rename to apps/review-desktop/code-oss/test/automation/src/editors.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/electron.ts b/apps/review-desktop/code-oss/test/automation/src/electron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/electron.ts rename to apps/review-desktop/code-oss/test/automation/src/electron.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/explorer.ts b/apps/review-desktop/code-oss/test/automation/src/explorer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/explorer.ts rename to apps/review-desktop/code-oss/test/automation/src/explorer.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/extensions.ts b/apps/review-desktop/code-oss/test/automation/src/extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/extensions.ts rename to apps/review-desktop/code-oss/test/automation/src/extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/index.ts b/apps/review-desktop/code-oss/test/automation/src/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/index.ts rename to apps/review-desktop/code-oss/test/automation/src/index.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/keybindings.ts b/apps/review-desktop/code-oss/test/automation/src/keybindings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/keybindings.ts rename to apps/review-desktop/code-oss/test/automation/src/keybindings.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/localization.ts b/apps/review-desktop/code-oss/test/automation/src/localization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/localization.ts rename to apps/review-desktop/code-oss/test/automation/src/localization.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/logger.ts b/apps/review-desktop/code-oss/test/automation/src/logger.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/logger.ts rename to apps/review-desktop/code-oss/test/automation/src/logger.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/notebook.ts b/apps/review-desktop/code-oss/test/automation/src/notebook.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/notebook.ts rename to apps/review-desktop/code-oss/test/automation/src/notebook.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/peek.ts b/apps/review-desktop/code-oss/test/automation/src/peek.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/peek.ts rename to apps/review-desktop/code-oss/test/automation/src/peek.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/playwrightBrowser.ts b/apps/review-desktop/code-oss/test/automation/src/playwrightBrowser.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/playwrightBrowser.ts rename to apps/review-desktop/code-oss/test/automation/src/playwrightBrowser.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/playwrightDriver.ts b/apps/review-desktop/code-oss/test/automation/src/playwrightDriver.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/playwrightDriver.ts rename to apps/review-desktop/code-oss/test/automation/src/playwrightDriver.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/playwrightElectron.ts b/apps/review-desktop/code-oss/test/automation/src/playwrightElectron.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/playwrightElectron.ts rename to apps/review-desktop/code-oss/test/automation/src/playwrightElectron.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/problems.ts b/apps/review-desktop/code-oss/test/automation/src/problems.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/problems.ts rename to apps/review-desktop/code-oss/test/automation/src/problems.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/processes.ts b/apps/review-desktop/code-oss/test/automation/src/processes.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/processes.ts rename to apps/review-desktop/code-oss/test/automation/src/processes.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/profiler.ts b/apps/review-desktop/code-oss/test/automation/src/profiler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/profiler.ts rename to apps/review-desktop/code-oss/test/automation/src/profiler.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/quickaccess.ts b/apps/review-desktop/code-oss/test/automation/src/quickaccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/quickaccess.ts rename to apps/review-desktop/code-oss/test/automation/src/quickaccess.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/quickinput.ts b/apps/review-desktop/code-oss/test/automation/src/quickinput.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/quickinput.ts rename to apps/review-desktop/code-oss/test/automation/src/quickinput.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/scm.ts b/apps/review-desktop/code-oss/test/automation/src/scm.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/scm.ts rename to apps/review-desktop/code-oss/test/automation/src/scm.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/search.ts b/apps/review-desktop/code-oss/test/automation/src/search.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/search.ts rename to apps/review-desktop/code-oss/test/automation/src/search.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/settings.ts b/apps/review-desktop/code-oss/test/automation/src/settings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/settings.ts rename to apps/review-desktop/code-oss/test/automation/src/settings.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/statusbar.ts b/apps/review-desktop/code-oss/test/automation/src/statusbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/statusbar.ts rename to apps/review-desktop/code-oss/test/automation/src/statusbar.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/task.ts b/apps/review-desktop/code-oss/test/automation/src/task.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/task.ts rename to apps/review-desktop/code-oss/test/automation/src/task.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/terminal.ts b/apps/review-desktop/code-oss/test/automation/src/terminal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/terminal.ts rename to apps/review-desktop/code-oss/test/automation/src/terminal.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/viewlet.ts b/apps/review-desktop/code-oss/test/automation/src/viewlet.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/viewlet.ts rename to apps/review-desktop/code-oss/test/automation/src/viewlet.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/src/workbench.ts b/apps/review-desktop/code-oss/test/automation/src/workbench.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/src/workbench.ts rename to apps/review-desktop/code-oss/test/automation/src/workbench.ts diff --git a/apps/whiteboard-desktop/code-oss/test/automation/tools/copy-driver-definition.js b/apps/review-desktop/code-oss/test/automation/tools/copy-driver-definition.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/tools/copy-driver-definition.js rename to apps/review-desktop/code-oss/test/automation/tools/copy-driver-definition.js diff --git a/apps/whiteboard-desktop/code-oss/test/automation/tools/copy-package-version.js b/apps/review-desktop/code-oss/test/automation/tools/copy-package-version.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/tools/copy-package-version.js rename to apps/review-desktop/code-oss/test/automation/tools/copy-package-version.js diff --git a/apps/whiteboard-desktop/code-oss/test/automation/tsconfig.json b/apps/review-desktop/code-oss/test/automation/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/automation/tsconfig.json rename to apps/review-desktop/code-oss/test/automation/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/cgmanifest.json b/apps/review-desktop/code-oss/test/cgmanifest.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/cgmanifest.json rename to apps/review-desktop/code-oss/test/cgmanifest.json diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/blocks-ci-screenshots.md b/apps/review-desktop/code-oss/test/componentFixtures/blocks-ci-screenshots.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/blocks-ci-screenshots.md rename to apps/review-desktop/code-oss/test/componentFixtures/blocks-ci-screenshots.md diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/component-explorer-attach.json b/apps/review-desktop/code-oss/test/componentFixtures/component-explorer-attach.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/component-explorer-attach.json rename to apps/review-desktop/code-oss/test/componentFixtures/component-explorer-attach.json diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/component-explorer-diff.json b/apps/review-desktop/code-oss/test/componentFixtures/component-explorer-diff.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/component-explorer-diff.json rename to apps/review-desktop/code-oss/test/componentFixtures/component-explorer-diff.json diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/component-explorer.json b/apps/review-desktop/code-oss/test/componentFixtures/component-explorer.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/component-explorer.json rename to apps/review-desktop/code-oss/test/componentFixtures/component-explorer.json diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/cssOrderBisect.mts b/apps/review-desktop/code-oss/test/componentFixtures/cssOrderBisect.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/cssOrderBisect.mts rename to apps/review-desktop/code-oss/test/componentFixtures/cssOrderBisect.mts diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/cssOrderScan.mts b/apps/review-desktop/code-oss/test/componentFixtures/cssOrderScan.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/cssOrderScan.mts rename to apps/review-desktop/code-oss/test/componentFixtures/cssOrderScan.mts diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/cssOrderShared.mts b/apps/review-desktop/code-oss/test/componentFixtures/cssOrderShared.mts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/cssOrderShared.mts rename to apps/review-desktop/code-oss/test/componentFixtures/cssOrderShared.mts diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/.gitignore b/apps/review-desktop/code-oss/test/componentFixtures/playwright/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/.gitignore rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/package-lock.json b/apps/review-desktop/code-oss/test/componentFixtures/playwright/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/package-lock.json rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/package.json b/apps/review-desktop/code-oss/test/componentFixtures/playwright/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/package.json rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/playwright.config.ts b/apps/review-desktop/code-oss/test/componentFixtures/playwright/playwright.config.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/playwright.config.ts rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/playwright.config.ts diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/tests/imageCarousel.spec.ts b/apps/review-desktop/code-oss/test/componentFixtures/playwright/tests/imageCarousel.spec.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/tests/imageCarousel.spec.ts rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/tests/imageCarousel.spec.ts diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/tests/utils.ts b/apps/review-desktop/code-oss/test/componentFixtures/playwright/tests/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/tests/utils.ts rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/tests/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/tsconfig.json b/apps/review-desktop/code-oss/test/componentFixtures/playwright/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/componentFixtures/playwright/tsconfig.json rename to apps/review-desktop/code-oss/test/componentFixtures/playwright/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/integration/browser/.gitignore b/apps/review-desktop/code-oss/test/integration/browser/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/browser/.gitignore rename to apps/review-desktop/code-oss/test/integration/browser/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/integration/browser/README.md b/apps/review-desktop/code-oss/test/integration/browser/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/browser/README.md rename to apps/review-desktop/code-oss/test/integration/browser/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/integration/browser/package-lock.json b/apps/review-desktop/code-oss/test/integration/browser/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/browser/package-lock.json rename to apps/review-desktop/code-oss/test/integration/browser/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/integration/browser/package.json b/apps/review-desktop/code-oss/test/integration/browser/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/browser/package.json rename to apps/review-desktop/code-oss/test/integration/browser/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/integration/browser/src/index.ts b/apps/review-desktop/code-oss/test/integration/browser/src/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/browser/src/index.ts rename to apps/review-desktop/code-oss/test/integration/browser/src/index.ts diff --git a/apps/whiteboard-desktop/code-oss/test/integration/browser/tsconfig.json b/apps/review-desktop/code-oss/test/integration/browser/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/browser/tsconfig.json rename to apps/review-desktop/code-oss/test/integration/browser/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/integration/electron/testrunner.d.ts b/apps/review-desktop/code-oss/test/integration/electron/testrunner.d.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/electron/testrunner.d.ts rename to apps/review-desktop/code-oss/test/integration/electron/testrunner.d.ts diff --git a/apps/whiteboard-desktop/code-oss/test/integration/electron/testrunner.js b/apps/review-desktop/code-oss/test/integration/electron/testrunner.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/integration/electron/testrunner.js rename to apps/review-desktop/code-oss/test/integration/electron/testrunner.js diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/.gitignore b/apps/review-desktop/code-oss/test/mcp/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/.gitignore rename to apps/review-desktop/code-oss/test/mcp/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/README.md b/apps/review-desktop/code-oss/test/mcp/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/README.md rename to apps/review-desktop/code-oss/test/mcp/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/package-lock.json b/apps/review-desktop/code-oss/test/mcp/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/package-lock.json rename to apps/review-desktop/code-oss/test/mcp/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/package.json b/apps/review-desktop/code-oss/test/mcp/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/package.json rename to apps/review-desktop/code-oss/test/mcp/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/scripts/start-stdio.sh b/apps/review-desktop/code-oss/test/mcp/scripts/start-stdio.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/scripts/start-stdio.sh rename to apps/review-desktop/code-oss/test/mcp/scripts/start-stdio.sh diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/application.ts b/apps/review-desktop/code-oss/test/mcp/src/application.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/application.ts rename to apps/review-desktop/code-oss/test/mcp/src/application.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automation.ts b/apps/review-desktop/code-oss/test/mcp/src/automation.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automation.ts rename to apps/review-desktop/code-oss/test/mcp/src/automation.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/activityBar.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/activityBar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/activityBar.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/activityBar.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/chat.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/chat.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/chat.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/chat.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/core.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/core.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/core.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/core.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/debug.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/debug.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/debug.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/debug.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/editor.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/editor.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/editor.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/editor.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/explorer.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/explorer.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/explorer.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/explorer.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/extensions.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/extensions.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/extensions.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/extensions.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/index.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/index.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/index.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/keybindings.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/keybindings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/keybindings.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/keybindings.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/localization.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/localization.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/localization.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/localization.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/notebook.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/notebook.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/notebook.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/notebook.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/problems.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/problems.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/problems.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/problems.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/profiler.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/profiler.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/profiler.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/profiler.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/quickAccess.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/quickAccess.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/quickAccess.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/quickAccess.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/scm.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/scm.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/scm.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/scm.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/search.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/search.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/search.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/search.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/settings.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/settings.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/settings.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/settings.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/statusbar.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/statusbar.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/statusbar.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/statusbar.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/task.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/task.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/task.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/task.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/terminal.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/terminal.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/terminal.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/terminal.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/windows.ts b/apps/review-desktop/code-oss/test/mcp/src/automationTools/windows.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/automationTools/windows.ts rename to apps/review-desktop/code-oss/test/mcp/src/automationTools/windows.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/options.ts b/apps/review-desktop/code-oss/test/mcp/src/options.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/options.ts rename to apps/review-desktop/code-oss/test/mcp/src/options.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/stdio.ts b/apps/review-desktop/code-oss/test/mcp/src/stdio.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/stdio.ts rename to apps/review-desktop/code-oss/test/mcp/src/stdio.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/src/utils.ts b/apps/review-desktop/code-oss/test/mcp/src/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/src/utils.ts rename to apps/review-desktop/code-oss/test/mcp/src/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/test/mcp/tsconfig.json b/apps/review-desktop/code-oss/test/mcp/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/mcp/tsconfig.json rename to apps/review-desktop/code-oss/test/mcp/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/.gitignore b/apps/review-desktop/code-oss/test/monaco/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/.gitignore rename to apps/review-desktop/code-oss/test/monaco/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/.mocharc.json b/apps/review-desktop/code-oss/test/monaco/.mocharc.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/.mocharc.json rename to apps/review-desktop/code-oss/test/monaco/.mocharc.json diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/.npmrc b/apps/review-desktop/code-oss/test/monaco/.npmrc similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/.npmrc rename to apps/review-desktop/code-oss/test/monaco/.npmrc diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/README.md b/apps/review-desktop/code-oss/test/monaco/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/README.md rename to apps/review-desktop/code-oss/test/monaco/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/core.js b/apps/review-desktop/code-oss/test/monaco/core.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/core.js rename to apps/review-desktop/code-oss/test/monaco/core.js diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/esm-check/esm-check.js b/apps/review-desktop/code-oss/test/monaco/esm-check/esm-check.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/esm-check/esm-check.js rename to apps/review-desktop/code-oss/test/monaco/esm-check/esm-check.js diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/esm-check/index.html b/apps/review-desktop/code-oss/test/monaco/esm-check/index.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/esm-check/index.html rename to apps/review-desktop/code-oss/test/monaco/esm-check/index.html diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/esm-check/index.js b/apps/review-desktop/code-oss/test/monaco/esm-check/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/esm-check/index.js rename to apps/review-desktop/code-oss/test/monaco/esm-check/index.js diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/monaco.test.ts b/apps/review-desktop/code-oss/test/monaco/monaco.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/monaco.test.ts rename to apps/review-desktop/code-oss/test/monaco/monaco.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/package-lock.json b/apps/review-desktop/code-oss/test/monaco/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/package-lock.json rename to apps/review-desktop/code-oss/test/monaco/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/package.json b/apps/review-desktop/code-oss/test/monaco/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/package.json rename to apps/review-desktop/code-oss/test/monaco/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/runner.js b/apps/review-desktop/code-oss/test/monaco/runner.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/runner.js rename to apps/review-desktop/code-oss/test/monaco/runner.js diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/tsconfig.json b/apps/review-desktop/code-oss/test/monaco/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/tsconfig.json rename to apps/review-desktop/code-oss/test/monaco/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/monaco/webpack.config.js b/apps/review-desktop/code-oss/test/monaco/webpack.config.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/monaco/webpack.config.js rename to apps/review-desktop/code-oss/test/monaco/webpack.config.js diff --git a/apps/whiteboard-desktop/code-oss/test/package.json b/apps/review-desktop/code-oss/test/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/package.json rename to apps/review-desktop/code-oss/test/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/.gitignore b/apps/review-desktop/code-oss/test/sanity/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/.gitignore rename to apps/review-desktop/code-oss/test/sanity/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/README.md b/apps/review-desktop/code-oss/test/sanity/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/README.md rename to apps/review-desktop/code-oss/test/sanity/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/containers/entrypoint.sh b/apps/review-desktop/code-oss/test/sanity/containers/entrypoint.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/containers/entrypoint.sh rename to apps/review-desktop/code-oss/test/sanity/containers/entrypoint.sh diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/package-lock.json b/apps/review-desktop/code-oss/test/sanity/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/package-lock.json rename to apps/review-desktop/code-oss/test/sanity/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/package.json b/apps/review-desktop/code-oss/test/sanity/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/package.json rename to apps/review-desktop/code-oss/test/sanity/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-docker.cmd b/apps/review-desktop/code-oss/test/sanity/scripts/run-docker.cmd similarity index 95% rename from apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-docker.cmd rename to apps/review-desktop/code-oss/test/sanity/scripts/run-docker.cmd index 88d7534dd..52befe329 100644 --- a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-docker.cmd +++ b/apps/review-desktop/code-oss/test/sanity/scripts/run-docker.cmd @@ -1,51 +1,51 @@ -@echo off -setlocal enabledelayedexpansion - -set ROOT=%~dp0.. -set CONTAINER= -set ARCH=amd64 -set REGISTRY=vscodehub.azurecr.io/vscode-linux-build-agent/sanity-tests -set ARGS= - -:parse_args -if "%~1"=="" goto :done_parsing -if "%~1"=="--container" ( - set CONTAINER=%~2 - shift & shift - goto :parse_args -) -if "%~1"=="--arch" ( - set ARCH=%~2 - shift & shift - goto :parse_args -) -set "ARGS=!ARGS! %~1" -shift -goto :parse_args - -:done_parsing -if "%CONTAINER%"=="" ( - echo Error: --container is required - exit /b 1 -) - -set HOST_ARCH=amd64 -if "%PROCESSOR_ARCHITECTURE%"=="ARM64" set HOST_ARCH=arm64 -if not "%ARCH%"=="%HOST_ARCH%" ( - echo Setting up QEMU emulation for %ARCH% on %HOST_ARCH% host - docker run --privileged --rm tonistiigi/binfmt --install all >nul 2>&1 -) - -set IMAGE=%REGISTRY%:%CONTAINER%-%ARCH% - -echo Pulling container image: %IMAGE% -docker pull --platform "linux/%ARCH%" "%IMAGE%" - -echo Running sanity tests in container -docker run ^ - --rm ^ - --platform "linux/%ARCH%" ^ - --volume "%ROOT%:/root" ^ - --entrypoint sh ^ - "%IMAGE%" ^ - /root/containers/entrypoint.sh %ARGS% +@echo off +setlocal enabledelayedexpansion + +set ROOT=%~dp0.. +set CONTAINER= +set ARCH=amd64 +set REGISTRY=vscodehub.azurecr.io/vscode-linux-build-agent/sanity-tests +set ARGS= + +:parse_args +if "%~1"=="" goto :done_parsing +if "%~1"=="--container" ( + set CONTAINER=%~2 + shift & shift + goto :parse_args +) +if "%~1"=="--arch" ( + set ARCH=%~2 + shift & shift + goto :parse_args +) +set "ARGS=!ARGS! %~1" +shift +goto :parse_args + +:done_parsing +if "%CONTAINER%"=="" ( + echo Error: --container is required + exit /b 1 +) + +set HOST_ARCH=amd64 +if "%PROCESSOR_ARCHITECTURE%"=="ARM64" set HOST_ARCH=arm64 +if not "%ARCH%"=="%HOST_ARCH%" ( + echo Setting up QEMU emulation for %ARCH% on %HOST_ARCH% host + docker run --privileged --rm tonistiigi/binfmt --install all >nul 2>&1 +) + +set IMAGE=%REGISTRY%:%CONTAINER%-%ARCH% + +echo Pulling container image: %IMAGE% +docker pull --platform "linux/%ARCH%" "%IMAGE%" + +echo Running sanity tests in container +docker run ^ + --rm ^ + --platform "linux/%ARCH%" ^ + --volume "%ROOT%:/root" ^ + --entrypoint sh ^ + "%IMAGE%" ^ + /root/containers/entrypoint.sh %ARGS% diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-docker.sh b/apps/review-desktop/code-oss/test/sanity/scripts/run-docker.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-docker.sh rename to apps/review-desktop/code-oss/test/sanity/scripts/run-docker.sh diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-macOS.sh b/apps/review-desktop/code-oss/test/sanity/scripts/run-macOS.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-macOS.sh rename to apps/review-desktop/code-oss/test/sanity/scripts/run-macOS.sh diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-ubuntu.sh b/apps/review-desktop/code-oss/test/sanity/scripts/run-ubuntu.sh similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-ubuntu.sh rename to apps/review-desktop/code-oss/test/sanity/scripts/run-ubuntu.sh diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-win32.cmd b/apps/review-desktop/code-oss/test/sanity/scripts/run-win32.cmd similarity index 97% rename from apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-win32.cmd rename to apps/review-desktop/code-oss/test/sanity/scripts/run-win32.cmd index 5c4ea7622..e8fef8dd4 100644 --- a/apps/whiteboard-desktop/code-oss/test/sanity/scripts/run-win32.cmd +++ b/apps/review-desktop/code-oss/test/sanity/scripts/run-win32.cmd @@ -1,69 +1,69 @@ -@echo off -setlocal - -for /f "tokens=*" %%a in ('powershell -NoProfile -Command "[int](Get-CimInstance Win32_Processor).Architecture"') do set ARCH=%%a -if "%ARCH%"=="12" (set "ARCH_NAME=ARM64") else if "%ARCH%"=="9" (set "ARCH_NAME=AMD64") else if "%ARCH%"=="5" (set "ARCH_NAME=ARM") else (set "ARCH_NAME=x86") - -echo System: %OS% %ARCH_NAME% -powershell -NoProfile -Command "$os = Get-CimInstance Win32_OperatingSystem; $total = $os.TotalVisibleMemorySize/1MB; $free = $os.FreePhysicalMemory/1MB; Write-Host ('Memory: {0:N0} GB free of {1:N0} GB' -f $free, $total)" -powershell -NoProfile -Command "$disk = Get-PSDrive C; Write-Host ('Disk C: {0:N0} GB free of {1:N0} GB' -f ($disk.Free/1GB), (($disk.Used+$disk.Free)/1GB))" - -echo Checking if WSL is installed -where wsl >nul 2>nul -if errorlevel 1 ( - echo WSL is not installed, skipping WSL setup -) else ( - echo Checking if Ubuntu is available on WSL - powershell -NoProfile -Command "if ((wsl -l -q) -contains 'Ubuntu') { exit 0 } else { exit 1 }" - if errorlevel 1 call :install_ubuntu - - echo Ensuring Ubuntu runs with WSL2 - wsl --set-version Ubuntu 2 >nul 2>nul - if errorlevel 1 ( - echo WARNING: Failed to switch Ubuntu to WSL2. WSL1 fallback workaround will be used for Node 24 server binaries. - ) - - echo WSL distributions: - wsl --list --verbose -) - -set PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 -set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe - -echo Running sanity tests -node "%~dp0..\out\index.js" %* - -goto :eof - -REM ==================================================================================================================== - -:install_ubuntu - -echo Ubuntu image is not present in WSL - -echo Setting default WSL version to 2 -wsl --set-default-version 2 >nul 2>nul -if errorlevel 1 ( - echo WARNING: Failed to set default WSL version to 2. Import may default to WSL1. -) - -if "%ARCH%"=="12" ( - set "ROOTFS_URL=https://cloud-images.ubuntu.com/wsl/jammy/current/ubuntu-jammy-wsl-arm64-ubuntu22.04lts.rootfs.tar.gz" -) else ( - set "ROOTFS_URL=https://cloud-images.ubuntu.com/wsl/jammy/current/ubuntu-jammy-wsl-amd64-ubuntu22.04lts.rootfs.tar.gz" -) - -set "ROOTFS_ZIP=%TEMP%\ubuntu-rootfs.tar.gz" -set "ROOTFS_DIR=%LOCALAPPDATA%\WSL\Ubuntu" - -echo Downloading Ubuntu rootfs from %ROOTFS_URL% to %ROOTFS_ZIP% -curl -L -o "%ROOTFS_ZIP%" "%ROOTFS_URL%" - -echo Importing Ubuntu into WSL at %ROOTFS_DIR% from %ROOTFS_ZIP% -mkdir "%ROOTFS_DIR%" 2>nul -wsl --import Ubuntu "%ROOTFS_DIR%" "%ROOTFS_ZIP%" - -echo Starting Ubuntu on WSL -wsl -d Ubuntu echo Ubuntu WSL is ready - -goto :eof +@echo off +setlocal + +for /f "tokens=*" %%a in ('powershell -NoProfile -Command "[int](Get-CimInstance Win32_Processor).Architecture"') do set ARCH=%%a +if "%ARCH%"=="12" (set "ARCH_NAME=ARM64") else if "%ARCH%"=="9" (set "ARCH_NAME=AMD64") else if "%ARCH%"=="5" (set "ARCH_NAME=ARM") else (set "ARCH_NAME=x86") + +echo System: %OS% %ARCH_NAME% +powershell -NoProfile -Command "$os = Get-CimInstance Win32_OperatingSystem; $total = $os.TotalVisibleMemorySize/1MB; $free = $os.FreePhysicalMemory/1MB; Write-Host ('Memory: {0:N0} GB free of {1:N0} GB' -f $free, $total)" +powershell -NoProfile -Command "$disk = Get-PSDrive C; Write-Host ('Disk C: {0:N0} GB free of {1:N0} GB' -f ($disk.Free/1GB), (($disk.Used+$disk.Free)/1GB))" + +echo Checking if WSL is installed +where wsl >nul 2>nul +if errorlevel 1 ( + echo WSL is not installed, skipping WSL setup +) else ( + echo Checking if Ubuntu is available on WSL + powershell -NoProfile -Command "if ((wsl -l -q) -contains 'Ubuntu') { exit 0 } else { exit 1 }" + if errorlevel 1 call :install_ubuntu + + echo Ensuring Ubuntu runs with WSL2 + wsl --set-version Ubuntu 2 >nul 2>nul + if errorlevel 1 ( + echo WARNING: Failed to switch Ubuntu to WSL2. WSL1 fallback workaround will be used for Node 24 server binaries. + ) + + echo WSL distributions: + wsl --list --verbose +) + +set PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 +set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe + +echo Running sanity tests +node "%~dp0..\out\index.js" %* + +goto :eof + +REM ==================================================================================================================== + +:install_ubuntu + +echo Ubuntu image is not present in WSL + +echo Setting default WSL version to 2 +wsl --set-default-version 2 >nul 2>nul +if errorlevel 1 ( + echo WARNING: Failed to set default WSL version to 2. Import may default to WSL1. +) + +if "%ARCH%"=="12" ( + set "ROOTFS_URL=https://cloud-images.ubuntu.com/wsl/jammy/current/ubuntu-jammy-wsl-arm64-ubuntu22.04lts.rootfs.tar.gz" +) else ( + set "ROOTFS_URL=https://cloud-images.ubuntu.com/wsl/jammy/current/ubuntu-jammy-wsl-amd64-ubuntu22.04lts.rootfs.tar.gz" +) + +set "ROOTFS_ZIP=%TEMP%\ubuntu-rootfs.tar.gz" +set "ROOTFS_DIR=%LOCALAPPDATA%\WSL\Ubuntu" + +echo Downloading Ubuntu rootfs from %ROOTFS_URL% to %ROOTFS_ZIP% +curl -L -o "%ROOTFS_ZIP%" "%ROOTFS_URL%" + +echo Importing Ubuntu into WSL at %ROOTFS_DIR% from %ROOTFS_ZIP% +mkdir "%ROOTFS_DIR%" 2>nul +wsl --import Ubuntu "%ROOTFS_DIR%" "%ROOTFS_ZIP%" + +echo Starting Ubuntu on WSL +wsl -d Ubuntu echo Ubuntu WSL is ready + +goto :eof diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/cli.test.ts b/apps/review-desktop/code-oss/test/sanity/src/cli.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/cli.test.ts rename to apps/review-desktop/code-oss/test/sanity/src/cli.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/context.ts b/apps/review-desktop/code-oss/test/sanity/src/context.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/context.ts rename to apps/review-desktop/code-oss/test/sanity/src/context.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/desktop.test.ts b/apps/review-desktop/code-oss/test/sanity/src/desktop.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/desktop.test.ts rename to apps/review-desktop/code-oss/test/sanity/src/desktop.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/detectors.ts b/apps/review-desktop/code-oss/test/sanity/src/detectors.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/detectors.ts rename to apps/review-desktop/code-oss/test/sanity/src/detectors.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/devTunnel.test.ts b/apps/review-desktop/code-oss/test/sanity/src/devTunnel.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/devTunnel.test.ts rename to apps/review-desktop/code-oss/test/sanity/src/devTunnel.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/githubAuth.ts b/apps/review-desktop/code-oss/test/sanity/src/githubAuth.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/githubAuth.ts rename to apps/review-desktop/code-oss/test/sanity/src/githubAuth.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/index.ts b/apps/review-desktop/code-oss/test/sanity/src/index.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/index.ts rename to apps/review-desktop/code-oss/test/sanity/src/index.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/main.ts b/apps/review-desktop/code-oss/test/sanity/src/main.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/main.ts rename to apps/review-desktop/code-oss/test/sanity/src/main.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/server.test.ts b/apps/review-desktop/code-oss/test/sanity/src/server.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/server.test.ts rename to apps/review-desktop/code-oss/test/sanity/src/server.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/serverWeb.test.ts b/apps/review-desktop/code-oss/test/sanity/src/serverWeb.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/serverWeb.test.ts rename to apps/review-desktop/code-oss/test/sanity/src/serverWeb.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/uiTest.ts b/apps/review-desktop/code-oss/test/sanity/src/uiTest.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/uiTest.ts rename to apps/review-desktop/code-oss/test/sanity/src/uiTest.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/src/wsl.test.ts b/apps/review-desktop/code-oss/test/sanity/src/wsl.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/src/wsl.test.ts rename to apps/review-desktop/code-oss/test/sanity/src/wsl.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/sanity/tsconfig.json b/apps/review-desktop/code-oss/test/sanity/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/sanity/tsconfig.json rename to apps/review-desktop/code-oss/test/sanity/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/.gitignore b/apps/review-desktop/code-oss/test/smoke/.gitignore similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/.gitignore rename to apps/review-desktop/code-oss/test/smoke/.gitignore diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/Audit.md b/apps/review-desktop/code-oss/test/smoke/Audit.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/Audit.md rename to apps/review-desktop/code-oss/test/smoke/Audit.md diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/README.md b/apps/review-desktop/code-oss/test/smoke/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/README.md rename to apps/review-desktop/code-oss/test/smoke/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/extension.js b/apps/review-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/extension.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/extension.js rename to apps/review-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/extension.js diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/package.json b/apps/review-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/package.json rename to apps/review-desktop/code-oss/test/smoke/extensions/vscode-smoketest-ext-host/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/package-lock.json b/apps/review-desktop/code-oss/test/smoke/package-lock.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/package-lock.json rename to apps/review-desktop/code-oss/test/smoke/package-lock.json diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/package.json b/apps/review-desktop/code-oss/test/smoke/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/package.json rename to apps/review-desktop/code-oss/test/smoke/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/accessibility/accessibility.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/accessibility/accessibility.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/accessibility/accessibility.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/accessibility/accessibility.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/agentsWindow/agentsWindow.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/agentsWindow/agentsWindow.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/agentsWindow/agentsWindow.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/agentsWindow/agentsWindow.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatDisabled.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatDisabled.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatDisabled.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatDisabled.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatModelConfig.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatModelConfig.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatModelConfig.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatModelConfig.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatSandbox.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatSandbox.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatSandbox.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatSandbox.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatSessions.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatSessions.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/chatSessions.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/chat/chatSessions.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/copilotCli.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/chat/copilotCli.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/copilotCli.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/chat/copilotCli.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/shellScenarios.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/chat/shellScenarios.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/chat/shellScenarios.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/chat/shellScenarios.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/extensions/extension-host-restart.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/extensions/extension-host-restart.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/extensions/extension-host-restart.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/extensions/extension-host-restart.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/extensions/extensions.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/extensions/extensions.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/extensions/extensions.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/extensions/extensions.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/languages/languages.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/languages/languages.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/languages/languages.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/languages/languages.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/multiroot/multiroot.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/multiroot/multiroot.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/multiroot/multiroot.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/multiroot/multiroot.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/notebook/notebook.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/notebook/notebook.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/notebook/notebook.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/notebook/notebook.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/preferences/preferences.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/preferences/preferences.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/preferences/preferences.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/preferences/preferences.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/search/search.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/search/search.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/search/search.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/search/search.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/statusbar/statusbar.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/statusbar/statusbar.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/statusbar/statusbar.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/statusbar/statusbar.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/task/task-quick-pick.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/task/task-quick-pick.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/task/task-quick-pick.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/task/task-quick-pick.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/task/task.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/task/task.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/task/task.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/task/task.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-editors.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-editors.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-editors.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-editors.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-helpers.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-helpers.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-helpers.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-helpers.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-input.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-input.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-input.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-input.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-persistence.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-persistence.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-persistence.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-persistence.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-profiles.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-profiles.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-profiles.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-profiles.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-splitCwd.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-splitCwd.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-splitCwd.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-splitCwd.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-stickyScroll.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-stickyScroll.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-stickyScroll.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-stickyScroll.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-tabs.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-tabs.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal-tabs.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal-tabs.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/terminal/terminal.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/terminal/terminal.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/workbench/data-loss.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/workbench/data-loss.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/workbench/data-loss.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/workbench/data-loss.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/workbench/launch.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/workbench/launch.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/workbench/launch.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/workbench/launch.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/areas/workbench/localization.test.ts b/apps/review-desktop/code-oss/test/smoke/src/areas/workbench/localization.test.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/areas/workbench/localization.test.ts rename to apps/review-desktop/code-oss/test/smoke/src/areas/workbench/localization.test.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/main.ts b/apps/review-desktop/code-oss/test/smoke/src/main.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/main.ts rename to apps/review-desktop/code-oss/test/smoke/src/main.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/src/utils.ts b/apps/review-desktop/code-oss/test/smoke/src/utils.ts similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/src/utils.ts rename to apps/review-desktop/code-oss/test/smoke/src/utils.ts diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/test/index.js b/apps/review-desktop/code-oss/test/smoke/test/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/test/index.js rename to apps/review-desktop/code-oss/test/smoke/test/index.js diff --git a/apps/whiteboard-desktop/code-oss/test/smoke/tsconfig.json b/apps/review-desktop/code-oss/test/smoke/tsconfig.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/smoke/tsconfig.json rename to apps/review-desktop/code-oss/test/smoke/tsconfig.json diff --git a/apps/whiteboard-desktop/code-oss/test/unit/README.md b/apps/review-desktop/code-oss/test/unit/README.md similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/README.md rename to apps/review-desktop/code-oss/test/unit/README.md diff --git a/apps/whiteboard-desktop/code-oss/test/unit/analyzeSnapshot.js b/apps/review-desktop/code-oss/test/unit/analyzeSnapshot.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/analyzeSnapshot.js rename to apps/review-desktop/code-oss/test/unit/analyzeSnapshot.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/assert.js b/apps/review-desktop/code-oss/test/unit/assert.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/assert.js rename to apps/review-desktop/code-oss/test/unit/assert.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/browser/index.js b/apps/review-desktop/code-oss/test/unit/browser/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/browser/index.js rename to apps/review-desktop/code-oss/test/unit/browser/index.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/browser/renderer.html b/apps/review-desktop/code-oss/test/unit/browser/renderer.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/browser/renderer.html rename to apps/review-desktop/code-oss/test/unit/browser/renderer.html diff --git a/apps/whiteboard-desktop/code-oss/test/unit/coverage.js b/apps/review-desktop/code-oss/test/unit/coverage.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/coverage.js rename to apps/review-desktop/code-oss/test/unit/coverage.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/electron/index.js b/apps/review-desktop/code-oss/test/unit/electron/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/electron/index.js rename to apps/review-desktop/code-oss/test/unit/electron/index.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/electron/preload.js b/apps/review-desktop/code-oss/test/unit/electron/preload.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/electron/preload.js rename to apps/review-desktop/code-oss/test/unit/electron/preload.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/electron/renderer.html b/apps/review-desktop/code-oss/test/unit/electron/renderer.html similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/electron/renderer.html rename to apps/review-desktop/code-oss/test/unit/electron/renderer.html diff --git a/apps/whiteboard-desktop/code-oss/test/unit/electron/renderer.js b/apps/review-desktop/code-oss/test/unit/electron/renderer.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/electron/renderer.js rename to apps/review-desktop/code-oss/test/unit/electron/renderer.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/fullJsonStreamReporter.js b/apps/review-desktop/code-oss/test/unit/fullJsonStreamReporter.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/fullJsonStreamReporter.js rename to apps/review-desktop/code-oss/test/unit/fullJsonStreamReporter.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/node/index.js b/apps/review-desktop/code-oss/test/unit/node/index.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/node/index.js rename to apps/review-desktop/code-oss/test/unit/node/index.js diff --git a/apps/whiteboard-desktop/code-oss/test/unit/node/package.json b/apps/review-desktop/code-oss/test/unit/node/package.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/node/package.json rename to apps/review-desktop/code-oss/test/unit/node/package.json diff --git a/apps/whiteboard-desktop/code-oss/test/unit/reporter.js b/apps/review-desktop/code-oss/test/unit/reporter.js similarity index 100% rename from apps/whiteboard-desktop/code-oss/test/unit/reporter.js rename to apps/review-desktop/code-oss/test/unit/reporter.js diff --git a/apps/whiteboard-desktop/code-oss/tsfmt.json b/apps/review-desktop/code-oss/tsfmt.json similarity index 100% rename from apps/whiteboard-desktop/code-oss/tsfmt.json rename to apps/review-desktop/code-oss/tsfmt.json diff --git a/apps/review-desktop/package.json b/apps/review-desktop/package.json new file mode 100644 index 000000000..624263358 --- /dev/null +++ b/apps/review-desktop/package.json @@ -0,0 +1,39 @@ +{ + "name": "@dev.fast/review-desktop", + "version": "0.0.33", + "private": true, + "license": "MIT", + "type": "module", + "scripts": { + "app:build": "bash scripts/build.sh", + "app:package:linux": "bash scripts/package-linux.sh", + "app:package:linux:distributions": "bash scripts/package-linux-distributions.sh", + "app:package:macos": "bash scripts/package-macos.sh", + "app:notarize:macos": "bash scripts/notarize-macos.sh", + "app:run": "bash scripts/run.sh", + "app:watch": "pnpm run protocol:sync && npm --prefix code-oss run watch", + "protocol:sync": "node scripts/protocol-sync.mjs", + "smoke:error-telemetry": "node scripts/smoke-error-telemetry.mjs", + "smoke:telemetry-delivery": "node scripts/smoke-telemetry-delivery.mjs", + "test:e2e:lsp": "node scripts/lsp-e2e.mjs", + "pretest": "pnpm run protocol:sync", + "test": "node --test \"scripts/**/*.test.mjs\" && TSX_TSCONFIG_PATH=tsconfig.test.json node --import tsx --test \"code-oss/src/vs/review/**/*.test.ts\"", + "pretypecheck": "pnpm run protocol:sync", + "typecheck": "npm --prefix code-oss run typecheck-client" + }, + "dependencies": { + "@dev.fast/review": "workspace:*", + "@dev.fast/review-protocol": "workspace:*" + }, + "devDependencies": { + "@dev.fast/review-canvas": "workspace:*", + "@types/node": "24.12.2", + "jsdom": "29.1.1", + "playwright": "1.62.1", + "tsx": "4.21.0", + "typescript": "6.0.3" + }, + "engines": { + "node": ">=24 <25" + } +} diff --git a/apps/whiteboard-desktop/scripts/app-icon-catalog.test.mjs b/apps/review-desktop/scripts/app-icon-catalog.test.mjs similarity index 93% rename from apps/whiteboard-desktop/scripts/app-icon-catalog.test.mjs rename to apps/review-desktop/scripts/app-icon-catalog.test.mjs index 838ea08b7..b4e66a879 100644 --- a/apps/whiteboard-desktop/scripts/app-icon-catalog.test.mjs +++ b/apps/review-desktop/scripts/app-icon-catalog.test.mjs @@ -89,10 +89,10 @@ test("preview uses the approved orange background", () => { }); test("only the preview workflow opts into the preview icon", () => { - assert.match(previewWorkflow, /WHITEBOARD_APP_ICON_CHANNEL:\s*preview/); - assert.doesNotMatch(stableWorkflow, /WHITEBOARD_APP_ICON_CHANNEL/); + assert.match(previewWorkflow, /REVIEW_APP_ICON_CHANNEL:\s*preview/); + assert.doesNotMatch(stableWorkflow, /REVIEW_APP_ICON_CHANNEL/); assert.match( applyAppIcon, - /getIconVariant\(process\.env\.WHITEBOARD_APP_ICON_CHANNEL\)/, + /getIconVariant\(process\.env\.REVIEW_APP_ICON_CHANNEL\)/, ); }); diff --git a/apps/whiteboard-desktop/scripts/apply-app-icon.mjs b/apps/review-desktop/scripts/apply-app-icon.mjs similarity index 97% rename from apps/whiteboard-desktop/scripts/apply-app-icon.mjs rename to apps/review-desktop/scripts/apply-app-icon.mjs index 523b0fd69..dfcc25699 100644 --- a/apps/whiteboard-desktop/scripts/apply-app-icon.mjs +++ b/apps/review-desktop/scripts/apply-app-icon.mjs @@ -7,7 +7,7 @@ // is kept only as the pre-Tahoe fallback. code-oss packaging has no asset-catalog step, so // this patches the bundle afterwards rather than modifying the vendored gulp pipeline. // -// Usage: [WHITEBOARD_APP_ICON_CHANNEL=preview] node apply-app-icon.mjs +// Usage: [REVIEW_APP_ICON_CHANNEL=preview] node apply-app-icon.mjs // [--icon-name NAME] import { spawnSync } from "node:child_process"; @@ -23,7 +23,7 @@ import { const SCRIPTS_DIR = path.dirname(fileURLToPath(import.meta.url)); -const ICON_VARIANT = getIconVariant(process.env.WHITEBOARD_APP_ICON_CHANNEL); +const ICON_VARIANT = getIconVariant(process.env.REVIEW_APP_ICON_CHANNEL); const ICON_SOURCE = ICON_VARIANT.iconSource; diff --git a/apps/whiteboard-desktop/scripts/build-app-icon-catalog.mjs b/apps/review-desktop/scripts/build-app-icon-catalog.mjs similarity index 90% rename from apps/whiteboard-desktop/scripts/build-app-icon-catalog.mjs rename to apps/review-desktop/scripts/build-app-icon-catalog.mjs index b57951566..39b8d7a0b 100644 --- a/apps/whiteboard-desktop/scripts/build-app-icon-catalog.mjs +++ b/apps/review-desktop/scripts/build-app-icon-catalog.mjs @@ -30,7 +30,7 @@ import { parseArgs } from "node:util"; export const ICONS_DIR = path.resolve( path.dirname(fileURLToPath(import.meta.url)), - "../../../packages/whiteboard/app/icons", + "../../../packages/review/app/icons", ); export const ICON_SOURCE = path.join(ICONS_DIR, "dev-fast.icon"); @@ -41,21 +41,21 @@ export const SOURCE_DIGEST = path.join(ICONS_DIR, "Assets.car.source-sha256"); export const ICON_NAME = "dev-fast"; -export const PWHITEBOARD_ICON_SOURCE = path.join( +export const PREVIEW_ICON_SOURCE = path.join( ICONS_DIR, "dev-fast-preview.icon", ); -export const PWHITEBOARD_CATALOG = path.join(ICONS_DIR, "Assets-preview.car"); +export const PREVIEW_CATALOG = path.join(ICONS_DIR, "Assets-preview.car"); -export const PWHITEBOARD_SOURCE_DIGEST = path.join( +export const PREVIEW_SOURCE_DIGEST = path.join( ICONS_DIR, "Assets-preview.car.source-sha256", ); -export const PWHITEBOARD_FALLBACK = path.join(ICONS_DIR, "dev-fast-preview.icns"); +export const PREVIEW_FALLBACK = path.join(ICONS_DIR, "dev-fast-preview.icns"); -export const PWHITEBOARD_ICON_NAME = "dev-fast-preview"; +export const PREVIEW_ICON_NAME = "dev-fast-preview"; export const DEPLOYMENT_TARGET = "26.0"; @@ -69,11 +69,11 @@ export const ICON_VARIANTS = Object.freeze({ }), preview: Object.freeze({ channel: "preview", - iconSource: PWHITEBOARD_ICON_SOURCE, - catalog: PWHITEBOARD_CATALOG, - sourceDigest: PWHITEBOARD_SOURCE_DIGEST, - fallback: PWHITEBOARD_FALLBACK, - iconName: PWHITEBOARD_ICON_NAME, + iconSource: PREVIEW_ICON_SOURCE, + catalog: PREVIEW_CATALOG, + sourceDigest: PREVIEW_SOURCE_DIGEST, + fallback: PREVIEW_FALLBACK, + iconName: PREVIEW_ICON_NAME, }), }); diff --git a/apps/whiteboard-desktop/scripts/build-linux-repository.py b/apps/review-desktop/scripts/build-linux-repository.py similarity index 97% rename from apps/whiteboard-desktop/scripts/build-linux-repository.py rename to apps/review-desktop/scripts/build-linux-repository.py index d684a8cbd..84641b8db 100644 --- a/apps/whiteboard-desktop/scripts/build-linux-repository.py +++ b/apps/review-desktop/scripts/build-linux-repository.py @@ -27,7 +27,7 @@ def digest(file): def sign(file, fingerprint): output = file.with_name(file.name + ".asc") args = ["gpg", "--batch", "--yes", "--local-user", fingerprint] - passphrase = os.environ.get("WHITEBOARD_SIGNING_PASSPHRASE_FILE") + passphrase = os.environ.get("REVIEW_SIGNING_PASSPHRASE_FILE") if passphrase: args += ["--pinentry-mode", "loopback", "--passphrase-file", passphrase] run(*args, "--armor", "--output", str(output), "--detach-sign", str(file)) @@ -41,7 +41,7 @@ def sign_rpm(file, fingerprint, public_key): "--define", f"_openpgp_sign_id {fingerprint}", "--define", f"_gpg_name {fingerprint}", "--define", f"__gpg {shutil.which('gpg')}"] - passphrase = os.environ.get("WHITEBOARD_SIGNING_PASSPHRASE_FILE") + passphrase = os.environ.get("REVIEW_SIGNING_PASSPHRASE_FILE") if passphrase: if any(character in passphrase for character in "\n\r\"%"): raise ValueError("Invalid signing passphrase file path") diff --git a/apps/whiteboard-desktop/scripts/build.sh b/apps/review-desktop/scripts/build.sh similarity index 81% rename from apps/whiteboard-desktop/scripts/build.sh rename to apps/review-desktop/scripts/build.sh index 7e50d5fce..ba9e4fe41 100755 --- a/apps/whiteboard-desktop/scripts/build.sh +++ b/apps/review-desktop/scripts/build.sh @@ -3,14 +3,14 @@ set -euo pipefail # The macOS release is split: Linux produces the payload, and macOS consumes it. # New packaged outputs must follow the "Linux-to-macOS build handoff" contract -# in apps/whiteboard-desktop/README.md. +# in apps/review-desktop/README.md. MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" -APP_DIR="$MONOREPO_ROOT/apps/whiteboard-desktop" +APP_DIR="$MONOREPO_ROOT/apps/review-desktop" CHECKOUT="$APP_DIR/code-oss" -PROTOCOL_BUNDLER="$MONOREPO_ROOT/packages/whiteboard-protocol/scripts/bundle-native-runtime.mjs" -PROTOCOL_OUTPUT="$CHECKOUT/out/vs/whiteboard/common/whiteboardProtocol.js" -EVENT_STREAM_OUTPUT="$CHECKOUT/out/vs/whiteboard/common/whiteboardEventStream.js" +PROTOCOL_BUNDLER="$MONOREPO_ROOT/packages/review-protocol/scripts/bundle-native-runtime.mjs" +PROTOCOL_OUTPUT="$CHECKOUT/out/vs/review/common/reviewProtocol.js" +EVENT_STREAM_OUTPUT="$CHECKOUT/out/vs/review/common/reviewEventStream.js" # shellcheck source=code-oss-dependencies.sh source "$APP_DIR/scripts/code-oss-dependencies.sh" @@ -18,7 +18,7 @@ source "$APP_DIR/scripts/code-oss-dependencies.sh" source "$APP_DIR/scripts/freshness.sh" DEV_FAST_ACTIVE=0 -if [[ "${WHITEBOARD_DESKTOP_CI_FAST:-0}" != "1" && "${WHITEBOARD_DESKTOP_DEV_FAST:-0}" == "1" ]]; then +if [[ "${REVIEW_DESKTOP_CI_FAST:-0}" != "1" && "${REVIEW_DESKTOP_DEV_FAST:-0}" == "1" ]]; then DEV_FAST_ACTIVE=1 fi @@ -34,11 +34,11 @@ mkdir -p "$CHECKOUT/out/vs/base/browser/dompurify" cp \ "$CHECKOUT/src/vs/base/browser/dompurify/cgmanifest.json" \ "$CHECKOUT/out/vs/base/browser/dompurify/cgmanifest.json" -if [[ -n "${WHITEBOARD_DESKTOP_CURATED_EXTENSION_TARGET:-}" ]]; then +if [[ -n "${REVIEW_DESKTOP_CURATED_EXTENSION_TARGET:-}" ]]; then node "$APP_DIR/scripts/curated-extensions.mjs" \ - "--target=$WHITEBOARD_DESKTOP_CURATED_EXTENSION_TARGET" + "--target=$REVIEW_DESKTOP_CURATED_EXTENSION_TARGET" elif [[ "$DEV_FAST_ACTIVE" == "1" ]]; then - DEV_FAST_EXTENSIONS_SELECTION="${DEV_WHITEBOARD_EXTENSIONS:-all}" + DEV_FAST_EXTENSIONS_SELECTION="${DEV_REVIEW_EXTENSIONS:-all}" node "$APP_DIR/scripts/curated-extensions.mjs" \ "--only=$DEV_FAST_EXTENSIONS_SELECTION" # run.sh follows this script in `pnpm dev`; leave the selection it @@ -49,7 +49,7 @@ elif [[ "$DEV_FAST_ACTIVE" == "1" ]]; then else node "$APP_DIR/scripts/curated-extensions.mjs" fi -if [[ "${WHITEBOARD_DESKTOP_COMPILE_ONLY:-0}" != "1" ]]; then +if [[ "${REVIEW_DESKTOP_COMPILE_ONLY:-0}" != "1" ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then PRODUCT_APP="$(node -p "require('./product.json').nameShort")" PRODUCT_EXE="$(node -p "require('./product.json').nameShort")" @@ -69,7 +69,7 @@ if [[ "${WHITEBOARD_DESKTOP_COMPILE_ONLY:-0}" != "1" ]]; then fi npm --prefix "$APP_DIR" run protocol:sync TYPECHECK_PID="" -if [[ "${WHITEBOARD_DESKTOP_CI_FAST:-0}" == "1" ]]; then +if [[ "${REVIEW_DESKTOP_CI_FAST:-0}" == "1" ]]; then # Transpile-only build with the tsgo typecheck running in the background; # the wait at the end of this script keeps type errors fatal. copy-codicons # must finish before transpile copies non-TS files. @@ -94,7 +94,7 @@ elif [[ "$DEV_FAST_ACTIVE" == "1" ]]; then "$CHECKOUT/build" \ "$CHECKOUT/product.json" \ "$DEPENDENCY_STAMP" \ - "$MONOREPO_ROOT/packages/whiteboard-protocol/src" \ + "$MONOREPO_ROOT/packages/review-protocol/src" \ "$PROTOCOL_BUNDLER"; then npm run gulp copy-codicons npm run transpile-client @@ -121,10 +121,10 @@ else node "$PROTOCOL_BUNDLER" "$EVENT_STREAM_OUTPUT" "$EVENT_STREAM_OUTPUT" fi if [[ "$DEV_FAST_ACTIVE" != "1" ]]; then - if [[ -n "${WHITEBOARD_POSTHOG_KEY:-}" ]]; then - node "$MONOREPO_ROOT/packages/whiteboard/scripts/embed-posthog-key.mjs" + if [[ -n "${REVIEW_POSTHOG_KEY:-}" ]]; then + node "$MONOREPO_ROOT/packages/review/scripts/embed-posthog-key.mjs" fi - rebuild_review_desktop_outputs "$MONOREPO_ROOT" "$MONOREPO_ROOT/packages/whiteboard" + rebuild_review_desktop_outputs "$MONOREPO_ROOT" "$MONOREPO_ROOT/packages/review" node "$APP_DIR/scripts/copy-canvas.mjs" fi if [[ -n "$TYPECHECK_PID" ]]; then diff --git a/apps/review-desktop/scripts/canvas-host-layout.test.mjs b/apps/review-desktop/scripts/canvas-host-layout.test.mjs new file mode 100644 index 000000000..929442bef --- /dev/null +++ b/apps/review-desktop/scripts/canvas-host-layout.test.mjs @@ -0,0 +1,40 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import test from "node:test"; + +const reviewCanvasPart = await readFile( + new URL( + "../code-oss/src/vs/review/browser/parts/canvas/reviewCanvasPart.ts", + import.meta.url, + ), + "utf8", +); + +const reviewCss = await readFile( + new URL("../code-oss/src/vs/review/browser/media/review.css", import.meta.url), + "utf8", +); + +test("peek overflow widgets host lives outside the canvas root", () => { + // Inside the workbench container (theme variables are scoped to + // .monaco-workbench), never inside the canvas surface. + assert.match( + reviewCanvasPart, + /layoutService\s*\.getContainer\(getWindow\(parent\)\)\s*\.appendChild\(overflowWidgets\)/, + ); + assert.match( + reviewCanvasPart, + /setOverflowWidgetsDomNode\(overflowWidgets\)/, + ); + assert.match( + reviewCss, + /\.review-overflow-widgets\s*{[^}]*position:\s*fixed;/s, + ); +}); + +test("Review canvas restores text selection inside the workbench", () => { + assert.match( + reviewCss, + /\.review-canvas-part \.review-canvas-host\s*{[^}]*-webkit-user-select:\s*text;[^}]*user-select:\s*text;/s, + ); +}); diff --git a/apps/whiteboard-desktop/scripts/code-oss-bootstrap.mjs b/apps/review-desktop/scripts/code-oss-bootstrap.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/code-oss-bootstrap.mjs rename to apps/review-desktop/scripts/code-oss-bootstrap.mjs diff --git a/apps/whiteboard-desktop/scripts/code-oss-bootstrap.test.mjs b/apps/review-desktop/scripts/code-oss-bootstrap.test.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/code-oss-bootstrap.test.mjs rename to apps/review-desktop/scripts/code-oss-bootstrap.test.mjs diff --git a/apps/whiteboard-desktop/scripts/code-oss-dependencies.sh b/apps/review-desktop/scripts/code-oss-dependencies.sh similarity index 100% rename from apps/whiteboard-desktop/scripts/code-oss-dependencies.sh rename to apps/review-desktop/scripts/code-oss-dependencies.sh diff --git a/apps/whiteboard-desktop/scripts/compile-darwin-payload.sh b/apps/review-desktop/scripts/compile-darwin-payload.sh similarity index 90% rename from apps/whiteboard-desktop/scripts/compile-darwin-payload.sh rename to apps/review-desktop/scripts/compile-darwin-payload.sh index 872847cd0..933af08a3 100755 --- a/apps/whiteboard-desktop/scripts/compile-darwin-payload.sh +++ b/apps/review-desktop/scripts/compile-darwin-payload.sh @@ -3,10 +3,10 @@ set -euo pipefail # The macOS release is split: Linux produces this payload, and macOS consumes it. # New packaged outputs must follow the "Linux-to-macOS build handoff" contract -# in apps/whiteboard-desktop/README.md. +# in apps/review-desktop/README.md. MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" -APP_DIR="$MONOREPO_ROOT/apps/whiteboard-desktop" +APP_DIR="$MONOREPO_ROOT/apps/review-desktop" CHECKOUT="$APP_DIR/code-oss" PAYLOAD="$APP_DIR/dist/darwin-payload.tar.zst" @@ -21,8 +21,8 @@ fi # The compile host is Linux, but curated extensions contain target-native # servers. Materialize the Darwin variants that the final app will execute. -WHITEBOARD_DESKTOP_COMPILE_ONLY=1 \ - WHITEBOARD_DESKTOP_CURATED_EXTENSION_TARGET=darwin-arm64 \ +REVIEW_DESKTOP_COMPILE_ONLY=1 \ + REVIEW_DESKTOP_CURATED_EXTENSION_TARGET=darwin-arm64 \ bash "$APP_DIR/scripts/build.sh" if git -C "$MONOREPO_ROOT" rev-parse HEAD >/dev/null 2>&1; then diff --git a/apps/whiteboard-desktop/scripts/copy-canvas.mjs b/apps/review-desktop/scripts/copy-canvas.mjs similarity index 83% rename from apps/whiteboard-desktop/scripts/copy-canvas.mjs rename to apps/review-desktop/scripts/copy-canvas.mjs index 8139aa58d..4d9bcf653 100644 --- a/apps/whiteboard-desktop/scripts/copy-canvas.mjs +++ b/apps/review-desktop/scripts/copy-canvas.mjs @@ -11,11 +11,11 @@ const monorepoRoot = path.resolve(appDirectory, "../.."); const sourceRoot = path.join( monorepoRoot, - "packages/whiteboard/app/dist/desktop", + "packages/review/app/dist/desktop", ); export function canvasTargets(args, appRoot = appDirectory) { - const targets = [path.join(appRoot, "code-oss/out/vs/whiteboard/canvas")]; + const targets = [path.join(appRoot, "code-oss/out/vs/review/canvas")]; for (let index = 0; index < args.length; index += 1) { if (args[index] !== "--packaged-root" || !args[index + 1]) { @@ -36,7 +36,7 @@ export function canvasTargets(args, appRoot = appDirectory) { ? path.join(packagedRoot, "Contents/Resources/app") : path.join(packagedRoot, "resources/app"); - targets.push(path.join(packagedAppRoot, "out/vs/whiteboard/canvas")); + targets.push(path.join(packagedAppRoot, "out/vs/review/canvas")); } return [...new Set(targets)]; @@ -62,7 +62,7 @@ export async function copyCanvas(targets = canvasTargets([])) { outputRoot === path.join(appDirectory, "code-oss/out"); if ( - relativeTarget !== path.join("vs", "whiteboard", "canvas") || + relativeTarget !== path.join("vs", "review", "canvas") || (!(await isDirectory(outputRoot)) && !isDevelopmentOutput) ) { throw new Error( @@ -89,9 +89,9 @@ export async function copyCanvas(targets = canvasTargets([])) { export function canvasLoaderSource({ canvasFile, wasmFile, stylesheets }) { return [ - `export { clearWhiteboardViewState, mountWhiteboardCanvas } from ${JSON.stringify(`./${canvasFile}`)};`, - `export const whiteboardWasmUrl = new URL(${JSON.stringify(`./${wasmFile}`)}, import.meta.url).href;`, - `export const whiteboardStylesheetUrls = ${JSON.stringify(stylesheets.map((file) => `./${file}`))}.map(file => new URL(file, import.meta.url).href);`, + `export { clearReviewViewState, mountReviewCanvas } from ${JSON.stringify(`./${canvasFile}`)};`, + `export const reviewWasmUrl = new URL(${JSON.stringify(`./${wasmFile}`)}, import.meta.url).href;`, + `export const reviewStylesheetUrls = ${JSON.stringify(stylesheets.map((file) => `./${file}`))}.map(file => new URL(file, import.meta.url).href);`, "", ].join("\n"); } diff --git a/apps/whiteboard-desktop/scripts/curated-extensions.manifest.mjs b/apps/review-desktop/scripts/curated-extensions.manifest.mjs similarity index 98% rename from apps/whiteboard-desktop/scripts/curated-extensions.manifest.mjs rename to apps/review-desktop/scripts/curated-extensions.manifest.mjs index f9a17d60c..95c7a5b53 100644 --- a/apps/whiteboard-desktop/scripts/curated-extensions.manifest.mjs +++ b/apps/review-desktop/scripts/curated-extensions.manifest.mjs @@ -13,7 +13,7 @@ // and paste the emitted sha256 values back in here. /** - * `group` drives the DEV_WHITEBOARD_EXTENSIONS materialization filter in run.sh. + * `group` drives the DEV_REVIEW_EXTENSIONS materialization filter in run.sh. * Which of the materialized extensions are enabled is a separate, persisted * choice made through the in-app "Manage Extensions" picker. * @@ -274,7 +274,7 @@ export const curatedExtensions = Object.freeze([ /** Build targets Review knows how to materialize platform-specific VSIXes for. */ export const supportedTargets = Object.freeze(["darwin-arm64", "linux-x64"]); -/** Group tokens accepted by DEV_WHITEBOARD_EXTENSIONS, in display order. */ +/** Group tokens accepted by DEV_REVIEW_EXTENSIONS, in display order. */ export const curatedGroups = Object.freeze([ "rust", "swift", @@ -352,7 +352,7 @@ export function targetKeyFor(extension, target) { return extension.targets[target] ? target : undefined; } -/** Parses a DEV_WHITEBOARD_EXTENSIONS value into the set of groups to materialize. */ +/** Parses a DEV_REVIEW_EXTENSIONS value into the set of groups to materialize. */ export function parseGroupSelection(raw) { const value = (raw ?? "all").trim(); diff --git a/apps/whiteboard-desktop/scripts/curated-extensions.mjs b/apps/review-desktop/scripts/curated-extensions.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/curated-extensions.mjs rename to apps/review-desktop/scripts/curated-extensions.mjs diff --git a/apps/whiteboard-desktop/scripts/curated-extensions.test.mjs b/apps/review-desktop/scripts/curated-extensions.test.mjs similarity index 94% rename from apps/whiteboard-desktop/scripts/curated-extensions.test.mjs rename to apps/review-desktop/scripts/curated-extensions.test.mjs index 09d296da1..ed04c9dc3 100644 --- a/apps/whiteboard-desktop/scripts/curated-extensions.test.mjs +++ b/apps/review-desktop/scripts/curated-extensions.test.mjs @@ -55,15 +55,15 @@ const runScript = await readFile(new URL("./run.sh", import.meta.url), "utf8"); const curatedContribution = await readFile( new URL( - "../code-oss/src/vs/whiteboard/contrib/extensions/whiteboardCuratedExtensions.contribution.ts", + "../code-oss/src/vs/review/contrib/extensions/reviewCuratedExtensions.contribution.ts", import.meta.url, ), "utf8", ); -const whiteboardConfiguration = await readFile( +const reviewConfiguration = await readFile( new URL( - "../code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.ts", + "../code-oss/src/vs/review/common/reviewConfigurationDefaults.ts", import.meta.url, ), "utf8", @@ -87,11 +87,11 @@ async function loadImportFreeTypeScriptModule(url) { const mainOptionalCatalog = ( await loadImportFreeTypeScriptModule( new URL( - "../code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionCatalog.ts", + "../code-oss/src/vs/review/node/reviewOptionalExtensionCatalog.ts", import.meta.url, ), ) -).whiteboardOptionalExtensionCatalog; +).reviewOptionalExtensionCatalog; test("pins every curated extension to a checksum for every supported target", () => { assert.ok(curatedExtensions.length > 0); @@ -258,7 +258,7 @@ test("resolves a target key for every extension on every supported target", () = } }); -test("parses DEV_WHITEBOARD_EXTENSIONS selections", () => { +test("parses DEV_REVIEW_EXTENSIONS selections", () => { assert.deepEqual([...bundledGroups], ["python", "vim", "emacs"]); assert.deepEqual([...optionalGroups], ["rust", "swift", "csharp", "go"]); assert.deepEqual( @@ -295,10 +295,10 @@ test("carries Darwin curated extensions from Linux compile through release valid ), ]); - assert.match(buildScript, /WHITEBOARD_DESKTOP_CURATED_EXTENSION_TARGET/); + assert.match(buildScript, /REVIEW_DESKTOP_CURATED_EXTENSION_TARGET/); assert.match( compileScript, - /WHITEBOARD_DESKTOP_CURATED_EXTENSION_TARGET=darwin-arm64/, + /REVIEW_DESKTOP_CURATED_EXTENSION_TARGET=darwin-arm64/, ); assert.match( compileScript, @@ -358,7 +358,7 @@ test("ignores every materialized curated extension directory", () => { }); test("materializes the selected groups from run.sh", () => { - assert.match(runScript, /DEV_WHITEBOARD_EXTENSIONS/); + assert.match(runScript, /DEV_REVIEW_EXTENSIONS/); assert.match(runScript, /curated-extensions\.mjs/); }); @@ -492,7 +492,7 @@ test("keeps the in-app picker list in sync with the manifest", () => { for (const extension of bundledExtensions) { assert.ok( curatedContribution.includes(`id: '${extension.id}'`), - `${extension.id} must appear in whiteboardCuratedExtensions.contribution.ts`, + `${extension.id} must appear in reviewCuratedExtensions.contribution.ts`, ); } @@ -527,7 +527,7 @@ test("manages optional extensions as four user-facing groups", () => { } assert.match(curatedContribution, /installMissingOptionalExtensions/); - assert.match(curatedContribution, /vscode:whiteboardDownloadOptionalExtension/); + assert.match(curatedContribution, /vscode:reviewDownloadOptionalExtension/); assert.match(curatedContribution, /getInstalled\(\)/); assert.match(curatedContribution, /getInstalled\(ExtensionType\.User\)/); assert.match(curatedContribution, /donotIncludePackAndDependencies: true/); @@ -547,11 +547,11 @@ test("keeps the keymaps mutually exclusive in the picker", () => { assert.match(curatedContribution, /KEYMAP_IDS/); - const enumDeclaration = whiteboardConfiguration.match( - /WHITEBOARD_KEYMAPS\s*=\s*\[([^\]]+)\]/, + const enumDeclaration = reviewConfiguration.match( + /REVIEW_KEYMAPS\s*=\s*\[([^\]]+)\]/, ); - assert.ok(enumDeclaration, "whiteboard.keymap enum declaration"); + assert.ok(enumDeclaration, "review.keymap enum declaration"); const enumValues = [...enumDeclaration[1].matchAll(/'([^']+)'/g)].map( (match) => match[1], diff --git a/apps/review-desktop/scripts/curated-keymap-and-quick-access.test.mjs b/apps/review-desktop/scripts/curated-keymap-and-quick-access.test.mjs new file mode 100644 index 000000000..c6f9f10ba --- /dev/null +++ b/apps/review-desktop/scripts/curated-keymap-and-quick-access.test.mjs @@ -0,0 +1,33 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import test from "node:test"; + +const quickAccess = await readFile( + new URL( + "../code-oss/src/vs/review/contrib/quickaccess/reviewQuickAccess.contribution.ts", + import.meta.url, + ), + "utf8", +); + +const curatedExtensions = await readFile( + new URL( + "../code-oss/src/vs/review/contrib/extensions/reviewCuratedExtensions.contribution.ts", + import.meta.url, + ), + "utf8", +); + +test("keeps extension-contributed commands visible in Review quick access", () => { + assert.match(quickAccess, /IExtensionService/); + assert.match(quickAccess, /extension\.contributes\?\.commands/); + assert.match(quickAccess, /extensionCommands\.has\(commandId\)/); +}); + +test("drives curated keymap defaults from review.keymap", () => { + assert.match( + curatedExtensions, + /getValue\(REVIEW_KEYMAP_SETTING\)/, + ); + assert.match(curatedExtensions, /defaultsApplied\.v2/); +}); diff --git a/apps/review-desktop/scripts/darwin-payload-manifest.sh b/apps/review-desktop/scripts/darwin-payload-manifest.sh new file mode 100644 index 000000000..802da3c13 --- /dev/null +++ b/apps/review-desktop/scripts/darwin-payload-manifest.sh @@ -0,0 +1,24 @@ +# shellcheck shell=bash +# This file exports variables to the scripts that source it. +# shellcheck disable=SC2034 + +# Paths are relative to the monorepo root. macOS packaging checks every +# required path after it extracts the Linux-built Darwin payload. +DARWIN_PAYLOAD_CURATED_EXTENSIONS_PATH="apps/review-desktop/code-oss/.build/review-curated-extensions/darwin-arm64" + +DARWIN_PAYLOAD_REQUIRED_PATHS=( + "apps/review-desktop/code-oss/out-vscode-min" + "apps/review-desktop/code-oss/.build/extensions" + "$DARWIN_PAYLOAD_CURATED_EXTENSIONS_PATH" + "packages/review/app/dist/desktop" + "packages/review/dist" + "packages/review/tutorial" + "packages/local-vcs/dist" +) + +# These build intermediates belong in the archive, but the macOS wrapper does +# not read them directly before Gulp assembles the application. +DARWIN_PAYLOAD_ARCHIVE_ONLY_PATHS=( + "apps/review-desktop/code-oss/out-build" + "apps/review-desktop/code-oss/out" +) diff --git a/apps/review-desktop/scripts/desktop-branding.test.mjs b/apps/review-desktop/scripts/desktop-branding.test.mjs new file mode 100644 index 000000000..a2a6c9176 --- /dev/null +++ b/apps/review-desktop/scripts/desktop-branding.test.mjs @@ -0,0 +1,31 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import test from "node:test"; + +const readSource = (relativePath) => + readFile(new URL(relativePath, import.meta.url), "utf8"); + +const product = JSON.parse(await readSource("../code-oss/product.json")); + +const themePackage = JSON.parse( + await readSource("../code-oss/extensions/review-themes/package.json"), +); + +test("uses slash-form branding in Review Desktop display surfaces", () => { + assert.equal(product.nameLong, "/dev/fast Review"); + assert.equal(product.win32NameVersion, "/dev/fast Review"); + assert.equal(themePackage.description, "Themes for /dev/fast Review."); +}); + +test("keeps compatibility-sensitive Desktop identifiers unchanged", () => { + assert.equal(product.darwinBundleIdentifier, "dev.fast.review"); + assert.equal(product.updateUrl, "https://update.dev.fast"); + assert.equal(product.urlProtocol, "dev-fast-review"); + assert.equal(product.dataFolderName, ".dev-fast-review"); + assert.equal(product.sharedDataFolderName, ".dev-fast-review-shared"); +}); + +test("uses the product short name for app bundle paths", async () => { + assert.equal(product.nameShort, "Review"); + assert.equal(product.win32DirName, "Review"); +}); diff --git a/apps/whiteboard-desktop/scripts/diff-layout-toggle-contract.test.mjs b/apps/review-desktop/scripts/diff-layout-toggle-contract.test.mjs similarity index 91% rename from apps/whiteboard-desktop/scripts/diff-layout-toggle-contract.test.mjs rename to apps/review-desktop/scripts/diff-layout-toggle-contract.test.mjs index 3fb52c582..d2ab8a67e 100644 --- a/apps/whiteboard-desktop/scripts/diff-layout-toggle-contract.test.mjs +++ b/apps/review-desktop/scripts/diff-layout-toggle-contract.test.mjs @@ -18,9 +18,9 @@ const diffCommandsService = readFileSync( "utf8", ); -const whiteboardWorkbenchMain = readFileSync( +const reviewWorkbenchMain = readFileSync( new URL( - "../code-oss/src/vs/whiteboard/whiteboard.common.main.ts", + "../code-oss/src/vs/review/review.common.main.ts", import.meta.url, ), "utf8", @@ -47,7 +47,7 @@ test("native diff editors expose the canonical inline/split toolbar toggle", () /updateValue\(modifiedResource, key, !value\)/, ); assert.match( - whiteboardWorkbenchMain, + reviewWorkbenchMain, /parts\/editor\/diffEditor\.workbench\.contribution\.js/, "Review must register the service backing the native toggle command", ); diff --git a/apps/whiteboard-desktop/scripts/e2e-runner.test.mjs b/apps/review-desktop/scripts/e2e-runner.test.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e-runner.test.mjs rename to apps/review-desktop/scripts/e2e-runner.test.mjs diff --git a/apps/whiteboard-desktop/scripts/e2e/KNOWN_BUGS.md b/apps/review-desktop/scripts/e2e/KNOWN_BUGS.md similarity index 85% rename from apps/whiteboard-desktop/scripts/e2e/KNOWN_BUGS.md rename to apps/review-desktop/scripts/e2e/KNOWN_BUGS.md index 2be6840a2..570ff1736 100644 --- a/apps/whiteboard-desktop/scripts/e2e/KNOWN_BUGS.md +++ b/apps/review-desktop/scripts/e2e/KNOWN_BUGS.md @@ -16,7 +16,7 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). - A community invitation dismissed before the first-run reload comes back — fix-pr #351 - The modal editor opened by Go to Definition ignores the first Escape — fix-pr #352 - The review topbar covers the Find widget and the contents pill — fix-pr #350 -- A review whose repository directory moves or is deleted renders `WhiteboardApiError: Review operation failed.` — fix-pr #355 +- A review whose repository directory moves or is deleted renders `ReviewApiError: Review operation failed.` — fix-pr #355 - `review app pick` goes to the launcher instead of reporting an unusable pointer — fix-pr #348 - One unreadable legacy `review.json` stops Review Desktop from starting — fix-pr #349 - Home says nothing about a legacy review directory left behind by the JSON cutover — not-a-bug @@ -38,11 +38,11 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `review info --review --json`. - **Expected:** the command prints the review's summary and exits 0. - **Actual:** exits 1 with - `{"name":"WhiteboardApiError","message":"Not found."}` thrown from - `WhiteboardApiClient.response`. `review info` with no `--review` fails the same way, + `{"name":"ReviewApiError","message":"Not found."}` thrown from + `ReviewApiClient.response`. `review info` with no `--review` fails the same way, so the verb is unusable. -- **Notes:** `whiteboard-info.ts:33` calls `client.read("/")`, and - `whiteboard-api-client.ts:75` builds `${serverUrl}/reviews-api${route}`, so the +- **Notes:** `review-info.ts:33` calls `client.read("/")`, and + `review-api-client.ts:75` builds `${serverUrl}/reviews-api${route}`, so the request goes to `/reviews-api/` with a trailing slash. The route is mounted at `/reviews-api` (`server/desktop-server.ts:159`) and Hono matches it strictly: a live probe returned 200 for `GET /reviews-api` and 404 for `GET /reviews-api/`. @@ -56,21 +56,21 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `review app pick --review --json`. - **Expected:** Desktop opens that review and the command exits 0. - **Actual:** exits 1 with - `{"name":"WhiteboardApiError","message":"Review or version not found."}` thrown from - `WhiteboardApiClient.post`. Reproduced for both importable fixtures. -- **Notes:** `whiteboard-app.ts:63` does + `{"name":"ReviewApiError","message":"Review or version not found."}` thrown from + `ReviewApiClient.post`. Reproduced for both importable fixtures. +- **Notes:** `review-app.ts:63` does `review = await client.read("/")` expecting - `Pick`, but `GET /reviews-api/:id` + `Pick`, but `GET /reviews-api/:id` returns `inspectSnapshot(...)` — an array of blocks — unless `full=true` - (`session-api/http.ts:620-637`). So `review.reviewId` is `undefined` and - `whiteboard-app.ts:93` posts to `/reviews-api/undefined/open`, which 404s. + (`review-api/http.ts:620-637`). So `review.reviewId` is `undefined` and + `review-app.ts:93` posts to `/reviews-api/undefined/open`, which 404s. `POST /reviews-api//open` works, so only the id lookup is wrong. ## The first-run telemetry notice disappears before it can be used - **Journey:** `first-run` · **Found:** 2026-09-17 · **Status:** fix-pr #351 - **Repro:** launch Desktop on a fresh profile with telemetry live - (`DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED` unset). The notification "Review sends + (`DEV_FAST_REVIEW_TELEMETRY_DISABLED` unset). The notification "Review sends anonymous usage data. You can change this in Settings." appears behind the modal "Join the Review community" dialog; dismiss the dialog and look for the notification. @@ -82,10 +82,10 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `review.telemetry.noticeShown.v1 = true` already in `/User/globalStorage/state.vscdb`. A first click on "Open Settings" fails with `element was detached from the DOM`. -- **Notes:** `whiteboardTelemetry.contribution.ts:36-41` stores the shown flag +- **Notes:** `reviewTelemetry.contribution.ts:36-41` stores the shown flag before it calls `notificationService.prompt`, so the notice is spent whether or not anyone saw it, and - `whiteboardCuratedExtensions.contribution.ts:664` runs + `reviewCuratedExtensions.contribution.ts:664` runs `workbench.action.reloadWindow` on a fresh profile once the keymap defaults are seeded. Storing the flag when the notice is dismissed, or re-showing it after the seeding reload, would fix it. @@ -103,9 +103,9 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). shared `sharedStorage/state.vscdb`. The journey corroborates the reading before it records this bug, and a stored flag would fail it instead with `the invitation returned although review.community.dontShowAgain is true`. -- **Notes:** `whiteboardCommunity.contribution.ts:35-38` stores the flag from the +- **Notes:** `reviewCommunity.contribution.ts:35-38` stores the flag from the dialog's promise callback, and - `whiteboardCuratedExtensions.contribution.ts:664` reloads the window on a fresh + `reviewCuratedExtensions.contribution.ts:664` reloads the window on a fresh profile about 1.8 s in; the pending storage write does not survive that reload. A dismissal after the reload persists, so only the first-run window loses it. @@ -142,32 +142,32 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `Match Whole Word` or `Use Regular Expression` in the Find widget. - **Expected:** the pill opens the contents drawer and the toggles flip. - **Actual:** neither click reaches its button. Playwright reports - `
…
intercepts pointer events` for the - pill and `
…
… subtree intercepts + `
…
intercepts pointer events` for the + pill and `
…
… subtree intercepts pointer events` for the toggles, and `document.elementFromPoint` at the - centre of each control returns an element inside `.whiteboard-topbar`. + centre of each control returns an element inside `.review-topbar`. - **Notes:** measured in the workbench renderer (viewport 1200x800): the review - canvas starts at y=74, `.whiteboard-topbar` is `position: sticky` from 74 to 109 - with `z-index: var(--whiteboard-debug-layer)` (`styles.css:2318`), and the whole + canvas starts at y=74, `.review-topbar` is `position: sticky` from 74 to 109 + with `z-index: var(--review-debug-layer)` (`styles.css:2318`), and the whole review scroll region starts at 109. That token is `2147483000` (`styles.css:140`) and five rules share it (`:1704`, `:1770`, `:2318`, `:3137`, `:3896`), so a fix belongs on the token or on the overlays, not on a literal; the prebuilt canvas CSS the staged runtime ships still carries an older `2147480000`, which is the number the measurement reports. Both overlays are laid out against a containing block whose top is y=40 — 34 px - above the canvas — so they land inside that band: `.whiteboard-toc-toggle` - (`position: fixed; top: calc(32px + var(--whiteboard-page-top))`, + above the canvas — so they land inside that band: `.review-toc-toggle` + (`position: fixed; top: calc(32px + var(--review-page-top))`, `styles.css:4641-4646`) measures 92–124, and - `.whiteboard-find-widget` (`position: absolute; top: 48px; z-index: 120`, + `.review-find-widget` (`position: absolute; top: 48px; z-index: 120`, `styles.css:503-519`) puts its toggles at 95–115. The topbar's near-maximum `z-index` beats both, so the covered part of each control is dead. The pill is - the only way into the contents below a 1360 px shell (`whiteboard-toc.tsx:25`, + the only way into the contents below a 1360 px shell (`review-toc.tsx:25`, `:216`), so in a normal window the reader has no working table of contents at all. The journey corroborates each failure with both Playwright's interception message and `elementFromPoint` before it falls back to `dispatchEvent("click")`. -## A review whose repository directory moves or is deleted renders `WhiteboardApiError: Review operation failed.` +## A review whose repository directory moves or is deleted renders `ReviewApiError: Review operation failed.` - **Journey:** `worktree-drift` · **Found:** 2026-09-17 · **Status:** fix-pr #355 - **Repro:** create a review with a `commits` target in a git repository, let it @@ -179,8 +179,8 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `-moved/.git/dev-fast/reviews//head/` and moved with the repository — or says which checkout it can no longer find. - **Actual:** the canvas renders only - `

WhiteboardApiError: Review operation failed.

` inside - `.whiteboard-canvas-root [data-whiteboard-api]`, with no title, no document and no + `

ReviewApiError: Review operation failed.

` inside + `.review-canvas-root [data-review-api]`, with no title, no document and no path. `GET /reviews-api//commits?version=` answers 500 with `{"error":"Review operation failed."}`; `GET /reviews-api/?full=true` and `GET /reviews-api` still answer 200 with the whole document, so the @@ -192,12 +192,12 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). and Home keeps offering the review (and a `View source →` link) under a directory that no longer exists. `api-document.tsx:100-105` loads `//commits` before anything else renders, and every provider failure - becomes the generic 500 at `session-api/http.ts:50`, which + becomes the generic 500 at `review-api/http.ts:50`, which `api-canvas.tsx:166` shows verbatim. A graceful degradation exists — `sourceUnavailable`, rendered as "Local checkout unavailable. Showing retained source." (`api-document.tsx:224-228`) — and one of its two writers is not gated on the target kind: `GET /:id?full=true` sets it for any target - when `data.sourcePins(snapshot)` throws a 404 `WhiteboardInputError` + when `data.sourcePins(snapshot)` throws a 404 `ReviewInputError` (`http.ts:620-633`). That path was not taken here — `?full=true` answered 200 and did not degrade, so `sourcePins` still resolved after the rename, and whatever `/:id/commits` needs from the repository is not what `sourcePins` @@ -206,7 +206,7 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `store.ts:186-198` and `:225-243`, *is* gated on `target.kind === "worktree"` and cannot fire for this review either.) The `Worktree unavailable` state at `desktop-entry.tsx:38-46` is unreachable - today: the only `{ kind: "source" }` render (`whiteboardCanvasPart.ts:308`) never + today: the only `{ kind: "source" }` render (`reviewCanvasPart.ts:308`) never sets `error`, so no journey can assert that string. ## `review app pick` goes to the launcher instead of reporting an unusable pointer @@ -233,21 +233,21 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). silent 90 s hang and a user without it gets a second Desktop. The journey asserts no pointer error reached the output, and that the command either reached a Desktop after the replacement or reported that it could not launch - one; it kills whatever it started, identified by `DEV_WHITEBOARD_HOME` in the + one; it kills whatever it started, identified by `DEV_REVIEW_HOME` in the process environment so a Desktop belonging to another session is never touched. -- **Notes:** `whiteboard-app.ts:49-50` calls `runtime.launch()` before it reads the - pointer, and `whiteboard-app-launcher.ts:281-289` catches every discovery error on +- **Notes:** `review-app.ts:49-50` calls `runtime.launch()` before it reads the + pointer, and `review-app-launcher.ts:281-289` catches every discovery error on purpose ("Launch must recover from stale, malformed, and incompatible discovery") and returns `null`, which the launcher reads as "nothing is running". Recovering by launching is right for `review app launch`, which the user asked to start something; for every other verb it turns a one-line diagnosis into a second Desktop and a 90 s wait. Reading the pointer first and - rethrowing anything but `null` from `runWhiteboardAppPick` would fix it. Two + rethrowing anything but `null` from `runReviewAppPick` would fix it. Two consequences beyond the message: the launched app inherits the caller's environment (`open`(1) propagates it), so it attaches to whichever - `DEV_WHITEBOARD_HOME` the CLI had; and the "Review Desktop is not ready. Run - `review app launch` and retry `review app pick`." throw at `whiteboard-app.ts:52-55` + `DEV_REVIEW_HOME` the CLI had; and the "Review Desktop is not ready. Run + `review app launch` and retry `review app pick`." throw at `review-app.ts:52-55` is unreachable, because a null pointer read means the launcher already gave up. ## One unreadable legacy `review.json` stops Review Desktop from starting @@ -258,12 +258,12 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `/reviews/11111111-1111-4111-8111-111111111111/review.json` holding `{"schemaVersion":1,"uuid":"11111111-1111-4111-8111-111111111111"}` — then start the Desktop's server host against that home - (`node /dist/server/desktop-host.js` with `DEV_WHITEBOARD_HOME=`, - `DEV_FAST_WHITEBOARD_SERVER_PORT=0`, `DEV_FAST_WHITEBOARD_APP_PID=`). + (`node /dist/server/desktop-host.js` with `DEV_REVIEW_HOME=`, + `DEV_FAST_REVIEW_SERVER_PORT=0`, `DEV_FAST_REVIEW_APP_PID=`). - **Expected:** the host starts, the reviews it can read are available, and the one it cannot is reported to the reader with the command its own error text names: "Invalid review.json; run `review migrate apply`" - (`whiteboard-home.ts:364-366`, `:706-710`). + (`review-home.ts:364-366`, `:706-710`). - **Actual:** the host exits 1 before it ever listens, and nothing starts. It prints `Error: Review migration could not finish. The original database is unchanged. Report: /.json-cutover-XXXXXX/report.json`, followed by the @@ -280,14 +280,14 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). In the app this is not a message the reader gets: the supervisor restarts the host on each exit and, once the delay budget runs out, fails with the generic "The Review server exhausted its restart budget without becoming ready." - (`whiteboardServerSupervisor.ts:290-313`), leaving the schema dump in the log. + (`reviewServerSupervisor.ts:290-313`), leaving the schema dump in the log. The advice the record's own error carries does not help either: `review migrate apply` on this record reports `: current artifact migration failed: Unsupported Review schema; the record was preserved.` and exits 1 (`stored-review-migration.ts:95-100`, `:190-194`), so a reader whose Desktop will not start has no way forward but to find and move the directory by hand. Skipping the unreadable directory — the cutover already records it in - `report.errors`, and `migrateJsonWhiteboards` leaves every original untouched — + `report.errors`, and `migrateJsonReviews` leaves every original untouched — and surfacing it once the app is up would keep the safety and the app. - **Also found, not a bug:** "Home says nothing about a legacy review directory left behind by the JSON cutover", below. @@ -309,9 +309,9 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `{"schemaVersion":1,"uuid":"11111111-1111-4111-8111-111111111111"}`, restart Review Desktop and open Home. - **Expected (by the plan):** Home lists the review as needing migration and - names the command to run, from the `MIGRATION_REQUIRED` `WhiteboardHomeError` + names the command to run, from the `MIGRATION_REQUIRED` `ReviewHomeError` whose message is "Invalid review.json; run `review migrate apply`: …" - (`whiteboard-home.ts:364-366`, `:706-710`). + (`review-home.ts:364-366`, `:706-710`). - **Actual:** Home renders the empty-Home onboarding rail and mentions neither the review nor the command; `GET /reviews-api` answers 200 without it; the directory is left byte-for-byte as seeded. The journey asserts all three, and @@ -319,12 +319,12 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). guidance, so the expectation is recorded rather than dropped. - **Notes:** `ensureJsonCutover` (`json-cutover.ts:238-270`) returns on its marker without reading `/reviews` again, and Home lists from the JSON - store (`session-api/store.ts:485`). The `MIGRATION_REQUIRED` error has no - Desktop consumer at all: it reaches only `ListWhiteboardsResult.errors` - (`whiteboard-home.ts:139-143`), `listWhiteboards` has one non-test caller, + store (`review-api/store.ts:485`). The `MIGRATION_REQUIRED` error has no + Desktop consumer at all: it reaches only `ListReviewsResult.errors` + (`review-home.ts:139-143`), `listReviews` has one non-test caller, `publish-preparation.ts:24` — the only place that sets - `reportUnreadableWhiteboards` — and `WhiteboardHomeError` appears nowhere in - `packages/whiteboard/app/src`. What is worth fixing is the path where such a + `reportUnreadableReviews` — and `ReviewHomeError` appears nowhere in + `packages/review/app/src`. What is worth fixing is the path where such a directory still matters, which is the entry above: before the cutover has run, the same record stops the Desktop from starting. @@ -332,11 +332,11 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). - **Journey:** `lsp-go` · **Found:** 2026-09-17 · **Status:** fix-pr #354 - **Repro:** launch Desktop with the curated `go` group materialized - (`DEV_WHITEBOARD_EXTENSIONS=go`) on a machine whose PATH and GOPATH have no + (`DEV_REVIEW_EXTENSIONS=go`) on a machine whose PATH and GOPATH have no `gopls`, then open a review with a `code_peek` over a `.go` file. - **Expected:** Review asks before it downloads and builds a language server, the way it asks before downloading an optional extension - (`whiteboardCuratedExtensions.contribution.ts:244-527`), or at least the way the + (`reviewCuratedExtensions.contribution.ts:244-527`), or at least the way the Go extension's own `promptForMissingTool` asks — `The "gopls" command is not available. Run "go install -v golang.org/x/tools/gopls@latest" to install.` with an `Install` action. @@ -357,7 +357,7 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). after that pass. `curated-extensions.manifest.mjs:247-248` describes the extension as prompting, which was true of older releases and is not true of the pinned one. - `whiteboardConfigurationDefaults.ts:104-107` already turns off that extension's + `reviewConfigurationDefaults.ts:104-107` already turns off that extension's survey and update prompts; it has no setting for this one, because the extension offers none — `go.toolsManagement.checkForUpdates: 'off'` only covers updates of tools that are already installed. Review chooses which @@ -386,7 +386,7 @@ Status values: `open`, `fix-pr #`, `fixed`, `not-a-bug` (with the reason). `Using server binary at …`, which is the line the extension logs once it has decided it has a workspace. Nothing recovers it: the journey asserts that signature before it retries in a new window. -- **Notes:** `whiteboardLocalLanguageFeatures.acquire` (`:152-166`) adds the +- **Notes:** `reviewLocalLanguageFeatures.acquire` (`:152-166`) adds the checkout as a workspace folder and then calls `extensions.activateByEvent("onLanguage:rust")` — but `addFolders` resolving in the renderer (`workspaceContextService.ts:72-74`, `:110-166`) does not mean diff --git a/apps/whiteboard-desktop/scripts/e2e/TESTING.md b/apps/review-desktop/scripts/e2e/TESTING.md similarity index 81% rename from apps/whiteboard-desktop/scripts/e2e/TESTING.md rename to apps/review-desktop/scripts/e2e/TESTING.md index 143a085fd..9107b11ec 100644 --- a/apps/whiteboard-desktop/scripts/e2e/TESTING.md +++ b/apps/review-desktop/scripts/e2e/TESTING.md @@ -9,7 +9,7 @@ a contract test that checks every journey exports `name`, `phase` and `run`. ## Prerequisites macOS or Linux, Node 24, and a built Desktop from -`pnpm --filter @dev.fast/whiteboard-desktop app:build`. `go` and `cargo` are needed +`pnpm --filter @dev.fast/review-desktop app:build`. `go` and `cargo` are needed only for the phase-2 journeys. ## Staging the runtime @@ -17,16 +17,16 @@ only for the phase-2 journeys. `--runtime` must name a production install of the CLI, not this checkout: ```sh -pnpm --filter @dev.fast/whiteboard-desktop app:build -(cd packages/whiteboard && pnpm pack --pack-destination /tmp/review-pack) +pnpm --filter @dev.fast/review-desktop app:build +(cd packages/review && pnpm pack --pack-destination /tmp/review-pack) mkdir -p /tmp/review-runtime && (cd /tmp/review-runtime && npm init -y >/dev/null && npm install --omit=dev /tmp/review-pack/dev.fast-review-*.tgz) -export WHITEBOARD_E2E_RUNTIME=/tmp/review-runtime/node_modules/@dev.fast/whiteboard +export REVIEW_E2E_RUNTIME=/tmp/review-runtime/node_modules/@dev.fast/review ``` ## Running ```sh -node apps/whiteboard-desktop/scripts/e2e/run.mjs --runtime "$WHITEBOARD_E2E_RUNTIME" +node apps/review-desktop/scripts/e2e/run.mjs --runtime "$REVIEW_E2E_RUNTIME" ``` `--journey a,b` selects journeys by name, `--list` prints them without launching @@ -40,7 +40,7 @@ prints a JSON summary on stdout, one entry per journey, `ok | failed | skipped`. Phase 1 runs offline, after a one-time network fetch of the curated VSIX cache that `lsp-python` triggers. Phase 2 (`lsp-go`, `lsp-rust`) downloads toolchains -and runs only with `WHITEBOARD_E2E_NETWORK=1`. In development mode each journey +and runs only with `REVIEW_E2E_NETWORK=1`. In development mode each journey re-materializes its extension group through `run.sh`, so this checkout's `code-oss/extensions` holds the last journey's selection afterwards; `node scripts/curated-extensions.mjs --only=all` restores it. @@ -51,7 +51,7 @@ A journey module exports `name` (matching its basename), `phase`, `options` passed to `createHarness`, and `run(ctx)`. Useful `ctx` helpers: `until` for polling, `api` and `apiOk` for the JSON review API, `cli` and `cliRaw` for the installed CLI, `check` to record what the journey proved, plus `knownBug`, -`restartDesktop`, `createWhiteboard`, `openHome` and `pickWhiteboard`. Throw +`restartDesktop`, `createReview`, `openHome` and `pickReview`. Throw `Error("skip: ...")` when the machine cannot run the journey. ## Known bugs diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/go/go.mod b/apps/review-desktop/scripts/e2e/fixtures/lsp/go/go.mod similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/go/go.mod rename to apps/review-desktop/scripts/e2e/fixtures/lsp/go/go.mod diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/go/orders.go b/apps/review-desktop/scripts/e2e/fixtures/lsp/go/orders.go similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/go/orders.go rename to apps/review-desktop/scripts/e2e/fixtures/lsp/go/orders.go diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/go/storage.go b/apps/review-desktop/scripts/e2e/fixtures/lsp/go/storage.go similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/go/storage.go rename to apps/review-desktop/scripts/e2e/fixtures/lsp/go/storage.go diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/python/orders.py b/apps/review-desktop/scripts/e2e/fixtures/lsp/python/orders.py similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/python/orders.py rename to apps/review-desktop/scripts/e2e/fixtures/lsp/python/orders.py diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/python/storage.py b/apps/review-desktop/scripts/e2e/fixtures/lsp/python/storage.py similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/python/storage.py rename to apps/review-desktop/scripts/e2e/fixtures/lsp/python/storage.py diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/rust/Cargo.toml b/apps/review-desktop/scripts/e2e/fixtures/lsp/rust/Cargo.toml similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/rust/Cargo.toml rename to apps/review-desktop/scripts/e2e/fixtures/lsp/rust/Cargo.toml diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/rust/src/lib.rs b/apps/review-desktop/scripts/e2e/fixtures/lsp/rust/src/lib.rs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/rust/src/lib.rs rename to apps/review-desktop/scripts/e2e/fixtures/lsp/rust/src/lib.rs diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/rust/src/storage.rs b/apps/review-desktop/scripts/e2e/fixtures/lsp/rust/src/storage.rs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/rust/src/storage.rs rename to apps/review-desktop/scripts/e2e/fixtures/lsp/rust/src/storage.rs diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/typescript/orders.ts b/apps/review-desktop/scripts/e2e/fixtures/lsp/typescript/orders.ts similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/typescript/orders.ts rename to apps/review-desktop/scripts/e2e/fixtures/lsp/typescript/orders.ts diff --git a/apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/typescript/storage.ts b/apps/review-desktop/scripts/e2e/fixtures/lsp/typescript/storage.ts similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/fixtures/lsp/typescript/storage.ts rename to apps/review-desktop/scripts/e2e/fixtures/lsp/typescript/storage.ts diff --git a/apps/whiteboard-desktop/scripts/e2e/harness.mjs b/apps/review-desktop/scripts/e2e/harness.mjs similarity index 90% rename from apps/whiteboard-desktop/scripts/e2e/harness.mjs rename to apps/review-desktop/scripts/e2e/harness.mjs index eb9b63fff..87128bf42 100644 --- a/apps/whiteboard-desktop/scripts/e2e/harness.mjs +++ b/apps/review-desktop/scripts/e2e/harness.mjs @@ -17,7 +17,7 @@ import os from "node:os"; import path from "node:path"; import { promisify } from "node:util"; -import { assertRuntimeContents } from "../stage-whiteboard-runtime.mjs"; +import { assertRuntimeContents } from "../stage-review-runtime.mjs"; const exec = promisify(execFile); @@ -25,7 +25,7 @@ export const appRoot = path.resolve(import.meta.dirname, "../.."); export const workspace = path.resolve(appRoot, "../.."); -export const sourcePackage = path.join(workspace, "packages/whiteboard"); +export const sourcePackage = path.join(workspace, "packages/review"); export const bugsLogPath = path.join(import.meta.dirname, "KNOWN_BUGS.md"); @@ -37,7 +37,7 @@ export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const watchedPages = new WeakSet(); const defaultSettings = { - "whiteboard.experimental.softwareMap.enabled": true, + "review.experimental.softwareMap.enabled": true, "security.workspace.trust.enabled": false, "telemetry.telemetryLevel": "off", "workbench.startupEditor": "none", @@ -78,10 +78,10 @@ export async function createHarness({ const env = { ...process.env, HOME: home, - DEV_WHITEBOARD_HOME: home, - DEV_FAST_WHITEBOARD_CLI_NO_DELEGATE: "1", - DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED: "1", - DEV_WHITEBOARD_EXTENSIONS: extensions, + DEV_REVIEW_HOME: home, + DEV_FAST_REVIEW_CLI_NO_DELEGATE: "1", + DEV_FAST_REVIEW_TELEMETRY_DISABLED: "1", + DEV_REVIEW_EXTENSIONS: extensions, }; for (const key of [ @@ -90,7 +90,7 @@ export async function createHarness({ "CLAUDE_CODE_SESSION_ID", "CLAUDE_SESSION_ID", "PI_SESSION_ID", - "DEV_FAST_WHITEBOARD_TOOLING_ROOT", + "DEV_FAST_REVIEW_TOOLING_ROOT", "NODE_OPTIONS", ]) delete env[key]; @@ -204,7 +204,7 @@ export async function createHarness({ // New workbench windows can show the isolated profile's community invitation. await candidate.addLocatorHandler( - candidate.getByText("Join the Whiteboard community", { exact: true }), + candidate.getByText("Join the Review community", { exact: true }), async () => { await candidate .getByRole("checkbox", { name: "Don't show again" }) @@ -251,7 +251,7 @@ export async function createHarness({ await new Promise((resolve) => portServer.close(resolve)); - env.DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT = String(port); + env.DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT = String(port); function spawnDesktop() { const launchArgs = packagedApp @@ -315,7 +315,7 @@ export async function createHarness({ async function dismissCommunityDialog(candidate) { if (disableCommunityHandler) return; - const dialog = candidate.getByText("Join the Whiteboard community", { + const dialog = candidate.getByText("Join the Review community", { exact: true, }); @@ -369,18 +369,13 @@ export async function createHarness({ const response = await fetch(new URL(route, discovery.url), { method, headers: { - "x-whiteboard-token": discovery.token, + "x-review-token": discovery.token, "content-type": "application/json", }, body: body === undefined ? undefined : JSON.stringify(body), }); - const value = await response.json(); - - return { - status: response.status, - value: value, - }; + return { status: response.status, value: await response.json() }; }; /** `api` plus a 200 assertion: an error body is JSON too, so an unasserted read can stand in for a document. */ @@ -404,7 +399,7 @@ export async function createHarness({ .flatMap((context) => context.pages())) if ( (await candidate - .locator(".whiteboard-canvas-root [data-whiteboard-api]") + .locator(".review-canvas-root [data-review-api]") .count() .catch(() => 0)) > 0 && (await candidate @@ -428,7 +423,7 @@ export async function createHarness({ return { ...(await exec( process.execPath, - [path.join(runtime, "dist/whiteboard-cli.js"), ...args], + [path.join(runtime, "dist/cli.js"), ...args], { cwd, env: commandEnv, @@ -461,7 +456,7 @@ export async function createHarness({ return { ...(await exec( process.execPath, - [path.join(runtime, "dist/whiteboard-cli.js"), ...args, "--json"], + [path.join(runtime, "dist/cli.js"), ...args, "--json"], { cwd, env, timeout: 60000, maxBuffer: 8 * 1024 * 1024 }, )), code: 0, @@ -512,8 +507,7 @@ export async function createHarness({ while (app.exitCode === null && Date.now() < deadline) await sleep(100); - if (app.exitCode === null) - throw new Error(`Timed out waiting for ${label}`); + if (app.exitCode === null) throw new Error(`Timed out waiting for ${label}`); } async function restartDesktop() { @@ -591,16 +585,16 @@ export async function createHarness({ }); } -/** Creates a review on spec's commits, inserts its blocks and opens it; returns { sessionId, repositoryId, title, canvas }. */ -export async function createWhiteboard(ctx, spec) { - const repository = await ctx.api("/sessions-api/repositories", "POST", { +/** Creates a review on spec's commits, inserts its blocks and opens it; returns { reviewId, repositoryId, title, canvas }. */ +export async function createReview(ctx, spec) { + const repository = await ctx.api("/reviews-api/repositories", "POST", { path: spec.repoPath ?? ctx.repo, }); assert.equal(repository.status, 200, JSON.stringify(repository.value)); const command = async (operation) => { - const result = await ctx.api("/sessions-api/commands", "POST", { + const result = await ctx.api("/reviews-api/commands", "POST", { commandId: randomUUID(), operation, }); @@ -610,7 +604,7 @@ export async function createWhiteboard(ctx, spec) { return result.value; }; - const { sessionId } = await command({ + const { reviewId } = await command({ type: "create", title: spec.title, target: { @@ -622,28 +616,24 @@ export async function createWhiteboard(ctx, spec) { }); for (const content of spec.blocks) - await command({ - type: "edit", - sessionId, - edit: { type: "insert", content }, - }); + await command({ type: "edit", reviewId, edit: { type: "insert", content } }); - const opened = await ctx.api(`/sessions-api/${sessionId}/open`, "POST", {}); + const opened = await ctx.api(`/reviews-api/${reviewId}/open`, "POST", {}); assert.equal(opened.status, 200, JSON.stringify(opened.value)); const page = await ctx.apiCanvasFor(spec.title); return { - sessionId, + reviewId, repositoryId: repository.value.id, title: spec.title, - canvas: page.locator(".whiteboard-canvas-root [data-whiteboard-api]"), + canvas: page.locator(".review-canvas-root [data-review-api]"), }; } /** The standard two-block order review used by several journeys. */ -export const orderWhiteboardBlocks = [ +export const orderReviewBlocks = [ { type: "section", title: "Overview", @@ -691,10 +681,10 @@ export async function dismissModalEditor( return true; } -/** Opens a review the way a reader does, with `review app pick --session`. */ -export async function pickWhiteboard(ctx, sessionId, cwd = ctx.repo) { +/** Opens a review the way a reader does, with `review app pick --review`. */ +export async function pickReview(ctx, reviewId, cwd = ctx.repo) { const picked = await ctx.cliRaw( - ["app", "pick", "--session", sessionId, "--json"], + ["app", "pick", "--review", reviewId, "--json"], cwd, ); @@ -705,7 +695,7 @@ export async function pickWhiteboard(ctx, sessionId, cwd = ctx.repo) { /** Opens the Settings page on the current `ctx.page`; `Meta+,` repeats because a fresh profile reloads the workbench. */ export async function openSettings(ctx) { const settings = ctx.page.locator( - ".whiteboard-home-content.whiteboard-settings-page", + ".review-home-content.review-settings-page", ); await ctx.until( @@ -732,7 +722,7 @@ export async function installExtensionGroup( const settings = await openSettings(ctx); await settings - .locator(".whiteboard-settings-row") + .locator(".review-settings-row") .filter({ hasText: "Extensions" }) .getByRole("button", { name: "Manage" }) .click(); @@ -780,5 +770,5 @@ export async function openHome(ctx) { if (await tab.count()) await tab.click(); else await ctx.restartDesktop(); - await ctx.page.locator("main.whiteboard-home").waitFor({ timeout: 60000 }); + await ctx.page.locator("main.review-home").waitFor({ timeout: 60000 }); } diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/cli-desktop-edges.mjs b/apps/review-desktop/scripts/e2e/journeys/cli-desktop-edges.mjs similarity index 94% rename from apps/whiteboard-desktop/scripts/e2e/journeys/cli-desktop-edges.mjs rename to apps/review-desktop/scripts/e2e/journeys/cli-desktop-edges.mjs index 2cae5e912..95b8b0780 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/cli-desktop-edges.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/cli-desktop-edges.mjs @@ -6,9 +6,9 @@ import path from "node:path"; import { promisify } from "node:util"; import { - createWhiteboard, - orderWhiteboardBlocks, - pickWhiteboard, + createReview, + orderReviewBlocks, + pickReview, sleep, workspace, } from "../harness.mjs"; @@ -95,7 +95,7 @@ async function installedDesktopPids(home) { const owned = new Set(); const belongs = new RegExp( - `DEV_WHITEBOARD_HOME=${home.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)}(\\s|$)`, + `DEV_REVIEW_HOME=${home.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)}(\\s|$)`, ); for (const line of environments.split("\n")) { @@ -108,9 +108,9 @@ async function installedDesktopPids(home) { } export async function run(ctx) { - const review = await createWhiteboard(ctx, { + const review = await createReview(ctx, { title: TITLE, - blocks: orderWhiteboardBlocks, + blocks: orderReviewBlocks, }); const pointer = path.join(ctx.home, "review-desktop/server.json"); @@ -121,7 +121,7 @@ export async function run(ctx) { const probe = async (contents) => { await writeFile(pointer, contents); - return ctx.cliRaw(["info", "--session", review.sessionId]); + return ctx.cliRaw(["info", "--review", review.reviewId]); }; const output = (result) => `${result.stdout}${result.stderr}`; @@ -214,7 +214,7 @@ export async function run(ctx) { assert.equal(result.code, 0, `review info: ${output(result)}`); assert.match( result.stdout, - new RegExp(review.sessionId), + new RegExp(review.reviewId), `review info named no review: ${output(result)}`, ); ctx.check("dead pids in the pointer do not stop the CLI reaching Desktop"); @@ -240,7 +240,7 @@ export async function run(ctx) { [], "app launch started a Desktop from /Applications although one was attached", ); - await pickWhiteboard(ctx, review.sessionId); + await pickReview(ctx, review.reviewId); await review.canvas .getByRole("heading", { name: TITLE, exact: true }) .waitFor(); @@ -263,15 +263,15 @@ export async function run(ctx) { const stray = async () => [...(await installedDesktopPids(probeHome))]; const picked = await ctx.cliRaw( - ["app", "pick", "--session", review.sessionId], + ["app", "pick", "--review", review.reviewId], ctx.repo, { timeout: 25000, env: { HOME: probeHome, - DEV_WHITEBOARD_HOME: probeHome, + DEV_REVIEW_HOME: probeHome, // The journey's Desktop already holds this port, so a second one would die of the collision, not of the CLI. - DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT: "", + DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT: "", }, }, ); diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/diffr-settings.mjs b/apps/review-desktop/scripts/e2e/journeys/diffr-settings.mjs similarity index 91% rename from apps/whiteboard-desktop/scripts/e2e/journeys/diffr-settings.mjs rename to apps/review-desktop/scripts/e2e/journeys/diffr-settings.mjs index ec2a825e7..e86b61dc9 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/diffr-settings.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/diffr-settings.mjs @@ -2,15 +2,15 @@ import assert from "node:assert/strict"; import { mkdir, writeFile } from "node:fs/promises"; import path from "node:path"; -import { createWhiteboard, openSettings } from "../harness.mjs"; +import { createReview, openSettings } from "../harness.mjs"; export const name = "diffr-settings"; export const phase = 1; export const options = { - settings: { "whiteboard.experimental.structuralDiff.enabled": true }, - env: { WHITEBOARD_DIFFR_BINARY: "", GEMINI_API_KEY: "", GOOGLE_API_KEY: "" }, + settings: { "review.experimental.structuralDiff.enabled": true }, + env: { REVIEW_DIFFR_BINARY: "", GEMINI_API_KEY: "", GOOGLE_API_KEY: "" }, async beforeLaunch(ctx) { ctx.env.XDG_CONFIG_HOME = path.join(ctx.root, "config"); await mkdir(path.join(ctx.repo, "tests"), { recursive: true }); @@ -57,7 +57,7 @@ function testFolds(events) { } export async function run(ctx) { - const review = await createWhiteboard(ctx, { + const review = await createReview(ctx, { title: "diffr settings validation", blocks: [ { @@ -74,11 +74,11 @@ export async function run(ctx) { async function comparison() { const response = await fetch( new URL( - `/sessions-api/${review.sessionId}/structural-diff`, + `/reviews-api/${review.reviewId}/structural-diff`, ctx.discovery.url, ), { - headers: { "x-whiteboard-token": ctx.discovery.token }, + headers: { "x-review-token": ctx.discovery.token }, }, ); diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/first-run.mjs b/apps/review-desktop/scripts/e2e/journeys/first-run.mjs similarity index 82% rename from apps/whiteboard-desktop/scripts/e2e/journeys/first-run.mjs rename to apps/review-desktop/scripts/e2e/journeys/first-run.mjs index f6ceb2037..529ecf0b1 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/first-run.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/first-run.mjs @@ -1,7 +1,7 @@ /** A fresh profile meets the community invitation, the telemetry notice and the onboarding rail, and keeps those choices. */ import assert from "node:assert/strict"; -import { assertNoBlockedWhiteboardRequests } from "../../whiteboard-network-policy.mjs"; +import { assertNoBlockedReviewRequests } from "../../review-network-policy.mjs"; import { readApplicationStorage } from "../storage.mjs"; export const name = "first-run"; @@ -12,8 +12,8 @@ export const options = { seedRepo: false, // Restore the real first-run telemetry notice, but point capture at a closed local port. env: { - DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED: "", - PROGRESSIVE_WHITEBOARD_POSTHOG_HOST: "http://127.0.0.1:9", + DEV_FAST_REVIEW_TELEMETRY_DISABLED: "", + PROGRESSIVE_REVIEW_POSTHOG_HOST: "http://127.0.0.1:9", }, disableCommunityHandler: true, }; @@ -50,9 +50,7 @@ const storedValue = (ctx, key, timeout = 10000) => export async function run(ctx) { const { page, until, userData } = ctx; - const dialog = page.getByText("Join the Whiteboard community", { - exact: true, - }); + const dialog = page.getByText("Join the Review community", { exact: true }); const dismissDialog = async () => { await page.getByRole("checkbox", { name: "Don't show again" }).check(); @@ -81,18 +79,15 @@ export async function run(ctx) { // Exact, because the screen-reader alert repeats the text with an "Info: " prefix. const notice = page.getByText( - "Whiteboard sends anonymous usage data. You can change this in Settings.", + "Review sends anonymous usage data. You can change this in Settings.", { exact: true }, ); // Sticky, so it outlives both the seeding reload and the 10 s a plain Info toast gets. - assert.ok( - await appears(notice, 30000), - "the telemetry notice never appeared", - ); + assert.ok(await appears(notice, 30000), "the telemetry notice never appeared"); await page.getByRole("button", { name: "Open Settings" }).click(); await page - .locator(".whiteboard-settings-page") + .locator(".review-settings-page") .getByText("Share anonymous usage data") .waitFor(); ctx.check("telemetry notice opens Settings at the Privacy row"); @@ -104,7 +99,7 @@ export async function run(ctx) { await tab.click(); - const welcome = page.locator("main.whiteboard-home"); + const welcome = page.locator("main.review-home"); await welcome.getByText("Connect your agents").waitFor(); await welcome.getByText("Take the tour").waitFor(); @@ -125,20 +120,20 @@ export async function run(ctx) { ); await ctx.restartDesktop(); - await ctx.page.locator("main.whiteboard-home").waitFor({ timeout: 60000 }); + await ctx.page.locator("main.review-home").waitFor({ timeout: 60000 }); await ctx.page.waitForTimeout(3000); assert.equal( await ctx.page - .getByText("Join the Whiteboard community", { exact: true }) + .getByText("Join the Review community", { exact: true }) .count(), 0, ); assert.equal( - await ctx.page.getByText("Whiteboard sends anonymous usage data").count(), + await ctx.page.getByText("Review sends anonymous usage data").count(), 0, ); ctx.check("dismissed dialog and notice stay hidden after a restart"); - assertNoBlockedWhiteboardRequests(ctx.requestUrls); + assertNoBlockedReviewRequests(ctx.requestUrls); ctx.check("no request left for a blocked host while telemetry was live"); } diff --git a/apps/review-desktop/scripts/e2e/journeys/home-multi-review.mjs b/apps/review-desktop/scripts/e2e/journeys/home-multi-review.mjs new file mode 100644 index 000000000..9f8501adb --- /dev/null +++ b/apps/review-desktop/scripts/e2e/journeys/home-multi-review.mjs @@ -0,0 +1,196 @@ +/** Three reviews over two worktrees: Home groups, filters and opens them, and dismiss / restore / delete reach the store. */ +import assert from "node:assert/strict"; +import { writeFile } from "node:fs/promises"; +import path from "node:path"; + +import { + createReview, + openHome, + orderReviewBlocks, + pickReview, +} from "../harness.mjs"; + +export const name = "home-multi-review"; + +export const phase = 1; + +export const options = {}; + +/** Every locator this journey uses, rebuilt from the current `ctx.page` after each return to Home. */ +function homeUi(ctx) { + const home = ctx.page.locator("main.review-home"); + + return { + home, + cards: home.locator(".review-home-card"), + rows: home.locator(".review-home-list-row"), + tabs: ctx.page.locator(".tabs-container .tab"), + // One canvas part renders whichever review tab is active, so the heading says which review the reader is on. + canvas: ctx.page.locator(".review-canvas-root [data-review-api]"), + }; +} + +/** The review ids the store lists; `apiOk` keeps "the deleted review is gone" from passing on an error body. */ +async function listedReviewIds(ctx) { + return (await ctx.apiOk("/reviews-api")).map((summary) => summary.reviewId); +} + +export async function run(ctx) { + const { git, root, until } = ctx; + + const first = await createReview(ctx, { + title: "Order review", + blocks: orderReviewBlocks, + }); + + const second = await createReview(ctx, { + title: "Second review", + blocks: [ + { type: "markdown", markdown: "Second look at the same change." }, + ], + }); + + // Home groups by checkout, not by repository, so a second worktree makes two groups out of three reviews. + const other = path.join(root, "repo-b"); + + await git("worktree", "add", "-q", "-b", "feature-b", other, ctx.head); + await writeFile( + path.join(other, "order.ts"), + 'export const status = "shipped";\n', + ); + await git("-C", other, "commit", "-qam", "Ship"); + + const headB = await git("-C", other, "rev-parse", "HEAD"); + + const third = await createReview(ctx, { + title: "Worktree B review", + repoPath: other, + base: ctx.head, + head: headB, + blocks: [{ type: "markdown", markdown: "Shipped." }], + }); + + await openHome(ctx); + + let { home, cards, rows, tabs, canvas } = homeUi(ctx); + + await until( + async () => (await home.locator(".review-home-workspace").count()) === 2, + "two workspace groups", + ); + await until(async () => { + const seen = await cards.count(); + + assert.equal(seen, 3, `saw ${seen}`); + + return true; + }, "three review cards"); + ctx.check("Home groups three reviews under two worktrees"); + + await home.locator('[aria-label="Search reviews"]').fill("Worktree B"); + await until(async () => (await cards.count()) === 1, "search narrows to one card"); + + // The list view replaces the cards with `.review-home-list-row`, so the same reviews are counted as rows here. + await home.locator('[aria-label="List view"]').click(); + await until( + async () => (await home.getAttribute("data-view")) === "list", + "the list view", + ); + await until(async () => (await rows.count()) === 1, "one row under the search"); + await home.locator('[aria-label="Clear search"]').click(); + await until(async () => (await rows.count()) === 3, "clear restores three rows"); + await home.locator('[aria-label="Card view"]').click(); + await until( + async () => (await home.getAttribute("data-view")) === "cards", + "the card view", + ); + await until(async () => (await cards.count()) === 3, "clear restores three"); + ctx.check("Home search, list view and clear behave"); + + for (const title of [first.title, second.title, third.title]) + assert.equal( + await tabs.filter({ hasText: title }).count(), + 1, + `one editor tab for ${title}`, + ); + + await cards.filter({ hasText: second.title }).click(); + await canvas.getByRole("heading", { name: second.title }).waitFor(); + await pickReview(ctx, first.reviewId); + await canvas.getByRole("heading", { name: first.title }).waitFor(); + ctx.check( + "two reviews open as separate tabs and app pick switches between them", + ); + + await openHome(ctx); + ({ home, cards } = homeUi(ctx)); + + // The dismiss button is a sibling of the card button inside the shell, not a descendant of `.review-home-card`. + const shellB = home + .locator(".review-home-card-shell") + .filter({ hasText: third.title }); + + const dismissedRow = home + .locator(".review-home-dismissed-row") + .filter({ hasText: third.title }); + + // Dismissed rows sit behind a disclosure that keeps its state across re-renders, so only open it when it is shut. + const expandDismissed = async () => { + const toggle = home.locator(".review-home-dismissed-toggle"); + + await toggle.waitFor(); + + if ((await toggle.getAttribute("aria-expanded")) !== "true") + await toggle.click(); + await dismissedRow.waitFor(); + }; + + const dismiss = async () => { + await shellB.hover(); + await shellB.locator('[title="Dismiss review"]').click(); + await home.locator('section[aria-label="Dismissed reviews"]').waitFor(); + }; + + await dismiss(); + await until( + async () => (await cards.count()) === 2, + "the dismissed review leaves the cards", + ); + await expandDismissed(); + await dismissedRow.locator(".review-home-restore").click(); + await until(async () => (await cards.count()) === 3, "restored"); + + // Delete is offered only in a dismissed review's row, so the permanent action always follows the reversible one. + await dismiss(); + await expandDismissed(); + assert.ok( + (await listedReviewIds(ctx)).includes(third.reviewId), + `${third.reviewId} is not listed before the delete`, + ); + await dismissedRow.locator('[title="Delete review"]').click(); + await dismissedRow.locator('[title="Click again to delete"]').click(); + await until( + async () => (await dismissedRow.count()) === 0, + "the deleted review leaves Home", + ); + await until(async () => { + const seen = await cards.count(); + + assert.equal(seen, 2, `saw ${seen}`); + + return true; + }, "two review cards after the delete"); + + const remaining = await listedReviewIds(ctx); + + assert.ok( + !remaining.includes(third.reviewId), + `${third.reviewId} is still listed after deletion`, + ); + assert.deepEqual( + [first.reviewId, second.reviewId].filter((id) => !remaining.includes(id)), + [], + "deleting one review must not unlist the others", + ); + ctx.check("dismiss, restore and two-click delete update Home and the store"); +} diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/json-api-edit.mjs b/apps/review-desktop/scripts/e2e/journeys/json-api-edit.mjs similarity index 76% rename from apps/whiteboard-desktop/scripts/e2e/journeys/json-api-edit.mjs rename to apps/review-desktop/scripts/e2e/journeys/json-api-edit.mjs index 127ca1978..ab9f2cb72 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/json-api-edit.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/json-api-edit.mjs @@ -2,9 +2,9 @@ import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; -import { createWhiteboard, orderWhiteboardBlocks } from "../harness.mjs"; +import { createReview, orderReviewBlocks } from "../harness.mjs"; import { - openLegacyWhiteboard, + openLegacyReview, seedLegacyFixtures, waitForImport, } from "../legacy-fixtures.mjs"; @@ -18,7 +18,7 @@ export const options = { beforeLaunch: seedLegacyFixtures }; export async function run(ctx) { const { api, apiOk, apiCanvasFor, legacyFixtures } = ctx; - // createWhiteboard has not run yet, so an imported fixture is the only open canvas available. + // createReview has not run yet, so an imported fixture is the only open canvas available. const fixture = legacyFixtures.find( (candidate) => candidate.metadata.sourceRepository === "devdotfast/review", ); @@ -28,23 +28,23 @@ export async function run(ctx) { const { metadata } = fixture; await waitForImport(ctx, metadata.sourceUuid); - await openLegacyWhiteboard(ctx, fixture); + await openLegacyReview(ctx, fixture); const snapshot = await waitForImport(ctx, metadata.sourceUuid); const page = await apiCanvasFor(snapshot.title); await ctx.watchPage(page); - const canvas = page.locator(".whiteboard-canvas-root"); + const canvas = page.locator(".review-canvas-root"); - const before = await apiOk(`/sessions-api/${metadata.sourceUuid}?full=true`); + const before = await apiOk(`/reviews-api/${metadata.sourceUuid}?full=true`); const edit = (content) => - api("/sessions-api/commands", "POST", { + api("/reviews-api/commands", "POST", { commandId: randomUUID(), operation: { type: "edit", - sessionId: metadata.sourceUuid, + reviewId: metadata.sourceUuid, edit: { type: "insert", content }, }, }); @@ -87,13 +87,9 @@ export async function run(ctx) { assert.match(rejected.value.error, new RegExp(message)); } - const after = await apiOk(`/sessions-api/${metadata.sourceUuid}?full=true`); + const after = await apiOk(`/reviews-api/${metadata.sourceUuid}?full=true`); - assert.deepEqual( - after, - before, - "rejected edits must not change the document", - ); + assert.deepEqual(after, before, "rejected edits must not change the document"); const accepted = await edit({ type: "callout", @@ -115,18 +111,15 @@ export async function run(ctx) { ); // The same API path the later journeys use to author their own reviews. - const created = await createWhiteboard(ctx, { + const created = await createReview(ctx, { title: "Order status e2e", - blocks: orderWhiteboardBlocks, + blocks: orderReviewBlocks, }); await created.canvas .getByRole("heading", { name: "Overview", exact: true }) .waitFor(); - await created.canvas - .getByText("moves from draft to queued") - .first() - .waitFor(); + await created.canvas.getByText("moves from draft to queued").first().waitFor(); assert.doesNotMatch(await created.canvas.innerText(), /Layout failed:/); - ctx.check("createWhiteboard helper opens an API review"); + ctx.check("createReview helper opens an API review"); } diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/legacy-import.mjs b/apps/review-desktop/scripts/e2e/journeys/legacy-import.mjs similarity index 89% rename from apps/whiteboard-desktop/scripts/e2e/journeys/legacy-import.mjs rename to apps/review-desktop/scripts/e2e/journeys/legacy-import.mjs index 29c97a01f..c6dd14551 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/legacy-import.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/legacy-import.mjs @@ -7,7 +7,7 @@ import { promisify } from "node:util"; import { legacyRoot, - openLegacyWhiteboard, + openLegacyReview, seedLegacyFixtures, waitForImport, } from "../legacy-fixtures.mjs"; @@ -29,7 +29,7 @@ export async function run(ctx) { const first = legacyFixtures[0]; const info = await ctx.cliRaw( - ["info", "--session", first.metadata.sourceUuid, "--json"], + ["info", "--review", first.metadata.sourceUuid, "--json"], first.worktreePath, ); @@ -82,7 +82,7 @@ export async function run(ctx) { "git", [ "show", - `${migrated.presentedDocumentRevision}:.bundle/document/whiteboard-document.json`, + `${migrated.presentedDocumentRevision}:.bundle/document/review-document.json`, ], { cwd: legacyDir, maxBuffer: 8 * 1024 * 1024 }, ); @@ -102,9 +102,9 @@ export async function run(ctx) { ); if (metadata.sourceRepository !== "devdotfast/review") { - await apiOk("/sessions-api"); + await apiOk("/reviews-api"); assert.equal( - (await api(`/sessions-api/${metadata.sourceUuid}`)).status, + (await api(`/reviews-api/${metadata.sourceUuid}`)).status, 404, `${fixtureName} without its repository stays legacy`, ); @@ -116,7 +116,7 @@ export async function run(ctx) { } await waitForImport(ctx, metadata.sourceUuid); - await openLegacyWhiteboard(ctx, fixture); + await openLegacyReview(ctx, fixture); const snapshot = await waitForImport(ctx, metadata.sourceUuid); const document = snapshot.document; @@ -136,7 +136,7 @@ export async function run(ctx) { `${fixtureName} carries origin`, ); - const history = await apiOk(`/sessions-api/${metadata.sourceUuid}/history`); + const history = await apiOk(`/reviews-api/${metadata.sourceUuid}/history`); assert.equal( history.length, @@ -148,15 +148,15 @@ export async function run(ctx) { `${fixtureName}: ${snapshot.version + 1} versions from ${revisions} revisions`, ); assert.ok( - (await apiOk("/sessions-api")).some( - (row) => row.sessionId === metadata.sourceUuid, + (await apiOk("/reviews-api")).some( + (row) => row.reviewId === metadata.sourceUuid, ), `${fixtureName} is listed by the review API`, ); page = await apiCanvasFor(golden.title); await ctx.watchPage(page); - const canvas = page.locator(".whiteboard-canvas-root"); + const canvas = page.locator(".review-canvas-root"); if (metadata.hasMap) { // The imported map section starts collapsed. @@ -172,6 +172,6 @@ export async function run(ctx) { console.log("E2E legacy fixture passed", fixtureName); } - await page.locator(".whiteboard-canvas-root").click({ trial: true }); + await page.locator(".review-canvas-root").click({ trial: true }); await page.screenshot({ path: path.join(root, "document.png") }); } diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/lsp-go.mjs b/apps/review-desktop/scripts/e2e/journeys/lsp-go.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/journeys/lsp-go.mjs rename to apps/review-desktop/scripts/e2e/journeys/lsp-go.mjs diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/lsp-python.mjs b/apps/review-desktop/scripts/e2e/journeys/lsp-python.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/journeys/lsp-python.mjs rename to apps/review-desktop/scripts/e2e/journeys/lsp-python.mjs diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/lsp-rust.mjs b/apps/review-desktop/scripts/e2e/journeys/lsp-rust.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/journeys/lsp-rust.mjs rename to apps/review-desktop/scripts/e2e/journeys/lsp-rust.mjs diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/lsp-typescript.mjs b/apps/review-desktop/scripts/e2e/journeys/lsp-typescript.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/journeys/lsp-typescript.mjs rename to apps/review-desktop/scripts/e2e/journeys/lsp-typescript.mjs diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/reader-navigation.mjs b/apps/review-desktop/scripts/e2e/journeys/reader-navigation.mjs similarity index 82% rename from apps/whiteboard-desktop/scripts/e2e/journeys/reader-navigation.mjs rename to apps/review-desktop/scripts/e2e/journeys/reader-navigation.mjs index cbdbe087b..ad28bd161 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/reader-navigation.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/reader-navigation.mjs @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; -import { createWhiteboard, orderWhiteboardBlocks } from "../harness.mjs"; +import { createReview, orderReviewBlocks } from "../harness.mjs"; export const name = "reader-navigation"; @@ -34,10 +34,10 @@ export async function run(ctx) { const { until } = ctx; // The contents need more than two headings and an entry below the fold, so two long sections are added. - const review = await createWhiteboard(ctx, { + const review = await createReview(ctx, { title: TITLE, blocks: [ - ...orderWhiteboardBlocks, + ...orderReviewBlocks, longSection("Rollout"), longSection("Risks"), ], @@ -48,9 +48,9 @@ export async function run(ctx) { await ctx.watchPage(page); - const canvas = page.locator(".whiteboard-canvas-root [data-whiteboard-api]"); + const canvas = page.locator(".review-canvas-root [data-review-api]"); - const views = page.locator('[aria-label="Session views"]'); + const views = page.locator('[aria-label="Review views"]'); const viewLabels = () => views @@ -60,7 +60,7 @@ export async function run(ctx) { ); const traces = await ctx.apiOk( - `/sessions-api/${review.sessionId}/agent-traces`, + `/reviews-api/${review.reviewId}/agent-traces`, ); assert.ok( @@ -70,7 +70,7 @@ export async function run(ctx) { // A two-commit range offers Commits and Diff, Map needs a software map this review has none of, Trace needs traces. const offered = [ - "Session", + "Review", "Commits", "Diff", ...(traces.sessions.length > 0 ? ["Trace"] : []), @@ -82,7 +82,7 @@ export async function run(ctx) { ); // Review goes last so the reader ends on the document the rest of the journey reads. - for (const label of [...offered.slice(1), "Session"]) { + for (const label of [...offered.slice(1), "Review"]) { const button = views.locator(`button[aria-label="${label}"]`); await button.click(); @@ -94,12 +94,12 @@ export async function run(ctx) { ctx.check("all offered review views activate"); - const find = page.locator('[role="search"][aria-label="Find in session"]'); + const find = page.locator('[role="search"][aria-label="Find in Review"]'); const input = find.locator('[aria-label="Find"]'); const countText = async () => - (await find.locator(".whiteboard-find-count").innerText()).trim(); + (await find.locator(".review-find-count").innerText()).trim(); await page.keyboard.press("Meta+F"); await find.waitFor(); @@ -111,7 +111,7 @@ export async function run(ctx) { return /^\d+ of \d+$/.test(text) ? text : null; }, "a plain-text match count"); - const wholeWord = find.locator(".whiteboard-find-toggle--whole-word"); + const wholeWord = find.locator(".review-find-toggle--whole-word"); await wholeWord.click(); await until( @@ -128,7 +128,7 @@ export async function run(ctx) { `the plain count (${plain}) to come back`, ); - await find.locator(".whiteboard-find-toggle--regex").click(); + await find.locator(".review-find-toggle--regex").click(); await input.fill("stat("); // An uncompilable pattern reads "Invalid expression" in the count and marks the input. await until( @@ -168,26 +168,24 @@ export async function run(ctx) { await input.press("Escape"); await find.waitFor({ state: "hidden" }); - ctx.check( - "find handles plain, whole-word, regex and invalid regex, and wraps", - ); + ctx.check("find handles plain, whole-word, regex and invalid regex, and wraps"); - const toc = page.locator("nav#whiteboard-toc"); + const toc = page.locator("nav#review-toc"); await toc.waitFor(); const isDrawerOpen = async () => - (await toc.getAttribute("class")).includes("whiteboard-toc--open"); + (await toc.getAttribute("class")).includes("review-toc--open"); // The contents are an open rail only at the top of a wide shell; otherwise a shut drawer is `pointer-events: none`. - if (!(await isDrawerOpen())) await page.locator(".whiteboard-toc-toggle").click(); + if (!(await isDrawerOpen())) await page.locator(".review-toc-toggle").click(); await until(isDrawerOpen, "the contents drawer to open"); // Entries are buttons, not links with an `href`, so the target is found by its heading text. - const links = toc.locator(".whiteboard-toc-link"); + const links = toc.locator(".review-toc-link"); assert.deepEqual( - (await links.locator(".whiteboard-toc-text").allInnerTexts()).map((text) => + (await links.locator(".review-toc-text").allInnerTexts()).map((text) => text.trim(), ), ["Overview", "Rollout", "Risks"], @@ -196,7 +194,7 @@ export async function run(ctx) { const target = canvas.getByRole("heading", { name: "Risks", exact: true }); - const region = page.locator(".whiteboard-view-region--review"); + const region = page.locator(".review-view-region--review"); /** How far the target heading sits below the top of the scrolling region. */ const offset = async () => { @@ -223,13 +221,13 @@ export async function run(ctx) { }, "Risks to scroll to the top of the review"); ctx.check("table of contents navigates"); - const history = () => ctx.apiOk(`/sessions-api/${review.sessionId}/history`); + const history = () => ctx.apiOk(`/reviews-api/${review.reviewId}/history`); const before = await history(); - const renamed = await ctx.api("/sessions-api/commands", "POST", { + const renamed = await ctx.api("/reviews-api/commands", "POST", { commandId: randomUUID(), - operation: { type: "rename", sessionId: review.sessionId, title: RENAMED }, + operation: { type: "rename", reviewId: review.reviewId, title: RENAMED }, }); assert.equal(renamed.status, 200, JSON.stringify(renamed.value)); @@ -272,15 +270,13 @@ export async function run(ctx) { ); await previous.click(); - const banner = page.locator('.whiteboard-history-banner[role="status"]'); + const banner = page.locator('.review-history-banner[role="status"]'); await banner .getByText("You are viewing an older version of this review.") .waitFor(); await canvas.getByRole("heading", { name: TITLE, exact: true }).waitFor(); - await canvas - .getByRole("heading", { name: "Overview", exact: true }) - .waitFor(); + await canvas.getByRole("heading", { name: "Overview", exact: true }).waitFor(); await banner.getByRole("button", { name: "Back to latest" }).click(); await banner.waitFor({ state: "hidden" }); await canvas.getByRole("heading", { name: RENAMED, exact: true }).waitFor(); diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/settings-and-migration.mjs b/apps/review-desktop/scripts/e2e/journeys/settings-and-migration.mjs similarity index 89% rename from apps/whiteboard-desktop/scripts/e2e/journeys/settings-and-migration.mjs rename to apps/review-desktop/scripts/e2e/journeys/settings-and-migration.mjs index eaeff05aa..2a2b1854b 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/settings-and-migration.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/settings-and-migration.mjs @@ -25,25 +25,25 @@ const LEGACY_RECORD = { schemaVersion: 1, uuid: LEGACY_UUID }; const THEME_SETTINGS = { dark: { "window.autoDetectColorScheme": false, - "workbench.colorTheme": "Whiteboard Dark", + "workbench.colorTheme": "Review Dark", }, light: { "window.autoDetectColorScheme": false, - "workbench.colorTheme": "Whiteboard Light", + "workbench.colorTheme": "Review Light", }, }; /** The telemetry checkbox, reached through its row: the row label is a ``, so `getByLabel` matches nothing. */ const telemetryToggle = (settings) => settings - .locator(".whiteboard-settings-row") + .locator(".review-settings-row") .filter({ hasText: "Share anonymous usage data" }) .locator('input[type="checkbox"]'); const themeSelect = (settings) => settings.getByLabel("Theme"); /** Writes the unreadable record into `/reviews//review.json`. */ -async function seedLegacyWhiteboard(home) { +async function seedLegacyReview(home) { const dir = path.join(home, "reviews", LEGACY_UUID); await mkdir(dir, { recursive: true }); @@ -63,9 +63,9 @@ async function runDesktopHost(ctx, home) { const env = { ...ctx.env, HOME: home, - DEV_WHITEBOARD_HOME: home, - DEV_FAST_WHITEBOARD_SERVER_PORT: "0", - DEV_FAST_WHITEBOARD_APP_PID: String(process.pid), + DEV_REVIEW_HOME: home, + DEV_FAST_REVIEW_SERVER_PORT: "0", + DEV_FAST_REVIEW_APP_PID: String(process.pid), }; try { @@ -107,8 +107,8 @@ export async function run(ctx) { ); // The preference is the whole effect under test; the harness runs with telemetry disabled whichever way it sits. await until( - () => readUserSettings(userData)["whiteboard.telemetry.enabled"] === !before, - `whiteboard.telemetry.enabled to be ${!before} in the workbench settings`, + () => readUserSettings(userData)["review.telemetry.enabled"] === !before, + `review.telemetry.enabled to be ${!before} in the workbench settings`, ); const theme = @@ -147,9 +147,9 @@ export async function run(ctx) { ); assert.equal( - restored["whiteboard.telemetry.enabled"], + restored["review.telemetry.enabled"], !before, - "whiteboard.telemetry.enabled did not survive the restart", + "review.telemetry.enabled did not survive the restart", ); assert.deepEqual( Object.fromEntries( @@ -163,21 +163,21 @@ export async function run(ctx) { ); // Nothing in the Desktop reads a legacy record once the cutover marker is set, so Home's text is asserted only if it does. - const legacyDir = await seedLegacyWhiteboard(ctx.home); + const legacyDir = await seedLegacyReview(ctx.home); await ctx.restartDesktop(); await openHome(ctx); - const home = ctx.page.locator("main.whiteboard-home"); + const home = ctx.page.locator("main.review-home"); // The onboarding rail is what an empty Home renders, so waiting for it makes the absences below mean "finished", not "slow". await home.getByText("Create your first review").waitFor({ timeout: 60000 }); - const summaries = await ctx.api("/sessions-api"); + const summaries = await ctx.api("/reviews-api"); assert.equal(summaries.status, 200, JSON.stringify(summaries.value)); assert.deepEqual( - summaries.value.filter((summary) => summary.sessionId === LEGACY_UUID), + summaries.value.filter((summary) => summary.reviewId === LEGACY_UUID), [], "the store listed a review it cannot read", ); @@ -213,7 +213,7 @@ export async function run(ctx) { // The reader's real upgrade path is a home whose cutover has not run, so the probe gets one of its own. const upgradeHome = path.join(ctx.root, "upgrade-home"); - await seedLegacyWhiteboard(upgradeHome); + await seedLegacyReview(upgradeHome); const host = await runDesktopHost(ctx, upgradeHome); diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/tutorial.mjs b/apps/review-desktop/scripts/e2e/journeys/tutorial.mjs similarity index 84% rename from apps/whiteboard-desktop/scripts/e2e/journeys/tutorial.mjs rename to apps/review-desktop/scripts/e2e/journeys/tutorial.mjs index 9c34350f8..a4ce33698 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/tutorial.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/tutorial.mjs @@ -11,7 +11,7 @@ export const phase = 1; export const options = { seedRepo: false }; -const TITLE = "Whiteboard: three-minute tour"; +const TITLE = "Review Desktop: three-minute tour"; const PROGRESS_KEY = "review.tutorial.progress.v1"; @@ -51,9 +51,9 @@ export async function run(ctx) { await ctx.page.keyboard.press("F1"); await ctx.page .locator(".quick-input-widget input") - .fill(">Whiteboard: Open Tutorial"); + .fill(">Review: Open Tutorial"); await ctx.page - .getByRole("option", { name: /Whiteboard: Open Tutorial/ }) + .getByRole("option", { name: /Review: Open Tutorial/ }) .click(); const page = await apiCanvasFor(TITLE); @@ -76,14 +76,14 @@ export async function run(ctx) { "native JSON tutorial renders with its guide and working keybinding picker", ); - const canvas = page.locator(".whiteboard-canvas-root [data-whiteboard-api]"); + const canvas = page.locator(".review-canvas-root [data-review-api]"); const guide = page.locator( 'aside.tutorial-guide[aria-label="Tutorial guide"]', ); const viewTab = (label) => - page.locator(`[aria-label="Session views"] button[aria-label="${label}"]`); + page.locator(`[aria-label="Review views"] button[aria-label="${label}"]`); await guide.waitFor(); @@ -91,7 +91,7 @@ export async function run(ctx) { await waitChecked(ctx, "chooseKeymap"); const editor = canvas - .locator('[data-whiteboard-section="Welcome"] .whiteboard-inline-editor') + .locator('[data-review-section="Welcome"] .review-inline-editor') .first(); await editor.locator(".view-line").first().waitFor(); @@ -143,21 +143,21 @@ export async function run(ctx) { await guide.waitFor(); await canvas - .locator('[data-whiteboard-section="Welcome"] a[data-whiteboard-anchor-id]') + .locator('[data-review-section="Welcome"] a[data-review-anchor-id]') .first() .click(); await waitChecked(ctx, "openPeek"); await viewTab("Commits").click(); await waitChecked(ctx, "openCommits"); - await page.locator(".whiteboard-commit-open").first().click(); + await page.locator(".review-commit-open").first().click(); await waitChecked(ctx, "openDiff"); - await viewTab("Session").click(); + await viewTab("Review").click(); // The two `external` steps complete when the tour overlay mounts, not when the reader steps through it. await canvas .locator( - '[data-whiteboard-section="Interactive Diagrams"] .sequence-diagram .diagram-tour-button', + '[data-review-section="Interactive Diagrams"] .sequence-diagram .diagram-tour-button', ) .first() .click(); @@ -167,11 +167,11 @@ export async function run(ctx) { await viewTab("Map (Experimental)").click(); await waitChecked(ctx, "openMap"); - await viewTab("Session").click(); + await viewTab("Review").click(); await canvas .locator( - '[data-whiteboard-section="Interactive Diagrams"] .database-lens .diagram-tour-button', + '[data-review-section="Interactive Diagrams"] .database-lens .diagram-tour-button', ) .first() .click(); @@ -180,7 +180,7 @@ export async function run(ctx) { await page.keyboard.press("Escape"); await canvas - .locator('[data-whiteboard-section="Agent traces"] .whiteboard-trace-quote') + .locator('[data-review-section="Agent traces"] .review-trace-quote') .first() .click(); await waitChecked(ctx, "openTraceQuote"); @@ -195,7 +195,7 @@ export async function run(ctx) { await openHome(ctx); - const home = ctx.page.locator("main.whiteboard-home"); + const home = ctx.page.locator("main.review-home"); await home.getByText(`${STEPS.length} of ${STEPS.length} checks`).waitFor(); @@ -210,8 +210,8 @@ export async function run(ctx) { await ctx.api("/tutorial", "DELETE"); - assert.equal((await status()).sessionId, null); + assert.equal((await status()).reviewUuid, null); await ctx.api("/tutorial/prepare", "POST", {}); - await until(async () => (await status()).sessionId, "tutorial re-prepared"); + await until(async () => (await status()).reviewUuid, "tutorial re-prepared"); ctx.check("DELETE /tutorial then prepare restores the hidden review"); } diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/worktree-drift.mjs b/apps/review-desktop/scripts/e2e/journeys/worktree-drift.mjs similarity index 87% rename from apps/whiteboard-desktop/scripts/e2e/journeys/worktree-drift.mjs rename to apps/review-desktop/scripts/e2e/journeys/worktree-drift.mjs index aa809554b..f51dda064 100644 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/worktree-drift.mjs +++ b/apps/review-desktop/scripts/e2e/journeys/worktree-drift.mjs @@ -5,10 +5,10 @@ import { rename, rm, writeFile } from "node:fs/promises"; import path from "node:path"; import { - createWhiteboard, + createReview, openHome, - orderWhiteboardBlocks, - pickWhiteboard, + orderReviewBlocks, + pickReview, } from "../harness.mjs"; export const name = "worktree-drift"; @@ -24,7 +24,7 @@ const RETAINED_SOURCE = "Local checkout unavailable. Showing retained source."; /** Every locator this journey uses, rebuilt from the current `ctx.page` because each restart replaces it. */ function canvasUi(ctx) { - const canvas = ctx.page.locator(".whiteboard-canvas-root [data-whiteboard-api]"); + const canvas = ctx.page.locator(".review-canvas-root [data-review-api]"); return { heading: canvas.getByRole("heading", { name: TITLE, exact: true }), @@ -32,7 +32,7 @@ function canvasUi(ctx) { unavailable: ctx.page.getByText("Worktree unavailable"), retained: canvas.getByText(RETAINED_SOURCE), peek: canvas - .locator('.whiteboard-inline-editor[data-whiteboard-inline-editor="order.ts"]') + .locator('.review-inline-editor[data-review-inline-editor="order.ts"]') .first(), }; } @@ -46,9 +46,9 @@ export async function run(ctx) { 'export const status = "dirty";\n', ); - const review = await createWhiteboard(ctx, { + const review = await createReview(ctx, { title: TITLE, - blocks: orderWhiteboardBlocks, + blocks: orderReviewBlocks, }); const peekText = async () => @@ -76,7 +76,7 @@ export async function run(ctx) { root, path.relative(repo, commonDir), "dev-fast/reviews", - review.sessionId, + review.reviewId, "head", ctx.head, ); @@ -88,7 +88,7 @@ export async function run(ctx) { // The control for everything below: the same restart and open, with the repository still where it was registered. await ctx.restartDesktop(); - await pickWhiteboard(ctx, review.sessionId); + await pickReview(ctx, review.reviewId); const control = await canvasUi(ctx) .heading.waitFor({ timeout: 60000 }) @@ -112,7 +112,7 @@ export async function run(ctx) { `the rename did not carry the pinned checkout to ${pinnedIn(moved)}`, ); await ctx.restartDesktop(); - await pickWhiteboard(ctx, review.sessionId, moved); + await pickReview(ctx, review.reviewId, moved); const { heading, unavailable } = canvasUi(ctx); @@ -131,14 +131,14 @@ export async function run(ctx) { ); const info = await ctx.cliRaw( - ["info", "--session", review.sessionId, "--json"], + ["info", "--review", review.reviewId, "--json"], moved, ); assert.equal(info.code, 0, `review info: ${info.stdout}\n${info.stderr}`); assert.match( info.stdout, - new RegExp(review.sessionId), + new RegExp(review.reviewId), `review info named no review: ${info.stdout}`, ); ctx.check("info resolves a review whose worktree moved"); @@ -151,7 +151,7 @@ export async function run(ctx) { await ctx.restartDesktop(); await openHome(ctx); await ctx.page - .locator("main.whiteboard-home .whiteboard-home-card") + .locator("main.review-home .review-home-card") .filter({ hasText: TITLE }) .click(); @@ -166,11 +166,11 @@ export async function run(ctx) { // Nothing is left to read from, so the retained document has to say so rather than pass for a current one. await deleted.retained.waitFor(); - const views = ctx.page.locator('[aria-label="Session views"]'); + const views = ctx.page.locator('[aria-label="Review views"]'); await views.locator('button[aria-label="Commits"]').click(); - const commits = ctx.page.locator(".whiteboard-view-region--commits"); + const commits = ctx.page.locator(".review-view-region--commits"); await commits .getByRole("heading", { name: "Commits unavailable", exact: true }) diff --git a/apps/whiteboard-desktop/scripts/e2e/legacy-fixtures.mjs b/apps/review-desktop/scripts/e2e/legacy-fixtures.mjs similarity index 85% rename from apps/whiteboard-desktop/scripts/e2e/legacy-fixtures.mjs rename to apps/review-desktop/scripts/e2e/legacy-fixtures.mjs index 82a4d110b..56194d2a9 100644 --- a/apps/whiteboard-desktop/scripts/e2e/legacy-fixtures.mjs +++ b/apps/review-desktop/scripts/e2e/legacy-fixtures.mjs @@ -4,7 +4,7 @@ import { mkdir, readFile, readdir, writeFile } from "node:fs/promises"; import path from "node:path"; import { promisify } from "node:util"; -import { pickWhiteboard, sourcePackage, workspace } from "./harness.mjs"; +import { pickReview, sourcePackage, workspace } from "./harness.mjs"; const exec = promisify(execFile); @@ -85,14 +85,14 @@ export async function seedLegacyFixtures(ctx) { } /** Opens an imported fixture through the shared `review app pick` helper. */ -export const openLegacyWhiteboard = (ctx, fixture) => - pickWhiteboard(ctx, fixture.metadata.sourceUuid, fixture.worktreePath); +export const openLegacyReview = (ctx, fixture) => + pickReview(ctx, fixture.metadata.sourceUuid, fixture.worktreePath); /** Startup migrates the legacy directory before exposing the JSON catalog. */ -export const waitForImport = (ctx, sessionId) => +export const waitForImport = (ctx, reviewId) => ctx.until(async () => { - await ctx.api("/sessions-api"); - const snapshot = await ctx.api(`/sessions-api/${sessionId}?full=true`); + await ctx.api("/reviews-api"); + const snapshot = await ctx.api(`/reviews-api/${reviewId}?full=true`); return snapshot.status === 200 ? snapshot.value : null; - }, `${sessionId} imported`); + }, `${reviewId} imported`); diff --git a/apps/whiteboard-desktop/scripts/e2e/lsp-languages.mjs b/apps/review-desktop/scripts/e2e/lsp-languages.mjs similarity index 92% rename from apps/whiteboard-desktop/scripts/e2e/lsp-languages.mjs rename to apps/review-desktop/scripts/e2e/lsp-languages.mjs index 7bb6d8c53..edb1d9009 100644 --- a/apps/whiteboard-desktop/scripts/e2e/lsp-languages.mjs +++ b/apps/review-desktop/scripts/e2e/lsp-languages.mjs @@ -16,7 +16,7 @@ import path from "node:path"; import { promisify } from "node:util"; import { - createWhiteboard, + createReview, dismissModalEditor, installExtensionGroup, } from "./harness.mjs"; @@ -76,7 +76,7 @@ export const LANGUAGES = { hoverText: /save_order\(order: OrderRecord\)/, }, go: { - // Not a DEV_WHITEBOARD_EXTENSIONS group: the Go extension installs gopls on activation, so it is downloaded only after consent. + // Not a DEV_REVIEW_EXTENSIONS group: the Go extension installs gopls on activation, so it is downloaded only after consent. extensions: "none", peekFile: "orders.go", symbol: "SaveOrder", @@ -104,7 +104,7 @@ export const LANGUAGES = { }, }, rust: { - // Not a DEV_WHITEBOARD_EXTENSIONS group: rust-analyzer is tier "optional", downloaded only after consent in the picker. + // Not a DEV_REVIEW_EXTENSIONS group: rust-analyzer is tier "optional", downloaded only after consent in the picker. extensions: "none", peekFile: "src/lib.rs", symbol: "save_order", @@ -213,18 +213,14 @@ async function serverNeverStarted( } /** The same review, in the window a restart left behind. */ -async function reopenWhiteboard(ctx, review) { - const opened = await ctx.api( - `/sessions-api/${review.sessionId}/open`, - "POST", - {}, - ); +async function reopenReview(ctx, review) { + const opened = await ctx.api(`/reviews-api/${review.reviewId}/open`, "POST", {}); assert.equal(opened.status, 200, JSON.stringify(opened.value)); const page = await ctx.apiCanvasFor(review.title); - return page.locator(".whiteboard-canvas-root [data-whiteboard-api]"); + return page.locator(".review-canvas-root [data-review-api]"); } /** `go install` writes to GOPATH/bin, and GOPATH defaults to $HOME/go inside the temp root. */ @@ -233,10 +229,7 @@ const goToolPath = (ctx, tool) => path.join(ctx.home, "go/bin", tool); /** Nothing the Go extension downloads may exist before the reader consents to its group. */ async function assertNothingInstalledYet(ctx, tool) { assert.equal( - await access(goToolPath(ctx, tool)).then( - () => true, - () => false, - ), + await access(goToolPath(ctx, tool)).then(() => true, () => false), false, `${tool} was installed before the Go group was consented to`, ); @@ -254,11 +247,7 @@ async function assertNothingInstalledYet(ctx, tool) { /** Waits for the consented-to Go extension to provision `tool` into the journey's GOPATH. */ async function provisionLanguageServer(ctx, tool) { await ctx.until( - () => - access(goToolPath(ctx, tool)).then( - () => true, - () => false, - ), + () => access(goToolPath(ctx, tool)).then(() => true, () => false), `${tool} to be installed into the journey's GOPATH`, 300000, ); @@ -272,9 +261,9 @@ export async function runLspJourney(ctx, id) { // Covers an explicit `--journey lsp-go` on a machine that never opted into the network. if ( (language.needsToolchain || language.optionalExtension) && - process.env.WHITEBOARD_E2E_NETWORK !== "1" + process.env.REVIEW_E2E_NETWORK !== "1" ) - throw new Error(`skip: ${id} needs WHITEBOARD_E2E_NETWORK=1`); + throw new Error(`skip: ${id} needs REVIEW_E2E_NETWORK=1`); if (language.needsToolchain) await requireToolchain(ctx, language.needsToolchain); @@ -310,7 +299,7 @@ export async function runLspJourney(ctx, id) { `${language.peekFile} does not call ${language.symbol}`, ); - const review = await createWhiteboard(ctx, { + const review = await createReview(ctx, { title: `${id} peek`, head, blocks: [ @@ -346,7 +335,7 @@ export async function runLspJourney(ctx, id) { "A review's Rust language server never starts when the extension wins a race with the workspace folder", ); await ctx.restartDesktop(); - canvas = await reopenWhiteboard(ctx, review); + canvas = await reopenReview(ctx, review); } } } @@ -357,7 +346,7 @@ async function hoverAndJump(ctx, id, language, canvas, lines, callLine) { const editor = canvas .locator( - `.whiteboard-inline-editor[data-whiteboard-inline-editor="${language.peekFile}"]`, + `.review-inline-editor[data-review-inline-editor="${language.peekFile}"]`, ) .first(); @@ -431,8 +420,7 @@ async function hoverAndJump(ctx, id, language, canvas, lines, callLine) { const definitionName = path.basename(language.definitionFile); await ctx.until( - async () => - (await modalTitle.innerText().catch(() => "")).includes(definitionName), + async () => (await modalTitle.innerText().catch(() => "")).includes(definitionName), `${id} Go to Definition to open ${language.definitionFile} in the modal editor`, 60000, ); diff --git a/apps/whiteboard-desktop/scripts/e2e/run.mjs b/apps/review-desktop/scripts/e2e/run.mjs similarity index 97% rename from apps/whiteboard-desktop/scripts/e2e/run.mjs rename to apps/review-desktop/scripts/e2e/run.mjs index 44fa2af61..986d77e1e 100644 --- a/apps/whiteboard-desktop/scripts/e2e/run.mjs +++ b/apps/review-desktop/scripts/e2e/run.mjs @@ -38,7 +38,7 @@ const selected = values.journey return found; }) : journeys.filter( - (j) => j.phase === 1 || process.env.WHITEBOARD_E2E_NETWORK === "1", + (j) => j.phase === 1 || process.env.REVIEW_E2E_NETWORK === "1", ); if (!values.runtime) diff --git a/apps/whiteboard-desktop/scripts/e2e/storage.mjs b/apps/review-desktop/scripts/e2e/storage.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/e2e/storage.mjs rename to apps/review-desktop/scripts/e2e/storage.mjs diff --git a/apps/whiteboard-desktop/scripts/editor-actions-contract.test.mjs b/apps/review-desktop/scripts/editor-actions-contract.test.mjs similarity index 81% rename from apps/whiteboard-desktop/scripts/editor-actions-contract.test.mjs rename to apps/review-desktop/scripts/editor-actions-contract.test.mjs index 8ff7dec9e..4abda10fa 100644 --- a/apps/whiteboard-desktop/scripts/editor-actions-contract.test.mjs +++ b/apps/review-desktop/scripts/editor-actions-contract.test.mjs @@ -7,7 +7,7 @@ const read = (relative) => const contextKeys = read("../code-oss/src/vs/workbench/common/contextkeys.ts"); -const whiteboardWorkbench = read("../code-oss/src/vs/whiteboard/browser/workbench.ts"); +const reviewWorkbench = read("../code-oss/src/vs/review/browser/workbench.ts"); const editorContribution = read( "../code-oss/src/vs/workbench/browser/parts/editor/editor.contribution.ts", @@ -20,11 +20,11 @@ const editorTabsControl = read( test("Review marks its window so shared chrome can opt out", () => { assert.match( contextKeys, - /export const IsWhiteboardWindowContext = new RawContextKey\('isWhiteboardWindow', false/, + /export const IsReviewWindowContext = new RawContextKey\('isReviewWindow', false/, ); assert.match( - whiteboardWorkbench, - /IsWhiteboardWindowContext\.bindTo\(contextKeyService\)\.set\(true\)/, + reviewWorkbench, + /IsReviewWindowContext\.bindTo\(contextKeyService\)\.set\(true\)/, "the Review workbench must set the context key it gates chrome on", ); }); @@ -41,7 +41,7 @@ test("the split editor toolbar icon is gated out of Review", () => { ); for (const item of splitToolItems) { - assert.match(item, /IsWhiteboardWindowContext\.toNegated\(\)/); + assert.match(item, /IsReviewWindowContext\.toNegated\(\)/); } }); @@ -53,7 +53,7 @@ test("Review renders no editor actions overflow menu", () => { assert.ok(update, "expected updateEditorActionsToolbar"); assert.match( update, - /IsWhiteboardWindowContext\.getValue\(this\.contextKeyService\) \? \[\] : secondary/, + /IsReviewWindowContext\.getValue\(this\.contextKeyService\) \? \[\] : secondary/, "Review must drop secondary actions so the toolbar shows no '...' button", ); assert.match( diff --git a/apps/whiteboard-desktop/scripts/freshness.sh b/apps/review-desktop/scripts/freshness.sh similarity index 85% rename from apps/whiteboard-desktop/scripts/freshness.sh rename to apps/review-desktop/scripts/freshness.sh index 6ca65f52d..06db23611 100644 --- a/apps/whiteboard-desktop/scripts/freshness.sh +++ b/apps/review-desktop/scripts/freshness.sh @@ -46,8 +46,8 @@ rebuild_review_desktop_outputs() { "$review_package/src" \ "$review_package/tsdown.config.ts" \ "$review_package/package.json" \ - "$monorepo_root/packages/whiteboard-protocol/src"; then - pnpm --dir "$monorepo_root" --filter @dev.fast/whiteboard build + "$monorepo_root/packages/review-protocol/src"; then + pnpm --dir "$monorepo_root" --filter @dev.fast/review build fi if needs_rebuild \ "$review_package/app/dist/desktop/.vite/manifest.json" \ @@ -55,8 +55,8 @@ rebuild_review_desktop_outputs() { "$review_package/app/desktop.vite.config.ts" \ "$review_package/app/package.json" \ "$review_package/package.json" \ - "$monorepo_root/packages/whiteboard-protocol/src"; then - pnpm --dir "$monorepo_root" --filter @dev.fast/whiteboard-canvas build + "$monorepo_root/packages/review-protocol/src"; then + pnpm --dir "$monorepo_root" --filter @dev.fast/review-canvas build fi local tutorial_output="$review_package/tutorial/pins.json" if needs_rebuild \ @@ -67,6 +67,6 @@ rebuild_review_desktop_outputs() { \( -path "$review_package/tutorial/.bundle" -o -path "$review_package/tutorial/git-stub" -o -path "$review_package/tutorial/pins.json" \) -prune \ -o -type f -newer "$tutorial_output" -print -quit )" ]]; then - pnpm --dir "$monorepo_root" --filter @dev.fast/whiteboard build:tutorial-assets + pnpm --dir "$monorepo_root" --filter @dev.fast/review build:tutorial-assets fi } diff --git a/apps/whiteboard-desktop/scripts/legacy-import-live-home.sh b/apps/review-desktop/scripts/legacy-import-live-home.sh similarity index 85% rename from apps/whiteboard-desktop/scripts/legacy-import-live-home.sh rename to apps/review-desktop/scripts/legacy-import-live-home.sh index d3a42a9e6..bb9e057aa 100755 --- a/apps/whiteboard-desktop/scripts/legacy-import-live-home.sh +++ b/apps/review-desktop/scripts/legacy-import-live-home.sh @@ -2,7 +2,7 @@ # Build a disposable review home for live-testing legacy review import, then # print how to launch the Desktop on it. The live ~/.dev is never modified. # -# bash apps/whiteboard-desktop/scripts/legacy-import-live-home.sh [home-dir] +# bash apps/review-desktop/scripts/legacy-import-live-home.sh [home-dir] # # The home gets: # - a copy of ~/.dev/reviews (schema-5 reviews with sealed JSON, "old JSON") @@ -14,10 +14,10 @@ set -euo pipefail WORKSPACE=$(cd "$(dirname "$0")/../../.." && pwd) -FIXTURES="$WORKSPACE/packages/whiteboard/src/fixtures/legacy-reviews" +FIXTURES="$WORKSPACE/packages/review/src/fixtures/legacy-reviews" HOME_DIR=${1:-$(mktemp -d /tmp/review-live-XXXX)} SCRATCH="$HOME_DIR/repos/review-scratch" -LIVE="${DEV_WHITEBOARD_HOME:-$HOME/.dev}" +LIVE="${DEV_REVIEW_HOME:-$HOME/.dev}" if [ "$(cd "$HOME_DIR" && pwd -P)" = "$(cd "$LIVE" 2>/dev/null && pwd -P)" ]; then echo "refusing to build inside the live review home $LIVE" >&2 @@ -89,12 +89,12 @@ fi echo "Launch the Desktop:" echo echo " cd $WORKSPACE" - echo " DEV_WHITEBOARD_HOME=\"$HOME_DIR\" DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED=1 DEV_FAST_WHITEBOARD_CLI_NO_DELEGATE=1 DEV_WHITEBOARD_EXTENSIONS=none pnpm dev" + echo " DEV_REVIEW_HOME=\"$HOME_DIR\" DEV_FAST_REVIEW_TELEMETRY_DISABLED=1 DEV_FAST_REVIEW_CLI_NO_DELEGATE=1 DEV_REVIEW_EXTENSIONS=none pnpm dev" echo echo "CLI in a second terminal (run \`review\` from inside $SCRATCH):" echo - echo " export DEV_WHITEBOARD_HOME=\"$HOME_DIR\" DEV_FAST_WHITEBOARD_CLI_NO_DELEGATE=1 DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED=1" - echo " alias review='pnpm --filter @dev.fast/whiteboard review'" + echo " export DEV_REVIEW_HOME=\"$HOME_DIR\" DEV_FAST_REVIEW_CLI_NO_DELEGATE=1 DEV_FAST_REVIEW_TELEMETRY_DISABLED=1" + echo " alias review='pnpm --filter @dev.fast/review review'" echo echo "Inventory (state before the Desktop lists Home):" echo @@ -106,8 +106,8 @@ import json, os, sys directory = sys.argv[1] record = json.load(open(os.path.join(directory, "review.json"))) -document = os.path.join(directory, ".bundle/document/whiteboard-document.json") -legacy = os.path.join(directory, ".bundle/whiteboard-document.js") +document = os.path.join(directory, ".bundle/document/review-document.json") +legacy = os.path.join(directory, ".bundle/review-document.js") bundle = "json" if os.path.exists(document) else "js" if os.path.exists(legacy) else "in git only" print( f"| {os.path.basename(directory.rstrip('/'))} | {record['schemaVersion']} | {bundle} | " diff --git a/apps/whiteboard-desktop/scripts/legacy-import-smoke.mjs b/apps/review-desktop/scripts/legacy-import-smoke.mjs similarity index 92% rename from apps/whiteboard-desktop/scripts/legacy-import-smoke.mjs rename to apps/review-desktop/scripts/legacy-import-smoke.mjs index bdf110b8e..c6a5bd90a 100644 --- a/apps/whiteboard-desktop/scripts/legacy-import-smoke.mjs +++ b/apps/review-desktop/scripts/legacy-import-smoke.mjs @@ -6,7 +6,7 @@ * mkdir -p "$SMOKE_HOME/reviews" && cp -R ~/.dev/reviews/. "$SMOKE_HOME/reviews/" * node scripts/legacy-import-smoke.mjs --home "$SMOKE_HOME" * - * Run from apps/whiteboard-desktop after `pnpm app:build`. The script refuses the + * Run from apps/review-desktop after `pnpm app:build`. The script refuses the * live ~/.dev home; copy only `reviews/` into a scratch home first. */ import assert from "node:assert/strict"; @@ -62,11 +62,11 @@ await new Promise((resolve) => portServer.close(resolve)); const env = { ...process.env, - DEV_WHITEBOARD_HOME: home, - DEV_FAST_WHITEBOARD_CLI_NO_DELEGATE: "1", - DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED: "1", - DEV_WHITEBOARD_EXTENSIONS: "none", - DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT: String(port), + DEV_REVIEW_HOME: home, + DEV_FAST_REVIEW_CLI_NO_DELEGATE: "1", + DEV_FAST_REVIEW_TELEMETRY_DISABLED: "1", + DEV_REVIEW_EXTENSIONS: "none", + DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT: String(port), }; for (const key of [ @@ -75,7 +75,7 @@ for (const key of [ "CLAUDE_CODE_SESSION_ID", "CLAUDE_SESSION_ID", "PI_SESSION_ID", - "DEV_FAST_WHITEBOARD_TOOLING_ROOT", + "DEV_FAST_REVIEW_TOOLING_ROOT", "NODE_OPTIONS", ]) delete env[key]; @@ -87,7 +87,7 @@ await mkdir(profile, { recursive: true }); await writeFile( path.join(profile, "settings.json"), JSON.stringify({ - "whiteboard.experimental.softwareMap.enabled": true, + "review.experimental.softwareMap.enabled": true, "security.workspace.trust.enabled": false, "telemetry.telemetryLevel": "off", "workbench.startupEditor": "none", @@ -189,17 +189,15 @@ const api = async (route, method = "GET", body) => { const response = await fetch(new URL(route, discovery.url), { method, headers: { - "x-whiteboard-token": discovery.token, + "x-review-token": discovery.token, "content-type": "application/json", }, body: body === undefined ? undefined : JSON.stringify(body), }); - const value = await response.json().catch(() => null); - return { status: response.status, - value: value, + value: await response.json().catch(() => null), }; }; @@ -241,7 +239,7 @@ for (const review of expected) { } else { const snapshot = await until(async () => { await api("/reviews"); - const candidate = await api(`/sessions-api/${review.uuid}?full=true`); + const candidate = await api(`/reviews-api/${review.uuid}?full=true`); if (candidate.status === 200) return candidate.value; @@ -275,7 +273,7 @@ for (const review of expected) { .flatMap((context) => context.pages())) if ( (await candidate - .locator(".whiteboard-canvas-root [data-whiteboard-api]") + .locator(".review-canvas-root [data-review-api]") .count() .catch(() => 0)) > 0 && (await candidate @@ -288,7 +286,7 @@ for (const review of expected) { return null; }, `JSON canvas for ${snapshot.title}`); - const canvas = page.locator(".whiteboard-canvas-root"); + const canvas = page.locator(".review-canvas-root"); assert.doesNotMatch(await canvas.innerText(), /Layout failed:/); await page.screenshot({ path: path.join(out, `${review.uuid}.png`) }); diff --git a/apps/review-desktop/scripts/linux-package.test.mjs b/apps/review-desktop/scripts/linux-package.test.mjs new file mode 100644 index 000000000..9fbaedd33 --- /dev/null +++ b/apps/review-desktop/scripts/linux-package.test.mjs @@ -0,0 +1,47 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { reviewPackage } from "../code-oss/build/linux/review-package.ts"; +import { releaseIdentityFor } from "./release-channel.mjs"; + +const product = (quality) => ({ quality, ...releaseIdentityFor(quality) }); + +test("stable versions package as dev-fast-review", () => { + assert.deepEqual(reviewPackage(product("stable"), "1.2.3", "2"), { + name: "dev-fast-review", + app: "review", + appName: "Review", + appId: "dev.fast.review", + rpmVersion: "1.2.3", + revision: "2", + file: "dev-fast-review-1.2.3-2.x86_64.rpm", + }); +}); + +test("preview versions package separately with a tilde RPM version", () => { + assert.deepEqual( + reviewPackage(product("preview"), "1.2.4-preview.20260922.7", "1"), + { + name: "dev-fast-review-preview", + app: "review-preview", + appName: "Review Preview", + appId: "dev.fast.review.preview", + rpmVersion: "1.2.4~preview.20260922.7", + revision: "1", + file: "dev-fast-review-preview-1.2.4~preview.20260922.7-1.x86_64.rpm", + }, + ); +}); + +test("the payload quality must match the version shape", () => { + assert.throws( + () => reviewPackage(product("stable"), "1.2.4-preview.20260922.7", "1"), + /quality "stable" does not match/, + ); + assert.throws( + () => reviewPackage(product("preview"), "1.2.4", "1"), + /quality "preview" does not match/, + ); + assert.throws(() => reviewPackage(product("stable"), "1.2.4-rc.1", "1")); + assert.throws(() => reviewPackage(product("stable"), "1.2.4", "0")); +}); diff --git a/apps/whiteboard-desktop/scripts/linux/README.md b/apps/review-desktop/scripts/linux/README.md similarity index 100% rename from apps/whiteboard-desktop/scripts/linux/README.md rename to apps/review-desktop/scripts/linux/README.md diff --git a/apps/whiteboard-desktop/scripts/linux/keys/0760DDC0AACD234D42A2C62626D3C32D039A5EC3.asc b/apps/review-desktop/scripts/linux/keys/0760DDC0AACD234D42A2C62626D3C32D039A5EC3.asc similarity index 100% rename from apps/whiteboard-desktop/scripts/linux/keys/0760DDC0AACD234D42A2C62626D3C32D039A5EC3.asc rename to apps/review-desktop/scripts/linux/keys/0760DDC0AACD234D42A2C62626D3C32D039A5EC3.asc diff --git a/apps/whiteboard-desktop/scripts/linux/test-publication.py b/apps/review-desktop/scripts/linux/test-publication.py similarity index 100% rename from apps/whiteboard-desktop/scripts/linux/test-publication.py rename to apps/review-desktop/scripts/linux/test-publication.py diff --git a/apps/whiteboard-desktop/scripts/linux/verify-fedora-container.sh b/apps/review-desktop/scripts/linux/verify-fedora-container.sh similarity index 100% rename from apps/whiteboard-desktop/scripts/linux/verify-fedora-container.sh rename to apps/review-desktop/scripts/linux/verify-fedora-container.sh diff --git a/apps/whiteboard-desktop/scripts/linux/verify-repository.sh b/apps/review-desktop/scripts/linux/verify-repository.sh similarity index 100% rename from apps/whiteboard-desktop/scripts/linux/verify-repository.sh rename to apps/review-desktop/scripts/linux/verify-repository.sh diff --git a/apps/whiteboard-desktop/scripts/lsp-e2e-extension.cjs b/apps/review-desktop/scripts/lsp-e2e-extension.cjs similarity index 98% rename from apps/whiteboard-desktop/scripts/lsp-e2e-extension.cjs rename to apps/review-desktop/scripts/lsp-e2e-extension.cjs index 09a29ba8f..9c6418bde 100644 --- a/apps/whiteboard-desktop/scripts/lsp-e2e-extension.cjs +++ b/apps/review-desktop/scripts/lsp-e2e-extension.cjs @@ -8,7 +8,7 @@ const path = require("node:path"); exports.activate = function (context) { context.subscriptions.push( vscode.commands.registerCommand("review.lspE2E", async () => { - const root = process.env.WHITEBOARD_LSP_E2E_ROOT; + const root = process.env.REVIEW_LSP_E2E_ROOT; const request = JSON.parse( await fs.readFile(path.join(root, "request.json"), "utf8"), diff --git a/apps/whiteboard-desktop/scripts/lsp-e2e.mjs b/apps/review-desktop/scripts/lsp-e2e.mjs similarity index 87% rename from apps/whiteboard-desktop/scripts/lsp-e2e.mjs rename to apps/review-desktop/scripts/lsp-e2e.mjs index 7988087a8..2cf90f599 100644 --- a/apps/whiteboard-desktop/scripts/lsp-e2e.mjs +++ b/apps/review-desktop/scripts/lsp-e2e.mjs @@ -39,10 +39,10 @@ const { values } = parseArgs({ const bundledDiffr = values.app ? path.join(values.app, "Contents/Resources/app/review-runtime/bin/diffr") - : path.join(workspace, "packages/whiteboard/bin/diffr"); + : path.join(workspace, "packages/review/bin/diffr"); const structuralDiffAvailable = - !!process.env.WHITEBOARD_DIFFR_BINARY || + !!process.env.REVIEW_DIFFR_BINARY || existsSync(bundledDiffr) || (await exec("which", ["diffr"]).then( () => true, @@ -66,18 +66,18 @@ const extension = path.join(root, "probe"); const env = { ...process.env, - DEV_WHITEBOARD_HOME: home, - DEV_WHITEBOARD_IMPORT_FROM: "none", - DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED: "1", - WHITEBOARD_LSP_E2E_ROOT: root, + DEV_REVIEW_HOME: home, + DEV_REVIEW_IMPORT_FROM: "none", + DEV_FAST_REVIEW_TELEMETRY_DISABLED: "1", + REVIEW_LSP_E2E_ROOT: root, }; for (const key of [ "NODE_OPTIONS", "DEV_FAST_AGENT_SESSION", "CODEX_THREAD_ID", - "DEV_FAST_WHITEBOARD_TOOLING_ROOT", - "DEV_FAST_WHITEBOARD_SERVER_ENTRY", + "DEV_FAST_REVIEW_TOOLING_ROOT", + "DEV_FAST_REVIEW_SERVER_ENTRY", ]) delete env[key]; @@ -314,11 +314,11 @@ async function launch() { NODE_ENV: "development", VSCODE_DEV: "1", VSCODE_CLI: "1", - DEV_FAST_WHITEBOARD_SERVER_ENTRY: path.join( + DEV_FAST_REVIEW_SERVER_ENTRY: path.join( workspace, - "packages/whiteboard/dist/server/desktop-host.js", + "packages/review/dist/server/desktop-host.js", ), - DEV_FAST_WHITEBOARD_TOOLING_ROOT: workspace, + DEV_FAST_REVIEW_TOOLING_ROOT: workspace, }; app = spawn( @@ -398,10 +398,10 @@ async function stop() { } async function api(route, method = "GET", body) { - const response = await fetch(`${discovery.url}/sessions-api${route}`, { + const response = await fetch(`${discovery.url}/reviews-api${route}`, { method, headers: { - "x-whiteboard-token": discovery.token, + "x-review-token": discovery.token, "content-type": "application/json", }, body: body === undefined ? undefined : JSON.stringify(body), @@ -416,7 +416,7 @@ async function api(route, method = "GET", body) { const command = (operation) => api("/commands", "POST", { commandId: randomUUID(), operation }); -async function createWhiteboard(fix, title, kind = "commits") { +async function createReview(fix, title, kind = "commits") { const repository = await api("/repositories", "POST", { path: fix.repo }); const pins = await api("/pins", "POST", { @@ -425,7 +425,7 @@ async function createWhiteboard(fix, title, kind = "commits") { head: fix.head, }); - const whiteboard = await command({ + const review = await command({ type: "create", title, ...(kind === "worktree" @@ -433,10 +433,10 @@ async function createWhiteboard(fix, title, kind = "commits") { : { pins }), }); - const sessionId = whiteboard.sessionId; + const reviewId = review.reviewId; await command({ type: "edit", - sessionId, + reviewId, edit: { type: "insert", content: { @@ -468,7 +468,7 @@ async function createWhiteboard(fix, title, kind = "commits") { }, }); - return api(`/${sessionId}?full=true`); + return api(`/${reviewId}?full=true`); } async function probe(request) { @@ -502,21 +502,19 @@ async function probe(request) { return result; } -function uri(whiteboard, side = "head", file = "main.ts", commit) { - const query = new URLSearchParams({ version: String(whiteboard.version), side }); +function uri(review, side = "head", file = "main.ts", commit) { + const query = new URLSearchParams({ version: String(review.version), side }); - if (whiteboard.pins.worktreeRevision) - query.set("generation", whiteboard.pins.worktreeRevision); + if (review.pins.worktreeRevision) + query.set("generation", review.pins.worktreeRevision); if (commit) query.set("commit", commit); - return locationUri( - `review-api-source://${whiteboard.sessionId}/${file}?${query}`, - ); + return locationUri(`review-api-source://${review.reviewId}/${file}?${query}`); } -function environmentUri(whiteboard, file) { - const resource = new URL(uri(whiteboard)); +function environmentUri(review, file) { + const resource = new URL(uri(review)); resource.protocol = "review-language-source:"; resource.pathname = file; @@ -550,13 +548,13 @@ function locationUri(value) { }); } -async function readyEnvironment(whiteboard, side = "head") { +async function readyEnvironment(review, side = "head") { return until(async () => { const result = await api( - `/${whiteboard.sessionId}/language-context?version=${whiteboard.version}&side=${side}`, + `/${review.reviewId}/language-context?version=${review.version}&side=${side}`, ); - const environments = await api(`/${whiteboard.sessionId}/workspaces`); + const environments = await api(`/${review.reviewId}/workspaces`); const prepared = environments.find( (item) => item.generation === result.identity, @@ -639,12 +637,12 @@ async function record(label) { try { await launch(); - const whiteboard = await createWhiteboard(first, "Local LSP regression"); - const other = await createWhiteboard(second, "Other repository"); + const review = await createReview(first, "Local LSP regression"); + const other = await createReview(second, "Other repository"); await until(async () => { - await api(`/${whiteboard.sessionId}/open`, "POST"); + await api(`/${review.reviewId}/open`, "POST"); await page - .locator(".whiteboard-canvas-root") + .locator(".review-canvas-root") .filter({ hasText: "Local LSP regression" }) .first() .waitFor({ timeout: 3000 }); @@ -652,8 +650,8 @@ try { return true; }, "rendered review"); const greetAt = at(mainText("head"), 3, "greet"); - const headEnvironment = await readyEnvironment(whiteboard); - const baseEnvironment = await readyEnvironment(whiteboard, "base"); + const headEnvironment = await readyEnvironment(review); + const baseEnvironment = await readyEnvironment(review, "base"); assert.notEqual(headEnvironment.rootPath, baseEnvironment.rootPath); assert.equal( ( @@ -667,16 +665,16 @@ try { for (const side of ["base", "head"]) { await expectDefinition( - uri(whiteboard, side), + uri(review, side), greetAt, - uri(whiteboard, side, "library.ts"), + uri(review, side, "library.ts"), 2, ); - await expectHover(uri(whiteboard, side), greetAt, "string"); + await expectHover(uri(review, side), greetAt, "string"); } await probe({ - uri: uri(whiteboard), + uri: uri(review), ...greetAt, open: true, command: "editor.action.showHover", @@ -692,13 +690,13 @@ try { ); await expectDefinition( - uri(whiteboard, "head", "main.py"), + uri(review, "head", "main.py"), { line: 2, character: 9 }, - uri(whiteboard, "head", "library_py.py"), + uri(review, "head", "library_py.py"), 0, ); await expectHover( - uri(whiteboard, "head", "main.py"), + uri(review, "head", "main.py"), { line: 2, character: 9 }, "str", ); @@ -718,7 +716,7 @@ try { ]) { await until(async () => { const result = await probe({ - uri: uri(whiteboard), + uri: uri(review), ...position, feature, open: true, @@ -726,14 +724,14 @@ try { return locations(result.result).some( (item) => - locationUri(item.uri) === uri(whiteboard, "head", "library.ts") && + locationUri(item.uri) === uri(review, "head", "library.ts") && (item.range[0]?.line ?? item.range.start?.line) === targetLine, ); }, feature); } const refs = await probe({ - uri: uri(whiteboard), + uri: uri(review), ...greetAt, feature: "vscode.executeReferenceProvider", open: true, @@ -741,14 +739,14 @@ try { assert.ok( locations(refs.result).some( - (item) => locationUri(item.uri) === uri(whiteboard), + (item) => locationUri(item.uri) === uri(review), ), ); await expectDefinition( - uri(whiteboard), + uri(review), at(mainText("head"), 6, "dependencyValue"), environmentUri( - whiteboard, + review, path.join( headEnvironment.rootPath, "node_modules/fixture-dependency/index.d.ts", @@ -757,21 +755,21 @@ try { 0, ); await expectDefinition( - uri(whiteboard), + uri(review), at(mainText("head"), 9, "greet()"), - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), 2, ); for (const line of [7, 8]) await expectDefinition( - uri(whiteboard), + uri(review), { line, character: mainText("head").split(/\r?\n/)[line].lastIndexOf("shared") + 1, }, - uri(whiteboard, "head", "main.ts"), + uri(review, "head", "main.ts"), line, ); await record( @@ -785,13 +783,13 @@ try { 2, ); await expectDefinition( - uri(whiteboard), + uri(review), greetAt, - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), 2, ); - const concurrent = await createWhiteboard( + const concurrent = await createReview( { ...first, base: first.head }, "Same worktree different pins", ); @@ -817,15 +815,15 @@ try { ); await expectDefinition( - uri(whiteboard, "base"), + uri(review, "base"), greetAt, - uri(whiteboard, "base", "library.ts"), + uri(review, "base", "library.ts"), 2, ); await expectDefinition( - uri(whiteboard), + uri(review), greetAt, - environmentUri(whiteboard, path.join(headEnvironment.rootPath, "library.ts")), + environmentUri(review, path.join(headEnvironment.rootPath, "library.ts")), 3, ); @@ -864,20 +862,20 @@ try { for (const side of ["base", "head"]) { await expectDefinition( - uri(whiteboard, side), + uri(review, side), greetAt, - uri(whiteboard, side, "library.ts"), + uri(review, side, "library.ts"), 2, ); - const result = await expectHover(uri(whiteboard, side), greetAt, "string"); + const result = await expectHover(uri(review, side), greetAt, "string"); assert.equal(result.active.text, mainText(side)); await expectDefinition( - uri(whiteboard, side), + uri(review, side), { line: 7, character: mainText("head").split(/\r?\n/)[7].lastIndexOf("shared") + 1, }, - uri(whiteboard, side, "main.ts"), + uri(review, side, "main.ts"), 7, ); } @@ -885,7 +883,7 @@ try { assert.equal( ( await api( - `/${whiteboard.sessionId}/file?version=${whiteboard.version}&side=head&file=main.ts`, + `/${review.reviewId}/file?version=${review.version}&side=head&file=main.ts`, ) ).text, mainText("head"), @@ -914,7 +912,7 @@ try { ); const unavailable = await probe({ - uri: uri(whiteboard), + uri: uri(review), ...greetAt, feature: definition, open: true, @@ -927,7 +925,7 @@ try { ); const deletedLine = await probe({ - uri: uri(whiteboard), + uri: uri(review), ...greetAt, feature: definition, open: true, @@ -947,7 +945,7 @@ try { "vscode.executeImplementationProvider", ]) { const result = await probe({ - uri: uri(whiteboard), + uri: uri(review), ...greetAt, feature, open: true, @@ -969,16 +967,16 @@ try { await git(first.repo, "reset", "--hard", first.head); await git(first.repo, "checkout", "--detach", first.base); await expectDefinition( - uri(whiteboard), + uri(review), greetAt, - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), 2, ); await git(first.repo, "checkout", "main"); await expectDefinition( - uri(whiteboard), + uri(review), greetAt, - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), 2, ); await record( @@ -986,7 +984,7 @@ try { ); const renamed = await probe({ - uri: uri(whiteboard, "base", "old.ts"), + uri: uri(review, "base", "old.ts"), line: 0, character: 25, feature: definition, @@ -995,20 +993,20 @@ try { assert.ok( locations(renamed.result).some( - (item) => locationUri(item.uri) === uri(whiteboard, "base", "library.ts"), + (item) => locationUri(item.uri) === uri(review, "base", "library.ts"), ), ); await expectDefinition( - uri(whiteboard, "head", "renamed.ts"), + uri(review, "head", "renamed.ts"), { line: 0, character: 25 }, - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), 2, ); for (const source of [ - uri(whiteboard, "base", "deleted.ts"), - `${uri(whiteboard, "base", "added.ts")}&empty=true`, - `${uri(whiteboard, "head", "deleted.ts")}&empty=true`, + uri(review, "base", "deleted.ts"), + `${uri(review, "base", "added.ts")}&empty=true`, + `${uri(review, "head", "deleted.ts")}&empty=true`, ]) { const result = await probe({ uri: source, @@ -1025,40 +1023,36 @@ try { "renamed/missing paths and empty added/deleted sides never select a substitute", ); await expectDefinition( - uri(whiteboard, "head", "main.ts", first.head), + uri(review, "head", "main.ts", first.head), greetAt, - uri(whiteboard, "head", "library.ts", first.head), + uri(review, "head", "library.ts", first.head), 2, ); await record("selected-commit source retains its own pinned coordinates"); const newerPins = await api("/pins", "POST", { - repositoryId: whiteboard.pins.repositoryId, + repositoryId: review.pins.repositoryId, base: first.base, head: first.base, }); - await command({ - type: "repin", - sessionId: whiteboard.sessionId, - pins: newerPins, - }); - const newerWhiteboard = await api(`/${whiteboard.sessionId}?full=true`); - const historical = await expectHover(uri(whiteboard), greetAt, "string"); + await command({ type: "repin", reviewId: review.reviewId, pins: newerPins }); + const newerReview = await api(`/${review.reviewId}?full=true`); + const historical = await expectHover(uri(review), greetAt, "string"); assert.equal(historical.active.text, mainText("head")); - const repinned = await expectHover(uri(newerWhiteboard), greetAt, "string"); + const repinned = await expectHover(uri(newerReview), greetAt, "string"); assert.equal(repinned.active.text, mainText("base")); await command({ type: "restore", - sessionId: whiteboard.sessionId, - version: whiteboard.version, + reviewId: review.reviewId, + version: review.version, }); await record( "historical saved versions keep their source after repin and restore", ); await probe({ - uri: uri(whiteboard), + uri: uri(review), ...greetAt, open: true, command: "editor.action.revealDefinition", @@ -1068,14 +1062,14 @@ try { const state = await probe({}); return ( - locationUri(state.active?.uri) === uri(whiteboard, "head", "library.ts") && + locationUri(state.active?.uri) === uri(review, "head", "library.ts") && state ); }, "rendered definition target"); assert.equal( locationUri(navigated.active.uri), - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), ); assert.equal(navigated.active.line, 2); await page.screenshot({ path: path.join(root, "definition-target.png") }); @@ -1084,17 +1078,17 @@ try { ); await probe({ command: "workbench.action.closeModalEditor" }); - await api(`/${whiteboard.sessionId}/open`, "POST"); + await api(`/${review.reviewId}/open`, "POST"); await until(async () => { await page - .locator(".whiteboard-canvas-root") + .locator(".review-canvas-root") .filter({ hasText: "Local LSP regression" }) .first() .waitFor({ timeout: 3000 }); return true; }, "reopened review"); - const restoredWhiteboard = await api(`/${whiteboard.sessionId}?full=true`); + const restoredReview = await api(`/${review.reviewId}?full=true`); if (structuralDiffAvailable) { // Document code views use the native unified diff editor. The modified @@ -1140,7 +1134,7 @@ try { await until( async () => locationUri((await probe({})).active?.uri) === - uri(restoredWhiteboard, "head", "library.ts"), + uri(restoredReview, "head", "library.ts"), "inline definition navigation", ); await record( @@ -1150,7 +1144,7 @@ try { console.log("SKIP rendered inline peeks: diffr is unavailable on PATH"); } - await probe({ diff: { base: uri(whiteboard, "base"), head: uri(whiteboard) } }); + await probe({ diff: { base: uri(review, "base"), head: uri(review) } }); for (const side of ["original", "modified"]) { const line = page @@ -1181,15 +1175,15 @@ try { await stop(); await launch(); await expectDefinition( - uri(whiteboard), + uri(review), greetAt, - uri(whiteboard, "head", "library.ts"), + uri(review, "head", "library.ts"), 2, ); await expectDefinition( - uri(whiteboard, "head", "main.py"), + uri(review, "head", "main.py"), { line: 2, character: 9 }, - uri(whiteboard, "head", "library_py.py"), + uri(review, "head", "library_py.py"), 0, ); await record("Desktop restart restores language-service context"); @@ -1247,7 +1241,7 @@ try { await git(precision.repo, "add", "."); await git(precision.repo, "commit", "-qm", "Different historical types"); precision.head = await git(precision.repo, "rev-parse", "HEAD"); - const exact = await createWhiteboard(precision, "Historical project semantics"); + const exact = await createReview(precision, "Historical project semantics"); await readyEnvironment(exact); await readyEnvironment(exact, "base"); @@ -1301,10 +1295,10 @@ try { const failedPreparation = await until(async () => { const environment = await api( - `/${exact.sessionId}/language-context?side=head&version=${exact.version}`, + `/${exact.reviewId}/language-context?side=head&version=${exact.version}`, ); - const environments = await api(`/${exact.sessionId}/workspaces`); + const environments = await api(`/${exact.reviewId}/workspaces`); return environments.find( (item) => @@ -1313,9 +1307,9 @@ try { }, "preparation failure"); await probe({ command: "workbench.action.closeModalEditor" }); - const opened = await api(`/${exact.sessionId}/open`, "POST"); + const opened = await api(`/${exact.reviewId}/open`, "POST"); assert.equal(opened.environmentIssues, undefined); - assert.deepEqual(await api(`/${exact.sessionId}/environment`, "POST", {}), { + assert.deepEqual(await api(`/${exact.reviewId}/environment`, "POST", {}), { issues: [], }); assert.equal( @@ -1332,7 +1326,7 @@ try { "node prepare.cjs", ); await api( - `/${exact.sessionId}/workspaces/${failedPreparation.id}/retry`, + `/${exact.reviewId}/workspaces/${failedPreparation.id}/retry`, "POST", ); await readyEnvironment(exact); @@ -1341,7 +1335,7 @@ try { ); const liveFixture = await fixture("live"); - const live = await createWhiteboard( + const live = await createReview( liveFixture, "Working tree language services", "worktree", @@ -1357,7 +1351,7 @@ try { ); await probe({ command: "workbench.action.closeModalEditor" }); - await api(`/${live.sessionId}/open`, "POST"); + await api(`/${live.reviewId}/open`, "POST"); if (structuralDiffAvailable) { const liveInline = page @@ -1516,7 +1510,7 @@ try { let environmentRequests = 0; const countEnvironment = (request) => { - if (request.url().includes(`/${live.sessionId}/language-context?`)) + if (request.url().includes(`/${live.reviewId}/language-context?`)) environmentRequests++; }; @@ -1627,7 +1621,7 @@ try { .every((entry) => entry.includes("/.git/dev-fast/reviews/")), ); assert.ok( - (await api(`/${live.sessionId}/workspaces`)).every((workspace) => + (await api(`/${live.reviewId}/workspaces`)).every((workspace) => workspace.rootPath.includes("/.git/dev-fast/reviews/"), ), ); @@ -1637,7 +1631,7 @@ try { ); await probe({ command: "workbench.action.closeModalEditor" }); - await api(`/${live.sessionId}/open`, "POST"); + await api(`/${live.reviewId}/open`, "POST"); await writeFile( path.join(liveFixture.repo, "main.ts"), "// saved staged line\n" + mainText("head"), @@ -1654,16 +1648,16 @@ try { await until( async () => ( - await api(`/${live.sessionId}/file?side=head&file=main.ts`) + await api(`/${live.reviewId}/file?side=head&file=main.ts`) ).text.startsWith("// saved unstaged line"), "saved worktree API bytes", ); - const updated = await api(`/${live.sessionId}?full=true`); + const updated = await api(`/${live.reviewId}?full=true`); assert.equal(updated.version, live.version); assert.equal(updated.document[0].children[2].source.start.line, 3); const historicalWorktree = await api( - `/${live.sessionId}/file?side=head&file=main.ts&version=${live.version}`, + `/${live.reviewId}/file?side=head&file=main.ts&version=${live.version}`, ); assert.equal( @@ -1671,7 +1665,7 @@ try { "// saved unstaged line\n// saved staged line\n" + mainText("head"), ); assert.ok( - (await api(`/${live.sessionId}/tree`)).some( + (await api(`/${live.reviewId}/tree`)).some( (file) => file.path === "fresh.ts", ), ); @@ -1700,7 +1694,7 @@ try { await git(liveFixture.repo, "add", "."); await git(liveFixture.repo, "commit", "-qm", "Current working files"); await until( - async () => (await api(`/${whole.sessionId}/diff`)).length === 0, + async () => (await api(`/${whole.reviewId}/diff`)).length === 0, "working changes baseline follows commit", ); @@ -1710,17 +1704,17 @@ try { target: { kind: "commits", repositoryId, head: "HEAD" }, }); - assert.deepEqual(await api(`/${single.sessionId}/diff`), []); + assert.deepEqual(await api(`/${single.reviewId}/diff`), []); await git(liveFixture.repo, "checkout", "--detach", liveFixture.head); await until( async () => - (await api(`/${live.sessionId}/file?side=head&file=main.ts`)).text === + (await api(`/${live.reviewId}/file?side=head&file=main.ts`)).text === mainText("head"), "worktree follows branch switch", ); assert.ok( ( - await api(`/${single.sessionId}/file?side=head&file=main.ts`) + await api(`/${single.reviewId}/file?side=head&file=main.ts`) ).text.startsWith("// saved unstaged line"), ); await record( @@ -1729,11 +1723,11 @@ try { await stop(); await launch(); await until(async () => { - await api(`/${live.sessionId}/open`, "POST"); + await api(`/${live.reviewId}/open`, "POST"); return true; }, "reopen live review"); - const reopened = await api(`/${live.sessionId}?full=true`); + const reopened = await api(`/${live.reviewId}?full=true`); await expectDefinition( uri(reopened), @@ -1744,7 +1738,7 @@ try { assert.equal( ( await api( - `/${live.sessionId}/file?side=head&file=main.ts&version=${live.version}`, + `/${live.reviewId}/file?side=head&file=main.ts&version=${live.version}`, ) ).text, mainText("head"), @@ -1776,7 +1770,7 @@ try { "export const child = 1;\n", ); - const homeWhiteboard = await createWhiteboard( + const homeReview = await createReview( liveFixture, "Home live source", "worktree", @@ -1788,7 +1782,7 @@ try { .getByRole("button", { name: "Source tree ↗", exact: true }) .click(); await page - .getByRole("tab", { name: new RegExp(`^Source — ${homeWhiteboard.title}$`) }) + .getByRole("tab", { name: new RegExp(`^Source — ${homeReview.title}$`) }) .waitFor(); await writeFile( path.join(liveFixture.repo, "from-home.ts"), @@ -1800,7 +1794,7 @@ try { await page.getByText("child.ts", { exact: true }).first().waitFor(); await command({ type: "rename", - sessionId: homeWhiteboard.sessionId, + reviewId: homeReview.reviewId, title: "Renamed live source", }); await writeFile( diff --git a/apps/whiteboard-desktop/scripts/main-bootstrap-imports.test.mjs b/apps/review-desktop/scripts/main-bootstrap-imports.test.mjs similarity index 98% rename from apps/whiteboard-desktop/scripts/main-bootstrap-imports.test.mjs rename to apps/review-desktop/scripts/main-bootstrap-imports.test.mjs index 0d3ed8930..1be32d3e3 100644 --- a/apps/whiteboard-desktop/scripts/main-bootstrap-imports.test.mjs +++ b/apps/review-desktop/scripts/main-bootstrap-imports.test.mjs @@ -247,7 +247,7 @@ test("main.ts reaches no module that localizes before bootstrapESM()", () => { ` chain: ${chainTo(module, importers)}\n` + ` why this is fatal: ${reason}\n` + ` fix: move the value you need into an import-free module under\n` + - ` vs/whiteboard/common/ (see whiteboardConfigurationDefaults.ts), or load\n` + + ` vs/review/common/ (see reviewConfigurationDefaults.ts), or load\n` + ` it behind the dynamic import in startup().`, ); } @@ -292,7 +292,7 @@ test("the bootstrap crash-note module imports nothing but node builtins", () => // It records a crash that happens before anything else exists, including the // NLS table. The tests above already forbid the fatal modules; this one keeps // the file at zero in-tree edges, so it cannot acquire one by accident. - const module = "vs/whiteboard/node/whiteboardBootstrapBreadcrumb.ts"; + const module = "vs/review/node/reviewBootstrapBreadcrumb.ts"; assert.ok( importers.has(module), `${module} must stay reachable from main.ts — it is the only record of a pre-bootstrap crash`, diff --git a/apps/whiteboard-desktop/scripts/notarize-macos.sh b/apps/review-desktop/scripts/notarize-macos.sh similarity index 95% rename from apps/whiteboard-desktop/scripts/notarize-macos.sh rename to apps/review-desktop/scripts/notarize-macos.sh index 80de62162..21096c00b 100755 --- a/apps/whiteboard-desktop/scripts/notarize-macos.sh +++ b/apps/review-desktop/scripts/notarize-macos.sh @@ -2,14 +2,14 @@ set -euo pipefail MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" -APP_DIR="$MONOREPO_ROOT/apps/whiteboard-desktop" +APP_DIR="$MONOREPO_ROOT/apps/review-desktop" CHECKOUT="$APP_DIR/code-oss" PRODUCT_NAME="$(node -p "require('$CHECKOUT/product.json').nameShort")" PACKAGED_APP="$APP_DIR/VSCode-darwin-arm64/$PRODUCT_NAME.app" VERSION="$(node -p "require('$APP_DIR/package.json').version")" -ARTIFACT_DIR="${DEV_FAST_WHITEBOARD_ARTIFACT_DIR:-$APP_DIR/dist}" -UPDATE_ZIP="$ARTIFACT_DIR/Whiteboard-darwin-arm64-$VERSION.zip" -DMG="$ARTIFACT_DIR/Whiteboard-darwin-arm64-$VERSION.dmg" +ARTIFACT_DIR="${DEV_FAST_REVIEW_ARTIFACT_DIR:-$APP_DIR/dist}" +UPDATE_ZIP="$ARTIFACT_DIR/Review-darwin-arm64-$VERSION.zip" +DMG="$ARTIFACT_DIR/Review-darwin-arm64-$VERSION.dmg" if (( $# > 0 )); then echo "usage: $0" >&2 diff --git a/apps/whiteboard-desktop/scripts/package-linux-distributions.sh b/apps/review-desktop/scripts/package-linux-distributions.sh similarity index 85% rename from apps/whiteboard-desktop/scripts/package-linux-distributions.sh rename to apps/review-desktop/scripts/package-linux-distributions.sh index 16d7fe8cd..95471a20a 100644 --- a/apps/whiteboard-desktop/scripts/package-linux-distributions.sh +++ b/apps/review-desktop/scripts/package-linux-distributions.sh @@ -8,7 +8,7 @@ DIST="$APP_DIR/dist/linux" echo 'Fedora packages must be built on Linux x86_64' >&2; exit 1; } -node "$APP_DIR/scripts/stage-whiteboard-runtime.mjs" --verify --packaged-root "$APP_DIR/VSCode-linux-x64" +node "$APP_DIR/scripts/stage-review-runtime.mjs" --verify --packaged-root "$APP_DIR/VSCode-linux-x64" # The package name and RPM version come from the stamped channel (review-package.ts). npm --prefix "$CHECKOUT" run gulp -- vscode-linux-x64-prepare-rpm npm --prefix "$CHECKOUT" run gulp -- vscode-linux-x64-build-rpm diff --git a/apps/review-desktop/scripts/package-linux.sh b/apps/review-desktop/scripts/package-linux.sh new file mode 100755 index 000000000..a2dc75cbf --- /dev/null +++ b/apps/review-desktop/scripts/package-linux.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail + +MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" +APP_DIR="$MONOREPO_ROOT/apps/review-desktop" +CHECKOUT="$APP_DIR/code-oss" +PACKAGED_ROOT="$APP_DIR/VSCode-linux-x64" + +if (( $# > 0 )); then + echo "usage: $0" >&2 + exit 2 +fi +if [[ "$(uname -s)" != "Linux" ]]; then + echo "Review Desktop Linux packaging must run on Linux" >&2 + exit 1 +fi +if [[ "$(uname -m)" != "x86_64" ]]; then + echo "Review Desktop Linux packaging currently requires x86_64" >&2 + exit 1 +fi +if [[ ! -f "$CHECKOUT/node_modules/gulp/bin/gulp.js" ]]; then + echo "code-oss dependencies are missing; run pnpm --filter @dev.fast/review-desktop app:build first" >&2 + exit 1 +fi + +node "$APP_DIR/scripts/curated-extensions.mjs" --target=linux-x64 + +export BUILD_SOURCEVERSION="${BUILD_SOURCEVERSION:-$(git -C "$MONOREPO_ROOT" rev-parse HEAD)}" + +npm --prefix "$CHECKOUT" run gulp -- vscode-linux-x64 + +APPLICATION_NAME="$(node -p 'require(process.argv[1]).applicationName' "$PACKAGED_ROOT/resources/app/product.json")" +if [[ ! -x "$PACKAGED_ROOT/$APPLICATION_NAME" ]]; then + echo "Review Desktop packaging did not create $PACKAGED_ROOT/$APPLICATION_NAME" >&2 + exit 1 +fi +node "$APP_DIR/scripts/copy-canvas.mjs" --packaged-root "$PACKAGED_ROOT" +node "$APP_DIR/scripts/curated-extensions.mjs" \ + --target=linux-x64 \ + --copy-to "$PACKAGED_ROOT/resources/app/extensions" + +# The installed app embeds its own Review server runtime (server, CLI, and +# agent skills) so it never reaches back into this checkout. +pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/review build +pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/review ensure:diffr --required +node "$APP_DIR/scripts/stage-review-runtime.mjs" --packaged-root "$PACKAGED_ROOT" + +node "$APP_DIR/scripts/stage-review-runtime.mjs" --verify --packaged-root "$PACKAGED_ROOT" diff --git a/apps/whiteboard-desktop/scripts/package-macos.sh b/apps/review-desktop/scripts/package-macos.sh similarity index 86% rename from apps/whiteboard-desktop/scripts/package-macos.sh rename to apps/review-desktop/scripts/package-macos.sh index 07294b299..3063cd4be 100755 --- a/apps/whiteboard-desktop/scripts/package-macos.sh +++ b/apps/review-desktop/scripts/package-macos.sh @@ -3,10 +3,10 @@ set -euo pipefail # The macOS release is split: Linux produces the payload, and macOS consumes it. # New packaged outputs must follow the "Linux-to-macOS build handoff" contract -# in apps/whiteboard-desktop/README.md. +# in apps/review-desktop/README.md. MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" -APP_DIR="$MONOREPO_ROOT/apps/whiteboard-desktop" +APP_DIR="$MONOREPO_ROOT/apps/review-desktop" CHECKOUT="$APP_DIR/code-oss" PRODUCT_NAME="$(node -p "require('$CHECKOUT/product.json').nameShort")" PACKAGED_APP="$APP_DIR/VSCode-darwin-arm64/$PRODUCT_NAME.app" @@ -32,14 +32,14 @@ if [[ "$(uname -m)" != "arm64" ]]; then exit 1 fi -PRECOMPILED="${WHITEBOARD_DESKTOP_PRECOMPILED:-0}" +PRECOMPILED="${REVIEW_DESKTOP_PRECOMPILED:-0}" if [[ "$PRECOMPILED" == "1" ]]; then # The compile payload from compile-darwin-payload.sh is already extracted # into the checkout. Run only the darwin-side packaging. for relative in "${DARWIN_PAYLOAD_REQUIRED_PATHS[@]}"; do required="$MONOREPO_ROOT/$relative" if [[ ! -d "$required" ]]; then - echo "WHITEBOARD_DESKTOP_PRECOMPILED=1 but $required does not exist" >&2 + echo "REVIEW_DESKTOP_PRECOMPILED=1 but $required does not exist" >&2 exit 1 fi done @@ -80,8 +80,8 @@ node "$APP_DIR/scripts/curated-extensions.mjs" \ # build.sh produces the server dist in local mode. In precompiled mode, the # server dist arrives in the darwin payload. # Fetch on Darwin: precompiled payloads were built on Linux. -pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/whiteboard ensure:diffr --required -node "$APP_DIR/scripts/stage-whiteboard-runtime.mjs" --packaged-root "$PACKAGED_APP" +pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/review ensure:diffr --required +node "$APP_DIR/scripts/stage-review-runtime.mjs" --packaged-root "$PACKAGED_APP" # Installs Assets.car and rewrites CFBundleIconName, which invalidates any # existing signature. It must therefore run after every other bundle mutation @@ -89,6 +89,6 @@ node "$APP_DIR/scripts/stage-whiteboard-runtime.mjs" --packaged-root "$PACKAGED_ # stock Code OSS icon. node "$APP_DIR/scripts/apply-app-icon.mjs" "$PACKAGED_APP" -node "$APP_DIR/scripts/stage-whiteboard-runtime.mjs" --verify --packaged-root "$PACKAGED_APP" +node "$APP_DIR/scripts/stage-review-runtime.mjs" --verify --packaged-root "$PACKAGED_APP" bash "$APP_DIR/scripts/notarize-macos.sh" diff --git a/apps/whiteboard-desktop/scripts/packaged-runtime.test.mjs b/apps/review-desktop/scripts/packaged-runtime.test.mjs similarity index 83% rename from apps/whiteboard-desktop/scripts/packaged-runtime.test.mjs rename to apps/review-desktop/scripts/packaged-runtime.test.mjs index 51cdea889..5a9283597 100644 --- a/apps/whiteboard-desktop/scripts/packaged-runtime.test.mjs +++ b/apps/review-desktop/scripts/packaged-runtime.test.mjs @@ -17,13 +17,13 @@ test("canvas targets are derived from fixed output locations", () => { const packagedMacRoot = path.resolve("/tmp/Review.app"); assert.deepEqual(canvasTargets([], fakeAppRoot), [ - path.join(fakeAppRoot, "code-oss/out/vs/whiteboard/canvas"), + path.join(fakeAppRoot, "code-oss/out/vs/review/canvas"), ]); assert.deepEqual( canvasTargets(["--packaged-root", packagedRoot], fakeAppRoot), [ - path.join(fakeAppRoot, "code-oss/out/vs/whiteboard/canvas"), - path.join(packagedRoot, "resources/app/out/vs/whiteboard/canvas"), + path.join(fakeAppRoot, "code-oss/out/vs/review/canvas"), + path.join(packagedRoot, "resources/app/out/vs/review/canvas"), ], ); // A macOS bundle nests its resources under Contents/; without this the mac @@ -31,8 +31,8 @@ test("canvas targets are derived from fixed output locations", () => { assert.deepEqual( canvasTargets(["--packaged-root", packagedMacRoot], fakeAppRoot), [ - path.join(fakeAppRoot, "code-oss/out/vs/whiteboard/canvas"), - path.join(packagedMacRoot, "Contents/Resources/app/out/vs/whiteboard/canvas"), + path.join(fakeAppRoot, "code-oss/out/vs/review/canvas"), + path.join(packagedMacRoot, "Contents/Resources/app/out/vs/review/canvas"), ], ); assert.throws( @@ -51,9 +51,9 @@ test("the canvas loader exposes transient view-state reset", () => { assert.match( source, - /export \{ clearWhiteboardViewState, mountWhiteboardCanvas \} from "\.\/assets\/canvas\.js";/, + /export \{ clearReviewViewState, mountReviewCanvas \} from "\.\/assets\/canvas\.js";/, ); - assert.doesNotMatch(source, /whiteboardDocRuntimeUrl|doc-runtime/); + assert.doesNotMatch(source, /reviewDocRuntimeUrl|doc-runtime/); }); test("macOS entitlement artifacts retain required app and helper permissions", async () => { diff --git a/apps/whiteboard-desktop/scripts/product-hardening.test.mjs b/apps/review-desktop/scripts/product-hardening.test.mjs similarity index 92% rename from apps/whiteboard-desktop/scripts/product-hardening.test.mjs rename to apps/review-desktop/scripts/product-hardening.test.mjs index ca8a648da..ad8ed997d 100644 --- a/apps/whiteboard-desktop/scripts/product-hardening.test.mjs +++ b/apps/review-desktop/scripts/product-hardening.test.mjs @@ -14,9 +14,9 @@ const webviewPreloader = await readFile( "utf8", ); -const whiteboardCanvasPart = await readFile( +const reviewCanvasPart = await readFile( new URL( - "../code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasPart.ts", + "../code-oss/src/vs/review/browser/parts/canvas/reviewCanvasPart.ts", import.meta.url, ), "utf8", @@ -35,7 +35,7 @@ test("updates only from the sanctioned dev.fast feed", () => { assert.equal(product.updateUrl, "https://update.dev.fast"); assert.equal( product.quality, - process.env.WHITEBOARD_EXPECTED_QUALITY ?? "stable", + process.env.REVIEW_EXPECTED_QUALITY ?? "stable", ); }); @@ -138,7 +138,7 @@ test("removes dormant Microsoft endpoint configuration that is safe to omit", () // Desktop Code OSS never reads `configurationDefaults` from product.json — only the // extension contribution point and the web workbench options carry that name. Keeping // a copy there reads as hardening while applying nothing, so the block is gone and -// `whiteboardConfigurationDefaults.ts` is the single channel. +// `reviewConfigurationDefaults.ts` is the single channel. test("keeps product.json free of defaults nothing reads", () => { assert.equal(product.configurationDefaults, undefined); }); @@ -151,19 +151,19 @@ test("guards the active webview frame body while tracking focus", () => { }); test("configures Zod's CSP-safe mode before the canvas module evaluates", () => { - const candidateConfig = whiteboardCanvasPart.indexOf( + const candidateConfig = reviewCanvasPart.indexOf( "canvasGlobal.__zod_globalConfig ??= {};", ); - const candidateModule = whiteboardCanvasPart.indexOf( - "vs/whiteboard/canvas/canvas-loader.js", + const candidateModule = reviewCanvasPart.indexOf( + "vs/review/canvas/canvas-loader.js", ); assert.notEqual(candidateConfig, -1); assert.notEqual(candidateModule, -1); assert.ok(candidateConfig < candidateModule); assert.match( - whiteboardCanvasPart, + reviewCanvasPart, /canvasGlobal\.__zod_globalConfig\.jitless = true;/, ); }); diff --git a/apps/whiteboard-desktop/scripts/protocol-sync.mjs b/apps/review-desktop/scripts/protocol-sync.mjs similarity index 82% rename from apps/whiteboard-desktop/scripts/protocol-sync.mjs rename to apps/review-desktop/scripts/protocol-sync.mjs index 76d85d03a..8b0e1518d 100644 --- a/apps/whiteboard-desktop/scripts/protocol-sync.mjs +++ b/apps/review-desktop/scripts/protocol-sync.mjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -// Regenerates the Code OSS protocol overlay from packages/whiteboard-protocol/src. +// Regenerates the Code OSS protocol overlay from packages/review-protocol/src. // Byte-compares before writing so an unchanged protocol keeps its mtime // (freshness.sh gates incremental builds on it). import { execFileSync } from "node:child_process"; @@ -17,12 +17,12 @@ const monorepoRoot = path.resolve(appDirectory, "..", ".."); const generatorPath = path.join( monorepoRoot, - "packages/whiteboard-protocol/scripts/generate-native-source.mjs", + "packages/review-protocol/scripts/generate-native-source.mjs", ); const generatedProtocolPath = path.join( appDirectory, - "code-oss/src/vs/whiteboard/common/whiteboardProtocol.ts", + "code-oss/src/vs/review/common/reviewProtocol.ts", ); function syncProtocol() { @@ -31,7 +31,7 @@ function syncProtocol() { ); try { - const temporaryPath = path.join(temporaryDirectory, "whiteboardProtocol.ts"); + const temporaryPath = path.join(temporaryDirectory, "reviewProtocol.ts"); execFileSync(process.execPath, [generatorPath, temporaryPath], { stdio: "inherit", }); diff --git a/apps/whiteboard-desktop/scripts/publish-linux-repository.py b/apps/review-desktop/scripts/publish-linux-repository.py similarity index 100% rename from apps/whiteboard-desktop/scripts/publish-linux-repository.py rename to apps/review-desktop/scripts/publish-linux-repository.py diff --git a/apps/whiteboard-desktop/scripts/release-channel.mjs b/apps/review-desktop/scripts/release-channel.mjs similarity index 85% rename from apps/whiteboard-desktop/scripts/release-channel.mjs rename to apps/review-desktop/scripts/release-channel.mjs index 10512d2d8..b10e19ad6 100644 --- a/apps/whiteboard-desktop/scripts/release-channel.mjs +++ b/apps/review-desktop/scripts/release-channel.mjs @@ -1,7 +1,7 @@ const RELEASE_IDENTITIES = Object.freeze({ stable: Object.freeze({ - nameShort: "Whiteboard", - nameLong: "/dev/fast Whiteboard", + nameShort: "Review", + nameLong: "/dev/fast Review", applicationName: "review", dataFolderName: ".dev-fast-review", sharedDataFolderName: ".dev-fast-review-shared", @@ -9,8 +9,8 @@ const RELEASE_IDENTITIES = Object.freeze({ urlProtocol: "dev-fast-review", }), preview: Object.freeze({ - nameShort: "Whiteboard Preview", - nameLong: "/dev/fast Whiteboard Preview", + nameShort: "Review Preview", + nameLong: "/dev/fast Review Preview", applicationName: "review-preview", dataFolderName: ".dev-fast-review-preview", sharedDataFolderName: ".dev-fast-review-preview-shared", diff --git a/apps/whiteboard-desktop/scripts/whiteboard-files-model-errors.test.mjs b/apps/review-desktop/scripts/review-files-model-errors.test.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/whiteboard-files-model-errors.test.mjs rename to apps/review-desktop/scripts/review-files-model-errors.test.mjs diff --git a/apps/review-desktop/scripts/review-network-policy.mjs b/apps/review-desktop/scripts/review-network-policy.mjs new file mode 100644 index 000000000..868367466 --- /dev/null +++ b/apps/review-desktop/scripts/review-network-policy.mjs @@ -0,0 +1,71 @@ +// This is a blocklist, not an allowlist. `update.dev.fast` and `open-vsx.org` +// are sanctioned hosts and must stay reachable. Do not add them here when +// tightening this policy. +const BLOCKED_HOSTS = new Set([ + "aka.ms", + "marketplace.visualstudio.com", + "update.code.visualstudio.com", + "vscode.blob.core.windows.net", + "vscode.download.prss.microsoft.com", +]); + +const BLOCKED_HOST_SUFFIXES = [ + ".data.microsoft.com", + ".mai.microsoft.com", + ".vsassets.io", + ".vscode-cdn.net", +]; + +export function blockedReviewRequestReason(value) { + let url; + + try { + url = new URL(value); + } catch { + return undefined; + } + + const hostname = url.hostname.toLowerCase(); + + if (BLOCKED_HOSTS.has(hostname)) { + return `blocked service host ${hostname}`; + } + + const suffix = BLOCKED_HOST_SUFFIXES.find( + (candidate) => + hostname === candidate.slice(1) || hostname.endsWith(candidate), + ); + + if (suffix) { + return `blocked service host ${hostname}`; + } + + if ( + hostname === "api.github.com" && + /^\/copilot(?:_internal)?(?:\/|$)/.test(url.pathname) + ) { + return `blocked Copilot endpoint ${url.pathname}`; + } + + return undefined; +} + +export function assertNoBlockedReviewRequests(requestUrls) { + const blocked = [ + ...new Map( + requestUrls.flatMap((url) => { + const reason = blockedReviewRequestReason(url); + + return reason ? [[url, reason]] : []; + }), + ), + ].sort(([left], [right]) => left.localeCompare(right)); + + if (blocked.length === 0) return; + throw new Error( + [ + "Review Desktop contacted disabled Microsoft or Copilot services:", + ...blocked.map(([url, reason]) => `- ${reason}: ${url}`), + ].join("\n"), + ); +} diff --git a/apps/review-desktop/scripts/review-network-policy.test.mjs b/apps/review-desktop/scripts/review-network-policy.test.mjs new file mode 100644 index 000000000..e9c66c8c4 --- /dev/null +++ b/apps/review-desktop/scripts/review-network-policy.test.mjs @@ -0,0 +1,79 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { + assertNoBlockedReviewRequests, + blockedReviewRequestReason, +} from "./review-network-policy.mjs"; + +test("blocks disabled Microsoft service and asset hosts", () => { + for (const url of [ + "https://mobile.events.data.microsoft.com/OneCollector/1.0", + "https://update.code.visualstudio.com/api/update/darwin-universal/stable/latest", + "https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery", + "https://cdn.vsassets.io/v/M123/file.js", + "https://abc.vscode-cdn.net/stable/pre/index.html", + "wss://falcon-caas.mai.microsoft.com/voice-code/api/v1/realtime/voice", + "https://aka.ms/github-copilot-overview", + "https://vscode.blob.core.windows.net/gallery/index", + "https://vscode.download.prss.microsoft.com/dbazure/download/stable/file", + ]) { + assert.ok(blockedReviewRequestReason(url), url); + } +}); + +test("blocks Copilot API paths without blocking ordinary GitHub API use", () => { + assert.ok( + blockedReviewRequestReason( + "https://api.github.com/copilot_internal/v2/token", + ), + ); + assert.ok( + blockedReviewRequestReason("https://api.github.com/copilot/mcp_registry"), + ); + assert.equal( + blockedReviewRequestReason( + "https://api.github.com/repos/Fix-Fast/dev/pulls/1", + ), + undefined, + ); +}); + +test("allows local Review resources and non-service protocols", () => { + for (const url of [ + "http://localhost:3000/api/review", + "http://127.0.0.1:3000/api/review", + "vscode-file://vscode-app/out/vs/code/electron-sandbox/workbench/workbench.html", + "vscode-webview://review/index.html", + "data:text/plain,review", + "https://open-vsx.org/api/swiftlang/swift-vscode", + ]) { + assert.equal(blockedReviewRequestReason(url), undefined, url); + } + + assert.doesNotThrow(() => + assertNoBlockedReviewRequests([ + "http://localhost:3000/api/review", + "https://api.github.com/repos/Fix-Fast/dev", + ]), + ); +}); + +test("reports each blocked request once", () => { + assert.throws( + () => + assertNoBlockedReviewRequests([ + "https://mobile.events.data.microsoft.com/OneCollector/1.0", + "https://mobile.events.data.microsoft.com/OneCollector/1.0", + ]), + (error) => { + assert.match(error.message, /disabled Microsoft or Copilot services/); + assert.equal( + error.message.match(/mobile\.events\.data\.microsoft\.com/g)?.length, + 2, + ); + + return true; + }, + ); +}); diff --git a/apps/review-desktop/scripts/run.sh b/apps/review-desktop/scripts/run.sh new file mode 100755 index 000000000..66fb703dc --- /dev/null +++ b/apps/review-desktop/scripts/run.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +set -euo pipefail + +MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" +APP_DIR="$MONOREPO_ROOT/apps/review-desktop" +CHECKOUT="$APP_DIR/code-oss" +REVIEW_PACKAGE="$MONOREPO_ROOT/packages/review" +REVIEW_SERVER="$REVIEW_PACKAGE/dist/server/desktop-host.js" + +if (( $# > 0 )); then + echo "usage: $0" >&2 + exit 2 +fi + +if [[ ! -f "$CHECKOUT/product.json" ]]; then + echo "the tracked Code OSS fork is missing; restore the checkout before running Review Desktop" >&2 + exit 1 +fi +PACKAGED_ROOT="${DEV_FAST_REVIEW_PACKAGED_ROOT:-}" +if [[ -n "$PACKAGED_ROOT" ]]; then + PACKAGED_ROOT="$(cd "$PACKAGED_ROOT" && pwd -P)" + CODE_EXE_NAME="$( + cd "$CHECKOUT" + node -p "require('./product.json').applicationName" + )" + CODE_BINARY="$PACKAGED_ROOT/$CODE_EXE_NAME" +elif [[ "$OSTYPE" == "darwin"* ]]; then + CODE_APP_NAME="$( + cd "$CHECKOUT" + node -p "require('./product.json').nameShort" + )" + CODE_EXE_NAME="$( + cd "$CHECKOUT" + node -p "require('./product.json').nameShort" + )" + CODE_BINARY="$CHECKOUT/.build/electron/$CODE_APP_NAME.app/Contents/MacOS/$CODE_EXE_NAME" +else + CODE_APP_NAME="$( + cd "$CHECKOUT" + node -p "require('./product.json').applicationName" + )" + CODE_BINARY="$CHECKOUT/.build/electron/$CODE_APP_NAME" +fi +if [[ ! -x "$CODE_BINARY" ]]; then + echo "Review Desktop binary is not built at $CODE_BINARY" >&2 + exit 1 +fi + +# shellcheck source=freshness.sh +source "$APP_DIR/scripts/freshness.sh" + +REVIEW_USER_HOME="$(node -p "require('node:os').homedir()")" +REVIEW_BASE_HOME="${DEV_REVIEW_HOME:-$REVIEW_USER_HOME/.dev}" +STATE_ROOT="${DEV_FAST_REVIEW_DESKTOP_STATE_ROOT:-$REVIEW_BASE_HOME/review-desktop/state}" +mkdir -p "$STATE_ROOT/user-data" "$STATE_ROOT/extensions" "$STATE_ROOT/logs" + +# Curated extensions are downloaded, not committed. Materialize the selected +# groups before launch. `all` is the bundled set. Explicit optional groups are +# available for development launches. Set DEV_REVIEW_EXTENSIONS to all +# (default), none, or a comma-separated subset of +# rust,swift,csharp,python,go,vim,emacs. Enablement is a persisted in-app choice. +# `pnpm dev` runs build.sh (which also materializes this selection) right +# before this script; skip the repeat call when the manifest is unchanged and +# the selection matches the one already materialized. +EXTENSIONS_SELECTION="${DEV_REVIEW_EXTENSIONS:-all}" +EXTENSIONS_SELECTION_STAMP="$CHECKOUT/.build/dev-fast/curated-extensions.stamp" +mkdir -p "$(dirname "$EXTENSIONS_SELECTION_STAMP")" +if [[ "$(cat "$EXTENSIONS_SELECTION_STAMP" 2>/dev/null)" != "$EXTENSIONS_SELECTION" ]] || + needs_rebuild "$EXTENSIONS_SELECTION_STAMP" "$APP_DIR/scripts/curated-extensions.manifest.mjs"; then + node "$APP_DIR/scripts/curated-extensions.mjs" --only="$EXTENSIONS_SELECTION" + echo "$EXTENSIONS_SELECTION" >"$EXTENSIONS_SELECTION_STAMP" +fi + +rebuild_review_desktop_outputs "$MONOREPO_ROOT" "$REVIEW_PACKAGE" +if [[ -z "$PACKAGED_ROOT" ]]; then + node "$APP_DIR/scripts/copy-canvas.mjs" + export DEV_FAST_REVIEW_SERVER_ENTRY="$REVIEW_SERVER" + export DEV_FAST_REVIEW_TOOLING_ROOT="$MONOREPO_ROOT" +fi + +CODE_ARGS=( + --disable-telemetry + --skip-welcome + "--user-data-dir=$STATE_ROOT/user-data" + "--extensions-dir=$STATE_ROOT/extensions" +) +if [[ -n "${DEV_FAST_REVIEW_SHARED_DATA_DIR:-}" ]]; then + CODE_ARGS+=("--shared-data-dir=$DEV_FAST_REVIEW_SHARED_DATA_DIR") +fi +if [[ -n "${DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT:-}" ]]; then + CODE_ARGS+=( + "--remote-debugging-port=$DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT" + ) +fi +if [[ "${DEV_FAST_REVIEW_DISABLE_GPU:-0}" == "1" ]]; then + CODE_ARGS+=(--disable-gpu) +fi +if [[ "${DEV_FAST_REVIEW_FORCE_ACCESSIBILITY:-0}" == "1" ]]; then + # Keeps Chromium's renderer accessibility tree alive for the generic Linux + # AT-SPI Computer Use backend. It is deliberately opt-in outside DevBoxes. + CODE_ARGS+=(--force-renderer-accessibility) +fi + +if [[ -n "$PACKAGED_ROOT" ]]; then + unset DEV_FAST_REVIEW_TOOLING_ROOT + unset NODE_ENV VSCODE_DEV VSCODE_CLI +else + ( + cd "$CHECKOUT" + node build/lib/preLaunch.ts + ) + export NODE_ENV=development + export VSCODE_DEV=1 + export VSCODE_CLI=1 +fi +export ELECTRON_ENABLE_STACK_DUMPING=1 +export ELECTRON_ENABLE_LOGGING=1 +cd "$CHECKOUT" +exec "$CODE_BINARY" \ + --disable-extension=vscode.vscode-api-tests \ + "${CODE_ARGS[@]}" \ + . diff --git a/apps/whiteboard-desktop/scripts/run.test.mjs b/apps/review-desktop/scripts/run.test.mjs similarity index 76% rename from apps/whiteboard-desktop/scripts/run.test.mjs rename to apps/review-desktop/scripts/run.test.mjs index 7d4650ffa..10a469752 100644 --- a/apps/whiteboard-desktop/scripts/run.test.mjs +++ b/apps/review-desktop/scripts/run.test.mjs @@ -10,10 +10,10 @@ test("Review Desktop can opt into Chromium renderer accessibility", async () => "utf8", ); - assert.match(source, /DEV_FAST_WHITEBOARD_FORCE_ACCESSIBILITY/u); + assert.match(source, /DEV_FAST_REVIEW_FORCE_ACCESSIBILITY/u); assert.match(source, /--force-renderer-accessibility/u); assert.match( mainSource, - /DEV_FAST_WHITEBOARD_FORCE_ACCESSIBILITY[\s\S]*setAccessibilitySupportEnabled\(true\)/u, + /DEV_FAST_REVIEW_FORCE_ACCESSIBILITY[\s\S]*setAccessibilitySupportEnabled\(true\)/u, ); }); diff --git a/apps/whiteboard-desktop/scripts/runtime-bundler.test.mjs b/apps/review-desktop/scripts/runtime-bundler.test.mjs similarity index 98% rename from apps/whiteboard-desktop/scripts/runtime-bundler.test.mjs rename to apps/review-desktop/scripts/runtime-bundler.test.mjs index 598c9e226..20d9ba016 100644 --- a/apps/whiteboard-desktop/scripts/runtime-bundler.test.mjs +++ b/apps/review-desktop/scripts/runtime-bundler.test.mjs @@ -20,7 +20,7 @@ import { requiredPackagedArtifacts, runtimeRootForPackagedRoot, stageDiffrBinary, -} from "./stage-whiteboard-runtime.mjs"; +} from "./stage-review-runtime.mjs"; test("runtime closure rejects transitive esbuild packages and native binaries", async () => { const root = await mkdtemp(path.join(os.tmpdir(), "review-bundler-closure-")); @@ -141,7 +141,7 @@ test("final package verification requires the CLI and rechecks archives outside path.join(runtime, "tutorial/runtime-manifest.json"), JSON.stringify({ version: 1, - whiteboardFiles: ["review.mdx"], + reviewFiles: ["review.mdx"], requiredPaths: ["review.mdx"], }), ); diff --git a/apps/whiteboard-desktop/scripts/share-e2e.mjs b/apps/review-desktop/scripts/share-e2e.mjs similarity index 90% rename from apps/whiteboard-desktop/scripts/share-e2e.mjs rename to apps/review-desktop/scripts/share-e2e.mjs index b779b44b1..6c38a26ff 100644 --- a/apps/whiteboard-desktop/scripts/share-e2e.mjs +++ b/apps/review-desktop/scripts/share-e2e.mjs @@ -41,7 +41,7 @@ try { [ "exec", "tsx", - "packages/whiteboard/scripts/seed-share-fixture.ts", + "packages/review/scripts/seed-share-fixture.ts", root, ...(values.github ? ["--github"] : []), ...(values.lsp ? ["--lsp"] : []), @@ -58,7 +58,7 @@ await mkdir(profile, { recursive: true }); await writeFile( path.join(profile, "settings.json"), JSON.stringify({ - "whiteboard.experimental.softwareMap.enabled": true, + "review.experimental.softwareMap.enabled": true, "telemetry.telemetryLevel": "off", "workbench.startupEditor": "none", "security.workspace.trust.enabled": false, @@ -104,13 +104,13 @@ await new Promise((resolve) => server.close(resolve)); const env = { ...process.env, - DEV_WHITEBOARD_HOME: fixture.home, - WHITEBOARD_LSP_E2E_ROOT: root, - DEV_WHITEBOARD_EXTENSIONS: "none", - DEV_FAST_WHITEBOARD_SHARED_DATA_DIR: path.join(root, "shared-data"), - DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT: String(port), - DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED: "1", - DEV_FAST_WHITEBOARD_CLI_NO_DELEGATE: "1", + DEV_REVIEW_HOME: fixture.home, + REVIEW_LSP_E2E_ROOT: root, + DEV_REVIEW_EXTENSIONS: "none", + DEV_FAST_REVIEW_SHARED_DATA_DIR: path.join(root, "shared-data"), + DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT: String(port), + DEV_FAST_REVIEW_TELEMETRY_DISABLED: "1", + DEV_FAST_REVIEW_CLI_NO_DELEGATE: "1", }; const app = spawn("bash", [path.join(appRoot, "scripts/run.sh")], { @@ -167,10 +167,10 @@ try { assert.equal(discovery.appPid, app.pid, "isolated implementation process"); const api = async (route, body) => { - const response = await fetch(discovery.url + "/sessions-api" + route, { + const response = await fetch(discovery.url + "/reviews-api" + route, { method: body === undefined ? "GET" : "POST", headers: { - "x-whiteboard-token": discovery.token, + "x-review-token": discovery.token, "content-type": "application/json", }, body: body === undefined ? undefined : JSON.stringify(body), @@ -202,7 +202,7 @@ try { await page .getByText("Sharing pinned commits", { exact: true }) .waitFor({ timeout: 60000 }); - await api(`/${fixture.sessionId}/open`, {}); + await api(`/${fixture.reviewId}/open`, {}); await page .getByText("A portable review", { exact: true }) .waitFor({ timeout: 60000 }); @@ -273,7 +273,7 @@ try { }; const location = { - uri: `review-api-source://${fixture.sessionId}/answer.ts?version=${fixture.version}&side=head`, + uri: `review-api-source://${fixture.reviewId}/answer.ts?version=${fixture.version}&side=head`, line: 0, character: 18, }; @@ -301,18 +301,18 @@ try { } const source = await api( - `/${fixture.sessionId}/file?side=head&file=${encodeURIComponent(fixture.sourceFile)}`, + `/${fixture.reviewId}/file?side=head&file=${encodeURIComponent(fixture.sourceFile)}`, ); assert.ok(source.text.includes(fixture.sourceText)); - const summary = await api(`/${fixture.sessionId}?full=true`); + const summary = await api(`/${fixture.reviewId}?full=true`); assert.equal(summary.version, fixture.version); await writeFile( path.join(root, "report.json"), JSON.stringify( { root, - sessionId: fixture.sessionId, + reviewId: fixture.reviewId, checks: [ "actual Desktop canvas", "native pinned source", diff --git a/apps/review-desktop/scripts/skill-versions.test.mjs b/apps/review-desktop/scripts/skill-versions.test.mjs new file mode 100644 index 000000000..863a38298 --- /dev/null +++ b/apps/review-desktop/scripts/skill-versions.test.mjs @@ -0,0 +1,90 @@ +import assert from "node:assert/strict"; +import { + cp, + link, + mkdir, + mkdtemp, + readFile, + rm, + writeFile, +} from "node:fs/promises"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import test from "node:test"; +import { fileURLToPath } from "node:url"; + +import { stampReviewSkills } from "./stage-review-runtime.mjs"; + +const appRoot = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + "..", +); + +const sourceSkills = path.resolve( + appRoot, + "../../packages/review/skills", +); + +test("stamps all packaged skills with the Desktop release, preserving source hardlinks", async () => { + const root = await mkdtemp(path.join(tmpdir(), "review-stamp-skills-")); + + try { + const runtime = path.join(root, "runtime"); + await cp(sourceSkills, path.join(runtime, "skills"), { recursive: true }); + const source = path.join(root, "source.md"); + const generated = path.join(runtime, "skills/dev-review/SKILL.md"); + const original = await readFile(generated, "utf8"); + await writeFile(source, original); + await rm(generated); + await link(source, generated); + await stampReviewSkills(runtime); + + const { version } = JSON.parse( + await readFile(path.join(appRoot, "package.json"), "utf8"), + ); + + for (const name of ["dev-review", "trace-archaeology"]) { + const output = await readFile( + path.join(runtime, "skills", name, "SKILL.md"), + "utf8", + ); + + assert.ok(output.includes(`review-version: "${version}"`)); + assert.ok(output.includes('review-managed-by: "Review Desktop"')); + assert.ok(output.includes("Do not edit.")); + } + + assert.equal(await readFile(source, "utf8"), original); + await stampReviewSkills(runtime, "2.0.0-preview.1"); + assert.ok( + (await readFile(generated, "utf8")).includes( + 'review-version: "2.0.0-preview.1"', + ), + ); + } finally { + await rm(root, { recursive: true, force: true }); + } +}); + +test("refuses invalid release versions and skills without generated metadata", async () => { + const root = await mkdtemp(path.join(tmpdir(), "review-invalid-skill-")); + + try { + await assert.rejects( + stampReviewSkills(root, "not-a-version"), + /release version/, + ); + const skill = path.join(root, "skills/dev-review"); + await mkdir(skill, { recursive: true }); + await writeFile( + path.join(skill, "SKILL.md"), + "---\nname: dev-review\ndescription: test\n---\n", + ); + await assert.rejects( + stampReviewSkills(root, "1.0.0"), + /Missing generated skill metadata/, + ); + } finally { + await rm(root, { recursive: true, force: true }); + } +}); diff --git a/apps/whiteboard-desktop/scripts/smoke-error-telemetry.mjs b/apps/review-desktop/scripts/smoke-error-telemetry.mjs similarity index 96% rename from apps/whiteboard-desktop/scripts/smoke-error-telemetry.mjs rename to apps/review-desktop/scripts/smoke-error-telemetry.mjs index 413bbb954..89ff19374 100644 --- a/apps/whiteboard-desktop/scripts/smoke-error-telemetry.mjs +++ b/apps/review-desktop/scripts/smoke-error-telemetry.mjs @@ -24,7 +24,7 @@ * Silence must never read as success: the run fails if no report arrives at * all, which is what a broken loopback route or a dead reporter looks like. * - * Requires a built app (`pnpm --filter @dev.fast/whiteboard-desktop app:build`). + * Requires a built app (`pnpm --filter @dev.fast/review-desktop app:build`). * Not part of `pnpm test` — it launches the application. */ import { spawn } from "node:child_process"; @@ -107,7 +107,7 @@ function cases(home) { ]; } -/** Must match hashErrorMessage in packages/whiteboard/src/error-telemetry.ts. */ +/** Must match hashErrorMessage in packages/review/src/error-telemetry.ts. */ function digestOf(message) { return createHash("sha256").update(message, "utf8").digest("hex").slice(0, 16); } @@ -187,11 +187,11 @@ export async function smokeErrorTelemetry({ // Isolate completely: a shared review home would publish into the // developer's real store, and a shared state root hands the launch to // an already-running Review instead of booting one. - DEV_WHITEBOARD_HOME: path.join(root, "home"), - DEV_FAST_WHITEBOARD_DESKTOP_STATE_ROOT: stateRoot, + DEV_REVIEW_HOME: path.join(root, "home"), + DEV_FAST_REVIEW_DESKTOP_STATE_ROOT: stateRoot, // Print events instead of sending them to the vendor. - DEV_FAST_WHITEBOARD_TELEMETRY_DEBUG: "1", - DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT: String(debugPort), + DEV_FAST_REVIEW_TELEMETRY_DEBUG: "1", + DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT: String(debugPort), }, stdio: ["ignore", "pipe", "pipe"], }); diff --git a/apps/whiteboard-desktop/scripts/smoke-launch-packaged.mjs b/apps/review-desktop/scripts/smoke-launch-packaged.mjs similarity index 97% rename from apps/whiteboard-desktop/scripts/smoke-launch-packaged.mjs rename to apps/review-desktop/scripts/smoke-launch-packaged.mjs index 1dc11bc29..97b7895e5 100644 --- a/apps/whiteboard-desktop/scripts/smoke-launch-packaged.mjs +++ b/apps/review-desktop/scripts/smoke-launch-packaged.mjs @@ -27,7 +27,7 @@ import os from "node:os"; import path from "node:path"; import { parseArgs } from "node:util"; -import { assertNoBlockedWhiteboardRequests } from "./whiteboard-network-policy.mjs"; +import { assertNoBlockedReviewRequests } from "./review-network-policy.mjs"; const APP_DIR = path.resolve(import.meta.dirname, ".."); @@ -128,7 +128,7 @@ export async function smokeLaunch({ // A launch that finds a running instance hands its arguments over and exits 0 // without opening anything. The throwaway user-data-dir is what keeps this a // real boot rather than a silent no-op. - const env = { ...process.env, ELECTRON_ENABLE_LOGGING: "1", DEV_WHITEBOARD_HOME: path.join(userDataDir, "whiteboard-home"), DEV_WHITEBOARD_IMPORT_FROM: "none" }; + const env = { ...process.env, ELECTRON_ENABLE_LOGGING: "1", DEV_REVIEW_HOME: path.join(userDataDir, "review-home"), DEV_REVIEW_IMPORT_FROM: "none" }; delete env.ELECTRON_RUN_AS_NODE; const child = spawn(binary, [`--user-data-dir=${userDataDir}`, `--extensions-dir=${path.join(userDataDir, "extensions")}`], { @@ -158,7 +158,7 @@ export async function smokeLaunch({ while (Date.now() < deadline) { mainLog = await readMainLog(userDataDir); const startupOutput = `${output}\n${mainLog}`; - assertNoBlockedWhiteboardRequests( + assertNoBlockedReviewRequests( startupOutput.match(/https?:\/\/[^\s"'<>]+/g) ?? [], ); diff --git a/apps/whiteboard-desktop/scripts/smoke-linux-ui.mjs b/apps/review-desktop/scripts/smoke-linux-ui.mjs similarity index 86% rename from apps/whiteboard-desktop/scripts/smoke-linux-ui.mjs rename to apps/review-desktop/scripts/smoke-linux-ui.mjs index 19aef605f..aa2736d45 100644 --- a/apps/whiteboard-desktop/scripts/smoke-linux-ui.mjs +++ b/apps/review-desktop/scripts/smoke-linux-ui.mjs @@ -8,17 +8,17 @@ import { _electron as electron } from "playwright"; if (process.platform !== "linux") throw new Error("Run this check on Linux"); -const packagedRoot = path.resolve(process.argv[2] ?? "apps/whiteboard-desktop/VSCode-linux-x64"); +const packagedRoot = path.resolve(process.argv[2] ?? "apps/review-desktop/VSCode-linux-x64"); const { applicationName } = JSON.parse( await readFile(path.join(packagedRoot, "resources", "app", "product.json"), "utf8"), ); -const output = path.resolve(process.argv[3] ?? "apps/whiteboard-desktop/dist/linux-ui"); +const output = path.resolve(process.argv[3] ?? "apps/review-desktop/dist/linux-ui"); await mkdir(output, { recursive: true }); -for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["custom", "Whiteboard Light", 1.25]]) { +for (const [controls, theme, scale] of [["native", "Review Dark", 1], ["custom", "Review Light", 1.25]]) { const profile = await mkdtemp(path.join(os.tmpdir(), "review-linux-ui-")); await mkdir(path.join(profile, "User")); await writeFile(path.join(profile, "User/settings.json"), JSON.stringify({ @@ -29,7 +29,7 @@ for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["cust "window.confirmBeforeClose": "never", "update.mode": "none", })); - const env = { ...process.env, DEV_WHITEBOARD_HOME: path.join(profile, "whiteboard-home"), DEV_WHITEBOARD_IMPORT_FROM: "none" }; + const env = { ...process.env, DEV_REVIEW_HOME: path.join(profile, "review-home"), DEV_REVIEW_IMPORT_FROM: "none" }; delete env.ELECTRON_RUN_AS_NODE; delete env.VSCODE_DEV; delete env.VSCODE_CLI; @@ -42,7 +42,7 @@ for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["cust env, // Docker emulation cannot create Chromium namespaces. This opt-in is only // for local UI inspection; CI and the separate startup gate keep sandboxing. - chromiumSandbox: process.env.WHITEBOARD_TEST_DISABLE_SANDBOX !== "1", + chromiumSandbox: process.env.REVIEW_TEST_DISABLE_SANDBOX !== "1", timeout: 90_000, }); const page = await app.firstWindow({ timeout: 90_000 }); @@ -50,7 +50,7 @@ for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["cust const menu = page.getByRole("button", { name: "Review menu", exact: true }); await menu.waitFor({ state: "visible" }); await dismissStartupInvitations(page, menu); - await page.locator(".whiteboard-onboarding-headline").waitFor({ state: "visible", timeout: 90_000 }); + await page.locator(".review-onboarding-headline").waitFor({ state: "visible", timeout: 90_000 }); if (controls === "native") { assert.equal(await page.evaluate(() => navigator.windowControlsOverlay?.visible), true, "Native Linux window controls overlay is inactive"); @@ -60,7 +60,7 @@ for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["cust await page.getByRole("menuitem", { name: /^Settings/ }).waitFor({ state: "visible" }); await page.waitForFunction(() => document.activeElement?.closest(".monaco-menu")); await page.keyboard.press("Escape"); - await page.waitForFunction(() => document.querySelector(".whiteboard-application-menu")?.getAttribute("aria-expanded") === "false"); + await page.waitForFunction(() => document.querySelector(".review-application-menu")?.getAttribute("aria-expanded") === "false"); await menu.click(); for (const name of [/^Manage Extensions/, /^Check for Updates/, /^About Review/, /^Quit Review/]) { @@ -73,14 +73,14 @@ for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["cust await app.evaluate(({ BrowserWindow }) => BrowserWindow.getAllWindows()[0].setSize(700, 600)); // Electron's viewport resize can precede the workbench layout pass. await page.waitForFunction(() => { - const titlebar = document.querySelector(".whiteboard-titlebar-container"); + const titlebar = document.querySelector(".review-titlebar-container"); const left = titlebar?.querySelector(".titlebar-left")?.getBoundingClientRect(); const right = titlebar?.querySelector(".titlebar-right")?.getBoundingClientRect(); return window.innerWidth <= 700 && left && right && left.right <= right.left && Math.abs(right.right - window.innerWidth) <= 1; }).catch(async (error) => { - const bounds = await page.locator(".whiteboard-titlebar-container").evaluate(element => ({ + const bounds = await page.locator(".review-titlebar-container").evaluate(element => ({ viewportWidth: window.innerWidth, left: element.querySelector(".titlebar-left").getBoundingClientRect().toJSON(), right: element.querySelector(".titlebar-right").getBoundingClientRect().toJSON(), @@ -137,7 +137,7 @@ for (const [controls, theme, scale] of [["native", "Whiteboard Dark", 1], ["cust async function dismissStartupInvitations(page, menu) { // Invitations are optional startup UI, not a prerequisite for titlebar checks. await page.getByRole("button", { name: "Not now", exact: true }) - .or(page.locator(".whiteboard-onboarding-headline")).first() + .or(page.locator(".review-onboarding-headline")).first() .waitFor({ state: "visible", timeout: 90_000 }); for (let prompt = 0; prompt < 5; prompt++) { diff --git a/apps/whiteboard-desktop/scripts/smoke-telemetry-delivery.mjs b/apps/review-desktop/scripts/smoke-telemetry-delivery.mjs similarity index 93% rename from apps/whiteboard-desktop/scripts/smoke-telemetry-delivery.mjs rename to apps/review-desktop/scripts/smoke-telemetry-delivery.mjs index 7a4271c37..c950eb894 100644 --- a/apps/whiteboard-desktop/scripts/smoke-telemetry-delivery.mjs +++ b/apps/review-desktop/scripts/smoke-telemetry-delivery.mjs @@ -5,13 +5,13 @@ * node scripts/smoke-telemetry-delivery.mjs [--timeout-ms 120000] * * Why this is separate from smoke-error-telemetry.mjs. That one runs with - * DEV_FAST_WHITEBOARD_TELEMETRY_DEBUG=1, and the debug sink PRINTS events instead of + * DEV_FAST_REVIEW_TELEMETRY_DEBUG=1, and the debug sink PRINTS events instead of * sending them. So it proves everything up to the sink and nothing after it: a * report could be shaped perfectly and still never leave, or leave with a * different payload than the sink displayed. * * This one sends for real, to a local endpoint standing in for the vendor - * (PROGRESSIVE_WHITEBOARD_POSTHOG_HOST), and asserts on the exact bytes of the + * (PROGRESSIVE_REVIEW_POSTHOG_HOST), and asserts on the exact bytes of the * batch request. Nothing reaches the real project. * * What only this can catch: an event that the queue rejects as unserializable, @@ -89,7 +89,7 @@ export async function smokeTelemetryDelivery({ timeoutMs = 120_000 } = {}) { // characters. Over the limit the app fails to claim its instance and never // starts, which reads as "the server never became ready". const stateRoot = await mkdtemp("/tmp/rvw-"); - const whiteboardHome = path.join(root, "home"); + const reviewHome = path.join(root, "home"); const logPath = path.join(root, "app.log"); const debugPort = 9500 + Math.floor(process.pid % 300); const thrown = `ENOENT: no such file or directory, open '${home}/work/acme-repo/plan.md'`; @@ -113,14 +113,14 @@ export async function smokeTelemetryDelivery({ timeoutMs = 120_000 } = {}) { env: { ...process.env, FORCE_COLOR: "0", - DEV_WHITEBOARD_HOME: whiteboardHome, - DEV_FAST_WHITEBOARD_DESKTOP_STATE_ROOT: stateRoot, - DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT: String(debugPort), + DEV_REVIEW_HOME: reviewHome, + DEV_FAST_REVIEW_DESKTOP_STATE_ROOT: stateRoot, + DEV_FAST_REVIEW_REMOTE_DEBUGGING_PORT: String(debugPort), // Send for real, but to us. Note there is deliberately NO - // DEV_FAST_WHITEBOARD_TELEMETRY_DEBUG here: the sink would suppress the + // DEV_FAST_REVIEW_TELEMETRY_DEBUG here: the sink would suppress the // send and this smoke would prove nothing. - PROGRESSIVE_WHITEBOARD_POSTHOG_HOST: capture.origin, - PROGRESSIVE_WHITEBOARD_POSTHOG_KEY: "phc_smoke_local_only", + PROGRESSIVE_REVIEW_POSTHOG_HOST: capture.origin, + PROGRESSIVE_REVIEW_POSTHOG_KEY: "phc_smoke_local_only", // The opt-out rules treat a test environment as opted out, and this // script may well be run from one. NODE_ENV: "development", @@ -258,7 +258,7 @@ export async function smokeTelemetryDelivery({ timeoutMs = 120_000 } = {}) { // every launch, forever. Only OUR event is checked: the app emits other // telemetry throughout the run, and anything queued in the last few seconds // is simply waiting for the next flush, which is not a fault. - const queueDir = path.join(whiteboardHome, "telemetry", "events"); + const queueDir = path.join(reviewHome, "telemetry", "events"); const queued = await readdir(queueDir).catch(() => []); const stillQueued = []; diff --git a/apps/review-desktop/scripts/stage-review-runtime-docs.test.mjs b/apps/review-desktop/scripts/stage-review-runtime-docs.test.mjs new file mode 100644 index 000000000..5202b0a58 --- /dev/null +++ b/apps/review-desktop/scripts/stage-review-runtime-docs.test.mjs @@ -0,0 +1,127 @@ +import assert from "node:assert/strict"; +import { + access, + mkdir, + mkdtemp, + readFile, + readdir, + rm, + writeFile, +} from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { after, test } from "node:test"; +import { fileURLToPath } from "node:url"; + +import { stageReviewDocs } from "./stage-review-runtime.mjs"; + +const temporaryRoots = []; + +const repositoryRoot = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + "../../..", +); + +after(async () => { + await Promise.all( + temporaryRoots.map((root) => rm(root, { recursive: true, force: true })), + ); +}); + +async function temporaryRoot(prefix) { + const root = await mkdtemp(path.join(os.tmpdir(), prefix)); + temporaryRoots.push(root); + + return root; +} + +test("stages the complete Review documentation tree inside dev-review", async () => { + const root = await temporaryRoot("review-runtime-docs-"); + const runtimeRoot = path.join(root, "review-runtime"); + const skillRoot = path.join(runtimeRoot, "skills", "dev-review"); + const docsRoot = path.join(root, "source-docs"); + await mkdir(path.join(skillRoot, "docs"), { recursive: true }); + await mkdir(path.join(docsRoot, "assets"), { recursive: true }); + await writeFile(path.join(skillRoot, "SKILL.md"), "# dev-review\n"); + await writeFile(path.join(skillRoot, "docs", "stale.md"), "stale\n"); + await writeFile(path.join(docsRoot, "README.md"), "# Review docs\n"); + await writeFile(path.join(docsRoot, "guide.md"), "# Guide\n"); + await writeFile( + path.join(docsRoot, "assets", "image.png"), + Buffer.from([0, 1, 2, 3]), + ); + + const destination = await stageReviewDocs(runtimeRoot, docsRoot); + + assert.equal( + await readFile(path.join(destination, "README.md"), "utf8"), + "# Review docs\n", + ); + assert.equal( + await readFile(path.join(destination, "guide.md"), "utf8"), + "# Guide\n", + ); + assert.deepEqual( + await readFile(path.join(destination, "assets", "image.png")), + Buffer.from([0, 1, 2, 3]), + ); + await assert.rejects(readFile(path.join(destination, "stale.md")), /ENOENT/); +}); + +test("bundled Review documentation has no escaping or broken relative links", async () => { + const docsRoot = path.join(repositoryRoot, "docs"); + const markdownFiles = await listMarkdownFiles(docsRoot); + const missing = []; + + for (const file of markdownFiles) { + const source = await readFile(file, "utf8"); + const links = source.matchAll(/!?\[[^\]]*\]\(([^)]+)\)/g); + + for (const match of links) { + const target = match[1].trim(); + + if (target.startsWith("#") || /^[a-z][a-z0-9+.-]*:/i.test(target)) { + continue; + } + + const relativeTarget = target.split("#", 1)[0]; + const resolved = path.resolve(path.dirname(file), relativeTarget); + + if ( + resolved !== docsRoot && + !resolved.startsWith(`${docsRoot}${path.sep}`) + ) { + missing.push(`${path.relative(docsRoot, file)} -> ${target} (escapes)`); + continue; + } + + try { + await access(resolved); + } catch { + missing.push(`${path.relative(docsRoot, file)} -> ${target}`); + } + } + } + + assert.deepEqual(missing, []); +}); + +async function listMarkdownFiles(root) { + const files = []; + + const walk = async (directory) => { + const entries = await readdir(directory, { withFileTypes: true }); + + for (const entry of entries) { + const absolute = path.join(directory, entry.name); + + if (entry.isDirectory()) await walk(absolute); + else if (entry.isFile() && entry.name.endsWith(".md")) + files.push(absolute); + } + }; + + await walk(root); + + return files; +} diff --git a/apps/review-desktop/scripts/stage-review-runtime.mjs b/apps/review-desktop/scripts/stage-review-runtime.mjs new file mode 100644 index 000000000..6f0a97b67 --- /dev/null +++ b/apps/review-desktop/scripts/stage-review-runtime.mjs @@ -0,0 +1,559 @@ +import { execFile } from "node:child_process"; +import { + access, + chmod, + copyFile, + cp, + mkdir, + open, + readFile, + readdir, + realpath, + rm, + stat, + writeFile, +} from "node:fs/promises"; +import { createRequire } from "node:module"; +import path from "node:path"; +import { fileURLToPath, pathToFileURL } from "node:url"; +import { promisify } from "node:util"; + +import { valid as validVersion } from "semver"; + +const execFileAsync = promisify(execFile); + +const appDirectory = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + "..", +); + +const monorepoRoot = path.resolve(appDirectory, "../.."); + +/** + * The installed application must not reach back into the build checkout, so the + * Review server ships as a self-contained production dependency closure rather + * than as a single bundled file: the runtime intentionally depends on native + * binaries and external Node libraries. The canvas is built and copied separately. + */ +export const RUNTIME_DIRECTORY_NAME = "review-runtime"; + +export const RUNTIME_SERVER_ENTRY = "dist/server/desktop-host.js"; + +export const RUNTIME_CLI_ENTRY = "dist/cli.js"; + +export const REQUIRED_RUNTIME_ENTRIES = [ + "package.json", + "LICENSE", + "THIRD_PARTY_NOTICES.md", + RUNTIME_SERVER_ENTRY, + RUNTIME_CLI_ENTRY, + "bin/diffr", + "skills/dev-review/SKILL.md", + "skills/dev-review/docs/README.md", + "skills/trace-archaeology/SKILL.md", + "tutorial/runtime-manifest.json", + "node_modules", +]; + +export function runtimeRootForPackagedRoot(packagedRoot) { + const resolved = path.resolve(packagedRoot); + + if (resolved === path.parse(resolved).root) { + throw new Error("The packaged Review root cannot be a filesystem root."); + } + + const packagedAppRoot = resolved.endsWith(".app") + ? path.join(resolved, "Contents/Resources/app") + : path.join(resolved, "resources/app"); + + return path.join(packagedAppRoot, RUNTIME_DIRECTORY_NAME); +} + +export function requiredPackagedArtifacts(packagedRoot) { + const runtimeRoot = runtimeRootForPackagedRoot(packagedRoot); + const packagedAppRoot = path.dirname(runtimeRoot); + + const entries = [ + "out/vs/review/review.desktop.main.js", + "out/vs/review/review.desktop.main.css", + "out/vs/review/electron-utility/reviewDesktopHostMain.js", + "out/vs/review/canvas/canvas-loader.js", + ...REQUIRED_RUNTIME_ENTRIES.map((entry) => + path.join(RUNTIME_DIRECTORY_NAME, entry), + ), + ]; + + if (!path.resolve(packagedRoot).endsWith(".app")) { + entries.push("extensions/vscodevim.vim/package.json"); + } + + return entries.map((entry) => path.join(packagedAppRoot, entry)); +} + +export async function assertPackagedArtifacts(packagedRoot) { + await assertNoRuntimeBundler(packagedRoot); + + for (const artifact of requiredPackagedArtifacts(packagedRoot)) { + try { + await access(artifact); + } catch { + throw new Error(`Review Desktop package is missing ${artifact}.`); + } + } +} + +export async function stageReviewRuntime(packagedRoot) { + const runtimeRoot = runtimeRootForPackagedRoot(packagedRoot); + const packagedAppRoot = path.dirname(runtimeRoot); + + if (!(await isDirectory(packagedAppRoot))) { + throw new Error( + `Refusing to stage the Review runtime outside a packaged app: ${packagedAppRoot}`, + ); + } + + await rm(runtimeRoot, { recursive: true, force: true }); + await execFileAsync( + "pnpm", + [ + "--config.allow-unused-patches=true", + // This workspace pins `nodeLinker: hoisted`, under which a plain deploy + // links workspace dependencies back to the checkout and never resolves + // their own dependency graphs. Injecting copies them in with their deps. + "--config.inject-workspace-packages=true", + "--filter", + "@dev.fast/review", + "--prod", + "deploy", + "--legacy", + // Keeps the root prepare/Husky lifecycle out of packaging. + "--ignore-scripts", + runtimeRoot, + ], + { cwd: monorepoRoot, maxBuffer: 64 * 1024 * 1024 }, + ); + + await stageReviewDocs(runtimeRoot); + await stageDiffrBinary(runtimeRoot); + await stampReviewSkills(runtimeRoot); + await makeTreeOwnerWritable(path.join(runtimeRoot, "tutorial", "git-stub")); + await assertRuntimeClosure(runtimeRoot); + + return runtimeRoot; +} + +/** Stamp only deployed copies, before signing; source skills remain editable. */ +export async function stampReviewSkills(runtimeRoot, version) { + const releaseVersion = + version ?? + JSON.parse(await readFile(path.join(appDirectory, "package.json"), "utf8")) + .version; + + if (!validVersion(releaseVersion)) { + throw new Error( + "A Review Desktop release version is required to stamp skills.", + ); + } + + const skillsRoot = path.join(runtimeRoot, "skills"); + + for (const entry of await readdir(skillsRoot, { withFileTypes: true })) { + if (!entry.isDirectory()) continue; + const skillPath = path.join(skillsRoot, entry.name, "SKILL.md"); + const source = await readFile(skillPath, "utf8"); + const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---/.exec(source); + + if ( + !frontmatter || + !/^ review-version: "[^"\n]+"$/m.test(frontmatter[1]) + ) { + throw new Error(`Missing generated skill metadata: ${skillPath}`); + } + + const stamped = frontmatter[0].replace( + /^ review-version: "[^"\n]+"$/m, + ` review-version: ${JSON.stringify(releaseVersion)}`, + ); + + // pnpm deploy may hardlink files from its store. Never modify that inode. + await rm(skillPath); + await writeFile(skillPath, stamped + source.slice(frontmatter[0].length)); + } +} + +export async function stageReviewDocs( + runtimeRoot, + sourceDocsRoot = path.join(monorepoRoot, "docs"), +) { + const skillRoot = path.join(runtimeRoot, "skills", "dev-review"); + + if (!(await isDirectory(skillRoot))) { + throw new Error( + `Cannot stage Review documentation without the dev-review skill: ${skillRoot}`, + ); + } + + if (!(await isDirectory(sourceDocsRoot))) { + throw new Error( + `Review documentation source is missing: ${sourceDocsRoot}`, + ); + } + + const destination = path.join(skillRoot, "docs"); + await rm(destination, { recursive: true, force: true }); + await cp(sourceDocsRoot, destination, { recursive: true }); + await assertMatchingFileTrees(sourceDocsRoot, destination); + + return destination; +} + +export async function stageDiffrBinary( + runtimeRoot, + source = path.join(monorepoRoot, "packages", "review", "bin", "diffr"), +) { + if (!(await stat(source).catch(() => null))?.isFile()) { + throw new Error( + `Missing ${source}. Run pnpm --filter @dev.fast/review ensure:diffr before packaging.`, + ); + } + + const require = createRequire( + path.join(monorepoRoot, "packages/review/package.json"), + ); + + const packageRoot = path.dirname( + require.resolve("@dev.fast/diffr/package.json"), + ); + + await execFileAsync(process.execPath, [ + path.join(packageRoot, "bin/fetch.mjs"), + "--check", + "--into", + path.dirname(source), + ]); + + const destination = path.join(runtimeRoot, "bin", "diffr"); + await mkdir(path.dirname(destination), { recursive: true }); + await copyFile(source, destination); + await chmod(destination, 0o755); +} + +async function assertMatchingFileTrees(sourceRoot, destinationRoot) { + const [sourceFiles, destinationFiles] = await Promise.all([ + listRelativeFiles(sourceRoot), + listRelativeFiles(destinationRoot), + ]); + + if (sourceFiles.join("\n") !== destinationFiles.join("\n")) { + throw new Error( + "The staged Review documentation file list does not match.", + ); + } + + for (const relative of sourceFiles) { + const [source, destination] = await Promise.all([ + readFile(path.join(sourceRoot, relative)), + readFile(path.join(destinationRoot, relative)), + ]); + + if (!source.equals(destination)) { + throw new Error( + `The staged Review documentation differs at ${relative}.`, + ); + } + } +} + +async function listRelativeFiles(root) { + const files = []; + + const walk = async (directory) => { + const entries = await readdir(directory, { withFileTypes: true }); + entries.sort((a, b) => a.name.localeCompare(b.name)); + + for (const entry of entries) { + const absolute = path.join(directory, entry.name); + + if (entry.isDirectory()) { + await walk(absolute); + } else if (entry.isFile()) { + files.push(path.relative(root, absolute)); + } else { + throw new Error( + `Review documentation contains an unsupported entry: ${absolute}`, + ); + } + } + }; + + await walk(root); + + return files; +} + +async function makeTreeOwnerWritable(directory) { + for (const entry of await readdir(directory, { withFileTypes: true })) { + const absolute = path.join(directory, entry.name); + + if (entry.isDirectory()) { + await makeTreeOwnerWritable(absolute); + continue; + } + + if (!entry.isFile()) continue; + + const current = await stat(absolute); + + if ((current.mode & 0o200) === 0) { + await chmod(absolute, current.mode | 0o200); + } + } +} + +export async function assertRuntimeClosure(runtimeRoot) { + for (const entry of REQUIRED_RUNTIME_ENTRIES) { + const target = path.join(runtimeRoot, entry); + + try { + await access(target); + } catch { + throw new Error(`The staged Review runtime is missing ${entry}.`); + } + } + + const tutorialRoot = path.join(runtimeRoot, "tutorial"); + const tutorialManifest = await readTutorialRuntimeManifest(tutorialRoot); + + for (const entry of tutorialManifest.requiredPaths) { + try { + await access(path.join(tutorialRoot, entry)); + } catch { + throw new Error( + `The staged Review runtime is missing tutorial/${entry}.`, + ); + } + } + + await assertRuntimeContents(runtimeRoot); +} + +export async function readTutorialRuntimeManifest(tutorialRoot) { + const value = JSON.parse( + await readFile(path.join(tutorialRoot, "runtime-manifest.json"), "utf8"), + ); + + const validEntries = (entries) => + Array.isArray(entries) && + entries.length > 0 && + entries.every(isSafeManifestPath); + + if ( + value?.version !== 1 || + !validEntries(value.reviewFiles) || + !validEntries(value.requiredPaths) || + value.reviewFiles.some((entry) => !value.requiredPaths.includes(entry)) + ) { + throw new Error("Tutorial runtime manifest is invalid."); + } + + return { + version: 1, + reviewFiles: [...new Set(value.reviewFiles)], + requiredPaths: [...new Set(value.requiredPaths)], + }; +} + +/** A manifest entry that names a file inside the tutorial tree. */ +function isSafeManifestPath(entry) { + // Only a JSON string equals its own String() rendering by identity. + return ( + String(entry) === entry && + entry.length > 0 && + !path.isAbsolute(entry) && + !entry.split(/[\\/]/u).includes("..") + ); +} + +/** Final package verification includes files outside the staged runtime, such + * as extension dependencies and ASAR archives, after all package mutations. */ +export async function assertNoRuntimeBundler(runtimeRoot) { + await inspectRuntimeTree(runtimeRoot, false); +} + +/** Validate the staged dependency closure in one traversal. */ +export async function assertRuntimeContents(runtimeRoot) { + await inspectRuntimeTree(runtimeRoot, true); +} + +async function inspectRuntimeTree(root, checkCheckoutReferences) { + const runtimeRoot = await realpath(root); + const offenders = []; + + const visit = async (directory) => { + for (const entry of await readdir(directory, { withFileTypes: true })) { + const absolute = path.join(directory, entry.name); + + if (entry.name === "esbuild" || entry.name === "esbuild.exe") { + throw new Error( + `The Review runtime must not ship esbuild: ${path.relative(runtimeRoot, absolute)}`, + ); + } + + if (entry.isSymbolicLink()) { + if (checkCheckoutReferences) { + const real = await realpathOrNull(absolute); + + if (!real) { + offenders.push( + `${path.relative(runtimeRoot, absolute)} (broken link)`, + ); + } else if ( + real !== runtimeRoot && + !real.startsWith(runtimeRoot + path.sep) + ) { + offenders.push( + `${path.relative(runtimeRoot, absolute)} -> ${real} (escapes runtime)`, + ); + } + } + + continue; + } + + if (entry.isDirectory()) { + await visit(absolute); + continue; + } + + if (!entry.isFile()) continue; + + if (entry.name.endsWith(".asar")) { + await assertNoArchivedBundler(absolute); + continue; + } + + const isManifest = entry.name === "package.json"; + + // Declarations and source maps can embed checkout paths just as emitted + // JavaScript can. Read manifests once for both closure checks. + const checkContents = + checkCheckoutReferences && + (isManifest || + /\.[cm]?js\.map$/.test(entry.name) || + (/\.(?:[cm]?js|d\.[cm]?ts)$/.test(entry.name) && + absolute.includes(`${path.sep}dist${path.sep}`))); + + if (!isManifest && !checkContents) continue; + const contents = await readFile(absolute, "utf8"); + + if (isManifest) { + const manifest = JSON.parse(contents); + + if ( + manifest.name === "esbuild" || + manifest.name?.startsWith("@esbuild/") + ) + throw new Error( + `The Review runtime must not ship ${manifest.name}: ${path.relative(runtimeRoot, absolute)}`, + ); + } + + if (checkContents && contents.includes(monorepoRoot)) { + offenders.push( + `${path.relative(runtimeRoot, absolute)} (build checkout path)`, + ); + } + } + }; + + await visit(runtimeRoot); + + if (offenders.length > 0) { + throw new Error( + `The staged Review runtime is not relocatable:\n ${offenders.join("\n ")}`, + ); + } +} + +// ASAR headers are two Chromium pickles: an 8-byte size pickle followed by +// a string pickle containing the JSON tree. Inspect the directory without +// extracting the app or requiring an archive tool in the installed runtime. +async function assertNoArchivedBundler(archive) { + const file = await open(archive, "r"); + + try { + const prefix = Buffer.alloc(16); + + if ((await file.read(prefix, 0, 16, 0)).bytesRead !== 16) + throw new Error(`Invalid ASAR header: ${archive}`); + const headerBytes = prefix.readUInt32LE(4); + const jsonBytes = prefix.readUInt32LE(12); + + if (jsonBytes > headerBytes - 8 || headerBytes > 64 * 1024 * 1024) + throw new Error(`Invalid ASAR header size: ${archive}`); + const contents = Buffer.alloc(jsonBytes); + + if ((await file.read(contents, 0, jsonBytes, 16)).bytesRead !== jsonBytes) + throw new Error(`Truncated ASAR header: ${archive}`); + + const visit = (node, parent = "") => { + for (const [name, child] of Object.entries(node.files ?? {})) { + const relative = `${parent}/${name}`; + + if (name === "esbuild" || name === "esbuild.exe" || name === "@esbuild") + throw new Error( + `The Review runtime must not ship esbuild: ${archive}:${relative}`, + ); + visit(child, relative); + } + }; + + visit(JSON.parse(contents.toString("utf8"))); + } finally { + await file.close(); + } +} + +async function realpathOrNull(target) { + try { + return await realpath(target); + } catch { + return null; + } +} + +async function isDirectory(candidate) { + try { + return (await stat(candidate)).isDirectory(); + } catch { + return false; + } +} + +if ( + process.argv[1] && + import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href +) { + const args = process.argv.slice(2); + const verifyOnly = args[0] === "--verify"; + const packagedRootIndex = verifyOnly ? 1 : 0; + + if ( + args.length !== packagedRootIndex + 2 || + args[packagedRootIndex] !== "--packaged-root" + ) { + throw new Error( + "usage: stage-review-runtime.mjs [--verify] --packaged-root ", + ); + } + + const packagedRoot = args[packagedRootIndex + 1]; + + if (verifyOnly) { + await assertPackagedArtifacts(packagedRoot); + process.stdout.write(`Verified the Review package at ${packagedRoot}\n`); + } else { + const runtimeRoot = await stageReviewRuntime(packagedRoot); + process.stdout.write(`Staged the Review runtime at ${runtimeRoot}\n`); + } +} diff --git a/apps/whiteboard-desktop/scripts/stamp-release-channel.mjs b/apps/review-desktop/scripts/stamp-release-channel.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/stamp-release-channel.mjs rename to apps/review-desktop/scripts/stamp-release-channel.mjs diff --git a/apps/whiteboard-desktop/scripts/stamp-release-channel.test.mjs b/apps/review-desktop/scripts/stamp-release-channel.test.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/stamp-release-channel.test.mjs rename to apps/review-desktop/scripts/stamp-release-channel.test.mjs diff --git a/apps/review-desktop/scripts/titlebar-navigation-contract.test.mjs b/apps/review-desktop/scripts/titlebar-navigation-contract.test.mjs new file mode 100644 index 000000000..5812d4b4a --- /dev/null +++ b/apps/review-desktop/scripts/titlebar-navigation-contract.test.mjs @@ -0,0 +1,72 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; + +const reviewTitlebar = readFileSync( + new URL( + "../code-oss/src/vs/review/browser/parts/reviewTitlebarPart.ts", + import.meta.url, + ), + "utf8", +); + +const reviewConfiguration = readFileSync( + new URL( + "../code-oss/src/vs/review/common/reviewConfigurationDefaults.ts", + import.meta.url, + ), + "utf8", +); + +const reviewMain = readFileSync( + new URL( + "../code-oss/src/vs/review/electron-browser/review.main.ts", + import.meta.url, + ), + "utf8", +); + +const commandCenterControl = readFileSync( + new URL( + "../code-oss/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts", + import.meta.url, + ), + "utf8", +); + +test("Review mounts VS Code's native back and forward controls", () => { + assert.match( + reviewMain, + /new ReviewConfigurationService\([\s\S]*?\{ defaultOverrides: reviewAgentsWindowDefaultOverrides \}\)/, + "Review's navigation defaults must survive Review configuration initialization", + ); + + assert.match( + reviewTitlebar, + /createInstance\(\s*CommandCenterControl,/, + "Review should mount VS Code's native titlebar control", + ); + assert.doesNotMatch( + reviewTitlebar, + /workbench\.action\.navigate(?:Back|Forward)/, + "Review must not recreate or manually dispatch native navigation actions", + ); + assert.doesNotMatch( + reviewTitlebar, + /review-title\b/, + "the titlebar carries no product label; the branding lives in the macOS application menu", + ); +}); + +test("the native control can omit the command launcher without hiding navigation", () => { + const centerMenuItem = commandCenterControl.match( + /MenuRegistry\.appendMenuItem\(MenuId\.CommandCenter, \{[\s\S]*?submenu: MenuId\.CommandCenterCenter,[\s\S]*?\n\}\);/, + )?.[0]; + + assert.match( + centerMenuItem ?? "", + /when: ContextKeyExpr\.has\('config\.window\.commandCenter'\)/, + "expected the native command-center menu item gated on config.window.commandCenter", + ); + assert.match(reviewConfiguration, /'window\.commandCenter': false,/); +}); diff --git a/apps/whiteboard-desktop/scripts/validate-release-artifacts.mjs b/apps/review-desktop/scripts/validate-release-artifacts.mjs similarity index 93% rename from apps/whiteboard-desktop/scripts/validate-release-artifacts.mjs rename to apps/review-desktop/scripts/validate-release-artifacts.mjs index 7557a2555..39834ad35 100644 --- a/apps/whiteboard-desktop/scripts/validate-release-artifacts.mjs +++ b/apps/review-desktop/scripts/validate-release-artifacts.mjs @@ -18,7 +18,7 @@ import { assertReleaseChannel, releaseIdentityFor, } from "./release-channel.mjs"; -import { assertPackagedArtifacts } from "./stage-whiteboard-runtime.mjs"; +import { assertPackagedArtifacts } from "./stage-review-runtime.mjs"; const APP_DIR = path.resolve(import.meta.dirname, ".."); @@ -35,7 +35,7 @@ export function buildManifest({ return { version, commit, - url: `${UPDATE_URL}/releases/${version}/darwin-arm64/Whiteboard-darwin-arm64-${version}.zip`, + url: `${UPDATE_URL}/releases/${version}/darwin-arm64/Review-darwin-arm64-${version}.zip`, name: version, pub_date: now.toISOString(), timestamp: now.getTime(), @@ -136,8 +136,8 @@ async function main() { `${sourceProduct.nameShort}.app`, ); - const zip = path.join(artifactDir, `Whiteboard-darwin-arm64-${version}.zip`); - const dmg = path.join(artifactDir, `Whiteboard-darwin-arm64-${version}.dmg`); + const zip = path.join(artifactDir, `Review-darwin-arm64-${version}.zip`); + const dmg = path.join(artifactDir, `Review-darwin-arm64-${version}.dmg`); await assertPackagedArtifacts(app); assertUpdaterCompatibleApp(app); diff --git a/apps/whiteboard-desktop/scripts/validate-release-artifacts.test.mjs b/apps/review-desktop/scripts/validate-release-artifacts.test.mjs similarity index 97% rename from apps/whiteboard-desktop/scripts/validate-release-artifacts.test.mjs rename to apps/review-desktop/scripts/validate-release-artifacts.test.mjs index 670bffc53..ba40a870a 100644 --- a/apps/whiteboard-desktop/scripts/validate-release-artifacts.test.mjs +++ b/apps/review-desktop/scripts/validate-release-artifacts.test.mjs @@ -40,7 +40,7 @@ test("buildManifest emits the schema the update Worker serves", () => { assert.deepEqual(manifest, { version: "1.2.3", commit: "abc123", - url: "https://update.dev.fast/releases/1.2.3/darwin-arm64/Whiteboard-darwin-arm64-1.2.3.zip", + url: "https://update.dev.fast/releases/1.2.3/darwin-arm64/Review-darwin-arm64-1.2.3.zip", name: "1.2.3", pub_date: "2026-07-29T00:00:00.000Z", timestamp: now.getTime(), diff --git a/apps/whiteboard-desktop/scripts/vendor-integrity.test.mjs b/apps/review-desktop/scripts/vendor-integrity.test.mjs similarity index 96% rename from apps/whiteboard-desktop/scripts/vendor-integrity.test.mjs rename to apps/review-desktop/scripts/vendor-integrity.test.mjs index c89987037..d7e9713f9 100644 --- a/apps/whiteboard-desktop/scripts/vendor-integrity.test.mjs +++ b/apps/review-desktop/scripts/vendor-integrity.test.mjs @@ -13,7 +13,7 @@ const vendorTimeExclusions = [ "extensions/vscode-colorize-tests", ]; -const whiteboardUnusedInstallTargets = [ +const reviewUnusedInstallTargets = [ "remote", "remote/web", "test/automation", @@ -56,7 +56,7 @@ test("extension compilation does not target vendor-time exclusions", async () => test("postinstall does not install unused remote and upstream test packages", () => { const unusedTargets = dirs.filter((directory) => - whiteboardUnusedInstallTargets.includes(directory), + reviewUnusedInstallTargets.includes(directory), ); assert.deepEqual(unusedTargets, []); diff --git a/apps/whiteboard-desktop/scripts/vscode-security-backports.test.mjs b/apps/review-desktop/scripts/vscode-security-backports.test.mjs similarity index 100% rename from apps/whiteboard-desktop/scripts/vscode-security-backports.test.mjs rename to apps/review-desktop/scripts/vscode-security-backports.test.mjs diff --git a/apps/whiteboard-desktop/scripts/watermark-branding.test.mjs b/apps/review-desktop/scripts/watermark-branding.test.mjs similarity index 84% rename from apps/whiteboard-desktop/scripts/watermark-branding.test.mjs rename to apps/review-desktop/scripts/watermark-branding.test.mjs index 1aeec5005..e0aa3c4bd 100644 --- a/apps/whiteboard-desktop/scripts/watermark-branding.test.mjs +++ b/apps/review-desktop/scripts/watermark-branding.test.mjs @@ -4,7 +4,7 @@ import test from "node:test"; const canonicalMark = await readFile( new URL( - "../../../packages/whiteboard/app/icons/dev-fast.icon/Assets/review-slashes-1024.svg", + "../../../packages/review/app/icons/dev-fast.icon/Assets/review-slashes-1024.svg", import.meta.url, ), "utf8", @@ -15,7 +15,7 @@ const themedAssets = await Promise.all( theme, source: await readFile( new URL( - `../code-oss/src/vs/whiteboard/browser/media/whiteboard-letterpress-${theme}.svg`, + `../code-oss/src/vs/review/browser/media/review-letterpress-${theme}.svg`, import.meta.url, ), "utf8", diff --git a/apps/whiteboard-desktop/tsconfig.test.json b/apps/review-desktop/tsconfig.test.json similarity index 100% rename from apps/whiteboard-desktop/tsconfig.test.json rename to apps/review-desktop/tsconfig.test.json diff --git a/apps/whiteboard-desktop/code-oss/build/next/index.ts b/apps/whiteboard-desktop/code-oss/build/next/index.ts deleted file mode 100644 index 06c4c080d..000000000 --- a/apps/whiteboard-desktop/code-oss/build/next/index.ts +++ /dev/null @@ -1,1045 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as esbuild from 'esbuild'; -import * as fs from 'fs'; -import { createRequire } from 'module'; -import * as path from 'path'; -import { promisify } from 'util'; - -import glob from 'glob'; -import gulpWatch from '../lib/watch/index.ts'; -import { nlsPlugin, createNLSCollector, finalizeNLS, postProcessNLS } from './nls-plugin.ts'; -import { convertPrivateFields, adjustSourceMap, type ConvertPrivateFieldsResult } from './private-to-property.ts'; -import { getVersion } from '../lib/getVersion.ts'; -import { getGitCommitDate } from '../lib/date.ts'; -import product from '../../product.json' with { type: 'json' }; -import packageJson from '../../package.json' with { type: 'json' }; -import { useEsbuildTranspile } from '../buildConfig.ts'; -import { isWebExtension, type IScannedBuiltinExtension } from '../lib/extensions.ts'; - -const globAsync = promisify(glob); -const nodeRequire = createRequire(import.meta.url); - -// ============================================================================ -// Configuration -// ============================================================================ - -const REPO_ROOT = path.dirname(path.dirname(import.meta.dirname)); -const commit = getVersion(REPO_ROOT); -const quality = (product as { quality?: string }).quality; -const version = (quality && quality !== 'stable') ? `${packageJson.version}-${quality}` : packageJson.version; - -// CLI: transpile [--watch] | bundle [--minify] [--nls] [--out ] -const command = process.argv[2]; // 'transpile' or 'bundle' - -function getArgValue(name: string): string | undefined { - const index = process.argv.indexOf(name); - if (index !== -1 && index + 1 < process.argv.length) { - return process.argv[index + 1]; - } - return undefined; -} - -const options = { - watch: process.argv.includes('--watch'), - minify: process.argv.includes('--minify'), - nls: process.argv.includes('--nls'), - manglePrivates: process.argv.includes('--mangle-privates'), - excludeTests: process.argv.includes('--exclude-tests'), - out: getArgValue('--out'), - sourceMapBaseUrl: getArgValue('--source-map-base-url'), -}; - -const SRC_DIR = 'src'; -const OUT_DIR = 'out'; -const OUT_VSCODE_DIR = 'out-vscode'; - -// UTF-8 BOM - added to test files with 'utf8' in the path (matches gulp build behavior) -const UTF8_BOM = Buffer.from([0xef, 0xbb, 0xbf]); - -// ============================================================================ -// Entry Points (from build/buildfile.ts) -// ============================================================================ - -// Extension host bundles are excluded from private field mangling because they -// expose API surface to extensions where encapsulation matters. -const extensionHostEntryPoints = [ - 'vs/workbench/api/node/extensionHostProcess', - 'vs/workbench/api/worker/extensionHostWorkerMain', -]; - -function isExtensionHostBundle(filePath: string): boolean { - const normalized = filePath.replaceAll('\\', '/'); - return extensionHostEntryPoints.some(ep => normalized.endsWith(`${ep}.js`)); -} - -// Workers - shared between targets -const workerEntryPoints = [ - 'vs/editor/common/services/editorWebWorkerMain', - 'vs/workbench/api/worker/extensionHostWorkerMain', - 'vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain', - 'vs/workbench/services/search/worker/localFileSearchMain', - 'vs/workbench/contrib/output/common/outputLinkComputerMain', - 'vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain', -]; - -// Desktop-only workers (use electron-browser) -const desktopWorkerEntryPoints = [ - 'vs/platform/profiling/electron-browser/profileAnalysisWorkerMain', -]; - -// Desktop workbench and code entry points -const desktopEntryPoints = [ - 'vs/whiteboard/whiteboard.desktop.main', - 'vs/whiteboard/electron-utility/whiteboardDesktopHostMain', - 'vs/workbench/contrib/debug/node/telemetryApp', - 'vs/platform/files/node/watcher/watcherMain', - 'vs/platform/terminal/node/ptyHostMain', - 'vs/platform/agentHost/node/agentHostMain', - 'vs/platform/agentHost/node/diffWorkerMain', - 'vs/workbench/api/node/extensionHostProcess', -]; - -const codeEntryPoints = [ - 'vs/code/node/cliProcessMain', - 'vs/code/electron-utility/sharedProcess/sharedProcessMain', - 'vs/code/electron-browser/workbench/workbench', -]; - -const bootstrapEntryPoints = [ - 'main', - 'cli', - 'bootstrap-fork', -]; - -const entryPoints = [ - ...workerEntryPoints, - ...desktopWorkerEntryPoints, - ...desktopEntryPoints, - ...codeEntryPoints, -]; - -const cssBundleEntryPoints = new Set([ - 'vs/whiteboard/whiteboard.desktop.main', - 'vs/code/electron-browser/workbench/workbench', -]); - -// ============================================================================ -// Resource Patterns (files to copy, not transpile/bundle) -// ============================================================================ - -// Common resources needed by all targets -const commonResourcePatterns = [ - // Tree-sitter queries - 'vs/editor/common/languages/highlights/*.scm', - 'vs/editor/common/languages/injections/*.scm', - - // SVGs referenced from CSS (needed for transpile/dev builds where CSS is copied as-is) - 'vs/workbench/browser/media/code-icon.svg', - 'vs/workbench/browser/parts/editor/media/letterpress*.svg' -]; - -// Resources for desktop target -const desktopResourcePatterns = [ - ...commonResourcePatterns, - - // HTML - 'vs/code/electron-browser/workbench/workbench.html', - 'vs/code/electron-browser/workbench/workbench-dev.html', - 'vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html', - 'vs/workbench/contrib/webview/browser/pre/*.html', - - // Webview pre scripts - 'vs/workbench/contrib/webview/browser/pre/*.js', - - // Shell scripts - 'vs/base/node/*.sh', - 'vs/workbench/contrib/terminal/common/scripts/*.sh', - 'vs/workbench/contrib/terminal/common/scripts/*.ps1', - 'vs/workbench/contrib/terminal/common/scripts/*.psm1', - 'vs/workbench/contrib/terminal/common/scripts/*.fish', - 'vs/workbench/contrib/terminal/common/scripts/*.zsh', - 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.psd1', - 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.psm1', - 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.dll', - 'vs/workbench/contrib/terminal/common/scripts/psreadline/*.ps1xml', - 'vs/workbench/contrib/terminal/common/scripts/psreadline/net6plus/*.dll', - 'vs/workbench/contrib/terminal/common/scripts/psreadline/netstd/*.dll', - 'vs/workbench/contrib/externalTerminal/**/*.scpt', - - // Media - audio - 'vs/platform/accessibilitySignal/browser/media/*.mp3', - - // Media - images - 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.svg', - 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.png', - 'vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', - 'vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}', - 'vs/workbench/services/extensionManagement/common/media/*.svg', - 'vs/workbench/services/extensionManagement/common/media/*.png', - 'vs/workbench/browser/parts/editor/media/*.png', - 'vs/workbench/contrib/debug/browser/media/*.png', - -]; - -// ============================================================================ -// Utilities -// ============================================================================ - -async function cleanDir(dir: string): Promise { - const fullPath = path.join(REPO_ROOT, dir); - console.log(`[clean] ${dir}`); - await fs.promises.rm(fullPath, { recursive: true, force: true }); - await fs.promises.mkdir(fullPath, { recursive: true }); -} - -/** - * Scan for built-in extensions in the given directory. - * Returns an array of extension entries for the builtinExtensionsScannerService. - */ -function scanBuiltinExtensions(extensionsRoot: string): Array { - const scannedExtensions: Array = []; - const extensionsPath = path.join(REPO_ROOT, extensionsRoot); - - if (!fs.existsSync(extensionsPath)) { - return scannedExtensions; - } - - for (const extensionFolder of fs.readdirSync(extensionsPath)) { - const packageJSONPath = path.join(extensionsPath, extensionFolder, 'package.json'); - if (!fs.existsSync(packageJSONPath)) { - continue; - } - try { - const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf8')); - if (!isWebExtension(packageJSON)) { - continue; - } - const children = fs.readdirSync(path.join(extensionsPath, extensionFolder)); - const packageNLSPath = children.filter(child => child === 'package.nls.json')[0]; - const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(extensionsPath, extensionFolder, packageNLSPath), 'utf8')) : undefined; - const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0]; - const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; - - scannedExtensions.push({ - extensionPath: extensionFolder, - packageJSON, - packageNLS, - readmePath: readme ? path.join(extensionFolder, readme) : undefined, - changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined, - }); - } catch (e) { - // Skip invalid extensions - } - } - - return scannedExtensions; -} - -/** - * Get the date from the out directory date file, or return the git commit date. - */ -function readISODate(outDir: string): string { - try { - return fs.readFileSync(path.join(REPO_ROOT, outDir, 'date'), 'utf8'); - } catch { - return getGitCommitDate(); - } -} - -/** - * Only used to make encoding tests happy. The source files don't have a BOM but the - * tests expect one... so we add it here. - */ -function needsBomAdded(filePath: string): boolean { - return /([\/\\])test\1.*utf8/.test(filePath); -} - -async function copyFile(srcPath: string, destPath: string): Promise { - await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); - - if (needsBomAdded(srcPath)) { - const content = await fs.promises.readFile(srcPath); - if (content[0] !== 0xef || content[1] !== 0xbb || content[2] !== 0xbf) { - await fs.promises.writeFile(destPath, Buffer.concat([UTF8_BOM, content])); - return; - } - } - await fs.promises.copyFile(srcPath, destPath); -} - -/** - * Standalone TypeScript files that need to be compiled separately (not bundled). - * These run in special contexts (e.g., Electron preload) where bundling isn't appropriate. - * Only needed for desktop target. - */ -const desktopStandaloneFiles = [ - 'vs/base/parts/sandbox/electron-browser/preload.ts', - 'vs/base/parts/sandbox/electron-browser/preload-aux.ts', - 'vs/platform/browserView/electron-browser/preload-browserView.ts', -]; - -async function compileStandaloneFiles(outDir: string, doMinify: boolean): Promise { - console.log(`[standalone] Compiling ${desktopStandaloneFiles.length} standalone files...`); - - const banner = `/*!-------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/`; - - await Promise.all(desktopStandaloneFiles.map(async (file) => { - const entryPath = path.join(REPO_ROOT, SRC_DIR, file); - const outPath = path.join(REPO_ROOT, outDir, file.replace(/\.ts$/, '.js')); - - await esbuild.build({ - entryPoints: [entryPath], - outfile: outPath, - bundle: false, // Don't bundle - these are standalone scripts - format: 'cjs', // CommonJS for Electron preload - platform: 'node', - target: ['es2024'], - sourcemap: 'linked', - sourcesContent: false, - minify: doMinify, - banner: { js: banner }, - logLevel: 'warning', - }); - })); - - console.log(`[standalone] Done`); -} - -/** - * Copy ALL non-TypeScript files from src/ to the output directory. - * This matches the old gulp build behavior where `gulp.src('src/**')` streams - * every file and non-TS files bypass the compiler via tsFilter.restore. - * Used for development/transpile builds only - production bundles use - * copyResources() with curated per-target patterns instead. - */ -async function copyAllNonTsFiles(outDir: string, excludeTests: boolean): Promise { - console.log(`[resources] Copying all non-TS files to ${outDir}...`); - - const ignorePatterns = [ - // Exclude .ts files but keep .d.ts files (they're needed at runtime for type references) - '**/*.ts', - ]; - if (excludeTests) { - ignorePatterns.push('**/test/**'); - } - - const files = await globAsync('**/*', { - cwd: path.join(REPO_ROOT, SRC_DIR), - nodir: true, - ignore: ignorePatterns, - }); - - // Re-include .d.ts files that were excluded by the *.ts ignore - const dtsFiles = await globAsync('**/*.d.ts', { - cwd: path.join(REPO_ROOT, SRC_DIR), - ignore: excludeTests ? ['**/test/**'] : [], - }); - - const allFiles = [...new Set([...files, ...dtsFiles])]; - - await Promise.all(allFiles.map(file => { - const srcPath = path.join(REPO_ROOT, SRC_DIR, file); - const destPath = path.join(REPO_ROOT, outDir, file); - return copyFile(srcPath, destPath); - })); - - console.log(`[resources] Copied ${allFiles.length} files`); -} - -/** - * Copy curated resource files for production bundles. - * Uses desktop resource patterns from the old build. Only called by bundle(). - */ -async function copyResources(outDir: string): Promise { - console.log(`[resources] Copying to ${outDir}...`); - let copied = 0; - - const ignorePatterns = ['**/test/**', '**/*-dev.html']; - - for (const pattern of desktopResourcePatterns) { - const files = await globAsync(pattern, { - cwd: path.join(REPO_ROOT, SRC_DIR), - ignore: ignorePatterns, - }); - - for (const file of files) { - const srcPath = path.join(REPO_ROOT, SRC_DIR, file); - const destPath = path.join(REPO_ROOT, outDir, file); - - await copyFile(srcPath, destPath); - copied++; - } - } - - console.log(`[resources] Copied ${copied} files`); -} - -// ============================================================================ -// Plugins -// ============================================================================ - -function inlineMinimistPlugin(): esbuild.Plugin { - return { - name: 'inline-minimist', - setup(build) { - build.onResolve({ filter: /^minimist$/ }, () => ({ - path: path.join(REPO_ROOT, 'node_modules/minimist/index.js'), - external: false, - })); - }, - }; -} - -function inlineReviewBrowserDependenciesPlugin(): esbuild.Plugin { - return { - name: 'inline-review-browser-dependencies', - setup(build) { - build.onResolve({ filter: /^(?:eventsource-parser|zod(?:\/.*)?)$/ }, args => ({ - path: nodeRequire.resolve(args.path, { paths: [args.resolveDir] }), - external: false, - })); - }, - }; -} - -function cssExternalPlugin(): esbuild.Plugin { - // Mark CSS imports as external so they stay as import statements - // The CSS files are copied separately and loaded by the browser at runtime - return { - name: 'css-external', - setup(build) { - build.onResolve({ filter: /\.css$/ }, (args) => ({ - path: args.path, - external: true, - })); - }, - }; -} - -/** - * esbuild plugin that transforms source files to inject build-time configuration. - * This runs during onLoad so the transformation happens before esbuild processes the content, - * ensuring placeholders like `/*BUILD->INSERT_PRODUCT_CONFIGURATION* /` are replaced - * before esbuild strips them as non-legal comments. - */ -function fileContentMapperPlugin(outDir: string): esbuild.Plugin { - // Cache the replacement strings (computed once) - let productConfigReplacement: string | undefined; - let builtinExtensionsReplacement: string | undefined; - - return { - name: 'file-content-mapper', - setup(build) { - build.onLoad({ filter: /\.ts$/ }, async (args) => { - // Skip .d.ts files - if (args.path.endsWith('.d.ts')) { - return undefined; - } - - let contents = await fs.promises.readFile(args.path, 'utf-8'); - let modified = false; - - // Inject product configuration - if (contents.includes('/*BUILD->INSERT_PRODUCT_CONFIGURATION*/')) { - if (productConfigReplacement === undefined) { - const productConfiguration = JSON.stringify({ - ...product, - version, - commit, - date: readISODate(outDir) - }); - // Remove the outer braces since the placeholder is inside an object literal - productConfigReplacement = productConfiguration.substring(1, productConfiguration.length - 1); - } - contents = contents.replace('/*BUILD->INSERT_PRODUCT_CONFIGURATION*/', () => productConfigReplacement!); - modified = true; - } - - // Inject built-in extensions list - if (contents.includes('/*BUILD->INSERT_BUILTIN_EXTENSIONS*/')) { - if (builtinExtensionsReplacement === undefined) { - const builtinExtensions = JSON.stringify(scanBuiltinExtensions('.build/extensions')); - // Remove the outer brackets since the placeholder is inside an array literal - builtinExtensionsReplacement = builtinExtensions.substring(1, builtinExtensions.length - 1); - } - contents = contents.replace('/*BUILD->INSERT_BUILTIN_EXTENSIONS*/', () => builtinExtensionsReplacement!); - modified = true; - } - - if (modified) { - return { contents, loader: 'ts' }; - } - - // No modifications, let esbuild handle normally - return undefined; - }); - }, - }; -} - -// ============================================================================ -// Transpile (Goal 1: TS → JS using esbuild.transform for maximum speed) -// ============================================================================ - -// Shared transform options for single-file transpilation -const transformOptions: esbuild.TransformOptions = { - loader: 'ts', - format: 'esm', - target: 'es2024', - sourcemap: 'inline', - sourcesContent: false, - tsconfigRaw: JSON.stringify({ - compilerOptions: { - experimentalDecorators: true, - useDefineForClassFields: false - } - }), -}; - -async function transpileFile(srcPath: string, destPath: string): Promise { - const source = await fs.promises.readFile(srcPath, 'utf-8'); - const result = await esbuild.transform(source, { - ...transformOptions, - sourcefile: srcPath, - }); - - await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); - - const adjustedCode = adjustEsmUrl(result.code); - await fs.promises.writeFile(destPath, adjustedCode); -} - -/* - * This enables https://github.com/microsoft/esm-url-bundler-plugins to work on both original and transpiled sources. - * Usees regex to only replace `.ts?esm` inside quoted URL strings, avoiding false positives. - * - * E.g.: - * - esmModuleLocationBundler: () => new URL("../../../api/worker/extensionHostWorkerMain.ts?esm", import.meta.url) - * + esmModuleLocationBundler: () => new URL("../../../api/worker/extensionHostWorkerMain.js?esm", import.meta.url) - */ -function adjustEsmUrl(code: string): string { - const fixedCode = code.replace(/\.ts(\?esm['"])/g, '.js$1'); - return fixedCode; -} - -async function transpile(outDir: string, excludeTests: boolean): Promise { - // Find all .ts files - const ignorePatterns = ['**/*.d.ts']; - if (excludeTests) { - ignorePatterns.push('**/test/**'); - } - - const files = await globAsync('**/*.ts', { - cwd: path.join(REPO_ROOT, SRC_DIR), - ignore: ignorePatterns, - }); - - console.log(`[transpile] Found ${files.length} files`); - - // Transpile all files in parallel using esbuild.transform (fastest approach) - await Promise.all(files.map(file => { - const srcPath = path.join(REPO_ROOT, SRC_DIR, file); - const destPath = path.join(REPO_ROOT, outDir, file.replace(/\.ts$/, '.js')); - return transpileFile(srcPath, destPath); - })); -} - -// ============================================================================ -// Bundle (Goal 2: JS → bundled JS) -// ============================================================================ - -async function bundle(outDir: string, doMinify: boolean, doNls: boolean, doManglePrivates: boolean, sourceMapBaseUrl?: string): Promise { - await cleanDir(outDir); - - // Write build date file (used by packaging to embed in product.json). - // Reuse the date from out-build/date if it exists (written by the gulp - // writeISODate task) so that all parallel bundle outputs share the same - // timestamp - this is required for deterministic builds (e.g. macOS Universal). - const outDirPath = path.join(REPO_ROOT, outDir); - await fs.promises.mkdir(outDirPath, { recursive: true }); - let buildDate: string; - try { - buildDate = await fs.promises.readFile(path.join(REPO_ROOT, 'out-build', 'date'), 'utf8'); - } catch { - buildDate = getGitCommitDate(); - } - await fs.promises.writeFile(path.join(outDirPath, 'date'), buildDate, 'utf8'); - - console.log(`[bundle] ${SRC_DIR} → ${outDir}${doMinify ? ' (minify)' : ''}${doNls ? ' (nls)' : ''}${doManglePrivates ? ' (mangle-privates)' : ''}`); - const t1 = Date.now(); - - // Read TSLib for banner - const tslibPath = path.join(REPO_ROOT, 'node_modules/tslib/tslib.es6.js'); - const tslib = await fs.promises.readFile(tslibPath, 'utf-8'); - const banner = { - js: `/*!-------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ -${tslib}`, - css: `/*!-------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/`, - }; - - // Shared TypeScript options for bundling directly from source - const tsconfigRaw = JSON.stringify({ - compilerOptions: { - experimentalDecorators: true, - useDefineForClassFields: false - } - }); - - // Create shared NLS collector (only used if doNls is true) - const nlsCollector = createNLSCollector(); - const preserveEnglish = false; // Production mode: replace messages with null - - // Collect all build results (with write: false) - const buildResults: { outPath: string; result: esbuild.BuildResult }[] = []; - - // Create the file content mapper plugin (injects product config, builtin extensions) - const contentMapperPlugin = fileContentMapperPlugin(outDir); - - // Bundle each entry point directly from TypeScript source - await Promise.all(entryPoints.map(async (entryPoint) => { - const entryPath = path.join(REPO_ROOT, SRC_DIR, `${entryPoint}.ts`); - const outPath = path.join(REPO_ROOT, outDir, `${entryPoint}.js`); - - // Use CSS external plugin for entry points that don't need bundled CSS - const plugins: esbuild.Plugin[] = cssBundleEntryPoints.has(entryPoint) ? [] : [cssExternalPlugin()]; - if (entryPoint === 'vs/whiteboard/whiteboard.desktop.main') { - plugins.push(inlineReviewBrowserDependenciesPlugin()); - } - // Add content mapper plugin to inject product config and builtin extensions - plugins.push(contentMapperPlugin); - if (doNls) { - plugins.unshift(nlsPlugin({ - baseDir: path.join(REPO_ROOT, SRC_DIR), - collector: nlsCollector, - })); - } - - // For entry points that bundle CSS, we need to use outdir instead of outfile - // because esbuild can't produce multiple output files (JS + CSS) with outfile - const needsCssBundling = cssBundleEntryPoints.has(entryPoint); - - const buildOptions: esbuild.BuildOptions = { - entryPoints: needsCssBundling - ? [{ in: entryPath, out: entryPoint }] - : [entryPath], - ...(needsCssBundling - ? { outdir: path.join(REPO_ROOT, outDir) } - : { outfile: outPath }), - bundle: true, - format: 'esm', - platform: 'neutral', - target: ['es2024'], - packages: 'external', - sourcemap: 'linked', - sourcesContent: true, - minify: doMinify, - treeShaking: true, - banner, - loader: { - '.ttf': 'file', - '.svg': 'file', - '.png': 'file', - '.sh': 'file', - }, - assetNames: 'media/[name]', - plugins, - write: false, // Don't write yet, we need to post-process - logLevel: 'warning', - logOverride: { - 'unsupported-require-call': 'silent', - }, - tsconfigRaw, - }; - - const result = await esbuild.build(buildOptions); - - buildResults.push({ outPath, result }); - })); - - // Bundle bootstrap files (with minimist inlined) directly from TypeScript source - for (const entry of bootstrapEntryPoints) { - const entryPath = path.join(REPO_ROOT, SRC_DIR, `${entry}.ts`); - if (!fs.existsSync(entryPath)) { - console.log(`[bundle] Skipping ${entry} (not found)`); - continue; - } - - const outPath = path.join(REPO_ROOT, outDir, `${entry}.js`); - - const bootstrapPlugins: esbuild.Plugin[] = [inlineMinimistPlugin(), contentMapperPlugin]; - if (doNls) { - bootstrapPlugins.unshift(nlsPlugin({ - baseDir: path.join(REPO_ROOT, SRC_DIR), - collector: nlsCollector, - })); - } - - const result = await esbuild.build({ - entryPoints: [entryPath], - outfile: outPath, - bundle: true, - format: 'esm', - platform: 'node', - target: ['es2024'], - packages: 'external', - sourcemap: 'linked', - sourcesContent: true, - minify: doMinify, - treeShaking: true, - banner, - plugins: bootstrapPlugins, - write: false, // Don't write yet, we need to post-process - logLevel: 'warning', - logOverride: { - 'unsupported-require-call': 'silent', - }, - tsconfigRaw, - }); - - buildResults.push({ outPath, result }); - } - - // Finalize NLS: sort entries, assign indices, write metadata files - let indexMap = new Map(); - if (doNls) { - // Also write NLS files to out-build for backwards compatibility with test runner - const nlsResult = await finalizeNLS( - nlsCollector, - path.join(REPO_ROOT, outDir), - [path.join(REPO_ROOT, 'out-build')] - ); - indexMap = nlsResult.indexMap; - } - - // Post-process and write all output files - let bundled = 0; - const mangleStats: { file: string; result: ConvertPrivateFieldsResult }[] = []; - // Map from JS file path to pre-mangle content + edits, for source map adjustment - const mangleEdits = new Map(); - // Map from JS file path to pre-NLS content + edits, for source map adjustment - const nlsEdits = new Map(); - // Defer .map files until all .js files are processed, because esbuild may - // emit the .map file in a different build result than the .js file (e.g. - // code-split chunks), and we need the NLS/mangle edits from the .js pass - // to be available when adjusting the .map. - const deferredMaps: { path: string; text: string; contents: Uint8Array }[] = []; - for (const { result } of buildResults) { - if (!result.outputFiles) { - continue; - } - - for (const file of result.outputFiles) { - await fs.promises.mkdir(path.dirname(file.path), { recursive: true }); - - if (file.path.endsWith('.js') || file.path.endsWith('.css')) { - let content = file.text; - - // Convert native #private fields to regular properties BEFORE NLS - // post-processing, so that the edit offsets align with esbuild's - // source map coordinate system (both reference the raw esbuild output). - // Skip extension host bundles - they expose API surface to extensions - // where true encapsulation matters more than the perf gain. - if (file.path.endsWith('.js') && doManglePrivates && !isExtensionHostBundle(file.path)) { - const preMangleCode = content; - const mangleResult = convertPrivateFields(content, file.path); - content = mangleResult.code; - if (mangleResult.editCount > 0) { - mangleStats.push({ file: path.relative(path.join(REPO_ROOT, outDir), file.path), result: mangleResult }); - mangleEdits.set(file.path, { preMangleCode, edits: mangleResult.edits }); - } - } - - // Apply NLS post-processing if enabled (JS only) - if (file.path.endsWith('.js') && doNls && indexMap.size > 0) { - const preNLSCode = content; - const nlsResult = postProcessNLS(content, indexMap, preserveEnglish); - content = nlsResult.code; - if (nlsResult.edits.length > 0) { - nlsEdits.set(file.path, { preNLSCode, edits: nlsResult.edits }); - } - } - - // Rewrite sourceMappingURL to CDN URL if configured - if (sourceMapBaseUrl) { - const relativePath = path.relative(path.join(REPO_ROOT, outDir), file.path); - content = content.replace( - /\/\/# sourceMappingURL=.+$/m, - `//# sourceMappingURL=${sourceMapBaseUrl}/${relativePath}.map` - ); - content = content.replace( - /\/\*# sourceMappingURL=.+\*\/$/m, - `/*# sourceMappingURL=${sourceMapBaseUrl}/${relativePath}.map*/` - ); - } - - await fs.promises.writeFile(file.path, content); - } else if (file.path.endsWith('.map')) { - // Defer .map processing until all .js files have been handled - deferredMaps.push({ path: file.path, text: file.text, contents: file.contents }); - } else { - // Write other files (assets, etc.) as-is - await fs.promises.writeFile(file.path, file.contents); - } - } - bundled++; - } - - // Second pass: process deferred .map files now that all mangle/NLS edits - // have been collected from .js processing above. - for (const mapFile of deferredMaps) { - const jsPath = mapFile.path.replace(/\.map$/, ''); - const mangle = mangleEdits.get(jsPath); - const nls = nlsEdits.get(jsPath); - - if (mangle || nls) { - let mapJson = JSON.parse(mapFile.text); - if (mangle) { - mapJson = adjustSourceMap(mapJson, mangle.preMangleCode, mangle.edits); - } - if (nls) { - mapJson = adjustSourceMap(mapJson, nls.preNLSCode, nls.edits); - } - await fs.promises.writeFile(mapFile.path, JSON.stringify(mapJson)); - } else { - await fs.promises.writeFile(mapFile.path, mapFile.contents); - } - } - - // Syntax-check JS files that were post-processed (mangle-privates, NLS). - // These steps do raw string surgery on bundled JS so a bug could silently - // produce syntactically broken output. Catch it here at build time. - // Uses esbuild.transform() as a parser since the bundles are ESM. - const postProcessedFiles = new Set([...mangleEdits.keys(), ...nlsEdits.keys()]); - if (postProcessedFiles.size > 0) { - const errors = (await Promise.all([...postProcessedFiles].map(async jsPath => { - try { - const src = await fs.promises.readFile(jsPath, 'utf-8'); - await esbuild.transform(src, { loader: 'js', format: 'esm' }); - return undefined; - } catch (e: unknown) { - const rel = path.relative(path.join(REPO_ROOT, outDir), jsPath); - const message = e instanceof Error ? e.message : String(e); - return { rel, message }; - } - }))).filter(error => error !== undefined).sort((a, b) => a.rel.localeCompare(b.rel)); - if (errors.length > 0) { - throw new Error(`[bundle] Syntax errors in post-processed JS files:\n${errors.map(e => `${e.rel}: ${e.message}`).join('\n')}`); - } - console.log(`[bundle] Syntax check passed for ${postProcessedFiles.size} post-processed JS files`); - } - - // Log mangle-privates stats - if (doManglePrivates && mangleStats.length > 0) { - let totalClasses = 0, totalFields = 0, totalEdits = 0, totalElapsed = 0; - for (const { file, result } of mangleStats) { - console.log(`[mangle-privates] ${file}: ${result.classCount} classes, ${result.fieldCount} fields, ${result.editCount} edits, ${result.elapsed}ms`); - totalClasses += result.classCount; - totalFields += result.fieldCount; - totalEdits += result.editCount; - totalElapsed += result.elapsed; - } - console.log(`[mangle-privates] Total: ${totalClasses} classes, ${totalFields} fields, ${totalEdits} edits, ${totalElapsed}ms`); - } - - // Copy resources (curated per-target patterns for production) - await copyResources(outDir); - - // Compile standalone TypeScript files (like Electron preload scripts) that cannot be bundled - await compileStandaloneFiles(outDir, doMinify); - - console.log(`[bundle] Done in ${Date.now() - t1}ms (${bundled} bundles)`); -} - -// ============================================================================ -// Watch Mode -// ============================================================================ - -async function watch(): Promise { - if (!useEsbuildTranspile) { - console.log('Starting transpilation...'); - console.log('Finished transpilation with 0 errors after 0 ms'); - console.log('[watch] esbuild transpile disabled (useEsbuildTranspile=false). Keeping process alive as no-op.'); - await new Promise(() => { }); // keep alive - return; - } - - console.log('Starting transpilation...'); - - const outDir = OUT_DIR; - - // Initial setup - await cleanDir(outDir); - console.log(`[transpile] ${SRC_DIR} → ${outDir}`); - - // Initial full build - const t1 = Date.now(); - try { - await transpile(outDir, false); - await copyAllNonTsFiles(outDir, false); - console.log(`Finished transpilation with 0 errors after ${Date.now() - t1} ms`); - } catch (err) { - console.error('[watch] Initial build failed:', err); - console.log(`Finished transpilation with 1 errors after ${Date.now() - t1} ms`); - // Continue watching anyway - } - - let pendingTsFiles: Set = new Set(); - let pendingCopyFiles: Set = new Set(); - - const processChanges = async () => { - console.log('Starting transpilation...'); - const t1 = Date.now(); - const tsFiles = [...pendingTsFiles]; - const filesToCopy = [...pendingCopyFiles]; - pendingTsFiles = new Set(); - pendingCopyFiles = new Set(); - - try { - // Transform changed TypeScript files in parallel - if (tsFiles.length > 0) { - console.log(`[watch] Transpiling ${tsFiles.length} file(s)...`); - await Promise.all(tsFiles.map(srcPath => { - const relativePath = path.relative(path.join(REPO_ROOT, SRC_DIR), srcPath); - const destPath = path.join(REPO_ROOT, outDir, relativePath.replace(/\.ts$/, '.js')); - return transpileFile(srcPath, destPath); - })); - } - - // Copy changed resource files in parallel - if (filesToCopy.length > 0) { - await Promise.all(filesToCopy.map(async (srcPath) => { - const relativePath = path.relative(path.join(REPO_ROOT, SRC_DIR), srcPath); - const destPath = path.join(REPO_ROOT, outDir, relativePath); - await fs.promises.mkdir(path.dirname(destPath), { recursive: true }); - await fs.promises.copyFile(srcPath, destPath); - console.log(`[watch] Copied ${relativePath}`); - })); - } - - if (tsFiles.length > 0 || filesToCopy.length > 0) { - console.log(`Finished transpilation with 0 errors after ${Date.now() - t1} ms`); - } - } catch (err) { - console.error('[watch] Rebuild failed:', err); - console.log(`Finished transpilation with 1 errors after ${Date.now() - t1} ms`); - // Continue watching - } - }; - - // Watch src directory using existing gulp-watch based watcher - let debounceTimer: ReturnType | undefined; - const srcDir = path.join(REPO_ROOT, SRC_DIR); - const watchStream = gulpWatch('src/**', { base: srcDir, readDelay: 200 }); - - watchStream.on('data', (file: { path: string }) => { - if (file.path.endsWith('.ts') && !file.path.endsWith('.d.ts')) { - pendingTsFiles.add(file.path); - } else { - // Copy any non-TS file (matches old gulp build's `src/**` behavior) - pendingCopyFiles.add(file.path); - } - - if (pendingTsFiles.size > 0 || pendingCopyFiles.size > 0) { - clearTimeout(debounceTimer); - debounceTimer = setTimeout(processChanges, 200); - } - }); - - console.log('[watch] Watching src/**/*.{ts,css,...} (Ctrl+C to stop)'); - - // Keep process alive - process.on('SIGINT', () => { - console.log('\n[watch] Stopping...'); - watchStream.end(); - process.exit(0); - }); -} - -// ============================================================================ -// Main -// ============================================================================ - -function printUsage(): void { - console.log(`Usage: npx tsx build/next/index.ts [options] - -Commands: - transpile Transpile TypeScript to JavaScript (single-file, fast) - bundle Bundle entry points into optimized bundles - -Options for 'transpile': - --watch Watch for changes and rebuild incrementally - --out Output directory (default: out) - --exclude-tests Exclude test files from transpilation - -Options for 'bundle': - --minify Minify the output bundles - --nls Process NLS (localization) strings - --mangle-privates Convert native #private fields to regular properties - --out Output directory (default: out-vscode) - --source-map-base-url Rewrite sourceMappingURL to CDN URL - -Examples: - npx tsx build/next/index.ts transpile - npx tsx build/next/index.ts transpile --watch - npx tsx build/next/index.ts transpile --out out-build - npx tsx build/next/index.ts transpile --out out-build --exclude-tests - npx tsx build/next/index.ts bundle - npx tsx build/next/index.ts bundle --minify --nls - npx tsx build/next/index.ts bundle --nls --out out-vscode-min -`); -} - -async function main(): Promise { - const t1 = Date.now(); - - try { - switch (command) { - case 'transpile': - if (options.watch) { - await watch(); - } else { - const outDir = options.out ?? OUT_DIR; - await cleanDir(outDir); - - // Write build date file (used by packaging to embed in product.json) - const outDirPath = path.join(REPO_ROOT, outDir); - await fs.promises.mkdir(outDirPath, { recursive: true }); - await fs.promises.writeFile(path.join(outDirPath, 'date'), getGitCommitDate(), 'utf8'); - - console.log(`[transpile] ${SRC_DIR} → ${outDir}${options.excludeTests ? ' (excluding tests)' : ''}`); - const t1 = Date.now(); - await transpile(outDir, options.excludeTests); - await copyAllNonTsFiles(outDir, options.excludeTests); - console.log(`[transpile] Done in ${Date.now() - t1}ms`); - } - break; - - case 'bundle': - await bundle(options.out ?? OUT_VSCODE_DIR, options.minify, options.nls, options.manglePrivates, options.sourceMapBaseUrl); - break; - - default: - printUsage(); - process.exit(command ? 1 : 0); - } - - if (!options.watch) { - console.log(`\n✓ Total: ${Date.now() - t1}ms`); - } - } catch (err) { - console.error('Build failed:', err); - process.exit(1); - } -} - -main(); diff --git a/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/package.json b/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/package.json deleted file mode 100644 index af8d04007..000000000 --- a/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "whiteboard-themes", - "displayName": "Review Themes", - "description": "Themes for /dev/fast Whiteboard.", - "categories": [ - "Themes" - ], - "version": "0.0.1", - "publisher": "dev-fast", - "license": "MIT", - "engines": { - "vscode": "*" - }, - "contributes": { - "themes": [ - { - "label": "Whiteboard Dark", - "uiTheme": "vs-dark", - "path": "./themes/whiteboard-dark.json" - }, - { - "label": "Whiteboard Light", - "uiTheme": "vs", - "path": "./themes/whiteboard-light.json" - } - ] - } -} diff --git a/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/themes/whiteboard-dark.json b/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/themes/whiteboard-dark.json deleted file mode 100644 index 0ef77adbf..000000000 --- a/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/themes/whiteboard-dark.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - // Whiteboard Dark: the Whiteboard syntax palette over the stock Dark+ include. - // Every scope the included theme colors is listed below, so none of its colors reaches the screen; - // the include only supplies grammar coverage. Roles: keyword, type, function, ink, string, number, - // operator, comment, inserted, deleted. Regenerated from the Whiteboard System — Syntax themes board. - "$schema": "vscode://schemas/color-theme", - "name": "Whiteboard Dark", - "include": "./../../theme-defaults/themes/dark_plus.json", - "semanticHighlighting": true, - "tokenColors": [ - { - "name": "Whiteboard: comment", - "scope": [ - "comment", - "punctuation.definition.comment" - ], - "settings": { - "foreground": "#778090", - "fontStyle": "italic" - } - }, - { - "name": "Whiteboard: keyword and storage", - "scope": [ - "keyword", - "keyword.control", - "storage", - "storage.type", - "storage.modifier", - "keyword.operator.noexcept", - "keyword.operator.new", - "keyword.operator.expression", - "keyword.operator.cast", - "keyword.operator.sizeof", - "keyword.operator.alignof", - "keyword.operator.typeid", - "keyword.operator.alignas", - "keyword.operator.instanceof", - "keyword.operator.logical.python", - "keyword.operator.wordlike", - "source.cpp keyword.operator.new", - "source.cpp keyword.operator.delete", - "keyword.operator.delete", - "keyword.other.using", - "keyword.other.directive.using", - "keyword.other.operator", - "entity.name.operator", - "variable.language", - "meta.preprocessor", - "entity.name.function.preprocessor", - "keyword.operator.or.regexp", - "keyword.control.anchor.regexp", - "meta.diff.header", - "header" - ], - "settings": { - "foreground": "#5B7CFF" - } - }, - { - "name": "Whiteboard: type, class, tag, attribute and selector", - "scope": [ - "entity.name.type", - "support.type", - "support.class", - "entity.other.inherited-class", - "entity.name.namespace", - "entity.other.attribute", - "entity.name.scope-resolution", - "entity.name.class", - "meta.type.cast.expr", - "meta.type.new.expr", - "support.constant.math", - "support.constant.dom", - "support.constant.json", - "punctuation.separator.namespace.ruby", - "storage.type.numeric.go", - "storage.type.byte.go", - "storage.type.boolean.go", - "storage.type.string.go", - "storage.type.uintptr.go", - "storage.type.error.go", - "storage.type.rune.go", - "storage.type.cs", - "storage.type.generic.cs", - "storage.type.modifier.cs", - "storage.type.variable.cs", - "storage.type.annotation.java", - "storage.type.generic.java", - "storage.type.java", - "storage.type.object.array.java", - "storage.type.primitive.array.java", - "storage.type.primitive.java", - "storage.type.token.java", - "storage.type.groovy", - "storage.type.annotation.groovy", - "storage.type.parameters.groovy", - "storage.type.generic.groovy", - "storage.type.object.array.groovy", - "storage.type.primitive.array.groovy", - "storage.type.primitive.groovy", - "entity.name.tag", - "entity.name.tag.css", - "entity.name.tag.less", - "entity.name.selector", - "entity.other.attribute-name", - "entity.other.attribute-name.class.css", - "source.css entity.other.attribute-name.class", - "entity.other.attribute-name.id.css", - "entity.other.attribute-name.parent-selector.css", - "entity.other.attribute-name.parent.less", - "source.css entity.other.attribute-name.pseudo-class", - "entity.other.attribute-name.pseudo-element.css", - "source.css.less entity.other.attribute-name.id", - "entity.other.attribute-name.scss" - ], - "settings": { - "foreground": "#6FC3E6" - } - }, - { - "name": "Whiteboard: class name", - "scope": [ - "entity.name.type.class" - ], - "settings": { - "foreground": "#6FC3E6", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: function, decorator and section", - "scope": [ - "entity.name.function", - "support.function", - "meta.function-call entity.name.function", - "meta.decorator", - "punctuation.decorator", - "support.constant.handlebars", - "source.powershell variable.other.member", - "entity.name.operator.custom-literal", - "support.function.git-rebase" - ], - "settings": { - "foreground": "#B7C4FF" - } - }, - { - "name": "Whiteboard: heading", - "scope": [ - "entity.name.section", - "markup.heading" - ], - "settings": { - "foreground": "#B7C4FF", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: variable, property name and key", - "scope": [ - "variable", - "variable.parameter", - "variable.other", - "variable.other.property", - "variable.other.object.property", - "support.variable", - "support.variable.property", - "meta.definition.variable.name", - "entity.name.variable", - "constant.other.placeholder", - "meta.object-literal.key", - "variable.other.constant", - "variable.other.enummember", - "support.type.vendored.property-name", - "support.type.property-name", - "support.type.property-name.json", - "source.css variable", - "source.coffee.embedded", - "meta.structure.dictionary.key.python", - "entity.name.label", - "constant.other.option", - "meta.embedded", - "source.groovy.embedded", - "string meta.image.inline.markdown", - "variable.legacy.builtin.python", - "meta.template.expression", - "storage.modifier.import.java", - "variable.language.wildcard.java", - "storage.modifier.package.java" - ], - "settings": { - "foreground": "#EEF0F4" - } - }, - { - "name": "Whiteboard: string, value and regexp", - "scope": [ - "string", - "string.template", - "punctuation.definition.string", - "meta.embedded.assembly", - "string.tag", - "string.value", - "string.regexp", - "constant.regexp", - "constant.character", - "string.comment.buffered.block.pug", - "string.quoted.pug", - "string.interpolated.pug", - "string.unquoted.plain.in.yaml", - "string.unquoted.plain.out.yaml", - "string.unquoted.block.yaml", - "string.quoted.single.yaml", - "string.quoted.double.xml", - "string.quoted.single.xml", - "string.unquoted.cdata.xml", - "string.quoted.double.html", - "string.quoted.single.html", - "string.unquoted.html", - "string.quoted.single.handlebars", - "string.quoted.double.handlebars", - "meta.preprocessor.string", - "markup.inline.raw", - "support.constant.property-value", - "support.constant.font-name", - "support.constant.media-type", - "support.constant.media", - "constant.other.color.rgb-value", - "constant.other.rgb-value", - "support.constant.color", - "constant.character.character-class.regexp", - "constant.other.character-class.set.regexp", - "constant.other.character-class.regexp", - "constant.character.set.regexp" - ], - "settings": { - "foreground": "#D9A85C" - } - }, - { - "name": "Whiteboard: number, unit and escape", - "scope": [ - "constant.numeric", - "keyword.other.unit", - "keyword.operator.plus.exponent", - "keyword.operator.minus.exponent", - "meta.preprocessor.numeric", - "constant.sha.git-rebase", - "constant.character.escape" - ], - "settings": { - "foreground": "#D48FD6" - } - }, - { - "name": "Whiteboard: boolean and language constant", - "scope": [ - "constant.language" - ], - "settings": { - "foreground": "#D48FD6", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: operator and punctuation", - "scope": [ - "keyword.operator", - "punctuation", - "meta.brace", - "punctuation.definition.tag", - "punctuation.definition.template-expression", - "punctuation.definition.template-expression.begin", - "punctuation.definition.template-expression.end", - "punctuation.section.embedded", - "punctuation.section.embedded.begin.php", - "punctuation.section.embedded.end.php", - "punctuation.definition.quote.begin.markdown", - "punctuation.definition.list.begin.markdown", - "markup.changed", - "punctuation.definition.group.regexp", - "punctuation.definition.group.assertion.regexp", - "punctuation.definition.character-class.regexp", - "punctuation.character.set.begin.regexp", - "punctuation.character.set.end.regexp", - "keyword.operator.negation.regexp", - "support.other.parenthesis.regexp", - "keyword.operator.quantifier.regexp" - ], - "settings": { - "foreground": "#9199A8" - } - }, - { - "name": "Whiteboard: inserted", - "scope": [ - "markup.inserted" - ], - "settings": { - "foreground": "#4ED990" - } - }, - { - "name": "Whiteboard: deleted", - "scope": [ - "markup.deleted" - ], - "settings": { - "foreground": "#F26A55" - } - }, - { - "name": "Whiteboard: invalid", - "scope": [ - "invalid", - "invalid.illegal" - ], - "settings": { - "foreground": "#F26A55", - "fontStyle": "underline" - } - }, - { - "name": "Whiteboard: markup bold", - "scope": [ - "markup.bold", - "strong" - ], - "settings": { - "foreground": "#EEF0F4", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: markup italic", - "scope": [ - "markup.italic", - "emphasis" - ], - "settings": { - "foreground": "#EEF0F4", - "fontStyle": "italic" - } - }, - { - "name": "Whiteboard: markup underline", - "scope": [ - "markup.underline" - ], - "settings": { - "fontStyle": "underline" - } - }, - { - "name": "Whiteboard: markup strikethrough", - "scope": [ - "markup.strikethrough" - ], - "settings": { - "fontStyle": "strikethrough" - } - }, - { - "name": "Whiteboard: link", - "scope": [ - "markup.underline.link", - "string.other.link", - "constant.other.reference.link" - ], - "settings": { - "foreground": "#5B7CFF", - "fontStyle": "underline" - } - } - ], - "semanticTokenColors": { - "newOperator": "#5B7CFF", - "stringLiteral": "#D9A85C", - "customLiteral": "#B7C4FF", - "numberLiteral": "#D48FD6" - }, - "colors": { - "editor.background": "#0C0F15", - "editorWidget.background": "#12161E", - "panel.border": "#262C37", - "editorWidget.border": "#39404D", - "focusBorder": "#5B7CFF", - "editorGroupHeader.tabsBackground": "#12161E", - "titleBar.activeBackground": "#12161E", - "titleBar.inactiveBackground": "#12161E", - "diffEditor.insertedLineBackground": "#4ED9901F", - "diffEditor.insertedTextBackground": "#4ED99038", - "diffEditor.removedLineBackground": "#F26A551F", - "diffEditor.removedTextBackground": "#F26A5538", - "widget.shadow": "#00000066", - "editorHoverWidget.border": "#39404D", - "editorHoverWidget.background": "#12161E", - "sideBar.background": "#12161E", - "diffEditor.diagonalFill": "#39404D40", - "diffEditor.unchangedCodeBackground": "#00000000", - "diffEditor.unchangedRegionBackground": "#0C0F15", - "diffEditor.unchangedRegionForeground": "#343A46", - "diffEditor.unchangedRegionShadow": "#00000000", - "gitDecoration.addedResourceForeground": "#4ED990", - "gitDecoration.modifiedResourceForeground": "#F2C14E", - "gitDecoration.renamedResourceForeground": "#9199A8", - "gitDecoration.deletedResourceForeground": "#F26A55", - "multiDiffEditor.border": "#262C37", - "multiDiffEditor.headerBackground": "#12161E", - "icon.foreground": "#9199A8", - "editor.selectionBackground": "#5B7CFF40", - "editor.lineHighlightBackground": "#12161E", - "scrollbarSlider.background": "#39404D80", - "toolbar.hoverBackground": "#1A1F29", - "list.inactiveSelectionBackground": "#1A1F29", - "list.activeSelectionForeground": "#EEF0F4", - "list.activeSelectionBackground": "#5B7CFF24", - "list.hoverBackground": "#1A1F29", - "input.background": "#1A1F29", - "editorGutter.background": "#0C0F15", - "editorLineNumber.activeForeground": "#9199A8", - "editorLineNumber.foreground": "#343A46", - "foreground": "#EEF0F4", - "disabledForeground": "#5F6776", - "descriptionForeground": "#9199A8", - "editor.foreground": "#EEF0F4", - "editorCursor.foreground": "#5B7CFF", - "editorBracketMatch.background": "#5B7CFF24", - "editorBracketMatch.border": "#5B7CFF4D", - "editorIndentGuide.background1": "#262C37", - "editorIndentGuide.activeBackground1": "#39404D", - "editorWhitespace.foreground": "#343A46", - "editorBracketHighlight.foreground1": "#9199A8", - "editorBracketHighlight.foreground2": "#9199A8", - "editorBracketHighlight.foreground3": "#9199A8", - "editorBracketHighlight.foreground4": "#9199A8", - "editorBracketHighlight.foreground5": "#9199A8", - "editorBracketHighlight.foreground6": "#9199A8", - "editorBracketHighlight.unexpectedBracket.foreground": "#F26A55" - } -} diff --git a/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/themes/whiteboard-light.json b/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/themes/whiteboard-light.json deleted file mode 100644 index 3fc3e8084..000000000 --- a/apps/whiteboard-desktop/code-oss/extensions/whiteboard-themes/themes/whiteboard-light.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - // Whiteboard Light: the Whiteboard syntax palette over the stock Light+ include. - // Every scope the included theme colors is listed below, so none of its colors reaches the screen; - // the include only supplies grammar coverage. Roles: keyword, type, function, ink, string, number, - // operator, comment, inserted, deleted. Regenerated from the Whiteboard System — Syntax themes board. - "$schema": "vscode://schemas/color-theme", - "name": "Whiteboard Light", - "include": "./../../theme-defaults/themes/light_plus.json", - "semanticHighlighting": true, - "tokenColors": [ - { - "name": "Whiteboard: comment", - "scope": [ - "comment", - "punctuation.definition.comment" - ], - "settings": { - "foreground": "#6B7382", - "fontStyle": "italic" - } - }, - { - "name": "Whiteboard: keyword and storage", - "scope": [ - "keyword", - "keyword.control", - "storage", - "storage.type", - "storage.modifier", - "keyword.operator.noexcept", - "keyword.operator.new", - "keyword.operator.expression", - "keyword.operator.cast", - "keyword.operator.sizeof", - "keyword.operator.alignof", - "keyword.operator.typeid", - "keyword.operator.alignas", - "keyword.operator.instanceof", - "keyword.operator.logical.python", - "keyword.operator.wordlike", - "source.cpp keyword.operator.new", - "source.cpp keyword.operator.delete", - "keyword.operator.delete", - "keyword.other.using", - "keyword.other.directive.using", - "keyword.other.operator", - "entity.name.operator", - "variable.language", - "meta.preprocessor", - "entity.name.function.preprocessor", - "keyword.operator.or.regexp", - "keyword.control.anchor.regexp", - "meta.diff.header", - "header" - ], - "settings": { - "foreground": "#2B55E6" - } - }, - { - "name": "Whiteboard: type, class, tag, attribute and selector", - "scope": [ - "entity.name.type", - "support.type", - "support.class", - "entity.other.inherited-class", - "entity.name.namespace", - "entity.other.attribute", - "entity.name.scope-resolution", - "entity.name.class", - "meta.type.cast.expr", - "meta.type.new.expr", - "support.constant.math", - "support.constant.dom", - "support.constant.json", - "punctuation.separator.namespace.ruby", - "storage.type.numeric.go", - "storage.type.byte.go", - "storage.type.boolean.go", - "storage.type.string.go", - "storage.type.uintptr.go", - "storage.type.error.go", - "storage.type.rune.go", - "storage.type.cs", - "storage.type.generic.cs", - "storage.type.modifier.cs", - "storage.type.variable.cs", - "storage.type.annotation.java", - "storage.type.generic.java", - "storage.type.java", - "storage.type.object.array.java", - "storage.type.primitive.array.java", - "storage.type.primitive.java", - "storage.type.token.java", - "storage.type.groovy", - "storage.type.annotation.groovy", - "storage.type.parameters.groovy", - "storage.type.generic.groovy", - "storage.type.object.array.groovy", - "storage.type.primitive.array.groovy", - "storage.type.primitive.groovy", - "entity.name.tag", - "entity.name.tag.css", - "entity.name.tag.less", - "entity.name.selector", - "entity.other.attribute-name", - "entity.other.attribute-name.class.css", - "source.css entity.other.attribute-name.class", - "entity.other.attribute-name.id.css", - "entity.other.attribute-name.parent-selector.css", - "entity.other.attribute-name.parent.less", - "source.css entity.other.attribute-name.pseudo-class", - "entity.other.attribute-name.pseudo-element.css", - "source.css.less entity.other.attribute-name.id", - "entity.other.attribute-name.scss" - ], - "settings": { - "foreground": "#0C6E8E" - } - }, - { - "name": "Whiteboard: class name", - "scope": [ - "entity.name.type.class" - ], - "settings": { - "foreground": "#0C6E8E", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: function, decorator and section", - "scope": [ - "entity.name.function", - "support.function", - "meta.function-call entity.name.function", - "meta.decorator", - "punctuation.decorator", - "support.constant.handlebars", - "source.powershell variable.other.member", - "entity.name.operator.custom-literal", - "support.function.git-rebase" - ], - "settings": { - "foreground": "#1F3F99" - } - }, - { - "name": "Whiteboard: heading", - "scope": [ - "entity.name.section", - "markup.heading" - ], - "settings": { - "foreground": "#1F3F99", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: variable, property name and key", - "scope": [ - "variable", - "variable.parameter", - "variable.other", - "variable.other.property", - "variable.other.object.property", - "support.variable", - "support.variable.property", - "meta.definition.variable.name", - "entity.name.variable", - "constant.other.placeholder", - "meta.object-literal.key", - "variable.other.constant", - "variable.other.enummember", - "support.type.vendored.property-name", - "support.type.property-name", - "support.type.property-name.json", - "source.css variable", - "source.coffee.embedded", - "meta.structure.dictionary.key.python", - "entity.name.label", - "constant.other.option", - "meta.embedded", - "source.groovy.embedded", - "string meta.image.inline.markdown", - "variable.legacy.builtin.python", - "meta.template.expression", - "storage.modifier.import.java", - "variable.language.wildcard.java", - "storage.modifier.package.java" - ], - "settings": { - "foreground": "#15181E" - } - }, - { - "name": "Whiteboard: string, value and regexp", - "scope": [ - "string", - "string.template", - "punctuation.definition.string", - "meta.embedded.assembly", - "string.tag", - "string.value", - "string.regexp", - "constant.regexp", - "constant.character", - "string.comment.buffered.block.pug", - "string.quoted.pug", - "string.interpolated.pug", - "string.unquoted.plain.in.yaml", - "string.unquoted.plain.out.yaml", - "string.unquoted.block.yaml", - "string.quoted.single.yaml", - "string.quoted.double.xml", - "string.quoted.single.xml", - "string.unquoted.cdata.xml", - "string.quoted.double.html", - "string.quoted.single.html", - "string.unquoted.html", - "string.quoted.single.handlebars", - "string.quoted.double.handlebars", - "meta.preprocessor.string", - "markup.inline.raw", - "support.constant.property-value", - "support.constant.font-name", - "support.constant.media-type", - "support.constant.media", - "constant.other.color.rgb-value", - "constant.other.rgb-value", - "support.constant.color", - "constant.character.character-class.regexp", - "constant.other.character-class.set.regexp", - "constant.other.character-class.regexp", - "constant.character.set.regexp" - ], - "settings": { - "foreground": "#8A5A1C" - } - }, - { - "name": "Whiteboard: number, unit and escape", - "scope": [ - "constant.numeric", - "keyword.other.unit", - "keyword.operator.plus.exponent", - "keyword.operator.minus.exponent", - "meta.preprocessor.numeric", - "constant.sha.git-rebase", - "constant.character.escape" - ], - "settings": { - "foreground": "#8B3F8A" - } - }, - { - "name": "Whiteboard: boolean and language constant", - "scope": [ - "constant.language" - ], - "settings": { - "foreground": "#8B3F8A", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: operator and punctuation", - "scope": [ - "keyword.operator", - "punctuation", - "meta.brace", - "punctuation.definition.tag", - "punctuation.definition.template-expression", - "punctuation.definition.template-expression.begin", - "punctuation.definition.template-expression.end", - "punctuation.section.embedded", - "punctuation.section.embedded.begin.php", - "punctuation.section.embedded.end.php", - "punctuation.definition.quote.begin.markdown", - "punctuation.definition.list.begin.markdown", - "markup.changed", - "punctuation.definition.group.regexp", - "punctuation.definition.group.assertion.regexp", - "punctuation.definition.character-class.regexp", - "punctuation.character.set.begin.regexp", - "punctuation.character.set.end.regexp", - "keyword.operator.negation.regexp", - "support.other.parenthesis.regexp", - "keyword.operator.quantifier.regexp" - ], - "settings": { - "foreground": "#5D6472" - } - }, - { - "name": "Whiteboard: inserted", - "scope": [ - "markup.inserted" - ], - "settings": { - "foreground": "#167A47" - } - }, - { - "name": "Whiteboard: deleted", - "scope": [ - "markup.deleted" - ], - "settings": { - "foreground": "#C93A27" - } - }, - { - "name": "Whiteboard: invalid", - "scope": [ - "invalid", - "invalid.illegal" - ], - "settings": { - "foreground": "#C93A27", - "fontStyle": "underline" - } - }, - { - "name": "Whiteboard: markup bold", - "scope": [ - "markup.bold", - "strong" - ], - "settings": { - "foreground": "#15181E", - "fontStyle": "bold" - } - }, - { - "name": "Whiteboard: markup italic", - "scope": [ - "markup.italic", - "emphasis" - ], - "settings": { - "foreground": "#15181E", - "fontStyle": "italic" - } - }, - { - "name": "Whiteboard: markup underline", - "scope": [ - "markup.underline" - ], - "settings": { - "fontStyle": "underline" - } - }, - { - "name": "Whiteboard: markup strikethrough", - "scope": [ - "markup.strikethrough" - ], - "settings": { - "fontStyle": "strikethrough" - } - }, - { - "name": "Whiteboard: link", - "scope": [ - "markup.underline.link", - "string.other.link", - "constant.other.reference.link" - ], - "settings": { - "foreground": "#2B55E6", - "fontStyle": "underline" - } - } - ], - "semanticTokenColors": { - "newOperator": "#2B55E6", - "stringLiteral": "#8A5A1C", - "customLiteral": "#1F3F99", - "numberLiteral": "#8B3F8A" - }, - "colors": { - "editor.background": "#FFFFFF", - "editorWidget.background": "#F3F4F6", - "panel.border": "#D8DBE1", - "editorWidget.border": "#B9BEC7", - "focusBorder": "#2B55E6", - "editorGroupHeader.tabsBackground": "#F3F4F6", - "titleBar.activeBackground": "#F3F4F6", - "titleBar.inactiveBackground": "#F3F4F6", - "diffEditor.insertedLineBackground": "#1B9A5716", - "diffEditor.insertedTextBackground": "#1B9A5733", - "diffEditor.removedLineBackground": "#D8402C16", - "diffEditor.removedTextBackground": "#D8402C33", - "widget.shadow": "#15181E1A", - "editorHoverWidget.border": "#B9BEC7", - "editorHoverWidget.background": "#FFFFFF", - "sideBar.background": "#F3F4F6", - "diffEditor.diagonalFill": "#D8DBE180", - "diffEditor.unchangedCodeBackground": "#00000000", - "diffEditor.unchangedRegionBackground": "#FFFFFF", - "diffEditor.unchangedRegionForeground": "#CDD1D8", - "diffEditor.unchangedRegionShadow": "#00000000", - "gitDecoration.addedResourceForeground": "#1B9A57", - "gitDecoration.modifiedResourceForeground": "#C98A0B", - "gitDecoration.renamedResourceForeground": "#5D6472", - "gitDecoration.deletedResourceForeground": "#D8402C", - "multiDiffEditor.border": "#D8DBE1", - "multiDiffEditor.headerBackground": "#F3F4F6", - "icon.foreground": "#5D6472", - "editor.selectionBackground": "#2B55E629", - "editor.lineHighlightBackground": "#F3F4F6", - "scrollbarSlider.background": "#B9BEC780", - "toolbar.hoverBackground": "#E9EBEF", - "list.inactiveSelectionBackground": "#E9EBEF", - "list.activeSelectionForeground": "#15181E", - "list.activeSelectionBackground": "#2B55E616", - "list.hoverBackground": "#E9EBEF", - "input.background": "#FFFFFF", - "editorGutter.background": "#FFFFFF", - "editorLineNumber.activeForeground": "#5D6472", - "editorLineNumber.foreground": "#CDD1D8", - "foreground": "#15181E", - "disabledForeground": "#9AA0AB", - "descriptionForeground": "#5D6472", - "editor.foreground": "#15181E", - "editorCursor.foreground": "#2B55E6", - "editorBracketMatch.background": "#2B55E616", - "editorBracketMatch.border": "#2B55E638", - "editorIndentGuide.background1": "#D8DBE1", - "editorIndentGuide.activeBackground1": "#B9BEC7", - "editorWhitespace.foreground": "#CDD1D8", - "editorBracketHighlight.foreground1": "#5D6472", - "editorBracketHighlight.foreground2": "#5D6472", - "editorBracketHighlight.foreground3": "#5D6472", - "editorBracketHighlight.foreground4": "#5D6472", - "editorBracketHighlight.foreground5": "#5D6472", - "editorBracketHighlight.foreground6": "#5D6472", - "editorBracketHighlight.unexpectedBracket.foreground": "#C93A27" - } -} diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/helpers/browser.cmd b/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/helpers/browser.cmd deleted file mode 100644 index 7a21259de..000000000 --- a/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/helpers/browser.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off -setlocal -SET VSCODE_PATH=%~dp0..\..\..\.. -FOR /F "tokens=* USEBACKQ" %%g IN (`where /r "%VSCODE_PATH%\.build\node" node.exe`) do (SET "NODE=%%g") -call "%NODE%" "%VSCODE_PATH%\out\server-cli.js" "Code Server - Dev" "" "" "code.cmd" "--openExternal" %* -endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/remote-cli/code.cmd b/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/remote-cli/code.cmd deleted file mode 100644 index 4d8214ead..000000000 --- a/apps/whiteboard-desktop/code-oss/resources/server/bin-dev/remote-cli/code.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off -setlocal -SET VSCODE_PATH=%~dp0..\..\..\.. -SET VSCODE_DEV=1 -FOR /F "tokens=* USEBACKQ" %%g IN (`where /r "%VSCODE_PATH%\.build\node" node.exe`) do (SET "NODE=%%g") -call "%NODE%" "%VSCODE_PATH%\out\server-cli.js" "Code Server - Dev" "" "" "code.cmd" %* -endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser.cmd b/apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser.cmd deleted file mode 100644 index 59664f04a..000000000 --- a/apps/whiteboard-desktop/code-oss/resources/server/bin/helpers/browser.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -setlocal -set ROOT_DIR=%~dp0..\.. -start "Open Browser" /B "%ROOT_DIR%\node.exe" "%ROOT_DIR%\out\server-cli.js" "@@APPNAME@@" "@@VERSION@@" "@@COMMIT@@" "@@APPNAME@@.cmd" "--openExternal" "%*" -endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code.cmd b/apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code.cmd deleted file mode 100644 index e69a31173..000000000 --- a/apps/whiteboard-desktop/code-oss/resources/server/bin/remote-cli/code.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -setlocal -set ROOT_DIR=%~dp0..\.. -call "%ROOT_DIR%\node.exe" "%ROOT_DIR%\out\server-cli.js" "@@APPNAME@@" "@@VERSION@@" "@@COMMIT@@" "@@APPNAME@@.cmd" %* -endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/bin/code.cmd b/apps/whiteboard-desktop/code-oss/resources/win32/bin/code.cmd deleted file mode 100644 index 7e7b92c9e..000000000 --- a/apps/whiteboard-desktop/code-oss/resources/win32/bin/code.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off -setlocal -set VSCODE_DEV= -set ELECTRON_RUN_AS_NODE=1 -"%~dp0..\@@NAME@@.exe" "%~dp0..\resources\app\out\cli.js" %* -IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL% -endlocal diff --git a/apps/whiteboard-desktop/code-oss/resources/win32/versioned/bin/code.cmd b/apps/whiteboard-desktop/code-oss/resources/win32/versioned/bin/code.cmd deleted file mode 100644 index 1298c72ee..000000000 --- a/apps/whiteboard-desktop/code-oss/resources/win32/versioned/bin/code.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off -setlocal -set VSCODE_DEV= -set ELECTRON_RUN_AS_NODE=1 -"%~dp0..\@@NAME@@.exe" "%~dp0..\@@VERSIONFOLDER@@\resources\app\out\cli.js" %* -IF %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL% -endlocal diff --git a/apps/whiteboard-desktop/code-oss/src/main.ts b/apps/whiteboard-desktop/code-oss/src/main.ts deleted file mode 100644 index b81ce4f55..000000000 --- a/apps/whiteboard-desktop/code-oss/src/main.ts +++ /dev/null @@ -1,779 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as path from 'node:path'; -import * as fs from 'original-fs'; -import * as os from 'node:os'; -import { performance } from 'node:perf_hooks'; -import { configurePortable } from './bootstrap-node.js'; -import { bootstrapESM } from './bootstrap-esm.js'; -import { app, protocol, crashReporter, Menu, contentTracing, net } from 'electron'; -import minimist from 'minimist'; -import { product } from './bootstrap-meta.js'; -import { validatedIpcMain } from './vs/base/parts/ipc/electron-main/ipcMain.js'; -import { parse } from './vs/base/common/jsonc.js'; -import { getUserDataPath } from './vs/platform/environment/node/userDataPath.js'; -// Evaluated before `startup()` calls `bootstrapESM()`, so this module and -// everything it imports runs with no NLS message table installed. It must not -// reach `vs/nls.js`, the platform registry, or the configuration registry: in a -// packaged build those throw `!!! NLS MISSING: !!!` into a modal, before any -// window or log exists, and the app never starts. That is why it reads setting -// keys from the import-free `vs/whiteboard/common/whiteboardConfigurationDefaults.ts` -// rather than from `whiteboardConfiguration.ts`, which owns the registry calls. -// Enforced by apps/whiteboard-desktop/scripts/main-bootstrap-imports.test.mjs. -import { migrateWhiteboardUserConfig } from './vs/whiteboard/node/whiteboardUserConfigMigration.js'; -import { importWhiteboardUserConfig, type WhiteboardUserConfigImportMode } from './vs/whiteboard/node/whiteboardUserConfigImport.js'; -import { registerWhiteboardOptionalExtensionInstaller } from './vs/whiteboard/node/whiteboardOptionalExtensionInstaller.js'; -import { writeWhiteboardBootstrapBreadcrumb } from './vs/whiteboard/node/whiteboardBootstrapBreadcrumb.js'; -import * as perf from './vs/base/common/performance.js'; -import { resolveNLSConfiguration } from './vs/base/node/nls.js'; -import { getUNCHost, addUNCHostToAllowlist } from './vs/base/node/unc.js'; -import { INLSConfiguration } from './vs/nls.js'; -import { NativeParsedArgs } from './vs/platform/environment/common/argv.js'; - -perf.mark('code/didStartMain'); - -perf.mark('code/willLoadMainBundle', { - // When built, the main bundle is a single JS file with all - // dependencies inlined. As such, we mark `willLoadMainBundle` - // as the start of the main bundle loading process. - startTime: Math.floor(performance.timeOrigin) -}); -perf.mark('code/didLoadMainBundle'); - -// Enable portable support -const portable = configurePortable(product); - -const args = parseCLIArgs(); -// Configure static command line arguments -const argvConfig = configureCommandlineSwitchesSync(args); -// Enable sandbox globally unless -// 1) disabled via command line using either -// `--no-sandbox` or `--disable-chromium-sandbox` argument. -// 2) argv.json contains `disable-chromium-sandbox: true`. -if (args['sandbox'] && - !args['disable-chromium-sandbox'] && - !argvConfig['disable-chromium-sandbox']) { - app.enableSandbox(); -} else if (app.commandLine.hasSwitch('no-sandbox') && - !app.commandLine.hasSwitch('disable-gpu-sandbox')) { - // Disable GPU sandbox whenever --no-sandbox is used. - app.commandLine.appendSwitch('disable-gpu-sandbox'); -} else { - app.commandLine.appendSwitch('no-sandbox'); - app.commandLine.appendSwitch('disable-gpu-sandbox'); -} - -// Set userData path before app 'ready' event -const userDataPath = getUserDataPath(args, product.nameShort ?? 'code-oss-dev'); -if (process.platform === 'win32') { - const userDataUNCHost = getUNCHost(userDataPath); - if (userDataUNCHost) { - addUNCHostToAllowlist(userDataUNCHost); // enables to use UNC paths in userDataPath - } -} -app.setPath('userData', userDataPath); -registerWhiteboardOptionalExtensionInstaller(validatedIpcMain, { - userDataPath, - platform: process.platform, - arch: process.arch, - request: options => net.request(options) -}); -try { - migrateWhiteboardUserConfig(userDataPath); - importWhiteboardUserConfig({ userDataPath, log: message => console.log(message) }); -} catch (error) { - console.error('Review could not import VS Code settings and keybindings:', error); - writeWhiteboardBootstrapBreadcrumb(userDataPath, error); -} -validatedIpcMain.handle('vscode:whiteboardImportUserConfig', async (_event, request: unknown) => { - const mode = request && typeof request === 'object' ? (request as { mode?: unknown }).mode : undefined; - if (mode !== 'preview' && mode !== 'apply') { - throw new Error(`Unsupported Review user-config import mode: ${String(mode)}`); - } - return importWhiteboardUserConfig({ - userDataPath, - mode: mode satisfies WhiteboardUserConfigImportMode, - log: message => console.log(message), - }); -}); - -// Resolve code cache path -const codeCachePath = getCodeCachePath(); - -// Disable default menu (https://github.com/electron/electron/issues/35512) -Menu.setApplicationMenu(null); - -// Configure crash reporter -perf.mark('code/willStartCrashReporter'); -// If a crash-reporter-directory is specified we store the crash reports -// in the specified directory and don't upload them to the crash server. -// -// Appcenter crash reporting is enabled if -// * enable-crash-reporter runtime argument is set to 'true' -// * --disable-crash-reporter command line parameter is not set -// -// Disable crash reporting in all other cases. -if (args['crash-reporter-directory'] || (argvConfig['enable-crash-reporter'] && !args['disable-crash-reporter'])) { - configureCrashReporter(); -} -perf.mark('code/didStartCrashReporter'); - -// Set logs path before app 'ready' event if running portable -// to ensure that no 'logs' folder is created on disk at a -// location outside of the portable directory -// (https://github.com/microsoft/vscode/issues/56651) -if (portable.isPortable) { - app.setAppLogsPath(path.join(userDataPath, 'logs')); -} - -// Register custom schemes with privileges -protocol.registerSchemesAsPrivileged([ - { - scheme: 'vscode-webview', - privileges: { standard: true, secure: true, supportFetchAPI: true, corsEnabled: true, allowServiceWorkers: true, codeCache: true } - }, - { - scheme: 'vscode-file', - privileges: { secure: true, standard: true, supportFetchAPI: true, corsEnabled: true, codeCache: true } - }, - { - scheme: 'vscode-remote-resource', - privileges: { secure: true, supportFetchAPI: true, corsEnabled: true } - }, - { - scheme: 'vscode-managed-remote-resource', - privileges: { secure: true, supportFetchAPI: true, corsEnabled: true } - } -]); - -// Global app listeners -registerListeners(); - -/** - * We can resolve the NLS configuration early if it is defined - * in argv.json before `app.ready` event. Otherwise we can only - * resolve NLS after `app.ready` event to resolve the OS locale. - */ -let nlsConfigurationPromise: Promise | undefined = undefined; - -// Use the most preferred OS language for language recommendation. -// The API might return an empty array on Linux, such as when -// the 'C' locale is the user's only configured locale. -// No matter the OS, if the array is empty, default back to 'en'. -const osLocale = processZhLocale((app.getPreferredSystemLanguages()?.[0] ?? 'en').toLowerCase()); -const userLocale = getUserDefinedLocale(argvConfig); -if (userLocale) { - nlsConfigurationPromise = resolveNLSConfiguration({ - userLocale, - osLocale, - commit: product.commit, - userDataPath, - nlsMetadataPath: import.meta.dirname - }); -} - -// Pass in the locale to Electron so that the -// Windows Control Overlay is rendered correctly on Windows. -// For now, don't pass in the locale on macOS due to -// https://github.com/microsoft/vscode/issues/167543. -// If the locale is `qps-ploc`, the Microsoft -// Pseudo Language Language Pack is being used. -// In that case, use `en` as the Electron locale. - -if (process.platform === 'win32' || process.platform === 'linux') { - const electronLocale = (!userLocale || userLocale === 'qps-ploc') ? 'en' : userLocale; - app.commandLine.appendSwitch('lang', electronLocale); -} - -// Load our code once ready -app.once('ready', function () { - if (args['trace']) { - let traceOptions: Electron.TraceConfig | Electron.TraceCategoriesAndOptions; - if (args['trace-memory-infra']) { - const customCategories = args['trace-category-filter']?.split(',') || []; - customCategories.push('disabled-by-default-memory-infra', 'disabled-by-default-memory-infra.v8.code_stats'); - traceOptions = { - included_categories: customCategories, - excluded_categories: ['*'], - memory_dump_config: { - allowed_dump_modes: ['light', 'detailed'], - triggers: [ - { - type: 'periodic_interval', - mode: 'detailed', - min_time_between_dumps_ms: 10000 - }, - { - type: 'periodic_interval', - mode: 'light', - min_time_between_dumps_ms: 1000 - } - ] - } - }; - } else { - traceOptions = { - categoryFilter: args['trace-category-filter'] || '*', - traceOptions: args['trace-options'] || 'record-until-full,enable-sampling' - }; - } - - contentTracing.startRecording(traceOptions).finally(() => onReady()); - } else { - onReady(); - } -}); - -async function onReady() { - perf.mark('code/mainAppReady'); - - try { - const [, nlsConfig] = await Promise.all([ - mkdirpIgnoreError(codeCachePath), - resolveNlsConfiguration() - ]); - - await startup(codeCachePath, nlsConfig); - } catch (error) { - console.error(error); - // Nothing is running yet that could report this: no window, no log, no - // Review server. Leave a note on disk instead; the next launch sends it - // through the normal opted-in path and deletes it. - writeWhiteboardBootstrapBreadcrumb(userDataPath, error); - } -} - -/** - * Main startup routine - */ -async function startup(codeCachePath: string | undefined, nlsConfig: INLSConfiguration): Promise { - process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfig); - process.env['VSCODE_CODE_CACHE_PATH'] = codeCachePath || ''; - - // Bootstrap ESM - await bootstrapESM(); - - // Load Main - await import('./vs/code/electron-main/main.js'); - perf.mark('code/didRunMainBundle'); -} - -function configureCommandlineSwitchesSync(cliArgs: NativeParsedArgs) { - const SUPPORTED_ELECTRON_SWITCHES = [ - - // alias from us for --disable-gpu - 'disable-hardware-acceleration', - - // override for the color profile to use - 'force-color-profile', - - // disable LCD font rendering, a Chromium flag - 'disable-lcd-text', - - // bypass any specified proxy for the given semi-colon-separated list of hosts - 'proxy-bypass-list', - - 'remote-debugging-port' - ]; - - if (process.platform === 'linux') { - - // Force enable screen readers on Linux via this flag - SUPPORTED_ELECTRON_SWITCHES.push('force-renderer-accessibility'); - - // override which password-store is used on Linux - SUPPORTED_ELECTRON_SWITCHES.push('password-store'); - } - - const SUPPORTED_MAIN_PROCESS_SWITCHES = [ - - // Persistently enable proposed api via argv.json: https://github.com/microsoft/vscode/issues/99775 - 'enable-proposed-api', - - // Log level to use. Default is 'info'. Allowed values are 'error', 'warn', 'info', 'debug', 'trace', 'off'. - 'log-level', - - // Use an in-memory storage for secrets - 'use-inmemory-secretstorage', - - // Enables display tracking to restore maximized windows under RDP: https://github.com/electron/electron/issues/47016 - 'enable-rdp-display-tracking', - ]; - - // Read argv config - const argvConfig = readArgvConfigSync(); - - Object.keys(argvConfig).forEach(argvKey => { - const argvValue = argvConfig[argvKey]; - - // Append Electron flags to Electron - if (SUPPORTED_ELECTRON_SWITCHES.indexOf(argvKey) !== -1) { - if (argvValue === true || argvValue === 'true') { - if (argvKey === 'disable-hardware-acceleration') { - app.disableHardwareAcceleration(); // needs to be called explicitly - } else { - app.commandLine.appendSwitch(argvKey); - } - } else if (typeof argvValue === 'string' && argvValue) { - if (argvKey === 'password-store') { - // Password store - // TODO@TylerLeonhardt: Remove this migration in 3 months - let migratedArgvValue = argvValue; - if (argvValue === 'gnome' || argvValue === 'gnome-keyring') { - migratedArgvValue = 'gnome-libsecret'; - } - app.commandLine.appendSwitch(argvKey, migratedArgvValue); - } else { - app.commandLine.appendSwitch(argvKey, argvValue); - } - } - } - - // Append main process flags to process.argv - else if (SUPPORTED_MAIN_PROCESS_SWITCHES.indexOf(argvKey) !== -1) { - switch (argvKey) { - case 'enable-proposed-api': - if (Array.isArray(argvValue)) { - argvValue.forEach(id => id && typeof id === 'string' && process.argv.push('--enable-proposed-api', id)); - } else { - console.error(`Unexpected value for \`enable-proposed-api\` in argv.json. Expected array of extension ids.`); - } - break; - - case 'log-level': - if (typeof argvValue === 'string') { - process.argv.push('--log', argvValue); - } else if (Array.isArray(argvValue)) { - for (const value of argvValue) { - process.argv.push('--log', value); - } - } - break; - - case 'use-inmemory-secretstorage': - if (argvValue) { - process.argv.push('--use-inmemory-secretstorage'); - } - break; - - case 'enable-rdp-display-tracking': - if (argvValue) { - process.argv.push('--enable-rdp-display-tracking'); - } - break; - } - } - }); - - // Following features are enabled from the runtime: - // `NetAdapterMaxBufSizeFeature` - Specify the max buffer size for NetToMojoPendingBuffer, refs https://github.com/microsoft/vscode/issues/268800 - // `DocumentPolicyIncludeJSCallStacksInCrashReports` - https://www.electronjs.org/docs/latest/api/web-frame-main#framecollectjavascriptcallstack-experimental - // `EarlyEstablishGpuChannel` - Refs https://issues.chromium.org/issues/40208065 - // `EstablishGpuChannelAsync` - Refs https://issues.chromium.org/issues/40208065 - // `GlobalShortcutsPortal` - Enables Electron's `globalShortcut` (system-wide keybindings) on Linux Wayland via the XDG global shortcuts portal (no-op elsewhere) - const featuresToEnable = - `NetAdapterMaxBufSizeFeature:NetAdapterMaxBufSize/8192,DocumentPolicyIncludeJSCallStacksInCrashReports,EarlyEstablishGpuChannel,EstablishGpuChannelAsync${process.platform === 'linux' ? ',GlobalShortcutsPortal' : ''},${app.commandLine.getSwitchValue('enable-features')}`; - app.commandLine.appendSwitch('enable-features', featuresToEnable); - - // Following features are disabled from the runtime: - // `CalculateNativeWinOcclusion` - Disable native window occlusion tracker (https://groups.google.com/a/chromium.org/g/embedder-dev/c/ZF3uHHyWLKw/m/VDN2hDXMAAAJ) - const featuresToDisable = - `CalculateNativeWinOcclusion,${app.commandLine.getSwitchValue('disable-features')}`; - app.commandLine.appendSwitch('disable-features', featuresToDisable); - - // Blink features to configure. - // `FontMatchingCTMigration` - Siwtch font matching on macOS to Appkit (Refs https://github.com/microsoft/vscode/issues/224496#issuecomment-2270418470). - // `StandardizedBrowserZoom` - Disable zoom adjustment for bounding box (https://github.com/microsoft/vscode/issues/232750#issuecomment-2459495394) - const blinkFeaturesToDisable = - `FontMatchingCTMigration,StandardizedBrowserZoom,${app.commandLine.getSwitchValue('disable-blink-features')}`; - app.commandLine.appendSwitch('disable-blink-features', blinkFeaturesToDisable); - - // Support JS Flags - const jsFlags = getJSFlags(cliArgs, argvConfig); - if (jsFlags) { - app.commandLine.appendSwitch('js-flags', jsFlags); - } - - // Use portal version 4 that supports current_folder option - // to address https://github.com/microsoft/vscode/issues/213780 - // Runtime sets the default version to 3, refs https://github.com/electron/electron/pull/44426 - app.commandLine.appendSwitch('xdg-portal-required-version', '4'); - - // Increase the maximum number of active WebGL contexts as each terminal may - // use up to 2 - app.commandLine.appendSwitch('max-active-webgl-contexts', '32'); - - return argvConfig; -} - -interface IArgvConfig { - [key: string]: string | string[] | boolean | undefined; - readonly locale?: string; - readonly 'disable-lcd-text'?: boolean; - readonly 'proxy-bypass-list'?: string; - readonly 'disable-hardware-acceleration'?: boolean; - readonly 'force-color-profile'?: string; - readonly 'enable-crash-reporter'?: boolean; - readonly 'crash-reporter-id'?: string; - readonly 'enable-proposed-api'?: string[]; - readonly 'log-level'?: string | string[]; - readonly 'disable-chromium-sandbox'?: boolean; - readonly 'use-inmemory-secretstorage'?: boolean; - readonly 'enable-rdp-display-tracking'?: boolean; - readonly 'remote-debugging-port'?: string; - readonly 'js-flags'?: string; -} - -function readArgvConfigSync(): IArgvConfig { - - // Read or create the argv.json config file sync before app('ready') - const argvConfigPath = getArgvConfigPath(); - let argvConfig: IArgvConfig | undefined = undefined; - try { - argvConfig = parse(fs.readFileSync(argvConfigPath).toString()); - } catch (error) { - if (error && error.code === 'ENOENT') { - createDefaultArgvConfigSync(argvConfigPath); - } else { - console.warn(`Unable to read argv.json configuration file in ${argvConfigPath}, falling back to defaults (${error})`); - } - } - - // Fallback to default - if (!argvConfig) { - argvConfig = {}; - } - - return argvConfig; -} - -function createDefaultArgvConfigSync(argvConfigPath: string): void { - try { - - // Ensure argv config parent exists - const argvConfigPathDirname = path.dirname(argvConfigPath); - if (!fs.existsSync(argvConfigPathDirname)) { - fs.mkdirSync(argvConfigPathDirname); - } - - // Default argv content - const defaultArgvConfigContent = [ - '// This configuration file allows you to pass permanent command line arguments to VS Code.', - '// Only a subset of arguments is currently supported to reduce the likelihood of breaking', - '// the installation.', - '//', - '// PLEASE DO NOT CHANGE WITHOUT UNDERSTANDING THE IMPACT', - '//', - '// NOTE: Changing this file requires a restart of VS Code.', - '{', - ' // Use software rendering instead of hardware accelerated rendering.', - ' // This can help in cases where you see rendering issues in VS Code.', - ' // "disable-hardware-acceleration": true', - '}' - ]; - - // Create initial argv.json with default content - fs.writeFileSync(argvConfigPath, defaultArgvConfigContent.join('\n')); - } catch (error) { - console.error(`Unable to create argv.json configuration file in ${argvConfigPath}, falling back to defaults (${error})`); - } -} - -function getArgvConfigPath(): string { - const vscodePortable = process.env['VSCODE_PORTABLE']; - if (vscodePortable) { - return path.join(vscodePortable, 'argv.json'); - } - - let dataFolderName = product.dataFolderName; - if (process.env['VSCODE_DEV']) { - dataFolderName = `${dataFolderName}-dev`; - } - - return path.join(os.homedir(), dataFolderName!, 'argv.json'); -} - -function configureCrashReporter(): void { - let crashReporterDirectory = args['crash-reporter-directory']; - let submitURL = ''; - if (crashReporterDirectory) { - crashReporterDirectory = path.normalize(crashReporterDirectory); - - if (!path.isAbsolute(crashReporterDirectory)) { - console.error(`The path '${crashReporterDirectory}' specified for --crash-reporter-directory must be absolute.`); - app.exit(1); - } - - if (!fs.existsSync(crashReporterDirectory)) { - try { - fs.mkdirSync(crashReporterDirectory, { recursive: true }); - } catch (error) { - console.error(`The path '${crashReporterDirectory}' specified for --crash-reporter-directory does not seem to exist or cannot be created.`); - app.exit(1); - } - } - - // Crashes are stored in the crashDumps directory by default, so we - // need to change that directory to the provided one - console.log(`Found --crash-reporter-directory argument. Setting crashDumps directory to be '${crashReporterDirectory}'`); - app.setPath('crashDumps', crashReporterDirectory); - } - - // Otherwise we configure the crash reporter from product.json - else { - const appCenter = product.appCenter; - if (appCenter) { - const isWindows = (process.platform === 'win32'); - const isLinux = (process.platform === 'linux'); - const isDarwin = (process.platform === 'darwin'); - const crashReporterId = argvConfig['crash-reporter-id']; - const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; - if (crashReporterId && uuidPattern.test(crashReporterId)) { - if (isWindows) { - switch (process.arch) { - case 'x64': - submitURL = appCenter['win32-x64']; - break; - case 'arm64': - submitURL = appCenter['win32-arm64']; - break; - } - } else if (isDarwin) { - if (product.darwinUniversalAssetId) { - submitURL = appCenter['darwin-universal']; - } else { - switch (process.arch) { - case 'x64': - submitURL = appCenter['darwin']; - break; - case 'arm64': - submitURL = appCenter['darwin-arm64']; - break; - } - } - } else if (isLinux) { - submitURL = appCenter['linux-x64']; - } - submitURL = submitURL.concat('&uid=', crashReporterId, '&iid=', crashReporterId, '&sid=', crashReporterId); - // Send the id for child node process that are explicitly starting crash reporter. - // For vscode this is ExtensionHost process currently. - const argv = process.argv; - const endOfArgsMarkerIndex = argv.indexOf('--'); - if (endOfArgsMarkerIndex === -1) { - argv.push('--crash-reporter-id', crashReporterId); - } else { - // if the we have an argument "--" (end of argument marker) - // we cannot add arguments at the end. rather, we add - // arguments before the "--" marker. - argv.splice(endOfArgsMarkerIndex, 0, '--crash-reporter-id', crashReporterId); - } - } - } - } - - // Start crash reporter for all processes - const productName = (product.crashReporter ? product.crashReporter.productName : undefined) || product.nameShort; - const companyName = (product.crashReporter ? product.crashReporter.companyName : undefined) || 'Microsoft'; - const uploadToServer = Boolean(!process.env['VSCODE_DEV'] && submitURL && !crashReporterDirectory); - crashReporter.start({ - companyName, - productName: process.env['VSCODE_DEV'] ? `${productName} Dev` : productName, - submitURL, - uploadToServer, - compress: true, - ignoreSystemCrashHandler: true - }); -} - -function getJSFlags(cliArgs: NativeParsedArgs, argvConfig: IArgvConfig): string | null { - const jsFlags: string[] = []; - - // Add any existing JS flags we already got from the command line - if (cliArgs['js-flags']) { - jsFlags.push(cliArgs['js-flags']); - } - - // Add JS flags from runtime arguments (argv.json) - if (typeof argvConfig['js-flags'] === 'string' && argvConfig['js-flags']) { - jsFlags.push(argvConfig['js-flags']); - } - - return jsFlags.length > 0 ? jsFlags.join(' ') : null; -} - -function parseCLIArgs(): NativeParsedArgs { - return minimist(process.argv, { - string: [ - 'user-data-dir', - 'locale', - 'js-flags', - 'crash-reporter-directory' - ], - boolean: [ - 'disable-chromium-sandbox', - ], - default: { - 'sandbox': true - }, - alias: { - 'no-sandbox': 'sandbox' - } - }); -} - -function registerListeners(): void { - - /** - * macOS: when someone drops a file to the not-yet running VSCode, the open-file event fires even before - * the app-ready event. We listen very early for open-file and remember this upon startup as path to open. - */ - const macOpenFiles: string[] = []; - (globalThis as { macOpenFiles?: string[] }).macOpenFiles = macOpenFiles; - app.on('open-file', function (event, path) { - macOpenFiles.push(path); - }); - - /** - * macOS: react to open-url requests. - */ - const openUrls: string[] = []; - const onOpenUrl = - function (event: { preventDefault: () => void }, url: string) { - event.preventDefault(); - - openUrls.push(url); - }; - - app.on('will-finish-launching', function () { - app.on('open-url', onOpenUrl); - }); - - (globalThis as { getOpenUrls?: () => string[] }).getOpenUrls = function () { - app.removeListener('open-url', onOpenUrl); - - return openUrls; - }; -} - -function getCodeCachePath(): string | undefined { - - // explicitly disabled via CLI args - if (process.argv.indexOf('--no-cached-data') > 0) { - return undefined; - } - - // running out of sources - if (process.env['VSCODE_DEV']) { - return undefined; - } - - // require commit id - const commit = product.commit; - if (!commit) { - return undefined; - } - - return path.join(userDataPath, 'CachedData', commit); -} - -async function mkdirpIgnoreError(dir: string | undefined): Promise { - if (typeof dir === 'string') { - try { - await fs.promises.mkdir(dir, { recursive: true }); - - return dir; - } catch (error) { - // ignore - } - } - - return undefined; -} - -//#region NLS Support - -function processZhLocale(appLocale: string): string { - if (appLocale.startsWith('zh')) { - const region = appLocale.split('-')[1]; - - // On Windows and macOS, Chinese languages returned by - // app.getPreferredSystemLanguages() start with zh-hans - // for Simplified Chinese or zh-hant for Traditional Chinese, - // so we can easily determine whether to use Simplified or Traditional. - // However, on Linux, Chinese languages returned by that same API - // are of the form zh-XY, where XY is a country code. - // For China (CN), Singapore (SG), and Malaysia (MY) - // country codes, assume they use Simplified Chinese. - // For other cases, assume they use Traditional. - if (['hans', 'cn', 'sg', 'my'].includes(region)) { - return 'zh-cn'; - } - - return 'zh-tw'; - } - - return appLocale; -} - -/** - * Resolve the NLS configuration - */ -async function resolveNlsConfiguration(): Promise { - - // First, we need to test a user defined locale. - // If it fails we try the app locale. - // If that fails we fall back to English. - - const nlsConfiguration = nlsConfigurationPromise ? await nlsConfigurationPromise : undefined; - if (nlsConfiguration) { - return nlsConfiguration; - } - - // Try to use the app locale which is only valid - // after the app ready event has been fired. - - let userLocale = app.getLocale(); - if (!userLocale) { - return { - userLocale: 'en', - osLocale, - resolvedLanguage: 'en', - defaultMessagesFile: path.join(import.meta.dirname, 'nls.messages.json'), - - // NLS: below 2 are a relic from old times only used by vscode-nls and deprecated - locale: 'en', - availableLanguages: {} - }; - } - - // See above the comment about the loader and case sensitiveness - userLocale = processZhLocale(userLocale.toLowerCase()); - - return resolveNLSConfiguration({ - userLocale, - osLocale, - commit: product.commit, - userDataPath, - nlsMetadataPath: import.meta.dirname - }); -} - -/** - * Language tags are case insensitive however an ESM loader is case sensitive - * To make this work on case preserving & insensitive FS we do the following: - * the language bundles have lower case language tags and we always lower case - * the locale we receive from the user or OS. - */ -function getUserDefinedLocale(argvConfig: IArgvConfig): string | undefined { - const locale = args['locale']; - if (locale) { - return locale.toLowerCase(); // a directly provided --locale always wins - } - - return typeof argvConfig?.locale === 'string' ? argvConfig.locale.toLowerCase() : undefined; -} - -//#endregion diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.ts b/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.ts deleted file mode 100644 index e9cf69cb9..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-browser/workbench/workbench.ts +++ /dev/null @@ -1,644 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/* eslint-disable no-restricted-globals */ - -(async function () { - - // Add a perf entry right from the top - performance.mark('code/didStartRenderer'); - - type ISandboxConfiguration = import('../../../base/parts/sandbox/common/sandboxTypes.js').ISandboxConfiguration; - type ILoadResult = import('../../../platform/window/electron-browser/window.js').ILoadResult; - type ILoadOptions = import('../../../platform/window/electron-browser/window.js').ILoadOptions; - type INativeWindowConfiguration = import('../../../platform/window/common/window.ts').INativeWindowConfiguration; - type IMainWindowSandboxGlobals = import('../../../base/parts/sandbox/electron-browser/globals.js').IMainWindowSandboxGlobals; - type IDesktopMain = import('../../../workbench/electron-browser/desktop.main.js').IDesktopMain; - - const preloadGlobals = (window as unknown as { vscode: IMainWindowSandboxGlobals }).vscode; // defined by preload.ts - const safeProcess = preloadGlobals.process; - - //#region Splash Screen Helpers - - function showSplash(configuration: INativeWindowConfiguration) { - performance.mark('code/willShowPartsSplash'); - showDefaultSplash(configuration); - performance.mark('code/didShowPartsSplash'); - } - - function showDefaultSplash(configuration: INativeWindowConfiguration) { - let data = configuration.partsSplash; - if (data) { - if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { - if ((configuration.colorScheme.dark && data.baseTheme !== 'hc-black') || (!configuration.colorScheme.dark && data.baseTheme !== 'hc-light')) { - data = undefined; // high contrast mode has been turned by the OS -> ignore stored colors and layouts - } - } else if (configuration.autoDetectColorScheme) { - if ((configuration.colorScheme.dark && data.baseTheme !== 'vs-dark') || (!configuration.colorScheme.dark && data.baseTheme !== 'vs')) { - data = undefined; // OS color scheme is tracked and has changed - } - } - } - - // developing an extension -> ignore stored layouts - if (data && configuration.extensionDevelopmentPath) { - data.layoutInfo = undefined; - } - - // minimal color configuration (works with or without persisted data) - let baseTheme; - let shellBackground; - let shellForeground; - if (data) { - baseTheme = data.baseTheme; - shellBackground = data.colorInfo.editorBackground; - shellForeground = data.colorInfo.foreground; - } else if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { - if (configuration.colorScheme.dark) { - baseTheme = 'hc-black'; - shellBackground = '#000000'; - shellForeground = '#FFFFFF'; - } else { - baseTheme = 'hc-light'; - shellBackground = '#FFFFFF'; - shellForeground = '#000000'; - } - } else if (configuration.autoDetectColorScheme) { - if (configuration.colorScheme.dark) { - baseTheme = 'vs-dark'; - shellBackground = '#1E1E1E'; - shellForeground = '#CCCCCC'; - } else { - baseTheme = 'vs'; - shellBackground = '#FFFFFF'; - shellForeground = '#000000'; - } - } - - const style = document.createElement('style'); - style.className = 'initialShellColors'; - window.document.head.appendChild(style); - style.textContent = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`; - - // set zoom level as soon as possible - if (typeof data?.zoomLevel === 'number' && typeof preloadGlobals?.webFrame?.setZoomLevel === 'function') { - preloadGlobals.webFrame.setZoomLevel(data.zoomLevel); - } - - // restore parts if possible (we might not always store layout info) - if (data?.layoutInfo) { - const { layoutInfo, colorInfo } = data; - const modernUI = layoutInfo.modernUI === true; - const floatingMargin = 4; - const floatingOuterMargin = floatingMargin * 2; - const floatingBorderWidth = 1; - - const splash = document.createElement('div'); - splash.id = 'monaco-parts-splash'; - splash.className = baseTheme ?? 'vs-dark'; - - if (layoutInfo.windowBorder && colorInfo.windowBorder) { - const borderElement = document.createElement('div'); - borderElement.style.position = 'absolute'; - borderElement.style.width = 'calc(100vw - 2px)'; - borderElement.style.height = 'calc(100vh - 2px)'; - borderElement.style.zIndex = '1'; // allow border above other elements - borderElement.style.border = `1px solid var(--window-border-color)`; - borderElement.style.setProperty('--window-border-color', colorInfo.windowBorder); - - if (layoutInfo.windowBorderRadius) { - borderElement.style.borderRadius = layoutInfo.windowBorderRadius; - } - - splash.appendChild(borderElement); - } - - const setBounds = (element: HTMLElement, bounds: { top: number; bottom?: number; left?: number; right?: number; width?: number; height?: number }) => { - element.style.position = 'absolute'; - element.style.top = `${bounds.top}px`; - if (typeof bounds.bottom === 'number') { - element.style.bottom = `${bounds.bottom}px`; - } - if (typeof bounds.left === 'number') { - element.style.left = `${bounds.left}px`; - } - if (typeof bounds.right === 'number') { - element.style.right = `${bounds.right}px`; - } - if (typeof bounds.width === 'number') { - element.style.width = `${bounds.width}px`; - } - if (typeof bounds.height === 'number') { - element.style.height = `${bounds.height}px`; - } - }; - - const setPartBounds = (element: HTMLElement, bounds: { top: number; left: number; width: number; height: number }) => { - element.style.position = 'absolute'; - element.style.top = `${bounds.top}px`; - element.style.left = `${bounds.left}px`; - element.style.width = `${bounds.width}px`; - element.style.height = `${bounds.height}px`; - }; - - const applyFloatingCardStyles = (element: HTMLElement, backgroundColor: string | undefined) => { - element.style.boxSizing = 'border-box'; - element.style.border = `${floatingBorderWidth}px solid ${colorInfo.agentsPanelBorder ?? colorInfo.editorGroupBorder ?? 'transparent'}`; - element.style.borderRadius = '8px'; - element.style.backgroundColor = backgroundColor ?? colorInfo.editorBackground ?? colorInfo.background; - element.style.overflow = 'hidden'; - }; - - const contentTop = layoutInfo.titleBarHeight; - const contentBottom = layoutInfo.statusBarHeight; - const contentHeight = `calc(100% - ${contentTop + contentBottom}px)`; - const activityHeight = modernUI ? `calc(100% - ${contentTop + contentBottom + floatingMargin}px)` : contentHeight; - - if (layoutInfo.auxiliaryBarWidth === Number.MAX_SAFE_INTEGER) { - // if auxiliary bar is maximized, it goes as wide as the - // window width but leaving room for activity bar - layoutInfo.auxiliaryBarWidth = window.innerWidth - layoutInfo.activityBarWidth; - } else { - // otherwise adjust for other parts sizes if not maximized - layoutInfo.auxiliaryBarWidth = Math.min(layoutInfo.auxiliaryBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth + layoutInfo.sideBarWidth)); - } - layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth + layoutInfo.auxiliaryBarWidth)); - - // part: title - if (layoutInfo.titleBarHeight > 0) { - const titleDiv = document.createElement('div'); - titleDiv.style.position = 'absolute'; - titleDiv.style.width = '100%'; - titleDiv.style.height = `${layoutInfo.titleBarHeight}px`; - titleDiv.style.left = '0'; - titleDiv.style.top = '0'; - titleDiv.style.backgroundColor = modernUI ? 'transparent' : `${colorInfo.titleBarBackground}`; - (titleDiv.style as CSSStyleDeclaration & { '-webkit-app-region': string })['-webkit-app-region'] = 'drag'; - splash.appendChild(titleDiv); - - if (!modernUI && colorInfo.titleBarBorder) { - const titleBorder = document.createElement('div'); - titleBorder.style.position = 'absolute'; - titleBorder.style.width = '100%'; - titleBorder.style.height = '1px'; - titleBorder.style.left = '0'; - titleBorder.style.bottom = '0'; - titleBorder.style.borderBottom = `1px solid ${colorInfo.titleBarBorder}`; - titleDiv.appendChild(titleBorder); - } - } - - // part: activity bar - if (layoutInfo.activityBarWidth > 0) { - const activityDiv = document.createElement('div'); - activityDiv.style.position = 'absolute'; - activityDiv.style.width = `${layoutInfo.activityBarWidth}px`; - activityDiv.style.height = activityHeight; - activityDiv.style.top = `${contentTop}px`; - if (layoutInfo.sideBarSide === 'left') { - activityDiv.style.left = '0'; - } else { - activityDiv.style.right = '0'; - } - activityDiv.style.backgroundColor = modernUI ? 'transparent' : `${colorInfo.activityBarBackground}`; - splash.appendChild(activityDiv); - - if (!modernUI && colorInfo.activityBarBorder) { - const activityBorderDiv = document.createElement('div'); - activityBorderDiv.style.position = 'absolute'; - activityBorderDiv.style.width = '1px'; - activityBorderDiv.style.height = '100%'; - activityBorderDiv.style.top = '0'; - if (layoutInfo.sideBarSide === 'left') { - activityBorderDiv.style.right = '0'; - activityBorderDiv.style.borderRight = `1px solid ${colorInfo.activityBarBorder}`; - } else { - activityBorderDiv.style.left = '0'; - activityBorderDiv.style.borderLeft = `1px solid ${colorInfo.activityBarBorder}`; - } - activityDiv.appendChild(activityBorderDiv); - } - } - - // part: side bar - if (layoutInfo.sideBarWidth > 0) { - const sideDiv = document.createElement('div'); - if (modernUI && layoutInfo.partBounds?.sideBar) { - setPartBounds(sideDiv, layoutInfo.partBounds.sideBar); - } else if (layoutInfo.sideBarSide === 'left') { - setBounds(sideDiv, { - top: contentTop, - bottom: modernUI ? contentBottom + floatingMargin : contentBottom, - left: layoutInfo.activityBarWidth + (modernUI ? floatingMargin : 0), - width: modernUI ? Math.max(0, layoutInfo.sideBarWidth - floatingOuterMargin - floatingBorderWidth * 2) : layoutInfo.sideBarWidth - }); - } else { - setBounds(sideDiv, { - top: contentTop, - bottom: modernUI ? contentBottom + floatingMargin : contentBottom, - right: layoutInfo.activityBarWidth + (modernUI ? floatingMargin : 0), - width: modernUI ? Math.max(0, layoutInfo.sideBarWidth - floatingOuterMargin - floatingBorderWidth * 2) : layoutInfo.sideBarWidth - }); - } - if (modernUI) { - applyFloatingCardStyles(sideDiv, colorInfo.agentsPanelBackground ?? colorInfo.sideBarBackground); - } else { - sideDiv.style.backgroundColor = `${colorInfo.sideBarBackground}`; - } - splash.appendChild(sideDiv); - - if (!modernUI && colorInfo.sideBarBorder) { - const sideBorderDiv = document.createElement('div'); - sideBorderDiv.style.position = 'absolute'; - sideBorderDiv.style.width = '1px'; - sideBorderDiv.style.height = '100%'; - sideBorderDiv.style.top = '0'; - sideBorderDiv.style.right = '0'; - if (layoutInfo.sideBarSide === 'left') { - sideBorderDiv.style.borderRight = `1px solid ${colorInfo.sideBarBorder}`; - } else { - sideBorderDiv.style.left = '0'; - sideBorderDiv.style.borderLeft = `1px solid ${colorInfo.sideBarBorder}`; - } - sideDiv.appendChild(sideBorderDiv); - } - } - - // part: auxiliary sidebar - if (layoutInfo.auxiliaryBarWidth > 0) { - const auxSideDiv = document.createElement('div'); - if (modernUI && layoutInfo.partBounds?.auxiliaryBar) { - setPartBounds(auxSideDiv, layoutInfo.partBounds.auxiliaryBar); - } else if (layoutInfo.sideBarSide === 'left') { - setBounds(auxSideDiv, { - top: contentTop, - bottom: modernUI ? contentBottom + floatingMargin : contentBottom, - right: modernUI ? floatingOuterMargin : 0, - width: modernUI ? Math.max(0, layoutInfo.auxiliaryBarWidth - floatingOuterMargin - floatingMargin - floatingBorderWidth * 2) : layoutInfo.auxiliaryBarWidth - }); - } else { - setBounds(auxSideDiv, { - top: contentTop, - bottom: modernUI ? contentBottom + floatingMargin : contentBottom, - left: modernUI ? floatingOuterMargin : 0, - width: modernUI ? Math.max(0, layoutInfo.auxiliaryBarWidth - floatingOuterMargin - floatingMargin - floatingBorderWidth * 2) : layoutInfo.auxiliaryBarWidth - }); - } - if (modernUI) { - applyFloatingCardStyles(auxSideDiv, colorInfo.sideBarBackground); - } else { - auxSideDiv.style.backgroundColor = `${colorInfo.sideBarBackground}`; - } - splash.appendChild(auxSideDiv); - - if (!modernUI && colorInfo.sideBarBorder) { - const auxSideBorderDiv = document.createElement('div'); - auxSideBorderDiv.style.position = 'absolute'; - auxSideBorderDiv.style.width = '1px'; - auxSideBorderDiv.style.height = '100%'; - auxSideBorderDiv.style.top = '0'; - if (layoutInfo.sideBarSide === 'left') { - auxSideBorderDiv.style.left = '0'; - auxSideBorderDiv.style.borderLeft = `1px solid ${colorInfo.sideBarBorder}`; - } else { - auxSideBorderDiv.style.right = '0'; - auxSideBorderDiv.style.borderRight = `1px solid ${colorInfo.sideBarBorder}`; - } - auxSideDiv.appendChild(auxSideBorderDiv); - } - } - - if (modernUI && (layoutInfo.partBounds?.editor || !layoutInfo.partBounds)) { - const editorDiv = document.createElement('div'); - if (layoutInfo.partBounds?.editor) { - setPartBounds(editorDiv, layoutInfo.partBounds.editor); - } else { - const editorLeft = (layoutInfo.sideBarSide === 'left' ? layoutInfo.activityBarWidth + layoutInfo.sideBarWidth : layoutInfo.auxiliaryBarWidth) + floatingMargin; - const editorRight = (layoutInfo.sideBarSide === 'left' ? layoutInfo.auxiliaryBarWidth : layoutInfo.activityBarWidth + layoutInfo.sideBarWidth) + floatingMargin; - setBounds(editorDiv, { - top: contentTop, - bottom: contentBottom + floatingMargin, - left: editorLeft, - right: editorRight - }); - } - applyFloatingCardStyles(editorDiv, colorInfo.editorBackground); - splash.appendChild(editorDiv); - } - - if (modernUI && layoutInfo.partBounds?.panel) { - const panelDiv = document.createElement('div'); - setPartBounds(panelDiv, layoutInfo.partBounds.panel); - applyFloatingCardStyles(panelDiv, colorInfo.panelBackground ?? colorInfo.editorBackground); - splash.appendChild(panelDiv); - } - - // part: statusbar - if (layoutInfo.statusBarHeight > 0) { - const statusDiv = document.createElement('div'); - statusDiv.style.position = 'absolute'; - statusDiv.style.width = '100%'; - statusDiv.style.height = `${layoutInfo.statusBarHeight}px`; - statusDiv.style.bottom = '0'; - statusDiv.style.left = '0'; - if (modernUI) { - statusDiv.style.backgroundColor = 'transparent'; - } else if (configuration.workspace && colorInfo.statusBarBackground) { - statusDiv.style.backgroundColor = colorInfo.statusBarBackground; - } else if (!configuration.workspace && colorInfo.statusBarNoFolderBackground) { - statusDiv.style.backgroundColor = colorInfo.statusBarNoFolderBackground; - } - splash.appendChild(statusDiv); - - if (!modernUI && colorInfo.statusBarBorder) { - const statusBorderDiv = document.createElement('div'); - statusBorderDiv.style.position = 'absolute'; - statusBorderDiv.style.width = '100%'; - statusBorderDiv.style.height = '1px'; - statusBorderDiv.style.top = '0'; - statusBorderDiv.style.borderTop = `1px solid ${colorInfo.statusBarBorder}`; - statusDiv.appendChild(statusBorderDiv); - } - } - - window.document.body.appendChild(splash); - } - } - - //#endregion - - //#region Window Helpers - - async function load(options: ILoadOptions): Promise> { - - // Window Configuration from Preload Script - const configuration = await resolveWindowConfiguration(); - - // Signal before import() - options?.beforeImport?.(configuration); - - // Developer settings - const { enableDeveloperKeybindings, removeDeveloperKeybindingsAfterLoad, developerDeveloperKeybindingsDisposable, forceDisableShowDevtoolsOnError } = setupDeveloperKeybindings(configuration, options); - - // NLS - setupNLS(configuration); - - // Compute base URL and set as global - const baseUrl = new URL(`${fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out/`); - globalThis._VSCODE_FILE_ROOT = baseUrl.toString(); - - // Set product configuration as global (used e.g. to select the ASAR path in `amdX`) - globalThis._VSCODE_PRODUCT_JSON = { ...configuration.product }; - - // Dev only: CSS import map tricks - setupCSSImportMaps(configuration, baseUrl); - - // ESM Import - try { - let workbenchUrl: string; - if (!!safeProcess.env['VSCODE_DEV'] && globalThis._VSCODE_USE_RELATIVE_IMPORTS) { - workbenchUrl = '../../../whiteboard/whiteboard.desktop.main.js'; // Review Desktop fork - } else { - workbenchUrl = new URL(`vs/whiteboard/whiteboard.desktop.main.js`, baseUrl).href; - } - - const result = await import(workbenchUrl); - if (developerDeveloperKeybindingsDisposable && removeDeveloperKeybindingsAfterLoad) { - developerDeveloperKeybindingsDisposable(); - } - - return { result, configuration }; - } catch (error) { - onUnexpectedError(error, enableDeveloperKeybindings && !forceDisableShowDevtoolsOnError); - - throw error; - } - } - - async function resolveWindowConfiguration() { - const timeout = setTimeout(() => { console.error(`[resolve window config] Could not resolve window configuration within 10 seconds, but will continue to wait...`); }, 10000); - performance.mark('code/willWaitForWindowConfig'); - - const configuration = await preloadGlobals.context.resolveConfiguration() as T; - performance.mark('code/didWaitForWindowConfig'); - - clearTimeout(timeout); - - return configuration; - } - - function setupDeveloperKeybindings(configuration: T, options: ILoadOptions) { - const { - forceEnableDeveloperKeybindings, - disallowReloadKeybinding, - removeDeveloperKeybindingsAfterLoad, - forceDisableShowDevtoolsOnError - } = typeof options?.configureDeveloperSettings === 'function' ? options.configureDeveloperSettings(configuration) : { - forceEnableDeveloperKeybindings: false, - disallowReloadKeybinding: false, - removeDeveloperKeybindingsAfterLoad: false, - forceDisableShowDevtoolsOnError: false - }; - - const isDev = !!safeProcess.env['VSCODE_DEV']; - const enableDeveloperKeybindings = Boolean(isDev || forceEnableDeveloperKeybindings); - let developerDeveloperKeybindingsDisposable: Function | undefined = undefined; - if (enableDeveloperKeybindings) { - developerDeveloperKeybindingsDisposable = registerDeveloperKeybindings(disallowReloadKeybinding); - } - - return { - enableDeveloperKeybindings, - removeDeveloperKeybindingsAfterLoad, - developerDeveloperKeybindingsDisposable, - forceDisableShowDevtoolsOnError - }; - } - - function registerDeveloperKeybindings(disallowReloadKeybinding: boolean | undefined): Function { - const ipcRenderer = preloadGlobals.ipcRenderer; - - const extractKey = - function (e: KeyboardEvent) { - return [ - e.ctrlKey ? 'ctrl-' : '', - e.metaKey ? 'meta-' : '', - e.altKey ? 'alt-' : '', - e.shiftKey ? 'shift-' : '', - e.keyCode - ].join(''); - }; - - // Devtools & reload support - const TOGGLE_DEV_TOOLS_KB = (safeProcess.platform === 'darwin' ? 'meta-alt-73' : 'ctrl-shift-73'); // mac: Cmd-Alt-I, rest: Ctrl-Shift-I - const TOGGLE_DEV_TOOLS_KB_ALT = '123'; // F12 - const RELOAD_KB = (safeProcess.platform === 'darwin' ? 'meta-82' : 'ctrl-82'); // mac: Cmd-R, rest: Ctrl-R - - let listener: ((e: KeyboardEvent) => void) | undefined = function (e) { - const key = extractKey(e); - if (key === TOGGLE_DEV_TOOLS_KB || key === TOGGLE_DEV_TOOLS_KB_ALT) { - ipcRenderer.send('vscode:toggleDevTools'); - } else if (key === RELOAD_KB && !disallowReloadKeybinding) { - ipcRenderer.send('vscode:reloadWindow'); - } - }; - - window.addEventListener('keydown', listener); - - return function () { - if (listener) { - window.removeEventListener('keydown', listener); - listener = undefined; - } - }; - } - - function setupNLS(configuration: T): void { - globalThis._VSCODE_NLS_MESSAGES = configuration.nls.messages; - globalThis._VSCODE_NLS_LANGUAGE = configuration.nls.language; - - let language = configuration.nls.language || 'en'; - if (language === 'zh-tw') { - language = 'zh-Hant'; - } else if (language === 'zh-cn') { - language = 'zh-Hans'; - } - - window.document.documentElement.setAttribute('lang', language); - } - - function onUnexpectedError(error: string | Error, showDevtoolsOnError: boolean): void { - if (showDevtoolsOnError) { - const ipcRenderer = preloadGlobals.ipcRenderer; - ipcRenderer.send('vscode:openDevTools'); - } - - console.error(`[uncaught exception]: ${error}`); - - if (error && typeof error !== 'string' && error.stack) { - console.error(error.stack); - } - } - - function fileUriFromPath(path: string, config: { isWindows?: boolean; scheme?: string; fallbackAuthority?: string }): string { - - // Since we are building a URI, we normalize any backslash - // to slashes and we ensure that the path begins with a '/'. - let pathName = path.replace(/\\/g, '/'); - if (pathName.length > 0 && pathName.charAt(0) !== '/') { - pathName = `/${pathName}`; - } - - let uri: string; - - // Windows: in order to support UNC paths (which start with '//') - // that have their own authority, we do not use the provided authority - // but rather preserve it. - if (config.isWindows && pathName.startsWith('//')) { - uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); - } - - // Otherwise we optionally add the provided authority if specified - else { - uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); - } - - return uri.replace(/#/g, '%23'); - } - - function setupCSSImportMaps(configuration: T, baseUrl: URL) { - - // DEV --------------------------------------------------------------------------------------- - // DEV: This is for development and enables loading CSS via import-statements via import-maps. - // DEV: For each CSS modules that we have we defined an entry in the import map that maps to - // DEV: a blob URL that loads the CSS via a dynamic @import-rule. - // DEV --------------------------------------------------------------------------------------- - - if (globalThis._VSCODE_DISABLE_CSS_IMPORT_MAP) { - return; // disabled in certain development setups - } - - if (Array.isArray(configuration.cssModules) && configuration.cssModules.length > 0) { - performance.mark('code/willAddCssLoader'); - - globalThis._VSCODE_CSS_LOAD = function (url) { - const link = document.createElement('link'); - link.setAttribute('rel', 'stylesheet'); - link.setAttribute('type', 'text/css'); - link.setAttribute('href', url); - - window.document.head.appendChild(link); - }; - - const importMap: { imports: Record } = { imports: {} }; - for (const cssModule of configuration.cssModules) { - const cssUrl = new URL(cssModule, baseUrl).href; - const jsSrc = `globalThis._VSCODE_CSS_LOAD('${cssUrl}');\n`; - const blob = new Blob([jsSrc], { type: 'application/javascript' }); - importMap.imports[cssUrl] = URL.createObjectURL(blob); - } - - const ttp = window.trustedTypes?.createPolicy('vscode-bootstrapImportMap', { createScript(value) { return value; }, }); - const importMapSrc = JSON.stringify(importMap, undefined, 2); - const importMapScript = document.createElement('script'); - importMapScript.type = 'importmap'; - importMapScript.setAttribute('nonce', '0c6a828f1297'); - // @ts-expect-error - importMapScript.textContent = ttp?.createScript(importMapSrc) ?? importMapSrc; - window.document.head.appendChild(importMapScript); - - performance.mark('code/didAddCssLoader'); - } - } - - //#endregion - - const { result, configuration } = await load( - { - configureDeveloperSettings: function (windowConfig) { - return { - // disable automated devtools opening on error when running extension tests - // as this can lead to nondeterministic test execution (devtools steals focus) - forceDisableShowDevtoolsOnError: typeof windowConfig.extensionTestsPath === 'string' || windowConfig['enable-smoke-test-driver'] === true, - // enable devtools keybindings in extension development window - forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath) && windowConfig.extensionDevelopmentPath.length > 0, - removeDeveloperKeybindingsAfterLoad: true - }; - }, - beforeImport: function (windowConfig) { - - // Show our splash as early as possible - showSplash(windowConfig); - - // Code windows have a `vscodeWindowId` property to identify them - Object.defineProperty(window, 'vscodeWindowId', { - get: () => windowConfig.windowId - }); - - // It looks like browsers only lazily enable - // the element when needed. Since we - // leverage canvas elements in our code in many - // locations, we try to help the browser to - // initialize canvas when it is idle, right - // before we wait for the scripts to be loaded. - window.requestIdleCallback(() => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - context?.clearRect(0, 0, canvas.width, canvas.height); - canvas.remove(); - }, { timeout: 50 }); - - // Track import() perf - performance.mark('code/willLoadWorkbenchMain'); - } - } - ); - - // Mark start of workbench - performance.mark('code/didLoadWorkbenchMain'); - - // Load workbench - result.main(configuration); -}()); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-main/main.ts b/apps/whiteboard-desktop/code-oss/src/vs/code/electron-main/main.ts deleted file mode 100644 index eea380cdd..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/code/electron-main/main.ts +++ /dev/null @@ -1,726 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import '../../platform/update/common/update.config.contribution.js'; - -import { app, dialog } from 'electron'; -import { unlinkSync, promises } from 'fs'; -import { URI } from '../../base/common/uri.js'; -import { coalesce, distinct } from '../../base/common/arrays.js'; -import { Promises, retry } from '../../base/common/async.js'; -import { toErrorMessage } from '../../base/common/errorMessage.js'; -import { ExpectedError, setUnexpectedErrorHandler } from '../../base/common/errors.js'; -import { IPathWithLineAndColumn, isValidBasename, parseLineAndColumnAware, sanitizeFilePath } from '../../base/common/extpath.js'; -import { Event } from '../../base/common/event.js'; -import { getPathLabel } from '../../base/common/labels.js'; -import { Schemas } from '../../base/common/network.js'; -import { basename, join, resolve } from '../../base/common/path.js'; -import { mark } from '../../base/common/performance.js'; -import { IProcessEnvironment, isLinux, isMacintosh, isWindows, OS } from '../../base/common/platform.js'; -import { cwd } from '../../base/common/process.js'; -import { rtrim, trim } from '../../base/common/strings.js'; -import { Promises as FSPromises } from '../../base/node/pfs.js'; -import { ProxyChannel } from '../../base/parts/ipc/common/ipc.js'; -import { Client as NodeIPCClient } from '../../base/parts/ipc/common/ipc.net.js'; -import { connect as nodeIPCConnect, serve as nodeIPCServe, Server as NodeIPCServer, XDG_RUNTIME_DIR } from '../../base/parts/ipc/node/ipc.net.js'; -import { CodeApplication } from './app.js'; -import { localize } from '../../nls.js'; -import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; -import { ConfigurationService } from '../../platform/configuration/common/configurationService.js'; -import { IDiagnosticsMainService } from '../../platform/diagnostics/electron-main/diagnosticsMainService.js'; -import { DiagnosticsService } from '../../platform/diagnostics/node/diagnosticsService.js'; -import { NativeParsedArgs } from '../../platform/environment/common/argv.js'; -import { EnvironmentMainService, IEnvironmentMainService } from '../../platform/environment/electron-main/environmentMainService.js'; -import { addArg, parseMainProcessArgv } from '../../platform/environment/node/argvHelper.js'; -import { createWaitMarkerFileSync } from '../../platform/environment/node/wait.js'; -import { IFileService } from '../../platform/files/common/files.js'; -import { FileService } from '../../platform/files/common/fileService.js'; -import { DiskFileSystemProvider } from '../../platform/files/node/diskFileSystemProvider.js'; -import { SyncDescriptor } from '../../platform/instantiation/common/descriptors.js'; -import { IInstantiationService, ServicesAccessor } from '../../platform/instantiation/common/instantiation.js'; -import { InstantiationService } from '../../platform/instantiation/common/instantiationService.js'; -import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; -import { ILaunchMainService } from '../../platform/launch/electron-main/launchMainService.js'; -import { ILifecycleMainService, LifecycleMainService } from '../../platform/lifecycle/electron-main/lifecycleMainService.js'; -import { BufferLogger } from '../../platform/log/common/bufferLog.js'; -import { ConsoleMainLogger, getLogLevel, ILoggerService, ILogService, isDevConsoleLogForwardingEnabled, registerDevConsoleLogForwarder } from '../../platform/log/common/log.js'; -import product from '../../platform/product/common/product.js'; -import { IProductService } from '../../platform/product/common/productService.js'; -import { IProtocolMainService } from '../../platform/protocol/electron-main/protocol.js'; -import { ProtocolMainService } from '../../platform/protocol/electron-main/protocolMainService.js'; -import { ITunnelService } from '../../platform/tunnel/common/tunnel.js'; -import { TunnelService } from '../../platform/tunnel/node/tunnelService.js'; -import { IRequestService } from '../../platform/request/common/request.js'; -import { RequestService } from '../../platform/request/electron-utility/requestService.js'; -import { ISignService } from '../../platform/sign/common/sign.js'; -import { SignService } from '../../platform/sign/node/signService.js'; -import { IStateReadService, IStateService } from '../../platform/state/node/state.js'; -import { NullTelemetryService } from '../../platform/telemetry/common/telemetryUtils.js'; -import { IThemeMainService } from '../../platform/theme/electron-main/themeMainService.js'; -import { IUserDataProfilesMainService, UserDataProfilesMainService } from '../../platform/userDataProfile/electron-main/userDataProfile.js'; -import { IPolicyService, NullPolicyService } from '../../platform/policy/common/policy.js'; -import { NativePolicyService } from '../../platform/policy/node/nativePolicyService.js'; -import { FilePolicyService } from '../../platform/policy/common/filePolicyService.js'; -import { MultiplexPolicyService } from '../../platform/policy/common/multiplexPolicyService.js'; -import { GITHUB_COPILOT_MACOS_BUNDLE_ID, GITHUB_COPILOT_WIN32_POLICY_NAME, GITHUB_COPILOT_WIN32_REGISTRY_PATH, INativeManagedSettingsService, IFileManagedSettingsService, MANAGED_SETTINGS_FILE_NAME, MANAGED_SETTINGS_LINUX_FILE_PATH, MANAGED_SETTINGS_MACOS_FILE_PATH, MANAGED_SETTINGS_WINDOWS_DIR, NullNativeManagedSettingsService, NullFileManagedSettingsService } from '../../platform/policy/common/copilotManagedSettings.js'; -import { FileManagedSettingsService } from '../../platform/policy/common/fileManagedSettingsService.js'; -import { NativeManagedSettingsService } from '../../platform/policy/node/nativeManagedSettingsService.js'; -import { DisposableStore } from '../../base/common/lifecycle.js'; -import { IUriIdentityService } from '../../platform/uriIdentity/common/uriIdentity.js'; -import { UriIdentityService } from '../../platform/uriIdentity/common/uriIdentityService.js'; -import { ILoggerMainService, LoggerMainService } from '../../platform/log/electron-main/loggerService.js'; -import { LogService } from '../../platform/log/common/logService.js'; -import { massageMessageBoxOptions } from '../../platform/dialogs/common/dialogs.js'; -import { SaveStrategy, StateService } from '../../platform/state/node/stateService.js'; -import { FileUserDataProvider } from '../../platform/userData/common/fileUserDataProvider.js'; -import { addUNCHostToAllowlist, getUNCHost } from '../../base/node/unc.js'; -import { ThemeMainService } from '../../platform/theme/electron-main/themeMainServiceImpl.js'; -import { LINUX_SYSTEM_POLICY_FILE_PATH } from '../../base/common/policy.js'; - -/** - * The main VS Code entry point. - * - * Note: This class can exist more than once for example when VS Code is already - * running and a second instance is started from the command line. It will always - * try to communicate with an existing instance to prevent that 2 VS Code instances - * are running at the same time. - */ -class CodeMain { - - main(): void { - try { - this.startup(); - } catch (error) { - console.error(error.message); - app.exit(1); - } - } - - private async startup(): Promise { - - // Set the error handler early enough so that we are not getting the - // default electron error dialog popping up - setUnexpectedErrorHandler(err => console.error(err)); - - // Graphical DevBoxes run without a desktop screen-reader daemon. Keep - // the native Linux accessibility provider enabled when Review Desktop - // explicitly opts into the generic Computer Use backend. - if (process.env['DEV_FAST_WHITEBOARD_FORCE_ACCESSIBILITY'] === '1') { - app.setAccessibilitySupportEnabled(true); - } - - // Create services - const [instantiationService, instanceEnvironment, environmentMainService, configurationService, stateMainService, bufferLogger, productService, userDataProfilesMainService] = this.createServices(); - - try { - - // Init services - try { - await this.initServices(environmentMainService, userDataProfilesMainService, configurationService, stateMainService, productService); - } catch (error) { - - // Show a dialog for errors that can be resolved by the user - this.handleStartupDataDirError(environmentMainService, productService, error); - - throw error; - } - - // Startup - await instantiationService.invokeFunction(async accessor => { - const logService = accessor.get(ILogService); - const lifecycleMainService = accessor.get(ILifecycleMainService); - const fileService = accessor.get(IFileService); - const loggerService = accessor.get(ILoggerService); - - // Create the main IPC server by trying to be the server - // If this throws an error it means we are not the first - // instance of VS Code running and so we would quit. - const mainProcessNodeIpcServer = await this.claimInstance(logService, environmentMainService, lifecycleMainService, instantiationService, productService, true); - - // Write a lockfile to indicate an instance is running - // (https://github.com/microsoft/vscode/issues/127861#issuecomment-877417451) - FSPromises.writeFile(environmentMainService.mainLockfile, String(process.pid)).catch(err => { - logService.warn(`app#startup(): Error writing main lockfile: ${err.stack}`); - }); - - // Delay creation of spdlog for perf reasons (https://github.com/microsoft/vscode/issues/72906) - bufferLogger.logger = loggerService.createLogger('main', { name: localize('mainLog', "Main") }); - - // Lifecycle - Event.once(lifecycleMainService.onWillShutdown)(evt => { - fileService.dispose(); - configurationService.dispose(); - evt.join('instanceLockfile', promises.unlink(environmentMainService.mainLockfile).catch(() => { /* ignored */ })); - }); - - // Check if Inno Setup is running. Briefly wait for the updating mutex to be released before refusing to launch. - const innoSetupActive = await this.checkInnoSetupMutex(productService, logService); - if (innoSetupActive) { - const message = `${productService.nameShort} is currently being updated. Please wait for the update to complete before launching.`; - instantiationService.invokeFunction(this.quit, new Error(message)); - return; - } - - return instantiationService.createInstance(CodeApplication, mainProcessNodeIpcServer, instanceEnvironment).startup(); - }); - } catch (error) { - instantiationService.invokeFunction(this.quit, error); - } - } - - private createServices(): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateService, BufferLogger, IProductService, UserDataProfilesMainService] { - const services = new ServiceCollection(); - const disposables = new DisposableStore(); - process.once('exit', () => disposables.dispose()); - - // Product - const productService = { _serviceBrand: undefined, ...product }; - services.set(IProductService, productService); - - // Environment - const environmentMainService = new EnvironmentMainService(this.resolveArgs(), productService); - const instanceEnvironment = this.patchEnvironment(environmentMainService); // Patch `process.env` with the instance's environment - services.set(IEnvironmentMainService, environmentMainService); - - // Logger - const loggerService = new LoggerMainService(getLogLevel(environmentMainService), environmentMainService.logsHome); - services.set(ILoggerMainService, loggerService); - - // Log: We need to buffer the spdlog logs until we are sure - // we are the only instance running, otherwise we'll have concurrent - // log file access on Windows (https://github.com/microsoft/vscode/issues/41218) - const bufferLogger = new BufferLogger(loggerService.getLogLevel()); - const logService = disposables.add(new LogService(bufferLogger, [new ConsoleMainLogger(loggerService.getLogLevel())])); - if (!environmentMainService.isBuilt && isDevConsoleLogForwardingEnabled) { - disposables.add(registerDevConsoleLogForwarder(logService)); - } - services.set(ILogService, logService); - - // Files - const fileService = new FileService(logService); - services.set(IFileService, fileService); - const diskFileSystemProvider = new DiskFileSystemProvider(logService); - fileService.registerProvider(Schemas.file, diskFileSystemProvider); - - // URI Identity - const uriIdentityService = new UriIdentityService(fileService); - services.set(IUriIdentityService, uriIdentityService); - - // State - const stateService = new StateService(SaveStrategy.DELAYED, environmentMainService, logService, fileService); - services.set(IStateReadService, stateService); - services.set(IStateService, stateService); - - // User Data Profiles - const userDataProfilesMainService = new UserDataProfilesMainService(stateService, uriIdentityService, environmentMainService, fileService, logService, productService); - services.set(IUserDataProfilesMainService, userDataProfilesMainService); - - // Use FileUserDataProvider for user data to - // enable atomic read / write operations. - fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesMainService, uriIdentityService, logService)); - - // Policy - let policyService: IPolicyService | undefined; - const policyProductName = isWindows - ? (productService.parentPolicyConfig?.win32RegValueName ?? productService.win32RegValueName) - : (productService.parentPolicyConfig?.darwinBundleIdentifier ?? productService.darwinBundleIdentifier); - const policyServices: IPolicyService[] = []; - if (isWindows && policyProductName) { - policyServices.push(disposables.add(new NativePolicyService(logService, policyProductName))); - } else if (isMacintosh && policyProductName) { - policyServices.push(disposables.add(new NativePolicyService(logService, policyProductName))); - } else if (isLinux) { - policyServices.push(disposables.add(new FilePolicyService(URI.file(LINUX_SYSTEM_POLICY_FILE_PATH), fileService, logService))); - } else if (environmentMainService.policyFile) { - policyServices.push(disposables.add(new FilePolicyService(environmentMainService.policyFile, fileService, logService))); - } - - let nativeManagedSettingsService: NativeManagedSettingsService | undefined; - if (isWindows) { - nativeManagedSettingsService = disposables.add(new NativeManagedSettingsService(logService, GITHUB_COPILOT_WIN32_POLICY_NAME, { registryPath: GITHUB_COPILOT_WIN32_REGISTRY_PATH })); - } else if (isMacintosh) { - nativeManagedSettingsService = disposables.add(new NativeManagedSettingsService(logService, GITHUB_COPILOT_MACOS_BUNDLE_ID)); - } - if (nativeManagedSettingsService) { - services.set(INativeManagedSettingsService, nativeManagedSettingsService); - } else { - services.set(INativeManagedSettingsService, new NullNativeManagedSettingsService()); - } - - // File-based managed settings - let fileManagedSettingsPath: string | undefined; - if (isWindows) { - const programFiles = process.env['ProgramFiles']; - if (programFiles) { - fileManagedSettingsPath = join(programFiles, MANAGED_SETTINGS_WINDOWS_DIR, MANAGED_SETTINGS_FILE_NAME); - } - } else if (isMacintosh) { - fileManagedSettingsPath = MANAGED_SETTINGS_MACOS_FILE_PATH; - } else if (isLinux) { - fileManagedSettingsPath = MANAGED_SETTINGS_LINUX_FILE_PATH; - } - if (fileManagedSettingsPath) { - const fileManagedSettingsService = disposables.add(new FileManagedSettingsService(URI.file(fileManagedSettingsPath), fileService, logService)); - services.set(IFileManagedSettingsService, fileManagedSettingsService); - } else { - services.set(IFileManagedSettingsService, new NullFileManagedSettingsService()); - } - - if (policyServices.length > 1) { - policyService = disposables.add(new MultiplexPolicyService(policyServices, logService)); - } else if (policyServices.length === 1) { - policyService = policyServices[0]; - } else { - policyService = new NullPolicyService(); - } - services.set(IPolicyService, policyService); - - // Configuration - const configurationService = new ConfigurationService(userDataProfilesMainService.defaultProfile.settingsResource, fileService, policyService, logService); - services.set(IConfigurationService, configurationService); - - // Lifecycle - services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService, undefined, false)); - - // Request - services.set(IRequestService, new SyncDescriptor(RequestService, undefined, true)); - - // Themes - services.set(IThemeMainService, new SyncDescriptor(ThemeMainService)); - - // Signing - services.set(ISignService, new SyncDescriptor(SignService, undefined, false /* proxied to other processes */)); - - // Tunnel - services.set(ITunnelService, new SyncDescriptor(TunnelService)); - - // Protocol (instantiated early and not using sync descriptor for security reasons) - services.set(IProtocolMainService, new ProtocolMainService(environmentMainService, userDataProfilesMainService, logService)); - - return [new InstantiationService(services, true), instanceEnvironment, environmentMainService, configurationService, stateService, bufferLogger, productService, userDataProfilesMainService]; - } - - private patchEnvironment(environmentMainService: IEnvironmentMainService): IProcessEnvironment { - const instanceEnvironment: IProcessEnvironment = { - VSCODE_IPC_HOOK: environmentMainService.mainIPCHandle - }; - - ['VSCODE_NLS_CONFIG', 'VSCODE_PORTABLE'].forEach(key => { - const value = process.env[key]; - if (typeof value === 'string') { - instanceEnvironment[key] = value; - } - }); - - Object.assign(process.env, instanceEnvironment); - - return instanceEnvironment; - } - - private async initServices(environmentMainService: IEnvironmentMainService, userDataProfilesMainService: UserDataProfilesMainService, configurationService: ConfigurationService, stateService: StateService, productService: IProductService): Promise { - await Promises.settled([ - - // Environment service (paths) - Promise.all([ - this.allowWindowsUNCPath(environmentMainService.extensionsPath), // enable extension paths on UNC drives... - environmentMainService.codeCachePath, // ...other user-data-derived paths should already be enlisted from `main.js` - environmentMainService.logsHome.with({ scheme: Schemas.file }).fsPath, - userDataProfilesMainService.defaultProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath, - environmentMainService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath, - environmentMainService.localHistoryHome.with({ scheme: Schemas.file }).fsPath, - environmentMainService.backupHome - ].map(path => path ? promises.mkdir(path, { recursive: true }) : undefined)), - - // State service - stateService.init(), - - // Configuration service - configurationService.initialize() - ]); - - // Initialize user data profiles after initializing the state - userDataProfilesMainService.init(); - } - - private allowWindowsUNCPath(path: string): string { - if (isWindows) { - const host = getUNCHost(path); - if (host) { - addUNCHostToAllowlist(host); - } - } - - return path; - } - - private async claimInstance(logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, productService: IProductService, retry: boolean): Promise { - - // Try to setup a server for running. If that succeeds it means - // we are the first instance to startup. Otherwise it is likely - // that another instance is already running. - let mainProcessNodeIpcServer: NodeIPCServer; - try { - mark('code/willStartMainServer'); - mainProcessNodeIpcServer = await nodeIPCServe(environmentMainService.mainIPCHandle); - mark('code/didStartMainServer'); - Event.once(lifecycleMainService.onWillShutdown)(() => mainProcessNodeIpcServer.dispose()); - } catch (error) { - - // Handle unexpected errors (the only expected error is EADDRINUSE that - // indicates another instance of VS Code is running) - if (error.code !== 'EADDRINUSE') { - - // Show a dialog for errors that can be resolved by the user - this.handleStartupDataDirError(environmentMainService, productService, error); - - // Any other runtime error is just printed to the console - throw error; - } - - // there's a running instance, let's connect to it - let client: NodeIPCClient; - try { - client = await nodeIPCConnect(environmentMainService.mainIPCHandle, 'main'); - } catch (error) { - - // Handle unexpected connection errors by showing a dialog to the user - if (!retry || isWindows || error.code !== 'ECONNREFUSED') { - if (error.code === 'EPERM') { - this.showStartupWarningDialog( - localize('secondInstanceAdmin', "Another instance of {0} is already running as administrator.", productService.nameShort), - localize('secondInstanceAdminDetail', "Please close the other instance and try again."), - productService - ); - } - - throw error; - } - - // it happens on Linux and OS X that the pipe is left behind - // let's delete it, since we can't connect to it and then - // retry the whole thing - try { - unlinkSync(environmentMainService.mainIPCHandle); - } catch (error) { - logService.warn('Could not delete obsolete instance handle', error); - - throw error; - } - - return this.claimInstance(logService, environmentMainService, lifecycleMainService, instantiationService, productService, false); - } - - // Tests from CLI require to be the only instance currently - if (environmentMainService.extensionTestsLocationURI && !environmentMainService.debugExtensionHost.break) { - const msg = `Running extension tests from the command line is currently only supported if no other instance of ${productService.nameShort} is running.`; - logService.error(msg); - client.dispose(); - - throw new Error(msg); - } - - // Show a warning dialog after some timeout if it takes long to talk to the other instance - // Skip this if we are running with --wait where it is expected that we wait for a while. - // Also skip when gathering diagnostics (--status) which can take a longer time. - let startupWarningDialogHandle: Timeout | undefined = undefined; - if (!environmentMainService.args.wait && !environmentMainService.args.status) { - startupWarningDialogHandle = setTimeout(() => { - this.showStartupWarningDialog( - localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", productService.nameShort), - localize('secondInstanceNoResponseDetail', "Please close all other instances and try again."), - productService - ); - }, 10000); - } - - const otherInstanceLaunchMainService = ProxyChannel.toService(client.getChannel('launch'), { disableMarshalling: true }); - const otherInstanceDiagnosticsMainService = ProxyChannel.toService(client.getChannel('diagnostics'), { disableMarshalling: true }); - - // Process Info - if (environmentMainService.args.status) { - return instantiationService.invokeFunction(async () => { - const diagnosticsService = new DiagnosticsService(NullTelemetryService, productService); - const mainDiagnostics = await otherInstanceDiagnosticsMainService.getMainDiagnostics(); - const remoteDiagnostics = await otherInstanceDiagnosticsMainService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true }); - const diagnostics = await diagnosticsService.getDiagnostics(mainDiagnostics, remoteDiagnostics); - console.log(diagnostics); - - throw new ExpectedError(); - }); - } - - // Windows: allow to set foreground - if (isWindows) { - await this.windowsAllowSetForegroundWindow(otherInstanceLaunchMainService, logService); - } - - // Send environment over... - logService.trace('Sending env to running instance...'); - await otherInstanceLaunchMainService.start(environmentMainService.args, process.env as IProcessEnvironment); - - // Cleanup - client.dispose(); - - // Now that we started, make sure the warning dialog is prevented - if (startupWarningDialogHandle) { - clearTimeout(startupWarningDialogHandle); - } - - throw new ExpectedError('Sent env to running instance. Terminating...'); - } - - // Print --status usage info - if (environmentMainService.args.status) { - console.log(localize('statusWarning', "Warning: The --status argument can only be used if {0} is already running. Please run it again after {0} has started.", productService.nameShort)); - - throw new ExpectedError('Terminating...'); - } - - // Set the VSCODE_PID variable here when we are sure we are the first - // instance to startup. Otherwise we would wrongly overwrite the PID - process.env['VSCODE_PID'] = String(process.pid); - - return mainProcessNodeIpcServer; - } - - private handleStartupDataDirError(environmentMainService: IEnvironmentMainService, productService: IProductService, error: NodeJS.ErrnoException): void { - if (error.code === 'EACCES' || error.code === 'EPERM') { - const directories = coalesce([environmentMainService.userDataPath, environmentMainService.extensionsPath, XDG_RUNTIME_DIR]).map(folder => getPathLabel(URI.file(folder), { os: OS, tildify: environmentMainService })); - - this.showStartupWarningDialog( - localize('startupDataDirError', "Unable to write program user data."), - localize('startupUserDataAndExtensionsDirErrorDetail', "{0}\n\nPlease make sure the following directories are writeable:\n\n{1}", toErrorMessage(error), directories.join('\n')), - productService - ); - } - } - - private showStartupWarningDialog(message: string, detail: string, productService: IProductService): void { - - // use sync variant here because we likely exit after this method - // due to startup issues and otherwise the dialog seems to disappear - // https://github.com/microsoft/vscode/issues/104493 - - dialog.showMessageBoxSync(massageMessageBoxOptions({ - type: 'warning', - buttons: [localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close")], - message, - detail - }, productService).options); - } - - private async windowsAllowSetForegroundWindow(launchMainService: ILaunchMainService, logService: ILogService): Promise { - if (isWindows) { - const processId = await launchMainService.getMainProcessId(); - - logService.trace('Sending some foreground love to the running instance:', processId); - - try { - (await import('windows-foreground-love')).allowSetForegroundWindow(processId); - } catch (error) { - logService.error(error); - } - } - } - - private quit(accessor: ServicesAccessor, reason?: ExpectedError | Error): void { - const logService = accessor.get(ILogService); - const lifecycleMainService = accessor.get(ILifecycleMainService); - - let exitCode = 0; - - if (reason) { - if ((reason as ExpectedError).isExpected) { - if (reason.message) { - logService.trace(reason.message); - } - } else { - exitCode = 1; // signal error to the outside - - if (reason.stack) { - logService.error(reason.stack); - } else { - logService.error(`Startup error: ${reason.toString()}`); - } - } - } - - lifecycleMainService.kill(exitCode); - } - - private async checkInnoSetupMutex(productService: IProductService, logService: ILogService): Promise { - if (!(isWindows && productService.win32MutexName && productService.win32VersionedUpdate)) { - return false; - } - - try { - const updatingMutexName = `${productService.win32MutexName}-updating`; - const mutex = await import('@vscode/windows-mutex'); - - if (!mutex.isActive(updatingMutexName)) { - return false; - } - - // Wait briefly for setup teardown to release the mutex; Inno's `nowait postinstall` runcode can race the setup process exit. - const pollIntervalMs = 250, retries = 120; // 30s total - logService.info(`checkInnoSetupMutex: ${updatingMutexName} is held, waiting up to ${(pollIntervalMs * retries) / 1000}s for setup to finish...`); - const start = Date.now(); - try { - await retry(async () => { - if (mutex.isActive(updatingMutexName)) { - throw new Error('mutex still held'); - } - }, pollIntervalMs, retries); - logService.info(`checkInnoSetupMutex: ${updatingMutexName} released after ${Date.now() - start}ms`); - return false; - } catch { - logService.warn(`checkInnoSetupMutex: ${updatingMutexName} still held after ${Date.now() - start}ms, giving up`); - return true; - } - } catch (error) { - logService.error('Failed to check Inno Setup mutex:', error); - return false; - } - } - - //#region Command line arguments utilities - - private resolveArgs(): NativeParsedArgs { - - // Parse arguments - const args = this.validatePaths(parseMainProcessArgv(process.argv)); - - if (args.wait && !args.waitMarkerFilePath) { - // If we are started with --wait create a random temporary file - // and pass it over to the starting instance. We can use this file - // to wait for it to be deleted to monitor that the edited file - // is closed and then exit the waiting process. - // - // Note: we are not doing this if the wait marker has been already - // added as argument. This can happen if VS Code was started from CLI. - const waitMarkerFilePath = createWaitMarkerFileSync(args.verbose); - if (waitMarkerFilePath) { - addArg(process.argv, '--waitMarkerFilePath', waitMarkerFilePath); - args.waitMarkerFilePath = waitMarkerFilePath; - } - } - - if (args.chat) { - if (args.chat['new-window']) { - // Apply `--new-window` flag to the main arguments - args['new-window'] = true; - } else if (args.chat['reuse-window']) { - // Apply `--reuse-window` flag to the main arguments - args['reuse-window'] = true; - } else if (args.chat['profile']) { - // Apply `--profile` flag to the main arguments - args['profile'] = args.chat['profile']; - } else { - // Unless we are started with specific instructions about - // new windows or reusing existing ones, always take the - // current working directory as workspace to open. - args._ = [cwd()]; - } - } - - return args; - } - - private validatePaths(args: NativeParsedArgs): NativeParsedArgs { - - // Track URLs if they're going to be used - if (args['open-url']) { - args._urls = args._; - args._ = []; - } - - // Normalize paths and watch out for goto line mode - if (!args['remote']) { - const paths = this.doValidatePaths(args._, args.goto); - args._ = paths; - } - - return args; - } - - private doValidatePaths(args: string[], gotoLineMode?: boolean): string[] { - const currentWorkingDir = cwd(); - const result = args.map(arg => { - let pathCandidate = String(arg); - - let parsedPath: IPathWithLineAndColumn | undefined = undefined; - if (gotoLineMode) { - parsedPath = parseLineAndColumnAware(pathCandidate); - pathCandidate = parsedPath.path; - } - - if (pathCandidate) { - pathCandidate = this.preparePath(currentWorkingDir, pathCandidate); - } - - const sanitizedFilePath = sanitizeFilePath(pathCandidate, currentWorkingDir); - - const filePathBasename = basename(sanitizedFilePath); - if (filePathBasename /* can be empty if code is opened on root */ && !isValidBasename(filePathBasename)) { - return null; // do not allow invalid file names - } - - if (gotoLineMode && parsedPath) { - parsedPath.path = sanitizedFilePath; - - return this.toPath(parsedPath); - } - - return sanitizedFilePath; - }); - - const caseInsensitive = isWindows || isMacintosh; - const distinctPaths = distinct(result, path => path && caseInsensitive ? path.toLowerCase() : (path || '')); - - return coalesce(distinctPaths); - } - - private preparePath(cwd: string, path: string): string { - - // Trim trailing quotes - if (isWindows) { - path = rtrim(path, '"'); // https://github.com/microsoft/vscode/issues/1498 - } - - // Trim whitespaces - path = trim(trim(path, ' '), '\t'); - - if (isWindows) { - - // Resolve the path against cwd if it is relative - path = resolve(cwd, path); - - // Trim trailing '.' chars on Windows to prevent invalid file names - path = rtrim(path, '.'); - } - - return path; - } - - private toPath(pathWithLineAndCol: IPathWithLineAndColumn): string { - const segments = [pathWithLineAndCol.path]; - - if (typeof pathWithLineAndCol.line === 'number') { - segments.push(String(pathWithLineAndCol.line)); - } - - if (typeof pathWithLineAndCol.column === 'number') { - segments.push(String(pathWithLineAndCol.column)); - } - - return segments.join(':'); - } - - //#endregion -} - -// Main Startup -const code = new CodeMain(); -code.main(); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard.css b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard.css deleted file mode 100644 index 4264aa6bb..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/media/whiteboard.css +++ /dev/null @@ -1,1249 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/* The workbench grid reserves a bottom gutter (`gutterBottom` in - whiteboard/browser/workbench.ts), so a strip of the workbench root stays exposed - below the editor. Without this rule it falls through to the stock - WORKBENCH_BACKGROUND (#252526 on dark) and reads as a band under the canvas. */ -.monaco-workbench.whiteboard-workbench { - background: var(--vscode-editor-background); -} - -.monaco-workbench.whiteboard-workbench.nomaineditorarea { - background-image: url("./whiteboard-letterpress-light.svg"); - background-position: center; - background-repeat: no-repeat; - background-size: 260px 260px; -} - -.monaco-workbench.whiteboard-workbench.nomaineditorarea.vs-dark { - background-image: url("./whiteboard-letterpress-dark.svg"); -} - -.monaco-workbench.whiteboard-workbench.nomaineditorarea.hc-light { - background-image: url("./whiteboard-letterpress-hc-light.svg"); -} - -.monaco-workbench.whiteboard-workbench.nomaineditorarea.hc-black { - background-image: url("./whiteboard-letterpress-hc-dark.svg"); -} - -/* KEEP IN SYNC WITH WHITEBOARD_CHROME_HEIGHT in whiteboard/common/whiteboardChrome.ts. The - overlay must be as tall as the editor tab strip below it, or the window - controls and the navigation arrows stop aligning with the tab pills. */ -.monaco-workbench .part.titlebar.whiteboard-chrome-overlay { - position: absolute; - top: 0; - left: 0; - z-index: 100; - width: 100%; - height: 40px; - box-shadow: none; - pointer-events: none; - background: transparent; -} - -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-left, -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-right { - width: max-content !important; - min-width: 0; - flex: 0 0 auto !important; - padding-left: 0 !important; - pointer-events: auto; -} - -.monaco-workbench.linux - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-right { - margin-left: auto; -} - -/* The native macOS stoplights sit over the left container. Make its unused - area draggable, including the space between and around the stoplights. The - navigation control below removes itself from this drag region. */ -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-left { - -webkit-app-region: drag; -} - -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-right { - -webkit-app-region: no-drag; -} - -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-drag-region { - left: var(--whiteboard-chrome-left-width, 0px); - right: var(--whiteboard-chrome-right-width, 0px); - width: auto; - display: none; - pointer-events: none; -} - -.monaco-workbench.nomaineditorarea - .part.titlebar.whiteboard-chrome-overlay - > .whiteboard-titlebar-container - > .titlebar-drag-region { - display: block; - pointer-events: auto; - -webkit-app-region: drag; -} - -.monaco-workbench - .part.editor - .editor-group-container - > .title - > .tabs-and-actions-container.whiteboard-chrome-tab-strip { - box-sizing: border-box; - padding-left: 6px; - padding-right: 6px; - user-select: none; - -webkit-app-region: drag; -} - -.monaco-workbench.whiteboard-tab-dragging - .part.editor - .editor-group-container - > .title - > .tabs-and-actions-container.whiteboard-chrome-tab-strip { - -webkit-app-region: no-drag; -} - -.monaco-workbench - .part.editor - .tabs-and-actions-container.whiteboard-chrome-tab-strip - .tabs-container { - -webkit-app-region: drag; -} - -.monaco-workbench.whiteboard-tab-dragging - .part.editor - .tabs-and-actions-container.whiteboard-chrome-tab-strip - .tabs-container { - -webkit-app-region: no-drag; -} - -.monaco-workbench - .part.editor - .editor-group-container - > .title - > .tabs-and-actions-container.whiteboard-chrome-inset { - padding-left: calc(var(--whiteboard-chrome-left-width, 0px) + 6px); - padding-right: calc(var(--whiteboard-chrome-right-width, 0px) + 6px); -} - -.monaco-workbench .part.editor .tabs-container > .tab, -.monaco-workbench .part.editor .tabs-container > .tabs-bar-add-tab, -.monaco-workbench .part.editor .tabs-and-actions-container > .editor-actions, -.monaco-workbench .part.editor .tabs-and-actions-container > .editor-layout-actions, -.monaco-workbench - .part.editor - .tabs-and-actions-container - > .monaco-scrollable-element - > .scrollbar { - -webkit-app-region: no-drag; -} - -/* --------------------------------------------------------------------------- - Whiteboard file explorer - - The explorer is the leftmost surface whenever it is visible, so the window - controls and the navigation arrows sit over its top row instead of over the - editor tab strip. Two rules follow from that: the explorer reserves one chrome - row for them, and the tab strip drops the traffic-light inset it would - otherwise need. - --------------------------------------------------------------------------- */ - -/* The grid sizes the `.split-view-view` wrapper, not the part inside it, and the - part is a static block. Without this the part grows to the list's content - height, the list never scrolls, and every row renders. */ -.monaco-workbench .part.whiteboard-explorer { - display: flex; - flex-direction: column; - height: 100%; - background-color: var(--vscode-editor-background); - /* An inset shadow rather than a border, so the tree keeps the full part width - and `WhiteboardExplorerPart.layout` needs no separator correction. */ - box-shadow: inset -1px 0 0 - var(--vscode-panel-border, var(--vscode-sideBar-border, transparent)); - overflow: hidden; -} - -/* The one chrome row keeps the editor tab-strip background, so the top of the - window reads as a single bar running across the tree and the tabs. The step - from that background down to the tree is the whole divider — deliberately no - bottom rule. - - A 1px rule here would be the only horizontal line at this edge: the editor tab - strip ends at the same y with no border and no shadow, because the Whiteboard pill - tabs carry no separators by design (see the pill-tab section below). A line on - just the tree half stops dead at the sash and reads as an unfinished stub. - - `WhiteboardExplorerPart` writes `--whiteboard-chrome-height` on this part and the - workbench layout writes `--whiteboard-explorer-width` on the inset tab strip - (never on the workbench root; see `publishWhiteboardChromeInset`), so - WHITEBOARD_CHROME_HEIGHT stays the only source. The fallbacks cover the frame - before the part first lays out. */ -.monaco-workbench .part.whiteboard-explorer > .whiteboard-explorer-chrome-spacer { - box-sizing: border-box; - height: var(--whiteboard-chrome-height, 40px); - flex-shrink: 0; - background-color: var(--vscode-editorGroupHeader-tabsBackground); - user-select: none; - -webkit-app-region: drag; -} - -/* Flex rather than `calc(100% - )`: the row above is the only fixed - height, so the tree takes whatever is left and the height is written once. */ -.monaco-workbench .part.whiteboard-explorer > .whiteboard-explorer-tree { - flex: 1; - min-height: 0; -} - -/* --------------------------------------------------------------------------- - The file-tree toggle - - The button always occupies its 22px slot, so the titlebar's left cluster keeps - a constant width. That matters because a ResizeObserver on the cluster feeds - `--whiteboard-chrome-left-width`, which the editor tab strip pads itself by — a - button that grew from 0 would slide every tab as it appeared. Only opacity and - transform animate here, so nothing reflows. - --------------------------------------------------------------------------- */ - -.monaco-workbench .whiteboard-titlebar-file-tree-toggle { - display: flex; - align-items: center; - justify-content: center; - width: 22px; - height: 22px; - margin-left: 4px; - border-radius: 5px; - flex-shrink: 0; - color: var(--vscode-icon-foreground); - /* Nothing to toggle until a file or diff tab is active. */ - opacity: 0; - transform: scale(0.8); - pointer-events: none; - /* The cluster around it drags the window; this button must not. */ - -webkit-app-region: no-drag; -} - -.monaco-workbench.whiteboard-explorer-available .whiteboard-titlebar-file-tree-toggle { - opacity: 1; - transform: none; - pointer-events: auto; - cursor: pointer; -} - -/* Reduced motion gets a straight cut: `monaco-enable-motion` is absent then, - because accessibility/browser/accessibilityService.ts toggles it from - `workbench.reduceMotion`. */ -.monaco-workbench.monaco-enable-motion .whiteboard-titlebar-file-tree-toggle { - transition: - opacity 120ms ease, - transform 120ms ease; -} - -.monaco-workbench .whiteboard-titlebar-file-tree-toggle:hover { - background-color: var(--vscode-toolbar-hoverBackground); -} - -.monaco-workbench .whiteboard-titlebar-file-tree-toggle:focus-visible { - outline: 1px solid var(--vscode-focusBorder); - outline-offset: -1px; -} - -/* One icon per state, picked here so the titlebar part needs no explorer state. */ -.monaco-workbench .whiteboard-titlebar-file-tree-toggle > .whiteboard-file-tree-icon-open, -.monaco-workbench.whiteboard-explorer-visible - .whiteboard-titlebar-file-tree-toggle - > .whiteboard-file-tree-icon-closed { - display: none; -} - -.monaco-workbench.whiteboard-explorer-visible - .whiteboard-titlebar-file-tree-toggle - > .whiteboard-file-tree-icon-open { - display: block; -} - -/* The tab strip pads itself past the traffic lights and the navigation arrows, - which is correct only while the editor is the leftmost surface. The tree now - covers that chrome, so the strip only has to clear whatever the tree does NOT - cover — subtract the tree's width rather than assuming it covers all of it. - - A flat `6px` would be wrong whenever the left cluster is wider than the tree. - The cluster counter-zooms (see `WhiteboardTitlebarPart.layout`), so zooming the - window out grows it in CSS pixels until it passes even the tree's 170px - minimum, and it would then sit over the first tab and swallow clicks as window - drags. `max()` keeps the plain 6px gutter in the normal case. */ -.monaco-workbench.whiteboard-explorer-visible - .part.editor - .editor-group-container - > .title - > .tabs-and-actions-container.whiteboard-chrome-inset { - padding-left: max( - 6px, - calc( - var(--whiteboard-chrome-left-width, 0px) + 6px - - var(--whiteboard-explorer-width, 0px) - ) - ); -} - -/* --------------------------------------------------------------------------- - Whiteboard pill tabs - - The tab row keeps the titlebar background and carries no separators, no - bottom border, and no per-tab top-border indicator. The active tab is a - raised pill. The other tabs are flat. - - Each rule below starts with `body` because it must outrank an upstream rule - of the same class count in multieditortabscontrol.css. - --------------------------------------------------------------------------- */ - -.monaco-workbench.whiteboard-workbench { - /* Each pill color mixes over the tab-strip background, so a theme change - carries into the pill. */ - /* Whiteboard: the active tab is a board-colored pill with a hairline, the - same surface and rule the canvas uses, so the tab reads as a piece of the - board lifted onto the tray. No drop shadow in either theme. */ - --whiteboard-tab-fill: var(--vscode-editor-background); - --whiteboard-tab-border: var(--vscode-panel-border); - --whiteboard-tab-hover-fill: color-mix( - in srgb, - #ffffff 4%, - var(--vscode-editorGroupHeader-tabsBackground) - ); - --whiteboard-tab-separator: var(--vscode-panel-border); - --whiteboard-tab-shadow: none; - --whiteboard-chrome-font: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, - monospace; -} - -/* The light themes use weaker mixes, so the pill stays subtle. */ -.monaco-workbench.whiteboard-workbench.vs, -.monaco-workbench.whiteboard-workbench.hc-light { - --whiteboard-tab-fill: var(--vscode-editor-background); - --whiteboard-tab-border: var(--vscode-panel-border); - --whiteboard-tab-hover-fill: color-mix( - in srgb, - #ffffff 40%, - var(--vscode-editorGroupHeader-tabsBackground) - ); - --whiteboard-tab-separator: var(--vscode-panel-border); - --whiteboard-tab-shadow: none; -} - -/* 28px pill + 6px above + 6px below = the 40px row. EditorTabsControl reports - the same 40px through EDITOR_TAB_HEIGHT.whiteboard. The tab-height variable is - an inline style on `.title`, so this rule redeclares it one level down. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - > .tabs-and-actions-container { - --editor-group-tab-height: 28px; - padding-top: 6px; - padding-bottom: 6px; -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title.compact-height - > .tabs-and-actions-container { - --editor-group-tab-height: 20px; -} - -/* No bottom border below the row. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title.title-border-bottom::after, -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - > .tabs-and-actions-container.tabs-border-bottom::after { - display: none; -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container { - gap: 4px; -} - -/* Flat by default. `redrawTabBorders` writes the separator as an inline - `border-right`, so only `!important` removes it. - - The pill carries no border at all: a 1px border would leave a 22px content - box inside the 24px tab, and the label line is `--editor-group-tab-height` - tall, so the icon and the name would sit 1px below the center. The active - pill draws its outline as an inset shadow instead, which costs no layout. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab { - border: none !important; - border-radius: 6px; - background-color: transparent; - box-shadow: none; - /* The whole inset. Upstream pads 10px on the left and nothing on the right, - which reads wider than the Paper design. */ - padding-left: 4px; - padding-right: 4px; -} - -/* Upstream shrinking tabs keep the label at its natural width, clip its flex - parent, and paint a gradient over the clipped edge. That treatment assumes - flat tabs. Inside Whiteboard's raised pill it becomes a dark block, and changing - only `text-overflow` cannot produce an ellipsis because the label itself - never gets narrower. - - Give the label the pill's available width instead. The browser then draws an - ellipsis only when the text is actually clipped. Remove the upstream - gradient in every tab state; theme rules can still assign its background, - but the pseudo-element has no box to paint. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab:is(.sizing-shrink, .sizing-fixed) - > .monaco-icon-label - > .monaco-icon-label-container { - flex: 1 1 auto; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab:is(.sizing-shrink, .sizing-fixed) - .monaco-icon-label-container::after { - content: none; - display: none; -} - -/* The raised pill. The first shadow is the 1px outline. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab.active { - background-color: var(--whiteboard-tab-fill); - box-shadow: - inset 0 0 0 1px var(--whiteboard-tab-border), - var(--whiteboard-tab-shadow); -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab:hover:not(.active) { - background-color: var(--whiteboard-tab-hover-fill); - box-shadow: none; -} - -/* The close button carries three insets of its own: a 28px column, a 16px - button centered in it, and 2px of padding around the glyph. Together they put - the glyph 10px inside the pill while the icon on the left sits at 4px. The - column hugs the glyph instead, so both sides read the same. The vertical - padding stays, so the hit target keeps its height. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab - > .tab-actions, -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab - > .tab-actions - > .monaco-action-bar { - width: 16px; -} - -/* The 28px column also held the gap after the name. Restore it as the 6px the - icon puts between itself and the name. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab - > .tab-actions { - margin-left: 6px; -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab - > .tab-actions - .action-label.codicon { - padding: 2px 0; -} - -/* Home carries no close button, but `sizing-fit` still stretches it to a fixed - 120px. That leaves ~30px of dead space on each side of the home icon and the - name, which reads as an off-center label. The pill hugs them instead. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab.sticky { - width: fit-content; -} - -/* Home is the one sticky tab, so it is always the last one before the whiteboard - tabs. A rule after it separates the two groups. `redrawTabBorders` draws that - rule as an inline border-right, which the flat rule above removes, so the - pseudo-element below draws it instead. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab.sticky:not(:last-child) { - margin-right: 8px; -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab.sticky:not(:last-child)::after { - content: ""; - position: absolute; - right: -7px; - top: 4px; - bottom: 4px; - width: 1px; - pointer-events: none; - background-color: var(--whiteboard-tab-separator); -} - -body - .monaco-workbench - .part.editor - > .content - .editor-group-container - > .editor-group-watermark-wrapper - .editor-group-watermark - .letterpress { - background-image: url("./whiteboard-letterpress-light.svg"); -} - -body - .monaco-workbench.vs-dark - .part.editor - > .content - .editor-group-container - .editor-group-watermark - .letterpress { - background-image: url("./whiteboard-letterpress-dark.svg"); -} - -body - .monaco-workbench.hc-light - .part.editor - > .content - .editor-group-container - .editor-group-watermark - .letterpress { - background-image: url("./whiteboard-letterpress-hc-light.svg"); -} - -body - .monaco-workbench.hc-black - .part.editor - > .content - .editor-group-container - .editor-group-watermark - .letterpress { - background-image: url("./whiteboard-letterpress-hc-dark.svg"); -} - -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - .whiteboard-titlebar-container - .whiteboard-traffic-light-inset { - flex-shrink: 0; - -webkit-app-region: drag; -} - -/* The navigation control sits in .titlebar-left, after the traffic lights. - titlebarpart.css scopes every .command-center rule to `.titlebar-center > - .window-title >`, so the rules below restate the ones that still apply here. - The margin is the gap from the traffic lights. It is also the only left - padding in macOS fullscreen, where the inset collapses to zero. */ -.whiteboard-titlebar-container .whiteboard-titlebar-navigation { - display: flex; - align-items: center; - flex: 0 0 auto; - font-size: 12px; - margin-left: 8px; -} - -.whiteboard-titlebar-container .whiteboard-application-menu { - display: flex; - align-items: center; - justify-content: center; - align-self: center; - width: 30px; - height: 28px; - margin-left: 6px; - padding: 0; - border: 0; - border-radius: 4px; - color: inherit; - background: transparent; - cursor: pointer; - -webkit-app-region: no-drag; -} - -.whiteboard-titlebar-container .whiteboard-application-menu:hover { - background: var(--vscode-toolbar-hoverBackground); -} - -.whiteboard-titlebar-container .whiteboard-application-menu:focus-visible, -.whiteboard-titlebar-container .window-controls-container > button:focus-visible { - outline: 1px solid var(--vscode-focusBorder); - outline-offset: -2px; -} - -.whiteboard-titlebar-container .window-controls-container > button { - padding: 0; - border: 0; - background: transparent; - -webkit-app-region: no-drag; -} - -/* Equal space on each side of the arrows. - - `CodeWindow.updateWindowControls` moves the traffic lights itself: it calls - `setWindowButtonPosition({ x: floor((WHITEBOARD_CHROME_HEIGHT - buttonHeight) / 2) + 1 })`. - At 40px with the 14px macOS Tahoe button that is x=14, and three 14px buttons - on the 20px macOS pitch end at 68. Change WHITEBOARD_CHROME_HEIGHT and that - number moves. - - The arrow glyph carries 2px of side bearing inside its box, so the back arrow - starts drawing 19px after the last light. On the other side the tab strip - adds 6px of its own (`.whiteboard-chrome-inset`), so 8px here lands the Home tab - 19px after the forward arrow draws. */ -.monaco-workbench - .part.titlebar.whiteboard-chrome-overlay - .whiteboard-titlebar-navigation { - margin-left: 12px; - margin-right: 8px; -} - -/* Without no-drag the full-size .titlebar-drag-region takes the clicks and the - arrows stop working. */ -.whiteboard-titlebar-container .whiteboard-titlebar-navigation > .command-center { - z-index: 2500; - -webkit-app-region: no-drag; -} - -.whiteboard-titlebar-container .whiteboard-titlebar-navigation > .command-center.hide { - visibility: hidden; -} - -.whiteboard-titlebar-container - .whiteboard-titlebar-navigation - > .command-center - > .monaco-toolbar - > .monaco-action-bar - > .actions-container - > .action-item - > .action-label { - color: inherit; -} - -.whiteboard-canvas-part, -.whiteboard-canvas-part > .whiteboard-canvas-container, -.whiteboard-canvas-part .whiteboard-canvas-host { - width: 100%; - height: 100%; -} - -/* The canvas topbar dresses itself as workbench chrome and reads its colors and - its type ramp straight from the --vscode-* theme variables, but there is no - such variable for the workbench UI font: style.css hardcodes a stack per - platform and per language. `system-ui` resolves to the same platform UI face - without copying that matrix. The selector outranks the canvas stylesheet's own - default, which keeps the standalone browser build on its mono face. Every text - item in the topbar reads this token, so the bar shows one face throughout. */ -.whiteboard-canvas-host .whiteboard-app { - --chrome-font: var(--whiteboard-chrome-font, var(--font-mono)); -} - -/* Whiteboard: every label on the tray is set in the same mono face as the - canvas chrome. The faces ship with the canvas stylesheet, whose @font-face - rules are hoisted out of its @scope so they apply document-wide. */ -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab - .monaco-icon-label { - font-family: var(--whiteboard-chrome-font); - font-size: 12px; -} - -body - .monaco-workbench.whiteboard-workbench - .part.editor - > .content - .editor-group-container - > .title - .tabs-container - > .tab.active - .monaco-icon-label { - font-weight: 600; -} - -/* Multi-diff headers print a full Whiteboard path in one label. Keep the file name - visible in narrow panes by placing the ellipsis at the leading edge. */ -.whiteboard-path-label .monaco-icon-label-container { - direction: rtl; - text-align: left; -} - -.whiteboard-path-label .label-name { - unicode-bidi: plaintext; -} - -.whiteboard-multidiff-counts { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 0 4px; - font-size: 12px; - font-variant-numeric: tabular-nums; -} - -.whiteboard-multidiff-counts[hidden] { - display: none; -} - -.whiteboard-multidiff-additions { - color: var(--vscode-gitDecoration-addedResourceForeground); -} - -.whiteboard-multidiff-deletions { - color: var(--vscode-gitDecoration-deletedResourceForeground); -} - -.whiteboard-counts-folded .whiteboard-multidiff-additions { - color: var(--vscode-descriptionForeground); -} - -.whiteboard-multidiff-open-container { - display: inline-flex; - align-items: center; - margin: 0 3px; -} - -.whiteboard-multidiff-open-container[hidden] { - display: none; -} - -.whiteboard-multidiff-open.monaco-button { - display: inline-flex; - align-items: center; - gap: 6px; - width: auto; - min-width: 0; - height: 24px; - line-height: 22px; - padding: 0 9px; - border: 1px solid color-mix(in srgb, var(--vscode-icon-foreground) 20%, transparent); - border-radius: 5px; - background: color-mix(in srgb, var(--vscode-icon-foreground) 5%, transparent); - color: var(--vscode-icon-foreground); - font-size: 12px; - white-space: nowrap; -} - -.whiteboard-multidiff-open.monaco-button .codicon[class*="codicon-"] { - margin: 0; - font-size: 13px; -} - -.whiteboard-multidiff-open.monaco-button:hover { - background: var(--vscode-toolbar-hoverBackground); -} - -.whiteboard-files-editor, -.whiteboard-files-editor-tree, -.whiteboard-files-editor-diffs { - min-width: 0; - min-height: 0; - height: 100%; -} - -.whiteboard-files-editor { - width: 100%; - overflow: hidden; - background: var(--vscode-editor-background); -} - -/* The sidebar is one tray from the progress line to the last file: the tree - paints no ground of its own and inherits the tray behind it (see the - "Sidebar tone" board). Hover and selection come from the theme's list - colors, the well and the marker tint. */ -.whiteboard-files-editor-tree { - border-right: 1px solid var(--vscode-sideBar-border, transparent); -} - -.whiteboard-changed-files { - box-sizing: border-box; - display: flex; - flex-direction: column; - height: 100%; - min-height: 0; - font-family: var(--whiteboard-chrome-font, system-ui, sans-serif); -} - -.whiteboard-changed-files-tree { - flex: 1 1 auto; - min-height: 0; -} - -.whiteboard-changed-files-row { - box-sizing: border-box; - display: flex; - align-items: center; - gap: 6px; - height: 22px; - padding-right: 8px; -} - -.whiteboard-changed-files-icon { - flex: 0 0 16px; - width: 16px; - color: var(--vscode-icon-foreground); - text-align: center; -} - -.whiteboard-changed-files-label { - flex: 1 1 auto; - min-width: 0; - overflow: hidden; - font-weight: 400; - text-overflow: ellipsis; - white-space: nowrap; -} - -.whiteboard-changed-files-folder .whiteboard-changed-files-label { - margin-left: 7px; - font-weight: 600; -} - -.whiteboard-files-editor-diffs { - position: relative; - min-width: 0; - min-height: 0; - overflow: hidden; - background: var(--vscode-multiDiffEditor-background); -} - -.whiteboard-files-editor-diffs - .monaco-component.multiDiffEditor - .multiDiffEntry - > .header - > .header-content { - margin-top: 0; -} - -.whiteboard-files-editor-diffs - .monaco-component.multiDiffEditor - .multiDiffEntry - > .header - > .header-content - .file-path - .title { - font-size: 12px; -} - -.whiteboard-files-editor-diffs - .monaco-component.multiDiffEditor - .multiDiffEntry - > .header - > .header-content - > .actions { - padding: 0; -} - -.whiteboard-files-editor-diffs - .multiDiffEntry - > .header - > .header-content - > .actions.has-no-actions { - display: none; -} - -.whiteboard-canvas-part > .whiteboard-canvas-container { - display: grid; - grid-template-rows: minmax(0, 1fr); - overflow: hidden; -} - -.whiteboard-canvas-part .whiteboard-canvas-host { - position: relative; - min-height: 0; - overflow: hidden; - background: var(--vscode-editor-background); - -webkit-user-select: text; - user-select: text; -} - -/* Hosts fixedOverflowWidgets (hover, definition) for the inline peek editors. - Lives in the workbench container — inside .monaco-workbench so theme - variables apply, outside .whiteboard-canvas-root whose container-query - containment would re-anchor and clip position: fixed widgets. The widgets - position themselves against the viewport; z-index matches the workbench's - other overflow-widget hosts (scm, keybindings editor). */ -.whiteboard-overflow-widgets { - position: fixed; - top: 0; - left: 0; - z-index: 5000; -} - -/* The host carries tabindex="-1" so the canvas app can focus it programmatically - (desktop-entry's mount handle calls container.focus()). It is a document - surface rather than a control, and it is not tab-reachable, so suppress the - workbench-wide `[tabindex="-1"]:focus` ring that would otherwise trace the - whole pane -- the same treatment upstream gives editor group containers. */ -.monaco-workbench .whiteboard-canvas-part .whiteboard-canvas-host:focus { - outline: none; -} - -.whiteboard-reveal-line { - background: color-mix(in srgb, var(--vscode-foreground) 5%, transparent); - border-left: 2px solid var(--vscode-panel-border); -} - -/* Give commenting and folding separate hit targets in the Files view. */ -.whiteboard-files-editor .monaco-editor .margin-view-overlays .cldr:is( - .codicon-folding-expanded, - .codicon-folding-collapsed, - .codicon-folding-manual-expanded, - .codicon-folding-manual-collapsed -) { - margin-left: 30px; - width: 20px !important; -} - -.whiteboard-files-editor-diffs { position: relative; } -.whiteboard-files-editor-summary { - display: flex; - align-items: center; - gap: 8px; - padding: 8px 12px; - border-bottom: 1px solid var(--vscode-sideBar-border, transparent); - color: var(--vscode-descriptionForeground); - font-size: 12px; - font-variant-numeric: tabular-nums; -} - -.whiteboard-files-editor-summary[hidden] { - display: none; -} - -.whiteboard-files-editor-summary-added { - color: var(--vscode-gitDecoration-addedResourceForeground); -} - -.whiteboard-files-editor-summary-removed { - color: var(--vscode-gitDecoration-deletedResourceForeground); -} - -.whiteboard-files-editor-summary-bar { - display: inline-flex; - gap: 1px; -} - -.whiteboard-files-editor-summary-block { - width: 8px; - height: 8px; - background: var(--vscode-editorWidget-border); -} - -.whiteboard-files-editor-summary-block.added { - background: var(--vscode-gitDecoration-addedResourceForeground); -} - -.whiteboard-files-editor-summary-block.removed { - background: var(--vscode-gitDecoration-deletedResourceForeground); -} - -.whiteboard-multidiff-note { - padding: 0 6px; - color: var(--vscode-descriptionForeground); - font-size: 12px; -} - -.whiteboard-multidiff-note[hidden] { - display: none; -} - -.whiteboard-structural-label-inline { - color: var(--vscode-editor-foldPlaceholderForeground); - font-style: italic; -} - -.whiteboard-structural-label-zone { - background-color: var(--vscode-editor-foldBackground); - color: var(--vscode-editor-foldPlaceholderForeground); -} - -.whiteboard-structural-label-zone pre { - margin: 0; - padding-left: 4ch; - font: inherit; - white-space: pre; -} - -.whiteboard-structural-stream-status:not([hidden]) { - position: absolute; - inset: 0; - z-index: 20; - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - padding: 24px; - color: var(--vscode-descriptionForeground); - background: var(--vscode-editor-background); -} -.whiteboard-structural-stream-status.loading::before { - content: ""; - width: 14px; - height: 14px; - flex-shrink: 0; - border: 2px solid currentColor; - border-right-color: transparent; - border-radius: 50%; - animation: whiteboard-structural-loading 1s linear infinite; -} -@keyframes whiteboard-structural-loading { to { transform: rotate(360deg); } } -@media (prefers-reduced-motion: reduce) { - .whiteboard-structural-stream-status.loading::before { animation: none; } -} -.whiteboard-header-viewed { width: 16px; height: 16px; padding: 0; margin: 0 8px; border: 1px solid var(--vscode-descriptionForeground); border-radius: 3px; color: var(--vscode-editor-foreground); background: transparent; font: 12px/14px sans-serif; cursor: pointer; } -.whiteboard-header-viewed[aria-checked="true"], .whiteboard-counts-viewed { opacity: .45; } -.whiteboard-tree-counts { display:inline-flex; flex-shrink:0; gap:6px; margin-left:auto; padding-left:8px; padding-right:8px; font:11px/22px var(--whiteboard-chrome-font, monospace); font-variant-numeric:tabular-nums; } -.whiteboard-tree-added { color:var(--vscode-gitDecoration-addedResourceForeground); } -.whiteboard-tree-removed { color:var(--vscode-gitDecoration-deletedResourceForeground); } - -/* One disclosure glyph. The canvas draws it as an inline SVG (DisclosureChevron); - the workbench trees and the multi-diff headers use codicons, so their glyph is - swapped for the same 12px stroke path through a mask. The tree sets the - twistie's left padding to the row's indent; stock sizing is border-box, so - past the first level the padding eats the whole 16px box and the glyph - lands on the label. Content-box keeps the 16px glyph slot beside the - indent at every depth, so the chevron sits the same distance from its - label as a file mark does from its name. The file header button and the - section header toggle are keyed on their codicon name, down = open. */ -.whiteboard-workbench .monaco-tl-twistie.codicon-tree-item-expanded { - box-sizing: content-box; - width: 16px; - padding-right: 0; - justify-content: center; -} -.whiteboard-workbench .monaco-tl-twistie.codicon-tree-item-expanded::before, -.whiteboard-workbench .collapse-button .codicon-chevron-down::before, -.whiteboard-workbench .collapse-button .codicon-chevron-right::before, -.whiteboard-workbench .whiteboard-diff-group-toggle .codicon-chevron-down::before, -.whiteboard-workbench .whiteboard-diff-group-toggle .codicon-chevron-right::before { - content: ""; - display: block; - flex: none; - width: 12px; - height: 12px; - background: currentColor; - mask: url("data:image/svg+xml;utf8,") center / 12px 12px no-repeat; - transform: rotate(90deg); - transition: transform 120ms ease; -} -.whiteboard-workbench .monaco-tl-twistie.collapsed.codicon-tree-item-expanded::before, -.whiteboard-workbench .collapse-button .codicon-chevron-right::before, -.whiteboard-workbench .whiteboard-diff-group-toggle .codicon-chevron-right::before { - transform: rotate(0deg); -} - -/* File marks in the changed-files tree: status is one stroke beside the name, - never a boxed codicon. Plus, minus, dot, arrow, a ghost file for referenced - context, three dots while loading, a bang on error; viewed replaces the mark - with a check. Colors come from the theme's gitDecoration foregrounds (add, - del, warn amber, ink-muted). Folder rows keep an empty slot and paint nothing. */ -.whiteboard-workbench { - --whiteboard-mark-plus: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-minus: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-dot: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-arrow: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-file: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-check: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-fold: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-dots: url("data:image/svg+xml;utf8,"); - --whiteboard-mark-bang: url("data:image/svg+xml;utf8,"); -} -.whiteboard-workbench .whiteboard-changed-files-icon[class*="whiteboard-changed-files-icon-"]::before, -.whiteboard-workbench .whiteboard-changed-files-icon.codicon-loading::before, -.whiteboard-workbench .whiteboard-changed-files-icon.codicon-error::before, -.whiteboard-workbench .whiteboard-file-viewed .whiteboard-changed-files-icon::before, -.whiteboard-workbench .whiteboard-file-folded .whiteboard-changed-files-icon::before { - content: ""; - display: block; - width: 16px; - height: 16px; - background: var(--whiteboard-mark-color, currentColor); - mask: var(--whiteboard-mark) center / 16px 16px no-repeat; - animation: none !important; -} -.whiteboard-workbench .whiteboard-changed-files-icon:not([hidden]) { display: flex; align-items: center; justify-content: center; } -.whiteboard-workbench .whiteboard-changed-files-icon-added { --whiteboard-mark: var(--whiteboard-mark-plus); --whiteboard-mark-color: var(--vscode-gitDecoration-addedResourceForeground); } -.whiteboard-workbench .whiteboard-changed-files-icon-deleted { --whiteboard-mark: var(--whiteboard-mark-minus); --whiteboard-mark-color: var(--vscode-gitDecoration-deletedResourceForeground); } -.whiteboard-workbench .whiteboard-changed-files-icon-modified { --whiteboard-mark: var(--whiteboard-mark-dot); --whiteboard-mark-color: var(--vscode-gitDecoration-modifiedResourceForeground); } -.whiteboard-workbench .whiteboard-changed-files-icon-renamed { --whiteboard-mark: var(--whiteboard-mark-arrow); --whiteboard-mark-color: var(--vscode-gitDecoration-renamedResourceForeground); } -.whiteboard-workbench .whiteboard-changed-files-icon-unchanged { --whiteboard-mark: var(--whiteboard-mark-file); --whiteboard-mark-color: var(--vscode-disabledForeground); } -.whiteboard-workbench .whiteboard-changed-files-icon.codicon-loading { --whiteboard-mark: var(--whiteboard-mark-dots); --whiteboard-mark-color: var(--vscode-descriptionForeground); } -.whiteboard-workbench .whiteboard-changed-files-icon.codicon-error { --whiteboard-mark: var(--whiteboard-mark-bang); --whiteboard-mark-color: var(--vscode-gitDecoration-deletedResourceForeground); } -.whiteboard-workbench .whiteboard-file-viewed { opacity: 1; color: var(--vscode-descriptionForeground); } -.whiteboard-workbench .whiteboard-file-viewed .whiteboard-changed-files-icon { --whiteboard-mark: var(--whiteboard-mark-check); --whiteboard-mark-color: var(--vscode-disabledForeground); } -/* Folded by default counts as done: the viewed treatment, with a fold mark. */ -.whiteboard-workbench .whiteboard-file-folded { opacity: 1; color: var(--vscode-descriptionForeground); } -.whiteboard-workbench .whiteboard-file-folded .whiteboard-changed-files-icon { --whiteboard-mark: var(--whiteboard-mark-fold); --whiteboard-mark-color: var(--vscode-disabledForeground); } - -/* Folds get out of the way: ghost ink on the code's own background, in the - chrome font. The theme sets the unchangedRegion background, foreground and - shadow. The row keeps Monaco's 24px height: its view zone and the handle - transforms assume it, and a shorter row rides up over the previous line. */ -.whiteboard-workbench .monaco-editor .diff-hidden-lines .center { - font: 11px/24px var(--whiteboard-chrome-font, monospace); -} -.whiteboard-workbench .monaco-editor .diff-hidden-lines .center:hover { - color: var(--vscode-descriptionForeground); -} - -/* The unfold glyph sits where the fold glyph will appear once the region is - open: in the glyph margin lane (an 18px square, the editor's line height) - at the top-left of the row, not centered under the line numbers and the - 24px row. Expand, and the collapse glyph lands under the same pointer. - Monaco centers the slot inline, hence the important. */ -.whiteboard-workbench .monaco-editor .diff-hidden-lines .center > div:first-child { - justify-content: flex-start !important; - align-items: flex-start !important; -} -.whiteboard-workbench .monaco-editor .diff-hidden-lines .center > div:first-child > a { - display: flex; - width: 18px; - height: 18px; - align-items: center; - justify-content: center; -} - -/* The canvas stylesheet resets every element to border-box, and the Diff - view's editors live inside the canvas. Monaco sizes the fold's drag - handles as content-box (4px tall plus 6px of transparent borders) and - offsets the whole widget by that sum, so a border-box handle is 4px short - and the fold row rides up over the previous line. */ -.monaco-editor .diff-hidden-lines .top, -.monaco-editor .diff-hidden-lines .bottom { - box-sizing: content-box; -} -.whiteboard-changed-files-label { flex:1; min-width:0; } -/* Left inset 10px and title gap 5px mirror the file header below it (5px - padding + 5px collapse-button margin, then 5px to the path), so the - section chevron and the file chevron sit on one vertical line. */ -.whiteboard-diff-group { height:48px; min-height:48px; box-sizing:border-box; display:flex; align-items:center; gap:12px; padding:12px 16px 4px 10px; border-top:1px solid var(--vscode-panel-border); background:var(--vscode-editor-background); color:var(--vscode-editor-foreground); } -.whiteboard-diff-group[hidden] { display:none; } -.whiteboard-diff-group-title { font-size:13px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } -.whiteboard-diff-group-counts { margin-left:auto; font:11px var(--vscode-editor-font-family, monospace); color:var(--vscode-descriptionForeground); white-space:nowrap; } -.whiteboard-diff-group.is-viewed > span { opacity:.45; } - -.whiteboard-diff-group-toggle { display:flex; align-items:center; gap:5px; min-width:0; border:0; padding:0; color:inherit; background:transparent; cursor:pointer; text-align:left; } -.whiteboard-diff-group-toggle:focus-visible { outline:1px solid var(--vscode-focusBorder); } - -/* The surrounding navigation owns the top edge of the diff pane. */ -.multi-diff-sticky-section .whiteboard-diff-group, -.whiteboard-files-editor-diffs .multiDiffEntry:first-child > .whiteboard-diff-group { - border-top: 0; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardApiEditorSerializer.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardApiEditorSerializer.test.ts deleted file mode 100644 index dcdda6b62..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardApiEditorSerializer.test.ts +++ /dev/null @@ -1,114 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; - -import { Event } from "../../../../base/common/event.js"; -import { Registry } from "../../../../platform/registry/common/platform.js"; -import { EditorExtensions, EditorsOrder, type IEditorFactoryRegistry } from "../../../../workbench/common/editor.js"; -import { EditorGroupModel } from "../../../../workbench/common/editor/editorGroupModel.js"; -import { WhiteboardCanvasEditorTabsService } from "../../../services/whiteboardCanvasEditorTabsService.js"; -import { WhiteboardApiEditorSerializer } from "./whiteboardApiEditorSerializer.js"; -import { WhiteboardCanvasEditorInput } from "./whiteboardCanvasEditorInput.js"; - -test("native group restoration preserves both reviews, order and pinned source versions without duplicate tabs", async (t) => { - const inputs: WhiteboardCanvasEditorInput[] = []; - let tabs: WhiteboardCanvasEditorTabsService; - const instantiation = { - createInstance(ctor: any, ...args: any[]) { - if (ctor !== WhiteboardCanvasEditorInput) return new ctor(...args); - const input = new WhiteboardCanvasEditorInput(args[0], {} as never); - inputs.push(input); - return input; - }, - invokeFunction(fn: any) { - return fn({ get: () => tabs }); - }, - }; - const groups: EditorGroupModel[] = []; - const editors = { - onDidCloseEditor: Event.None, - async openEditor(input: WhiteboardCanvasEditorInput, options: any, group: EditorGroupModel) { - group.openEditor(input, { pinned: options.pinned, active: !options.inactive }); - }, - }; - const groupService = { groups, mainPart: { activeGroup: undefined as EditorGroupModel | undefined } }; - const createTabs = () => - new WhiteboardCanvasEditorTabsService(instantiation as never, editors as never, groupService as never, {} as never, {} as never); - tabs = createTabs(); - const registry = Registry.as(EditorExtensions.EditorFactory); - registry.start({ get: () => instantiation } as never); - const registration = registry.registerEditorSerializer(WhiteboardCanvasEditorInput.ID, WhiteboardApiEditorSerializer); - const config = { getValue: () => undefined, onDidChangeConfiguration: Event.None }; - const group = (state?: ReturnType) => - new EditorGroupModel(state, instantiation as never, config as never); - const left = group(), - right = group(); - t.after(() => { - registration.dispose(); - tabs.dispose(); - left.dispose(); - right.dispose(); - groups.forEach((group) => group.dispose()); - inputs.forEach((input) => input.dispose()); - }); - left.openEditor(tabs.inputFor({ kind: "home" }), { pinned: true, sticky: true }); - left.openEditor(tabs.inputFor({ kind: "api", sessionId: "a", title: "Review A" }), { pinned: true, active: true }); - left.openEditor(tabs.inputFor({ kind: "api-source", sessionId: "a", title: "Review A", selection: { sessionId: "a", kind: "version", version: 7 } }), { - pinned: true, - active: false, - }); - right.openEditor(tabs.inputFor({ kind: "api", sessionId: "b", title: "Review B" }), { pinned: true, active: true }); - const saved = [left.serialize(), right.serialize()]; - tabs.dispose(); - tabs = createTabs(); - groups.push(...saved.map((state) => group(state))); - groupService.mainPart.activeGroup = groups[1]; - assert.deepEqual( - groups.map((group) => group.getEditors(EditorsOrder.SEQUENTIAL).map((editor) => editor.getName())), - [["Home", "Review A", "Source — Review A (v7)"], ["Review B"]], - ); - assert.equal(groups[0]!.activeEditor!.getName(), "Review A"); - const restored = groups[0]!.activeEditor; - assert.equal(await tabs.openApiWhiteboard("a", "Renamed A"), restored); - assert.equal(groups[0]!.count, 3); - assert.equal(groups[0]!.stickyCount, 1); - assert.equal(groups[1]!.count, 1); - assert.equal(restored!.getName(), "Renamed A"); -}); - -test("invalid saved tabs are ignored instead of preventing the window from restoring", () => { - const serializer = new WhiteboardApiEditorSerializer(); - for (const value of [ - "invalid JSON", - "null", - '{"kind":"api"}', - '{"kind":"api-source","sessionId":"a","title":"A","version":-1}', - ]) { - assert.equal(serializer.deserialize({} as never, value), undefined); - } -}); - - -test("current Source tabs retain identity and main version tabs still restore", () => { - const inputs: WhiteboardCanvasEditorInput[] = []; - let tabs: WhiteboardCanvasEditorTabsService; - const instantiation = { - createInstance(_ctor: unknown, target: ConstructorParameters[0]) { - const input = new WhiteboardCanvasEditorInput(target, {} as never); - inputs.push(input); - return input; - }, - invokeFunction(fn: (accessor: { get(): WhiteboardCanvasEditorTabsService }) => unknown) { return fn({ get: () => tabs }); }, - }; - tabs = new WhiteboardCanvasEditorTabsService(instantiation as never, { onDidCloseEditor: Event.None } as never, {} as never, {} as never, {} as never); - try { - const serializer = new WhiteboardApiEditorSerializer(); - const restored = serializer.deserialize(instantiation as never, JSON.stringify({ kind: "api-source", sessionId: "a", title: "A", selection: { sessionId: "a", kind: "current" } })); - assert.equal(tabs.inputFor({ kind: "api-source", sessionId: "a", title: "A", selection: { sessionId: "a", kind: "current" } }), restored); - assert.notEqual(tabs.inputFor({ kind: "api-source", sessionId: "a", title: "A", selection: { sessionId: "a", kind: "version", version: 2 } }), restored); - const upgraded = serializer.deserialize(instantiation as never, JSON.stringify({ kind: "api-source", reviewId: "a", title: "A", selection: { reviewId: "a", kind: "current" } })); - assert.equal(upgraded, restored); - assert.deepEqual(JSON.parse(serializer.serialize(upgraded as WhiteboardCanvasEditorInput)!), { kind: "api-source", sessionId: "a", title: "A", selection: { sessionId: "a", kind: "current" } }); - const historical = serializer.deserialize(instantiation as never, JSON.stringify({ kind: "api-source", sessionId: "a", title: "A", version: 2 })); - assert.equal((historical as WhiteboardCanvasEditorInput).getName(), "Source — A (v2)"); - } finally { tabs.dispose(); inputs.forEach(input => input.dispose()); } -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardApiEditorSerializer.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardApiEditorSerializer.ts deleted file mode 100644 index 857ccbbc0..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardApiEditorSerializer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { IInstantiationService } from "../../../../platform/instantiation/common/instantiation.js"; -import type { IEditorSerializer } from "../../../../workbench/common/editor.js"; -import type { EditorInput } from "../../../../workbench/common/editor/editorInput.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../../services/whiteboardCanvasEditorTabsService.js"; -import { WhiteboardCanvasEditorInput } from "./whiteboardCanvasEditorInput.js"; - -/** Let the workbench persist API tab order, groups and focus alongside other editors. */ -export class WhiteboardApiEditorSerializer implements IEditorSerializer { - canSerialize(editor: EditorInput) { - return editor instanceof WhiteboardCanvasEditorInput && - (editor.target.kind === "api" || editor.target.kind === "api-source" || editor.target.kind === "home"); - } - - serialize(editor: WhiteboardCanvasEditorInput) { - return this.canSerialize(editor) ? JSON.stringify(editor.target) : undefined; - } - - deserialize(instantiation: IInstantiationService, value: string) { - let target; - try { target = JSON.parse(value); } catch { return; } - if (!target || !["api", "api-source", "home"].includes(target.kind)) return; - // Restore old saved editor state once; serialize() writes only session IDs. - for (const record of [target, target.selection]) { - if (record && typeof record === "object" && "reviewId" in record) { - if ("sessionId" in record) return; - record.sessionId = record.reviewId; - delete record.reviewId; - } - } - if (target.kind !== "home" && (typeof target.sessionId !== "string" || typeof target.title !== "string")) return; - if (target.kind === "api-source") { - // Main already persists version-based Source tabs. Translate directly; - // intermediate development-only view/generation payloads need no adapter. - if (!target.selection && Number.isInteger(target.version) && target.version >= 0) - target = { kind: target.kind, sessionId: target.sessionId, title: target.title, - selection: { sessionId: target.sessionId, kind: "version", version: target.version } }; - const selection = target.selection; - if (!selection || selection.sessionId !== target.sessionId || - !["current", "version"].includes(selection.kind) || - (selection.kind === "version" && (!Number.isInteger(selection.version) || selection.version < 0))) return; - - } - return instantiation.invokeFunction(accessor => accessor.get(IWhiteboardCanvasEditorTabsService).inputFor(target)); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasEditor.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasEditor.contribution.ts deleted file mode 100644 index cbad696ae..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasEditor.contribution.ts +++ /dev/null @@ -1,130 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from "../../../../base/common/event.js"; -import { Disposable } from "../../../../base/common/lifecycle.js"; -import { SyncDescriptor } from "../../../../platform/instantiation/common/descriptors.js"; -import { Registry } from "../../../../platform/registry/common/platform.js"; -import { EditorPaneDescriptor, IEditorPaneRegistry } from "../../../../workbench/browser/editor.js"; -import { - IWorkbenchContribution, - registerWorkbenchContribution2, - WorkbenchPhase, -} from "../../../../workbench/common/contributions.js"; -import { - EditorExtensions, - EditorResourceAccessor, - SideBySideEditor, - type IEditorFactoryRegistry, -} from "../../../../workbench/common/editor.js"; -import { IEditorGroupsService } from "../../../../workbench/services/editor/common/editorGroupsService.js"; -import { IEditorService } from "../../../../workbench/services/editor/common/editorService.js"; -import { IWhiteboardApiCatalogService } from "../../../services/whiteboardApiCatalogService.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../../services/whiteboardCanvasEditorTabsService.js"; -import { IWhiteboardDesktopConnectionService } from "../../../services/whiteboardDesktopConnectionService.js"; -import { WhiteboardApiEditorSerializer } from "./whiteboardApiEditorSerializer.js"; -import { WhiteboardCanvasEditorInput } from "./whiteboardCanvasEditorInput.js"; -import { WhiteboardCanvasEditorPane } from "./whiteboardCanvasPart.js"; -import { isWhiteboardReadonlySource } from "../../../common/whiteboardReadonlySource.js"; - -Registry.as(EditorExtensions.EditorFactory).registerEditorSerializer( - WhiteboardCanvasEditorInput.ID, - WhiteboardApiEditorSerializer, -); - -Registry.as(EditorExtensions.EditorPane).registerEditorPane( - EditorPaneDescriptor.create(WhiteboardCanvasEditorPane, WhiteboardCanvasEditorPane.ID, "Whiteboard"), - [new SyncDescriptor(WhiteboardCanvasEditorInput)], -); - -class WhiteboardCanvasEditorContribution extends Disposable implements IWorkbenchContribution { - static readonly ID = "workbench.contrib.devfast.whiteboardCanvasEditor"; - - constructor( - @IEditorService private readonly editorService: IEditorService, - @IEditorGroupsService - private readonly editorGroupsService: IEditorGroupsService, - @IWhiteboardDesktopConnectionService - private readonly desktopConnection: IWhiteboardDesktopConnectionService, - @IWhiteboardApiCatalogService private readonly apiCatalog: IWhiteboardApiCatalogService, - @IWhiteboardCanvasEditorTabsService - private readonly tabsService: IWhiteboardCanvasEditorTabsService, - ) { - super(); - this._register(this.editorService.onDidActiveEditorChange(() => { - const editor = this.editorService.activeEditor; - const resource = EditorResourceAccessor.getCanonicalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY }); - if (editor && resource && isWhiteboardReadonlySource(resource)) this.tabsService.registerWhiteboardEditor(resource.authority, editor); - })); - this._register( - this.editorService.onDidCloseEditor(({ editor }) => { - if (!(editor instanceof WhiteboardCanvasEditorInput)) return; - if (editor.target.kind !== "api") { - void this.tabsService.openHome(true); - } - }), - ); - this._register( - apiCatalog.onDidCloseWhiteboard((uuid) => { - void this.tabsService.closeWhiteboard(uuid); - }), - ); - void this.initialize(); - } - - private async initialize(): Promise { - await this.editorGroupsService.whenRestored; - // Restored pinned source editors belong to the same review as their URI. - for (const group of this.editorGroupsService.groups) { - for (const editor of group.editors) { - const resource = EditorResourceAccessor.getCanonicalUri(editor, { - supportSideBySide: SideBySideEditor.PRIMARY, - }); - if (resource && isWhiteboardReadonlySource(resource)) this.tabsService.registerWhiteboardEditor(resource.authority, editor); - } - } - this.closeRestoredApiTabsMissingFromCatalog(); - await this.tabsService.openHome(!this.editorService.activeEditor); - await this.desktopConnection.initialize(); - await this.apiCatalog.initialize(); - } - - /** Restored API tabs may belong to reviews deleted or dismissed while the app was closed. */ - private closeRestoredApiTabsMissingFromCatalog(): void { - const restored = new Set( - this.editorGroupsService.groups.flatMap((group) => - group.editors.flatMap((editor) => - editor instanceof WhiteboardCanvasEditorInput && - (editor.target.kind === "api" || editor.target.kind === "api-source") - ? [editor.target.sessionId] - : [], - ), - ), - ); - if (restored.size === 0) return; - const reconcile = async () => { - // The managed tutorial is intentionally absent from the Home catalog. - const tutorial = await this.desktopConnection.getTutorialStatus().catch(() => undefined); - for (const sessionId of restored) { - if (sessionId === tutorial?.sessionId) continue; - const review = this.apiCatalog.reviews.find((review) => review.sessionId === sessionId); - if (!review || review.dismissedAt) void this.tabsService.closeWhiteboard(sessionId); - } - }; - if (this.apiCatalog.loaded) void reconcile(); - else - this._register( - Event.once(this.apiCatalog.onDidChange)(() => { - void reconcile(); - }), - ); - } -} - -registerWorkbenchContribution2( - WhiteboardCanvasEditorContribution.ID, - WhiteboardCanvasEditorContribution, - WorkbenchPhase.AfterRestored, -); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasEditorInput.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasEditorInput.ts deleted file mode 100644 index 3d0903839..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasEditorInput.ts +++ /dev/null @@ -1,117 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Codicon } from "../../../../base/common/codicons.js"; -import type { ThemeIcon } from "../../../../base/common/themables.js"; -import { URI } from "../../../../base/common/uri.js"; -import { localize } from "../../../../nls.js"; -import { - EditorInputCapabilities, - type GroupIdentifier, - type IUntypedEditorInput, -} from "../../../../workbench/common/editor.js"; -import { EditorInput } from "../../../../workbench/common/editor/editorInput.js"; -import { IEditorGroupsService } from "../../../../workbench/services/editor/common/editorGroupsService.js"; - -import { SCRATCHPAD_SESSION_ID, type WhiteboardSourceSelection } from "../../../common/whiteboardProtocol.js"; -import { sourceSelectionIdentity } from "../../../common/whiteboardSourceView.js"; - -export type WhiteboardCanvasEditorTarget = - | { readonly kind: "home" } - | { readonly kind: "welcome" } - | { readonly kind: "settings" } - | { - readonly kind: "api-source"; - readonly sessionId: string; - readonly selection: WhiteboardSourceSelection; - readonly title: string; - } - | { readonly kind: "api"; readonly sessionId: string; readonly title: string }; - -export class WhiteboardCanvasEditorInput extends EditorInput { - static readonly ID = "workbench.editors.devfast.whiteboardCanvas"; - static readonly EDITOR_ID = "workbench.editor.devfast.whiteboardCanvas"; - - readonly resource: URI; - private _target: WhiteboardCanvasEditorTarget; - constructor( - target: WhiteboardCanvasEditorTarget, - @IEditorGroupsService - private readonly editorGroupsService: IEditorGroupsService, - ) { - super(); - this._target = target; - this.resource = URI.from({ - scheme: "devfast-review-canvas", - authority: target.kind, - path: - target.kind === "api-source" - ? `/${sourceSelectionIdentity(target.selection)}` - : target.kind === "api" - ? `/${target.sessionId}` - : `/${target.kind}`, - }); - } - - get target(): WhiteboardCanvasEditorTarget { - return this._target; - } - - setApiTitle(title: string): void { - if (this._target.kind !== "api" || this._target.title === title) return; - this._target = { ...this._target, title }; - this._onDidChangeLabel.fire(); - } - - override get typeId(): string { - return WhiteboardCanvasEditorInput.ID; - } - - override get editorId(): string { - return WhiteboardCanvasEditorInput.EDITOR_ID; - } - - override get capabilities(): EditorInputCapabilities { - let capabilities = - EditorInputCapabilities.Readonly | EditorInputCapabilities.Singleton | EditorInputCapabilities.ForceReveal; - if (this.target.kind === "home") { - capabilities |= EditorInputCapabilities.CannotClose; - } - return capabilities; - } - - override canMove(sourceGroup: GroupIdentifier, targetGroup: GroupIdentifier): true | string { - if ( - this.target.kind === "home" && - this.editorGroupsService.getPart(targetGroup) !== this.editorGroupsService.mainPart - ) { - return localize("whiteboardHomeCannotMove", "The Home tab cannot move to a separate window."); - } - return super.canMove(sourceGroup, targetGroup); - } - - override getName(): string { - if (this.target.kind === "api-source") return this.target.selection.kind === "current" ? `Source — ${this.target.title}` : `Source — ${this.target.title} (v${this.target.selection.version})`; - if (this.target.kind === "api") return this.target.title; - if (this.target.kind === "home") return "Home"; - if (this.target.kind === "welcome") return "Welcome"; - if (this.target.kind === "settings") return "Settings"; - return "Session"; - } - - override getIcon(): ThemeIcon | undefined { - if (this.target.kind === "home") return Codicon.home; - if (this.target.kind === "api-source") return Codicon.repo; - if (this.target.kind === "api" && this.target.sessionId === SCRATCHPAD_SESSION_ID) return Codicon.edit; - return undefined; - } - - override matches(other: EditorInput | IUntypedEditorInput): boolean { - return ( - super.matches(other) || - (other instanceof WhiteboardCanvasEditorInput && other.resource.toString() === this.resource.toString()) - ); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasPart.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasPart.ts deleted file mode 100644 index 982f8ff6e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasPart.ts +++ /dev/null @@ -1,1143 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { $, addDisposableListener, getWindow, type Dimension } from "../../../../base/browser/dom.js"; -import type { IHoverOptions, IHoverWidget } from "../../../../base/browser/ui/hover/hover.js"; -import { HoverPosition } from "../../../../base/browser/ui/hover/hoverWidget.js"; -import { createTrustedTypesPolicy } from "../../../../base/browser/trustedTypes.js"; -import type { CancellationToken } from "../../../../base/common/cancellation.js"; -import { Emitter } from "../../../../base/common/event.js"; -import { Disposable, DisposableStore, MutableDisposable, toDisposable } from "../../../../base/common/lifecycle.js"; -import { FileAccess } from "../../../../base/common/network.js"; -import type { ICursorPositionChangedEvent } from "../../../../editor/common/cursorEvents.js"; -import { ICommandService } from "../../../../platform/commands/common/commands.js"; -import { ConfigurationTarget, IConfigurationService } from "../../../../platform/configuration/common/configuration.js"; -import { TextEditorSelectionSource, type IEditorOptions } from "../../../../platform/editor/common/editor.js"; -import { IHoverService } from "../../../../platform/hover/browser/hover.js"; -import { createDecorator, IInstantiationService } from "../../../../platform/instantiation/common/instantiation.js"; -import { ILogService } from "../../../../platform/log/common/log.js"; -import { FocusMode } from "../../../../platform/native/common/native.js"; -import { INotificationService } from "../../../../platform/notification/common/notification.js"; -import { IProductService } from "../../../../platform/product/common/productService.js"; -import { IEditorProgressService, LongRunningOperation } from "../../../../platform/progress/common/progress.js"; -import { IStorageService, StorageScope, StorageTarget } from "../../../../platform/storage/common/storage.js"; -import { ITelemetryService } from "../../../../platform/telemetry/common/telemetry.js"; -import { ColorScheme } from "../../../../platform/theme/common/theme.js"; -import { IThemeService } from "../../../../platform/theme/common/themeService.js"; -import { Part } from "../../../../workbench/browser/part.js"; -import { EditorPane } from "../../../../workbench/browser/parts/editor/editorPane.js"; -import type { - IEditorControl, - IEditorOpenContext, - IEditorPaneSelection, - IEditorPaneSelectionChangeEvent, -} from "../../../../workbench/common/editor.js"; -import { EditorPaneSelectionChangeReason } from "../../../../workbench/common/editor.js"; -import type { IEditorGroup } from "../../../../workbench/services/editor/common/editorGroupsService.js"; -import { IHostService } from "../../../../workbench/services/host/browser/host.js"; -import { IWorkbenchLayoutService, Parts } from "../../../../workbench/services/layout/browser/layoutService.js"; -import { - WHITEBOARD_KEYMAP_SETTING, - WHITEBOARD_SOFTWARE_MAP_SETTING, - WHITEBOARD_STRUCTURAL_DIFF_SETTING, - WHITEBOARD_TELEMETRY_SETTING, -} from "../../../common/whiteboardConfigurationDefaults.js"; -import { resolveWhiteboardSourceView, whiteboardSourceAnchor, type WhiteboardSourceView, type WhiteboardSourceSelection } from "../../../common/whiteboardProtocol.js"; -import type { - WhiteboardCanvasBridge, - WhiteboardCanvasContent, - WhiteboardCanvasDiagnostic, - WhiteboardCanvasHandle, - WhiteboardCanvasInstallContent, - WhiteboardCanvasModule, - WhiteboardCanvasOnboarding, - WhiteboardCanvasSettingsContent, - WhiteboardCanvasSetupActions, - WhiteboardCanvasTutorialBridge, - WhiteboardCliInstallStatus, - WhiteboardKeymapChoice, - WhiteboardRuntimeConfig, - WhiteboardSurfaceEvent, - WhiteboardTheme, - TutorialProgressV1, - TutorialStepId, -} from "../../../common/whiteboardProtocol.js"; -import { - parseWhiteboardVerbRequest, - WHITEBOARD_CANVAS_RESUME_EVENT, - WHITEBOARD_TUTORIAL_PROGRESS_STORAGE_KEY, - WHITEBOARD_TUTORIAL_STEP_IDS -} from "../../../common/whiteboardProtocol.js"; -import { IWhiteboardVerbsService } from "../../../contrib/verbs/whiteboardVerbs.js"; -import { IWhiteboardApiCatalogService } from "../../../services/whiteboardApiCatalogService.js"; -import { IWhiteboardApiSourceService } from "../../../services/whiteboardApiSourceService.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../../services/whiteboardCanvasEditorTabsService.js"; -import { IWhiteboardDesktopConnectionService } from "../../../services/whiteboardDesktopConnectionService.js"; -import { WhiteboardDiffViewService } from "../../../services/whiteboardDiffViewService.js"; -import { - WhiteboardEmbeddedEditorSelection, - whiteboardEmbeddedSelectionFromOptions, -} from "../../../services/whiteboardEmbeddedNavigation.js"; -import { WhiteboardEmbeddedEditors } from "../../../services/whiteboardEmbeddedEditors.js"; -import { IWhiteboardTelemetryService } from "../../../services/whiteboardTelemetryService.js"; - -import "../../media/whiteboard.css"; -import { applyWhiteboardThemeChoice, currentWhiteboardThemeChoice } from "../../whiteboardThemeChoice.js"; -import { IWhiteboardExplorerPartsService } from "../explorer/whiteboardExplorerPart.js"; -import { WhiteboardCanvasEditorInput } from "./whiteboardCanvasEditorInput.js"; - -interface WhiteboardCanvasAssetsModule extends WhiteboardCanvasModule { - readonly clearWhiteboardViewState: (config: WhiteboardRuntimeConfig) => void; - readonly whiteboardWasmUrl: string; - readonly whiteboardStylesheetUrls: readonly string[]; -} - -interface WhiteboardCanvasGlobalThis { - __zod_globalConfig?: { - jitless?: boolean; - }; -} - -interface WhiteboardCanvasLoadLifecycle { - ready(): void; - reportDiagnostic(diagnostic: WhiteboardCanvasDiagnostic): void; -} - -type WhiteboardCanvasState = "home" | "connecting" | "active" | "completed" | "error"; - -const whiteboardCanvasPolicy = createTrustedTypesPolicy("whiteboardCanvas", { - createScriptURL: (value: string) => value, -}); - -const requestWhiteboardApi: typeof fetch = (url, init) => fetch(url, init); - -function isTutorialStepId(step: unknown): step is TutorialStepId { - return typeof step === "string" && WHITEBOARD_TUTORIAL_STEP_IDS.includes(step as TutorialStepId); -} -function embeddedSelectionChangeReason(event: ICursorPositionChangedEvent): EditorPaneSelectionChangeReason { - switch (event.source) { - case TextEditorSelectionSource.PROGRAMMATIC: - return EditorPaneSelectionChangeReason.PROGRAMMATIC; - case TextEditorSelectionSource.NAVIGATION: - return EditorPaneSelectionChangeReason.NAVIGATION; - case TextEditorSelectionSource.JUMP: - return EditorPaneSelectionChangeReason.JUMP; - default: - return EditorPaneSelectionChangeReason.USER; - } -} - -export class WhiteboardCanvasEditorPane extends EditorPane { - static readonly ID = WhiteboardCanvasEditorInput.EDITOR_ID; - - private readonly canvas = this._register(new MutableDisposable()); - private readonly surfaceEvents = this._register(new Emitter()); - private readonly _onDidChangeSelection = this._register(new Emitter()); - readonly onDidChangeSelection = this._onDidChangeSelection.event; - private readonly embeddedSelectionListeners = this._register(new MutableDisposable()); - private readonly themeEvents = this._register(new Emitter()); - private container: HTMLElement | null = null; - private canvasMount: HTMLElement | null = null; - private targetDocument: Document | null = null; - private apiContent: Extract | undefined; - private loadGeneration = 0; - private openingGeneration: number | undefined; - private readonly refreshProgress: LongRunningOperation; - private renderedInput: WhiteboardCanvasEditorInput | undefined; - private readyInput: WhiteboardCanvasEditorInput | undefined; - private assetsPromise: Promise | null = null; - private readonly modelSubscription = this._register(new MutableDisposable()); - private readonly inlineEditors: WhiteboardEmbeddedEditors; - private readonly diffViews: WhiteboardDiffViewService; - - constructor( - group: IEditorGroup, - @ITelemetryService telemetryService: ITelemetryService, - @IThemeService private readonly whiteboardThemeService: IThemeService, - @IStorageService private readonly storageService: IStorageService, - @IProductService private readonly productService: IProductService, - @IWhiteboardDesktopConnectionService - private readonly desktopConnection: IWhiteboardDesktopConnectionService, - @IWhiteboardApiSourceService private readonly apiSource: IWhiteboardApiSourceService, - @IWhiteboardApiCatalogService private readonly apiCatalog: IWhiteboardApiCatalogService, - @IWhiteboardVerbsService private readonly verbs: IWhiteboardVerbsService, - @IWhiteboardCanvasEditorTabsService - private readonly tabsService: IWhiteboardCanvasEditorTabsService, - @IWhiteboardExplorerPartsService - private readonly explorerParts: IWhiteboardExplorerPartsService, - @IInstantiationService - whiteboardInstantiationService: IInstantiationService, - @IHostService private readonly hostService: IHostService, - @IWorkbenchLayoutService - private readonly layoutService: IWorkbenchLayoutService, - @ICommandService private readonly commandService: ICommandService, - @IConfigurationService - private readonly configurationService: IConfigurationService, - @IWhiteboardTelemetryService - private readonly whiteboardTelemetryService: IWhiteboardTelemetryService, - @ILogService private readonly logService: ILogService, - @IHoverService private readonly hoverService: IHoverService, - @INotificationService private readonly notificationService: INotificationService, - @IEditorProgressService editorProgressService: IEditorProgressService, - ) { - super(WhiteboardCanvasEditorPane.ID, group, telemetryService, whiteboardThemeService, storageService); - this.inlineEditors = this._register(whiteboardInstantiationService.createInstance(WhiteboardEmbeddedEditors)); - this.refreshProgress = this._register(new LongRunningOperation(editorProgressService)); - this.diffViews = this._register( - whiteboardInstantiationService.createInstance(WhiteboardDiffViewService, this.inlineEditors), - ); - this._register( - verbs.onDidEmitSurfaceEvent((event) => { - if ( - event.event === "editorSelectionChanged" && - event.sessionId !== this.apiContent?.sessionId - ) - return; - this.surfaceEvents.fire(event); - }), - ); - this._register( - verbs.onDidRequestCanvasFocus(() => { - this.canvas.value?.focus(); - void this.hostService.focus(this.targetDocument?.defaultView ?? window); - }), - ); - this._register( - this.inlineEditors.onDidChangeActiveEditor(() => { - this._onDidChangeControl.fire(); - this.bindEmbeddedSelectionControl(); - }), - ); - this._register( - whiteboardThemeService.onDidColorThemeChange(() => { - const theme = this.colorScheme(); - this.themeEvents.fire(theme); - this.surfaceEvents.fire({ event: "themeChanged", theme }); - }), - ); - this._register(desktopConnection.onDidFail((error) => void this.renderFailure(error))); - this._register( - configurationService.onDidChangeConfiguration((event) => { - if ( - !event.affectsConfiguration(WHITEBOARD_SOFTWARE_MAP_SETTING) && - !event.affectsConfiguration(WHITEBOARD_STRUCTURAL_DIFF_SETTING) - ) - return; - if (this.apiContent) { - this.apiContent = { - ...this.apiContent, - structuralDiffEnabled: this.currentStructuralDiffEnabled(), - softwareMapEnabled: this.currentSoftwareMapEnabled(), - }; - this.canvas.value?.update(this.apiContent); - return; - } - }), - ); - } - - protected override createEditor(parent: HTMLElement): void { - parent.classList.add("whiteboard-canvas-part"); - this.targetDocument = parent.ownerDocument; - parent.ownerDocument.title = "Whiteboard"; - parent.ownerDocument.body.dataset["whiteboardCanvasMode"] = "renderer"; - const outer = $(".content.whiteboard-canvas-container"); - this.container = $(".whiteboard-canvas-host"); - this.container.tabIndex = -1; - this.canvasMount = $(".whiteboard-canvas-surface"); - this.container.appendChild(this.canvasMount); - outer.append(this.container); - parent.appendChild(outer); - // Inline peek editors promise fixedOverflowWidgets; their hover and - // definition widgets must be parented outside .review-canvas-root, - // whose container-query containment re-anchors and clips - // position: fixed descendants — but inside .monaco-workbench, where - // the --vscode-* theme variables that style hover widgets are scoped. - // One shared host serves every peek in this pane. - const overflowWidgets = $(".whiteboard-overflow-widgets.monaco-editor"); - this.layoutService.getContainer(getWindow(parent)).appendChild(overflowWidgets); - this._register(toDisposable(() => overflowWidgets.remove())); - this.diffViews.setOverflowWidgetsDomNode(overflowWidgets); - this.desktopConnection.attachControl(async (value) => { - const request = parseWhiteboardVerbRequest(value); - if (request.name === "authoringCapabilities") { - return { ok: true, result: { softwareMapEnabled: this.currentSoftwareMapEnabled() } }; - } - if (request.name === "openApiWhiteboard") { - const response = await this.verbs.dispatch(request); - return response.ok ? { ok: true, result: { softwareMapEnabled: this.currentSoftwareMapEnabled() } } : response; - } - if (request.name === "focusWindow") { - await this.hostService.focus(this.targetDocument?.defaultView ?? window, { mode: FocusMode.Force }); - return { ok: true }; - } - return this.verbs.dispatch(request); - }); - void this.desktopConnection.initialize().catch((error) => this.renderError(error)); - } - - override async setInput( - input: WhiteboardCanvasEditorInput, - options: IEditorOptions | undefined, - context: IEditorOpenContext, - token: CancellationToken, - ): Promise { - const generation = ++this.loadGeneration; - this.refreshProgress.stop(); - this.openingGeneration = generation; - try { - await this.setWhiteboardInput(input, options, context, token, generation); - } finally { - if (this.openingGeneration === generation) { - this.openingGeneration = undefined; - } - } - } - - private async setWhiteboardInput( - input: WhiteboardCanvasEditorInput, - options: IEditorOptions | undefined, - context: IEditorOpenContext, - token: CancellationToken, - generation: number, - ): Promise { - await super.setInput(input, options, context, token); - this.restoreEmbeddedSelection(options); - try { - await this.desktopConnection.initialize(); - } catch (error) { - if (generation === this.loadGeneration && !token.isCancellationRequested) { - await this.renderError(error, generation); - } - return; - } - if (generation !== this.loadGeneration || token.isCancellationRequested) { - return; - } - if (input.target.kind === "api" && this.readyInput === input && this.renderedInput === input) { - this.canvasMount?.dispatchEvent(new globalThis.Event(WHITEBOARD_CANVAS_RESUME_EVENT)); - return; - } - if (input.target.kind === "api-source") { - // The Source placeholder replaces the mount, so the reuse shortcuts - // above must not treat the previous review as still rendered. - this.renderedInput = input; - this.readyInput = undefined; - this.setCanvasState("home"); - await this.render({ kind: "source" }, generation); - return; - } - if (!(await this.resetCanvasForGeneration(generation))) { - return; - } - this.modelSubscription.clear(); - if (input.target.kind === "api") { - try { - const { sessionId } = input.target; - const [connection, assets] = await Promise.all([this.desktopConnection.getConnection(), this.loadAssets()]); - if (generation !== this.loadGeneration || token.isCancellationRequested) return; - this.renderedInput = input; - this.setCanvasState("active", sessionId); - void this.apiCatalog - .attention(sessionId, "view") - .catch((error) => this.logService.warn("[Whiteboard] Could not mark review viewed:", error)); - let sourceSelection: WhiteboardSourceSelection = { sessionId, kind: "current" }; - let sourceView: WhiteboardSourceView = resolveWhiteboardSourceView({ sessionId, version: 0, pins: {} }); - const source = this.apiSource.canvas(() => sourceView, this.inlineEditors, this.diffViews); - const closeTutorial = () => void this.group.closeEditor(input); - const updateTutorial = (progress: TutorialProgressV1) => { - this.writeTutorialProgress(progress); - if (!this.apiContent) return; - this.apiContent = { - ...this.apiContent, - tutorial: this.createTutorialBridge(sessionId, progress, updateTutorial, closeTutorial), - }; - this.canvas.value?.update(this.apiContent); - }; - await this.render( - { - setTutorial: (enabled) => { - if ( - !this.apiContent || - generation !== this.loadGeneration || - enabled === Boolean(this.apiContent.tutorial) - ) - return; - this.apiContent = { - ...this.apiContent, - tutorial: enabled - ? this.createTutorialBridge(sessionId, this.readTutorialProgress(), updateTutorial, closeTutorial) - : undefined, - }; - this.canvas.value?.update(this.apiContent); - }, - kind: "api", - sessionId, - structuralDiffEnabled: this.currentStructuralDiffEnabled(), - softwareMapEnabled: this.currentSoftwareMapEnabled(), - setTitle: (title) => input.setApiTitle(title), - setSourceView: (selection, next) => { - sourceSelection = selection; - sourceView = next; - source.openStructuralComparison(); - }, - openSource: (source, range) => this.apiSource.open(source, range), - bridge: { - ...source, - ...this.sharedBridge(generation, () => { - this.readyInput = input; - }), - config: this.whiteboardRuntimeConfig( - { - ...connection, - sessionId: sessionId, - }, - assets, - ), - request: requestWhiteboardApi, - post: async (request) => { - if (request.name === "openSourceTree") { - await this.tabsService.openApiSource(sourceSelection, input.getName()); - this.explorerParts.show(); - return { ok: true }; - } - if (request.name === "reveal") { - const range = { startLine: request.args.startLine, endLine: request.args.endLine }; - await this.apiSource.open( - { view: whiteboardSourceAnchor(sourceView, request.args.pins), file: request.args.path, side: request.args.side ?? "head" }, - range, - ); - return { ok: true }; - } - if (request.name === "openDiff") { - await this.apiSource.openDiff(sourceView, request.args.path); - return { ok: true }; - } - return this.verbs.dispatch(request); - }, - }, - }, - generation, - assets, - ); - } catch (error) { - if (generation === this.loadGeneration) await this.renderError(error, generation); - } - return; - } - if (input.target.kind === "home") { - this.renderedInput = input; - this.setCanvasState("home"); - await this.apiCatalog.initialize(); - let emptyStateVisible = false; - /* The empty-list render suspends on the install fetch below, while - the list render has no await at all. The sequence number keeps a - suspended empty render from resuming after a later list render - and overwriting it with a stale snapshot. */ - let renderSeq = 0; - const renderHome = async () => { - const seq = ++renderSeq; - const whiteboards = this.apiCatalog.reviews; - const isEmpty = whiteboards.length === 0; - // Only the Welcome rail needs install status; the list must - // render without waiting on it. One fetch serves both the - // install card and the onboarding rail. - const install = isEmpty ? await this.resolveInstallContent() : undefined; - if (seq !== renderSeq) return; - if (isEmpty && !emptyStateVisible) { - this.whiteboardTelemetryService.capture("home_empty_state_viewed"); - } - emptyStateVisible = isEmpty; - const openWhiteboard = (uuid: string) => { - this.whiteboardTelemetryService.capture("review_opened", { - via: "home", - }); - const api = this.apiCatalog.reviews.find((whiteboard) => whiteboard.sessionId === uuid); - return api ? this.tabsService.openApiWhiteboard(uuid, api.title) : Promise.resolve(); - }; - return this.render( - { - kind: "home", - whiteboards, - openWhiteboard: (uuid) => void openWhiteboard(uuid), - deleteWhiteboard: (uuid) => this.apiCatalog.deleteWhiteboard(uuid), - dismissWhiteboard: (uuid) => this.apiCatalog.attention(uuid, "dismiss"), - restoreWhiteboard: (uuid) => this.apiCatalog.attention(uuid, "restore"), - openSourceTree: (uuid) => { - const api = this.apiCatalog.reviews.find((whiteboard) => whiteboard.sessionId === uuid); - if (api) { - void this.tabsService.openApiSource({ sessionId: api.sessionId, kind: "current" }, api.title).then(() => this.explorerParts.show()); - return; - } - }, - // Home shows the Welcome rail while the list is empty. - install, - setupActions: this.setupActions(), - onboarding: install ? this.resolveOnboarding(install.status) : undefined, - openTutorial: () => this.openTutorial(), - }, - generation, - ); - }; - // Home stays live while it is the rendered input: a deletion or a - // newly published review re-renders the list. render() drops stale - // generations once another input starts loading. - const subscriptions = new DisposableStore(); - subscriptions.add(this.desktopConnection.onDidChangeLists(() => void renderHome())); - subscriptions.add(this.apiCatalog.onDidChange(() => void renderHome())); - this.modelSubscription.value = subscriptions; - await renderHome(); - return; - } - if (input.target.kind === "welcome") { - void this.desktopConnection - .prepareTutorial() - .catch((error) => this.logService.warn("[Whiteboard] Tutorial preparation did not complete:", error)); - this.renderedInput = input; - this.setCanvasState("home"); - /* Same stale-resume guard as Home: the install fetch suspends, and - a later list event must win over an earlier suspended render. */ - let renderSeq = 0; - const renderWelcome = async () => { - const seq = ++renderSeq; - const install = await this.resolveInstallContent(); - if (seq !== renderSeq) return; - return this.render( - { - kind: "welcome", - install, - setupActions: this.setupActions(), - close: () => void this.group.closeEditor(input), - onboarding: install ? this.resolveOnboarding(install.status) : undefined, - openTutorial: () => this.openTutorial(), - }, - generation, - ); - }; - // The last step completes when a review publishes, which can happen - // while this tab sits open. - this.modelSubscription.value = this.desktopConnection.onDidChangeLists(() => void renderWelcome()); - await renderWelcome(); - return; - } - if (input.target.kind === "settings") { - this.renderedInput = input; - this.setCanvasState("home"); - const [settings, install] = await Promise.all([this.resolveSettingsContent(), this.resolveInstallContent()]); - await this.render({ kind: "settings", settings: { ...settings, install } }, generation); - return; - } - } - - override async clearInput(): Promise { - // Keep apiContent with the mounted canvas so resuming it preserves its review identity. - // render() replaces both when another input is shown. - this.refreshProgress.stop(); - await super.clearInput(); - } - - protected override setEditorVisible(visible: boolean): void { - super.setEditorVisible(visible); - if (!visible) this.refreshProgress.stop(); - } - - override focus(): void { - this.canvas.value?.focus(); - } - - showFind(): boolean { - const editor = this.inlineEditors.activeCodeEditor; - let seed: string | undefined; - if (editor?.hasTextFocus()) { - const model = editor.getModel(); - const selection = editor.getSelection(); - if (model && selection && !selection.isEmpty()) { - seed = model.getValueInRange(selection); - } - } - return this.canvas.value?.showFind(seed) ?? false; - } - - override getControl(): IEditorControl | undefined { - return this.inlineEditors; - } - - override setOptions(options: IEditorOptions | undefined): void { - super.setOptions(options); - this.restoreEmbeddedSelection(options); - } - - getSelection(): IEditorPaneSelection | undefined { - const editor = this.inlineEditors.selectionCodeEditor; - const position = editor?.getPosition(); - const model = editor?.getModel(); - if (!editor || !position || !model) return undefined; - const domNode = editor.getDomNode(); - const view = domNode?.closest(".whiteboard-files-editor") ? "diff" : "review"; - const section = domNode?.closest("[data-whiteboard-section]")?.dataset["whiteboardSection"]; - return new WhiteboardEmbeddedEditorSelection(editor, { - view, - path: model.uri.path.slice(1), - side: new URLSearchParams(model.uri.query).get("side") === "base" ? "base" : "head", - lineNumber: position.lineNumber, - column: position.column, - section, - }); - } - - private bindEmbeddedSelectionControl(): void { - const editor = this.inlineEditors.activeCodeEditor; - if (!editor) { - this.embeddedSelectionListeners.clear(); - return; - } - const store = new DisposableStore(); - store.add( - editor.onDidFocusEditorText(() => { - this._onDidChangeSelection.fire({ - reason: EditorPaneSelectionChangeReason.USER, - }); - }), - ); - store.add( - editor.onDidChangeCursorPosition((event) => - this._onDidChangeSelection.fire({ - reason: embeddedSelectionChangeReason(event), - }), - ), - ); - this.embeddedSelectionListeners.value = store; - } - - private restoreEmbeddedSelection(options: IEditorOptions | undefined): void { - const selection = whiteboardEmbeddedSelectionFromOptions(options); - if (!selection) return; - selection.restoreInCanvas(); - } - - /** - * Retargets the Toggle Inline View command at the in-tab diff. The diff - * editor commands duck-type this method on the active pane, so the Review - * tab answers for its embedded diff and no-ops in the other views. - */ - toggleRenderSideBySide(): void { - this.diffViews.toggleRenderSideBySide(); - } - - override layout(_dimension: Dimension): void { - // The canvas uses normal CSS flow and fills the editor pane. - } - - private setupActions(): WhiteboardCanvasSetupActions { - return { - load: () => this.loadInstallContent(), - installCli: async () => { await this.commandService.executeCommand("whiteboard.installCliInPath"); }, - }; - } - - private async resolveInstallContent(): Promise { - try { - return await this.loadInstallContent(); - } catch (error) { - this.logService.warn("Whiteboard install status failed", error); - return undefined; - } - } - - private async loadInstallContent(): Promise { - const status = await this.desktopConnection.getCliInstallStatus(); - return { - status, - apply: async (request) => { - await this.desktopConnection.applyCliInstall(request); - return this.desktopConnection.getCliInstallStatus(); - }, - remove: async (request) => { - await this.desktopConnection.removeCliInstall(request); - return this.desktopConnection.getCliInstallStatus(); - }, - removeLegacySkills: async () => { - await this.desktopConnection.removeLegacySkills(); - return this.desktopConnection.getCliInstallStatus(); - }, - finishUpdate: async () => { - await this.desktopConnection.finishCliInstallUpdate(); - return this.desktopConnection.getCliInstallStatus(); - }, - decline: async () => { - await this.desktopConnection.declineCliInstall(); - return this.desktopConnection.getCliInstallStatus(); - }, - skip: async () => { - await this.desktopConnection.skipCliInstallPrompts(); - return this.desktopConnection.getCliInstallStatus(); - }, - enablePrompts: async () => { - await this.desktopConnection.resetCliInstallPrompts(); - return this.desktopConnection.getCliInstallStatus(); - }, - }; - } - - private openTutorial(): void { - // The command opens and focuses the tutorial tab itself, and reports - // its own failures. Welcome stays open behind it: it is a hub the - // reader comes back to, not a one-shot wizard. - void this.commandService.executeCommand("whiteboard.openTutorial"); - } - - /** - * Settings state and actions for the Settings page. Every value lives in - * workbench configuration, apart from the retention window, which the review - * server owns. Extensions reuse the existing quick pick. - */ - private async resolveSettingsContent(): Promise { - // Settings must render even when the server preference cannot be read; - // the row then shows the default, off. - const scratchpadEnabled = await this.desktopConnection.readScratchpadEnabled().catch(() => false); - return { - telemetryEnabled: this.currentTelemetryEnabled(), - setTelemetryEnabled: async (enabled) => { - this.whiteboardTelemetryService.capture("setting_changed", { - setting: "telemetry_enabled", - enabled, - }); - if (!enabled) { - await this.whiteboardTelemetryService.flush(); - } - await this.configurationService.updateValue(WHITEBOARD_TELEMETRY_SETTING, enabled, ConfigurationTarget.USER); - return this.currentTelemetryEnabled(); - }, - theme: currentWhiteboardThemeChoice(this.configurationService, this.whiteboardThemeService), - setTheme: async (choice) => { - await applyWhiteboardThemeChoice(this.configurationService, choice); - return currentWhiteboardThemeChoice(this.configurationService, this.whiteboardThemeService); - }, - keymap: this.currentKeymap(), - setKeymap: async (choice) => { - this.whiteboardTelemetryService.capture("setting_changed", { - setting: "keymap", - enabled: true, - }); - await this.commandService.executeCommand("whiteboard.setKeymap", choice); - return this.currentKeymap(); - }, - softwareMapEnabled: this.currentSoftwareMapEnabled(), - setSoftwareMapEnabled: async (enabled) => { - this.whiteboardTelemetryService.capture("setting_changed", { - setting: "software_map_enabled", - enabled, - }); - await this.configurationService.updateValue(WHITEBOARD_SOFTWARE_MAP_SETTING, enabled, ConfigurationTarget.USER); - return this.currentSoftwareMapEnabled(); - }, - scratchpadEnabled, - setScratchpadEnabled: async (enabled) => { - this.whiteboardTelemetryService.capture("setting_changed", { - setting: "scratchpad_enabled", - enabled, - }); - return this.desktopConnection.setScratchpadEnabled(enabled); - }, - structuralDiffEnabled: this.currentStructuralDiffEnabled(), - setStructuralDiffEnabled: async (enabled) => { - await this.configurationService.updateValue( - WHITEBOARD_STRUCTURAL_DIFF_SETTING, - enabled, - ConfigurationTarget.USER, - ); - return this.currentStructuralDiffEnabled(); - }, - reloadWindow: async () => { await this.commandService.executeCommand("workbench.action.reloadWindow"); }, - diffrConfig: { - saveSummarizer: (input) => this.desktopConnection.saveDiffrSummarizer(input), - testSummarizer: (input) => this.desktopConnection.testDiffrSummarizer(input), - read: () => this.desktopConnection.readDiffrConfig(), - set: (key, value) => { - this.whiteboardTelemetryService.capture("setting_changed", { - setting: "diffr_config", - enabled: true, - }); - return this.desktopConnection.setDiffrConfigValue(key, value); - }, - }, - manageExtensions: () => void this.commandService.executeCommand("whiteboard.manageExtensions"), - }; - } - - private currentKeymap(): WhiteboardKeymapChoice { - return this.configurationService.getValue(WHITEBOARD_KEYMAP_SETTING) ?? "none"; - } - - private currentStructuralDiffEnabled(): boolean { - return ( - this.configurationService.getValue( - WHITEBOARD_STRUCTURAL_DIFF_SETTING, - ) === true - ); - } - - private currentSoftwareMapEnabled(): boolean { - return this.configurationService.getValue(WHITEBOARD_SOFTWARE_MAP_SETTING) === true; - } - - // The setting ships as true, so only an explicit false means opted out. - private currentTelemetryEnabled(): boolean { - return this.configurationService.getValue(WHITEBOARD_TELEMETRY_SETTING) !== false; - } - - /** - * Step state for the Welcome rail, derived from the install status the - * caller already fetched, so one render costs one status round-trip. The - * rest is local: stored tutorial progress and the review list. - */ - private resolveOnboarding(status: WhiteboardCliInstallStatus): WhiteboardCanvasOnboarding { - const checked = new Set(this.readTutorialProgress().checked); - const steps = WHITEBOARD_TUTORIAL_STEP_IDS.filter((step) => step !== "openMap" || this.currentSoftwareMapEnabled()); - return { - installed: !status.cli || status.shim.installed, - tutorialChecked: steps.filter((step) => checked.has(step)).length, - tutorialTotal: steps.length, - // Drafts are filtered out of this list and the tutorial never - // joins it, so this counts only a real published review. - published: this.apiCatalog.reviews.length > 0, - }; - } - - private createTutorialBridge( - sessionId: string, - progress: TutorialProgressV1, - onChange: (progress: TutorialProgressV1) => void, - close: () => void, - ): WhiteboardCanvasTutorialBridge { - /* Mutations re-read stored progress instead of using the captured - snapshot: two events arriving before the re-rendered bridge lands - (hover then goto-definition) must not clobber each other. */ - const setStep = (step: TutorialStepId, checked: boolean) => { - if (!WHITEBOARD_TUTORIAL_STEP_IDS.includes(step)) return; - const current = this.readTutorialProgress(); - if (current.checked.includes(step) === checked) return; - const values = new Set(current.checked); - if (checked) values.add(step); - else values.delete(step); - onChange({ ...current, checked: [...values] }); - }; - return { - content: { sessionId, progress, keymap: this.currentKeymap() }, - setStep, - dismiss: () => onChange({ ...this.readTutorialProgress(), dismissed: true }), - reopen: () => onChange({ ...this.readTutorialProgress(), dismissed: false }), - selectKeymap: async (keymap) => { - if (keymap !== "none" && keymap !== "vim" && keymap !== "emacs") { - throw new Error("Unsupported tutorial keymap choice."); - } - setStep("chooseKeymap", true); - try { - /* The keymap command may reload the window before its promise can - settle. Persist the completed step first so the restored tutorial - advances from the choice the user already made. */ - await this.commandService.executeCommand("whiteboard.setKeymap", keymap); - } catch (error) { - setStep("chooseKeymap", false); - throw error; - } - }, - close, - }; - } - - private readTutorialProgress(): TutorialProgressV1 { - const empty: TutorialProgressV1 = { - version: 1, - checked: [], - dismissed: false, - }; - const raw = this.storageService.get(WHITEBOARD_TUTORIAL_PROGRESS_STORAGE_KEY, StorageScope.APPLICATION); - if (!raw) return empty; - try { - const value = JSON.parse(raw) as { - version?: unknown; - checked?: unknown; - dismissed?: unknown; - steps?: unknown; - }; - if ( - value.version !== 1 || - !Array.isArray(value.steps) || - !Array.isArray(value.checked) || - !value.checked.every(isTutorialStepId) || - typeof value.dismissed !== "boolean" - ) { - throw new Error("Invalid tutorial progress."); - } - const checked = new Set(value.checked); - const known = value.steps.filter(isTutorialStepId); - if (known.length > 0 && known.every((step) => checked.has(step))) { - for (const step of WHITEBOARD_TUTORIAL_STEP_IDS) { - checked.add(step); - } - } - return { - version: 1, - checked: [...checked], - dismissed: value.dismissed, - }; - } catch { - this.writeTutorialProgress(empty); - return empty; - } - } - - private writeTutorialProgress(progress: TutorialProgressV1): void { - this.storageService.store( - WHITEBOARD_TUTORIAL_PROGRESS_STORAGE_KEY, - // `steps` marks which step ids existed at write time, so a later - // release can tell a finished tour from one its new steps reopened. - JSON.stringify({ ...progress, steps: WHITEBOARD_TUTORIAL_STEP_IDS }), - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - } - - private async renderFailure(error: Error): Promise { - this.refreshProgress.stop(); - const generation = ++this.loadGeneration; - if (await this.resetCanvasForGeneration(generation)) { - await this.renderError(error, generation); - } - } - - private async renderError(error: unknown, generation?: number): Promise { - const activeGeneration = generation ?? ++this.loadGeneration; - this.setCanvasState("error"); - await this.render( - { - kind: "error", - message: error instanceof Error ? error.message : String(error), - }, - activeGeneration, - ); - } - - private async render( - content: WhiteboardCanvasContent, - generation: number, - loadedAssets?: WhiteboardCanvasAssetsModule, - ): Promise { - if (!this.canvasMount) return; - const assets = loadedAssets ?? (await this.loadAssets()); - if (generation !== this.loadGeneration) return; - this.apiContent = content.kind === "api" ? content : undefined; - if (this.canvas.value) { - this.canvas.value.update(content); - } else { - this.canvas.value = assets.mountWhiteboardCanvas(this.canvasMount, content); - } - } - - private loadAssets(): Promise { - this.assetsPromise ??= this.importAssets().catch((error) => { - this.assetsPromise = null; - throw error; - }); - return this.assetsPromise; - } - - private async importAssets(): Promise { - // Zod 4 probes the Function constructor unless its CSP-safe mode is set - // before the canvas module graph is evaluated. Chromium reports the caught - // probe as a Trusted Types violation, so configure the bundled authoring - // runtime before importing it instead of weakening the workbench policy. - const canvasGlobal = globalThis as WhiteboardCanvasGlobalThis; - canvasGlobal.__zod_globalConfig ??= {}; - canvasGlobal.__zod_globalConfig.jitless = true; - - const url = FileAccess.asBrowserUri("vs/whiteboard/canvas/canvas-loader.js").toString(true); - const trustedUrl = whiteboardCanvasPolicy?.createScriptURL(url) ?? (url as string); - const assets = (await import( - /* webpackIgnore: true */ trustedUrl as unknown as string - )) as WhiteboardCanvasAssetsModule; - if (typeof assets.mountWhiteboardCanvas !== "function") { - throw new Error("Whiteboard canvas bundle has no mount function."); - } - await Promise.all(assets.whiteboardStylesheetUrls.map((stylesheet) => loadStylesheet(document, stylesheet))); - return assets; - } - - /** The bridge members every canvas shares; `onReady` runs once the mount reports ready. */ - private sharedBridge( - generation: number, - onReady: () => void, - lifecycle?: WhiteboardCanvasLoadLifecycle, - ): Pick< - WhiteboardCanvasBridge, - | "appSessionId" - | "subscribe" - | "currentTheme" - | "onDidChangeTheme" - | "currentDiffLayout" - | "setDiffLayout" - | "onDidChangeDiffLayout" - | "setupTooltip" - | "notify" - | "ready" - | "reportDiagnostic" - > { - return { - appSessionId: this.whiteboardTelemetryService.appSessionId, - subscribe: (listener) => this.surfaceEvents.event(listener), - currentTheme: () => this.colorScheme(), - onDidChangeTheme: (listener) => this.themeEvents.event(listener), - currentDiffLayout: () => this.diffViews.diffLayout.get(), - setDiffLayout: (layout) => this.diffViews.diffLayout.set(layout), - onDidChangeDiffLayout: (listener) => this.diffViews.diffLayout.onDidChange(listener), - notify: ({ kind, text }) => { - if (kind === "error") this.notificationService.error(text); - else this.notificationService.info(text); - }, - setupTooltip: (target, content) => { - const store = new DisposableStore(); - const hover = store.add(new MutableDisposable()); - const options: IHoverOptions = { - target, - content, - position: { hoverPosition: HoverPosition.ABOVE }, - appearance: { compact: true, showPointer: true }, - persistence: { hideOnKeyDown: true }, - }; - store.add(addDisposableListener(target, "mouseenter", () => { - if (target.getAttribute("aria-expanded") === "true") return; - hover.value = this.hoverService.showDelayedHover(options, { groupId: "whiteboard-topbar", reducedDelay: true }); - })); - store.add(addDisposableListener(target, "focus", () => { - if (!target.matches(":focus-visible") || target.getAttribute("aria-expanded") === "true") return; - hover.value = this.hoverService.showInstantHover(options); - })); - for (const event of ["blur", "pointerdown", "click", "keydown"]) { - store.add(addDisposableListener(target, event, () => hover.clear())); - } - return store; - }, - ready: () => { - if (generation !== this.loadGeneration || !this.targetDocument) return; - this.targetDocument.body.dataset["whiteboardCanvasReady"] = "true"; - onReady(); - }, - reportDiagnostic: (diagnostic) => { - if (generation === this.loadGeneration && diagnostic.level === "error") { - delete this.targetDocument?.body.dataset["whiteboardCanvasReady"]; - } - const method = diagnostic.level === "error" ? console.error : console.warn; - method(`[Whiteboard canvas ${diagnostic.source}] ${diagnostic.message}`, diagnostic.stack ?? ""); - lifecycle?.reportDiagnostic(diagnostic); - }, - }; - } - - private whiteboardRuntimeConfig( - connection: Pick, - assets: WhiteboardCanvasAssetsModule, - ): WhiteboardRuntimeConfig { - return { - ...connection, - wasmUrl: assets.whiteboardWasmUrl, - appVersion: this.productService.reviewVersion ?? this.productService.version, - theme: this.colorScheme(), - host: "desktop", - }; - } - - private async resetCanvasForGeneration(generation: number): Promise { - if (generation !== this.loadGeneration) { - return false; - } - this.readyInput = undefined; - this.inlineEditors.reset(); - this.diffViews.reset(); - return generation === this.loadGeneration; - } - - private setCanvasState(state: WhiteboardCanvasState, sessionId?: string): void { - if (!this.targetDocument) return; - this.targetDocument.body.dataset["whiteboardCanvasState"] = state; - if (state === "active" && sessionId) { - this.targetDocument.body.dataset["sessionId"] = sessionId; - delete this.targetDocument.body.dataset["whiteboardCanvasReady"]; - } else { - delete this.targetDocument.body.dataset["sessionId"]; - delete this.targetDocument.body.dataset["whiteboardCanvasReady"]; - } - } - - private colorScheme(): WhiteboardTheme { - const type = this.whiteboardThemeService.getColorTheme().type; - return type === ColorScheme.LIGHT || type === ColorScheme.HIGH_CONTRAST_LIGHT ? "light" : "dark"; - } -} - -class WhiteboardCanvasPlaceholderPart extends Part { - override readonly minimumWidth = 0; - override readonly maximumWidth = Number.POSITIVE_INFINITY; - override readonly minimumHeight = 0; - override readonly maximumHeight = Number.POSITIVE_INFINITY; - - constructor( - @IThemeService themeService: IThemeService, - @IStorageService storageService: IStorageService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - ) { - super( - Parts.WHITEBOARD_CANVAS_PART, - { hasTitle: false, borderWidth: () => 0 }, - themeService, - storageService, - layoutService, - ); - } - - override create(parent: HTMLElement): void { - this.element = parent; - super.create(parent); - } - - protected override createContentArea(parent: HTMLElement): HTMLElement { - return parent; - } - - toJSON(): object { - return { type: Parts.WHITEBOARD_CANVAS_PART }; - } -} - -export const IWhiteboardCanvasPartsService = createDecorator("whiteboardCanvasPartsService"); - -export interface IWhiteboardCanvasPartsService { - readonly _serviceBrand: undefined; -} - -export class WhiteboardCanvasParts extends Disposable implements IWhiteboardCanvasPartsService { - declare readonly _serviceBrand: undefined; - - constructor(@IInstantiationService instantiationService: IInstantiationService) { - super(); - this._register(instantiationService.createInstance(WhiteboardCanvasPlaceholderPart)); - } -} - -function loadStylesheet(document: Document, url: string): Promise { - const existing = [...document.querySelectorAll('link[data-whiteboard-canvas-stylesheet="true"]')].find( - (link) => link.href === url, - ); - if (existing) return Promise.resolve(); - return new Promise((resolve, reject) => { - const link = document.createElement("link"); - link.rel = "stylesheet"; - link.href = url; - link.dataset["whiteboardCanvasStylesheet"] = "true"; - link.addEventListener("load", () => resolve(), { once: true }); - link.addEventListener("error", () => reject(new Error(`Whiteboard canvas stylesheet failed: ${url}`)), { once: true }); - document.head.appendChild(link); - }); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardFind.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardFind.contribution.ts deleted file mode 100644 index e7171037f..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardFind.contribution.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { KeyCode, KeyMod } from "../../../../base/common/keyCodes.js"; -import { localize2 } from "../../../../nls.js"; -import { - Action2, - registerAction2, -} from "../../../../platform/actions/common/actions.js"; -import { ICommandService } from "../../../../platform/commands/common/commands.js"; -import type { ServicesAccessor } from "../../../../platform/instantiation/common/instantiation.js"; -import { KeybindingWeight } from "../../../../platform/keybinding/common/keybindingsRegistry.js"; -import { ActiveEditorContext } from "../../../../workbench/common/contextkeys.js"; -import { IEditorService } from "../../../../workbench/services/editor/common/editorService.js"; -import { WhiteboardCanvasEditorInput } from "./whiteboardCanvasEditorInput.js"; -import { WhiteboardCanvasEditorPane } from "./whiteboardCanvasPart.js"; - -const WHITEBOARD_FIND_COMMAND_ID = "whiteboard.action.find"; - -class WhiteboardFindAction extends Action2 { - constructor() { - super({ - id: WHITEBOARD_FIND_COMMAND_ID, - title: localize2("whiteboard.action.find", "Find in session"), - keybinding: { - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyMod.CtrlCmd | KeyCode.KeyF, - when: ActiveEditorContext.isEqualTo(WhiteboardCanvasEditorInput.EDITOR_ID), - }, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const pane = accessor.get(IEditorService).activeEditorPane; - if (pane instanceof WhiteboardCanvasEditorPane) { - if (pane.showFind()) return; - } - await accessor.get(ICommandService).executeCommand("actions.find"); - } -} - -registerAction2(WhiteboardFindAction); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/explorer/whiteboardExplorerPart.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/explorer/whiteboardExplorerPart.ts deleted file mode 100644 index 6624b3a26..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/explorer/whiteboardExplorerPart.ts +++ /dev/null @@ -1,631 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { sourceTreeUri, sourceTreeSelection, sourceTreeRoot } from "../../../common/whiteboardSourceView.js"; - -import { $ } from "../../../../base/browser/dom.js"; -import type { IListVirtualDelegate } from "../../../../base/browser/ui/list/list.js"; -import type { IListAccessibilityProvider } from "../../../../base/browser/ui/list/listWidget.js"; -import type { IAsyncDataSource, ITreeNode, ITreeRenderer } from "../../../../base/browser/ui/tree/tree.js"; -import { Sequencer } from "../../../../base/common/async.js"; -import { compareFileNamesDefault } from "../../../../base/common/comparers.js"; -import { Disposable } from "../../../../base/common/lifecycle.js"; -import { basename, dirname, isEqual, isEqualOrParent } from "../../../../base/common/resources.js"; -import { URI } from "../../../../base/common/uri.js"; -import { localize } from "../../../../nls.js"; -import { - IConfigurationService, - type IConfigurationChangeEvent, -} from "../../../../platform/configuration/common/configuration.js"; -import { FILES_EXCLUDE_CONFIG, FileKind, type IFileStat } from "../../../../platform/files/common/files.js"; -import { IInstantiationService, createDecorator } from "../../../../platform/instantiation/common/instantiation.js"; -import { WorkbenchAsyncDataTree } from "../../../../platform/list/browser/listService.js"; -import { ILogService } from "../../../../platform/log/common/log.js"; -import { IStorageService, StorageScope, StorageTarget } from "../../../../platform/storage/common/storage.js"; -import { IThemeService } from "../../../../platform/theme/common/themeService.js"; -import { DEFAULT_LABELS_CONTAINER, ResourceLabels, type IResourceLabel } from "../../../../workbench/browser/labels.js"; -import { Part } from "../../../../workbench/browser/part.js"; -import { EditorResourceAccessor, SideBySideEditor } from "../../../../workbench/common/editor.js"; -import type { EditorInput } from "../../../../workbench/common/editor/editorInput.js"; -import { ResourceGlobMatcher } from "../../../../workbench/common/resources.js"; -import { createFileIconThemableTreeContainerScope } from "../../../../workbench/contrib/files/browser/views/explorerView.js"; -import type { IFilesConfiguration } from "../../../../workbench/contrib/files/common/files.js"; -import { IEditorGroupsService } from "../../../../workbench/services/editor/common/editorGroupsService.js"; -import { IEditorService } from "../../../../workbench/services/editor/common/editorService.js"; -import { IWorkbenchLayoutService, Parts } from "../../../../workbench/services/layout/browser/layoutService.js"; -import { WHITEBOARD_CHROME_HEIGHT } from "../../../common/whiteboardChrome.js"; -import { - IWhiteboardApiSourceService, - WHITEBOARD_API_SOURCE_SCHEME, -} from "../../../services/whiteboardApiSourceService.js"; -import { IWhiteboardApiCatalogService } from "../../../services/whiteboardApiCatalogService.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../../services/whiteboardCanvasEditorTabsService.js"; - -import "../../media/whiteboard.css"; -import { WhiteboardCanvasEditorInput } from "../canvas/whiteboardCanvasEditorInput.js"; - -/** The row height of one explorer entry, in CSS pixels. */ -const WHITEBOARD_EXPLORER_ROW_HEIGHT = 22; - -const WHITEBOARD_EXPLORER_TEMPLATE_ID = "review.explorer.entry"; - -/** - * Whether the tree belongs beside this editor input. - * - * The rule is the resource, not the pane: a tree accompanies anything showing a - * file from disk. Review's own surfaces — the canvas, the Diff (multi-file) view - * and Home — are all `WhiteboardCanvasEditorInput`, whose resource carries the - * `devfast-review-canvas` scheme, so they are excluded by construction. - * - * This used to be a whitelist of pane ids (`TEXT_FILE_EDITOR_ID`, - * `TEXT_DIFF_EDITOR_ID`). That was wrong: clicking an image or any other binary - * file *in the tree* opens a different pane, which fell outside the list and made - * the tree collapse itself out from under the click. - */ -function accompaniesEditor(input: EditorInput | undefined): boolean { - if (!input) { - return false; - } - - if (isSourceTab(input)) { - return true; - } - - const resource = EditorResourceAccessor.getCanonicalUri(input, { supportSideBySide: SideBySideEditor.PRIMARY }); - return resource?.scheme === WHITEBOARD_API_SOURCE_SCHEME; -} - -/** The Source tab owns the current or version-selected repository tree. */ -function isSourceTab(input: EditorInput | undefined): boolean { - return input instanceof WhiteboardCanvasEditorInput && input.target.kind === "api-source"; -} - -interface IWhiteboardExplorerTemplate { - readonly label: IResourceLabel; -} - -const whiteboardExplorerDelegate: IListVirtualDelegate = { - getHeight: () => WHITEBOARD_EXPLORER_ROW_HEIGHT, - getTemplateId: () => WHITEBOARD_EXPLORER_TEMPLATE_ID, -}; - -/** - * Resolves directory children on demand and remembers every stat it produced. - * - * `revealResource` walks that cache to expand a file's ancestors, so the cache - * is part of the contract rather than an optimization: a stat that never came - * back through here cannot be revealed. - * - * Children the `files.exclude` setting hides never leave this class, so they are - * absent from the tree and from the cache. Excluding here rather than in a - * `ITreeFilter` keeps one rule: what the data source returns is what the tree - * holds, which is what reveal can reach. - */ -class WhiteboardExplorerDataSource implements IAsyncDataSource { - private readonly stats = new Map(); - - constructor( - private readonly excludes: ResourceGlobMatcher, - private readonly logService: ILogService, - private readonly apiSource: IWhiteboardApiSourceService, - ) { } - - hasChildren(element: URI | null | IFileStat): boolean { - if (element === null) { - return false; - } - return URI.isUri(element) ? true : element.isDirectory; - } - - async getChildren(element: URI | null | IFileStat): Promise { - if (element === null) { - return []; // no active review, so no tree - } - - const resource = URI.isUri(element) ? element : element.resource; - try { - const siblings = await this.apiSource.children(resource); - // One name set for the whole directory. A `files.exclude` `when` clause - // asks whether a sibling exists, and it is asked once per child, so - // scanning the sibling array each time would be quadratic. - const siblingNames = new Set(siblings.map((sibling) => basename(sibling.resource))); - const children = siblings.filter( - (child) => !this.excludes.matches(child.resource, (name) => siblingNames.has(name)), - ); - for (const child of children) { - this.stats.set(child.resource.path, child); - } - return children.sort(compareWhiteboardExplorerStats); - } catch (error) { - // Keep other directories usable when a pinned source request fails. - this.logService.trace(`[review] explorer cannot resolve ${resource.fsPath}: ${error}`); - return []; - } - } - - statFor(resource: URI): IFileStat | undefined { - return this.stats.get(resource.path); - } - - reset(): void { - this.stats.clear(); - } -} - -function compareWhiteboardExplorerStats(one: IFileStat, other: IFileStat): number { - if (one.isDirectory !== other.isDirectory) { - return one.isDirectory ? -1 : 1; - } - return compareFileNamesDefault(basename(one.resource), basename(other.resource)); -} - -class WhiteboardExplorerRenderer extends Disposable implements ITreeRenderer { - readonly templateId = WHITEBOARD_EXPLORER_TEMPLATE_ID; - - private readonly labels: ResourceLabels; - - constructor(@IInstantiationService instantiationService: IInstantiationService) { - super(); - this.labels = this._register(instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER)); - } - - renderTemplate(container: HTMLElement): IWhiteboardExplorerTemplate { - return { label: this.labels.create(container, { supportHighlights: true }) }; - } - - renderElement(node: ITreeNode, _index: number, template: IWhiteboardExplorerTemplate): void { - template.label.setFile(node.element.resource, { - fileKind: node.element.isDirectory ? FileKind.FOLDER : FileKind.FILE, - fileDecorations: { colors: false, badges: false }, - // The tree already shows the path through its indentation, so the - // parent-folder description `setFile` adds by default is noise. - hidePath: true, - }); - } - - disposeTemplate(template: IWhiteboardExplorerTemplate): void { - template.label.dispose(); - } -} - -const whiteboardExplorerAccessibilityProvider: IListAccessibilityProvider = { - getWidgetAriaLabel: () => localize("review.explorer.ariaLabel", "Session files"), - getAriaLabel: (element: IFileStat) => basename(element.resource), -}; - -/** - * The read-only file tree that sits left of a full-screened reviewed file. - * - * Review reviews a pinned snapshot worktree, so this part deliberately is not - * the stock explorer view: it offers no rename, delete, cut/paste, new-file or - * drag-and-drop, and it never writes. It is a `WorkbenchAsyncDataTree` over - * `IFileService`, which keeps virtualization, keyboard navigation, type-ahead - * find, file icons and the `workbench.list.*` settings on stock components. - */ -export class WhiteboardExplorerPart extends Part { - override readonly minimumWidth = 170; - override readonly maximumWidth = 480; - override readonly minimumHeight = 0; - override readonly maximumHeight = Number.POSITIVE_INFINITY; - - /** - * Dragging the sash past half the minimum width collapses the leaf instead of - * pinning it at 170px. The split view calls `setVisible` to do that, so the - * collapse arrives as an ordinary part visibility change and - * `WhiteboardExplorerParts` records it as a user close. - */ - readonly snap = true; - - /** `null` while no review is active, which renders an empty tree. */ - private tree: WorkbenchAsyncDataTree | undefined; - private dataSource: WhiteboardExplorerDataSource | undefined; - private root: URI | undefined; - - /** Serializes reveals and re-roots so two walks cannot interleave expands. */ - private readonly sequencer = new Sequencer(); - - constructor( - @IThemeService themeService: IThemeService, - @IStorageService storageService: IStorageService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @IInstantiationService private readonly instantiationService: IInstantiationService, - @IEditorService private readonly editorService: IEditorService, - @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService, - @IConfigurationService private readonly configurationService: IConfigurationService, - @ILogService private readonly logService: ILogService, - @IWhiteboardApiSourceService private readonly apiSource: IWhiteboardApiSourceService, - @IWhiteboardApiCatalogService private readonly catalog: IWhiteboardApiCatalogService, - @IWhiteboardCanvasEditorTabsService private readonly tabsService: IWhiteboardCanvasEditorTabsService, - ) { - super( - Parts.WHITEBOARD_EXPLORER_PART, - { hasTitle: false, borderWidth: () => 0 }, - themeService, - storageService, - layoutService, - ); - } - - override create(parent: HTMLElement): void { - this.element = parent; - super.create(parent); - } - - protected override createContentArea(parent: HTMLElement): HTMLElement { - // Publish the chrome row height so whiteboard.css sizes the spacer from the same - // constant this part lays the tree out with, rather than a second literal. - parent.style.setProperty("--whiteboard-chrome-height", `${WHITEBOARD_CHROME_HEIGHT}px`); - - // The macOS traffic lights float over the top-left of the window, and the - // explorer is the leftmost surface, so reserve the one chrome row for them - // and let the reserved strip drag the window. - parent.appendChild($(".whiteboard-explorer-chrome-spacer")); - - const workspaceTreeContainer = $(".whiteboard-explorer-tree.review-explorer-workspace-tree"); - parent.appendChild(workspaceTreeContainer); - this.createWorkspaceTree(workspaceTreeContainer); - - return parent; - } - - private createWorkspaceTree(treeContainer: HTMLElement): void { - this._register(createFileIconThemableTreeContainerScope(treeContainer, this.themeService)); - - // `ResourceGlobMatcher` owns the whole `files.exclude` story: per-folder - // expressions, the absolute-to-relative conversion the globs need, the - // configuration listener, and the workspace-folder listener. That last one is - // why nothing here has to rebuild the patterns when the active review - // changes the root. - const excludes = this._register( - this.instantiationService.createInstance( - ResourceGlobMatcher, - (folder?: URI) => this.configurationService.getValue({ resource: folder }).files?.exclude, - (event: IConfigurationChangeEvent) => event.affectsConfiguration(FILES_EXCLUDE_CONFIG), - ), - ); - - const dataSource = new WhiteboardExplorerDataSource(excludes, this.logService, this.apiSource); - this.dataSource = dataSource; - - // A settings change can hide a folder that is currently expanded, so rebuild - // every resolved level rather than trying to patch the tree in place. - this._register(excludes.onExpressionChange(() => this.refreshTree())); - - const renderer = this._register(this.instantiationService.createInstance(WhiteboardExplorerRenderer)); - const tree = this._register( - this.instantiationService.createInstance( - WorkbenchAsyncDataTree, - "WhiteboardExplorer", - treeContainer, - whiteboardExplorerDelegate, - [renderer], - dataSource, - { - identityProvider: { getId: (stat: IFileStat) => `${this.root?.toString()}/${stat.resource.path}` }, - accessibilityProvider: whiteboardExplorerAccessibilityProvider, - keyboardNavigationLabelProvider: { - getKeyboardNavigationLabel: (stat: IFileStat) => basename(stat.resource), - }, - multipleSelectionSupport: false, - // A repository root has too many folders to auto-expand any of them. - collapseByDefault: () => true, - }, - ), - ); - this.tree = tree; - - this._register( - tree.onDidOpen((event) => { - const stat = event.element; - if (!stat || stat.isDirectory) { - return; - } - - // Register the tab against the review it belongs to, so dismissing - // or deleting the review closes it — the same lifecycle the - // changed-files tree's diff tabs get from `whiteboardDiffTabs`. - const sessionId = stat.resource.scheme === WHITEBOARD_API_SOURCE_SCHEME ? stat.resource.authority : undefined; - void Promise.resolve( - this.editorService.openEditor( - { - resource: stat.resource, - options: { - pinned: event.editorOptions.pinned, - preserveFocus: event.editorOptions.preserveFocus, - revealIfVisible: true, - }, - }, - this.editorGroupsService.mainPart.activeGroup, - ), - ).then((pane) => { - if (pane?.input && sessionId) { - this.tabsService.registerWhiteboardEditor(sessionId, pane.input); - } - }); - }), - ); - - this._register(this.editorService.onDidActiveEditorChange(() => this.updateRoot())); - let revision: string | undefined; - this._register(this.catalog.onDidChange(() => { - if (!this.root || sourceTreeSelection(this.root).kind !== "current") return; - const review = this.catalog.reviews.find(review => review.sessionId === this.root!.authority); - const next = JSON.stringify([review?.sessionId, review?.version, review?.pins?.worktreeRevision]); - if (next === revision) return; - revision = next; - this.refreshTree(); - })); - - this.root = undefined; - this.updateRoot(); - } - - /** Re-resolves every expanded level, for when what the tree may show changes. */ - private refreshTree(): void { - if (!this.tree) { - return; - } - - this.sequencer - .queue(async () => { - this.dataSource?.reset(); - await this.tree?.updateChildren(undefined, true); - }) - .catch((error) => this.logService.trace(`[review] explorer cannot refresh: ${error}`)); - } - - private updateRoot(): void { - const input = this.editorService.activeEditor; - const resource = EditorResourceAccessor.getCanonicalUri(input, { supportSideBySide: SideBySideEditor.PRIMARY }); - const folder = - input instanceof WhiteboardCanvasEditorInput && input.target.kind === "api-source" - ? sourceTreeUri(input.target.selection) - : resource?.scheme === WHITEBOARD_API_SOURCE_SCHEME - ? sourceTreeRoot(resource, this.root) - : undefined; - if (folder && this.root && isEqual(folder, this.root)) { - return; - } - - this.root = folder; - - this.sequencer - .queue(async () => { - const tree = this.tree; - if (!tree) { - return; - } - - this.dataSource?.reset(); - await tree.setInput(folder ?? null); - }) - .catch((error) => this.logService.trace(`[review] explorer cannot root at ${folder?.fsPath}: ${error}`)); - } - - /** - * Expands the tree down to `resource` and selects it. - * - * Every step is a no-op when it cannot be met — a resource outside the root, a - * missing ancestor stat — because the caller is an active-editor change, and a - * resource the tree does not hold is not a failure. - */ - revealResource(resource: URI | undefined): void { - const root = this.root; - if (resource && root && resource.scheme === WHITEBOARD_API_SOURCE_SCHEME && sourceTreeRoot(resource, root).toString() === root.toString()) { - // A base-side or commit-scoped editor still belongs to the selected tree. - resource = resource.with({ scheme: root.scheme, query: root.query }); - } - if (!resource || !root || !isEqualOrParent(resource, root)) { - return; - } - - this.sequencer - .queue(async () => { - const tree = this.tree; - const dataSource = this.dataSource; - if (!tree || !dataSource || !this.root || !isEqual(this.root, root)) { - return; - } - - // Walk root -> resource so each expand resolves the level that holds the - // next ancestor. The data source records those stats as it goes, which is - // the only way the next step can find its element. - for (const ancestor of ancestorsBetween(root, resource)) { - const stat = dataSource.statFor(ancestor); - if (!stat) { - return; - } - await tree.expand(stat); - } - - const target = dataSource.statFor(resource); - if (!target) { - return; - } - - tree.setSelection([target]); - tree.setFocus([target]); - tree.reveal(target); - }) - .catch((error) => this.logService.trace(`[review] explorer cannot reveal ${resource.fsPath}: ${error}`)); - } - - setActiveResource(resource: URI | undefined): void { - this.revealResource(resource); - } - - override layout(width: number, height: number, top: number, left: number): void { - super.layout(width, height, top, left); - - const contentHeight = Math.max(0, height - WHITEBOARD_CHROME_HEIGHT); - // Both trees, visible or not: a hidden tree that skipped layout would - // come back with stale zero dimensions and render no rows. - this.tree?.layout(contentHeight, width); - } - - toJSON(): object { - return { type: Parts.WHITEBOARD_EXPLORER_PART }; - } -} - -/** - * The directories between `root` (exclusive) and `resource` (exclusive), nearest - * the root first. Expanding them in this order reveals `resource`. - */ -function ancestorsBetween(root: URI, resource: URI): URI[] { - const ancestors: URI[] = []; - let current = dirname(resource); - while (!isEqual(current, root)) { - ancestors.unshift(current); - const parent = dirname(current); - if (isEqual(parent, current)) { - return []; // walked past the root; nothing to expand - } - current = parent; - } - return ancestors; -} - -export const IWhiteboardExplorerPartsService = createDecorator("whiteboardExplorerPartsService"); - -export interface IWhiteboardExplorerPartsService { - readonly _serviceBrand: undefined; - - /** - * Closes the file tree when it is open, reopens it when it is closed. A no-op - * unless the active editor is one the tree accompanies. - */ - toggle(): void; - - /** - * Clears a sticky close so the tree accompanies the active editor. The - * "Open source tree" CTAs call this after opening the Source tab, so the - * CTA always reveals the tree even after the user dismissed it. - */ - show(): void; -} - -/** Marks the workbench while the tree has a tab to accompany, so the toolbar toggle can fade in. */ -const WHITEBOARD_EXPLORER_AVAILABLE_CLASS = "whiteboard-explorer-available"; - -/** Remembers a close across reloads. Workspace-scoped: it is a per-review preference. */ -const WHITEBOARD_EXPLORER_USER_CLOSED_KEY = "review.explorer.userClosed"; - -/** - * Creates the explorer part and owns its show/hide policy. - * - * The part is a grid leaf, so the grid — not the editor — decides how much room - * the file surface gets. This service is the only thing that toggles it. It is - * eager so the part registers itself before `renderWorkbench` looks it up. - * - * Visibility has two inputs: - * - * - `available` — the active editor shows a file from disk, per - * {@link accompaniesEditor}. Derived, never persisted, and what the toolbar - * toggle fades in on. - * - `userClosed` — the user dismissed the tree. This *is* persisted, because a - * close is a decision rather than derived state: it has to survive the next tab - * switch, the next session, and a reload. See the note in - * `common/whiteboardWorkbenchVisibility.ts`. - * - * The tree shows only when it is available and not closed. - */ -export class WhiteboardExplorerParts extends Disposable implements IWhiteboardExplorerPartsService { - declare readonly _serviceBrand: undefined; - - private readonly part: WhiteboardExplorerPart; - - private available = false; - private userClosed: boolean; - - /** - * Set while this service is driving the grid, so the part-visibility listener - * below does not read our own `setPartHidden` back as a user action. - */ - private applying = false; - - constructor( - @IInstantiationService instantiationService: IInstantiationService, - @IEditorService private readonly editorService: IEditorService, - @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, - @IStorageService private readonly storageService: IStorageService, - ) { - super(); - this.part = this._register(instantiationService.createInstance(WhiteboardExplorerPart)); - this.userClosed = this.storageService.getBoolean(WHITEBOARD_EXPLORER_USER_CLOSED_KEY, StorageScope.WORKSPACE, false); - - this._register(this.editorService.onDidActiveEditorChange(() => this.update())); - - // A sash drag past the snap threshold collapses the leaf through the grid, - // never through `toggle`. Treat any hide that arrives while the tree is - // available as the user closing it, so dragging it shut is as sticky as - // pressing the button. - this._register( - this.layoutService.onDidChangePartVisibility((event) => { - if (this.applying || event.partId !== Parts.WHITEBOARD_EXPLORER_PART || !this.available) { - return; - } - this.setUserClosed(!event.visible); - }), - ); - - // The grid starts the leaf hidden on every launch, so a restored file - // editor needs this one run to bring it back. - this.update(); - } - - toggle(): void { - if (!this.available) { - return; - } - - this.setUserClosed(!this.userClosed); - this.update(); - } - - show(): void { - this.setUserClosed(false); - this.update(); - } - - private setUserClosed(userClosed: boolean): void { - if (this.userClosed === userClosed) { - return; - } - - this.userClosed = userClosed; - this.storageService.store( - WHITEBOARD_EXPLORER_USER_CLOSED_KEY, - userClosed, - StorageScope.WORKSPACE, - StorageTarget.MACHINE, - ); - } - - private update(): void { - const input = this.editorService.activeEditor ?? undefined; - this.available = accompaniesEditor(input); - const visible = this.available && !this.userClosed; - - this.layoutService.mainContainer.classList.toggle(WHITEBOARD_EXPLORER_AVAILABLE_CLASS, this.available); - - this.applying = true; - try { - this.layoutService.setPartHidden(!visible, Parts.WHITEBOARD_EXPLORER_PART); - } finally { - this.applying = false; - } - - if (!visible) { - return; - } - - this.part.setActiveResource( - EditorResourceAccessor.getCanonicalUri(input, { - supportSideBySide: SideBySideEditor.PRIMARY, - }), - ); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/whiteboardLinuxTitlebar.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/whiteboardLinuxTitlebar.ts deleted file mode 100644 index 4f6f581b7..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/whiteboardLinuxTitlebar.ts +++ /dev/null @@ -1,101 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from '../../../nls.js'; -import { Separator, toAction } from '../../../base/common/actions.js'; -import { Disposable } from '../../../base/common/lifecycle.js'; -import { ThemeIcon } from '../../../base/common/themables.js'; -import { Codicon } from '../../../base/common/codicons.js'; -import { $, addDisposableListener, append, getWindowId } from '../../../base/browser/dom.js'; -import { renderIcon } from '../../../base/browser/ui/iconLabel/iconLabels.js'; -import { CodeWindow } from '../../../base/browser/window.js'; -import { ICommandService } from '../../../platform/commands/common/commands.js'; -import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js'; -import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; -import { IConfigurationService } from '../../../platform/configuration/common/configuration.js'; -import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js'; -import { INativeHostService } from '../../../platform/native/common/native.js'; -import { INotificationService } from '../../../platform/notification/common/notification.js'; -import { WindowControlsStyle, getWindowControlsStyle } from '../../../platform/window/common/window.js'; - -/** Linux has no macOS application menu. Keep its commands next to navigation. */ -export class WhiteboardLinuxTitlebar extends Disposable { - constructor( - left: HTMLElement, - controls: HTMLElement | undefined, - targetWindow: CodeWindow, - @ICommandService commandService: ICommandService, - @IContextMenuService contextMenuService: IContextMenuService, - @IKeybindingService keybindingService: IKeybindingService, - @IDialogService dialogService: IDialogService, - @IConfigurationService configurationService: IConfigurationService, - @INativeHostService nativeHostService: INativeHostService, - @INotificationService notificationService: INotificationService, - ) { - super(); - const menu = append(left, $('button.whiteboard-application-menu', { - type: 'button', title: localize('review.menu.title', "Whiteboard menu (F10)"), - 'aria-label': localize('review.menu.label', "Whiteboard menu"), 'aria-haspopup': 'menu', 'aria-expanded': 'false', - })); - append(menu, renderIcon(Codicon.menu)); - let dialogOpen = false; - this._register(dialogService.onWillShowDialog(() => { dialogOpen = true; })); - this._register(dialogService.onDidShowDialog(() => { dialogOpen = false; })); - const command = (id: string, label: string) => toAction({ id, label, run: () => commandService.executeCommand(id) }); - const showMenu = () => { - if (dialogOpen || menu.getAttribute('aria-expanded') === 'true') { return; } - menu.setAttribute('aria-expanded', 'true'); - contextMenuService.showContextMenu({ - getAnchor: () => menu, - autoSelectFirstItem: true, - getActions: () => [ - command('workbench.action.showCommands', localize('review.menu.commands', "Command Palette...")), - command('whiteboard.openSettings', localize('review.menu.settings', "Settings...")), - command('whiteboard.manageExtensions', localize('review.menu.extensions', "Manage Extensions...")), - command('whiteboard.openWelcome', localize('review.menu.welcome', "Getting Started...")), - new Separator(), - command('whiteboard.checkForUpdates', localize('review.menu.updates', "Check for Updates...")), - toAction({ id: 'whiteboard.about', label: localize('review.menu.about', "About Whiteboard"), run: () => dialogService.about() }), - new Separator(), - command('workbench.action.quit', localize('review.menu.quit', "Quit Whiteboard")), - ], - getKeyBinding: action => keybindingService.lookupKeybinding(action.id), - onHide: () => { menu.setAttribute('aria-expanded', 'false'); menu.focus(); }, - }); - }; - this._register(addDisposableListener(menu, 'click', showMenu)); - this._register(addDisposableListener(menu, 'keydown', event => { - if (event.key === 'ArrowDown') { event.preventDefault(); showMenu(); } - })); - this._register(addDisposableListener(targetWindow, 'keydown', event => { - if (event.key === 'F10' && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) { - event.preventDefault(); event.stopPropagation(); showMenu(); - } - }, true)); - if (!controls || getWindowControlsStyle(configurationService) !== WindowControlsStyle.CUSTOM) { return; } - const options = { targetWindowId: getWindowId(targetWindow) }; - const button = (label: string, icon: ThemeIcon, run: () => Promise, close = false) => { - const element = append(controls, $('button.window-icon', { type: 'button', 'aria-label': label, title: label })); - if (close) { element.classList.add('window-close'); } - append(element, renderIcon(icon)); - this._register(addDisposableListener(element, 'click', () => { void run().catch(error => notificationService.error(error)); })); - return element; - }; - button(localize('review.window.minimize', "Minimize"), Codicon.chromeMinimize, () => nativeHostService.minimizeWindow(options)); - let maximized = false; - const maximize = button(localize('review.window.maximize', "Maximize"), Codicon.chromeMaximize, - () => maximized ? nativeHostService.unmaximizeWindow(options) : nativeHostService.maximizeWindow(options)); - const updateMaximized = (value: boolean) => { - maximized = value; - maximize.replaceChildren(renderIcon(value ? Codicon.chromeRestore : Codicon.chromeMaximize)); - const label = value ? localize('review.window.restore', "Restore") : localize('review.window.maximize', "Maximize"); - maximize.title = label; maximize.setAttribute('aria-label', label); - }; - this._register(nativeHostService.onDidMaximizeWindow(id => { if (id === options.targetWindowId) { updateMaximized(true); } })); - this._register(nativeHostService.onDidUnmaximizeWindow(id => { if (id === options.targetWindowId) { updateMaximized(false); } })); - void nativeHostService.isMaximized(options).then(updateMaximized, error => notificationService.error(error)); - button(localize('review.window.close', "Close"), Codicon.chromeClose, () => nativeHostService.closeWindow(options), true); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/whiteboardTitlebarPart.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/whiteboardTitlebarPart.ts deleted file mode 100644 index d3ba80ccb..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/parts/whiteboardTitlebarPart.ts +++ /dev/null @@ -1,376 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import '../../../workbench/browser/parts/titlebar/media/titlebarpart.css'; -import '../media/whiteboard.css'; -import { localize } from '../../../nls.js'; -import { MultiWindowParts, Part } from '../../../workbench/browser/part.js'; -import { ITitleService } from '../../../workbench/services/title/browser/titleService.js'; -import { getWCOTitlebarAreaRect, getZoomFactor, isFullscreen, isWCOEnabled, onDidChangeFullscreen } from '../../../base/browser/browser.js'; -import { TitlebarStyle, WindowControlsStyle, getTitleBarStyle, getWindowControlsStyle, hasCustomTitlebar, hasNativeTitlebar } from '../../../platform/window/common/window.js'; -import { WHITEBOARD_CHROME_HEIGHT } from '../../common/whiteboardChrome.js'; -import { IConfigurationService } from '../../../platform/configuration/common/configuration.js'; -import { DisposableStore, toDisposable } from '../../../base/common/lifecycle.js'; -import { IThemeService } from '../../../platform/theme/common/themeService.js'; -import { EDITOR_GROUP_HEADER_TABS_BACKGROUND, TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_INACTIVE_FOREGROUND } from '../../../workbench/common/theme.js'; -import { isLinux, isMacintosh, isNative, isWeb, platformLocale } from '../../../base/common/platform.js'; -import { $, addDisposableListener, append, getWindow, getWindowId, prepend } from '../../../base/browser/dom.js'; -import { renderIcon } from '../../../base/browser/ui/iconLabel/iconLabels.js'; -import { Codicon } from '../../../base/common/codicons.js'; -import { KeyCode } from '../../../base/common/keyCodes.js'; -import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js'; -import { ICommandService } from '../../../platform/commands/common/commands.js'; -import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; -import { Emitter, Event } from '../../../base/common/event.js'; -import { IStorageService } from '../../../platform/storage/common/storage.js'; -import { IWorkbenchLayoutService, Parts } from '../../../workbench/services/layout/browser/layoutService.js'; -import { IHostService } from '../../../workbench/services/host/browser/host.js'; -import { IEditorGroupsContainer } from '../../../workbench/services/editor/common/editorGroupsService.js'; -import { CodeWindow, mainWindow } from '../../../base/browser/window.js'; -import { safeIntl } from '../../../base/common/date.js'; -import { IAuxiliaryTitlebarPart, ITitleProperties, ITitleVariable, ITitlebarPart } from '../../../workbench/browser/parts/titlebar/titlebarPart.js'; -import { WindowTitle } from '../../../workbench/browser/parts/titlebar/windowTitle.js'; -import { CommandCenterControl } from '../../../workbench/browser/parts/titlebar/commandCenterControl.js'; -import { INativeHostService } from '../../../platform/native/common/native.js'; -import { getDefaultHoverDelegate } from '../../../base/browser/ui/hover/hoverDelegateFactory.js'; -import { WhiteboardLinuxTitlebar } from './whiteboardLinuxTitlebar.js'; - -/** - * The deliberately small Review titlebar. It owns the drag region and the macOS - * traffic-light inset while reusing VS Code's native navigation control. The - * navigation control sits at the left, directly after the traffic lights, where - * macOS applications put their back and forward arrows. The bar carries no - * product label: the branding lives in the macOS application menu. - */ -export class WhiteboardTitlebarPart extends Part implements ITitlebarPart { - - readonly minimumWidth = 0; - readonly maximumWidth = Number.POSITIVE_INFINITY; - - get minimumHeight(): number { - const wcoHeight = isWeb && isWCOEnabled() - ? getWCOTitlebarAreaRect(getWindow(this.element))?.height ?? 0 - : 0; - return Math.max(WHITEBOARD_CHROME_HEIGHT, wcoHeight) / (this.preventZoom ? getZoomFactor(getWindow(this.element)) : 1); - } - - get maximumHeight(): number { return this.minimumHeight; } - - private readonly _onMenubarVisibilityChange = this._register(new Emitter()); - readonly onMenubarVisibilityChange = this._onMenubarVisibilityChange.event; - - private readonly _onWillDispose = this._register(new Emitter()); - readonly onWillDispose = this._onWillDispose.event; - - protected rootContainer!: HTMLElement; - protected windowControlsContainer: HTMLElement | undefined; - private leftContent!: HTMLElement; - private rightContent!: HTMLElement; - - get leftContainer(): HTMLElement { return this.leftContent; } - get rightContainer(): HTMLElement { return this.rightContent; } - get rightWindowControlsContainer(): HTMLElement | undefined { return this.windowControlsContainer; } - - private readonly titleBarStyle: TitlebarStyle; - private isInactive = false; - - constructor( - id: string, - targetWindow: CodeWindow, - @IConfigurationService protected readonly configurationService: IConfigurationService, - @IThemeService themeService: IThemeService, - @IStorageService storageService: IStorageService, - @IWorkbenchLayoutService protected override readonly layoutService: IWorkbenchLayoutService, - @IHostService hostService: IHostService, - @IInstantiationService private readonly instantiationService: IInstantiationService, - @ICommandService private readonly commandService: ICommandService, - ) { - super(id, { hasTitle: false }, themeService, storageService, layoutService); - this.titleBarStyle = getTitleBarStyle(configurationService); - - const targetWindowId = getWindowId(targetWindow); - this._register(hostService.onDidChangeFocus(focused => this.setInactive(!focused))); - this._register(hostService.onDidChangeActiveWindow(windowId => this.setInactive(windowId !== targetWindowId))); - } - - private setInactive(inactive: boolean): void { - this.isInactive = inactive; - this.updateStyles(); - } - - updateProperties(_properties: ITitleProperties): void { } - registerVariables(_variables: ITitleVariable[]): void { } - updateOptions(_options: { compact: boolean }): void { } - - protected get paintsBackground(): boolean { return true; } - - protected override createContentArea(parent: HTMLElement): HTMLElement { - this.element = parent; - this.rootContainer = append(parent, $('.titlebar-container.whiteboard-titlebar-container')); - prepend(this.rootContainer, $('div.titlebar-drag-region')); - - this.leftContent = append(this.rootContainer, $('.titlebar-left')); - this.rightContent = append(this.rootContainer, $('.titlebar-right')); - - // The window controls come first so the traffic-light inset stays to the - // left of the navigation control that the block below appends. - if (!hasNativeTitlebar(this.configurationService, this.titleBarStyle)) { - let controlsLocation: 'left' | 'right' = isMacintosh ? 'left' : 'right'; - if (isMacintosh && isNative) { - const localeInfo = safeIntl.Locale(platformLocale).value; - if ((localeInfo as { textInfo?: { direction?: string } }).textInfo?.direction === 'rtl') { - controlsLocation = 'right'; - } - } - - if (isMacintosh && isNative && controlsLocation === 'left') { - const spacer = append(this.leftContent, $('div.window-controls-container.whiteboard-traffic-light-inset')); - const updateSpacer = () => { - const fullscreen = isFullscreen(mainWindow); - spacer.style.display = fullscreen ? 'none' : ''; - spacer.style.width = fullscreen ? '0' : '70px'; - }; - updateSpacer(); - this._register(onDidChangeFullscreen(windowId => { - if (windowId === getWindowId(mainWindow)) { - updateSpacer(); - } - })); - } else if (getWindowControlsStyle(this.configurationService) !== WindowControlsStyle.HIDDEN) { - const controlsParent = controlsLocation === 'left' ? this.leftContent : this.rightContent; - this.windowControlsContainer = append(controlsParent, $('div.window-controls-container')); - if (isWeb) { - append(controlsLocation === 'left' ? this.rightContent : this.leftContent, $('div.window-controls-container')); - } - if (isWCOEnabled()) { - this.windowControlsContainer.classList.add('wco-enabled'); - } - } - } - - if (isLinux && isNative) { - this._register(this.instantiationService.createInstance(WhiteboardLinuxTitlebar, this.leftContent, this.windowControlsContainer, getWindow(parent))); - } - const navigationContainer = append(this.leftContent, $('div.whiteboard-titlebar-navigation')); - const windowTitle = this._register(this.instantiationService.createInstance(WindowTitle, getWindow(parent))); - const navigationControl = this._register(this.instantiationService.createInstance( - CommandCenterControl, - windowTitle, - getDefaultHoverDelegate('mouse'), - )); - append(navigationContainer, navigationControl.element); - this.createFileTreeToggle(); - - this.updateStyles(); - return this.element; - } - - /** - * The file-tree toggle, right of the navigation arrows. - * - * The button holds a fixed 22px slot at all times, even with no tree to - * toggle. That keeps the left cluster a constant width, and the cluster width - * is what `--whiteboard-chrome-left-width` reports to the editor tab strip — so - * fading the button in never moves a tab. Both icons render here and CSS picks - * one, which keeps this part free of any explorer state subscription. - */ - private createFileTreeToggle(): void { - const toggle = append(this.leftContent, $('div.whiteboard-titlebar-file-tree-toggle', { - role: 'button', - tabindex: '0', - title: localize('whiteboard.toggleFileTree.tooltip', "Toggle File Tree"), - 'aria-label': localize('whiteboard.toggleFileTree.tooltip', "Toggle File Tree"), - })); - - append(toggle, renderIcon(Codicon.layoutSidebarLeft)).classList.add('whiteboard-file-tree-icon-open'); - append(toggle, renderIcon(Codicon.layoutSidebarLeftOff)).classList.add('whiteboard-file-tree-icon-closed'); - - const run = () => void this.commandService.executeCommand('whiteboard.toggleFileTree'); - this._register(addDisposableListener(toggle, 'click', run)); - this._register(addDisposableListener(toggle, 'keydown', event => { - const keyboardEvent = new StandardKeyboardEvent(event); - if (keyboardEvent.equals(KeyCode.Enter) || keyboardEvent.equals(KeyCode.Space)) { - keyboardEvent.preventDefault(); - keyboardEvent.stopPropagation(); - run(); - } - })); - } - - override updateStyles(): void { - super.updateStyles(); - if (!this.element) { - return; - } - - this.element.classList.toggle('inactive', this.isInactive); - this.element.style.backgroundColor = this.paintsBackground - ? this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND) || '' - : ''; - this.element.style.color = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_FOREGROUND : TITLE_BAR_ACTIVE_FOREGROUND) || ''; - } - - get hasZoomableElements(): boolean { return false; } - get preventZoom(): boolean { return true; } - - override layout(width: number, height: number): void { - if (hasCustomTitlebar(this.configurationService, this.titleBarStyle)) { - const zoomFactor = getZoomFactor(getWindow(this.element)); - this.element.style.setProperty('--zoom-factor', zoomFactor.toString()); - this.rootContainer.classList.toggle('counter-zoom', this.preventZoom); - } - super.layoutContents(width, height); - } - - focus(): void { } - toJSON(): object { return { type: Parts.TITLEBAR_PART }; } - - override dispose(): void { - this._onWillDispose.fire(); - super.dispose(); - } -} - -export class MainWhiteboardTitlebarPart extends WhiteboardTitlebarPart { - protected override get paintsBackground(): boolean { return false; } - - override updateStyles(): void { - super.updateStyles(); - if (isLinux && this.element && this.nativeHostService) { - void this.nativeHostService.updateWindowControls({ - targetWindowId: getWindowId(mainWindow), - backgroundColor: this.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND) ?? undefined, - foregroundColor: this.element.style.color, - }); - } - } - - - override layout(width: number, height: number): void { - super.layout(width, height); - void this.nativeHostService.updateWindowControls({ - targetWindowId: getWindowId(mainWindow), - height: Math.round(WHITEBOARD_CHROME_HEIGHT * getZoomFactor(mainWindow)) - }); - } - - private readonly _onDidChangeChromeInsets = this._register(new Emitter()); - readonly onDidChangeChromeInsets = this._onDidChangeChromeInsets.event; - - /** Left and right window-chrome cluster widths, in CSS pixels. */ - readonly chromeInsets = { left: 0, right: 0 }; - - protected override createContentArea(parent: HTMLElement): HTMLElement { - const element = super.createContentArea(parent); - // Written on this part, never the workbench root; see - // `publishWhiteboardChromeInset` for why. - const updateChromeWidths = () => { - const left = this.leftContainer.getBoundingClientRect().width; - const right = this.rightContainer.getBoundingClientRect().width; - if (left === this.chromeInsets.left && right === this.chromeInsets.right) { - return; - } - this.chromeInsets.left = left; - this.chromeInsets.right = right; - this.element.style.setProperty('--whiteboard-chrome-left-width', `${left}px`); - this.element.style.setProperty('--whiteboard-chrome-right-width', `${right}px`); - this._onDidChangeChromeInsets.fire(); - }; - const observer = new ResizeObserver(updateChromeWidths); - observer.observe(this.leftContainer); - observer.observe(this.rightContainer); - this._register(toDisposable(() => observer.disconnect())); - updateChromeWidths(); - - return element; - } - - constructor( - @IConfigurationService configurationService: IConfigurationService, - @IThemeService themeService: IThemeService, - @IStorageService storageService: IStorageService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @IHostService hostService: IHostService, - @IInstantiationService instantiationService: IInstantiationService, - @ICommandService commandService: ICommandService, - @INativeHostService private readonly nativeHostService: INativeHostService, - ) { - super(Parts.TITLEBAR_PART, mainWindow, configurationService, themeService, storageService, layoutService, hostService, instantiationService, commandService); - } -} - -export class AuxiliaryWhiteboardTitlebarPart extends WhiteboardTitlebarPart implements IAuxiliaryTitlebarPart { - private static counter = 1; - get height(): number { return this.minimumHeight; } - - constructor( - readonly container: HTMLElement, - private readonly mainTitlebar: WhiteboardTitlebarPart, - @IConfigurationService configurationService: IConfigurationService, - @IThemeService themeService: IThemeService, - @IStorageService storageService: IStorageService, - @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, - @IHostService hostService: IHostService, - @IInstantiationService instantiationService: IInstantiationService, - @ICommandService commandService: ICommandService, - ) { - super(`workbench.parts.auxiliaryTitle.${AuxiliaryWhiteboardTitlebarPart.counter++}`, getWindow(container), configurationService, themeService, storageService, layoutService, hostService, instantiationService, commandService); - } - - override get preventZoom(): boolean { - return getZoomFactor(getWindow(this.element)) < 1 || !this.mainTitlebar.hasZoomableElements; - } -} - -export class WhiteboardTitleService extends MultiWindowParts implements ITitleService { - declare _serviceBrand: undefined; - readonly mainPart: WhiteboardTitlebarPart; - readonly onMenubarVisibilityChange: Event; - - constructor( - @IInstantiationService protected readonly instantiationService: IInstantiationService, - @IStorageService storageService: IStorageService, - @IThemeService themeService: IThemeService, - ) { - super('workbench.whiteboardTitleService', themeService, storageService); - this.mainPart = this._register(this.instantiationService.createInstance(MainWhiteboardTitlebarPart)); - this.onMenubarVisibilityChange = this.mainPart.onMenubarVisibilityChange; - this._register(this.registerPart(this.mainPart)); - } - - createAuxiliaryTitlebarPart(container: HTMLElement, _editorGroupsContainer: IEditorGroupsContainer, instantiationService: IInstantiationService): IAuxiliaryTitlebarPart { - const partContainer = $('.part.titlebar', { role: 'none' }); - partContainer.style.position = 'relative'; - container.insertBefore(partContainer, container.firstChild); - - const disposables = new DisposableStore(); - const part = instantiationService.createInstance(AuxiliaryWhiteboardTitlebarPart, partContainer, this.mainPart); - disposables.add(this.registerPart(part)); - disposables.add(Event.runAndSubscribe(part.onDidChange, () => partContainer.style.height = `${part.height}px`)); - part.create(partContainer); - Event.once(part.onWillDispose)(() => disposables.dispose()); - return part; - } - - updateProperties(properties: ITitleProperties): void { - for (const part of this.parts) { - part.updateProperties(properties); - } - } - - registerVariables(variables: ITitleVariable[]): void { - for (const part of this.parts) { - part.registerVariables(variables); - } - } - - private _windowTitle: WindowTitle | undefined; - get windowTitle(): WindowTitle { - if (!this._windowTitle) { - this._windowTitle = this._register(this.instantiationService.createInstance(WindowTitle, mainWindow)); - } - return this._windowTitle; - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardChangedFilesTree.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardChangedFilesTree.test.ts deleted file mode 100644 index a41c40c50..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardChangedFilesTree.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import { createRequire, registerHooks } from 'node:module'; -import test from 'node:test'; - -import type { WhiteboardDiffFileWire, WhiteboardDiffProgressFile, StructuralLineCounts } from '../common/whiteboardProtocol.js'; - -// jsdom ships no types here; the DOM globals below are all this test reads from it. -const { JSDOM } = createRequire(import.meta.url)('jsdom'); -const dom = new JSDOM(''); -for (const key of ['window', 'document', 'HTMLElement', 'HTMLCanvasElement', 'Node', 'MutationObserver', 'Element', 'navigator', 'customElements', 'UIEvent', 'MouseEvent', 'KeyboardEvent'] as const) { - Object.defineProperty(globalThis, key, { configurable: true, value: dom.window[key] }); -} -dom.window.matchMedia = () => ({ matches: false, addEventListener() { }, removeEventListener() { } }) as never; -registerHooks({ load(url, context, next) { - return url.endsWith('.css') ? { format: 'module', source: '', shortCircuit: true } : next(url, context); -} }); -const { ChangedFilesTreeRenderer } = await import('./whiteboardChangedFilesTree.js'); - -const file = (path: string): WhiteboardDiffFileWire => ({ path, status: 'modified', additions: 3, deletions: 1 } as WhiteboardDiffFileWire); -const progress = (path: string, state: WhiteboardDiffProgressFile['state'], remaining: number): WhiteboardDiffProgressFile => ({ - path, state, remaining: { additions: remaining, deletions: 0 }, total: { additions: 3, deletions: 1 }, viewedRanges: [], changedRanges: [], -}); - -function row(state: WhiteboardDiffProgressFile['state'] | undefined, counts?: StructuralLineCounts) { - const path = 'src/a.ts'; - const renderer = new ChangedFilesTreeRenderer( - new Map(counts ? [[path, counts]] : []), - new Map(state ? [[path, progress(path, state, state === 'unread' ? 3 : 0)]] : []), - new Map(), - ); - const template = renderer.renderTemplate(document.createElement('div')); - renderer.renderElement({ element: { kind: 'file', name: 'a.ts', file: file(path) } } as never, 0, template); - return { row: template.row, counts: template.counts.textContent }; -} - -test('a folded file reads as done: greyed like a viewed one, "Folded" in place of its counts', () => { - const folded = row('folded'); - assert.equal(folded.counts, 'Folded'); - assert.ok(folded.row.classList.contains('whiteboard-file-folded')); - assert.ok(!folded.row.classList.contains('whiteboard-file-viewed')); -}); - -test('a viewed file says "Viewed" in place of its counts', () => { - const viewed = row('viewed'); - assert.equal(viewed.counts, 'Viewed'); - assert.ok(viewed.row.classList.contains('whiteboard-file-viewed')); -}); - -test('a file with changes left to read shows its remaining counts, not greyed', () => { - const unread = row('unread'); - assert.equal(unread.counts, '+3−0'); - assert.ok(!unread.row.classList.contains('whiteboard-file-folded')); - assert.ok(!unread.row.classList.contains('whiteboard-file-viewed')); -}); - -test('without progress, the structural counts show and nothing reads as folded', () => { - const pending = row(undefined, { added: 4, removed: 1 }); - assert.equal(pending.counts, '+4−1'); - assert.ok(!pending.row.classList.contains('whiteboard-file-folded')); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardChangedFilesTree.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardChangedFilesTree.ts deleted file mode 100644 index dfb9ad860..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardChangedFilesTree.ts +++ /dev/null @@ -1,358 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { buildTree, type ChangedFileElement, type ChangedTreeElement } from "../common/whiteboardChangedFilesModel.js"; - -import { $, append } from "../../base/browser/dom.js"; -import type { IListVirtualDelegate } from "../../base/browser/ui/list/list.js"; -import { RenderIndentGuides } from "../../base/browser/ui/tree/abstractTree.js"; -import type { - ICompressedTreeElement, - ICompressedTreeNode, -} from "../../base/browser/ui/tree/compressedObjectTreeModel.js"; -import type { ICompressibleTreeRenderer } from "../../base/browser/ui/tree/objectTree.js"; -import { - ObjectTreeElementCollapseState, - type ITreeNode, -} from "../../base/browser/ui/tree/tree.js"; -import { Codicon } from "../../base/common/codicons.js"; -import { Emitter, type Event } from "../../base/common/event.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import { ThemeIcon } from "../../base/common/themables.js"; -import { localize } from "../../nls.js"; -import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; -import { WorkbenchCompressibleObjectTree } from "../../platform/list/browser/listService.js"; -import { registerColor } from "../../platform/theme/common/colorRegistry.js"; -import type { WhiteboardDiffFileWire, WhiteboardDiffProgressFile, StructuralLineCounts } from "../common/whiteboardProtocol.js"; - -registerColor( - "gitDecoration.addedResourceForeground", - { - light: "#587c0c", - dark: "#81b88b", - hcDark: "#a1e3ad", - hcLight: "#374e06", - }, - localize("review.gitDecoration.added", "Color for added file resources."), -); -registerColor( - "gitDecoration.modifiedResourceForeground", - { - light: "#895503", - dark: "#E2C08D", - hcDark: "#E2C08D", - hcLight: "#895503", - }, - localize("review.gitDecoration.modified", "Color for modified file resources."), -); -registerColor( - "gitDecoration.deletedResourceForeground", - { - light: "#ad0707", - dark: "#c74e39", - hcDark: "#c74e39", - hcLight: "#ad0707", - }, - localize("review.gitDecoration.deleted", "Color for deleted file resources."), -); -registerColor( - "gitDecoration.renamedResourceForeground", - { - light: "#007100", - dark: "#73C991", - hcDark: "#73C991", - hcLight: "#007100", - }, - localize("review.gitDecoration.renamed", "Color for renamed file resources."), -); - -const CHANGED_FILE_ROW_HEIGHT = 22; - -interface ChangedFilesTreeTemplate { - readonly row: HTMLElement; - readonly icon: HTMLElement; - readonly label: HTMLElement; - readonly counts: HTMLElement; -} - -class ChangedFilesTreeDelegate - implements IListVirtualDelegate -{ - getHeight(): number { - return CHANGED_FILE_ROW_HEIGHT; - } - - getTemplateId(): string { - return ChangedFilesTreeRenderer.TEMPLATE_ID; - } -} - -export class ChangedFilesTreeRenderer - implements - ICompressibleTreeRenderer< - ChangedTreeElement, - void, - ChangedFilesTreeTemplate - > -{ - static readonly TEMPLATE_ID = "review.changedFiles.entry"; - readonly templateId = ChangedFilesTreeRenderer.TEMPLATE_ID; - - constructor(private readonly counts: Map, private readonly progress: Map, private readonly states: Map) { } - - renderTemplate(container: HTMLElement): ChangedFilesTreeTemplate { - const row = append(container, $(".whiteboard-changed-files-row")); - const icon = append(row, $("span.whiteboard-changed-files-icon")); - icon.setAttribute("aria-hidden", "true"); - const label = append(row, $("span.whiteboard-changed-files-label")); - const counts = append(row, $("span.whiteboard-tree-counts")); - return { row, icon, label, counts }; - } - - renderElement( - node: ITreeNode, - _index: number, - template: ChangedFilesTreeTemplate, - ): void { - this.renderElements([node.element], template); - } - - renderCompressedElements( - node: ITreeNode>, - _index: number, - template: ChangedFilesTreeTemplate, - ): void { - this.renderElements(node.element.elements, template); - } - - disposeTemplate(_template: ChangedFilesTreeTemplate): void {} - - private renderElements( - elements: readonly ChangedTreeElement[], - template: ChangedFilesTreeTemplate, - ): void { - const element = elements[elements.length - 1]; - const isFile = element.kind === "file"; - - template.row.classList.toggle("whiteboard-changed-files-folder", !isFile); - const done = isFile ? this.progress.get(element.file.path)?.state : undefined; - // Folded files read as done, like viewed ones: greyed, with the reason in place of counts. - template.row.classList.toggle("whiteboard-file-viewed", done === "viewed"); - template.row.classList.toggle("whiteboard-file-folded", done === "folded"); - template.icon.hidden = !isFile; - template.icon.className = isFile - ? `review-changed-files-icon review-changed-files-icon-${element.file.status} ${ThemeIcon.asClassName(fileStatusIcon(element.file.status))}` - : "whiteboard-changed-files-icon"; - template.counts.hidden = !isFile; - template.counts.replaceChildren(); - template.counts.removeAttribute("title"); - if (isFile) { - const progress = this.progress.get(element.file.path); - const compact = (n: number) => new Intl.NumberFormat('en', { notation: 'compact', maximumFractionDigits: 1 }).format(n).toLowerCase(); - const additions = progress?.remaining.additions ?? this.counts.get(element.file.path)?.added; - const deletions = progress?.remaining.deletions ?? this.counts.get(element.file.path)?.removed; - if (element.file.status === 'unchanged') template.counts.textContent = 'Unchanged'; - else if (progress?.state === 'viewed') template.counts.textContent = 'Viewed'; - else if (progress?.state === 'folded') template.counts.textContent = 'Folded'; - else if (additions !== undefined && deletions !== undefined) { - const added = append(template.counts, $('span.whiteboard-tree-added')); added.textContent = `+${compact(additions)}`; - const removed = append(template.counts, $('span.whiteboard-tree-removed')); removed.textContent = `−${compact(deletions)}`; - } - template.counts.title = additions === undefined ? "Waiting for structural coverage" : element.file.status === "unchanged" ? "Referenced context; no changed lines" : progress?.state === "folded" ? `Folded by default; counted as done · Total +${progress.total.additions} −${progress.total.deletions}` : `Remaining +${additions} −${deletions} · Total +${progress?.total.additions ?? this.counts.get(element.file.path)?.added} −${progress?.total.deletions ?? this.counts.get(element.file.path)?.removed}`; - } - const state = isFile ? this.states.get(element.file.path) : undefined; - if (state) template.icon.className = `whiteboard-changed-files-icon codicon codicon-${state.status === "loading" ? "loading codicon-modifier-spin" : "error"}`; - template.row.title = state?.message ?? (state?.status === "loading" ? "Loading diff…" : ""); - template.row.setAttribute("aria-busy", String(state?.status === "loading")); - template.label.textContent = isFile - ? element.name - : elements.map((item) => item.name).join("/"); - } -} - -/** A Workbench-compressed tree over one Review's changed files. */ -export class WhiteboardChangedFilesTree extends Disposable { - private readonly _onDidOpenFile = this._register( - new Emitter(), - ); - readonly onDidOpenFile: Event = - this._onDidOpenFile.event; - - private readonly tree: WorkbenchCompressibleObjectTree< - ChangedTreeElement, - void - >; - private readonly fileElements = new Map(); - private files: readonly WhiteboardDiffFileWire[] = []; - private readonly states = new Map(); - private activePath: string | undefined; - private readonly counts = new Map(); - setCounts(path: string, counts: StructuralLineCounts): void { - const previous = this.counts.get(path); - this.counts.set(path, counts); - if (previous?.added !== counts.added || previous?.removed !== counts.removed) this.refreshFile(path); - } - private readonly progress = new Map(); - setProgressFiles(files: readonly WhiteboardDiffProgressFile[]): void { - const previous = new Map(this.progress); - this.progress.clear(); - for (const file of files) this.progress.set(file.path, file); - for (const path of new Set([...previous.keys(), ...this.progress.keys()])) { - const before = previous.get(path), after = this.progress.get(path); - if (before?.state !== after?.state || - before?.remaining.additions !== after?.remaining.additions || - before?.remaining.deletions !== after?.remaining.deletions || - before?.total.additions !== after?.total.additions || - before?.total.deletions !== after?.total.deletions) this.refreshFile(path); - } - } - - private refreshFile(path: string): void { - // The parameterless rerender only remeasures dynamic heights; these rows - // have fixed heights. Target the model node to refresh its rendered data. - const element = this.fileElements.get(path); - if (element) this.tree.rerender(element); - } - private syncingActiveFile = false; - - constructor( - container: HTMLElement, - @IInstantiationService instantiationService: IInstantiationService, - ) { - super(); - container.classList.add("whiteboard-changed-files"); - const treeContainer = append( - container, - $(".whiteboard-changed-files-tree"), - ); - const renderer = new ChangedFilesTreeRenderer(this.counts, this.progress, this.states); - this.tree = this._register( - instantiationService.createInstance( - WorkbenchCompressibleObjectTree, - "WhiteboardChangedFiles", - treeContainer, - new ChangedFilesTreeDelegate(), - [renderer], - { - accessibilityProvider: { - getAriaLabel: (element) => - element.kind === "file" ? element.file.path : element.path, - getWidgetAriaLabel: () => - localize("review.changedFiles.ariaLabel", "Changed files"), - }, - alwaysConsumeMouseWheel: false, - horizontalScrolling: false, - identityProvider: { - getId: (element) => - element.kind === "file" - ? element.file.path - : `dir:${element.path}`, - }, - indent: 12, - keyboardNavigationLabelProvider: { - getKeyboardNavigationLabel: (element) => element.name, - getCompressedNodeKeyboardNavigationLabel: (elements) => - elements.map((element) => element.name).join("/"), - }, - compressionEnabled: true, - multipleSelectionSupport: false, - openOnSingleClick: true, - renderIndentGuides: RenderIndentGuides.None, - }, - ), - ); - this._register( - this.tree.onDidOpen((event) => { - if (this.syncingActiveFile || event.element?.kind !== "file") return; - this._onDidOpenFile.fire(event.element.file); - }), - ); - this.refresh(); - } - - setFiles(files: readonly WhiteboardDiffFileWire[]): void { - const selectedElement = this.tree - .getSelection() - .find((element) => element?.kind === "file"); - const selectedPath = - selectedElement?.kind === "file" ? selectedElement.file.path : undefined; - this.files = files; - this.refresh(selectedPath); - } - - setFileState(path: string, status: "loading" | "error" | undefined, message?: string): void { - if (status) this.states.set(path, { status, message }); - else this.states.delete(path); - const element = this.fileElements.get(path); - if (element) this.tree.rerender(element); - } - - setActiveFile(path: string | undefined, reveal = true): void { - if (!reveal && this.activePath === path) return; - this.activePath = path; - this.syncSelection(path, reveal); - } - - layout(height: number, width: number): void { - this.tree.layout(Math.max(0, height), width); - } - - private refresh(selectedPath?: string): void { - const roots = buildTree(this.files); - this.fileElements.clear(); - collectFileElements(roots, this.fileElements); - this.tree.setChildren(null, toTreeElements(roots)); - this.syncSelection(this.activePath ?? selectedPath); - } - - private syncSelection(path: string | undefined, reveal = true): void { - const element = path ? this.fileElements.get(path) : undefined; - this.syncingActiveFile = true; - try { - this.tree.setSelection(element ? [element] : []); - this.tree.setFocus(element ? [element] : []); - if (element && reveal) this.tree.reveal(element); - } finally { - this.syncingActiveFile = false; - } - } -} - -function fileStatusIcon(status: WhiteboardDiffFileWire["status"]): ThemeIcon { - if (status === "unchanged") return Codicon.file; - if (status === "added") return Codicon.diffAdded; - if (status === "deleted") return Codicon.diffRemoved; - if (status === "renamed") return Codicon.diffRenamed; - return Codicon.diffModified; -} - -function toTreeElements( - elements: readonly ChangedTreeElement[], -): ICompressedTreeElement[] { - return elements.map((element) => - element.kind === "file" - ? { element, incompressible: true } - : { - element, - collapsible: true, - collapsed: ObjectTreeElementCollapseState.PreserveOrExpanded, - children: toTreeElements(element.children), - }, - ); -} - -function collectFileElements( - elements: readonly ChangedTreeElement[], - target: Map, -): void { - for (const element of elements) { - if (element.kind === "file") { - target.set(element.file.path, element); - } else { - collectFileElements(element.children, target); - } - } -} - diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardCommunity.contribution.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardCommunity.contribution.test.ts deleted file mode 100644 index f08bd6117..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardCommunity.contribution.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import type { IConfirmation, IConfirmationResult } from '../../platform/dialogs/common/dialogs.js'; -import { WHITEBOARD_DISCORD_URL } from '../common/whiteboardProtocol.js'; -import { setFirstRunReloadPending } from '../common/whiteboardFirstRunReload.js'; -import { DISMISSED_KEY, WhiteboardCommunityContribution } from './whiteboardCommunity.contribution.js'; - -const settle = () => new Promise(resolve => setImmediate(resolve)); - -function setup(answer: Promise, reviews: Array<{ kind?: "scratchpad" }> = [{}, {}], dismissed = false) { - const catalog = { reviews, initialize: async () => { } }; - const asked: IConfirmation[] = []; - const stored: Array<{ key: string; value: unknown }> = []; - const opened: unknown[] = []; - const invite = () => new WhiteboardCommunityContribution( - { confirm: (confirmation: IConfirmation) => { asked.push(confirmation); return answer; } } as never, - { getBoolean: () => dismissed, store: (key: string, value: unknown) => { stored.push({ key, value }); dismissed = Boolean(value); } } as never, - { open: async (target: unknown) => { opened.push(target); return true; } } as never, - catalog as never, - ); - return { asked, stored, opened, invite, catalog }; -} - -test('skips the invitation when the first-run seeding reload is pending', async () => { - setFirstRunReloadPending(true); - const { asked, stored, invite } = setup(new Promise(() => { })); - invite(); - await settle(); - assert.deepEqual(asked, [], 'the reload would discard the invitation'); - assert.deepEqual(stored, []); -}); - -for (const confirmed of [false, true]) { - test(`permanently dismisses the invitation after ${confirmed ? 'joining' : 'declining'}`, async () => { - setFirstRunReloadPending(false); - const { asked, stored, opened, invite } = setup(Promise.resolve({ confirmed })); - invite(); - await settle(); - assert.equal(asked.length, 1); - assert.deepEqual(stored, [{ key: DISMISSED_KEY, value: true }]); - assert.deepEqual(opened, confirmed ? [WHITEBOARD_DISCORD_URL] : []); - invite(); - await settle(); - assert.equal(asked.length, 1, 'subsequent launches must not ask again'); - }); -} - -for (const reviews of [[], [{}], [{}, { kind: "scratchpad" as const }]]) { - test(`skips the invitation with fewer than two reviews: ${JSON.stringify(reviews)}`, async () => { - setFirstRunReloadPending(false); - const { asked, invite } = setup(Promise.resolve({ confirmed: false }), reviews); - invite(); - await settle(); - assert.equal(asked.length, 0); - }); -} - -test('waits until the next launch after the second review is created', async () => { - setFirstRunReloadPending(false); - const { asked, invite, catalog } = setup(Promise.resolve({ confirmed: false }), [{}]); - invite(); - await settle(); - catalog.reviews.push({}); - await settle(); - assert.equal(asked.length, 0); - invite(); - await settle(); - assert.equal(asked.length, 1); -}); - -test('waits for the catalog to load before checking eligibility', async () => { - setFirstRunReloadPending(false); - const { asked, invite, catalog } = setup(Promise.resolve({ confirmed: false }), []); - let loaded!: () => void; - catalog.initialize = () => new Promise(resolve => { loaded = resolve; }); - invite(); - await settle(); - assert.equal(asked.length, 0); - catalog.reviews.push({}, {}, {}); - loaded(); - await settle(); - assert.equal(asked.length, 1); -}); - -test('respects permanent dismissal after two reviews', async () => { - setFirstRunReloadPending(false); - const { asked, invite } = setup(Promise.resolve({ confirmed: false }), [{}, {}], true); - invite(); - await settle(); - assert.equal(asked.length, 0); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardCommunity.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardCommunity.contribution.ts deleted file mode 100644 index 261278f20..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardCommunity.contribution.ts +++ /dev/null @@ -1,56 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { onUnexpectedError } from '../../base/common/errors.js'; -import { IDialogService } from '../../platform/dialogs/common/dialogs.js'; -import { IOpenerService } from '../../platform/opener/common/opener.js'; -import { IStorageService, StorageScope, StorageTarget } from '../../platform/storage/common/storage.js'; -import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../workbench/common/contributions.js'; -import { isFirstRunReloadPending } from '../common/whiteboardFirstRunReload.js'; -import { WHITEBOARD_DISCORD_URL } from '../common/whiteboardProtocol.js'; -import { IWhiteboardApiCatalogService } from '../services/whiteboardApiCatalogService.js'; - -export const DISMISSED_KEY = 'review.community.dontShowAgain'; - -export class WhiteboardCommunityContribution implements IWorkbenchContribution { - - static readonly ID = 'workbench.contrib.devfast.whiteboardCommunity'; - - constructor( - @IDialogService dialogService: IDialogService, - @IStorageService storageService: IStorageService, - @IOpenerService openerService: IOpenerService, - @IWhiteboardApiCatalogService catalogService: IWhiteboardApiCatalogService, - ) { - if (storageService.getBoolean(DISMISSED_KEY, StorageScope.APPLICATION, false)) { - return; - } - - this.invite(dialogService, storageService, openerService, catalogService).catch(onUnexpectedError); - } - - private async invite(dialogService: IDialogService, storageService: IStorageService, openerService: IOpenerService, catalogService: IWhiteboardApiCatalogService): Promise { - if (await isFirstRunReloadPending()) { - return; // the seeding reload would discard both the question and the answer - } - await catalogService.initialize(); - if (catalogService.reviews.filter(whiteboard => whiteboard.kind !== 'scratchpad').length < 2) { - return; - } - const result = await dialogService.confirm({ - type: 'info', - message: 'Join the Whiteboard community', - detail: 'Meet the team, ask questions, and share feedback in the /dev/fast Discord. You can also join anytime using the Discord link next to Report a bug.', - primaryButton: 'Join Discord', - cancelButton: 'Not now', - }); - storageService.store(DISMISSED_KEY, true, StorageScope.APPLICATION, StorageTarget.MACHINE); - if (result.confirmed) { - await openerService.open(WHITEBOARD_DISCORD_URL, { openExternal: true }); - } - } -} - -registerWorkbenchContribution2(WhiteboardCommunityContribution.ID, WhiteboardCommunityContribution, WorkbenchPhase.AfterRestored); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardPaneCompositePartService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardPaneCompositePartService.ts deleted file mode 100644 index b05fd9640..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardPaneCompositePartService.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from '../../base/common/event.js'; -import { InstantiationType, registerSingleton } from '../../platform/instantiation/common/extensions.js'; -import type { IProgressIndicator } from '../../platform/progress/common/progress.js'; -import { Extensions as PaneCompositeExtensions, type PaneCompositeDescriptor } from '../../workbench/browser/panecomposite.js'; -import type { IPaneComposite } from '../../workbench/common/panecomposite.js'; -import { ViewContainerLocation } from '../../workbench/common/views.js'; -import { Parts, type SINGLE_WINDOW_PARTS } from '../../workbench/services/layout/browser/layoutService.js'; -import { IPaneCompositePartService } from '../../workbench/services/panecomposite/browser/panecomposite.js'; - -/** Supplies the pane-composite contract without creating chrome that Review does not show. */ -class WhiteboardPaneCompositePartService implements IPaneCompositePartService { - declare readonly _serviceBrand: undefined; - - readonly onDidPaneCompositeOpen = Event.None; - readonly onDidPaneCompositeClose = Event.None; - - getRegistryId(location: ViewContainerLocation): string { - switch (location) { - case ViewContainerLocation.Sidebar: - return PaneCompositeExtensions.Viewlets; - case ViewContainerLocation.Panel: - return PaneCompositeExtensions.Panels; - case ViewContainerLocation.AuxiliaryBar: - return PaneCompositeExtensions.Auxiliary; - } - } - - getPartId(location: ViewContainerLocation): SINGLE_WINDOW_PARTS { - switch (location) { - case ViewContainerLocation.Sidebar: - return Parts.SIDEBAR_PART; - case ViewContainerLocation.Panel: - return Parts.PANEL_PART; - case ViewContainerLocation.AuxiliaryBar: - return Parts.AUXILIARYBAR_PART; - } - } - - openPaneComposite(_id: string | undefined, _location: ViewContainerLocation, _focus?: boolean): Promise { - return Promise.resolve(undefined); - } - - getActivePaneComposite(_location: ViewContainerLocation): IPaneComposite | undefined { return undefined; } - getPaneComposite(_id: string, _location: ViewContainerLocation): PaneCompositeDescriptor | undefined { return undefined; } - getPaneComposites(_location: ViewContainerLocation): PaneCompositeDescriptor[] { return []; } - getPinnedPaneCompositeIds(_location: ViewContainerLocation): string[] { return []; } - getVisiblePaneCompositeIds(_location: ViewContainerLocation): string[] { return []; } - getPaneCompositeIds(_location: ViewContainerLocation): string[] { return []; } - getProgressIndicator(_id: string, _location: ViewContainerLocation): IProgressIndicator | undefined { return undefined; } - hideActivePaneComposite(_location: ViewContainerLocation): void { } - getLastActivePaneCompositeId(_location: ViewContainerLocation): string { return ''; } -} - -registerSingleton(IPaneCompositePartService, WhiteboardPaneCompositePartService, InstantiationType.Delayed); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardTheme.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardTheme.contribution.ts deleted file mode 100644 index dee56d17c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardTheme.contribution.ts +++ /dev/null @@ -1,58 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize, localize2 } from '../../nls.js'; -import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../platform/actions/common/actions.js'; -import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; -import type { ServicesAccessor } from '../../platform/instantiation/common/instantiation.js'; -import { IQuickInputService, type IQuickPickItem } from '../../platform/quickinput/common/quickInput.js'; -import { IThemeService } from '../../platform/theme/common/themeService.js'; -import { type WhiteboardThemeChoice, applyWhiteboardThemeChoice, currentWhiteboardThemeChoice } from './whiteboardThemeChoice.js'; - -interface IWhiteboardThemeQuickPickItem extends IQuickPickItem { - readonly choice: WhiteboardThemeChoice; -} - -class SelectWhiteboardThemeAction extends Action2 { - constructor() { - super({ - id: 'whiteboard.selectTheme', - title: localize2('whiteboard.selectTheme', "Whiteboard: Theme"), - f1: true - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const configurationService = accessor.get(IConfigurationService); - const quickInputService = accessor.get(IQuickInputService); - const themeService = accessor.get(IThemeService); - const currentChoice = currentWhiteboardThemeChoice(configurationService, themeService); - const items: IWhiteboardThemeQuickPickItem[] = [ - { choice: 'light', label: localize('review.theme.light', "Light"), picked: currentChoice === 'light' }, - { choice: 'dark', label: localize('review.theme.dark', "Dark"), picked: currentChoice === 'dark' }, - { choice: 'system', label: localize('review.theme.system', "System"), picked: currentChoice === 'system' } - ]; - - const picked = await quickInputService.pick(items, { - title: localize('review.theme.title', "Whiteboard: Theme"), - placeHolder: localize('review.theme.placeholder', "Select a theme") - }); - if (!picked) { - return; - } - - await applyWhiteboardThemeChoice(configurationService, picked.choice); - } -} - -registerAction2(SelectWhiteboardThemeAction); - -MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { - command: { - id: 'whiteboard.selectTheme', - title: localize('whiteboard.selectTheme.menu', "Theme...") - }, - order: 0 -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardThemeChoice.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardThemeChoice.ts deleted file mode 100644 index b244c6767..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/whiteboardThemeChoice.ts +++ /dev/null @@ -1,57 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ConfigurationTarget, IConfigurationService } from '../../platform/configuration/common/configuration.js'; -import { ColorScheme } from '../../platform/theme/common/theme.js'; -import { IThemeService } from '../../platform/theme/common/themeService.js'; - -/** - * The theme choice, shared by the `whiteboard.selectTheme` quick pick and the - * Settings canvas tab. This module registers nothing, so the canvas part can - * import it without pulling in a contribution. - */ - -const WHITEBOARD_DARK_THEME = 'Whiteboard Dark'; -const WHITEBOARD_LIGHT_THEME = 'Whiteboard Light'; - -export type WhiteboardThemeChoice = 'dark' | 'light' | 'system'; - -export function currentWhiteboardThemeChoice(configurationService: IConfigurationService, themeService: IThemeService): WhiteboardThemeChoice { - if (configurationService.getValue('window.autoDetectColorScheme')) { - return 'system'; - } - - // The theme service applies a theme change asynchronously, so a read taken - // right after applyWhiteboardThemeChoice still reports the previous theme. The - // configured name is authoritative whenever it names a Review theme. - const configured = configurationService.getValue('workbench.colorTheme'); - if (configured === WHITEBOARD_LIGHT_THEME) { - return 'light'; - } - if (configured === WHITEBOARD_DARK_THEME) { - return 'dark'; - } - - const type = themeService.getColorTheme().type; - return type === ColorScheme.LIGHT || type === ColorScheme.HIGH_CONTRAST_LIGHT ? 'light' : 'dark'; -} - -export async function applyWhiteboardThemeChoice(configurationService: IConfigurationService, choice: WhiteboardThemeChoice): Promise { - switch (choice) { - case 'dark': - await configurationService.updateValue('window.autoDetectColorScheme', false, ConfigurationTarget.USER); - await configurationService.updateValue('workbench.colorTheme', WHITEBOARD_DARK_THEME, ConfigurationTarget.USER); - break; - case 'light': - await configurationService.updateValue('window.autoDetectColorScheme', false, ConfigurationTarget.USER); - await configurationService.updateValue('workbench.colorTheme', WHITEBOARD_LIGHT_THEME, ConfigurationTarget.USER); - break; - case 'system': - await configurationService.updateValue('window.autoDetectColorScheme', true, ConfigurationTarget.USER); - await configurationService.updateValue('workbench.preferredDarkColorTheme', WHITEBOARD_DARK_THEME, ConfigurationTarget.USER); - await configurationService.updateValue('workbench.preferredLightColorTheme', WHITEBOARD_LIGHT_THEME, ConfigurationTarget.USER); - break; - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/workbench.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/workbench.ts deleted file mode 100644 index 4797ab9b0..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/browser/workbench.ts +++ /dev/null @@ -1,2073 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import '../../workbench/browser/style.js'; -import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../base/common/lifecycle.js'; -import { Emitter, Event, setGlobalLeakWarningThreshold } from '../../base/common/event.js'; -import { Dimension, IDimension, addDisposableListener, getActiveDocument, getActiveElement, getClientArea, getWindowId, getWindows, isAncestorUsingFlowTo, isHTMLElement, runWhenWindowIdle, size } from '../../base/browser/dom.js'; -import { DeferredPromise, RunOnceScheduler } from '../../base/common/async.js'; -import { isChrome, isFirefox, isFullscreen, isSafari, onDidChangeFullscreen } from '../../base/browser/browser.js'; -import { mark } from '../../base/common/performance.js'; -import { onUnexpectedError, setUnexpectedErrorHandler } from '../../base/common/errors.js'; -import { WhiteboardErrorReportLimiter } from '../common/whiteboardErrorReport.js'; -import { IWhiteboardTelemetryService } from '../services/whiteboardTelemetryService.js'; -import { isLinux, isMacintosh, isNative, isWeb, isWindows } from '../../base/common/platform.js'; -import { IPartVisibilityChangeEvent, IWorkbenchLayoutService, MULTI_WINDOW_PARTS, PanelAlignment, Parts, Position, SINGLE_WINDOW_PARTS } from '../../workbench/services/layout/browser/layoutService.js'; -import { ILayoutOffsetInfo } from '../../platform/layout/browser/layoutService.js'; -import { Part } from '../../workbench/browser/part.js'; -import { Direction, ISerializableView, ISerializedGrid, ISerializedLeafNode, ISerializedNode, IViewSize, Orientation, SerializableGrid } from '../../base/browser/ui/grid/grid.js'; -import { IEditorGroupsService } from '../../workbench/services/editor/common/editorGroupsService.js'; -import { IEditorService } from '../../workbench/services/editor/common/editorService.js'; -import { IPaneCompositePartService } from '../../workbench/services/panecomposite/browser/panecomposite.js'; -import { IViewDescriptorService, ViewContainerLocation } from '../../workbench/common/views.js'; -import { ILogService } from '../../platform/log/common/log.js'; -import { IInstantiationService, ServicesAccessor, refineServiceDecorator } from '../../platform/instantiation/common/instantiation.js'; -import { ITitleService } from '../../workbench/services/title/browser/titleService.js'; -import { CodeWindow, mainWindow } from '../../base/browser/window.js'; -import { coalesce } from '../../base/common/arrays.js'; -import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; -import { InstantiationService } from '../../platform/instantiation/common/instantiationService.js'; -import { getSingletonServiceDescriptors } from '../../platform/instantiation/common/extensions.js'; -import { ILifecycleService, LifecyclePhase, WillShutdownEvent } from '../../workbench/services/lifecycle/common/lifecycle.js'; -import { IStorageService, StorageScope, StorageTarget, WillSaveStateReason } from '../../platform/storage/common/storage.js'; -import { IConfigurationChangeEvent, IConfigurationService } from '../../platform/configuration/common/configuration.js'; -import { IHostService } from '../../workbench/services/host/browser/host.js'; -import { IDialogService } from '../../platform/dialogs/common/dialogs.js'; -import { INotificationService } from '../../platform/notification/common/notification.js'; -import { NotificationService } from '../../workbench/services/notification/common/notificationService.js'; -import { IHoverService, WorkbenchHoverDelegate } from '../../platform/hover/browser/hover.js'; -import { setHoverDelegateFactory } from '../../base/browser/ui/hover/hoverDelegateFactory.js'; -import { setBaseLayerHoverDelegate } from '../../base/browser/ui/hover/hoverDelegate2.js'; -import { Registry } from '../../platform/registry/common/platform.js'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from '../../workbench/common/contributions.js'; -import { EditorExtensions, IEditorFactoryRegistry, IEditorWillOpenEvent } from '../../workbench/common/editor.js'; -import { setARIAContainer } from '../../base/browser/ui/aria/aria.js'; -import { FontMeasurements } from '../../editor/browser/config/fontMeasurements.js'; -import { createBareFontInfoFromRawSettings } from '../../editor/common/config/fontInfoFromSettings.js'; -import { toErrorMessage } from '../../base/common/errorMessage.js'; -import { WorkbenchContextKeysHandler } from '../../workbench/browser/contextkeys.js'; -import { PixelRatio } from '../../base/browser/pixelRatio.js'; -import { AccessibilityProgressSignalScheduler } from '../../platform/accessibilitySignal/browser/progressAccessibilitySignalScheduler.js'; -import { setProgressAccessibilitySignalScheduler } from '../../base/browser/ui/progressbar/progressAccessibilitySignal.js'; -import { AccessibleViewRegistry } from '../../platform/accessibility/browser/accessibleViewRegistry.js'; -import { NotificationAccessibleView } from '../../workbench/browser/parts/notifications/notificationAccessibleView.js'; -import { NotificationsCenter } from '../../workbench/browser/parts/notifications/notificationsCenter.js'; -import { NotificationsAlerts } from '../../workbench/browser/parts/notifications/notificationsAlerts.js'; -import { NotificationsStatus } from '../../workbench/browser/parts/notifications/notificationsStatus.js'; -import { registerNotificationCommands } from '../../workbench/browser/parts/notifications/notificationsCommands.js'; -import { NotificationsToasts } from '../../workbench/browser/parts/notifications/notificationsToasts.js'; -import { IMarkdownRendererService } from '../../platform/markdown/browser/markdownRenderer.js'; -import { EditorMarkdownCodeBlockRenderer } from '../../editor/browser/widget/markdownRenderer/browser/editorMarkdownCodeBlockRenderer.js'; -import { SyncDescriptor } from '../../platform/instantiation/common/descriptors.js'; -import { MainWhiteboardTitlebarPart, WhiteboardTitleService } from './parts/whiteboardTitlebarPart.js'; -import { IContextKeyService, RawContextKey } from '../../platform/contextkey/common/contextkey.js'; -import { IsWhiteboardWindowContext } from '../../workbench/common/contextkeys.js'; -import { - NotificationsPosition, - NotificationsSettings, - getNotificationsPosition -} from '../../workbench/common/notifications.js'; -import { IWhiteboardCanvasPartsService } from './parts/canvas/whiteboardCanvasPart.js'; -import { IWhiteboardExplorerPartsService } from './parts/explorer/whiteboardExplorerPart.js'; -import { initialWhiteboardPartVisibility } from '../common/whiteboardWorkbenchVisibility.js'; -import { WHITEBOARD_CHROME_HEIGHT } from '../common/whiteboardChrome.js'; - -const EDITOR_PART_MINIMUM_WIDTH = 300; -const EDITOR_PART_DEFAULT_WIDTH = 600; -const EXPLORER_PART_DEFAULT_WIDTH = 260; -const EditorMaximizedContext = new RawContextKey('editorMaximized', false); - -//#region WhiteboardWorkbench Options - -export interface IWorkbenchOptions { - /** - * Extra classes to be added to the workbench container. - */ - extraClasses?: string[]; -} - -//#endregion - -//#region Layout Classes - -enum LayoutClasses { - SIDEBAR_HIDDEN = 'nosidebar', - MAIN_EDITOR_AREA_HIDDEN = 'nomaineditorarea', - PANEL_HIDDEN = 'nopanel', - AUXILIARYBAR_HIDDEN = 'noauxiliarybar', - SESSIONS_HIDDEN = 'nosessionspart', - /** Positive polarity: the explorer is hidden on most tabs, so the class marks the exception. */ - EXPLORER_VISIBLE = 'whiteboard-explorer-visible', - STATUSBAR_HIDDEN = 'nostatusbar', - SHELL_GRADIENT_BACKGROUND = 'shell-gradient-background', - FULLSCREEN = 'fullscreen', - MAXIMIZED = 'maximized' -} - -//#endregion - -//#region Part Visibility State - -/** Visibility of each workbench part in the Agents window layout. */ -export interface IPartVisibilityState { - sidebar: boolean; - auxiliaryBar: boolean; - editor: boolean; - panel: boolean; - sessions: boolean; - explorer: boolean; -} - -interface IPartSizesState { - sidebar?: number; - auxiliaryBar?: number; - sessions?: number; - editor?: number; - panel?: number; - explorer?: number; -} - -//#endregion - -export interface IAgentWorkbenchLayoutService extends IWorkbenchLayoutService { - isEditorMaximized(): boolean; - setEditorMaximized(maximized: boolean): void; - - readonly onDidChangeEditorMaximized: Event; - - /** - * Suppresses the automatic editor part show/hide that normally fires from - * `editorService.onWillOpenEditor` / `onDidCloseEditor`. Use this around - * programmatic editor operations (e.g. applying a working set) so that the - * editor part visibility is not changed as a side-effect. Dispose the - * returned handle to release the suppression. Calls nest via a counter. - */ - suppressEditorPartAutoVisibility(): IDisposable; -} - -export const IAgentWorkbenchLayoutService = refineServiceDecorator(IWorkbenchLayoutService); - - -const WHITEBOARD_CHROME_INSET_PROPERTIES = ['--whiteboard-chrome-left-width', '--whiteboard-chrome-right-width', '--whiteboard-explorer-width'] as const; -export class WhiteboardWorkbench extends Disposable implements IAgentWorkbenchLayoutService { - - declare readonly _serviceBrand: undefined; - - //#region Lifecycle Events - - private readonly _onWillShutdown = this._register(new Emitter()); - readonly onWillShutdown = this._onWillShutdown.event; - - private readonly _onDidShutdown = this._register(new Emitter()); - readonly onDidShutdown = this._onDidShutdown.event; - - //#endregion - - //#region Events - - private readonly _onDidChangeZenMode = this._register(new Emitter()); - readonly onDidChangeZenMode = this._onDidChangeZenMode.event; - - private readonly _onDidChangeMainEditorCenteredLayout = this._register(new Emitter()); - readonly onDidChangeMainEditorCenteredLayout = this._onDidChangeMainEditorCenteredLayout.event; - - private readonly _onDidChangePanelAlignment = this._register(new Emitter()); - readonly onDidChangePanelAlignment = this._onDidChangePanelAlignment.event; - - private readonly _onDidChangeWindowMaximized = this._register(new Emitter<{ windowId: number; maximized: boolean }>()); - readonly onDidChangeWindowMaximized = this._onDidChangeWindowMaximized.event; - - private readonly _onDidChangePanelPosition = this._register(new Emitter()); - readonly onDidChangePanelPosition = this._onDidChangePanelPosition.event; - - private readonly _onDidChangePartVisibility = this._register(new Emitter()); - readonly onDidChangePartVisibility = this._onDidChangePartVisibility.event; - - private readonly _onDidChangeNotificationsVisibility = this._register(new Emitter()); - readonly onDidChangeNotificationsVisibility = this._onDidChangeNotificationsVisibility.event; - - private readonly _onDidChangeAuxiliaryBarMaximized = this._register(new Emitter()); - readonly onDidChangeAuxiliaryBarMaximized = this._onDidChangeAuxiliaryBarMaximized.event; - - private readonly _onDidChangeEditorMaximized = this._register(new Emitter()); - readonly onDidChangeEditorMaximized = this._onDidChangeEditorMaximized.event; - - private readonly _onDidLayoutMainContainer = this._register(new Emitter()); - readonly onDidLayoutMainContainer = this._onDidLayoutMainContainer.event; - - private readonly _onDidLayoutActiveContainer = this._register(new Emitter()); - readonly onDidLayoutActiveContainer = this._onDidLayoutActiveContainer.event; - - private readonly _onDidLayoutContainer = this._register(new Emitter<{ container: HTMLElement; dimension: IDimension }>()); - readonly onDidLayoutContainer = this._onDidLayoutContainer.event; - - private readonly _onDidAddContainer = this._register(new Emitter<{ container: HTMLElement; disposables: DisposableStore }>()); - readonly onDidAddContainer = this._onDidAddContainer.event; - - private readonly _onDidChangeActiveContainer = this._register(new Emitter()); - readonly onDidChangeActiveContainer = this._onDidChangeActiveContainer.event; - - //#endregion - - //#region Properties - - readonly mainContainer = document.createElement('div'); - - get activeContainer(): HTMLElement { - return this.getContainerFromDocument(getActiveDocument()); - } - - get containers(): Iterable { - const containers: HTMLElement[] = []; - for (const { window } of getWindows()) { - containers.push(this.getContainerFromDocument(window.document)); - } - return containers; - } - - private getContainerFromDocument(targetDocument: Document): HTMLElement { - if (targetDocument === this.mainContainer.ownerDocument) { - return this.mainContainer; - } else { - // eslint-disable-next-line no-restricted-syntax - return targetDocument.body.getElementsByClassName('monaco-workbench')[0] as HTMLElement; - } - } - - private _mainContainerDimension!: IDimension; - get mainContainerDimension(): IDimension { return this._mainContainerDimension; } - - get activeContainerDimension(): IDimension { - return this.getContainerDimension(this.activeContainer); - } - - private getContainerDimension(container: HTMLElement): IDimension { - if (container === this.mainContainer) { - return this.mainContainerDimension; - } else { - return getClientArea(container); - } - } - - get mainContainerOffset(): ILayoutOffsetInfo { - return this.computeContainerOffset(); - } - - get activeContainerOffset(): ILayoutOffsetInfo { - return this.computeContainerOffset(); - } - - private computeContainerOffset(): ILayoutOffsetInfo { - let top = 0; - let quickPickTop = 0; - - if (this.isVisible(Parts.TITLEBAR_PART, mainWindow)) { - top = WHITEBOARD_CHROME_HEIGHT; - quickPickTop = top; - } - - return { top, quickPickTop }; - } - - //#endregion - - //#region State - - private readonly parts = new Map(); - protected workbenchGrid!: SerializableGrid; - - protected sideBarPartView!: ISerializableView; - private panelPartView!: ISerializableView; - protected auxiliaryBarPartView!: ISerializableView; - protected editorPartView!: ISerializableView; - - protected sessionsPartView!: ISerializableView; - protected explorerPartView!: ISerializableView; - - /** The editor part container; the auxiliary bar is docked inside it. */ - protected _editorPartContainer: HTMLElement | undefined; - - protected readonly partVisibility: IPartVisibilityState = { - sidebar: true, - auxiliaryBar: true, - editor: false, - panel: false, - sessions: true, - explorer: false - }; - - private mainWindowFullscreen = false; - private readonly maximized = new Set(); - private _editorMaximized = false; - private _editorLastNonMaximizedVisibility: IPartVisibilityState | undefined; - private _editorLastNonMaximizedSize: IViewSize | undefined; - private _restoreAttachedEditorMaximizedOnShow = false; - protected _editorPartAutoVisibilitySuppressionCount = 0; - protected _hasAppliedInitialEditorSplit = false; - private readonly whiteboardChromeTabStrips: HTMLElement[] = []; - private readonly whiteboardChromeDragListeners = this._register(new DisposableStore()); - private readonly whiteboardChromeInsetScheduler = this._register(new RunOnceScheduler(() => this.updateWhiteboardChromeInset(), 0)); - - private readonly restoredPromise = new DeferredPromise(); - readonly whenRestored = this.restoredPromise.p; - private restored = false; - - readonly openedDefaultEditors = false; - - protected _savedPartSizes: IPartSizesState = {}; - - //#endregion - - private static readonly _PART_VISIBILITY_KEY = 'workbench.sessions.partVisibility'; - private static readonly _PART_SIZES_KEY = 'workbench.sessions.partSizes'; - - //#region Services - - protected editorGroupService!: IEditorGroupsService; - private editorService!: IEditorService; - private paneCompositeService!: IPaneCompositePartService; - private viewDescriptorService!: IViewDescriptorService; - private storageService!: IStorageService; - - //#endregion - - constructor( - protected readonly parent: HTMLElement, - private readonly options: IWorkbenchOptions | undefined, - private readonly serviceCollection: ServiceCollection, - private readonly logService: ILogService - ) { - super(); - - // Sessions-scoped mobile viewport tweaks. These are applied here - // (rather than in the shared workbench.html) so that the regular - // code-web workbench — which does not handle safe-area insets — is - // not affected on notched mobile devices. - // The viewport `` tag is injected by the shared workbench.html, - // so we cannot use dom.ts `h()` to create it. Look it up by tag name - // and filter by the `name` attribute to avoid a selector query. - // eslint-disable-next-line no-restricted-syntax - const metaElements = mainWindow.document.head.getElementsByTagName('meta'); - let viewportMeta: HTMLMetaElement | undefined; - for (let i = 0; i < metaElements.length; i++) { - if (metaElements[i].name === 'viewport') { - viewportMeta = metaElements[i]; - break; - } - } - if (viewportMeta && !viewportMeta.content.includes('viewport-fit=')) { - viewportMeta.content = `${viewportMeta.content}, viewport-fit=cover`; - } - - // Perf: measure workbench startup time - mark('code/willStartWorkbench'); - - this.registerErrorHandler(logService); - } - - //#region Error Handling - - private registerErrorHandler(logService: ILogService): void { - // Increase stack trace limit for better errors stacks - if (!isFirefox) { - Error.stackTraceLimit = 100; - } - - // Listen on unhandled rejection events - // Note: intentionally not registered as disposable to handle - // errors that can occur during shutdown phase. - mainWindow.addEventListener('unhandledrejection', (event) => { - // See https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent - onUnexpectedError(event.reason); - - // Prevent the printing of this event to the console - event.preventDefault(); - }); - - // Listen on synchronous errors that never reach a promise. Without this - // they only reach the console, so they are invisible to the log and to - // telemetry alike. - mainWindow.addEventListener('error', (event) => { - onUnexpectedError(event.error ?? event.message); - }); - - // Install handler for unexpected errors - setUnexpectedErrorHandler(error => this.handleUnexpectedError(error, logService)); - } - - private previousUnexpectedError: { message: string | undefined; time: number } = { message: undefined, time: 0 }; - private handleUnexpectedError(error: unknown, logService: ILogService): void { - const message = toErrorMessage(error, true); - if (!message) { - return; - } - - const now = Date.now(); - if (message === this.previousUnexpectedError.message && now - this.previousUnexpectedError.time <= 1000) { - return; // Return if error message identical to previous and shorter than 1 second - } - - this.previousUnexpectedError.time = now; - this.previousUnexpectedError.message = message; - - // Log it - logService.error(message); - - // Report it - this.reportUnexpectedError(error); - } - - private readonly errorReportLimiter = new WhiteboardErrorReportLimiter(); - private workbenchInstantiationService: IInstantiationService | undefined; - private whiteboardTelemetryService: IWhiteboardTelemetryService | undefined; - - /** - * Send the error to the loopback Whiteboard server, which strips the message and - * every stack frame outside the shipped bundle before anything leaves this - * machine. Errors raised before `startup()` have no service to report - * through and are dropped rather than buffered: buffering would hold raw - * messages before the telemetry setting can be read. - */ - private reportUnexpectedError(error: unknown): void { - this.errorReportLimiter.report(error, report => { - this.whiteboardTelemetryService ??= this.workbenchInstantiationService?.invokeFunction(accessor => accessor.get(IWhiteboardTelemetryService)); - this.whiteboardTelemetryService?.capture('client_error', { - error_source: 'renderer_unexpected', - error_process: 'renderer', - }, report); - }); - } - - //#endregion - - //#region Startup - - startup(): IInstantiationService { - try { - // Configure emitter leak warning threshold - this._register(setGlobalLeakWarningThreshold(175)); - - // Services - const instantiationService = this.initServices(this.serviceCollection); - - // The error handler is installed in the constructor, long before any - // service exists. Keep the instantiation service here so it can - // resolve the telemetry service on the first error. - this.workbenchInstantiationService = instantiationService; - - instantiationService.invokeFunction(accessor => { - const lifecycleService = accessor.get(ILifecycleService); - const storageService = accessor.get(IStorageService); - const configurationService = accessor.get(IConfigurationService); - const hostService = accessor.get(IHostService); - const hoverService = accessor.get(IHoverService); - const dialogService = accessor.get(IDialogService); - const notificationService = accessor.get(INotificationService) as NotificationService; - const markdownRendererService = accessor.get(IMarkdownRendererService); - - // On web, the configuration service needs access to the - // instantiation service for dynamic configuration resolution. - if (isWeb && typeof (configurationService as IConfigurationService & { acquireInstantiationService?(i: IInstantiationService): void }).acquireInstantiationService === 'function') { - (configurationService as IConfigurationService & { acquireInstantiationService(i: IInstantiationService): void }).acquireInstantiationService(instantiationService); - } - - // Set code block renderer for markdown rendering - markdownRendererService.setDefaultCodeBlockRenderer(instantiationService.createInstance(EditorMarkdownCodeBlockRenderer)); - - // Default Hover Delegate must be registered before creating any workbench/layout components - setHoverDelegateFactory((placement, enableInstantHover) => instantiationService.createInstance(WorkbenchHoverDelegate, placement, { instantHover: enableInstantHover }, {})); - setBaseLayerHoverDelegate(hoverService); - - // Layout - this.initLayout(accessor); - - // Registries - this creates and registers all parts - Registry.as(WorkbenchExtensions.Workbench).start(accessor); - Registry.as(EditorExtensions.EditorFactory).start(accessor); - - // Context Keys - this._register(instantiationService.createInstance(WorkbenchContextKeysHandler)); - - // Editor Maximized Context Key - const editorMaximizedContext = EditorMaximizedContext.bindTo(accessor.get(IContextKeyService)); - this._register(this.onDidChangeEditorMaximized(() => { - editorMaximizedContext.set(this.isEditorMaximized()); - })); - - const contextKeyService = accessor.get(IContextKeyService); - - // Marks this window as Review so shared workbench contributions can - // opt out of chrome Review does not offer (split editors, the editor - // actions overflow menu). - IsWhiteboardWindowContext.bindTo(contextKeyService).set(true); - - // Register Listeners - this.registerListeners(lifecycleService, storageService, configurationService, hostService, dialogService); - - // Render WhiteboardWorkbench - this.renderWorkbench(instantiationService, notificationService, storageService, configurationService); - - // WhiteboardWorkbench Layout - this.createWorkbenchLayout(); - - // WhiteboardWorkbench Management - this.createWorkbenchManagement(instantiationService); - - // Layout - this.layout(); - - // Restore - this.restore(lifecycleService); - }); - - return instantiationService; - } catch (error) { - onUnexpectedError(error); - - throw error; // rethrow because this is a critical issue we cannot handle properly here - } - } - - private initServices(serviceCollection: ServiceCollection): IInstantiationService { - // Layout Service - serviceCollection.set(IAgentWorkbenchLayoutService, this); - - // All Contributed Services - const contributedServices = getSingletonServiceDescriptors(); - for (const [id, descriptor] of contributedServices) { - serviceCollection.set(id, descriptor); - } - - // The Review titlebar is a workbench part, not a contributed native - // service. Install it after the registry has been materialized so a - // platform title-service registration cannot replace the custom part. - serviceCollection.set(ITitleService, new SyncDescriptor(WhiteboardTitleService, [])); - - const instantiationService = new InstantiationService(serviceCollection, true); - - // Wrap up - instantiationService.invokeFunction(accessor => { - const lifecycleService = accessor.get(ILifecycleService); - lifecycleService.phase = LifecyclePhase.Ready; - }); - - return instantiationService; - } - - private registerListeners(lifecycleService: ILifecycleService, storageService: IStorageService, configurationService: IConfigurationService, hostService: IHostService, dialogService: IDialogService): void { - // Configuration changes - this._register(configurationService.onDidChangeConfiguration(e => this.updateFontAliasing(e, configurationService))); - - // Font Info - if (isNative) { - this._register(storageService.onWillSaveState(e => { - if (e.reason === WillSaveStateReason.SHUTDOWN) { - this.storeFontInfo(storageService); - } - })); - } else { - this._register(lifecycleService.onWillShutdown(() => this.storeFontInfo(storageService))); - } - - // Part Sizes — persist current grid sizes so they are restored on reload - this._register(storageService.onWillSaveState(() => this._savePartSizes())); - - // Lifecycle - this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event))); - this._register(lifecycleService.onDidShutdown(() => { - this._onDidShutdown.fire(); - this.dispose(); - })); - - // Flush storage on window focus loss - this._register(hostService.onDidChangeFocus(focus => { - if (!focus) { - storageService.flush(); - } - })); - - // Dialogs showing/hiding - this._register(dialogService.onWillShowDialog(() => this.mainContainer.classList.add('modal-dialog-visible'))); - this._register(dialogService.onDidShowDialog(() => this.mainContainer.classList.remove('modal-dialog-visible'))); - } - - //#region Font Aliasing and Caching - - private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto' | undefined; - private updateFontAliasing(e: IConfigurationChangeEvent | undefined, configurationService: IConfigurationService) { - if (!isMacintosh) { - return; // macOS only - } - - if (e && !e.affectsConfiguration('workbench.fontAliasing')) { - return; - } - - const aliasing = configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>('workbench.fontAliasing'); - if (this.fontAliasing === aliasing) { - return; - } - - this.fontAliasing = aliasing; - - // Remove all - const fontAliasingValues: (typeof aliasing)[] = ['antialiased', 'none', 'auto']; - this.mainContainer.classList.remove(...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); - - // Add specific - if (fontAliasingValues.some(option => option === aliasing)) { - this.mainContainer.classList.add(`monaco-font-aliasing-${aliasing}`); - } - } - - private restoreFontInfo(storageService: IStorageService, configurationService: IConfigurationService): void { - const storedFontInfoRaw = storageService.get('editorFontInfo', StorageScope.APPLICATION); - if (storedFontInfoRaw) { - try { - const storedFontInfo = JSON.parse(storedFontInfoRaw); - if (Array.isArray(storedFontInfo)) { - FontMeasurements.restoreFontInfo(mainWindow, storedFontInfo); - } - } catch (err) { - /* ignore */ - } - } - - FontMeasurements.readFontInfo(mainWindow, createBareFontInfoFromRawSettings(configurationService.getValue('editor'), PixelRatio.getInstance(mainWindow).value)); - } - - private storeFontInfo(storageService: IStorageService): void { - const serializedFontInfo = FontMeasurements.serializeFontInfo(mainWindow); - if (serializedFontInfo) { - storageService.store('editorFontInfo', JSON.stringify(serializedFontInfo), StorageScope.APPLICATION, StorageTarget.MACHINE); - } - } - - /** - * Applies Review's runtime-derived initial visibility and removes the - * obsolete persisted visibility record. Part sizes remain independently - * persisted so an explicitly opened editor can reuse its last valid width. - */ - private _applyInitialPartVisibility(): void { - this.storageService.remove(WhiteboardWorkbench._PART_VISIBILITY_KEY, StorageScope.WORKSPACE); - Object.assign(this.partVisibility, initialWhiteboardPartVisibility); - } - - private _loadPartSizes(storageService: IStorageService): IPartSizesState { - const raw = storageService.get(WhiteboardWorkbench._PART_SIZES_KEY, StorageScope.WORKSPACE); - if (raw) { - try { - return JSON.parse(raw); - } catch { - // Corrupted data — remove the bad key so we don't keep warning on every startup - storageService.remove(WhiteboardWorkbench._PART_SIZES_KEY, StorageScope.WORKSPACE); - } - } - return {}; - } - - private _savePartSizes(): void { - if (!this.workbenchGrid) { - return; - } - - // The editor-part grid node hosts the docked auxiliary bar in single-pane, so - // it is "visible" whenever the editor OR the detail is shown. Use the node's - // real visibility (not just `partVisibility.editor`) so a Detail-only session - // records its *current* collapsed node width — reading the stale cached visible - // size (wide) here would restore a wide node on reload and flicker the editor - // open via the width-based reveal-sync. Classic layout is unaffected - // (`_editorNodeVisible` returns `partVisibility.editor` there). - const editorNodeVisible = this.partVisibility.editor; - const editorGridWidth = this._persistedGridViewSize(this.editorPartView, 'width', editorNodeVisible); - let editorWidth = editorGridWidth; - - // A sub-minimum measurement is never a real user width: the editor may be - // hidden (single-pane returns the detail-only node minus the detail width, - // i.e. ~0), or the high-priority sessions part may have transiently squeezed - // the node below its minimum. Persisting it would rebuild the editor at its - // 300px minimum on reload and lose the last user-selected width. Preserve the - // last valid global width instead (or omit it so the default is used). The - // descriptor keeps the editor contribution at zero while the editor part is - // hidden, so keeping a valid width here is safe. - if (editorWidth === undefined || editorWidth < EDITOR_PART_MINIMUM_WIDTH) { - editorWidth = (this._savedPartSizes.editor !== undefined && this._savedPartSizes.editor >= EDITOR_PART_MINIMUM_WIDTH) - ? this._savedPartSizes.editor - : undefined; - } else { - // Track the latest good width so a later shutdown-time squeeze falls back to it. - this._savedPartSizes = { ...this._savedPartSizes, editor: editorWidth }; - } - - const sizes: IPartSizesState = { - sessions: this._persistedGridViewSize(this.sessionsPartView, 'width', this.partVisibility.sessions), - editor: editorWidth, - // The explorer is hidden on most tabs, so this is usually the grid's - // cached visible size — the width the user last dragged the sash to. - explorer: this._persistedGridViewSize(this.explorerPartView, 'width', this.partVisibility.explorer), - }; - - this.storageService.store(WhiteboardWorkbench._PART_SIZES_KEY, JSON.stringify(sizes), StorageScope.WORKSPACE, StorageTarget.MACHINE); - } - - //#endregion - - private renderWorkbench(instantiationService: IInstantiationService, notificationService: NotificationService, storageService: IStorageService, configurationService: IConfigurationService): void { - // ARIA & Signals - setARIAContainer(this.mainContainer); - setProgressAccessibilitySignalScheduler((msDelayTime: number, msLoopTime?: number) => instantiationService.createInstance(AccessibilityProgressSignalScheduler, msDelayTime, msLoopTime)); - - // Apply Review's fixed desktop visibility before the grid is built. - this._applyInitialPartVisibility(); - - // Load saved grid part sizes — these will be consumed when building the - // grid descriptor so editor/sidebar/auxbar/panel restore to their previous - // dimensions across reloads. - this._savedPartSizes = this._loadPartSizes(storageService); - - // State specific classes - const platformClass = isWindows ? 'windows' : isLinux ? 'linux' : 'mac'; - const workbenchClasses = coalesce([ - 'monaco-workbench', - 'whiteboard-workbench', - // LayoutClasses.SHELL_GRADIENT_BACKGROUND, - platformClass, - isWeb ? 'web' : undefined, - isChrome ? 'chromium' : isFirefox ? 'firefox' : isSafari ? 'safari' : undefined, - ...this.getLayoutClasses(), - ...(this.options?.extraClasses ? this.options.extraClasses : []) - ]); - - this.mainContainer.classList.add(...workbenchClasses); - - // Apply font aliasing - this.updateFontAliasing(undefined, configurationService); - - // Warm up font cache information before building up too many dom elements - this.restoreFontInfo(storageService, configurationService); - - // Review owns exactly one chrome part. Sidebar, panel, auxiliary bar, - // activity bar, status bar, and banner parts are never instantiated. - for (const { id, role, classes } of [ - { id: Parts.TITLEBAR_PART, role: 'none', classes: ['titlebar'] }, - ]) { - const partContainer = this.createPartContainer(id, role, classes); - - mark(`code/willCreatePart/${id}`); - this.getPart(id).create(partContainer); - mark(`code/didCreatePart/${id}`); - - partContainer.classList.add('whiteboard-chrome-overlay'); - this.mainContainer.appendChild(partContainer); - } - - // Create Editor Part (hidden by default) - this.createEditorPart(); - - // Create Sessions Part - this.createSessionsPart(); - - // Create Review Explorer Part (hidden until a file or diff tab is active) - this.createExplorerPart(); - - // Notification Handlers - this.createNotificationsHandlers(instantiationService, notificationService, configurationService); - - // Add WhiteboardWorkbench to DOM - this.parent.appendChild(this.mainContainer); - } - - private createNotificationsHandlers( - instantiationService: IInstantiationService, - notificationService: NotificationService, - configurationService: IConfigurationService - ): void { - // Instantiate Notification components - const notificationsCenter = this._register(instantiationService.createInstance(NotificationsCenter, this.mainContainer, notificationService.model)); - const notificationsToasts = this._register(instantiationService.createInstance(NotificationsToasts, this.mainContainer, notificationService.model)); - this._register(instantiationService.createInstance(NotificationsAlerts, notificationService.model)); - const notificationsStatus = this._register(instantiationService.createInstance(NotificationsStatus, notificationService.model)); - - // Visibility - this._register(notificationsCenter.onDidChangeVisibility(() => { - notificationsStatus.update(notificationsCenter.isVisible, notificationsToasts.isVisible); - notificationsToasts.update(notificationsCenter.isVisible); - })); - - this._register(notificationsToasts.onDidChangeVisibility(() => { - notificationsStatus.update(notificationsCenter.isVisible, notificationsToasts.isVisible); - })); - - // Register Commands - registerNotificationCommands(notificationsCenter, notificationsToasts, notificationService.model); - - // Register notification accessible view - AccessibleViewRegistry.register(new NotificationAccessibleView()); - - // The shared notification controllers apply a top-right inline offset based on the - // default workbench custom titlebar height. The sessions workbench has its own - // fixed chrome, so re-apply the sessions-specific top-right offset after they run. - this.registerSessionsNotificationOffsets(configurationService, notificationsCenter, notificationsToasts); - - // Register with Layout - this.registerNotifications({ - onDidChangeNotificationsVisibility: Event.map( - Event.any(notificationsToasts.onDidChangeVisibility, notificationsCenter.onDidChangeVisibility), - () => notificationsToasts.isVisible || notificationsCenter.isVisible - ) - }); - } - - private registerSessionsNotificationOffsets( - configurationService: IConfigurationService, - notificationsCenter: NotificationsCenter, - notificationsToasts: NotificationsToasts - ): void { - const applySessionsNotificationOffsets = () => { - const position = getNotificationsPosition(configurationService); - const notificationsCenterContainer = this.getWorkbenchChildByClassName('notifications-center'); - const notificationsToastsContainer = this.getWorkbenchChildByClassName('notifications-toasts'); - - if (position === NotificationsPosition.TOP_RIGHT) { - notificationsCenterContainer?.style.setProperty('top', '40px'); - notificationsToastsContainer?.style.setProperty('top', '40px'); - } - }; - - this._register(this.onDidLayoutMainContainer(() => applySessionsNotificationOffsets())); - this._register(notificationsCenter.onDidChangeVisibility(() => applySessionsNotificationOffsets())); - this._register(notificationsToasts.onDidChangeVisibility(() => applySessionsNotificationOffsets())); - this._register(configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(NotificationsSettings.NOTIFICATIONS_POSITION)) { - applySessionsNotificationOffsets(); - } - })); - } - - private getWorkbenchChildByClassName(className: string): HTMLElement | undefined { - for (const child of this.mainContainer.children) { - if (isHTMLElement(child) && child.classList.contains(className)) { - return child; - } - } - - return undefined; - } - - private createPartContainer(id: string, role: string, classes: string[]): HTMLElement { - const part = document.createElement('div'); - part.classList.add('part', ...classes); - part.id = id; - part.setAttribute('role', role); - return part; - } - - private createEditorPart(): void { - const editorPartContainer = document.createElement('div'); - editorPartContainer.classList.add('part', 'editor'); - editorPartContainer.id = Parts.EDITOR_PART; - editorPartContainer.setAttribute('role', 'main'); - this._editorPartContainer = editorPartContainer; - - mark('code/willCreatePart/workbench.parts.editor'); - this.getPart(Parts.EDITOR_PART).create(editorPartContainer, { restorePreviousState: true }); - mark('code/didCreatePart/workbench.parts.editor'); - - this.mainContainer.appendChild(editorPartContainer); - } - - private createSessionsPart(): void { - const sessionsPartContainer = document.createElement('div'); - sessionsPartContainer.classList.add('part', 'sessionspart', 'basepanel', 'right'); - sessionsPartContainer.id = Parts.SESSIONS_PART; - sessionsPartContainer.setAttribute('role', 'main'); - - mark(`code/willCreatePart/${Parts.SESSIONS_PART}`); - this.getPart(Parts.SESSIONS_PART).create(sessionsPartContainer); - mark(`code/didCreatePart/${Parts.SESSIONS_PART}`); - - this.mainContainer.appendChild(sessionsPartContainer); - } - - private createExplorerPart(): void { - const explorerPartContainer = document.createElement('div'); - explorerPartContainer.classList.add('part', 'whiteboard-explorer'); - explorerPartContainer.id = Parts.WHITEBOARD_EXPLORER_PART; - explorerPartContainer.setAttribute('role', 'navigation'); - - mark(`code/willCreatePart/${Parts.WHITEBOARD_EXPLORER_PART}`); - this.getPart(Parts.WHITEBOARD_EXPLORER_PART).create(explorerPartContainer); - mark(`code/didCreatePart/${Parts.WHITEBOARD_EXPLORER_PART}`); - - this.mainContainer.appendChild(explorerPartContainer); - } - - private restore(lifecycleService: ILifecycleService): void { - // Update perf marks - mark('code/didStartWorkbench'); - performance.measure('perf: workbench create & restore', 'code/didLoadWorkbenchMain', 'code/didStartWorkbench'); - - // Set lifecycle phase to `Restored` - lifecycleService.phase = LifecyclePhase.Restored; - - // Mark as restored - this.setRestored(); - - // Set lifecycle phase to `Eventually` after a short delay and when idle (min 2.5sec, max 5sec) - const eventuallyPhaseScheduler = this._register(new RunOnceScheduler(() => { - this._register(runWhenWindowIdle(mainWindow, () => lifecycleService.phase = LifecyclePhase.Eventually, 2500)); - }, 2500)); - eventuallyPhaseScheduler.schedule(); - } - - //#endregion - - //#region Initialization - - initLayout(accessor: ServicesAccessor): void { - // Services - accessing these triggers their instantiation - // which creates and registers the parts - this.editorGroupService = accessor.get(IEditorGroupsService); - this.editorService = accessor.get(IEditorService); - // Forces eager creation of the sessions part so it registers itself with the - // layout service before renderWorkbench() looks it up via getPart(). - accessor.get(IWhiteboardCanvasPartsService); - // Same for the file explorer part, which also owns its own show/hide policy. - accessor.get(IWhiteboardExplorerPartsService); - // The sidebar, panel, and auxiliary bar stay hidden in Review, but the - // part-visibility setters below still reach for this service; leaving it - // unassigned would throw the moment any of them ran. - this.paneCompositeService = accessor.get(IPaneCompositePartService); - this.storageService = accessor.get(IStorageService); - accessor.get(ITitleService); - - const editorMainPart = this.editorGroupService.mainPart; - this._register(editorMainPart.onDidLayout(() => this.whiteboardChromeInsetScheduler.schedule())); - const titlebarPart = this.getPart(Parts.TITLEBAR_PART); - if (titlebarPart instanceof MainWhiteboardTitlebarPart) { - this._register(titlebarPart.onDidChangeChromeInsets(() => this.whiteboardChromeInsetScheduler.schedule())); - } - this._register(editorMainPart.onDidAddGroup(() => this.whiteboardChromeInsetScheduler.schedule())); - this._register(editorMainPart.onDidRemoveGroup(() => this.whiteboardChromeInsetScheduler.schedule())); - this._register(editorMainPart.onDidMoveGroup(() => this.whiteboardChromeInsetScheduler.schedule())); - - // Register layout listeners - this.registerLayoutListeners(); - - // Editor opens should only affect the main editor part when - // they actually target one of the main editor groups. Modal - // opens stay neutral. Programmatic opens that suppress auto - // visibility (e.g. working set application) are ignored. - // The base handler reveals a hidden editor for any such open; - this._register(this.editorService.onWillOpenEditor(e => this.revealEditorOnOpen(e))); - - // Hide editor part when last editor closes - this._register(this.editorService.onDidCloseEditor(() => this.handleDidCloseEditor())); - - // Initialize layout state (must be done before createWorkbenchLayout) - this._mainContainerDimension = getClientArea(this.parent, new Dimension(800, 600)); - // Establish runtime-derived visibility before the context keys handler is - // created. The editor becomes visible only in response to a real open. - this._applyInitialPartVisibility(); - } - - private areAllGroupsInMainPartEmpty(): boolean { - for (const group of this.editorGroupService.mainPart.groups) { - if (!group.isEmpty) { - return false; - } - } - return true; - } - - protected revealEditorOnOpen(e: IEditorWillOpenEvent): void { - if (this._editorPartAutoVisibilitySuppressionCount > 0) { - return; - } - - const group = this.editorGroupService.mainPart.groups.find(g => g.id === e.groupId); - if (!group) { - return; - } - - if (!this.partVisibility.editor) { - this.setEditorHidden(false); - this.restoreAttachedEditorMaximizedState(); - } - } - - private handleDidCloseEditor(): void { - if (this._editorPartAutoVisibilitySuppressionCount > 0 || !this.areAllGroupsInMainPartEmpty()) { - return; - } - - this._handleAllEditorsClosed(); - } - - suppressEditorPartAutoVisibility(): IDisposable { - this._editorPartAutoVisibilitySuppressionCount++; - let disposed = false; - return toDisposable(() => { - if (disposed) { - return; - } - disposed = true; - this._editorPartAutoVisibilitySuppressionCount--; - }); - } - - protected rememberAttachedEditorMaximizedState(): void { - this._restoreAttachedEditorMaximizedOnShow = this._editorMaximized && this.partVisibility.auxiliaryBar; - } - - private restoreAttachedEditorMaximizedState(): void { - const shouldRestore = this._restoreAttachedEditorMaximizedOnShow && this.partVisibility.auxiliaryBar; - this._restoreAttachedEditorMaximizedOnShow = false; - - if (shouldRestore) { - this.setEditorMaximized(true); - } - } - - //#region Layout helpers - - /** - * Handles a change in the editor-part grid view's visibility. In the classic - * layout the editor part is a standalone grid view, so its view visibility *is* - * the editor visibility — map it to `setEditorHidden` and raise the part event. - */ - protected _onEditorPartGridVisibilityChange(visible: boolean): void { - this.setEditorHidden(!visible); - this._onDidChangePartVisibility.fire({ partId: Parts.EDITOR_PART, visible }); - } - - protected get _isEditorPartAutoVisibilitySuppressed(): boolean { - return this._editorPartAutoVisibilitySuppressionCount > 0; - } - - /** Width the auxiliary bar occupies when visible (for max-editor-dimension math). */ - protected _auxiliaryBarLayoutWidth(): number { - return this.workbenchGrid ? this.workbenchGrid.getViewSize(this.auxiliaryBarPartView).width : 0; - } - - protected _auxiliaryBarViewSize(): IViewSize { - if (!this.workbenchGrid || !this.auxiliaryBarPartView) { - return { width: 0, height: 0 }; - } - return this.workbenchGrid.getViewSize(this.auxiliaryBarPartView); - } - - protected _setAuxiliaryBarViewSize(size: IViewSize): void { - if (this.auxiliaryBarPartView) { - this.workbenchGrid.resizeView(this.auxiliaryBarPartView, size); - } - } - - protected _resizeAuxiliaryBarBy(deltaWidth: number, deltaHeight: number): void { - if (!this.auxiliaryBarPartView) { - return; - } - const currentSize = this.workbenchGrid.getViewSize(this.auxiliaryBarPartView); - this.workbenchGrid.resizeView(this.auxiliaryBarPartView, { - width: currentSize.width + deltaWidth, - height: currentSize.height + deltaHeight - }); - } - - /** - * Reads a part's size from the workbench grid for persistence. For visible - * parts, the current view size; for hidden parts, the grid's cached visible - * size (the size it had the last time it was shown) so toggling visibility - * later restores the same dimensions. - */ - protected _persistedGridViewSize(view: ISerializableView, dimension: 'width' | 'height', visible: boolean): number | undefined { - if (visible) { - return this.workbenchGrid.getViewSize(view)[dimension]; - } - return this.workbenchGrid.getViewCachedVisibleSize(view); - } - - protected _applyEditorVisibility(hidden: boolean): void { - const shouldApplyEvenSplit = !hidden && !this._hasAppliedInitialEditorSplit; - - // Capture the main-area width (the sessions part occupies it fully while the - // editor is hidden) before revealing, so the even split can halve it. - const mainAreaWidth = this.workbenchGrid.getViewSize(this.sessionsPartView).width; - - this.workbenchGrid.setViewVisible(this.editorPartView, !hidden); - - if (shouldApplyEvenSplit) { - this._hasAppliedInitialEditorSplit = true; - this._applyEditorSplitSize(mainAreaWidth); - } - } - - protected _applyAuxiliaryBarVisibility(hidden: boolean): void { - // Skipped before the grid exists: during startup the layout controller (a - // BlockRestore contribution) runs before createWorkbenchLayout(), so the - // visibility is recorded in partVisibility and applied when the grid is built. - if (this.workbenchGrid) { - this.workbenchGrid.setViewVisible(this.auxiliaryBarPartView, !hidden); - } - } - - protected _handleAllEditorsClosed(): void { - if (this.partVisibility.editor) { - this.rememberAttachedEditorMaximizedState(); - this.setEditorHidden(true); - } - } - - //#endregion - - private registerLayoutListeners(): void { - // Fullscreen changes - this._register(onDidChangeFullscreen(windowId => { - if (windowId === getWindowId(mainWindow)) { - this.mainWindowFullscreen = isFullscreen(mainWindow); - this.updateFullscreenClass(); - this.layout(); - } - })); - - // Window resize — needed for device emulation and mobile viewport changes - const onWindowResize = () => this.layout(); - this._register(addDisposableListener(mainWindow, 'resize', onWindowResize)); - } - - private updateFullscreenClass(): void { - if (this.mainWindowFullscreen) { - this.mainContainer.classList.add(LayoutClasses.FULLSCREEN); - } else { - this.mainContainer.classList.remove(LayoutClasses.FULLSCREEN); - } - } - - /** - * Written on the tab strip that reads them, not the workbench root: a - * changed inherited custom property restyles every element below it, and - * with a canvas full of peek editors that was a ~200ms stall per explorer - * show, hide or sash move. - */ - private publishWhiteboardChromeInset(tabStrip: HTMLElement): void { - const titlebarPart = this.getPart(Parts.TITLEBAR_PART); - const insets = titlebarPart instanceof MainWhiteboardTitlebarPart ? titlebarPart.chromeInsets : { left: 0, right: 0 }; - const explorerWidth = this.isVisible(Parts.WHITEBOARD_EXPLORER_PART) ? this.getSize(Parts.WHITEBOARD_EXPLORER_PART).width : 0; - tabStrip.style.setProperty('--whiteboard-chrome-left-width', `${insets.left}px`); - tabStrip.style.setProperty('--whiteboard-chrome-right-width', `${insets.right}px`); - tabStrip.style.setProperty('--whiteboard-explorer-width', `${explorerWidth}px`); - } - - private updateWhiteboardChromeInset(): void { - this.whiteboardChromeDragListeners.clear(); - this.mainContainer.classList.remove('whiteboard-tab-dragging'); - for (const tabStrip of this.whiteboardChromeTabStrips) { - tabStrip.classList.remove('whiteboard-chrome-tab-strip', 'whiteboard-chrome-inset'); - for (const property of WHITEBOARD_CHROME_INSET_PROPERTIES) { - tabStrip.style.removeProperty(property); - } - } - this.whiteboardChromeTabStrips.length = 0; - - const editorPartContainer = this._editorPartContainer; - if (!editorPartContainer) { - return; - } - - let topLeftGroup: HTMLElement | undefined; - let topLeftRect: DOMRect | undefined; - const visibleGroups: { group: HTMLElement; rect: DOMRect }[] = []; - const groups = editorPartContainer.getElementsByClassName('editor-group-container'); - for (let index = 0; index < groups.length; index++) { - const group = groups[index]; - if (!isHTMLElement(group)) { - continue; - } - - const rect = group.getBoundingClientRect(); - if (rect.width === 0 || rect.height === 0) { - continue; - } - - visibleGroups.push({ group, rect }); - - if (!topLeftRect || rect.top < topLeftRect.top - 1 || (Math.abs(rect.top - topLeftRect.top) <= 1 && rect.left < topLeftRect.left)) { - topLeftGroup = group; - topLeftRect = rect; - } - } - - if (!topLeftGroup || !topLeftRect) { - return; - } - - const finishTabDrag = () => this.mainContainer.classList.remove('whiteboard-tab-dragging'); - - // Every top-row group shares window dragging. Only the leftmost group - // needs the navigation inset. - for (const { group, rect } of visibleGroups) { - if (Math.abs(rect.top - topLeftRect.top) > 1) { - continue; - } - - const tabStrip = group.querySelector(':scope > .title > .tabs-and-actions-container'); - if (!isHTMLElement(tabStrip)) { - continue; - } - - this.whiteboardChromeTabStrips.push(tabStrip); - tabStrip.classList.add('whiteboard-chrome-tab-strip'); - if (group === topLeftGroup) { - tabStrip.classList.add('whiteboard-chrome-inset'); - this.publishWhiteboardChromeInset(tabStrip); - } - this.whiteboardChromeDragListeners.add(addDisposableListener(tabStrip, 'dragstart', () => this.mainContainer.classList.add('whiteboard-tab-dragging'))); - this.whiteboardChromeDragListeners.add(addDisposableListener(tabStrip, 'dragend', finishTabDrag)); - this.whiteboardChromeDragListeners.add(addDisposableListener(tabStrip, 'drop', finishTabDrag)); - } - } - - //#endregion - - //#region WhiteboardWorkbench Layout Creation - - createWorkbenchLayout(): void { - const editorPart = this.getPart(Parts.EDITOR_PART); - const sessionsPart = this.getPart(Parts.SESSIONS_PART); - const explorerPart = this.getPart(Parts.WHITEBOARD_EXPLORER_PART); - - this.sessionsPartView = sessionsPart; - this.editorPartView = editorPart; - this.explorerPartView = explorerPart; - - const viewMap: { [key: string]: ISerializableView } = { - [Parts.SESSIONS_PART]: this.sessionsPartView, - [Parts.EDITOR_PART]: this.editorPartView, - [Parts.WHITEBOARD_EXPLORER_PART]: this.explorerPartView - }; - - const fromJSON = ({ type }: { type: string }) => viewMap[type]; - const workbenchGrid = SerializableGrid.deserialize( - this.createGridDescriptor(), - { fromJSON }, - { proportionalLayout: false } - ); - - this.mainContainer.prepend(workbenchGrid.element); - this.mainContainer.setAttribute('role', 'application'); - this.workbenchGrid = workbenchGrid; - this.workbenchGrid.edgeSnapping = this.mainWindowFullscreen; - // If the editor is restored visible, it already has an established - // width, so a later reveal must not force an even split over it. - this._hasAppliedInitialEditorSplit = this.partVisibility.editor; - - for (const part of [sessionsPart, editorPart, explorerPart]) { - this._register(part.onDidVisibilityChange(visible => { - // A grid branch forwards its own show/hide to every child leaf, - // including leaves whose slot stays hidden. That notification - // describes the branch, not the part, so acting on it would reveal - // a part the grid still holds hidden. The grid is authoritative for - // every part it owns, and Review puts all of them in the grid. - if (this.workbenchGrid.isViewVisible(part) === !visible) { - return; - } - - if (part === editorPart) { - this._onEditorPartGridVisibilityChange(visible); - this.handleContainerDidLayout(this.mainContainer, this._mainContainerDimension); - return; - } - - if (part === sessionsPart) { - this.setSessionsHidden(!visible); - } - - if (part === explorerPart) { - this.setExplorerHidden(!visible); - } - - this._onDidChangePartVisibility.fire({ partId: part.getId(), visible }); - this.handleContainerDidLayout(this.mainContainer, this._mainContainerDimension); - })); - } - } - - createWorkbenchManagement(_instantiationService: IInstantiationService): void { } - - /** - * Creates the grid descriptor for the Agent Sessions layout. - * - * Structure (horizontal orientation): - * - Sidebar (left, spans full height from top to bottom) - * - Right section (vertical): - * - Titlebar (top of right section) - * - Top right (horizontal): Chat Bar | Editor | Auxiliary Bar - * - Panel (below chat, editor, and auxiliary bar) - */ - private createGridDescriptor(): ISerializedGrid { - const { width, height } = this._mainContainerDimension; - - return this.createDesktopGridDescriptor(width, height); - } - - /** - * Standard multi-part layout. Sidebar, panel, and auxiliary bar are hidden - * in the grid via partVisibility defaults. - */ - private createDesktopGridDescriptor(width: number, height: number): ISerializedGrid { - const savedEditorWidth = this._savedPartSizes.editor; - const editorSize = savedEditorWidth !== undefined && savedEditorWidth >= EDITOR_PART_MINIMUM_WIDTH ? savedEditorWidth : EDITOR_PART_DEFAULT_WIDTH; - const effectiveEditorWidth = this.partVisibility.editor ? editorSize : 0; - const sessionsWidth = this._savedPartSizes.sessions - ?? Math.max(0, width - effectiveEditorWidth); - const contentHeight = height; - - const sessionsNode: ISerializedLeafNode = { - type: 'leaf', - data: { type: Parts.SESSIONS_PART }, - size: sessionsWidth, - visible: this.partVisibility.sessions - }; - - const editorNode: ISerializedLeafNode = { - type: 'leaf', - data: { type: Parts.EDITOR_PART }, - size: effectiveEditorWidth, - visible: this.partVisibility.editor - }; - - // The explorer sits left of the editor. `partVisibility.explorer` is always - // false here — it is derived from the active editor, and no editor is - // restored yet — so the leaf carries only the width a later reveal uses. - const explorerNode: ISerializedLeafNode = { - type: 'leaf', - data: { type: Parts.WHITEBOARD_EXPLORER_PART }, - size: this._savedPartSizes.explorer ?? EXPLORER_PART_DEFAULT_WIDTH, - visible: this.partVisibility.explorer - }; - - const contentSection: ISerializedNode = { - type: 'branch', - data: [sessionsNode, explorerNode, editorNode], - size: contentHeight - }; - - const result: ISerializedGrid = { - root: { - type: 'branch', - size: width, - data: [contentSection] - }, - orientation: Orientation.VERTICAL, - width, - height - }; - - return result; - } - - //#endregion - - //#region Layout Methods - - layout(): void { - this._mainContainerDimension = getClientArea( - this.mainWindowFullscreen ? mainWindow.document.body : this.parent - ); - - this.logService.trace(`WhiteboardWorkbench#layout, height: ${this._mainContainerDimension.height}, width: ${this._mainContainerDimension.width}`); - - size(this.mainContainer, this._mainContainerDimension.width, this._mainContainerDimension.height); - - // A deliberate 10px breathing gap along the bottom edge, kept to match the window - // shape of stock VS Code. Review draws no part cards, so this is bare workbench - // ground rather than a margin around a card; whiteboard.css paints it with the editor - // background so it reads as one surface. - // - // The right edge takes no gutter: stock VS Code runs its parts flush to the window - // edge, and Review has no right-edge card to inset -- the card margins that would - // have needed one live under `.agent-sessions-workbench`, a class `workbenchClasses` - // never includes. - const gutterBottom = 10; - const gridWidth = this._mainContainerDimension.width; - const gridHeight = this._mainContainerDimension.height - gutterBottom; - - // Layout the grid widget - this.workbenchGrid.layout(gridWidth, gridHeight); - this.getPart(Parts.TITLEBAR_PART).layout(gridWidth, WHITEBOARD_CHROME_HEIGHT, 0, 0); - this.updateWhiteboardChromeInset(); - - // Emit as event - this.handleContainerDidLayout(this.mainContainer, this._mainContainerDimension); - } - - private handleContainerDidLayout(container: HTMLElement, dimension: IDimension): void { - this._onDidLayoutContainer.fire({ container, dimension }); - if (container === this.mainContainer) { - this._onDidLayoutMainContainer.fire(dimension); - } - if (container === this.activeContainer) { - this._onDidLayoutActiveContainer.fire(dimension); - } - } - - isFloatingPanelsEnabled(): boolean { - return false; // the agents window has its own floating card design - } - - getLayoutClasses(): string[] { - return coalesce([ - !this.partVisibility.sidebar ? LayoutClasses.SIDEBAR_HIDDEN : undefined, - !this.partVisibility.editor ? LayoutClasses.MAIN_EDITOR_AREA_HIDDEN : undefined, - !this.partVisibility.panel ? LayoutClasses.PANEL_HIDDEN : undefined, - !this.partVisibility.auxiliaryBar ? LayoutClasses.AUXILIARYBAR_HIDDEN : undefined, - !this.partVisibility.sessions ? LayoutClasses.SESSIONS_HIDDEN : undefined, - LayoutClasses.STATUSBAR_HIDDEN, // agents window never has a status bar - this.mainWindowFullscreen ? LayoutClasses.FULLSCREEN : undefined, - ]); - } - - //#endregion - - //#region Part Management - - registerPart(part: Part): IDisposable { - const id = part.getId(); - this.parts.set(id, part); - return toDisposable(() => this.parts.delete(id)); - } - - getPart(key: Parts): Part { - const part = this.parts.get(key); - if (!part) { - throw new Error(`Unknown part ${key}`); - } - return part; - } - - hasFocus(part: Parts): boolean { - const container = this.getContainer(mainWindow, part); - if (!container) { - return false; - } - - const activeElement = getActiveElement(); - if (!activeElement) { - return false; - } - - return isAncestorUsingFlowTo(activeElement, container); - } - - focusPart(part: MULTI_WINDOW_PARTS, targetWindow: Window): void; - focusPart(part: SINGLE_WINDOW_PARTS): void; - focusPart(part: Parts, targetWindow: Window = mainWindow): void { - switch (part) { - case Parts.EDITOR_PART: - this.editorGroupService.activeGroup.focus(); - break; - case Parts.PANEL_PART: - this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel)?.focus(); - break; - case Parts.SIDEBAR_PART: - this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar)?.focus(); - break; - case Parts.AUXILIARYBAR_PART: - this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar)?.focus(); - break; - case Parts.SESSIONS_PART: - // TODO: focus chat bar content once it is wired up - this.getPart(Parts.SESSIONS_PART).getContainer()?.focus(); - break; - default: { - const container = this.getContainer(targetWindow, part); - container?.focus(); - } - } - } - - focus(): void { - this.focusPart(Parts.SESSIONS_PART); - } - - //#endregion - - //#region Container Methods - - getContainer(targetWindow: Window): HTMLElement; - getContainer(targetWindow: Window, part: Parts): HTMLElement | undefined; - getContainer(targetWindow: Window, part?: Parts): HTMLElement | undefined { - if (typeof part === 'undefined') { - return this.getContainerFromDocument(targetWindow.document); - } - - if (targetWindow === mainWindow) { - return this.parts.get(part)?.getContainer(); - } - - // For auxiliary windows, only editor part is supported - if (part === Parts.EDITOR_PART) { - const container = this.getContainerFromDocument(targetWindow.document); - const partCandidate = this.editorGroupService.getPart(container); - if (partCandidate instanceof Part) { - return partCandidate.getContainer(); - } - } - - return undefined; - } - - whenContainerStylesLoaded(_window: CodeWindow): Promise | undefined { - return undefined; - } - - //#endregion - - //#region Part Visibility - - isActivityBarHidden(): boolean { - return true; // No activity bar in this layout - } - - isVisible(part: SINGLE_WINDOW_PARTS): boolean; - isVisible(part: MULTI_WINDOW_PARTS, targetWindow: Window): boolean; - isVisible(part: Parts, targetWindow?: Window): boolean { - switch (part) { - case Parts.TITLEBAR_PART: - return true; - case Parts.SIDEBAR_PART: - case Parts.AUXILIARYBAR_PART: - case Parts.PANEL_PART: - return false; - case Parts.EDITOR_PART: - return this.partVisibility.editor; - case Parts.SESSIONS_PART: - return this.partVisibility.sessions; - case Parts.WHITEBOARD_EXPLORER_PART: - return this.partVisibility.explorer; - case Parts.ACTIVITYBAR_PART: - case Parts.STATUSBAR_PART: - case Parts.BANNER_PART: - default: - return false; - } - } - - setPartHidden(hidden: boolean, part: Parts): void { - switch (part) { - case Parts.SIDEBAR_PART: - this.setSideBarHidden(hidden); - break; - case Parts.AUXILIARYBAR_PART: - this.setAuxiliaryBarHidden(hidden); - break; - case Parts.EDITOR_PART: - this.setEditorHidden(hidden); - break; - case Parts.PANEL_PART: - this.setPanelHidden(hidden); - break; - case Parts.SESSIONS_PART: - this.setSessionsHidden(hidden); - break; - case Parts.WHITEBOARD_EXPLORER_PART: - this.setExplorerHidden(hidden); - break; - } - } - - private setSideBarHidden(hidden: boolean): void { - if (this.partVisibility.sidebar === !hidden) { - return; - } - - this.partVisibility.sidebar = !hidden; - this.mainContainer.classList.toggle(LayoutClasses.SIDEBAR_HIDDEN, hidden); - - // Propagate to grid - this.workbenchGrid.setViewVisible( - this.sideBarPartView, - !hidden, - ); - - // If sidebar becomes hidden, also hide the current active pane composite - if (hidden && this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar)) { - this.paneCompositeService.hideActivePaneComposite(ViewContainerLocation.Sidebar); - } - - // If sidebar becomes visible, show last active Viewlet or default viewlet - if (!hidden && !this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar)) { - const viewletToOpen = this.paneCompositeService.getLastActivePaneCompositeId(ViewContainerLocation.Sidebar) ?? - this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id; - if (viewletToOpen) { - this.paneCompositeService.openPaneComposite(viewletToOpen, ViewContainerLocation.Sidebar); - } - } - } - - setAuxiliaryBarHidden(hidden: boolean): void { - if (this.partVisibility.auxiliaryBar === !hidden) { - return; - } - - if (hidden) { - this._restoreAttachedEditorMaximizedOnShow = false; - } - - this.partVisibility.auxiliaryBar = !hidden; - this.mainContainer.classList.toggle(LayoutClasses.AUXILIARYBAR_HIDDEN, hidden); - - this._applyAuxiliaryBarVisibility(hidden); - - // If auxiliary bar becomes hidden, also hide the current active pane composite - if (hidden && this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar)) { - this.paneCompositeService.hideActivePaneComposite(ViewContainerLocation.AuxiliaryBar); - } - - // If auxiliary bar becomes visible, show last active pane composite or default - if (!hidden && !this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.AuxiliaryBar)) { - const paneCompositeToOpen = this.paneCompositeService.getLastActivePaneCompositeId(ViewContainerLocation.AuxiliaryBar) ?? - this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.AuxiliaryBar)?.id; - if (paneCompositeToOpen) { - this.paneCompositeService.openPaneComposite(paneCompositeToOpen, ViewContainerLocation.AuxiliaryBar); - } - } - - } - - setEditorHidden(hidden: boolean): void { - if (this.partVisibility.editor === !hidden) { - return; - } - - if (hidden && this._editorMaximized) { - this.setEditorMaximized(false); - } - - this.partVisibility.editor = !hidden; - this.mainContainer.classList.toggle(LayoutClasses.MAIN_EDITOR_AREA_HIDDEN, hidden); - - if (this.editorPartView) { - this._applyEditorVisibility(hidden); - } - } - - /** - * Sizes the editor part when it is first revealed from a hidden state, so it - * opens as a comfortable split with the sessions part rather than at its - * minimum/restored width. The default grid layout splits the main area evenly; - * layouts with different sizing (e.g. the single-pane side pane) override this. - */ - protected _applyEditorSplitSize(mainAreaWidth: number): void { - const targetEditorWidth = Math.max(EDITOR_PART_MINIMUM_WIDTH, Math.floor(mainAreaWidth / 2)); - const currentEditorSize = this.workbenchGrid.getViewSize(this.editorPartView); - this.workbenchGrid.resizeView(this.editorPartView, { - width: targetEditorWidth, - height: currentEditorSize.height - }); - } - - private setPanelHidden(hidden: boolean): void { - if (this.partVisibility.panel === !hidden) { - return; - } - - // If hiding and the panel is maximized, exit maximized state first - if (hidden && this.workbenchGrid.hasMaximizedView()) { - this.workbenchGrid.exitMaximizedView(); - } - - const panelHadFocus = !hidden || this.hasFocus(Parts.PANEL_PART); - - this.partVisibility.panel = !hidden; - this.mainContainer.classList.toggle(LayoutClasses.PANEL_HIDDEN, hidden); - - // Propagate to grid - this.workbenchGrid.setViewVisible( - this.panelPartView, - !hidden, - ); - - // If panel becomes hidden, also hide the current active pane composite - if (hidden && this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel)) { - this.paneCompositeService.hideActivePaneComposite(ViewContainerLocation.Panel); - - // Focus the chat bar when hiding the panel if it had focus - if (panelHadFocus) { - this.focusPart(Parts.SESSIONS_PART); - } - } - - // If panel becomes visible, show last active panel or default and focus it - if (!hidden) { - if (!this.paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel)) { - const panelToOpen = this.paneCompositeService.getLastActivePaneCompositeId(ViewContainerLocation.Panel) ?? - this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Panel)?.id; - if (panelToOpen) { - this.paneCompositeService.openPaneComposite(panelToOpen, ViewContainerLocation.Panel); - } - } - - this.focusPart(Parts.PANEL_PART); - } - } - - private setSessionsHidden(hidden: boolean): void { - // Review hosts Home, canvases, files, and diffs in the editor group. The - // sessions part stays registered as a hidden layout placeholder with no - // content, so showing it only adds dead space no Review command can - // collapse. See `initialWhiteboardPartVisibility`. - if (!hidden) { - return; - } - - if (this.partVisibility.sessions === !hidden) { - return; - } - - this.partVisibility.sessions = !hidden; - this.mainContainer.classList.toggle(LayoutClasses.SESSIONS_HIDDEN, hidden); - - // Propagate to grid - this.workbenchGrid.setViewVisible(this.sessionsPartView, !hidden); - } - - /** - * Shows or hides the file explorer leaf. - * - * `WhiteboardExplorerParts` is the only caller: it derives the state from the - * active editor pane. A maximized editor owns the whole window, so a tab - * switch under it must not bring the explorer back. - */ - private setExplorerHidden(hidden: boolean): void { - if (!hidden && this._editorMaximized) { - return; - } - - if (this.partVisibility.explorer === !hidden) { - return; - } - - this.partVisibility.explorer = !hidden; - this.mainContainer.classList.toggle(LayoutClasses.EXPLORER_VISIBLE, !hidden); - - // The eager explorer service runs in initLayout(), before the grid exists. - // The descriptor reads partVisibility, so the state above still lands. - if (this.workbenchGrid) { - this.workbenchGrid.setViewVisible(this.explorerPartView, !hidden); - } - } - - //#endregion - - //#region Position Methods (Fixed - Not Configurable) - - getSideBarPosition(): Position { - return Position.LEFT; // Always left in this layout - } - - getPanelPosition(): Position { - return Position.BOTTOM; // Always bottom in this layout - } - - setPanelPosition(_position: Position): void { - // No-op: Panel position is fixed in this layout - } - - getPanelAlignment(): PanelAlignment { - return 'justify'; // Full width panel - } - - setPanelAlignment(_alignment: PanelAlignment): void { - // No-op: Panel alignment is fixed in this layout - } - - //#endregion - - //#region Size Methods - - getSize(part: Parts): IViewSize { - if (part === Parts.TITLEBAR_PART) { - return { width: this._mainContainerDimension.width, height: WHITEBOARD_CHROME_HEIGHT }; - } - if (part === Parts.AUXILIARYBAR_PART) { - return this._auxiliaryBarViewSize(); - } - const view = this.getPartView(part); - if (!view) { - return { width: 0, height: 0 }; - } - return this.workbenchGrid.getViewSize(view); - } - - setSize(part: Parts, size: IViewSize): void { - if (part === Parts.AUXILIARYBAR_PART) { - this._setAuxiliaryBarViewSize(size); - return; - } - const view = this.getPartView(part); - if (view) { - this.workbenchGrid.resizeView(view, size); - } - } - - resizePart(part: Parts, sizeChangeWidth: number, sizeChangeHeight: number): void { - if (part === Parts.AUXILIARYBAR_PART) { - this._resizeAuxiliaryBarBy(sizeChangeWidth, sizeChangeHeight); - return; - } - const view = this.getPartView(part); - if (!view) { - return; - } - - const currentSize = this.workbenchGrid.getViewSize(view); - this.workbenchGrid.resizeView(view, { - width: currentSize.width + sizeChangeWidth, - height: currentSize.height + sizeChangeHeight - }); - } - - private getPartView(part: Parts): ISerializableView | undefined { - switch (part) { - case Parts.SIDEBAR_PART: - return this.sideBarPartView; - case Parts.AUXILIARYBAR_PART: - return this.auxiliaryBarPartView; - case Parts.EDITOR_PART: - return this.editorPartView; - case Parts.PANEL_PART: - return this.panelPartView; - case Parts.SESSIONS_PART: - return this.sessionsPartView; - case Parts.WHITEBOARD_EXPLORER_PART: - return this.explorerPartView; - default: - return undefined; - } - } - - getMaximumEditorDimensions(_container: HTMLElement): IDimension { - // Return the available space for editor (excluding other parts) - const sidebarWidth = this.partVisibility.sidebar ? this.workbenchGrid.getViewSize(this.sideBarPartView).width : 0; - const auxiliaryBarWidth = this.partVisibility.auxiliaryBar - ? this._auxiliaryBarLayoutWidth() - : 0; - const panelHeight = this.partVisibility.panel ? this.workbenchGrid.getViewSize(this.panelPartView).height : 0; - return new Dimension( - this._mainContainerDimension.width - sidebarWidth - auxiliaryBarWidth, - this._mainContainerDimension.height - panelHeight - ); - } - - //#endregion - - //#region Unsupported Features (No-ops) - - toggleMaximizedPanel(): void { - // Review never adds a panel node to its fixed grid. - } - - isPanelMaximized(): boolean { - return false; - } - - toggleMaximizedAuxiliaryBar(): void { - // No-op: Maximize not supported in this layout - } - - setAuxiliaryBarMaximized(_maximized: boolean): boolean { - return false; // Maximize not supported - } - - isAuxiliaryBarMaximized(): boolean { - return false; // Maximize not supported - } - - isEditorMaximized(): boolean { - return this._editorMaximized; - } - - setEditorMaximized(maximized: boolean): void { - if (maximized === this._editorMaximized) { - return; - } - - if (maximized) { - // Save current visibility state - this._editorLastNonMaximizedVisibility = { - sidebar: this.partVisibility.sidebar, - auxiliaryBar: this.partVisibility.auxiliaryBar, - editor: this.partVisibility.editor, - panel: this.partVisibility.panel, - sessions: this.partVisibility.sessions, - explorer: this.partVisibility.explorer, - }; - - // Save the editor part size so it can be restored on un-maximize. - // While maximized the layout controller forces the auxiliary bar - // (Changes) visible, which shrinks the editor; without restoring the - // size the editor would not return to its previous width. - this._editorLastNonMaximizedSize = this.editorPartView - ? this.workbenchGrid.getViewSize(this.editorPartView) - : undefined; - - // Ensure editor is visible - if (!this.partVisibility.editor) { - this.setEditorHidden(false); - } - - // Hide all other content parts - if (this.partVisibility.sidebar) { - this.setSideBarHidden(true); - } - if (this.partVisibility.sessions) { - this.setSessionsHidden(true); - } - if (this.partVisibility.explorer) { - this.setExplorerHidden(true); - } - - this._editorMaximized = true; - } else { - const state = this._editorLastNonMaximizedVisibility; - const size = this._editorLastNonMaximizedSize; - this._editorLastNonMaximizedSize = undefined; - - // Restore previous visibility state, including the auxiliary bar - // (which the layout controller forced visible while maximized). - this.setSideBarHidden(!state?.sidebar); - this.setSessionsHidden(!state?.sessions); - this.setAuxiliaryBarHidden(!state?.auxiliaryBar); - - this._editorMaximized = false; - - // After the flag clears, so `setExplorerHidden` no longer refuses to show. - this.setExplorerHidden(!state?.explorer); - - // Restore the editor part width captured before maximizing. - if (this.editorPartView && size) { - this.workbenchGrid.resizeView(this.editorPartView, size); - } - } - - this._onDidChangeEditorMaximized.fire(); - } - - toggleZenMode(): void { - // No-op: Zen mode not supported in this layout - } - - toggleMenuBar(): void { - // No-op: Menu bar toggle not supported in this layout - } - - isMainEditorLayoutCentered(): boolean { - return false; // Centered layout not supported - } - - centerMainEditorLayout(_active: boolean): void { - // No-op: Centered layout not supported in this layout - } - - hasMainWindowBorder(): boolean { - return false; - } - - getMainWindowBorderRadius(): string | undefined { - return undefined; - } - - //#endregion - - //#region Window Maximized State - - isWindowMaximized(targetWindow: Window): boolean { - return this.maximized.has(getWindowId(targetWindow)); - } - - updateWindowMaximizedState(targetWindow: Window, maximized: boolean): void { - const windowId = getWindowId(targetWindow); - if (maximized) { - this.maximized.add(windowId); - if (targetWindow === mainWindow) { - this.mainContainer.classList.add(LayoutClasses.MAXIMIZED); - } - } else { - this.maximized.delete(windowId); - if (targetWindow === mainWindow) { - this.mainContainer.classList.remove(LayoutClasses.MAXIMIZED); - } - } - - this._onDidChangeWindowMaximized.fire({ windowId, maximized }); - } - - //#endregion - - //#region Neighbor Parts - - getVisibleNeighborPart(part: Parts, direction: Direction): Parts | undefined { - if (!this.workbenchGrid) { - return undefined; - } - - const view = this.getPartView(part); - if (!view) { - return undefined; - } - - const neighbor = this.workbenchGrid.getNeighborViews(view, direction, false); - if (neighbor.length === 0) { - return undefined; - } - - const neighborView = neighbor[0]; - - if (neighborView === this.sideBarPartView) { - return Parts.SIDEBAR_PART; - } - if (neighborView === this.auxiliaryBarPartView) { - return Parts.AUXILIARYBAR_PART; - } - if (neighborView === this.editorPartView) { - return Parts.EDITOR_PART; - } - if (neighborView === this.panelPartView) { - return Parts.PANEL_PART; - } - if (neighborView === this.sessionsPartView) { - return Parts.SESSIONS_PART; - } - if (neighborView === this.explorerPartView) { - return Parts.WHITEBOARD_EXPLORER_PART; - } - - return undefined; - } - - //#endregion - - //#region Restore - - isRestored(): boolean { - return this.restored; - } - - setRestored(): void { - this.restored = true; - this.restoredPromise.complete(); - } - - //#endregion - - //#region Notifications Registration - - registerNotifications(delegate: { onDidChangeNotificationsVisibility: Event }): void { - this._register(delegate.onDidChangeNotificationsVisibility(visible => this._onDidChangeNotificationsVisibility.fire(visible))); - } - - //#endregion -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardAboutDialog.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardAboutDialog.test.ts deleted file mode 100644 index c4957377b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardAboutDialog.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import { appendWhiteboardInstallId } from './whiteboardAboutDialog.js'; - -test('appends the install id to visible and copied About details', () => { - const about = appendWhiteboardInstallId({ - title: 'Review', - details: 'Version: 1', - detailsToCopy: 'Version: 1', - }, 'install-123'); - - assert.equal(about.details, 'Version: 1\ninstall id: install-123'); - assert.equal(about.detailsToCopy, 'Version: 1\ninstall id: install-123'); -}); - -test('keeps About useful when the install id is unavailable', () => { - const about = appendWhiteboardInstallId({ - title: 'Review', - details: 'Version: 1', - detailsToCopy: 'Version: 1', - }, undefined); - - assert.equal(about.details, 'Version: 1\ninstall id: Unknown'); - assert.equal(about.detailsToCopy, 'Version: 1\ninstall id: Unknown'); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardAboutDialog.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardAboutDialog.ts deleted file mode 100644 index 52c0ba00d..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardAboutDialog.ts +++ /dev/null @@ -1,22 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface WhiteboardAboutDialogDetails { - readonly title: string; - readonly details: string; - readonly detailsToCopy: string; -} - -export function appendWhiteboardInstallId( - about: WhiteboardAboutDialogDetails, - installationId: string | undefined, -): WhiteboardAboutDialogDetails { - const line = `install id: ${installationId || "Unknown"}`; - return { - ...about, - details: `${about.details}\n${line}`, - detailsToCopy: `${about.detailsToCopy}\n${line}`, - }; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardBootstrapBreadcrumb.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardBootstrapBreadcrumb.test.ts deleted file mode 100644 index 5f6d89ec8..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardBootstrapBreadcrumb.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -// This test lives under common/ because that is one of the three directories -// the Review unit-test glob covers; the module under test is in node/. - -import assert from "node:assert/strict"; -import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; -import { tmpdir } from "node:os"; -import path from "node:path"; -import test from "node:test"; - -import { - drainWhiteboardBootstrapBreadcrumbs, - whiteboardBootstrapBreadcrumbPath, - writeWhiteboardBootstrapBreadcrumb, -} from "../node/whiteboardBootstrapBreadcrumb.js"; - -function withTempUserData(body: (userDataPath: string) => void): void { - const root = mkdtempSync(path.join(tmpdir(), "review-breadcrumb-")); - try { - body(path.join(root, "user-data")); - } finally { - rmSync(root, { recursive: true, force: true }); - } -} - -test("a crash note round-trips and the file is then gone", () => { - withTempUserData(userDataPath => { - const error = new TypeError("cannot load main"); - error.stack = "TypeError: cannot load main\n at f (/app/out/vs/code/electron-main/main.js:1:1)"; - writeWhiteboardBootstrapBreadcrumb(userDataPath, error, 1234); - - const drained = drainWhiteboardBootstrapBreadcrumbs(userDataPath); - assert.equal(drained.length, 1); - assert.equal(drained[0].name, "TypeError"); - assert.equal(drained[0].message, "cannot load main"); - assert.equal(drained[0].t, 1234); - assert.match(drained[0].stack, /electron-main\/main\.js:1:1/); - assert.equal(existsSync(whiteboardBootstrapBreadcrumbPath(userDataPath)), false); - assert.deepEqual(drainWhiteboardBootstrapBreadcrumbs(userDataPath), []); - }); -}); - -test("several crashes accumulate as separate lines", () => { - withTempUserData(userDataPath => { - writeWhiteboardBootstrapBreadcrumb(userDataPath, new Error("first")); - writeWhiteboardBootstrapBreadcrumb(userDataPath, new Error("second")); - assert.deepEqual( - drainWhiteboardBootstrapBreadcrumbs(userDataPath).map(entry => entry.message), - ["first", "second"], - ); - }); -}); - -test("a crash loop cannot fill the disk", () => { - withTempUserData(userDataPath => { - writeWhiteboardBootstrapBreadcrumb(userDataPath, new Error("first")); - const file = whiteboardBootstrapBreadcrumbPath(userDataPath); - writeFileSync(file, `${"x".repeat(70 * 1024)}\n`, "utf8"); - writeWhiteboardBootstrapBreadcrumb(userDataPath, new Error("dropped")); - assert.equal(readFileSync(file, "utf8").includes("dropped"), false); - }); -}); - -test("recording a crash never raises one", () => { - assert.doesNotThrow(() => { - writeWhiteboardBootstrapBreadcrumb("", undefined); - writeWhiteboardBootstrapBreadcrumb("\0invalid", new Error("boom")); - }); - assert.deepEqual(drainWhiteboardBootstrapBreadcrumbs("\0invalid"), []); -}); - -test("one unreadable line does not lose the others", () => { - withTempUserData(userDataPath => { - writeWhiteboardBootstrapBreadcrumb(userDataPath, new Error("kept")); - const file = whiteboardBootstrapBreadcrumbPath(userDataPath); - writeFileSync(file, `not json\n${readFileSync(file, "utf8")}`, "utf8"); - assert.deepEqual( - drainWhiteboardBootstrapBreadcrumbs(userDataPath).map(entry => entry.message), - ["kept"], - ); - }); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCanvasReuse.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCanvasReuse.ts deleted file mode 100644 index 896118a24..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCanvasReuse.ts +++ /dev/null @@ -1,66 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface WhiteboardCanvasReuseCandidate { - readonly input: object; - readonly readyInput: object | undefined; - readonly model: object; - readonly renderedModel: object | null; - readonly modelState: "active" | "completed" | "unavailable"; -} - -export interface WhiteboardCanvasScrollSnapshot { - readonly input: object; - readonly model: object; - readonly scrollTop: number; -} - -function captureWhiteboardCanvasScrollSnapshot( - input: object, - model: { readonly state: "active" | "completed" | "unavailable" }, - document: Document, -): WhiteboardCanvasScrollSnapshot | undefined { - if (model.state !== "active") return undefined; - const region = document.querySelector(".whiteboard-view-region"); - if (!region) return undefined; - return { input, model, scrollTop: region.scrollTop }; -} - -export function preserveWhiteboardCanvasScrollSnapshot( - pending: WhiteboardCanvasScrollSnapshot | undefined, - input: object, - model: { readonly state: "active" | "completed" | "unavailable" }, - document: Document, -): WhiteboardCanvasScrollSnapshot | undefined { - return pending?.input === input && pending.model === model - ? pending - : captureWhiteboardCanvasScrollSnapshot(input, model, document); -} - -export function canRestoreWhiteboardCanvasScrollSnapshot( - snapshot: WhiteboardCanvasScrollSnapshot | undefined, - candidate: { - readonly input: object; - readonly model: object; - readonly modelState: "active" | "completed" | "unavailable"; - }, -): snapshot is WhiteboardCanvasScrollSnapshot { - return ( - candidate.modelState === "active" && - snapshot?.input === candidate.input && - snapshot.model === candidate.model - ); -} - -/** Reuse only the still-ready view owned by this exact input and model. */ -export function canReuseWhiteboardCanvas( - candidate: WhiteboardCanvasReuseCandidate, -): boolean { - return ( - candidate.modelState === "active" && - candidate.input === candidate.readyInput && - candidate.model === candidate.renderedModel - ); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardChangedFilesModel.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardChangedFilesModel.ts deleted file mode 100644 index 2b533c59c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardChangedFilesModel.ts +++ /dev/null @@ -1,94 +0,0 @@ -import type { WhiteboardDiffFileWire } from "./whiteboardProtocol.js"; - -export interface ChangedFileElement { - readonly kind: "file"; - readonly file: WhiteboardDiffFileWire; - readonly name: string; -} - -export interface ChangedFolderElement { - readonly kind: "folder"; - readonly name: string; - readonly path: string; - readonly children: ChangedTreeElement[]; -} - -export type ChangedTreeElement = ChangedFileElement | ChangedFolderElement; - -interface MutableFolder { - readonly name: string; - readonly path: string; - readonly folders: Map; - readonly files: ChangedFileElement[]; -} - -/** Returns changed files in the same folder-first order that the tree shows. */ -export function orderWhiteboardDiffFiles( - files: readonly WhiteboardDiffFileWire[], -): readonly WhiteboardDiffFileWire[] { - const ordered: WhiteboardDiffFileWire[] = []; - collectFiles(buildTree(files), ordered); - return ordered; -} - -export function buildTree( - files: readonly WhiteboardDiffFileWire[], -): ChangedTreeElement[] { - const root: MutableFolder = { - name: "", - path: "", - folders: new Map(), - files: [], - }; - - for (const file of files) { - const segments = file.path.split("/").filter(Boolean); - const name = segments.pop() ?? file.path; - let folder = root; - for (const segment of segments) { - const path = folder.path ? `${folder.path}/${segment}` : segment; - let child = folder.folders.get(segment); - if (!child) { - child = { - name: segment, - path, - folders: new Map(), - files: [], - }; - folder.folders.set(segment, child); - } - folder = child; - } - folder.files.push({ kind: "file", file, name }); - } - - return folderChildren(root); -} - -function folderChildren(folder: MutableFolder): ChangedTreeElement[] { - const folders = [...folder.folders.values()] - .map((child): ChangedFolderElement => ({ - kind: "folder", - name: child.name, - path: child.path, - children: folderChildren(child), - })) - .sort((left, right) => left.name.localeCompare(right.name)); - const files = [...folder.files].sort((left, right) => - left.name.localeCompare(right.name), - ); - return [...folders, ...files]; -} - -function collectFiles( - elements: readonly ChangedTreeElement[], - target: WhiteboardDiffFileWire[], -): void { - for (const element of elements) { - if (element.kind === "file") { - target.push(element.file); - } else { - collectFiles(element.children, target); - } - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardChrome.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardChrome.ts deleted file mode 100644 index 7d2d3a87a..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardChrome.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * The height of the one Review chrome row, in CSS pixels. - * - * Review draws the titlebar as an overlay on the editor tab strip, so one - * height controls three things that must agree: the titlebar part, the macOS - * window controls, and the editor tab strip. 40px is a 28px tab pill plus 6px - * of padding above it and 6px below it. - * - * KEEP IN SYNC WITH: - * - `.whiteboard-chrome-overlay` and the pill metrics in - * `review/browser/media/whiteboard.css`. - * - `EditorTabsControl.EDITOR_TAB_HEIGHT.review` in - * `workbench/browser/parts/editor/editorTabsControl.ts`. - */ -export const WHITEBOARD_CHROME_HEIGHT = 40; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCliInstallStartup.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCliInstallStartup.test.ts deleted file mode 100644 index 7cf3c9d50..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCliInstallStartup.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import type { WhiteboardCliInstallStatus } from './whiteboardProtocol.js'; -import { whiteboardCliInstallStartupAction } from './whiteboardCliInstallStartup.js'; - -const base: WhiteboardCliInstallStatus = { - fingerprint: 'f', - stamp: null, - stale: false, - updateNeeded: false, - shim: { path: '/p', installed: true, profileConfigured: true, onPath: true }, - trace: { enabled: false, configured: false, autoActivateRepositories: false, envPath: '/e', settingsPath: '/s' }, - cli: null, - connect: { command: 'whiteboard', args: ['mcp'], prompts: { claude: '', codex: '', cursor: '', opencode: '', pi: '' }, plugins: { claude: { label: 'c' }, codex: { label: 'c' }, cursor: { label: 'c' }, opencode: { label: 'c' }, pi: { label: 'c' } } }, - legacySkills: [], -}; - -test('opens Welcome for an upgrader before resyncing', () => { - assert.equal( - whiteboardCliInstallStartupAction({ ...base, stamp: { consent: 'granted', updatedAt: 't' }, updateNeeded: true, stale: true }), - 'openWelcome', - ); -}); - -test('resyncs a stale stamp', () => { - assert.equal( - whiteboardCliInstallStartupAction({ ...base, stamp: { consent: 'granted', updatedAt: 't' }, stale: true }), - 'resync', - ); -}); - -test('does nothing when declined', () => { - assert.equal( - whiteboardCliInstallStartupAction({ ...base, stamp: { consent: 'declined', updatedAt: 't' }, stale: true }), - 'none', - ); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCliInstallStartup.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCliInstallStartup.ts deleted file mode 100644 index 75751015e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCliInstallStartup.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type { WhiteboardCliInstallStatus } from './whiteboardProtocol.js'; - -export type WhiteboardCliInstallStartupAction = 'none' | 'resync' | 'openWelcome'; - -/** - * What a built app does with the install stamp at startup. Only a granted - * stamp acts: an upgrader without the update marker sees the update screen, - * and a stale fingerprint rewrites the whiteboard command silently. - */ -export function whiteboardCliInstallStartupAction(status: WhiteboardCliInstallStatus): WhiteboardCliInstallStartupAction { - if (status.stamp?.consent !== 'granted') { - return 'none'; - } - if (status.updateNeeded) { - return 'openWelcome'; - } - return status.stale ? 'resync' : 'none'; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCommandPalette.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCommandPalette.test.ts deleted file mode 100644 index eeced8f8e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCommandPalette.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import { whiteboardCommandPaletteLabel } from './whiteboardCommandPalette.js'; - -test('uses the human-readable command title', () => { - assert.equal( - whiteboardCommandPaletteLabel('whiteboard.installCliInPath', { - title: { value: 'Review: Install CLI in PATH', original: 'Review: Install CLI in PATH' }, - }), - 'Review: Install CLI in PATH', - ); -}); - -test('includes a command category and removes icons', () => { - assert.equal( - whiteboardCommandPaletteLabel('extension.command', { - title: '$(zap) Run', - category: { value: 'Extension', original: 'Extension' }, - }), - 'Extension: Run', - ); -}); - -test('falls back to the command id when metadata is unavailable', () => { - assert.equal(whiteboardCommandPaletteLabel('internal.command', undefined), 'internal.command'); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCommandPalette.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCommandPalette.ts deleted file mode 100644 index 36d39f75e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardCommandPalette.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { stripIcons } from '../../base/common/iconLabels.js'; -import { localize } from '../../nls.js'; -import type { ICommandAction } from '../../platform/action/common/action.js'; - -type CommandLabel = Pick; - -export function whiteboardCommandPaletteLabel(commandId: string, command: CommandLabel | undefined): string { - if (!command) { - return commandId; - } - - let label = typeof command.title === 'string' ? command.title : command.title.value; - const category = typeof command.category === 'string' ? command.category : command.category?.value; - if (category) { - label = localize('review.commandWithCategory', "{0}: {1}", category, label); - } - - return stripIcons(label) || commandId; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfiguration.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfiguration.ts deleted file mode 100644 index 26577b80c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfiguration.ts +++ /dev/null @@ -1,60 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Registers Review's configuration with the workbench. - * - * Importing this module pulls in the configuration registry, which constructs - * itself — and localizes — at module scope. That makes it unsafe anywhere the - * Electron main process can reach before `bootstrapESM()`; see the header of - * `whiteboardConfigurationDefaults.ts`. Renderer code reaches it through the bare - * side-effect import in `whiteboard.common.main.ts`. - * - * The setting keys and default values live in `whiteboardConfigurationDefaults.ts` - * and are deliberately *not* re-exported from here: a re-export would let a - * main-process consumer import data through this module and put the registry - * back on its import path. - */ -import { localize } from '../../nls.js'; -import { Registry } from '../../platform/registry/common/platform.js'; -import { ConfigurationScope, Extensions, type IConfigurationRegistry } from '../../platform/configuration/common/configurationRegistry.js'; -import { WHITEBOARD_KEYMAPS, WHITEBOARD_KEYMAP_SETTING, WHITEBOARD_SOFTWARE_MAP_SETTING, WHITEBOARD_STRUCTURAL_DIFF_SETTING, WHITEBOARD_TELEMETRY_SETTING, curatedExtensionConfigurationDefaults, whiteboardConfigurationDefaults } from './whiteboardConfigurationDefaults.js'; - -const configurationRegistry = Registry.as(Extensions.Configuration); - -configurationRegistry.registerConfiguration({ - id: 'whiteboard', - title: localize('whiteboardConfigurationTitle', "Whiteboard"), - type: 'object', - scope: ConfigurationScope.APPLICATION, - properties: { - [WHITEBOARD_KEYMAP_SETTING]: { - type: 'string', - enum: [...WHITEBOARD_KEYMAPS], - default: 'none', - description: localize('whiteboard.keymap', "Select the curated keymap extension Whiteboard enables."), - }, - [WHITEBOARD_TELEMETRY_SETTING]: { - type: 'boolean', - default: true, - description: localize('whiteboard.telemetry.enabled', "Send anonymous Whiteboard usage data."), - }, - [WHITEBOARD_STRUCTURAL_DIFF_SETTING]: { - type: 'boolean', - default: true, - description: localize('whiteboard.experimental.structuralDiff.enabled', "Replace the standard diff view with structural diffs from diffr."), - }, - [WHITEBOARD_SOFTWARE_MAP_SETTING]: { - type: 'boolean', - default: false, - description: localize('whiteboard.experimental.softwareMap.enabled', "Show the experimental Software Map view in sessions."), - }, - }, -}); - -configurationRegistry.registerDefaultConfigurations([ - { overrides: whiteboardConfigurationDefaults }, - { overrides: curatedExtensionConfigurationDefaults } -]); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.test.ts deleted file mode 100644 index 6fc04e51b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import { whiteboardConfigurationDefaults } from './whiteboardConfigurationDefaults.js'; - -test('turns off diff indicators for the indicator-free visual language', () => { - assert.equal(whiteboardConfigurationDefaults['diffEditor.renderIndicators'], false); -}); - -test('keeps the VSCodium-derived opt-out defaults', () => { - assert.equal(whiteboardConfigurationDefaults['telemetry.telemetryLevel'], 'off'); - assert.equal(whiteboardConfigurationDefaults['telemetry.enableTelemetry'], false); - assert.equal(whiteboardConfigurationDefaults['telemetry.enableCrashReporter'], false); - assert.equal(whiteboardConfigurationDefaults['telemetry.editStats.enabled'], false); - assert.equal(whiteboardConfigurationDefaults['workbench.enableExperiments'], false); - assert.equal( - whiteboardConfigurationDefaults['workbench.commandPalette.experimental.enableNaturalLanguageSearch'], - false, - ); - assert.equal(whiteboardConfigurationDefaults['workbench.settings.enableNaturalLanguageSearch'], false); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.ts deleted file mode 100644 index a3f6520eb..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.ts +++ /dev/null @@ -1,139 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Review's configuration data: setting keys and default values, with no imports - * and no side effects. - * - * This module is deliberately import-free. `vs/review/node/reviewUserConfigImport.ts` - * reads these keys from the Electron main process, which `src/main.ts` reaches - * before `startup()` calls `bootstrapESM()` — the step that installs - * `globalThis._VSCODE_NLS_MESSAGES`. Anything imported here is evaluated inside - * that pre-bootstrap window, where a packaged build's mangled `localize(2488, null)` - * throws `!!! NLS MISSING: 2488 !!!` into a modal, before any window or log exists. - * - * Registration lives in `reviewConfiguration.ts`, which imports this file and owns - * the configuration-registry calls. Never add an import here, and never re-export - * these values from `reviewConfiguration.ts` — a re-export would put the - * configuration registry back on the main process's import path. - * - * Enforced by `scripts/main-bootstrap-imports.test.mjs`. - */ - -export const WHITEBOARD_KEYMAP_SETTING = 'whiteboard.keymap'; -export const WHITEBOARD_TELEMETRY_SETTING = 'whiteboard.telemetry.enabled'; -export const WHITEBOARD_STRUCTURAL_DIFF_SETTING = 'whiteboard.experimental.structuralDiff.enabled'; -export const WHITEBOARD_SOFTWARE_MAP_SETTING = 'whiteboard.experimental.softwareMap.enabled'; -export const WHITEBOARD_KEYMAPS = ['none', 'vim', 'emacs'] as const; -export type WhiteboardKeymap = typeof WHITEBOARD_KEYMAPS[number]; - -export const whiteboardConfigurationDefaults = { - [WHITEBOARD_SOFTWARE_MAP_SETTING]: false, - [WHITEBOARD_STRUCTURAL_DIFF_SETTING]: true, - [WHITEBOARD_TELEMETRY_SETTING]: true, - 'telemetry.telemetryLevel': 'off', - 'telemetry.enableTelemetry': false, - 'telemetry.enableCrashReporter': false, - 'telemetry.editStats.enabled': false, - 'security.workspace.trust.enabled': false, - 'workbench.enableExperiments': false, - 'workbench.commandPalette.experimental.enableNaturalLanguageSearch': false, - 'workbench.settings.enableNaturalLanguageSearch': false, - 'window.autoDetectColorScheme': true, - 'workbench.colorTheme': 'Whiteboard Dark', - 'workbench.preferredDarkColorTheme': 'Whiteboard Dark', - 'workbench.preferredLightColorTheme': 'Whiteboard Light', - 'workbench.startupEditor': 'none', - 'workbench.activityBar.location': 'hidden', - 'workbench.statusBar.visible': false, - 'window.title': 'Whiteboard', - 'window.commandCenter': false, - 'workbench.navigationControl.enabled': true, - 'window.menuBarVisibility': 'hidden', - 'workbench.editor.showTabs': 'multiple', - 'workbench.editor.editorActionsLocation': 'hidden', - // Reduce tab widths when the row fills. The native tab control truncates the - // labels first. It keeps horizontal scrolling after tabs reach their minimum. - 'workbench.editor.tabSizing': 'shrink', - // Keep wheel, trackpad, keyboard, and active-tab scrolling. Hide only the - // scrollbar, which would otherwise sit across the bottom of the pill row. - 'workbench.editor.titleScrollbarVisibility': 'hidden', - // Home is the only sticky editor in Review. "compact" makes a sticky tab show - // its icon alone, so the Home pill lost its name. "normal" shows the home - // icon and the word "Home". - 'workbench.editor.pinnedTabSizing': 'normal', - // A sticky tab shows an unpin button in place of its close button. Home is - // always sticky and the reader cannot unpin it, so the button is dead chrome. - 'workbench.editor.tabActionUnpinVisibility': false, - 'workbench.layoutControl.enabled': false, - // Diffs and code peeks are Monaco editors, and Monaco takes its font from - // this setting rather than from CSS. Geist Mono is bundled with the canvas - // stylesheet (its @font-face rules are hoisted out of the canvas scope), so - // the editors share the chrome and code face of the whiteboard design. The - // tail is Monaco's own macOS default stack. - 'editor.fontFamily': '"Geist Mono", Menlo, Monaco, "Courier New", monospace', - 'editor.minimap.enabled': false, - 'diffEditor.renderIndicators': false, - 'breadcrumbs.enabled': false, - 'git.enabled': false, - // Retain read-only protection when opening a legacy Review-owned checkout. - // New review sources use immutable virtual documents; LSP targets are local files. - 'files.readonlyInclude': { '/**/.git/dev-fast/worktrees/**': true }, - // Keep read-only badges from crowding Review's compact file tabs. - 'workbench.editor.decorations.badges': false, - 'chat.disableAIFeatures': true, - 'extensions.ignoreRecommendations': true, - 'workbench.tips.enabled': false -} as const; - -/** - * Defaults that keep the curated built-in extensions quiet. - * - * Review ships no marketplace, so an extension that prompts to install or update - * something offers the reader a dead end. Every key here closes one such prompt. - * Keep this aligned with the curated groups in - * `scripts/curated-extensions.manifest.mjs`, whose contract test is - * `scripts/curated-extensions.test.mjs`. - */ -export const curatedExtensionConfigurationDefaults = { - // ms-python.python resolves the "Default" language server to Pylance, which is - // proprietary and can never ship here, then prompts to install it. ty is - // Review's Python language server and ignores this setting. - 'python.languageServer': 'None', - // Fetches A/B experiment payloads and prompts into them. - 'python.experiments.enabled': false, - // "Do you want to create a virtual environment?" on requirements.txt. - 'python.createEnvironment.trigger': 'off', - // "Configure a test framework?" on test files. - 'python.testing.promptToConfigure': false, - - // golang.go asks users to fill in a survey on a timer. - 'go.survey.prompt': false, - // Prompts to `go install` newer tools against a toolchain Review does not ship. - 'go.toolsManagement.checkForUpdates': 'off', - - // "This file is not linked to a Cargo project" — routine when the review is - // scoped to a subdirectory of a workspace. - 'rust-analyzer.showUnlinkedFileNotification': false, - 'rust-analyzer.notifications.cargoTomlNotFound': false, - 'rust-analyzer.showRequestFailedErrorNotification': false, - - // The Swift extension can offer to install Swiftly. Review uses the Swift - // toolchain that the user installed and made available on the shell PATH. - 'swift.disableSwiftlyInstallPrompt': true, - - // The .NET support extension must not send its own telemetry or expose AI - // tools. C# uses the system .NET SDK that Review resolves from the shell PATH. - 'dotnetAcquisitionExtension.enableTelemetry': false, - 'dotnetAcquisitionExtension.enableLanguageModelTools': false - - // charliermarsh.ruff already defaults `ruff.showNotifications` to "off". - // astral-sh.ty, vscodevim.vim and tuttieee.emacs-mcx contribute no prompts. -} as const; - -export const whiteboardAgentsWindowDefaultOverrides = { - 'window.title': whiteboardConfigurationDefaults['window.title'], - 'workbench.navigationControl.enabled': whiteboardConfigurationDefaults['workbench.navigationControl.enabled'], -} as const; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardDesktopBootstrap.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardDesktopBootstrap.test.ts deleted file mode 100644 index b766df6f8..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardDesktopBootstrap.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import { - WHITEBOARD_DESKTOP_CONNECTION_VERSION, - WhiteboardReadyEventReader, -} from './whiteboardDesktopBootstrap.js'; - -const credentials = { - token: 'token', - instanceId: 'instance', -}; - -test('carries the install id from the ready message', () => { - const reader = new WhiteboardReadyEventReader(credentials); - const connection = reader.push(`${JSON.stringify({ - event: 'ready', - version: WHITEBOARD_DESKTOP_CONNECTION_VERSION, - url: 'http://127.0.0.1:4321', - ...credentials, - installationId: 'install-123', - })}\n`); - - assert.equal(connection?.installationId, 'install-123'); -}); - -test('accepts an older ready message without an install id', () => { - const reader = new WhiteboardReadyEventReader(credentials); - const connection = reader.push(`${JSON.stringify({ - event: 'ready', - version: WHITEBOARD_DESKTOP_CONNECTION_VERSION, - url: 'http://127.0.0.1:4321', - ...credentials, - })}\n`); - - assert.equal(connection?.installationId, undefined); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardDesktopBootstrap.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardDesktopBootstrap.ts deleted file mode 100644 index 776834dac..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardDesktopBootstrap.ts +++ /dev/null @@ -1,164 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * The Whiteboard server runs in a utility process and announces the endpoint it - * bound as a single newline-delimited JSON object on stdout. The main process - * is the only party that knows the credentials it generated, so it validates - * that announcement here before handing a connection to any renderer. - */ -// Hand-maintained twin of WHITEBOARD_DESKTOP_DISCOVERY_VERSION in -// @dev.fast/whiteboard-protocol. Version 3: the desktop serves prebuilt -// revisions instead of building them. -export const WHITEBOARD_DESKTOP_CONNECTION_VERSION = 3; - -/** Main-process IPC channel the renderer asks for that endpoint on. */ -export const WHITEBOARD_DESKTOP_CHANNEL = "review"; - -export interface WhiteboardDesktopConnection { - readonly version: number; - readonly url: string; - readonly token: string; - readonly instanceId: string; - readonly installationId?: string; - readonly cliPath?: string; - readonly cliVersion?: string; -} - -export interface WhiteboardDesktopCredentials { - readonly token: string; - readonly instanceId: string; -} - -/** - * The Review runtime is staged inside the application bundle at packaging time - * so an installed app never reaches back into a development checkout. - */ -const WHITEBOARD_RUNTIME_SERVER_ENTRY = - "review-runtime/dist/server/desktop-host.js"; - -/** - * Resolves the server entry point. A development checkout may point at its own - * build output, but a packaged app must only ever use the runtime staged inside - * the bundle: honouring an environment override there would let an installed - * app be pointed at arbitrary code. - */ -export function resolveWhiteboardServerEntry(input: { - readonly isBuilt: boolean; - readonly appRoot: string; - readonly serverEntryOverride?: string | undefined; - readonly join?: (...segments: string[]) => string; -}): string { - const join = input.join ?? ((...segments) => segments.join("/")); - if (!input.isBuilt && input.serverEntryOverride) { - return input.serverEntryOverride; - } - return join(input.appRoot, WHITEBOARD_RUNTIME_SERVER_ENTRY); -} - -export class WhiteboardReadyEventReader { - private buffer = ""; - private done = false; - - constructor(private readonly credentials: WhiteboardDesktopCredentials) {} - - /** - * Feeds a stdout chunk and returns the connection once the ready event has - * been seen. Lines that are not the ready event are server logs and are - * ignored; a ready event that fails validation throws immediately so startup - * fails with a real reason instead of stalling until the readiness timeout. - */ - push(chunk: string): WhiteboardDesktopConnection | undefined { - if (this.done) return undefined; - this.buffer += chunk; - let newline = this.buffer.indexOf("\n"); - while (newline !== -1) { - const line = this.buffer.slice(0, newline).trim(); - this.buffer = this.buffer.slice(newline + 1); - const connection = this.readLine(line); - if (connection) { - this.done = true; - this.buffer = ""; - return connection; - } - newline = this.buffer.indexOf("\n"); - } - return undefined; - } - - private readLine(line: string): WhiteboardDesktopConnection | undefined { - if (!line.startsWith("{")) return undefined; - let parsed: unknown; - try { - parsed = JSON.parse(line); - } catch { - return undefined; - } - if (!isRecord(parsed) || parsed["event"] !== "ready") return undefined; - return this.validate(parsed); - } - - private validate(event: Record): WhiteboardDesktopConnection { - const version = event["version"]; - if (version !== WHITEBOARD_DESKTOP_CONNECTION_VERSION) { - throw new Error( - `The Whiteboard server announced an unsupported discovery version: ${String(version)}.`, - ); - } - const url = event["url"]; - const token = event["token"]; - const instanceId = event["instanceId"]; - if ( - typeof url !== "string" || - typeof token !== "string" || - typeof instanceId !== "string" - ) { - throw new Error("The Whiteboard server ready event is malformed."); - } - if ( - token !== this.credentials.token || - instanceId !== this.credentials.instanceId - ) { - throw new Error( - "The Whiteboard server ready event carried unexpected credentials.", - ); - } - const cliPath = event["cliPath"]; - const cliVersion = event["cliVersion"]; - const installationId = event["installationId"]; - return { - version: WHITEBOARD_DESKTOP_CONNECTION_VERSION, - url: loopbackOrigin(url), - token, - instanceId, - ...(typeof installationId === "string" && installationId - ? { installationId } - : {}), - ...(typeof cliPath === "string" && cliPath ? { cliPath } : {}), - ...(typeof cliVersion === "string" && cliVersion ? { cliVersion } : {}), - }; - } -} - -function loopbackOrigin(value: string): string { - let url: URL; - try { - url = new URL(value); - } catch { - throw new Error( - `The Whiteboard server must listen on http loopback, got ${value}.`, - ); - } - if (url.protocol !== "http:" || url.hostname !== "127.0.0.1" || !url.port) { - throw new Error( - `The Whiteboard server must listen on http loopback, got ${value}.`, - ); - } - return url.origin; -} - -function isRecord(value: unknown): value is Record { - return typeof value === "object" && value !== null && !Array.isArray(value); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardErrorReport.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardErrorReport.test.ts deleted file mode 100644 index 111a024ed..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardErrorReport.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { CancellationError, ErrorNoTelemetry } from "../../base/common/errors.js"; -import { - packWhiteboardError, - WhiteboardErrorReportLimiter, - type WhiteboardErrorReport, -} from "./whiteboardErrorReport.js"; - -function errorWithStack(message: string): Error { - const error = new TypeError(message); - error.stack = `TypeError: ${message}\n at f (/app/out/vs/whiteboard/browser/workbench.js:1:1)`; - return error; -} - -test("packWhiteboardError keeps the name, message, and stack", () => { - const packed = packWhiteboardError(errorWithStack("boom")); - assert.equal(packed?.name, "TypeError"); - assert.equal(packed?.message, "boom"); - assert.match(packed?.stack ?? "", /workbench\.js:1:1/); -}); - -test("packWhiteboardError skips errors that say nothing about a defect", () => { - assert.equal(packWhiteboardError(undefined), undefined); - assert.equal(packWhiteboardError("boom"), undefined); - assert.equal(packWhiteboardError({ name: "Error", message: "no stack" }), undefined); - const systemError = errorWithStack("EACCES") as Error & { code?: string }; - systemError.code = "EACCES"; - assert.equal(packWhiteboardError(systemError), undefined); - const noTelemetry = new ErrorNoTelemetry("private"); - noTelemetry.stack = "CodeExpectedError\n at f (/app/out/vs/base/common/errors.js:1:1)"; - assert.equal(packWhiteboardError(noTelemetry), undefined); - const cancelled = new CancellationError(); - cancelled.stack = "Canceled\n at f (/app/out/vs/base/common/errors.js:1:1)"; - assert.equal(packWhiteboardError(cancelled), undefined); -}); - -test("packWhiteboardError unwraps a loader error and an array stack", () => { - const packed = packWhiteboardError({ - detail: { name: "SyntaxError", message: "bad", stack: ["SyntaxError: bad", " at f (/app/out/vs/code/x.js:2:2)"] }, - }); - assert.equal(packed?.name, "SyntaxError"); - assert.match(packed?.stack ?? "", /vs\/code\/x\.js:2:2/); -}); - -test("the limiter removes an immediate repeat but allows it later", () => { - let now = 1000; - const limiter = new WhiteboardErrorReportLimiter(30, () => now); - const sent: WhiteboardErrorReport[] = []; - const send = (report: WhiteboardErrorReport): void => { sent.push(report); }; - - limiter.report(errorWithStack("boom"), send); - limiter.report(errorWithStack("boom"), send); - assert.equal(sent.length, 1); - - now += 1001; - limiter.report(errorWithStack("boom"), send); - assert.equal(sent.length, 2); -}); - -test("the limiter caps a session and never lets a report raise an error", () => { - let now = 0; - const limiter = new WhiteboardErrorReportLimiter(3, () => (now += 5000)); - let sent = 0; - for (let index = 0; index < 10; index++) { - limiter.report(errorWithStack(`boom ${index}`), () => { sent++; }); - } - assert.equal(sent, 3); - - const guarded = new WhiteboardErrorReportLimiter(30, () => 0); - assert.doesNotThrow(() => { - guarded.report(errorWithStack("boom"), () => { throw new Error("reporting failed"); }); - }); -}); - -test("the limiter refuses to run inside itself", () => { - const limiter = new WhiteboardErrorReportLimiter(30, () => 0); - let depth = 0; - limiter.report(errorWithStack("outer"), () => { - depth++; - limiter.report(errorWithStack("inner"), () => { depth++; }); - }); - assert.equal(depth, 1); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardErrorReport.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardErrorReport.ts deleted file mode 100644 index e3511d94b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardErrorReport.ts +++ /dev/null @@ -1,116 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationError, ErrorNoTelemetry } from "../../base/common/errors.js"; - -/** - * Shared error reporting rules for the Review workbench and the Review part of - * the Electron main process. - * - * The raw name, message, and stack packed here travel only to the loopback - * Whiteboard server on the same machine. That server replaces the message with a - * digest and keeps only the stack frames that resolve inside the shipped - * bundle; see packages/whiteboard/src/error-telemetry.ts. Nothing in - * this file is ever sent to a vendor as it stands. - * - * The filters mirror upstream `BaseErrorTelemetry._onErrorEvent`. They are - * reimplemented rather than imported because that module pulls the whole file - * service in behind it, and this one runs in the main process too. - */ - -export interface WhiteboardErrorReport { - readonly name: string; - readonly message: string; - readonly stack: string; -} - -/** - * Unwrap a loader error, then decide whether it is worth reporting. Errors with - * a system `code`, cancellations, errors marked as never-report, and errors - * without a stack are all skipped: none of them says anything about a defect in - * Review. - */ -export function packWhiteboardError(error: unknown): WhiteboardErrorReport | undefined { - if (!error || typeof error !== 'object') { - return undefined; - } - let candidate = error as { code?: unknown; detail?: { stack?: unknown }; name?: unknown; message?: unknown; stack?: unknown }; - if (candidate.code) { - return undefined; - } - // Unwrap nested errors from the module loader, as upstream does. - if (candidate.detail && (candidate.detail as { stack?: unknown }).stack) { - candidate = candidate.detail as typeof candidate; - } - if (ErrorNoTelemetry.isErrorNoTelemetry(candidate as Error) || candidate instanceof CancellationError) { - return undefined; - } - // Array stacks come from workerServer.ts; upstream works around this too. - const stack = Array.isArray(candidate.stack) ? candidate.stack.join('\n') : candidate.stack; - if (typeof stack !== 'string' || stack.length === 0) { - return undefined; // an error without a stack is not useful telemetry - } - return { - name: typeof candidate.name === 'string' ? candidate.name : 'Error', - message: typeof candidate.message === 'string' ? candidate.message : '', - stack, - }; -} - -/** - * Keeps error reporting from becoming its own incident: it removes bursts of - * one repeating error, bounds the total per session, and refuses to run inside - * itself when reporting an error throws another one. - */ -export class WhiteboardErrorReportLimiter { - private static readonly REPEAT_WINDOW_MS = 1000; - - private previousKey: string | undefined; - private previousTime = 0; - private reported = 0; - private reporting = false; - - constructor( - private readonly maxPerSession = 30, - private readonly now: () => number = () => Date.now(), - ) { } - - /** - * Pack the error, decide whether it is worth reporting, and hand it to - * `send`. Re-entry is blocked, so an error raised inside `send` cannot start - * a second report, and nothing here ever throws: the callers sit on the - * error path itself, where a throw would escape into unrelated code. - */ - report(error: unknown, send: (report: WhiteboardErrorReport) => void): void { - if (this.reporting) { - return; - } - this.reporting = true; - try { - if (this.reported >= this.maxPerSession) { - return; - } - const packed = packWhiteboardError(error); - if (!packed || this.isRepeat(packed)) { - return; - } - this.reported++; - send(packed); - } catch { - // Reporting an error must never raise one. - } finally { - this.reporting = false; - } - } - - private isRepeat(report: WhiteboardErrorReport): boolean { - const key = `${report.name}\n${report.stack.split('\n', 2).join('\n')}`; - const time = this.now(); - const repeat = key === this.previousKey && time - this.previousTime <= WhiteboardErrorReportLimiter.REPEAT_WINDOW_MS; - this.previousKey = key; - this.previousTime = time; - return repeat; - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardEventStream.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardEventStream.ts deleted file mode 100644 index dea7bc0cf..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardEventStream.ts +++ /dev/null @@ -1,109 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createParser } from "eventsource-parser"; - -import { type JsonValue, parseJsonText } from "./whiteboardProtocol.js"; - -const DEFAULT_MAX_EVENT_CHARACTERS = 1024 * 1024; -const EVENT_BOUNDARY = /(?:\r\n|\r|\n)(?:\r\n|\r|\n)/g; - -export interface ConsumeWhiteboardEventStreamOptions { - readonly maxEventCharacters?: number; -} - -export async function consumeWhiteboardEventStream( - stream: ReadableStream, - onValue: (value: JsonValue) => void | Promise, - signal: AbortSignal, - options: ConsumeWhiteboardEventStreamOptions = {}, -): Promise { - const maxEventCharacters = - options.maxEventCharacters ?? DEFAULT_MAX_EVENT_CHARACTERS; - if (!Number.isSafeInteger(maxEventCharacters) || maxEventCharacters <= 0) { - throw new Error("maxEventCharacters must be a positive safe integer."); - } - - const reader = stream.getReader(); - const decoder = new TextDecoder(); - const sizeGuard = new IncompleteEventSizeGuard(maxEventCharacters); - const pendingPayloads: string[] = []; - const parser = createParser({ - onEvent: (event) => pendingPayloads.push(event.data), - onError: (error) => console.error(error), - }); - - const feed = (chunk: string): void => { - sizeGuard.push(chunk); - parser.feed(chunk); - }; - const drain = async (): Promise => { - while (pendingPayloads.length > 0) { - const payload = pendingPayloads.shift(); - if (payload === undefined) continue; - try { - await onValue(parseJsonText(payload)); - } catch (error) { - console.error(error); - } - } - }; - const cancelReader = (): void => { - void reader.cancel().catch(() => undefined); - }; - - signal.addEventListener("abort", cancelReader, { once: true }); - try { - while (!signal.aborted) { - const { value, done } = await reader.read(); - if (done) { - const trailing = decoder.decode(); - if (trailing) feed(trailing); - feed("\n\n"); - parser.reset(); - await drain(); - return; - } - - const decoded = decoder.decode(value, { stream: true }); - if (decoded) feed(decoded); - await drain(); - } - } finally { - signal.removeEventListener("abort", cancelReader); - await reader.cancel().catch(() => undefined); - } -} - -class IncompleteEventSizeGuard { - private unfinishedEvent = ""; - - constructor(private readonly maximum: number) {} - - push(chunk: string): void { - this.unfinishedEvent += chunk; - EVENT_BOUNDARY.lastIndex = 0; - - let eventStart = 0; - for ( - let match = EVENT_BOUNDARY.exec(this.unfinishedEvent); - match; - match = EVENT_BOUNDARY.exec(this.unfinishedEvent) - ) { - this.assertWithinLimit(match.index - eventStart); - eventStart = EVENT_BOUNDARY.lastIndex; - } - - this.unfinishedEvent = this.unfinishedEvent.slice(eventStart); - this.assertWithinLimit(this.unfinishedEvent.length); - } - - private assertWithinLimit(length: number): void { - if (length <= this.maximum) return; - throw new Error( - `Whiteboard event exceeded ${this.maximum} characters before its terminator.`, - ); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardFirstRunReload.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardFirstRunReload.ts deleted file mode 100644 index 0c9d0b7c1..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardFirstRunReload.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Registry } from '../../platform/registry/common/platform.js'; -import { Extensions as WorkbenchExtensions, type IWorkbenchContributionsRegistry } from '../../workbench/common/contributions.js'; - -/** - * Seeding the keymap defaults reloads the window once on a fresh profile - * (whiteboardCuratedExtensions.contribution.ts). A startup prompt must skip itself - * when that reload is coming: the reload takes both the question and the - * answer with it, and a storage write after the shutdown close is dropped. - */ - -let pending: boolean | undefined; - -export function setFirstRunReloadPending(reloadPending: boolean): void { - pending = reloadPending; -} - -/** Resolves once the seeder has decided; a seeder that never ran means no reload. */ -export async function isFirstRunReloadPending(): Promise { - if (pending === undefined) { - await Registry.as(WorkbenchExtensions.Workbench).whenRestored; - } - return pending ?? false; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLens.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLens.test.ts deleted file mode 100644 index 03976e5d5..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLens.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import assert from 'node:assert/strict'; -import test from 'node:test'; -import { lensContextGaps } from './whiteboardLens.js'; -import type { IDocumentDiff } from '../../editor/common/diff/documentDiffProvider.js'; - -const plain: IDocumentDiff = { changes: [], moves: [], identical: false, quitEarly: false }; -test('a lens keeps disjoint attachments and hides the intervening code', () => { - const gaps = lensContextGaps(plain, 100, 100, [ - { side: 'head', file: 'a.ts', fromLine: 20, toLine: 22 }, - { side: 'base', file: 'a.ts', fromLine: 70, toLine: 72 }, - ]); - assert.deepEqual(gaps.map(gap => [gap.originalStart, gap.originalCount]), [[1, 16], [26, 41], [76, 25]]); -}); -test('one-sided inserted ranges use correspondence without hiding their opposite context', () => { - const diff = { ...plain, sourceLineAlignment: Array.from({ length: 50 }, (_, i) => [null, i] as const) }; - const gaps = lensContextGaps(diff, 0, 50, [{ side: 'head', file: 'new.ts', fromLine: 20, toLine: 25 }]); - assert.deepEqual(gaps.map(gap => [gap.originalCount, gap.modifiedStart, gap.modifiedCount, gap.change]), [[0, 1, 16, 'inserted'], [0, 29, 22, 'inserted']]); -}); -test('structural folds within the lens survive, overlapping folds do not', () => { - const inside = { originalStart: 20, modifiedStart: 20, originalCount: 3, modifiedCount: 3, label: 'body' }; - const outside = { originalStart: 1, modifiedStart: 1, originalCount: 20, modifiedCount: 20 }; - const gaps = lensContextGaps({ ...plain, contextGaps: [inside, outside] }, 100, 100, [{ side: 'base', file: 'a', fromLine: 18, toLine: 28 }]); - assert.ok(gaps.includes(inside)); - assert.ok(!gaps.includes(outside)); -}); - -test('viewed folds never hide an unread counterpart, and do not overlap structural folds', async () => { - const { viewedContextGaps } = await import('./whiteboardLens.js'); - const range = (side: 'base' | 'head', fromLine: number, toLine: number) => ({ side, file: 'a.ts', fromLine, toLine }); - const changed = [range('base', 3, 5), range('head', 3, 5)]; - assert.deepEqual(viewedContextGaps(plain, 10, 10, [range('head', 3, 5)], changed), []); - const gaps = viewedContextGaps({ ...plain, contextGaps: [{ originalStart: 2, modifiedStart: 2, originalCount: 5, modifiedCount: 5, label: 'body' }] }, 10, 10, changed, changed); - assert.equal(gaps.length, 1); - assert.equal(gaps[0].label, 'Viewed'); - assert.equal(gaps[0].modifiedCount, 3); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLens.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLens.ts deleted file mode 100644 index f1439901f..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLens.ts +++ /dev/null @@ -1,99 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ -import type { IDocumentDiff, IDocumentContextGap } from '../../editor/common/diff/documentDiffProvider.js'; -import type { WhiteboardDiffLens } from './whiteboardProtocol.js'; - -/** Project pinned ranges onto the current diff's correspondence, never onto another revision. */ -export function lensContextGaps(diff: IDocumentDiff, originalCount: number, modifiedCount: number, ranges: WhiteboardDiffLens['ranges']): IDocumentContextGap[] { - const rows = alignmentRows(diff, originalCount, modifiedCount); - const visible = rows.map(row => ranges.some(range => { - const line = row[range.side === 'base' ? 0 : 1]; - return line !== null && line + 1 >= range.fromLine && line + 1 <= range.toLine; - })); - // Context follows alignment rows, keeping both sides synchronized around insertions. - const context = visible.map((_, index) => visible.slice(Math.max(0, index - 3), index + 4).some(Boolean)); - if (diff.contextScopes) { - // A lens must not clip context that diffr kept around its selected code. - // Seed enclosing scope boundaries, then retain each visible context run - // touching a seed. Never expand through a collapsed provider band. - const scopes = [diff.contextScopes.original, diff.contextScopes.modified]; - const enclosing = scopes.map((sideScopes, side) => sideScopes.filter(([start, end]) => - rows.some((row, index) => visible[index] && row[side] !== null && row[side]! >= start && row[side]! < end))); - const open = rows.map(row => row.every((line, side) => line === null || !(diff.contextGaps ?? []).some(gap => { - if (gap.collapsed === false) return false; - const start = side === 0 ? gap.originalStart : gap.modifiedStart; - const count = side === 0 ? gap.originalCount : gap.modifiedCount; - return line + 1 >= start && line + 1 < start + count; - }))); - const seeds = rows.map((row, index) => visible[index] || row.some((line, side) => - line !== null && enclosing[side].some(([start, end]) => line === start || line === end - 1))); - for (let start = 0; start < rows.length;) { - if (!open[start]) { start++; continue; } - let end = start + 1; - while (end < rows.length && open[end]) end++; - if (seeds.slice(start, end).some(Boolean)) context.fill(true, start, end); - start = end; - } - } - const gaps: IDocumentContextGap[] = []; - let left = 1, right = 1; - for (let index = 0; index < rows.length;) { - if (context[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; continue; } - const originalStart = left, modifiedStart = right; - while (index < rows.length && !context[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; } - gaps.push({ - originalStart, modifiedStart, originalCount: left - originalStart, modifiedCount: right - modifiedStart, label: 'Outside lens', breadcrumbs: false, - owner: left === originalStart ? 'head' : right === modifiedStart ? 'base' : 'both', change: gapChange(diff, originalStart, left, modifiedStart, right) - }); - } - // Keep structural folds only when fully within the visible slice; no overlapping bands. - const overlap = (a: IDocumentContextGap, b: IDocumentContextGap) => - (a.originalCount > 0 && b.originalCount > 0 && a.originalStart < b.originalStart + b.originalCount && b.originalStart < a.originalStart + a.originalCount) || - (a.modifiedCount > 0 && b.modifiedCount > 0 && a.modifiedStart < b.modifiedStart + b.modifiedCount && b.modifiedStart < a.modifiedStart + a.modifiedCount); - return [...gaps, ...(diff.contextGaps ?? []).filter(gap => !gaps.some(hidden => overlap(gap, hidden)))].sort((a, b) => a.originalStart - b.originalStart || a.modifiedStart - b.modifiedStart); -} - -export function alignmentRows(diff: IDocumentDiff, originalCount: number, modifiedCount: number): (readonly [number | null, number | null])[] { - const rows: (readonly [number | null, number | null])[] = []; - if (diff.sourceLineAlignment) rows.push(...diff.sourceLineAlignment); - else { - let left = 0, right = 0; - const append = (leftEnd: number, rightEnd: number) => { - while (left < leftEnd || right < rightEnd) rows.push([left < leftEnd ? left++ : null, right < rightEnd ? right++ : null]); - }; - for (const change of diff.changes) { - append(change.original.startLineNumber - 1, change.modified.startLineNumber - 1); - append(change.original.endLineNumberExclusive - 1, change.modified.endLineNumberExclusive - 1); - } - append(originalCount, modifiedCount); - } - return rows; -} - -/** A paired row folds only when none of its changed lines remain unread. */ -export function viewedContextGaps(diff: IDocumentDiff, originalCount: number, modifiedCount: number, viewed: WhiteboardDiffLens['ranges'], changed: WhiteboardDiffLens['ranges']): IDocumentContextGap[] { - const rows = alignmentRows(diff, originalCount, modifiedCount); - const contains = (ranges: WhiteboardDiffLens['ranges'], side: 0 | 1, line: number) => ranges.some(range => range.side === (side === 0 ? 'base' : 'head') && line + 1 >= range.fromLine && line + 1 <= range.toLine); - const hidden = rows.map(row => row.some((line, side) => line !== null && contains(viewed, side as 0 | 1, line)) && row.every((line, side) => line === null || !contains(changed, side as 0 | 1, line) || contains(viewed, side as 0 | 1, line))); - const gaps: IDocumentContextGap[] = []; - let left = 1, right = 1; - for (let index = 0; index < rows.length;) { - if (!hidden[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; continue; } - const originalStart = left, modifiedStart = right; - while (index < rows.length && hidden[index]) { if (rows[index][0] !== null) left++; if (rows[index][1] !== null) right++; index++; } - gaps.push({ originalStart, modifiedStart, originalCount: left - originalStart, modifiedCount: right - modifiedStart, label: 'Viewed', breadcrumbs: false, owner: left === originalStart ? 'head' : right === modifiedStart ? 'base' : 'both', change: gapChange(diff, originalStart, left, modifiedStart, right) }); - } - const overlaps = (a: IDocumentContextGap, b: IDocumentContextGap) => - (a.originalCount > 0 && b.originalCount > 0 && a.originalStart < b.originalStart + b.originalCount && b.originalStart < a.originalStart + a.originalCount) || - (a.modifiedCount > 0 && b.modifiedCount > 0 && a.modifiedStart < b.modifiedStart + b.modifiedCount && b.modifiedStart < a.modifiedStart + a.modifiedCount); - return [...gaps, ...(diff.contextGaps ?? []).filter(gap => !gaps.some(viewed => overlaps(gap, viewed)))].sort((a, b) => a.originalStart - b.originalStart || a.modifiedStart - b.modifiedStart); -} - -/** Lens and viewed folds describe coverage, not a new diff; retain the provider's change status. */ -function gapChange(diff: IDocumentDiff, originalStart: number, originalEnd: number, modifiedStart: number, modifiedEnd: number): NonNullable { - const removed = diff.sourceLineAlignment?.some(([l, r]) => r === null && l !== null && l + 1 >= originalStart && l + 1 < originalEnd) || diff.changes.some(c => originalStart < originalEnd && !c.original.isEmpty && c.original.startLineNumber < originalEnd && c.original.endLineNumberExclusive > originalStart); - const added = diff.sourceLineAlignment?.some(([l, r]) => l === null && r !== null && r + 1 >= modifiedStart && r + 1 < modifiedEnd) || diff.changes.some(c => modifiedStart < modifiedEnd && !c.modified.isEmpty && c.modified.startLineNumber < modifiedEnd && c.modified.endLineNumberExclusive > modifiedStart); - return removed && added ? 'modified' : removed ? 'removed' : added ? 'inserted' : 'unchanged'; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLensFiles.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLensFiles.test.ts deleted file mode 100644 index 813b4babd..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLensFiles.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import assert from 'node:assert/strict'; -import test from 'node:test'; -import { lensFiles } from './whiteboardLensFiles.js'; -import { lensContextGaps } from './whiteboardLens.js'; -import type { WhiteboardDiffFileWire, WhiteboardDiffLens } from './whiteboardProtocol.js'; - -const files: WhiteboardDiffFileWire[] = [{ path: 'renamed.ts', previousPath: 'old.ts', status: 'renamed', additions: 2, deletions: 1 }]; -const lens: WhiteboardDiffLens = { - id: 'lens', title: 'Context', sessionId: 'review', version: 1, ranges: [ - { file: 'old.ts', side: 'base', fromLine: 2, toLine: 5 }, - { file: 'context.ts', side: 'base', fromLine: 10, toLine: 12 }, - { file: 'context.ts', side: 'head', fromLine: 10, toLine: 12 }, - ] -}; - -test('diagram references add each unchanged file once, preserving rename identity', () => { - const result = lensFiles(files, lens); - assert.deepEqual(result, [...files, { path: 'context.ts', status: 'unchanged', additions: 0, deletions: 0 }]); - assert.equal(files.length, 1); -}); - -test('clearing the lens and whole-file glob lenses do not introduce context files', () => { - assert.equal(lensFiles(files), files); - assert.equal(lensFiles(files, { ...lens, wholeFiles: true }), files); -}); - -test('an identical file exposes the referenced slice with three surrounding lines', () => { - const gaps = lensContextGaps({ changes: [], moves: [], identical: true, quitEarly: false }, 30, 30, lens.ranges.filter(range => range.file === 'context.ts')); - assert.deepEqual(gaps.map(gap => [gap.originalStart, gap.originalCount, gap.modifiedStart, gap.modifiedCount]), [[1, 6, 1, 6], [16, 15, 16, 15]]); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLensFiles.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLensFiles.ts deleted file mode 100644 index 2837d55af..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardLensFiles.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { WhiteboardDiffFileWire, WhiteboardDiffLens } from './whiteboardProtocol.js'; - -/** Diagram evidence may provide context outside the comparison's changed-file list. */ -export function lensFiles(files: readonly WhiteboardDiffFileWire[], lens?: WhiteboardDiffLens): readonly WhiteboardDiffFileWire[] { - if (!lens || lens.wholeFiles) return files; - const known = new Set(files.flatMap(file => [file.path, ...(file.previousPath ? [file.previousPath] : [])])); - const context: WhiteboardDiffFileWire[] = []; - for (const range of lens.ranges) { - if (known.has(range.file)) continue; - known.add(range.file); - context.push({ path: range.file, status: 'unchanged', additions: 0, deletions: 0 }); - } - return [...files, ...context]; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardModuleCache.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardModuleCache.test.ts deleted file mode 100644 index de706956c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardModuleCache.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { WhiteboardModuleCache } from "./whiteboardModuleCache.js"; - -test("concurrent loads of one key share a single loader call", async () => { - const cache = new WhiteboardModuleCache(); - let calls = 0; - const loader = async () => { - calls += 1; - return "module"; - }; - const [first, second] = await Promise.all([ - cache.load("a", loader), - cache.load("a", loader), - ]); - assert.equal(first, "module"); - assert.equal(second, "module"); - assert.equal(calls, 1); - assert.equal(await cache.load("a", loader), "module"); - assert.equal(calls, 1); -}); - -test("a rejected load is evicted so the next caller retries", async () => { - const cache = new WhiteboardModuleCache(); - let calls = 0; - const loader = async () => { - calls += 1; - if (calls === 1) throw new Error("boom"); - return "recovered"; - }; - await assert.rejects(cache.load("a", loader), /boom/); - assert.equal(await cache.load("a", loader), "recovered"); - assert.equal(calls, 2); -}); - -test("a loader that throws synchronously rejects instead of throwing", async () => { - const cache = new WhiteboardModuleCache(); - await assert.rejects( - cache.load("a", () => { - throw new Error("sync"); - }), - /sync/, - ); -}); - -test("clear forces the next load to run the loader again", async () => { - const cache = new WhiteboardModuleCache(); - let calls = 0; - const loader = async () => ++calls; - assert.equal(await cache.load("a", loader), 1); - cache.clear(); - assert.equal(await cache.load("a", loader), 2); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardModuleCache.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardModuleCache.ts deleted file mode 100644 index 81fb623ab..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardModuleCache.ts +++ /dev/null @@ -1,36 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Caches in-flight and settled module loads by key. Concurrent callers share - * one promise, a fulfilled load stays cached until `clear()`, and a rejected - * load is evicted so the next caller retries. - */ -export class WhiteboardModuleCache { - private readonly entries = new Map>(); - - load(key: string, loader: () => Promise): Promise { - const cached = this.entries.get(key) as Promise | undefined; - if (cached) { - return cached; - } - - let pending: Promise; - pending = Promise.resolve() - .then(loader) - .catch((error) => { - if (this.entries.get(key) === pending) { - this.entries.delete(key); - } - throw error; - }); - this.entries.set(key, pending); - return pending; - } - - clear(): void { - this.entries.clear(); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardPeek.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardPeek.ts deleted file mode 100644 index bc79952f0..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardPeek.ts +++ /dev/null @@ -1,373 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type { - WhiteboardDiffFileWire, - WhiteboardDiffSide, - WhiteboardInlineEditorRange, -} from "./whiteboardProtocol.js"; - -export const WHITEBOARD_PEEK_MAX_VISIBLE_LINES = 18; -export const WHITEBOARD_PEEK_LINE_HEIGHT = 20; -const WHITEBOARD_PEEK_CONTEXT_LINES = 3; - -export type WhiteboardPeekHeightMode = "capped" | "content"; - -export interface WhiteboardPeekWindow { - startLine: number; - endLine: number; - lineCount: number; - visibleLineCount: number; - height: number; -} - -export interface WhiteboardPeekHiddenArea { - startLineNumber: number; - endLineNumber: number; -} - -export interface WhiteboardPeekLineMapping { - originalStartLine: number; - originalEndLineExclusive: number; - modifiedStartLine: number; - modifiedEndLineExclusive: number; -} - -export function whiteboardPeekSideAvailable( - status: WhiteboardDiffFileWire["status"] | undefined, - side: WhiteboardDiffSide, -): boolean { - return !( - (side === "base" && status === "added") || - (side === "head" && status === "deleted") - ); -} - -export function whiteboardPeekWindow( - totalLines: number, - startLine: number, - endLine: number, - heightMode: WhiteboardPeekHeightMode, - contextLines = WHITEBOARD_PEEK_CONTEXT_LINES, -): WhiteboardPeekWindow { - if ( - !Number.isInteger(totalLines) || - totalLines <= 0 || - !Number.isInteger(startLine) || - !Number.isInteger(endLine) || - startLine <= 0 || - endLine < startLine || - endLine > totalLines || - !Number.isInteger(contextLines) || - contextLines < 0 - ) { - throw new Error("CodePeek range is outside the resolved file."); - } - const windowStart = Math.max(1, startLine - contextLines); - const windowEnd = Math.min(totalLines, endLine + contextLines); - const lineCount = windowEnd - windowStart + 1; - const visibleLineCount = - heightMode === "content" - ? lineCount - : Math.min(WHITEBOARD_PEEK_MAX_VISIBLE_LINES, lineCount); - return { - startLine: windowStart, - endLine: windowEnd, - lineCount, - visibleLineCount, - height: visibleLineCount * WHITEBOARD_PEEK_LINE_HEIGHT, - }; -} - -export function whiteboardPeekWindows( - totalLines: number, - ranges: readonly WhiteboardInlineEditorRange[], - heightMode: WhiteboardPeekHeightMode, - contextLines = WHITEBOARD_PEEK_CONTEXT_LINES, -): WhiteboardPeekWindow[] { - if (ranges.length === 0) { - throw new Error("CodePeek requires at least one range."); - } - return mergeWhiteboardPeekWindows( - ranges.map((range) => - whiteboardPeekWindow( - totalLines, - range.startLine, - range.endLine, - heightMode, - contextLines, - ), - ), - heightMode, - ); -} - -export function whiteboardPeekWindowsLineCount( - windows: readonly WhiteboardPeekWindow[], -): number { - return windows.reduce((total, window) => total + window.lineCount, 0); -} - -export function whiteboardPeekCappedHeight(measuredHeight: number): number { - return Math.min( - WHITEBOARD_PEEK_MAX_VISIBLE_LINES * WHITEBOARD_PEEK_LINE_HEIGHT, - Math.max(0, measuredHeight), - ); -} - -/** The subset of ICodeEditor that window measurement needs. */ -interface WhiteboardPeekRenderedEditor { - getModel(): unknown; - getTopForLineNumber(lineNumber: number, includeViewZones?: boolean): number; - getBottomForLineNumber(lineNumber: number, includeViewZones?: boolean): number; -} - -/** - * Total height of peek windows as actually rendered by an editor. Each - * window is measured independently so hidden gaps do not inflate the result. - * Wrapped lines and in-window view zones are included; alignment view zones - * outside the windows are excluded. Returns undefined when the editor cannot - * be measured yet. - */ -export function whiteboardPeekWindowsRenderedHeight( - editor: WhiteboardPeekRenderedEditor, - windows: readonly WhiteboardPeekWindow[], -): number | undefined { - if (!editor.getModel() || windows.length === 0) return undefined; - let height = 0; - for (const window of windows) { - // Monaco excludes view zones by default. Inline diffs render deleted - // lines as view zones, so they must count toward the window height. - const top = editor.getTopForLineNumber(window.startLine, true); - const bottom = editor.getBottomForLineNumber(window.endLine, true); - if (bottom <= top) return undefined; - height += bottom - top; - } - return height; -} -export function whiteboardPeekHiddenAreas( - totalLines: number, - windows: readonly WhiteboardPeekWindow[], -): WhiteboardPeekHiddenArea[] { - const hidden: WhiteboardPeekHiddenArea[] = []; - let nextVisibleLine = 1; - for (const window of windows) { - if (window.startLine > nextVisibleLine) { - hidden.push({ - startLineNumber: nextVisibleLine, - endLineNumber: window.startLine - 1, - }); - } - nextVisibleLine = Math.max(nextVisibleLine, window.endLine + 1); - } - if (nextVisibleLine <= totalLines) { - hidden.push({ - startLineNumber: nextVisibleLine, - endLineNumber: totalLines, - }); - } - return hidden; -} - -export function whiteboardPeekLineMappings( - patch: string, -): WhiteboardPeekLineMapping[] { - const mappings: WhiteboardPeekLineMapping[] = []; - let originalLine = 0; - let modifiedLine = 0; - let inHunk = false; - let changeStart: { original: number; modified: number } | undefined; - - const finishChange = () => { - if (!changeStart) return; - mappings.push({ - originalStartLine: changeStart.original, - originalEndLineExclusive: originalLine, - modifiedStartLine: changeStart.modified, - modifiedEndLineExclusive: modifiedLine, - }); - changeStart = undefined; - }; - - for (const row of patch.split(/\r?\n/)) { - const header = - /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(row); - if (header) { - finishChange(); - originalLine = Number(header[1]); - modifiedLine = Number(header[2]); - inHunk = true; - continue; - } - if (!inHunk) continue; - if (row.startsWith("\\ No newline at end of file")) continue; - const marker = row[0]; - if (marker === " ") { - finishChange(); - originalLine += 1; - modifiedLine += 1; - } else if (marker === "-" || marker === "+") { - changeStart ??= { original: originalLine, modified: modifiedLine }; - if (marker === "-") originalLine += 1; - else modifiedLine += 1; - } - } - finishChange(); - return mappings; -} - -function flipWhiteboardPeekLineMappings( - mappings: readonly WhiteboardPeekLineMapping[], -): WhiteboardPeekLineMapping[] { - return mappings.map((mapping) => ({ - originalStartLine: mapping.modifiedStartLine, - originalEndLineExclusive: mapping.modifiedEndLineExclusive, - modifiedStartLine: mapping.originalStartLine, - modifiedEndLineExclusive: mapping.originalEndLineExclusive, - })); -} - -function mappedWhiteboardPeekWindow( - destinationLineCount: number, - sourceWindow: WhiteboardPeekWindow, - mappings: readonly WhiteboardPeekLineMapping[], -): WhiteboardPeekWindow { - const startLine = clampLine( - mapWhiteboardPeekLine(sourceWindow.startLine, mappings, "start"), - destinationLineCount, - ); - const endLine = Math.max( - startLine, - clampLine( - mapWhiteboardPeekLine(sourceWindow.endLine, mappings, "end"), - destinationLineCount, - ), - ); - return whiteboardPeekWindow( - destinationLineCount, - startLine, - endLine, - "content", - 0, - ); -} - -function mappedWhiteboardPeekWindows( - destinationLineCount: number, - sourceWindows: readonly WhiteboardPeekWindow[], - mappings: readonly WhiteboardPeekLineMapping[], -): WhiteboardPeekWindow[] { - return mergeWhiteboardPeekWindows( - sourceWindows.map((window) => - mappedWhiteboardPeekWindow(destinationLineCount, window, mappings), - ), - "content", - ); -} - -export function whiteboardPeekDiffWindows( - originalLineCount: number, - modifiedLineCount: number, - ranges: readonly WhiteboardInlineEditorRange[], - defaultSide: WhiteboardDiffSide, - baseToHeadMappings: readonly WhiteboardPeekLineMapping[], -): { - readonly original: readonly WhiteboardPeekWindow[]; - readonly modified: readonly WhiteboardPeekWindow[]; -} { - const baseRanges = ranges.filter( - (range) => (range.side ?? defaultSide) === "base", - ); - const headRanges = ranges.filter( - (range) => (range.side ?? defaultSide) === "head", - ); - const originalSelections = - baseRanges.length > 0 - ? whiteboardPeekWindows(originalLineCount, baseRanges, "content") - : []; - const modifiedSelections = - headRanges.length > 0 - ? whiteboardPeekWindows(modifiedLineCount, headRanges, "content") - : []; - const originalFromHead = mappedWhiteboardPeekWindows( - originalLineCount, - modifiedSelections, - flipWhiteboardPeekLineMappings(baseToHeadMappings), - ); - const modifiedFromBase = mappedWhiteboardPeekWindows( - modifiedLineCount, - originalSelections, - baseToHeadMappings, - ); - return { - original: mergeWhiteboardPeekWindows( - [...originalSelections, ...originalFromHead], - "content", - ), - modified: mergeWhiteboardPeekWindows( - [...modifiedSelections, ...modifiedFromBase], - "content", - ), - }; -} - -function mergeWhiteboardPeekWindows( - windows: readonly WhiteboardPeekWindow[], - heightMode: WhiteboardPeekHeightMode, -): WhiteboardPeekWindow[] { - const sorted = [...windows].sort( - (left, right) => left.startLine - right.startLine, - ); - const merged: WhiteboardPeekWindow[] = []; - for (const window of sorted) { - const previous = merged.at(-1); - if (!previous || window.startLine > previous.endLine + 1) { - merged.push(window); - continue; - } - const endLine = Math.max(previous.endLine, window.endLine); - const lineCount = endLine - previous.startLine + 1; - const visibleLineCount = - heightMode === "content" - ? lineCount - : Math.min(WHITEBOARD_PEEK_MAX_VISIBLE_LINES, lineCount); - merged[merged.length - 1] = { - startLine: previous.startLine, - endLine, - lineCount, - visibleLineCount, - height: visibleLineCount * WHITEBOARD_PEEK_LINE_HEIGHT, - }; - } - return merged; -} - -function mapWhiteboardPeekLine( - line: number, - mappings: readonly WhiteboardPeekLineMapping[], - edge: "start" | "end", -): number { - const mapping = mappings.findLast( - (candidate) => candidate.originalStartLine <= line, - ); - if (!mapping) return line; - if (mapping.originalEndLineExclusive <= line) { - return ( - line - - mapping.originalEndLineExclusive + - mapping.modifiedEndLineExclusive - ); - } - return edge === "start" - ? mapping.modifiedStartLine - : Math.max( - mapping.modifiedStartLine, - mapping.modifiedEndLineExclusive - 1, - ); -} - -function clampLine(line: number, totalLines: number): number { - return Math.max(1, Math.min(line, totalLines)); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReadonlySource.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReadonlySource.ts deleted file mode 100644 index ef0da5d77..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReadonlySource.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { URI } from "../../base/common/uri.js"; - -export const WHITEBOARD_LANGUAGE_SOURCE_SCHEME = "review-language-source"; - -/** These resources own presentation buffers, never workspace working copies. */ -export function isWhiteboardReadonlySource(resource: URI | undefined): boolean { - return resource?.scheme === "review-api-source" || resource?.scheme === WHITEBOARD_LANGUAGE_SOURCE_SCHEME || resource?.scheme === "devfast-review-unified"; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReconnect.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReconnect.test.ts deleted file mode 100644 index 055ec1a2d..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReconnect.test.ts +++ /dev/null @@ -1,110 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { - WHITEBOARD_CLIENT_RECONNECT_DELAYS, - reconnectUntilAborted, -} from "./whiteboardReconnect.js"; - -function failing(times: number): (onConnected: () => void) => Promise { - let calls = 0; - return async () => { - calls += 1; - if (calls <= times) throw new Error(`failure ${calls}`); - }; -} - -test("walks the delay table between failures and returns once connect resolves", async () => { - const waits: number[] = []; - const errors: string[] = []; - await reconnectUntilAborted(new AbortController().signal, failing(3), { - onRetry: (error) => errors.push((error as Error).message), - wait: async (ms) => { - waits.push(ms); - }, - }); - assert.deepEqual(waits, WHITEBOARD_CLIENT_RECONNECT_DELAYS.slice(0, 3)); - assert.deepEqual(errors, ["failure 1", "failure 2", "failure 3"]); -}); - -test("keeps retrying at the last delay when no exhaustion handler is given", async () => { - const waits: number[] = []; - const total = WHITEBOARD_CLIENT_RECONNECT_DELAYS.length + 2; - await reconnectUntilAborted(new AbortController().signal, failing(total), { - wait: async (ms) => { - waits.push(ms); - }, - }); - const last = WHITEBOARD_CLIENT_RECONNECT_DELAYS[WHITEBOARD_CLIENT_RECONNECT_DELAYS.length - 1]; - assert.deepEqual(waits, [...WHITEBOARD_CLIENT_RECONNECT_DELAYS, last, last]); -}); - -test("calls onExhausted with the last error once the table runs out", async () => { - const waits: number[] = []; - await assert.rejects( - reconnectUntilAborted( - new AbortController().signal, - failing(WHITEBOARD_CLIENT_RECONNECT_DELAYS.length + 1), - { - onExhausted: (error) => { - throw new Error("exhausted", { cause: error }); - }, - wait: async (ms) => { - waits.push(ms); - }, - }, - ), - (error: Error) => - error.message === "exhausted" && - (error.cause as Error).message === - `failure ${WHITEBOARD_CLIENT_RECONNECT_DELAYS.length + 1}`, - ); - assert.deepEqual(waits, [...WHITEBOARD_CLIENT_RECONNECT_DELAYS]); -}); - -test("a successful connection restarts the delay table", async () => { - const waits: number[] = []; - let calls = 0; - await reconnectUntilAborted( - new AbortController().signal, - async (onConnected) => { - calls += 1; - if (calls === 1) throw new Error("first"); - if (calls === 2) { - onConnected(); - throw new Error("stream ended"); - } - }, - { - wait: async (ms) => { - waits.push(ms); - }, - }, - ); - const first = WHITEBOARD_CLIENT_RECONNECT_DELAYS[0]; - assert.deepEqual(waits, [first, first]); -}); - -test("returns quietly when the signal aborts during a failure", async () => { - const controller = new AbortController(); - let waited = false; - await reconnectUntilAborted( - controller.signal, - async () => { - controller.abort(); - throw new Error("aborted mid-connect"); - }, - { - onRetry: () => assert.fail("must not retry after abort"), - wait: async () => { - waited = true; - }, - }, - ); - assert.equal(waited, false); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReconnect.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReconnect.ts deleted file mode 100644 index fd0e3e4b6..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardReconnect.ts +++ /dev/null @@ -1,61 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -export const WHITEBOARD_SERVER_RESTART_DELAYS = [250, 1_000, 2_000] as const; - -// Keep the renderer retrying after the utility host has scheduled its final -// restart. The replacement process still needs time to boot and attach its -// authenticated event streams after the host's delay has elapsed. -export const WHITEBOARD_CLIENT_RECONNECT_DELAYS = [ - ...WHITEBOARD_SERVER_RESTART_DELAYS, - 4_000, -] as const; - -export interface WhiteboardReconnectOptions { - /** Observes each failure before the next delay. */ - readonly onRetry?: (error: unknown) => void; - /** - * Called once every delay in the table has been used since the last - * successful connection. Omit it to keep retrying at the last delay. - */ - readonly onExhausted?: (error: unknown) => never; - readonly wait?: (ms: number) => Promise; -} - -/** - * Runs `connect` until it resolves or `signal` aborts, backing off through - * `WHITEBOARD_CLIENT_RECONNECT_DELAYS` between failures. `connect` receives an - * `onConnected` callback that restarts the delay table. - */ -export async function reconnectUntilAborted( - signal: AbortSignal, - connect: (onConnected: () => void) => Promise, - options: WhiteboardReconnectOptions = {}, -): Promise { - const wait = - options.wait ?? - ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); - let attempt = 0; - while (!signal.aborted) { - try { - await connect(() => { - attempt = 0; - }); - return; - } catch (error) { - if (signal.aborted) return; - options.onRetry?.(error); - let delay = WHITEBOARD_CLIENT_RECONNECT_DELAYS[attempt++]; - if (delay === undefined) { - options.onExhausted?.(error); - delay = - WHITEBOARD_CLIENT_RECONNECT_DELAYS[ - WHITEBOARD_CLIENT_RECONNECT_DELAYS.length - 1 - ]; - } - await wait(delay); - } - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardSourceView.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardSourceView.ts deleted file mode 100644 index 169244c5c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardSourceView.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { URI } from "../../base/common/uri.js"; -import { whiteboardSourcePinsFromQuery, whiteboardSourceQuery, type WhiteboardApiSourceLocation, type WhiteboardSourceSelection } from "./whiteboardProtocol.js"; - -export const WHITEBOARD_API_SOURCE_SCHEME = "review-api-source"; - -export function apiSourceUri(target: WhiteboardApiSourceLocation, empty = false): URI { - const query = new URLSearchParams({ side: target.side }); - for (const [key, value] of Object.entries(whiteboardSourceQuery(target.view))) { - if (value !== undefined) query.set(key, String(value)); - } - if (target.view.generation) query.set("generation", target.view.generation); - if (empty) query.set("empty", "true"); - return URI.from({ scheme: WHITEBOARD_API_SOURCE_SCHEME, authority: target.view.sessionId, path: `/${target.file}`, query: query.toString() }); -} - -/** Decode resolved read coordinates; generation only separates client models. */ -export function sourceLocation(resource: URI): WhiteboardApiSourceLocation { - const query = new URLSearchParams(resource.query); - const commit = query.get("commit") ?? undefined; - return { - view: Object.freeze({ - sessionId: resource.authority, - version: Number(query.get("version")), - generation: query.get("generation") ?? undefined, - commit, - pins: whiteboardSourcePinsFromQuery((key) => query.get(key)), - }), - side: query.get("side") === "base" ? "base" : "head", - file: resource.path.slice(1), - }; -} - -/** Tabs and directory nodes keep intent, never a resolved refresh token. */ -export const WHITEBOARD_API_TREE_SCHEME = "review-api-tree"; - -export function sourceSelectionIdentity(selection: WhiteboardSourceSelection): string { - return `${selection.sessionId}/${selection.kind === "current" ? "current" : selection.version}`; -} - -export function sourceTreeUri(selection: WhiteboardSourceSelection, file = ""): URI { - return URI.from({ scheme: WHITEBOARD_API_TREE_SCHEME, authority: selection.sessionId, - path: `/${file}`, query: selection.kind === "version" ? `version=${selection.version}` : "" }); -} - -export function sourceTreeSelection(resource: URI): WhiteboardSourceSelection { - const version = new URLSearchParams(resource.query).get("version"); - return version === null ? { sessionId: resource.authority, kind: "current" } - : { sessionId: resource.authority, kind: "version", version: Number(version) }; -} - -/** An open Source tab owns the tree while its files change revisions. */ -export function sourceTreeRoot(resource: URI, current?: URI): URI { - if (current && resource.authority === current.authority) { - const selection = sourceTreeSelection(current); - if (selection.kind === "current" || selection.version === sourceLocation(resource).view.version) return current; - } - return sourceTreeUri({ sessionId: resource.authority, kind: "version", version: sourceLocation(resource).view.version }); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardStructuralDiff.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardStructuralDiff.test.ts deleted file mode 100644 index f9570c18e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardStructuralDiff.test.ts +++ /dev/null @@ -1,360 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; -import { projectInlineSourceAlignment, projectSplitSourceAlignment } from "../../editor/common/diff/sourceLineAlignment.js"; -import { - collapsedRegions, - hiddenLinesOf, - structuralContextGaps, - bandDetail, - structuralHighlights, - structuralRows, - utf16Column, - type StructuralFold, - type StructuralLeaf, - type StructuralRegion, - type StructuralTextDiff, -} from "./whiteboardStructuralDiff.js"; - -/** - * A leaf whose `id`, `alignment_id` and `fold_state_id` are all `id`. Tests pair two leaves by giving - * them one number on both sides, which repeats the `id` across sides as diffr never does; nothing here - * keys identity across sides, and the tests that tell the ids apart set them through `extra`. - */ -function leaf(id: number, start: number, end: number, extra: Partial = {}): StructuralLeaf { - return { id, alignment_id: id, fold_state_id: id, kind: "leaf", start: { line: start, column: 0 }, end: { line: end, column: 0 }, ...extra }; -} -function fold(id: number, children: StructuralRegion[], tags: string[] = ["context:body"]): StructuralFold { - const first = children[0], last = children[children.length - 1]; - return { id, fold_state_id: id, kind: "fold", start: first.start, end: last.end, tags, children }; -} -function text(lines: string[], regions: StructuralRegion[]) { - return { text: lines.join("\n") + "\n", regions }; -} -const stats = { textual: { added: 0, removed: 0 }, visible: { added: 0, removed: 0 } }; - -test("paired collapse removes hidden height without leaving padding for hidden anchors", () => { - const rows: [number | null, number | null][] = [ - [0, 0], - [1, 1], - [null, 2], - [2, 3], - [3, 4], - ]; - const segments = projectSplitSourceAlignment( - rows, - (l) => (l === 1 || l === 2 ? 0 : 20), - (r) => (r >= 1 && r <= 3 ? 0 : 20), - ); - assert.deepEqual( - segments.map((s) => [s.leftEnd, s.rightEnd, s.rightHeight - s.leftHeight]), - [ - [1, 1, 0], - [3, 4, 0], - [4, 5, 0], - ], - ); -}); - -test("a one-sided band's height is filled on the other side at the row that starts the fold, not past it", () => { - // Right-only row 1, then a right fold (rows 2..4) whose band is 50px and whose middle row pairs with left 1, then right-only row 5. - const rows: [number | null, number | null][] = [ - [0, 0], - [null, 1], - [null, 2], - [1, 3], - [null, 4], - [null, 5], - [2, 6], - ]; - const segments = projectSplitSourceAlignment( - rows, - (l) => (l === 1 ? 0 : 20), - (r) => (r === 2 ? 50 : r === 3 || r === 4 ? 0 : 20), - ); - // Fillers sit after a segment's last left line: after left 0 for row 1 and the band, then again after left 0 (left 1 is folded) for row 5. - assert.deepEqual( - segments.map((s) => [s.leftEnd, s.rightEnd, s.rightHeight - s.leftHeight]), - [ - [1, 3, 70], - [2, 5, 0], - [2, 6, 20], - [3, 7, 0], - ], - ); -}); - -test("leaves zip by alignment_id into rows: paired line for line, unpaired one-sided, trailing empty lines paired", () => { - // As diffr numbers them: every region has its own id; paired leaves share alignment and fold state. - const rhsLeaf = (id: number, alignment: number, start: number, end: number) => - leaf(id, start, end, { alignment_id: alignment, fold_state_id: alignment === 9 ? id : alignment - 1 }); - const diff: StructuralTextDiff = { - type: "text", structural_changes: { base: [], head: [] }, - stats, - lhs: text(["a", "b", "c", "d"], [leaf(0, 0, 1, { alignment_id: 1 }), leaf(1, 1, 2, { alignment_id: 2 }), leaf(2, 2, 4, { alignment_id: 3 })]), - rhs: text(["a", "x", "b", "c", "d"], [rhsLeaf(3, 1, 0, 1), rhsLeaf(4, 9, 1, 2), rhsLeaf(5, 2, 2, 3), rhsLeaf(6, 3, 3, 5)]), - }; - assert.deepEqual(structuralRows(diff), [ - [0, 0], - [null, 1], - [1, 2], - [2, 3], - [3, 4], - [4, 5], - ]); -}); - -test("one-sided files and nested folds still tile", () => { - const added: StructuralTextDiff = { - type: "text", structural_changes: { base: [], head: [] }, - stats, - rhs: text(["fn f() {", " 1", "}"], [fold(1, [leaf(2, 0, 1), leaf(3, 1, 2), leaf(4, 2, 3)])]), - }; - assert.deepEqual(structuralRows(added), [ - [null, 0], - [null, 1], - [null, 2], - [null, 3], - ]); -}); - - -test("structural coverage tints inserted lines without novel tokens, retaining UTF-16 token highlights", () => { - const diff: StructuralTextDiff = { - type: "text", structural_changes: { base: [[1, 2]], head: [[1, 4]] }, - stats, - lhs: text(["a", "b"], [leaf(1, 0, 1), leaf(2, 1, 2, { changed: [{ line: 1, start_column: 0, end_column: 1 }] })]), - rhs: text(["a", "b + é", "", "}"], [leaf(1, 0, 1), leaf(3, 1, 4, { changed: [{ line: 1, start_column: 2, end_column: 6 }] })]), - }; - const paint = structuralHighlights(diff); - assert.deepEqual(paint.originalLines, [2]); - assert.deepEqual(paint.modifiedLines, [2, 3, 4]); - assert.deepEqual(paint.modified, [{ startLineNumber: 2, startColumn: 3, endLineNumber: 2, endColumn: 6 }]); -}); - -test("fully novel lines retain line tint without token tint on either side", () => { - for (const changed of [ - [{ line: 0, start_column: 0, end_column: 13 }], - [{ line: 0, start_column: 1, end_column: 12 }], - [{ line: 0, start_column: 1, end_column: 6 }, { line: 0, start_column: 7, end_column: 12 }], - ]) { - const source = text(["\tconst café \t"], [leaf(1, 0, 1, { changed })]); - const paint = structuralHighlights({ type: "text", stats, structural_changes: { base: [[0, 1]], head: [[0, 1]] }, lhs: source, rhs: source }); - assert.deepEqual(paint.originalLines, [1]); - assert.deepEqual(paint.modifiedLines, [1]); - assert.deepEqual(paint.original, []); - assert.deepEqual(paint.modified, []); - } -}); - -test("Tree-sitter byte offsets convert to Monaco UTF-16 columns", () => { - assert.equal(utf16Column("a😀éz", 7), 5); -}); - - -test("a collapsed region hides every line it covers, fold or leaf; nested collapses are subsumed", () => { - const collapsed = { collapsed: true, label: "x" }; - const inner = fold(3, [leaf(4, 3, 4), leaf(5, 4, 6)]); - inner.visibility = collapsed; - const body = fold(2, [leaf(6, 2, 3), inner, leaf(7, 6, 8)]); - body.visibility = collapsed; - assert.deepEqual(hiddenLinesOf(body), { start: 2, end: 8 }); - assert.deepEqual(hiddenLinesOf(leaf(1, 0, 2, { visibility: collapsed })), { start: 0, end: 2 }); - assert.deepEqual(collapsedRegions([leaf(1, 0, 2, { visibility: collapsed }), body], (id) => id === 1 || id === 2 || id === 3).map((r) => r.fold_state_id), [1, 2]); - assert.deepEqual(collapsedRegions([leaf(1, 0, 2), body], (id) => id === 3).map((r) => r.fold_state_id), [3]); -}); - -test("every collapsed region becomes a labelled band: paired across sides, or one-sided at the aligned line", () => { - const pseudocode = "// pseudocode\nif not key: return None\nreturn call(key)"; - const gapL = leaf(1, 0, 40, { visibility: { collapsed: true, label: "40 unchanged lines" } }); - // The paired gap has an id of its own and pairs with the left one by alignment. - const gapR = leaf(11, 0, 40, { alignment_id: 1, fold_state_id: 1, visibility: { collapsed: true, label: "40 unchanged lines" } }); - // A body fold covers the body alone; the signature line is the leaf before it. - const removed = fold(2, [leaf(4, 41, 60)], ["deleted-bodies:function"]); - removed.visibility = { collapsed: true, label: "19 lines removed" }; - const added = fold(5, [leaf(7, 41, 70)], ["deleted-bodies:function"]); - added.visibility = { collapsed: true, label: pseudocode }; - const tailL = leaf(8, 60, 62), tailR = leaf(8, 70, 72); - const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); - const diff: StructuralTextDiff = { - type: "text", structural_changes: { base: [], head: [] }, - stats, - lhs: text(lines(62), [gapL, leaf(3, 40, 41), removed, tailL]), - rhs: text(lines(72), [gapR, leaf(6, 40, 41), added, tailR]), - }; - const gaps = structuralContextGaps(diff, (id) => id === 1 || id === 2 || id === 5); - assert.deepEqual(gaps, [ - { originalStart: 1, originalCount: 40, modifiedStart: 1, modifiedCount: 40, label: "40 unchanged lines", owner: "both", change: "unchanged", collapsed: true, foldStateId: 1, regionIds: [11, 1], breadcrumbs: true }, - // The removed body hides lines 42..60 on the left; its rows precede the added body's, so it anchors before them on the right. - { originalStart: 42, originalCount: 19, modifiedStart: 41, modifiedCount: 0, label: "19 lines removed", owner: "base", change: "removed", collapsed: true, foldStateId: 2, regionIds: [2], breadcrumbs: true }, - { originalStart: 61, originalCount: 0, modifiedStart: 42, modifiedCount: 29, label: pseudocode, owner: "head", change: "inserted", collapsed: true, foldStateId: 5, regionIds: [5], breadcrumbs: true }, - ]); - // A region the reader revealed stays a band, marked open, so the editor keeps a fold control on it. - const revealed = structuralContextGaps(diff, (id) => id === 2 || id === 5, (id) => (id === 1 ? false : id === 2 || id === 5 ? true : undefined)); - assert.deepEqual(revealed.map((g) => [g.foldStateId, g.collapsed]), [[1, false], [2, true], [5, true]]); - // A region the state never knew is not a band at all, and neither is one that never starts collapsed. - assert.deepEqual(structuralContextGaps(diff, (id) => id === 2 || id === 5).map((g) => g.foldStateId), [2, 5]); - assert.deepEqual(structuralContextGaps(diff, () => false, (id) => (id === 8 ? false : id === 2 ? true : undefined)).map((g) => g.foldStateId), [2]); - // A collapsed region without a label is named by its line count. - const unlabeled = leaf(9, 0, 3, { visibility: { collapsed: true, label: "" } }); - const small: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(3), [unlabeled]), rhs: text(lines(3), [unlabeled]) }; - assert.equal(structuralContextGaps(small, () => true)[0].label, "3 hidden lines"); -}); - -test("a band's detail drops diffr's pseudocode marker line and keeps one-line labels empty", () => { - assert.equal(bandDetail("// pseudocode\nx = 1\n y = 2"), "x = 1\n y = 2"); - assert.equal(bandDetail("# pseudocode\nreturn x"), "return x"); - assert.equal(bandDetail("first\nsecond"), "first\nsecond"); - assert.equal(bandDetail("19 lines removed"), ""); -}); - -test("a one-sided band also hides the opposite lines the zip aligned with it", () => { - // The lhs fold is unpaired (no rhs region shares its fold state), but its body leaf (3) pairs with an rhs leaf: the band spans both. - const body = fold(2, [leaf(4, 1, 6)], ["deleted-bodies:function"]); - body.visibility = { collapsed: true, label: "5 unchanged lines" }; - const rhsHead = leaf(3, 0, 1), rhsBody = leaf(4, 1, 6); - const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); - const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(6), [leaf(3, 0, 1), body]), rhs: text(lines(6), [rhsHead, rhsBody]) }; - const [gap] = structuralContextGaps(diff, (id) => id === 2); - assert.deepEqual(gap, { - originalStart: 2, originalCount: 5, modifiedStart: 2, modifiedCount: 5, - label: "5 unchanged lines", owner: "base", change: "unchanged", collapsed: true, foldStateId: 2, regionIds: [2], breadcrumbs: true, - }); -}); - -test("a one-sided band starts after the row before its fold and hides only the opposite lines inside its rows", () => { - const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); - // Right: a function whose body has an inserted run, a middle leaf paired with the left, and another inserted run. - const added = fold(20, [leaf(22, 3, 5), leaf(12, 5, 7), leaf(23, 7, 9)], ["deleted-bodies:function"]); - added.visibility = { collapsed: true, label: "// pseudocode\nreturn rows" }; - const inserted: StructuralTextDiff = { - type: "text", structural_changes: { base: [], head: [] }, - stats, - lhs: text(lines(6), [leaf(10, 0, 2), leaf(12, 2, 4), leaf(14, 4, 6)]), - rhs: text(lines(11), [leaf(10, 0, 2), leaf(21, 2, 3), added, leaf(14, 9, 11)]), - }; - assert.deepEqual(structuralRows(inserted).slice(0, 10), [ - [0, 0], [1, 1], [null, 2], [null, 3], [null, 4], [2, 5], [3, 6], [null, 7], [null, 8], [4, 9], - ]); - assert.deepEqual(structuralContextGaps(inserted, (id) => id === 20), [{ - originalStart: 3, originalCount: 2, modifiedStart: 4, modifiedCount: 6, - label: "// pseudocode\nreturn rows", owner: "head", change: "inserted", collapsed: true, foldStateId: 20, regionIds: [20], breadcrumbs: true, - }]); - // The mirror: a left-only function whose rows are all filler on the right, followed by a right-only line. - const removed = fold(20, [leaf(22, 3, 6)], ["deleted-bodies:function"]); - removed.visibility = { collapsed: true, label: "3 lines removed" }; - const deleted: StructuralTextDiff = { - type: "text", structural_changes: { base: [], head: [] }, - stats, - lhs: text(lines(8), [leaf(10, 0, 2), leaf(21, 2, 3), removed, leaf(14, 6, 8)]), - rhs: text(lines(5), [leaf(10, 0, 2), leaf(30, 2, 3), leaf(14, 3, 5)]), - }; - assert.deepEqual(structuralRows(deleted).slice(0, 8), [[0, 0], [1, 1], [2, null], [3, null], [4, null], [5, null], [null, 2], [6, 3]]); - assert.deepEqual(structuralContextGaps(deleted, (id) => id === 20), [{ - originalStart: 4, originalCount: 3, modifiedStart: 3, modifiedCount: 0, - label: "3 lines removed", owner: "base", change: "removed", collapsed: true, foldStateId: 20, regionIds: [20], breadcrumbs: true, - }]); -}); - -test("alignment and fold state are separate: the zip follows one, collapse follows the other", () => { - const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); - // A docstring (id 1) linked to its function under fold state 7 on the rhs. The matched - // functions have their own ids (2 and 5), share fold state 7, and their leaves pair by alignment. - const doc = { ...leaf(1, 0, 2, { visibility: { collapsed: true, label: "" } }), fold_state_id: 7 }; - const fnR = { ...fold(5, [leaf(4, 3, 6)]), fold_state_id: 7 }; - fnR.visibility = { collapsed: true, label: "3 hidden lines" }; - const fnL = { ...fold(2, [leaf(4, 1, 4)]), fold_state_id: 7 }; - fnL.visibility = { collapsed: true, label: "3 hidden lines" }; - const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(4), [leaf(3, 0, 1), fnL]), rhs: text(lines(6), [doc, leaf(3, 2, 3), fnR]) }; - // Rows pair the functions' leaves by alignment_id; the docstring is rhs-only. - assert.deepEqual(structuralRows(diff).slice(0, 3), [[null, 0], [null, 1], [0, 2]]); - // One toggle, fold state 7, hides both the docstring and the paired function. - const gaps = structuralContextGaps(diff, (id) => id === 7); - assert.deepEqual(gaps.map((g) => [g.change, g.foldStateId]).sort(), [["inserted", 7], ["unchanged", 7]]); - assert.deepEqual(gaps.find((g) => g.change === "unchanged"), { - originalStart: 2, originalCount: 3, modifiedStart: 4, modifiedCount: 3, - label: "3 hidden lines", owner: "both", change: "unchanged", collapsed: true, foldStateId: 7, regionIds: [5, 2], breadcrumbs: true, - }); - // With fold state 7 open, neither the docstring nor the function is a band. - assert.deepEqual(structuralContextGaps(diff, () => false), []); -}); - -test("a docstring bundled with its function shares one fold state and shows a bare count", () => { - const collapsed = { collapsed: true, label: "" }; - const doc = leaf(30, 0, 2, { tags: ["summarize:docstring"], visibility: collapsed }); - doc.fold_state_id = 40; - const body = fold(40, [leaf(42, 3, 6)], ["deleted-bodies:function"]); - body.visibility = { collapsed: true, label: "// pseudocode\nreturn x" }; - const lines = ["/// a", "/// b", "fn f() {", "x", "y", "}"]; - const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text([], []), rhs: text(lines, [doc, leaf(41, 2, 3), body]) }; - const open = new Set(); - const state = (id: number) => (id === 40 ? !open.has(id) : undefined); - const gaps = structuralContextGaps(diff, (id) => state(id) === true, state); - assert.deepEqual(gaps.map((g) => [g.foldStateId, g.breadcrumbs, g.collapsed]), [[40, false, true], [40, true, true]]); - open.add(40); - assert.deepEqual(structuralContextGaps(diff, (id) => state(id) === true, state).map((g) => g.collapsed), [false, false]); -}); - -test("a fold pairs through fold state, and a docstring fold only with a docstring fold", () => { - const lines = (n: number) => Array.from({ length: n }, (_, i) => `l${i}`); - const collapsed = { collapsed: true, label: "" }; - // lhs: a docstring fold (0-3) linked to the function body (3-7). rhs: only the body (0-4), matched with the lhs body. - const docL: StructuralRegion = { ...fold(1, [leaf(2, 0, 3)], ["deleted-bodies:docstring"]), fold_state_id: 9, visibility: collapsed }; - const bodyL: StructuralRegion = { ...fold(4, [leaf(6, 4, 7)], ["deleted-bodies:function"]), fold_state_id: 9, visibility: { collapsed: true, label: "3 lines" } }; - const bodyR: StructuralRegion = { ...fold(7, [leaf(6, 1, 4)], ["deleted-bodies:function"]), fold_state_id: 9, visibility: { collapsed: true, label: "3 lines" } }; - const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(lines(7), [docL, leaf(5, 3, 4), bodyL]), rhs: text(lines(4), [leaf(5, 0, 1), bodyR]) }; - const gaps = structuralContextGaps(diff, (id) => id === 9); - // A whole-node docstring fold covers every line it holds; the body fold starts below - // the signature leaf beside it. - assert.deepEqual(gaps.map((g) => [g.change, g.originalStart, g.originalCount, g.modifiedStart, g.modifiedCount, g.breadcrumbs]), [ - ["removed", 1, 3, 1, 0, false], - ["unchanged", 5, 3, 2, 3, true], - ]); - // Folds that share an id but not a fold state are not a pair. - const other: StructuralRegion = { ...bodyR, id: 4, fold_state_id: 10 }; - const unpaired: StructuralTextDiff = { ...diff, rhs: text(lines(4), [other]) }; - assert.deepEqual(structuralContextGaps(unpaired, (id) => id === 9 || id === 10).map((g) => g.owner).sort(), ["base", "base", "head"]); -}); - - -test("inline correspondence omits a large folded region rather than balancing its hidden sides", () => { - const rows: [number | null, number | null][] = [[0, 0], ...Array.from({ length: 100 }, (_, i): [number, null] => [i + 1, null]), [101, 1], [102, 2]]; - const result = projectInlineSourceAlignment(rows, l => l > 0 && l < 101 ? 0 : 20, () => 20, new Set([101]), new Set([1])); - assert.deepEqual(result, [{ leftStart: 101, leftEnd: 102, rightStart: 1, rightEnd: 2, leftHeight: 20, rightHeight: 20 }]); -}); - -test("inline correspondence retains removed code, changed pairs, and insertion order", () => { - const rows: [number | null, number | null][] = [[0, 0], [1, null], [null, 1], [2, 2], [3, 3]]; - const result = projectInlineSourceAlignment(rows, () => 20, r => r === 2 ? 40 : 20, new Set([2]), new Set([2])); - assert.deepEqual(result, [{ leftStart: 1, leftEnd: 3, rightStart: 1, rightEnd: 3, leftHeight: 40, rightHeight: 60 }]); -}); - -test("a folded changed pair separates inline original-code zones", () => { - const rows: [number, number][] = [[0, 0], [1, 1], [2, 2]]; - const result = projectInlineSourceAlignment(rows, l => l === 1 ? 0 : 20, r => r === 1 ? 0 : 20, new Set([0, 1, 2]), new Set([0, 1, 2])); - assert.deepEqual(result.map(s => [s.leftStart, s.leftEnd, s.rightStart, s.rightEnd]), [[0, 1, 0, 1], [2, 3, 2, 3]]); -}); - - -test("base-owned unchanged fold projects both ranges and retains its toggle identity after reveal", () => { - const base = fold(26, [leaf(16, 0, 1), fold(28, [leaf(17, 1, 4)]), leaf(18, 4, 5)]); - base.visibility = { collapsed: true, label: "5 unchanged lines" }; - const head = fold(334, [leaf(16, 0, 1), fold(336, [leaf(17, 1, 4)]), leaf(18, 4, 5)]); - const diff: StructuralTextDiff = { type: "text", structural_changes: { base: [], head: [] }, stats, lhs: text(["a", "b", "c", "d", "e"], [base]), rhs: text(["a", "b", "c", "d", "e"], [head]) }; - for (const collapsed of [true, false, true]) { - const [gap] = structuralContextGaps(diff, () => collapsed, id => id === 26 ? collapsed : undefined); - assert.equal(gap.owner, "base"); assert.equal(gap.change, "unchanged"); - assert.equal(gap.originalCount, 5); assert.equal(gap.modifiedCount, 5); - assert.equal(gap.foldStateId, 26); assert.equal(gap.collapsed, collapsed); - } - // Paired leaves with changed spans are modified, regardless of fold ownership. - const l = base.children[0]; const r = head.children[0]; - if (l.kind !== "leaf" || r.kind !== "leaf") throw new Error("Expected leaves"); - l.changed = [{ line: 0, start_column: 0, end_column: 1 }]; r.changed = [{ line: 0, start_column: 0, end_column: 1 }]; - diff.structural_changes = { base: [[0, 1]], head: [[0, 1]] }; - assert.equal(structuralContextGaps(diff, id => id === 26)[0].change, "modified"); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardStructuralDiff.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardStructuralDiff.ts deleted file mode 100644 index 6df181148..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardStructuralDiff.ts +++ /dev/null @@ -1,303 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { structuralRows } from "./whiteboardProtocol.js"; -export { structuralRows } from "./whiteboardProtocol.js"; - -import type { - StructuralPairing, StructuralFileRef, StructuralRegion, StructuralSource, - StructuralDiff, -} from "./whiteboardProtocol.js"; -export type { - StructuralPairing, StructuralProblem, StructuralPos, StructuralSpan, - StructuralVisibility, StructuralRegion, StructuralSyntaxSpan, StructuralSource, - StructuralLineCounts, StructuralStats, StructuralDiff, StructuralFileRef, - StructuralFileChange, -} from "./whiteboardProtocol.js"; -export { STRUCTURAL_DIFF_WIRE_VERSION as STRUCTURAL_WIRE_VERSION } from "./whiteboardProtocol.js"; -export type { StructuralDiffEvent as StructuralEvent } from "./whiteboardProtocol.js"; -export type StructuralLeaf = Extract; -export type StructuralFold = Extract; -export type StructuralTextDiff = Extract; -export type StructuralBinaryDiff = Extract; - -/** Review keys a file by its head path, or its base path for a deletion. */ -export function structuralFilePath(file: StructuralPairing): string { - return file.rhs?.path ?? file.lhs!.path; -} - -/** The 0-based, half-open line span a region touches. An end at column 0 does not touch its end line. */ -export function regionLines(region: StructuralRegion): { start: number; end: number } { - return { start: region.start.line, end: region.end.column === 0 ? region.end.line : region.end.line + 1 }; -} - -/** Preserve the context plugin's scope boundaries for lens projection. */ -export function structuralContextScopes(diff: StructuralTextDiff) { - const scopes = (source: StructuralSource | undefined) => { - const result: [number, number][] = []; - const visit = (region: StructuralRegion) => { - if (region.kind !== "fold") return; - if (region.tags?.includes("context:scope")) { - const { start, end } = regionLines(region); - result.push([start, end]); - } - region.children.forEach(visit); - }; - source?.regions?.forEach(visit); - return result; - }; - return { original: scopes(diff.lhs), modified: scopes(diff.rhs) }; -} - -export function structuralLeaves(regions: readonly StructuralRegion[] | undefined): StructuralLeaf[] { - const leaves: StructuralLeaf[] = []; - const walk = (region: StructuralRegion) => { - if (region.kind === "leaf") leaves.push(region); - else for (const child of region.children) walk(child); - }; - for (const region of regions ?? []) walk(region); - return leaves; -} - -export function utf16Column(text: string, byteColumn: number): number { - let bytes = 0, - units = 0; - for (const character of text) { - if (bytes >= byteColumn) break; - bytes += new TextEncoder().encode(character).length; - units += character.length; - } - return units + 1; -} - -/** - * Whole-line tint follows diffr’s structural coverage, matching change counts. - * Changed token spans supply the stronger tint within those lines. - */ -export function structuralHighlights(diff: StructuralTextDiff) { - function side(source: StructuralSource | undefined, ranges: readonly (readonly [number, number])[]) { - if (!source) return { spans: [], lines: [] }; - const lines = source.text.replace(/\r\n/g, "\n").split("\n"); - const changedLines: number[] = []; - for (const [start, end] of ranges) { - for (let line = start; line < end; line++) changedLines.push(line + 1); - } - const spans = []; - for (const leaf of structuralLeaves(source.regions)) { - for (const span of leaf.changed ?? []) { - spans.push({ - startLineNumber: span.line + 1, - startColumn: utf16Column(lines[span.line], span.start_column), - endLineNumber: span.line + 1, - endColumn: utf16Column(lines[span.line], span.end_column), - }); - } - } - // Keep coverage for counts, but reserve token tint for partially changed lines. - const byLine = new Map(); - for (const span of spans) { - const group = byLine.get(span.startLineNumber) ?? []; - group.push(span); - byLine.set(span.startLineNumber, group); - } - const fullyNovel = new Set(); - for (const [line, group] of byLine) { - let end = 0; - let unchanged = ""; - for (const span of group.sort((a, b) => a.startColumn - b.startColumn)) { - unchanged += lines[line - 1].slice(end, Math.max(end, span.startColumn - 1)); - end = Math.max(end, span.endColumn - 1); - } - unchanged += lines[line - 1].slice(end); - if (!unchanged.trim()) fullyNovel.add(line); - } - return { spans: spans.filter(span => !fullyNovel.has(span.startLineNumber)), lines: changedLines }; - } - const original = side(diff.lhs, diff.structural_changes.base); - const modified = side(diff.rhs, diff.structural_changes.head); - return { - original: original.spans, - modified: modified.spans, - originalLines: original.lines, - modifiedLines: modified.lines, - }; -} - -/** Tags are `:`; several plugins capture docstrings, each under its own prefix. */ -const isDocstring = (region: StructuralRegion) => region.tags?.some((tag) => tag.slice(tag.lastIndexOf(":") + 1) === "docstring") === true; - -/** A hidden band on one or both sides, one-based like Monaco's diff editor. */ -export interface StructuralGap { - originalStart: number; - modifiedStart: number; - originalCount: number; - modifiedCount: number; - label: string; - /** What the band hides: unchanged context, or lines that exist on one side only. */ - owner: "base" | "head" | "both"; - change: "unchanged" | "inserted" | "removed" | "modified"; - /** False for a region the reader revealed: it stays a band the editor can fold again. */ - collapsed: boolean; - /** The fold-state id of the region(s) this band hides; toggling the band toggles it. */ - foldStateId: number; - /** Label precedence: head first, then base. */ - regionIds: readonly number[]; - /** False for a bundled docstring: its band shows the bare count, no symbol names. */ - breadcrumbs: boolean; -} - -/** - * The text a band shows under its title. diffr prepends a ` pseudocode` - * line to a summary for terminals; the app has its own caption, so that line - * is dropped here. A one-line label has no detail. - */ -export function bandDetail(label: string): string { - const lines = label.split("\n"); - if (lines.length < 2) return ""; - const body = /^(\/\/|#|--|;|%)\s*pseudocode$/.test(lines[0].trim()) ? lines.slice(1) : lines; - return body.join("\n"); -} - -/** - * The lines a collapsed region hides on its side, zero-based half-open: every - * line it covers, fold or leaf. A fold covers its body alone — the line that - * opens the construct is the last line of the leaf before it — so a band - * hides exactly the fold's range, and the signature above it stays a row. - */ -export function hiddenLinesOf(region: StructuralRegion): { start: number; end: number } { - return regionLines(region); -} - -/** Collapsed regions of one side, outermost first; a collapsed descendant of a collapsed region is subsumed. `isCollapsed` answers for a fold-state id. */ -export function collapsedRegions( - regions: readonly StructuralRegion[] | undefined, - isCollapsed: (foldStateId: number) => boolean, -): StructuralRegion[] { - return knownRegions(regions, (id) => (isCollapsed(id) ? true : undefined)).map((r) => r.region); -} - -/** - * Regions of one side the state knows about, outermost first: collapsed ones - * and ones a reader revealed. A collapsed region subsumes its descendants; a - * revealed one still lists them, since a child may be collapsed on its own. - */ -export function knownRegions( - regions: readonly StructuralRegion[] | undefined, - state: (foldStateId: number) => boolean | undefined, -): { region: StructuralRegion; collapsed: boolean }[] { - const result: { region: StructuralRegion; collapsed: boolean }[] = []; - const walk = (region: StructuralRegion) => { - const known = state(region.fold_state_id); - const hides = hiddenLinesOf(region).end > hiddenLinesOf(region).start; - if (known === true) { - if (hides) result.push({ region, collapsed: true }); - return; - } - // Open, but a band by the wire's default: a reader revealed it, and the editor can fold it again. - if (known === false && hides && region.visibility?.collapsed === true) result.push({ region, collapsed: false }); - if (region.kind === "fold") for (const child of region.children) walk(child); - }; - for (const region of regions ?? []) walk(region); - return result; -} - -/** - * Every collapsed region as a diff-editor band. A region collapsed on both - * sides becomes one band: a leaf with the leaf sharing its `alignment_id`, a - * fold with the fold sharing its `fold_state_id` (a docstring only with a - * docstring, since a docstring shares its body's fold state). A region on one side only - * becomes a band on that side; the other side's range starts right after the - * row that precedes the region and covers only the opposite lines the zip put - * inside the region's rows, none when those rows are filler. - */ -export function structuralContextGaps( - diff: StructuralTextDiff, - isCollapsed: (foldStateId: number) => boolean, - state: (foldStateId: number) => boolean | undefined = (id) => (isCollapsed(id) ? true : undefined), -): StructuralGap[] { - const rows = structuralRows(diff); - const rowOfLeft = new Map(), rowOfRight = new Map(); - rows.forEach(([l, r], index) => { - if (l !== null) rowOfLeft.set(l, index); - if (r !== null) rowOfRight.set(r, index); - }); - // One-based start and count of the opposite range for lines hidden on `side`. Rows are monotone, so - // the opposite lines inside the region's rows follow the opposite line of the row before it. - const oppositeSpan = (side: 0 | 1, hidden: { start: number; end: number }): { start: number; count: number } => { - const other = side === 0 ? 1 : 0; - const rowOf = side === 0 ? rowOfLeft : rowOfRight; - const first = rowOf.get(hidden.start)!, last = rowOf.get(hidden.end - 1)!; - let before = -1; - for (let index = first - 1; index >= 0 && before === -1; index--) before = rows[index][other] ?? -1; - let count = 0; - for (let index = first; index <= last; index++) if (rows[index][other] !== null) count++; - return { start: before + 2, count }; - }; - const lhs = knownRegions(diff.lhs?.regions, state); - const rhs = knownRegions(diff.rhs?.regions, state); - // Leaves pair by alignment; folds pair by fold state, the only identity they share across sides. - const usedRhs = new Set(); - const pairs = (left: StructuralRegion, right: StructuralRegion) => { - if (left.kind === "leaf") return right.kind === "leaf" && right.alignment_id === left.alignment_id; - return right.kind === "fold" && right.fold_state_id === left.fold_state_id && isDocstring(right) === isDocstring(left); - }; - const counterpart = (left: StructuralRegion) => - rhs.find(({ region: right }) => !usedRhs.has(right) && pairs(left, right)); - const gaps: StructuralGap[] = []; - for (const { region: left, collapsed } of lhs) { - const hidden = hiddenLinesOf(left); - const partner = counterpart(left); - if (partner) { - usedRhs.add(partner.region); - const right = hiddenLinesOf(partner.region); - gaps.push({ - originalStart: hidden.start + 1, originalCount: hidden.end - hidden.start, - modifiedStart: right.start + 1, modifiedCount: right.end - right.start, - label: partner.region.visibility?.label || left.visibility?.label || "", - owner: "both", change: "unchanged", - collapsed: collapsed && partner.collapsed, - foldStateId: left.fold_state_id, regionIds: [partner.region.id, left.id], - breadcrumbs: !isDocstring(left) && !isDocstring(partner.region), - }); - continue; - } - const opposite = oppositeSpan(0, hidden); - gaps.push({ - originalStart: hidden.start + 1, originalCount: hidden.end - hidden.start, - modifiedStart: opposite.start, modifiedCount: opposite.count, - label: left.visibility?.label || "", owner: "base", change: "unchanged", collapsed, foldStateId: left.fold_state_id, regionIds: [left.id], - breadcrumbs: !isDocstring(left), - }); - } - for (const { region: right, collapsed } of rhs) { - if (usedRhs.has(right)) continue; - const hidden = hiddenLinesOf(right); - const opposite = oppositeSpan(1, hidden); - gaps.push({ - originalStart: opposite.start, originalCount: opposite.count, - modifiedStart: hidden.start + 1, modifiedCount: hidden.end - hidden.start, - label: right.visibility?.label || "", owner: "head", change: "unchanged", collapsed, foldStateId: right.fold_state_id, regionIds: [right.id], - breadcrumbs: !isDocstring(right), - }); - } - // Ownership says which fold state to toggle, never whether its contents were deleted. - const highlights = structuralHighlights(diff); - const removedLines = new Set(highlights.originalLines), addedLines = new Set(highlights.modifiedLines); - for (const [left, right] of rows) { - if (left !== null && right === null) removedLines.add(left + 1); - if (right !== null && left === null) addedLines.add(right + 1); - } - for (const gap of gaps) { - const removed = [...removedLines].some(line => line >= gap.originalStart && line < gap.originalStart + gap.originalCount); - const added = [...addedLines].some(line => line >= gap.modifiedStart && line < gap.modifiedStart + gap.modifiedCount); - gap.change = removed && added ? "modified" : removed ? "removed" : added ? "inserted" : "unchanged"; - } - gaps.sort((a, b) => (a.modifiedStart - b.modifiedStart) || (a.originalStart - b.originalStart)); - for (const gap of gaps) if (!gap.label) { - const count = Math.max(gap.originalCount, gap.modifiedCount); - gap.label = `${count} hidden line${count === 1 ? "" : "s"}`; - } - return gaps; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardTelemetryRequest.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardTelemetryRequest.test.ts deleted file mode 100644 index db01fd77b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardTelemetryRequest.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { whiteboardTelemetryEventRequest } from "./whiteboardTelemetryRequest.js"; - -test("builds an authenticated JSON POST for a telemetry event", () => { - const request = whiteboardTelemetryEventRequest( - { token: "secret", appSessionId: "app-1" }, - { name: "review_presented" }, - ); - assert.equal(request.method, "POST"); - assert.deepEqual(request.headers, { - "content-type": "application/json", - "x-whiteboard-token": "secret", - "x-review-app-session-id": "app-1", - }); - assert.deepEqual(JSON.parse(String(request.body)), { name: "review_presented" }); - assert.equal(request.keepalive, false); -}); - -test("keepalive is opt-in", () => { - const request = whiteboardTelemetryEventRequest( - { token: "secret", appSessionId: "app-1" }, - { name: "x" }, - { keepalive: true }, - ); - assert.equal(request.keepalive, true); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardTelemetryRequest.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardTelemetryRequest.ts deleted file mode 100644 index 1a11d203a..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardTelemetryRequest.ts +++ /dev/null @@ -1,30 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface WhiteboardTelemetryAuth { - readonly token: string; - readonly appSessionId: string; -} - -/** - * The POST every telemetry sender makes to a Whiteboard server `telemetry/event` - * endpoint; callers pick the URL and how the request is dispatched. - */ -export function whiteboardTelemetryEventRequest( - auth: WhiteboardTelemetryAuth, - event: unknown, - options: { readonly keepalive?: boolean } = {}, -): RequestInit { - return { - method: "POST", - headers: { - "content-type": "application/json", - "x-whiteboard-token": auth.token, - "x-review-app-session-id": auth.appSessionId, - }, - body: JSON.stringify(event), - keepalive: options.keepalive ?? false, - }; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardUpdateNotice.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardUpdateNotice.ts deleted file mode 100644 index 2f6521d33..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardUpdateNotice.ts +++ /dev/null @@ -1,119 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Decisions behind Review's update toasts, kept free of services so they can be - * tested directly. - * - * Everything here keys off the build's `commit`, never its version. Packaged - * `product.json` carries the Code OSS version (`1.129.1`) for every Review - * release, so it is identical before and after an update and cannot say whether - * one landed. Only `commit` changes. The release semver a human recognises - * ("0.0.7") exists solely in the update feed's `productVersion`, which is why it - * has to be captured from the update payload and stored rather than read back - * off the running product. - */ - -/** A downloaded update, staged and waiting for the restart that applies it. */ -export interface IWhiteboardStagedUpdate { - /** `product.json` `commit` of the build that will be running after restart. */ - readonly targetCommit: string; - /** Release semver, e.g. "0.0.7". Absent if the feed omitted it. */ - readonly productVersion?: string; -} - -export function serializeStagedUpdate(staged: IWhiteboardStagedUpdate): string { - return JSON.stringify(staged); -} - -/** - * Storage is user-writable and survives across versions, so treat anything - * unexpected as absent rather than throwing — this runs during workbench - * startup, where a parse error would be a far worse outcome than a missed toast. - */ -export function parseStagedUpdate(raw: string | undefined): IWhiteboardStagedUpdate | undefined { - if (!raw) { - return undefined; - } - let parsed: unknown; - try { - parsed = JSON.parse(raw); - } catch { - return undefined; - } - if (typeof parsed !== 'object' || parsed === null) { - return undefined; - } - const { targetCommit, productVersion } = parsed as Record; - if (typeof targetCommit !== 'string' || !targetCommit) { - return undefined; - } - return { - targetCommit, - productVersion: typeof productVersion === 'string' && productVersion ? productVersion : undefined, - }; -} - -/** - * `IUpdate.version` is the target commit and `IUpdate.productVersion` the - * release semver — the update Worker documents that split, and the darwin - * service validates both fields separately. - */ -export function stagedUpdateFromReady(update: { version?: string; productVersion?: string } | undefined): IWhiteboardStagedUpdate | undefined { - if (!update?.version) { - return undefined; - } - return { targetCommit: update.version, productVersion: update.productVersion }; -} - -export type WhiteboardUpdateNotice = - /** Nothing was staged; say nothing. */ - | { readonly kind: 'none' } - /** Something was staged but it is not what is running; drop it silently. */ - | { readonly kind: 'clear' } - /** The staged update is now running; announce it once. */ - | { readonly kind: 'announce'; readonly productVersion?: string }; - -/** - * Whether this launch is the first one after a staged update applied. - * - * A missing `currentCommit` means an unbuilt run, where updates are disabled - * outright — clear rather than announce, so a record left by a packaged build - * cannot produce a bogus toast in a development window. - */ -export function decideUpdateNotice( - staged: IWhiteboardStagedUpdate | undefined, - currentCommit: string | undefined, -): WhiteboardUpdateNotice { - if (!staged) { - return { kind: 'none' }; - } - if (currentCommit && currentCommit === staged.targetCommit) { - return { kind: 'announce', productVersion: staged.productVersion }; - } - return { kind: 'clear' }; -} - -/** Whether a newly-ready update replaces whatever was staged before it. */ -export function supersedesStagedUpdate( - existing: IWhiteboardStagedUpdate | undefined, - next: IWhiteboardStagedUpdate, -): boolean { - return !existing || existing.targetCommit !== next.targetCommit; -} - -/** - * Whether to prompt for this update. - * - * Skipping is bound to the exact commit, so a later release still prompts. Note - * that skipping only silences the toast: Squirrel still installs the update on - * quit, which is why the staged record is written regardless. - */ -export function shouldPromptForUpdate( - next: IWhiteboardStagedUpdate, - skippedCommit: string | undefined, -): boolean { - return !skippedCommit || skippedCommit !== next.targetCommit; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardWorkbenchVisibility.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardWorkbenchVisibility.ts deleted file mode 100644 index 524d95a6b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardWorkbenchVisibility.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Review hosts Home, review canvases, files, and diffs in one native editor - * group. The upstream agent sessions part stays hidden in this layout. - * - * `explorer` is never persisted. `WhiteboardExplorerParts` derives it from the - * active editor pane on every change, so the layout always starts it hidden and - * lets that service reassert it once the restored editor is known. - * - * A user *closing* the tree is a separate matter. That is a decision rather than - * derived state, so it has to survive the next tab switch and a reload. - * `WhiteboardExplorerParts` persists it on its own key (`review.explorer.userClosed`) - * and folds it into the derived value. No part visibility is stored here. - */ -export const initialWhiteboardPartVisibility = { - sidebar: false, - auxiliaryBar: false, - editor: true, - panel: false, - sessions: false, - explorer: false, -} as const; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/explorer/whiteboardFileTree.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/explorer/whiteboardFileTree.contribution.ts deleted file mode 100644 index 2f890062b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/explorer/whiteboardFileTree.contribution.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize2 } from '../../../nls.js'; -import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js'; -import { Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; -import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; -import { KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js'; -import { IWhiteboardExplorerPartsService } from '../../browser/parts/explorer/whiteboardExplorerPart.js'; - -/** - * Closes and reopens the file tree beside a reviewed file. - * - * `Cmd+B` matches VS Code's Toggle Primary Side Bar, and it is taken here on - * purpose. `ToggleSidebarVisibilityAction` in - * `workbench/browser/actions/layoutActions.ts` claims the same chord at - * `WorkbenchContrib`, and Review reaches that file transitively through - * `workbench/browser/workbench.contribution.js`. At equal weight the last rule - * registered wins, which is registration order rather than intent — so this asks - * for one more than `WorkbenchContrib` to win deterministically. - * - * The binding carries no `when` clause on purpose, so the chord can never reach - * the stock action. That action is not merely inert in Review: it flips - * `partVisibility.sidebar`, toggles the layout class, and then calls - * `setViewVisible` on `WhiteboardWorkbench.sideBarPartView`, which Review never - * assigns. It throws with the layout state already half-changed. So this action - * always takes the key and no-ops itself when there is no tree to toggle, rather - * than declining the key and handing it to something that breaks the window. - */ -class ToggleWhiteboardFileTreeAction extends Action2 { - constructor() { - super({ - id: 'whiteboard.toggleFileTree', - title: localize2('whiteboard.toggleFileTree', "Whiteboard: Toggle File Tree"), - f1: true, - keybinding: { - weight: KeybindingWeight.WorkbenchContrib + 1, - primary: KeyMod.CtrlCmd | KeyCode.KeyB, - }, - }); - } - - override run(accessor: ServicesAccessor): void { - accessor.get(IWhiteboardExplorerPartsService).toggle(); - } -} - -registerAction2(ToggleWhiteboardFileTreeAction); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/extensions/whiteboardCuratedExtensions.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/extensions/whiteboardCuratedExtensions.contribution.ts deleted file mode 100644 index e3a05ce7e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/extensions/whiteboardCuratedExtensions.contribution.ts +++ /dev/null @@ -1,737 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize, localize2 } from '../../../nls.js'; -import { Codicon } from '../../../base/common/codicons.js'; -import { getErrorMessage } from '../../../base/common/errors.js'; -import { DisposableStore } from '../../../base/common/lifecycle.js'; -import { isLinux, isMacintosh } from '../../../base/common/platform.js'; -import { ThemeIcon } from '../../../base/common/themables.js'; -import { URI } from '../../../base/common/uri.js'; -import { ipcRenderer } from '../../../base/parts/sandbox/electron-browser/globals.js'; -import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../platform/actions/common/actions.js'; -import { CommandsRegistry, ICommandService } from '../../../platform/commands/common/commands.js'; -import { IConfigurationService, ConfigurationTarget } from '../../../platform/configuration/common/configuration.js'; -import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; -import { ExtensionType, type IExtensionIdentifier } from '../../../platform/extensions/common/extensions.js'; -import { - IExtensionManagementService, - IGlobalExtensionEnablementService, - type ILocalExtension -} from '../../../platform/extensionManagement/common/extensionManagement.js'; -import { areSameExtensions } from '../../../platform/extensionManagement/common/extensionManagementUtil.js'; -import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; -import { IMainProcessService } from '../../../platform/ipc/common/mainProcessService.js'; -import { ILogService } from '../../../platform/log/common/log.js'; -import { INotificationService } from '../../../platform/notification/common/notification.js'; -import { IProgressService, ProgressLocation } from '../../../platform/progress/common/progress.js'; -import { IQuickInputService, type IQuickPickItem } from '../../../platform/quickinput/common/quickInput.js'; -import { Registry } from '../../../platform/registry/common/platform.js'; -import { IStorageService, StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js'; -import { LifecyclePhase } from '../../../workbench/services/lifecycle/common/lifecycle.js'; -import { - Extensions as WorkbenchExtensions, - type IWorkbenchContribution, - type IWorkbenchContributionsRegistry -} from '../../../workbench/common/contributions.js'; -import { WHITEBOARD_KEYMAP_SETTING, type WhiteboardKeymap } from '../../common/whiteboardConfigurationDefaults.js'; -import { WHITEBOARD_DESKTOP_CHANNEL } from '../../common/whiteboardDesktopBootstrap.js'; -import { setFirstRunReloadPending } from '../../common/whiteboardFirstRunReload.js'; -import type { WhiteboardUserConfigImportResult } from '../../node/whiteboardUserConfigImport.js'; -import { IWhiteboardTelemetryService } from '../../services/whiteboardTelemetryService.js'; -import { whiteboardOptionalExtensionCatalog } from '../../node/whiteboardOptionalExtensionCatalog.js'; -import { - installMissingOptionalExtensions, - OptionalExtensionInstallError, - optionalGroupMemberIds, - upgradeOptionalExtensionPins -} from './whiteboardOptionalExtensionManagement.js'; - -/** - * The curated bundled extensions Review materializes, mirroring - * apps/whiteboard-desktop/scripts/curated-extensions.manifest.mjs. A test in - * curated-extensions.test.mjs keeps the two lists in step. - * - * Only bundled extensions that are installed show up as individual rows. - * Optional groups always show so the user can consent to their download. - */ -const BUNDLED_EXTENSIONS: readonly { id: string; label: string }[] = [ - { id: 'ms-python.python', label: localize('review.curated.python', "Python") }, - { id: 'astral-sh.ty', label: localize('review.curated.ty', "Python type checking (ty)") }, - { id: 'charliermarsh.ruff', label: localize('review.curated.ruff', "Python lint and format (ruff)") }, - { id: 'vscodevim.vim', label: localize('review.curated.vim', "Vim keybindings") }, - { id: 'tuttieee.emacs-mcx', label: localize('review.curated.emacs', "Emacs keybindings") } -]; - -const OPTIONAL_GROUPS: readonly { group: string; label: string; detail?: string }[] = [ - { group: 'rust', label: localize('review.curated.rust', "Rust (rust-analyzer)") }, - { group: 'swift', label: localize('review.curated.swift', "Swift") }, - { - group: 'csharp', - label: localize('review.curated.csharp', "C#"), - detail: localize('review.curated.csharp.requiresDotnet', "Requires a system .NET SDK. Whiteboard does not download .NET.") - }, - { - group: 'go', - label: localize('review.curated.go', "Go"), - detail: localize('review.curated.go.installsTools', "Downloads the Go extension, which then installs gopls and vscgo with the Go toolchain on your machine (about 40 MB from proxy.golang.org).") - } -] as const; - -const ALL_CURATED_IDS = [ - ...BUNDLED_EXTENSIONS.map(extension => extension.id), - ...whiteboardOptionalExtensionCatalog.map(extension => extension.id) -]; - -type CuratedQuickPickItem = IQuickPickItem & ( - | { kind: 'bundled'; id: string } - | { kind: 'optional'; group: string } -); - -/** The two keymaps fight over the same keys, so only one may be on at a time. */ -const KEYMAP_EXTENSION_IDS: Readonly, string>> = { - vim: 'vscodevim.vim', - emacs: 'tuttieee.emacs-mcx', -}; -const KEYMAP_IDS = Object.values(KEYMAP_EXTENSION_IDS); - -const SEEDED_STORAGE_KEY = 'review.curatedExtensions.defaultsApplied.v2'; - -type ExtensionEnablementTrigger = 'user' | 'keymap' | 'startup_seed'; - -function isDisabled(disabled: readonly IExtensionIdentifier[], id: string): boolean { - return disabled.some(identifier => areSameExtensions(identifier, { id })); -} - -/** - * Applies the enable/disable choice. Extension enablement only takes effect when - * the extension host restarts, so callers offer a reload afterwards. Takes the - * services rather than a ServicesAccessor: callers reach this after awaits, and - * an accessor is only valid during the synchronous span of its invocation. - */ -export async function setCuratedExtensionsEnabled( - enablementService: IGlobalExtensionEnablementService, - extensionManagementService: IExtensionManagementService, - enabledIds: readonly string[], - whiteboardTelemetryService: IWhiteboardTelemetryService, - trigger: ExtensionEnablementTrigger = 'user' -): Promise { - const installed = await extensionManagementService.getInstalled(); - const installedCurated = installed.filter(extension => - ALL_CURATED_IDS.some(id => areSameExtensions(extension.identifier, { id })) - ); - let changed = false; - - for (const extension of installedCurated) { - const extensionId = ALL_CURATED_IDS.find(id => areSameExtensions(extension.identifier, { id })); - if (!extensionId) { - continue; - } - let didChange: boolean; - if (enabledIds.some(id => areSameExtensions(extension.identifier, { id }))) { - didChange = await enablementService.enableExtension(extension.identifier); - if (didChange) { - whiteboardTelemetryService.capture('extension_enabled', { extension_id: extensionId, trigger }); - } - } else { - didChange = await enablementService.disableExtension(extension.identifier); - if (didChange) { - whiteboardTelemetryService.capture('extension_disabled', { extension_id: extensionId, trigger }); - } - } - changed ||= didChange; - } - return changed; -} - -/** - * Selects a keymap from the Settings tab. - * - * This touches the two keymap extensions only. `setCuratedExtensionsEnabled` - * takes the full enabled list, so passing one keymap id to it would disable - * rust-analyzer, Python, and Go. - * - * The extension enablement moves here rather than at the next launch, because - * CuratedExtensionDefaults reconciles enablement against `whiteboard.keymap` on - * startup and would force a surprise reload if the two disagreed. - */ -async function applyWhiteboardKeymap(accessor: ServicesAccessor, keymap: WhiteboardKeymap): Promise { - const configurationService = accessor.get(IConfigurationService); - const enablementService = accessor.get(IGlobalExtensionEnablementService); - const commandService = accessor.get(ICommandService); - const dialogService = accessor.get(IDialogService); - const whiteboardTelemetryService = accessor.get(IWhiteboardTelemetryService); - - if (configurationService.getValue(WHITEBOARD_KEYMAP_SETTING) === keymap) { - return; - } - await configurationService.updateValue(WHITEBOARD_KEYMAP_SETTING, keymap, ConfigurationTarget.USER); - - let changed = false; - for (const [candidate, id] of Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) { - const didChange = candidate === keymap - ? await enablementService.enableExtension({ id }) - : await enablementService.disableExtension({ id }); - if (didChange) { - whiteboardTelemetryService.capture(candidate === keymap ? 'extension_enabled' : 'extension_disabled', { - extension_id: id, - trigger: 'keymap' - }); - } - changed ||= didChange; - } - if (!changed) { - return; - } - - // The caller may be a page the user is still reading, so offer the reload - // rather than force it. - const reload = await dialogService.confirm({ - type: 'info', - message: localize('whiteboard.keymap.reload', "Reload Whiteboard to apply the keymap?"), - detail: localize('whiteboard.keymap.reloadDetail', "Keymap extensions only take effect after the extension host restarts."), - primaryButton: localize('whiteboard.keymap.reloadNow', "&&Reload"), - cancelButton: localize('whiteboard.keymap.reloadLater', "Later"), - }); - if (reload.confirmed) { - await whiteboardTelemetryService.flush(); - await commandService.executeCommand('workbench.action.reloadWindow'); - } -} - -CommandsRegistry.registerCommand('whiteboard.setKeymap', (accessor, keymap: WhiteboardKeymap) => - applyWhiteboardKeymap(accessor, keymap) -); - -function findInstalled(installed: readonly ILocalExtension[], id: string): ILocalExtension | undefined { - return installed.find(extension => areSameExtensions(extension.identifier, { id })); -} - -function optionalDownloadSize(group: string, installed: readonly ILocalExtension[]): number { - const target = isMacintosh ? 'darwin-arm64' : isLinux ? 'linux-x64' : undefined; - return whiteboardOptionalExtensionCatalog - .filter(extension => extension.group === group && !findInstalled(installed, extension.id)) - .reduce((total, extension) => { - const targets = extension.targets as Readonly>; - const pin = targets['universal'] ?? (target ? targets[target] : undefined); - return total + (pin?.size ?? 0); - }, 0); -} - -function formatDownloadSize(bytes: number): string { - return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; -} - -function optionalExtensionLabel(extensionId: string): string { - const extension = whiteboardOptionalExtensionCatalog.find(candidate => candidate.id === extensionId); - const group = extension && OPTIONAL_GROUPS.find(candidate => candidate.group === extension.group); - if (!extension || !group) { - return extensionId; - } - return extension.role === 'support' - ? localize('review.curated.extensionSupport', "{0} support", group.label) - : group.label; -} - -async function stageRustAnalyzer( - mainProcessService: IMainProcessService, - logService: ILogService -): Promise { - try { - await mainProcessService.getChannel(WHITEBOARD_DESKTOP_CHANNEL).call('stageRustAnalyzer'); - } catch (error) { - logService.error(`[Whiteboard extensions] Could not stage rust-analyzer: ${getErrorMessage(error)}`); - } -} - -class ManageCuratedExtensionsAction extends Action2 { - constructor() { - super({ - id: 'whiteboard.manageExtensions', - title: localize2('whiteboard.manageExtensions', "Manage Extensions..."), - f1: true - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const quickInputService = accessor.get(IQuickInputService); - const extensionManagementService = accessor.get(IExtensionManagementService); - const enablementService = accessor.get(IGlobalExtensionEnablementService); - const commandService = accessor.get(ICommandService); - const configurationService = accessor.get(IConfigurationService); - const dialogService = accessor.get(IDialogService); - const notificationService = accessor.get(INotificationService); - const progressService = accessor.get(IProgressService); - const mainProcessService = accessor.get(IMainProcessService); - const logService = accessor.get(ILogService); - const whiteboardTelemetryService = accessor.get(IWhiteboardTelemetryService); - - let installed = await extensionManagementService.getInstalled(); - - const disabled = enablementService.getDisabledExtensions(); - const items: CuratedQuickPickItem[] = BUNDLED_EXTENSIONS - .filter(curated => findInstalled(installed, curated.id)) - .map(curated => ({ - kind: 'bundled', - id: curated.id, - label: curated.label, - description: curated.id, - picked: !isDisabled(disabled, curated.id) - })); - for (const optionalGroup of OPTIONAL_GROUPS) { - const members = optionalGroupMemberIds(optionalGroup.group); - const installedMembers = members - .map(id => findInstalled(installed, id)) - .filter((extension): extension is ILocalExtension => Boolean(extension)); - const primary = whiteboardOptionalExtensionCatalog.find(extension => - extension.group === optionalGroup.group && extension.role === 'primary' - ); - const downloadSize = optionalDownloadSize(optionalGroup.group, installed); - const userMembers = installedMembers.filter(extension => extension.type === ExtensionType.User); - items.push({ - kind: 'optional', - group: optionalGroup.group, - label: optionalGroup.label, - description: downloadSize > 0 - ? localize('review.curated.downloadSize', "Download {0}", formatDownloadSize(downloadSize)) - : localize('review.curated.installed', "Installed"), - detail: optionalGroup.detail, - picked: Boolean(primary && findInstalled(installed, primary.id)) && - installedMembers.every(extension => !isDisabled(disabled, extension.identifier.id)), - buttons: userMembers.length > 0 ? [{ - iconClass: ThemeIcon.asClassName(Codicon.trash), - tooltip: localize('review.curated.uninstall', "Uninstall this optional language group") - }] : undefined - }); - } - - const installedBefore = new Set(installed.map(extension => extension.identifier.id.toLowerCase())); - const initiallySelected = new Set(items.filter(item => item.picked).map(item => item)); - const picked = await new Promise(resolve => { - const disposables = new DisposableStore(); - const quickPick = disposables.add(quickInputService.createQuickPick()); - let accepted: readonly CuratedQuickPickItem[] | undefined; - - quickPick.canSelectMany = true; - quickPick.title = localize('review.curated.title', "Manage Extensions"); - quickPick.placeholder = localize('review.curated.placeholder', "Select language groups to download, install, or enable"); - quickPick.items = items; - quickPick.selectedItems = items.filter(item => item.picked); - - const updateAcceptLabel = (selected: readonly CuratedQuickPickItem[]): void => { - const selectedSet = new Set(selected); - const selectedGroups = new Set(selected - .filter((item): item is CuratedQuickPickItem & { kind: 'optional' } => item.kind === 'optional') - .map(item => item.group)); - const installCount = whiteboardOptionalExtensionCatalog.filter(extension => - selectedGroups.has(extension.group) && !installedBefore.has(extension.id.toLowerCase()) - ).length; - const hasOtherChanges = items.some(item => { - if (initiallySelected.has(item) === selectedSet.has(item)) { - return false; - } - return item.kind !== 'optional' || !selectedSet.has(item) || - !whiteboardOptionalExtensionCatalog.some(extension => - extension.group === item.group && !installedBefore.has(extension.id.toLowerCase()) - ); - }); - - quickPick.okLabel = installCount > 0 && !hasOtherChanges - ? installCount === 1 - ? localize('review.curated.installOneExtension', "Install 1 extension") - : localize('review.curated.installManyExtensions', "Install {0} extensions", installCount) - : localize('review.curated.saveExtensions', "Save"); - }; - - updateAcceptLabel(quickPick.selectedItems); - disposables.add(quickPick.onDidChangeSelection(updateAcceptLabel)); - disposables.add(quickPick.onDidAccept(() => { - accepted = quickPick.selectedItems.slice(); - quickPick.hide(); - })); - disposables.add(quickPick.onDidTriggerItemButton(context => { - if (context.item.kind !== 'optional') { - return; - } - const item = context.item; - void (async () => { - const confirmation = await dialogService.confirm({ - type: 'warning', - message: localize('review.curated.confirmUninstall', "Uninstall {0}?", item.label), - detail: localize('review.curated.confirmUninstallDetail', "Whiteboard will remove all user-installed members of this language group."), - primaryButton: localize('review.curated.uninstallNow', "&&Uninstall") - }); - if (!confirmation.confirmed) { - return; - } - try { - const members = optionalGroupMemberIds(item.group); - const userMembers = (await extensionManagementService.getInstalled(ExtensionType.User)) - .filter(extension => members.some(id => areSameExtensions(extension.identifier, { id }))); - for (const extension of userMembers) { - await extensionManagementService.uninstall(extension, { - donotIncludePack: true, - donotCheckDependents: true - }); - const extensionId = ALL_CURATED_IDS.find(id => areSameExtensions(extension.identifier, { id })); - if (extensionId) { - whiteboardTelemetryService.capture('extension_uninstalled', { - extension_id: extensionId, - trigger: 'user' - }); - } - } - if (userMembers.length > 0) { - await whiteboardTelemetryService.flush(); - await commandService.executeCommand('workbench.action.reloadWindow'); - } - } catch (error) { - notificationService.error(localize( - 'review.curated.uninstallFailed', - "Whiteboard could not uninstall the optional extension group: {0}", - getErrorMessage(error) - )); - } - })(); - })); - disposables.add(quickPick.onDidHide(() => { - resolve(accepted); - disposables.dispose(); - })); - quickPick.show(); - }); - if (!picked) { - return; - } - - const selectedOptionalGroups = picked - .filter((item): item is CuratedQuickPickItem & { kind: 'optional' } => item.kind === 'optional') - .map(item => item.group); - let newInstalls: readonly ILocalExtension[]; - try { - newInstalls = await progressService.withProgress({ - location: ProgressLocation.Notification, - title: localize('review.curated.installingLanguageSupport', "Adding language support..."), - delay: 0 - }, progress => installMissingOptionalExtensions({ - groups: selectedOptionalGroups, - installedIds: installedBefore, - download: async extensionId => { - progress.report({ - message: localize( - 'review.curated.downloadingExtension', - "Downloading {0}...", - optionalExtensionLabel(extensionId) - ) - }); - return ipcRenderer.invoke( - 'vscode:whiteboardDownloadOptionalExtension', - extensionId - ) as Promise; - }, - install: async (extensionId, vsixPath) => { - progress.report({ - message: localize( - 'review.curated.installingExtension', - "Installing {0}...", - optionalExtensionLabel(extensionId) - ) - }); - return extensionManagementService.install(URI.file(vsixPath), { - donotIncludePackAndDependencies: true, - installGivenVersion: true, - pinned: true - }); - }, - rollback: extension => extensionManagementService.uninstall(extension, { - donotIncludePack: true, - donotCheckDependents: true - }), - onInstalled: (extensionId, trigger, durationMs) => { - whiteboardTelemetryService.capture('extension_installed', { - extension_id: extensionId, - trigger, - duration_ms: durationMs - }); - }, - onInstallFailed: (extensionId, trigger, phase) => { - whiteboardTelemetryService.capture('extension_install_failed', { - extension_id: extensionId, - trigger, - phase - }); - }, - onRolledBack: extensionId => { - whiteboardTelemetryService.capture('extension_uninstalled', { - extension_id: extensionId, - trigger: 'rollback' - }); - } - }, 'user')); - } catch (error) { - if (error instanceof OptionalExtensionInstallError) { - for (const rollbackError of error.rollbackErrors) { - notificationService.error(localize( - 'review.curated.rollbackFailed', - "Whiteboard could not roll back an optional extension: {0}", - getErrorMessage(rollbackError) - )); - } - const message = error.phase === 'download' - ? localize('review.curated.downloadFailed', "Whiteboard could not download an optional extension: {0}", getErrorMessage(error.originalError)) - : localize('review.curated.installFailed', "Whiteboard could not install an optional extension: {0}", getErrorMessage(error.originalError)); - notificationService.error(message); - } else { - notificationService.error(getErrorMessage(error)); - } - return; - } - - installed = await extensionManagementService.getInstalled(); - if (newInstalls.some(extension => areSameExtensions(extension.identifier, { id: 'rust-lang.rust-analyzer' }))) { - await stageRustAnalyzer(mainProcessService, logService); - } - let enabledIds = picked - .filter((item): item is CuratedQuickPickItem & { kind: 'bundled' } => item.kind === 'bundled') - .map(item => item.id); - for (const group of selectedOptionalGroups) { - enabledIds.push(...optionalGroupMemberIds(group)); - } - const pickedKeymaps = enabledIds.filter(id => KEYMAP_IDS.includes(id)); - if (pickedKeymaps.length > 1) { - // Keep the one that was off before, i.e. the one being turned on now. - const newlyEnabled = pickedKeymaps.find(id => isDisabled(disabled, id)) ?? pickedKeymaps[0]; - enabledIds = enabledIds.filter(id => !KEYMAP_IDS.includes(id) || id === newlyEnabled); - } - - const keymap = (Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) - .find(([, id]) => enabledIds.includes(id))?.[0] ?? 'none'; - const enablementChanged = await setCuratedExtensionsEnabled( - enablementService, - extensionManagementService, - enabledIds, - whiteboardTelemetryService, - 'user' - ); - const keymapChanged = configurationService.getValue(WHITEBOARD_KEYMAP_SETTING) !== keymap; - if (keymapChanged) { - await configurationService.updateValue(WHITEBOARD_KEYMAP_SETTING, keymap, ConfigurationTarget.USER); - } - if (newInstalls.length > 0 || enablementChanged || keymapChanged) { - await whiteboardTelemetryService.flush(); - await commandService.executeCommand('workbench.action.reloadWindow'); - } - } -} - -registerAction2(ManageCuratedExtensionsAction); - -class ImportUserConfigAction extends Action2 { - constructor() { - super({ - id: 'whiteboard.importUserConfig', - title: localize2('whiteboard.importUserConfig', "Whiteboard: Import VS Code Settings and Keybindings..."), - f1: true, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const dialogService = accessor.get(IDialogService); - const commandService = accessor.get(ICommandService); - - try { - const preview = await ipcRenderer.invoke( - 'vscode:whiteboardImportUserConfig', - { mode: 'preview' }, - ) as WhiteboardUserConfigImportResult; - if (preview.status === 'disabled') { - await dialogService.info( - localize('whiteboard.importUserConfig.disabled', "VS Code settings import is disabled."), - localize('whiteboard.importUserConfig.disabledDetail', "Unset DEV_WHITEBOARD_IMPORT_FROM=none and restart Whiteboard to enable imports."), - ); - return; - } - if (preview.status === 'not-found' || !preview.source) { - await dialogService.info( - localize('whiteboard.importUserConfig.notFound', "No VS Code settings were found."), - localize('whiteboard.importUserConfig.notFoundDetail', "Whiteboard checks Code, Code - Insiders, VSCodium, and Cursor's default profiles."), - ); - return; - } - - const overwriteDetail = preview.wouldOverwrite.length > 0 - ? localize( - 'whiteboard.importUserConfig.overwriteDetail', - "The following Whiteboard files will be overwritten:\n{0}", - preview.wouldOverwrite.join('\n'), - ) - : localize( - 'whiteboard.importUserConfig.createDetail', - "Whiteboard will create settings files under its user profile. Source:\n{0}", - preview.source, - ); - const confirmation = await dialogService.confirm({ - type: 'warning', - message: localize('whiteboard.importUserConfig.confirm', "Import VS Code settings and keybindings?"), - detail: overwriteDetail, - primaryButton: localize('whiteboard.importUserConfig.import', "Import"), - }); - if (!confirmation.confirmed) { - return; - } - - const result = await ipcRenderer.invoke( - 'vscode:whiteboardImportUserConfig', - { mode: 'apply' }, - ) as WhiteboardUserConfigImportResult; - if (result.status !== 'imported') { - throw new Error(`Unexpected Whiteboard user-config import result: ${result.status}`); - } - - const reload = await dialogService.confirm({ - type: 'info', - message: localize('whiteboard.importUserConfig.complete', "VS Code settings and keybindings were imported."), - detail: localize('whiteboard.importUserConfig.reloadDetail', "Reload Whiteboard to apply keybindings and keymap extension changes."), - primaryButton: localize('whiteboard.importUserConfig.reload', "Reload"), - }); - if (reload.confirmed) { - await commandService.executeCommand('workbench.action.reloadWindow'); - } - } catch (error) { - await dialogService.error( - localize('whiteboard.importUserConfig.error', "Whiteboard could not import VS Code settings and keybindings."), - String(error), - ); - } - } -} - -registerAction2(ImportUserConfigAction); - -MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { - command: { - id: 'whiteboard.manageExtensions', - title: localize('whiteboard.manageExtensions.menu', "Manage Extensions...") - }, - order: 1 -}); - -/** - * Seeds the shipped keymap defaults once per profile. An imported whiteboard.keymap - * selects Vim or Emacs; otherwise both remain off. After that the user's choice - * in the picker wins. - */ -class CuratedExtensionDefaults implements IWorkbenchContribution { - constructor( - @IStorageService storageService: IStorageService, - @IGlobalExtensionEnablementService enablementService: IGlobalExtensionEnablementService, - @IConfigurationService configurationService: IConfigurationService, - @ICommandService commandService: ICommandService, - @IWhiteboardTelemetryService whiteboardTelemetryService: IWhiteboardTelemetryService, - ) { - const alreadySeeded = storageService.getBoolean(SEEDED_STORAGE_KEY, StorageScope.APPLICATION, false); - const keymap = configurationService.getValue(WHITEBOARD_KEYMAP_SETTING); - const disabled = enablementService.getDisabledExtensions(); - const keymapStateMatches = (Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) - .every(([candidate, id]) => isDisabled(disabled, id) === (candidate !== keymap)); - // `applyKeymapDefault` reloads only when it actually flips an extension, which is - // exactly when the disabled set does not match the keymap yet. Record that now so - // first-run prompts skip themselves instead of being eaten by the reload. - setFirstRunReloadPending(!keymapStateMatches); - if (alreadySeeded && keymapStateMatches) { - return; - } - if (!alreadySeeded) { - storageService.store(SEEDED_STORAGE_KEY, true, StorageScope.APPLICATION, StorageTarget.MACHINE); - } - void this.applyKeymapDefault(keymap, enablementService, commandService, whiteboardTelemetryService); - } - - private async applyKeymapDefault( - keymap: WhiteboardKeymap, - enablementService: IGlobalExtensionEnablementService, - commandService: ICommandService, - whiteboardTelemetryService: IWhiteboardTelemetryService, - ): Promise { - let changed = false; - for (const [candidate, id] of Object.entries(KEYMAP_EXTENSION_IDS) as [Exclude, string][]) { - const didChange = candidate === keymap - ? await enablementService.enableExtension({ id }) - : await enablementService.disableExtension({ id }); - if (didChange) { - whiteboardTelemetryService.capture(candidate === keymap ? 'extension_enabled' : 'extension_disabled', { - extension_id: id, - trigger: 'startup_seed' - }); - } - changed ||= didChange; - } - if (changed) { - await whiteboardTelemetryService.flush(); - await commandService.executeCommand('workbench.action.reloadWindow'); - } - } -} - -class OptionalExtensionPinUpgrades implements IWorkbenchContribution { - constructor( - @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, - @IMainProcessService private readonly mainProcessService: IMainProcessService, - @ILogService private readonly logService: ILogService, - @IWhiteboardTelemetryService private readonly whiteboardTelemetryService: IWhiteboardTelemetryService - ) { - void this.run().catch(error => { - this.logService.error(`[Whiteboard extensions] Could not check optional extension pins: ${getErrorMessage(error)}`); - }); - } - - private async run(): Promise { - const installed = await this.extensionManagementService.getInstalled(ExtensionType.User); - await upgradeOptionalExtensionPins({ - installed: installed.map(extension => ({ - id: extension.identifier.id, - version: extension.manifest.version - })), - download: extensionId => ipcRenderer.invoke( - 'vscode:whiteboardDownloadOptionalExtension', - extensionId - ) as Promise, - install: async (_extensionId, vsixPath) => { - await this.extensionManagementService.install(URI.file(vsixPath), { - donotIncludePackAndDependencies: true, - installGivenVersion: true, - pinned: true - }); - }, - stageRustAnalyzer: () => stageRustAnalyzer(this.mainProcessService, this.logService), - logError: (message, error) => { - this.logService.error(`[Whiteboard extensions] ${message}: ${getErrorMessage(error)}`); - }, - onInstalled: (extensionId, trigger, durationMs) => { - this.whiteboardTelemetryService.capture('extension_installed', { - extension_id: extensionId, - trigger, - duration_ms: durationMs - }); - }, - onInstallFailed: (extensionId, trigger, phase) => { - this.whiteboardTelemetryService.capture('extension_install_failed', { - extension_id: extensionId, - trigger, - phase - }); - } - }, 'auto_upgrade'); - } -} - -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( - CuratedExtensionDefaults, - LifecyclePhase.Restored -); -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( - OptionalExtensionPinUpgrades, - LifecyclePhase.Eventually -); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/extensions/whiteboardOptionalExtensionManagement.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/extensions/whiteboardOptionalExtensionManagement.ts deleted file mode 100644 index 0ca291aa0..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/extensions/whiteboardOptionalExtensionManagement.ts +++ /dev/null @@ -1,171 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { whiteboardOptionalExtensionCatalog } from '../../node/whiteboardOptionalExtensionCatalog.js'; -import * as semver from '../../../base/common/semver/semver.js'; - -export type OptionalExtensionInstallPhase = 'download' | 'install'; -export type OptionalExtensionInstallTrigger = 'user' | 'auto_upgrade'; - -export class OptionalExtensionInstallError extends Error { - constructor( - readonly phase: OptionalExtensionInstallPhase, - readonly extensionId: string, - readonly originalError: unknown, - readonly rollbackErrors: readonly unknown[] = [] - ) { - super(`Optional extension ${phase} failed`); - } -} - -export interface OptionalExtensionInstallCallbacks { - readonly onInstalled?: (extensionId: string, trigger: OptionalExtensionInstallTrigger, durationMs: number) => void; - readonly onInstallFailed?: (extensionId: string, trigger: OptionalExtensionInstallTrigger, phase: OptionalExtensionInstallPhase) => void; -} - -export interface OptionalExtensionInstallTransaction extends OptionalExtensionInstallCallbacks { - readonly groups: readonly string[]; - readonly installedIds: ReadonlySet; - readonly download: (extensionId: string) => Promise; - readonly install: (extensionId: string, vsixPath: string) => Promise; - readonly rollback: (installed: T) => Promise; - readonly onRolledBack?: (extensionId: string) => void; -} - -/** Support extensions install before the primary extension that activates them. */ -function compareOptionalExtensionInstallOrder( - left: { readonly role: string }, - right: { readonly role: string } -): number { - if (left.role === right.role) { - return 0; - } - return left.role === 'support' ? -1 : 1; -} - -export async function installMissingOptionalExtensions( - transaction: OptionalExtensionInstallTransaction, - trigger: OptionalExtensionInstallTrigger = 'user' -): Promise { - const requestedGroups = new Set(transaction.groups); - const missing = whiteboardOptionalExtensionCatalog.filter(extension => - requestedGroups.has(extension.group) && !transaction.installedIds.has(extension.id) - ); - if (missing.length === 0) { - return []; - } - - const downloads = new Map(); - const startedAt = new Map(); - await Promise.all(missing.map(async extension => { - startedAt.set(extension.id, Date.now()); - try { - downloads.set(extension.id, await transaction.download(extension.id)); - } catch (error) { - transaction.onInstallFailed?.(extension.id, trigger, 'download'); - throw new OptionalExtensionInstallError('download', extension.id, error); - } - })); - - const installed: { readonly extensionId: string; readonly local: T }[] = []; - const installOrder = [...missing].sort(compareOptionalExtensionInstallOrder); - try { - for (const extension of installOrder) { - const vsixPath = downloads.get(extension.id); - if (!vsixPath) { - throw new Error(`Missing verified VSIX path for ${extension.id}`); - } - try { - const local = await transaction.install(extension.id, vsixPath); - installed.push({ extensionId: extension.id, local }); - transaction.onInstalled?.(extension.id, trigger, Date.now() - (startedAt.get(extension.id) ?? Date.now())); - } catch (error) { - transaction.onInstallFailed?.(extension.id, trigger, 'install'); - throw new OptionalExtensionInstallError('install', extension.id, error); - } - } - return installed.map(entry => entry.local); - } catch (error) { - const rollbackErrors: unknown[] = []; - for (const entry of installed.reverse()) { - try { - await transaction.rollback(entry.local); - transaction.onRolledBack?.(entry.extensionId); - } catch (rollbackError) { - rollbackErrors.push(rollbackError); - } - } - if (error instanceof OptionalExtensionInstallError) { - throw new OptionalExtensionInstallError(error.phase, error.extensionId, error.originalError, rollbackErrors); - } - throw error; - } -} - -export function optionalGroupMemberIds(group: string): readonly string[] { - return whiteboardOptionalExtensionCatalog - .filter(extension => extension.group === group) - .map(extension => extension.id); -} - -export interface InstalledOptionalExtensionPin { - readonly id: string; - readonly version: string; -} - -export interface OptionalExtensionPinUpgradeTransaction extends OptionalExtensionInstallCallbacks { - readonly installed: readonly InstalledOptionalExtensionPin[]; - readonly download: (extensionId: string) => Promise; - readonly install: (extensionId: string, vsixPath: string) => Promise; - readonly stageRustAnalyzer: () => Promise; - readonly logError: (message: string, error: unknown) => void; -} - -export async function upgradeOptionalExtensionPins( - transaction: OptionalExtensionPinUpgradeTransaction, - trigger: OptionalExtensionInstallTrigger = 'auto_upgrade' -): Promise { - const installed = new Map(transaction.installed.map(extension => [extension.id.toLowerCase(), extension.version])); - const changed: string[] = []; - for (const group of new Set(whiteboardOptionalExtensionCatalog.map(extension => extension.group))) { - const primary = whiteboardOptionalExtensionCatalog.find(extension => extension.group === group && extension.role === 'primary'); - if (!primary || !installed.has(primary.id)) { - continue; - } - - const members = whiteboardOptionalExtensionCatalog - .filter(extension => extension.group === group) - .sort(compareOptionalExtensionInstallOrder); - for (const extension of members) { - const currentVersion = installed.get(extension.id); - if (currentVersion && !semver.lt(currentVersion, extension.version)) { - continue; - } - const startedAt = Date.now(); - let vsixPath: string; - try { - vsixPath = await transaction.download(extension.id); - } catch (error) { - transaction.onInstallFailed?.(extension.id, trigger, 'download'); - transaction.logError(`Could not update optional extension ${extension.id}`, error); - break; - } - try { - await transaction.install(extension.id, vsixPath); - installed.set(extension.id, extension.version); - changed.push(extension.id); - transaction.onInstalled?.(extension.id, trigger, Date.now() - startedAt); - if (extension.id === 'rust-lang.rust-analyzer') { - await transaction.stageRustAnalyzer(); - } - } catch (error) { - transaction.onInstallFailed?.(extension.id, trigger, 'install'); - transaction.logError(`Could not update optional extension ${extension.id}`, error); - break; - } - } - } - return changed; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/install/whiteboardCliInstall.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/install/whiteboardCliInstall.contribution.ts deleted file mode 100644 index bfa34b14f..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/install/whiteboardCliInstall.contribution.ts +++ /dev/null @@ -1,294 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { isCancellationError } from "../../../base/common/errors.js"; -import { isLinux, isMacintosh } from "../../../base/common/platform.js"; -import { localize, localize2 } from "../../../nls.js"; -import { Action2, registerAction2 } from "../../../platform/actions/common/actions.js"; -import { IDialogService } from "../../../platform/dialogs/common/dialogs.js"; -import type { ServicesAccessor } from "../../../platform/instantiation/common/instantiation.js"; -import { INativeHostService } from "../../../platform/native/common/native.js"; -import { INotificationService } from "../../../platform/notification/common/notification.js"; -import { Registry } from "../../../platform/registry/common/platform.js"; -import { IStorageService, StorageScope } from "../../../platform/storage/common/storage.js"; -import { - Extensions as WorkbenchExtensions, - type IWorkbenchContribution, - type IWorkbenchContributionsRegistry, -} from "../../../workbench/common/contributions.js"; -import { INativeWorkbenchEnvironmentService } from "../../../workbench/services/environment/electron-browser/environmentService.js"; -import { LifecyclePhase } from "../../../workbench/services/lifecycle/common/lifecycle.js"; -import { whiteboardCliInstallStartupAction } from "../../common/whiteboardCliInstallStartup.js"; -import { WHITEBOARD_TUTORIAL_PROGRESS_STORAGE_KEY } from "../../common/whiteboardProtocol.js"; -import { IWhiteboardApiCatalogService } from "../../services/whiteboardApiCatalogService.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../services/whiteboardCanvasEditorTabsService.js"; -import { IWhiteboardDesktopConnectionService } from "../../services/whiteboardDesktopConnectionService.js"; - -/** - * The macOS app bundle that contains this build, derived from the resources - * path inside it. Development runs live outside a bundle and return undefined. - */ -function macAppBundlePath(appRoot: string): string | undefined { - const marker = appRoot.indexOf(".app/"); - return marker === -1 ? undefined : appRoot.slice(0, marker + ".app".length); -} - -class OpenWelcomeAction extends Action2 { - constructor() { - super({ - id: "whiteboard.openWelcome", - title: localize2("review.welcome", "Whiteboard: Welcome..."), - f1: true, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - await accessor.get(IWhiteboardCanvasEditorTabsService).openWelcome(true); - } -} - -registerAction2(OpenWelcomeAction); - -class OpenTutorialAction extends Action2 { - constructor() { - super({ - id: "whiteboard.openTutorial", - title: localize2("whiteboard.openTutorial", "Whiteboard: Open Tutorial..."), - f1: true, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const notificationService = accessor.get(INotificationService); - const desktopConnection = accessor.get(IWhiteboardDesktopConnectionService); - const tabsService = accessor.get(IWhiteboardCanvasEditorTabsService); - try { - const opened = await desktopConnection.openTutorial(); - await tabsService.openApiWhiteboard(opened.sessionId, opened.title); - } catch (error) { - notificationService.error( - localize("review.tutorial.failed", "Whiteboard could not open the tutorial: {0}", String(error)), - ); - } - } -} - -registerAction2(OpenTutorialAction); - -class InstallWhiteboardCliInPathAction extends Action2 { - constructor() { - super({ - id: "whiteboard.installCliInPath", - title: localize2("whiteboard.installCliInPath", "Whiteboard: Install CLI in PATH"), - f1: true, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const nativeHostService = accessor.get(INativeHostService); - const notificationService = accessor.get(INotificationService); - const desktopConnection = accessor.get(IWhiteboardDesktopConnectionService); - try { - if (isMacintosh) { - await nativeHostService.uninstallShellCommand({ commandName: "review", symlinkOnly: true }); - } - const installed = await desktopConnection.applyCliInstall({ shim: true }); - notificationService.info( - localize( - "review.cliInstall.installed", - "Whiteboard installed the CLI at {0}. New terminals can use the whiteboard command.", - installed.shimPath ?? "~/.local/bin/whiteboard", - ), - ); - } catch (error) { - if (isCancellationError(error)) { - return; - } - notificationService.error( - localize("review.cliInstall.failed", "Whiteboard could not install the CLI in PATH: {0}", String(error)), - ); - } - } -} - -registerAction2(InstallWhiteboardCliInPathAction); - -/** - * Removes everything the app installed on this machine: the tutorial, the - * whiteboard terminal command, managed trace capture, and the consent stamp. It then - * points at the app bundle so the user can move it to the Trash. Other Whiteboard - * data stays untouched. Resetting the stamp makes a later reinstall start as - * a first run. - */ -class UninstallWhiteboardDesktopAction extends Action2 { - constructor() { - super({ - id: "whiteboard.uninstallApp", - title: localize2("whiteboard.uninstallApp", "Whiteboard: Uninstall Whiteboard..."), - f1: true, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - const dialogService = accessor.get(IDialogService); - const environmentService = accessor.get(INativeWorkbenchEnvironmentService); - const nativeHostService = accessor.get(INativeHostService); - const desktopConnection = accessor.get(IWhiteboardDesktopConnectionService); - const storageService = accessor.get(IStorageService); - - const status = await desktopConnection.getCliInstallStatus(); - const detail = [ - status.stamp?.shimPath - ? localize("whiteboard.uninstall.shim", "Removes the whiteboard terminal command at {0}.", status.stamp.shimPath) - : localize("whiteboard.uninstall.noShim", "The whiteboard terminal command is not installed."), - status.stamp?.traceManaged - ? localize( - "review.uninstall.trace", - "Disables trace capture and restores hook paths for known repositories. R2 credentials stay on disk.", - ) - : localize("review.uninstall.noTrace", "Trace capture is not managed by Whiteboard."), - localize("review.uninstall.tutorial", "Removes the bundled tutorial repository and session."), - localize("review.uninstall.keepsData", "Your sessions and their history stay on disk."), - ].join("\n"); - const { confirmed } = await dialogService.confirm({ - message: localize("review.uninstall.confirm", "Remove everything Whiteboard installed on this machine?"), - detail, - primaryButton: localize("review.uninstall.remove", "&&Remove"), - }); - if (!confirmed) { - return; - } - - // The tutorial is disposable state: a failed delete must not stop - // the command removal the user just confirmed. - let tutorialError: unknown; - try { - await desktopConnection.deleteTutorial(); - storageService.remove(WHITEBOARD_TUTORIAL_PROGRESS_STORAGE_KEY, StorageScope.APPLICATION); - } catch (error) { - tutorialError = error; - } - try { - await desktopConnection.removeCliInstall({ - shim: true, - ...(status.stamp?.traceManaged ? { trace: true } : {}), - }); - await desktopConnection.resetCliInstallPrompts(); - if (tutorialError) { - await dialogService.error( - localize("review.uninstall.tutorialFailed", "Whiteboard could not remove the tutorial data at ~/.dev/tutorial."), - String(tutorialError), - ); - } - } catch (error) { - await dialogService.error( - localize("whiteboard.uninstall.failed", "Whiteboard could not remove its command and trace setup."), - String(error), - ); - return; - } - - if (isLinux) { - await dialogService.info( - localize("review.uninstall.linuxDone", "Whiteboard’s user-installed integrations were removed."), - localize( - "review.uninstall.linuxFinish", - "To remove the app, quit Whiteboard and run sudo apt remove dev-fast-review on Ubuntu, or sudo pacman -R dev-fast-review on Omarchy / Arch. Your sessions and settings stay on disk.", - ), - ); - return; - } - - const bundlePath = macAppBundlePath(environmentService.appRoot); - if (bundlePath) { - const { confirmed: reveal } = await dialogService.confirm({ - message: localize("whiteboard.uninstall.done", "Whiteboard's command and trace setup were removed."), - detail: localize( - "review.uninstall.finish", - "To finish, quit Whiteboard and move {0} to the Trash.", - bundlePath, - ), - primaryButton: localize("review.uninstall.reveal", "&&Show in Finder"), - cancelButton: localize("review.uninstall.close", "Close"), - }); - if (reveal) { - await nativeHostService.showItemInFolder(bundlePath); - } - } else { - await dialogService.info( - localize("whiteboard.uninstall.done", "Whiteboard's command and trace setup were removed."), - localize("whiteboard.uninstall.finishDev", "This is a development build, so there is no app bundle to remove."), - ); - } - } -} - -registerAction2(UninstallWhiteboardDesktopAction); - -/** - * First-run onboarding, the upgrade screen, and silent re-sync. Consent lives in the server's - * install stamp (~/.dev/review-desktop/state/cli-install.json), not workbench - * storage, so the CLI and the app read one source of truth: - * - no stamp: open no tab; empty Home renders the Welcome rail, and - * Preferences > Getting Started reaches the same pane when Home has - * whiteboards to list instead; - * - granted + stamp without the update marker: open Welcome, which shows the - * update screen, unless empty Home already renders the Welcome rail; - * - granted + stale CLI fingerprint: rewrite the whiteboard command silently; - * - declined or skipped: never open automatically (the menu action stays available). - * - * Dev sessions (`pnpm dev`, isBuilt false) never auto-open. - */ -class WhiteboardCliInstallStartup implements IWorkbenchContribution { - constructor( - @INativeWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService, - @INotificationService private readonly notificationService: INotificationService, - @IWhiteboardDesktopConnectionService private readonly whiteboardDesktopConnectionService: IWhiteboardDesktopConnectionService, - @IWhiteboardCanvasEditorTabsService private readonly tabsService: IWhiteboardCanvasEditorTabsService, - @IWhiteboardApiCatalogService private readonly apiCatalog: IWhiteboardApiCatalogService, - ) { - if (!environmentService.isBuilt) { - return; - } - void this.check().catch((error) => { - this.notificationService.warn( - localize( - "whiteboard.cliInstall.updateFailed", - "Whiteboard could not update its CLI: {0}. Retry from Getting Started, or restart Whiteboard.", - String(error), - ), - ); - }); - } - - private async check(): Promise { - const status = await this.whiteboardDesktopConnectionService.getCliInstallStatus(); - switch (whiteboardCliInstallStartupAction(status)) { - case "openWelcome": - // With no whiteboards to list, Home already renders the Welcome - // rail, so opening a tab here would show it twice. - await this.apiCatalog.initialize(); - if (this.apiCatalog.reviews.length > 0) await this.tabsService.openWelcome(true); - return; - case "resync": - // Without an installed command there is nothing to rewrite or announce. - if (!status.stamp?.shimPath || status.stamp.commandDisabled) return; - await this.whiteboardDesktopConnectionService.applyCliInstall({ - shim: true, - autoUpdate: true, - }); - // Whiteboard has no status bar; status() messages would be dropped. - this.notificationService.info(localize("whiteboard.cliInstall.resyncedCli", "Whiteboard updated the installed CLI.")); - return; - case "none": - return; - } - } -} - -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( - WhiteboardCliInstallStartup, - LifecyclePhase.Restored, -); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/quickaccess/whiteboardQuickAccess.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/quickaccess/whiteboardQuickAccess.contribution.ts deleted file mode 100644 index 3dbea1123..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/quickaccess/whiteboardQuickAccess.contribution.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken } from '../../../base/common/cancellation.js'; -import { localize } from '../../../nls.js'; -import { MenuRegistry, registerAction2 } from '../../../platform/actions/common/actions.js'; -import { CommandsRegistry, ICommandService } from '../../../platform/commands/common/commands.js'; -import { IDialogService } from '../../../platform/dialogs/common/dialogs.js'; -import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js'; -import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js'; -import { AbstractCommandsQuickAccessProvider, type ICommandQuickPick } from '../../../platform/quickinput/browser/commandsQuickAccess.js'; -import { Extensions, type IQuickAccessRegistry } from '../../../platform/quickinput/common/quickAccess.js'; -import { Registry } from '../../../platform/registry/common/platform.js'; -import { ITelemetryService } from '../../../platform/telemetry/common/telemetry.js'; -import { ShowAllCommandsAction } from '../../../workbench/contrib/quickaccess/browser/commandsQuickAccess.js'; -import { IExtensionService } from '../../../workbench/services/extensions/common/extensions.js'; -import { whiteboardCommandPaletteLabel } from '../../common/whiteboardCommandPalette.js'; - -const FOREIGN_COMMAND = /chat|debug|extension|git|keybinding|mcp|notebook|preference|profile|remote|scm|setting|sync|task|terminal|test|update/i; - -export class WhiteboardCommandsQuickAccessProvider extends AbstractCommandsQuickAccessProvider { - constructor( - @IInstantiationService instantiationService: IInstantiationService, - @IKeybindingService keybindingService: IKeybindingService, - @ICommandService commandService: ICommandService, - @ITelemetryService telemetryService: ITelemetryService, - @IDialogService dialogService: IDialogService, - @IExtensionService private readonly extensionService: IExtensionService, - ) { - super({ showAlias: false }, instantiationService, keybindingService, commandService, telemetryService, dialogService); - } - - protected override async getCommandPicks(token: CancellationToken): Promise { - if (token.isCancellationRequested) return []; - await this.extensionService.whenInstalledExtensionsRegistered(); - if (token.isCancellationRequested) return []; - const extensionCommands = new Set( - this.extensionService.extensions.flatMap(extension => - extension.contributes?.commands?.map(command => command.command) ?? [] - ) - ); - return [...CommandsRegistry.getCommands().keys()] - .filter(commandId => commandId.startsWith('review.') || extensionCommands.has(commandId) || !FOREIGN_COMMAND.test(commandId)) - .sort((left, right) => left.localeCompare(right)) - .map(commandId => ({ - commandId, - label: whiteboardCommandPaletteLabel(commandId, MenuRegistry.getCommand(commandId)), - })); - } - - protected override hasAdditionalCommandPicks(_filter: string, _token: CancellationToken): boolean { - return false; - } - - protected override async getAdditionalCommandPicks( - _allPicks: ICommandQuickPick[], - _picksSoFar: ICommandQuickPick[], - _filter: string, - _token: CancellationToken, - ): Promise { - return []; - } -} - -Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ - ctor: WhiteboardCommandsQuickAccessProvider, - prefix: WhiteboardCommandsQuickAccessProvider.PREFIX, - contextKey: 'inCommandsPicker', - placeholder: localize('whiteboardCommandsQuickAccessPlaceholder', 'Type the name of an editor or Whiteboard command to run.'), - helpEntries: [{ - description: localize('whiteboardCommandsQuickAccess', 'Show and run Whiteboard commands'), - commandId: ShowAllCommandsAction.ID, - commandCenterOrder: 20 - }] -}); - -registerAction2(ShowAllCommandsAction); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/settings/whiteboardSettings.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/settings/whiteboardSettings.contribution.ts deleted file mode 100644 index e04467cb8..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/settings/whiteboardSettings.contribution.ts +++ /dev/null @@ -1,35 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize2 } from '../../../nls.js'; -import { KeyCode, KeyMod } from '../../../base/common/keyCodes.js'; -import { Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; -import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; -import { KeybindingWeight } from '../../../platform/keybinding/common/keybindingsRegistry.js'; -import { IWhiteboardCanvasEditorTabsService } from '../../services/whiteboardCanvasEditorTabsService.js'; - -/** - * Opens the Settings canvas tab. Review does not register the stock settings - * editor, so this tab is the only settings surface in the app. - */ -class OpenWhiteboardSettingsAction extends Action2 { - constructor() { - super({ - id: 'whiteboard.openSettings', - title: localize2('whiteboard.openSettings', "Whiteboard: Settings..."), - f1: true, - keybinding: { - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyMod.CtrlCmd | KeyCode.Comma, - }, - }); - } - - override async run(accessor: ServicesAccessor): Promise { - await accessor.get(IWhiteboardCanvasEditorTabsService).openSettings(true); - } -} - -registerAction2(OpenWhiteboardSettingsAction); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/sharing/whiteboardSharing.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/sharing/whiteboardSharing.contribution.ts deleted file mode 100644 index 0f5a0fcac..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/sharing/whiteboardSharing.contribution.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Disposable } from "../../../base/common/lifecycle.js"; -import { URI } from "../../../base/common/uri.js"; -import { localize2 } from "../../../nls.js"; -import { Action2, registerAction2 } from "../../../platform/actions/common/actions.js"; -import type { ServicesAccessor } from "../../../platform/instantiation/common/instantiation.js"; -import { - INotificationService, - Severity, -} from "../../../platform/notification/common/notification.js"; -import { IProgressService, ProgressLocation } from "../../../platform/progress/common/progress.js"; -import { IQuickInputService } from "../../../platform/quickinput/common/quickInput.js"; -import { IURLService, type IURLHandler } from "../../../platform/url/common/url.js"; -import { - registerWorkbenchContribution2, - WorkbenchPhase, -} from "../../../workbench/common/contributions.js"; -import { SessionApiClient } from "../../common/whiteboardProtocol.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../services/whiteboardCanvasEditorTabsService.js"; -import { IWhiteboardDesktopConnectionService } from "../../services/whiteboardDesktopConnectionService.js"; - -async function openShare( - url: string, - session: IWhiteboardDesktopConnectionService, - tabs: IWhiteboardCanvasEditorTabsService, - notifications: INotificationService, - progress: IProgressService, -) { - try { - const client = new SessionApiClient({ ...await session.getConnection(), apiPath: "/sessions-api" }); - await progress.withProgress({ location: ProgressLocation.Notification, title: "Opening shared review" }, async (reporter) => { - const started = await client.post<{ sessionId: string }>("/sharing/import", { url }); - for (;;) { - const status = await client.read<{ stage: string; title?: string; error?: string }>(`/sharing/import/${started.sessionId}`); - if (status.stage === "error") throw new Error(status.error ?? "Could not open the shared session."); - if (status.stage === "ready") { - await tabs.openApiWhiteboard(started.sessionId, status.title ?? "Shared review"); - return; - } - const message = status.stage === "fetching" - ? "Fetching pinned GitHub commits…" - : status.stage === "validating" - ? "Preparing pinned source…" - : "Downloading review resources…"; - reporter.report({ message }); - await new Promise((resolve) => setTimeout(resolve, 500)); - } - }); - } catch (error) { - notifications.prompt( - Severity.Error, - error instanceof Error ? error.message : "Could not open the shared session.", - [{ label: "Retry", run: () => openShare(url, session, tabs, notifications, progress) }], - ); - } -} - -class SharedWhiteboardUrlHandler extends Disposable implements IURLHandler { - constructor( - @IURLService urls: IURLService, - @IWhiteboardDesktopConnectionService private readonly session: IWhiteboardDesktopConnectionService, - @IWhiteboardCanvasEditorTabsService private readonly tabs: IWhiteboardCanvasEditorTabsService, - @INotificationService private readonly notifications: INotificationService, - @IProgressService private readonly progress: IProgressService, - ) { - super(); - this._register(urls.registerHandler(this)); - } - async handleURL(uri: URI): Promise { - if (uri.authority !== "share") return false; - try { - const origin = new URLSearchParams(uri.query).get("origin") ?? "https://app.dev.fast"; - const url = new URL(`/s${uri.path}`, origin); - url.hash = uri.fragment; - await openShare(url.href, this.session, this.tabs, this.notifications, this.progress); - } catch { - this.notifications.error("Invalid Whiteboard share link."); - } - return true; - } -} -registerWorkbenchContribution2( - "review.sharing.urls", - SharedWhiteboardUrlHandler, - WorkbenchPhase.BlockRestore, -); -registerAction2( - class extends Action2 { - constructor() { - super({ - id: "whiteboard.openSharedSession", - title: localize2("whiteboard.openSharedSession", "Open Shared Session"), - f1: true, - }); - } - async run(accessor: ServicesAccessor) { - const session = accessor.get(IWhiteboardDesktopConnectionService), - tabs = accessor.get(IWhiteboardCanvasEditorTabsService), - notifications = accessor.get(INotificationService), - progress = accessor.get(IProgressService); - const url = await accessor - .get(IQuickInputService) - .input({ - prompt: "Paste a Whiteboard share link", - placeHolder: "https://app.dev.fast/s/…", - ignoreFocusLost: true, - }); - if (url) await openShare(url, session, tabs, notifications, progress); - } - }, -); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardLspTelemetry.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardLspTelemetry.contribution.ts deleted file mode 100644 index 986a7709a..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardLspTelemetry.contribution.ts +++ /dev/null @@ -1,272 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { RunOnceScheduler } from '../../../base/common/async.js'; -import { Disposable, DisposableStore } from '../../../base/common/lifecycle.js'; -import type { ICodeEditor } from '../../../editor/browser/editorBrowser.js'; -import { MouseTargetType } from '../../../editor/browser/editorBrowser.js'; -import { ICodeEditorService } from '../../../editor/browser/services/codeEditorService.js'; -import { ContentHoverController } from '../../../editor/contrib/hover/browser/contentHoverController.js'; -import { ClickLinkGesture } from '../../../editor/contrib/gotoSymbol/browser/link/clickLinkGesture.js'; -import { ILanguageFeaturesService } from '../../../editor/common/services/languageFeatures.js'; -import type { ITextModel } from '../../../editor/common/model.js'; -import { ModelDecorationInjectedTextOptions } from '../../../editor/common/model/textModel.js'; -import { IModelService } from '../../../editor/common/services/model.js'; -import { ICommandService } from '../../../platform/commands/common/commands.js'; -import { Registry } from '../../../platform/registry/common/platform.js'; -import { - Extensions as WorkbenchExtensions, - type IWorkbenchContribution, - type IWorkbenchContributionsRegistry, -} from '../../../workbench/common/contributions.js'; -import { IExtensionService } from '../../../workbench/services/extensions/common/extensions.js'; -import { LifecyclePhase } from '../../../workbench/services/lifecycle/common/lifecycle.js'; -import { WhiteboardEmbeddedEditors } from '../../services/whiteboardEmbeddedEditors.js'; -import { IWhiteboardTelemetryService } from '../../services/whiteboardTelemetryService.js'; - -const HOVER_DWELL_MS = 1_000; -const HOVER_VISIBILITY_POLL_MS = 100; -const LS_ACTIVATION_WAIT_MS = 10_000; - -const LANGUAGE_MAP: Record = { - typescript: 'typescript', - typescriptreact: 'typescript', - javascript: 'javascript', - javascriptreact: 'javascript', - python: 'python', - go: 'go', - rust: 'rust', - swift: 'swift', - csharp: 'csharp', - json: 'json', - jsonc: 'json', - css: 'css', - scss: 'css', - less: 'css', - html: 'html', - markdown: 'markdown', - yaml: 'yaml', - toml: 'toml', - shellscript: 'shell', - sql: 'sql', -}; - -function toLspLanguage(languageId: string): string { - return Object.prototype.hasOwnProperty.call(LANGUAGE_MAP, languageId) - ? LANGUAGE_MAP[languageId] - : 'other'; -} - -const LSP_COMMANDS: Record = { - 'editor.action.revealDefinition': 'goto_definition', - 'editor.action.revealDefinitionAside': 'goto_definition', - 'editor.action.goToDeclaration': 'goto_definition', - 'editor.action.revealDeclaration': 'goto_definition', - 'editor.action.peekDefinition': 'peek_definition', - 'editor.action.peekDeclaration': 'peek_definition', - 'editor.action.previewDeclaration': 'peek_definition', - 'editor.action.goToTypeDefinition': 'goto_type_definition', - 'editor.action.peekTypeDefinition': 'goto_type_definition', - 'editor.action.goToImplementation': 'goto_implementation', - 'editor.action.peekImplementation': 'goto_implementation', - 'editor.action.goToReferences': 'references', - 'editor.action.referenceSearch.trigger': 'references', - 'editor.action.findReferences': 'references', - 'editor.action.rename': 'rename', - 'editor.action.formatDocument': 'format', - 'editor.action.formatSelection': 'format', - 'editor.action.quickFix': 'code_action', - 'editor.action.showHover': 'hover', - 'editor.action.showDefinitionPreviewHover': 'hover', - 'workbench.action.gotoSymbol': 'symbol_search', -}; - -const LS_EXTENSIONS: Record = { - python: 'astral-sh.ty', - go: 'golang.go', - rust: 'rust-lang.rust-analyzer', - swift: 'swiftlang.swift-vscode', - csharp: 'muhammad-sammy.csharp', -}; - -class WhiteboardLspTelemetryContribution extends Disposable implements IWorkbenchContribution { - private readonly editorStores = new Map(); - private readonly lastCommandHover = new WeakMap(); - private readonly scheduledLsGroups = new Set(); - - constructor( - @ICommandService commandService: ICommandService, - @ICodeEditorService private readonly codeEditorService: ICodeEditorService, - @ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService, - @IModelService modelService: IModelService, - @IExtensionService private readonly extensionService: IExtensionService, - @IWhiteboardTelemetryService private readonly telemetryService: IWhiteboardTelemetryService, - ) { - super(); - this._register(commandService.onDidExecuteCommand(event => { - const feature = Object.prototype.hasOwnProperty.call(LSP_COMMANDS, event.commandId) - ? LSP_COMMANDS[event.commandId] - : undefined; - if (!feature) { - return; - } - const editor = this.activeEditor(); - const model = editor?.getModel(); - if (!editor || !model) { - return; - } - if (feature === 'hover') { - this.lastCommandHover.set(editor, Date.now()); - } - this.captureLspUsed(editor, model, feature, 'command'); - })); - - for (const editor of codeEditorService.listCodeEditors()) { - this.trackEditor(editor); - } - this._register(codeEditorService.onCodeEditorAdd(editor => this.trackEditor(editor))); - this._register(codeEditorService.onCodeEditorRemove(editor => this.untrackEditor(editor))); - - for (const model of modelService.getModels()) { - this.scheduleLsHealth(model); - } - this._register(modelService.onModelAdded(model => this.scheduleLsHealth(model))); - this._register(modelService.onModelLanguageChanged(({ model }) => this.scheduleLsHealth(model))); - } - - private activeEditor(): ICodeEditor | null { - return this.codeEditorService.getFocusedCodeEditor() ?? this.codeEditorService.getActiveCodeEditor(); - } - - private trackEditor(editor: ICodeEditor): void { - if (this.editorStores.has(editor)) { - return; - } - const store = new DisposableStore(); - this.editorStores.set(editor, store); - this._register(store); - - const hoverController = ContentHoverController.get(editor); - if (hoverController) { - this.trackHover(editor, hoverController, store); - } - - const clickLinkGesture = store.add(new ClickLinkGesture(editor)); - store.add(clickLinkGesture.onExecute(event => { - const model = editor.getModel(); - const position = event.target.position; - if ( - !model - || !position - || !event.isLeftClick - || !event.isNoneOrSingleMouseDown - || !event.hasTriggerModifier - || event.target.type !== MouseTargetType.CONTENT_TEXT - || event.target.detail.injectedText?.options instanceof ModelDecorationInjectedTextOptions - || !model.getWordAtPosition(position) - || !this.languageFeaturesService.definitionProvider.has(model) - ) { - return; - } - this.captureLspUsed(editor, model, 'goto_definition', 'mouse'); - })); - } - - private trackHover(editor: ICodeEditor, controller: ContentHoverController, store: DisposableStore): void { - let captured = false; - const dwell = store.add(new RunOnceScheduler(() => { - if (!controller.isHoverVisible) { - captured = false; - return; - } - captured = true; - if (Date.now() - (this.lastCommandHover.get(editor) ?? 0) >= HOVER_DWELL_MS) { - const model = editor.getModel(); - if (model) { - this.captureLspUsed(editor, model, 'hover', 'mouse'); - } - } - visibilityPoll.schedule(HOVER_VISIBILITY_POLL_MS); - }, HOVER_DWELL_MS)); - const visibilityPoll = store.add(new RunOnceScheduler(() => { - if (controller.isHoverVisible) { - visibilityPoll.schedule(HOVER_VISIBILITY_POLL_MS); - return; - } - captured = false; - }, HOVER_VISIBILITY_POLL_MS)); - const resetIfHidden = () => { - if (controller.isHoverVisible) { - return; - } - dwell.cancel(); - visibilityPoll.cancel(); - captured = false; - }; - - store.add(controller.onHoverContentsChanged(() => { - if (!controller.isHoverVisible) { - resetIfHidden(); - return; - } - if (!captured) { - dwell.schedule(HOVER_DWELL_MS); - } - })); - store.add(editor.onMouseMove(resetIfHidden)); - store.add(editor.onMouseLeave(resetIfHidden)); - store.add(editor.onMouseDown(resetIfHidden)); - store.add(editor.onDidScrollChange(resetIfHidden)); - store.add(editor.onDidChangeModel(resetIfHidden)); - } - - private untrackEditor(editor: ICodeEditor): void { - this.editorStores.get(editor)?.dispose(); - this.editorStores.delete(editor); - } - - private captureLspUsed(editor: ICodeEditor, model: ITextModel, feature: string, via: string): void { - this.telemetryService.capture('lsp_used', { - feature, - via, - language: toLspLanguage(model.getLanguageId()), - editor_kind: this.editorKind(editor), - }); - } - - private editorKind(editor: ICodeEditor): string { - if (WhiteboardEmbeddedEditors.owns(editor)) { - return 'inline_peek'; - } - for (const diffEditor of this.codeEditorService.listDiffEditors()) { - if (diffEditor.getOriginalEditor() === editor || diffEditor.getModifiedEditor() === editor) { - return 'diff'; - } - } - return 'files_tab'; - } - - private scheduleLsHealth(model: ITextModel): void { - const group = toLspLanguage(model.getLanguageId()); - const extensionId = LS_EXTENSIONS[group]; - if (!extensionId || this.scheduledLsGroups.has(group)) { - return; - } - this.scheduledLsGroups.add(group); - const timer = new RunOnceScheduler(() => { - const status = this.extensionService.getExtensionsStatus()[extensionId]; - this.telemetryService.capture('ls_activated', { - group, - ok: status?.activationTimes !== undefined && status.runningLocation !== null, - }); - }, LS_ACTIVATION_WAIT_MS); - this._register(timer); - timer.schedule(); - } -} - -Registry.as( - WorkbenchExtensions.Workbench, -).registerWorkbenchContribution(WhiteboardLspTelemetryContribution, LifecyclePhase.Eventually); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardTelemetry.contribution.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardTelemetry.contribution.test.ts deleted file mode 100644 index 59bfa23a6..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardTelemetry.contribution.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import type { IPromptChoice, IPromptOptions } from '../../../platform/notification/common/notification.js'; -import { setFirstRunReloadPending } from '../../common/whiteboardFirstRunReload.js'; -import { NOTICE_STORAGE_KEY, WhiteboardTelemetryNotice } from './whiteboardTelemetry.contribution.js'; - -const settle = () => new Promise(resolve => setImmediate(resolve)); - -function setup() { - const stored: Array<{ key: string; value: unknown }> = []; - const prompts: Array<{ choices: IPromptChoice[]; options?: IPromptOptions }> = []; - const settingsOpened: unknown[] = []; - const notice = () => new WhiteboardTelemetryNotice( - { getBoolean: () => false, store: (key: string, value: unknown) => stored.push({ key, value }) } as never, - { - prompt: (_severity: unknown, _message: string, choices: IPromptChoice[], options?: IPromptOptions) => { - prompts.push({ choices, options }); - return { close() { } }; - }, - } as never, - { openSettings: async (preview: unknown) => { settingsOpened.push(preview); } } as never, - ); - return { stored, prompts, settingsOpened, notice }; -} - -test('keeps the telemetry notice unspent until the reader answers it', async () => { - setFirstRunReloadPending(false); - const { stored, prompts, notice } = setup(); - notice(); - await settle(); - assert.equal(prompts.length, 1, 'the notice is shown'); - assert.deepEqual(stored, [], 'showing the notice does not record it as seen'); - // A non-sticky Info toast is purged without closing the notification, so `onCancel` - // would never fire and the notice would return on every launch. - assert.equal(prompts[0].options?.sticky, true); - prompts[0].options?.onCancel?.(); - assert.deepEqual(stored, [{ key: NOTICE_STORAGE_KEY, value: true }]); -}); - -test('spends the notice when the reader opens Settings', async () => { - setFirstRunReloadPending(false); - const { stored, prompts, settingsOpened, notice } = setup(); - notice(); - await settle(); - prompts[0].choices[0].run(); - assert.deepEqual(stored, [{ key: NOTICE_STORAGE_KEY, value: true }]); - assert.deepEqual(settingsOpened, [true]); -}); - -test('skips the telemetry notice when the first-run seeding reload is pending', async () => { - setFirstRunReloadPending(true); - const { stored, prompts, notice } = setup(); - notice(); - await settle(); - assert.deepEqual(prompts, [], 'a pending reload would take the notice with it'); - assert.deepEqual(stored, []); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardTelemetry.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardTelemetry.contribution.ts deleted file mode 100644 index 586adf773..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/telemetry/whiteboardTelemetry.contribution.ts +++ /dev/null @@ -1,82 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from '../../../nls.js'; -import { onUnexpectedError } from '../../../base/common/errors.js'; -import Severity from '../../../base/common/severity.js'; -import { INotificationService } from '../../../platform/notification/common/notification.js'; -import { Registry } from '../../../platform/registry/common/platform.js'; -import { IStorageService, StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js'; -import { - Extensions as WorkbenchExtensions, - type IWorkbenchContribution, - type IWorkbenchContributionsRegistry, -} from '../../../workbench/common/contributions.js'; -import { LifecyclePhase } from '../../../workbench/services/lifecycle/common/lifecycle.js'; -import { isFirstRunReloadPending } from '../../common/whiteboardFirstRunReload.js'; -import { IWhiteboardCanvasEditorTabsService } from '../../services/whiteboardCanvasEditorTabsService.js'; - -export const NOTICE_STORAGE_KEY = 'review.telemetry.noticeShown.v1'; - -export class WhiteboardTelemetryNotice implements IWorkbenchContribution { - constructor( - @IStorageService storageService: IStorageService, - @INotificationService notificationService: INotificationService, - @IWhiteboardCanvasEditorTabsService tabsService: IWhiteboardCanvasEditorTabsService, - ) { - if ( - storageService.getBoolean( - NOTICE_STORAGE_KEY, - StorageScope.APPLICATION, - false, - ) - ) { - return; - } - this.show(storageService, notificationService, tabsService).catch(onUnexpectedError); - } - - private async show( - storageService: IStorageService, - notificationService: INotificationService, - tabsService: IWhiteboardCanvasEditorTabsService, - ): Promise { - if (await isFirstRunReloadPending()) { - return; // the seeding reload would take the notice with it - } - // Spend the notice only once the reader answers it: a reload before then removes - // the notice, and a flag written up front never brings it back. - const markShown = () => storageService.store( - NOTICE_STORAGE_KEY, - true, - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - notificationService.prompt( - Severity.Info, - localize( - 'review.telemetry.notice', - "Whiteboard sends anonymous usage data. You can change this in Settings.", - ), - [{ - label: localize( - 'review.telemetry.openSettings', - "Open Settings", - ), - // Review does not register the stock settings editor, so the - // Settings canvas tab is where this setting lives. - run: () => { - markShown(); - void tabsService.openSettings(true); - }, - }], - { sticky: true, onCancel: markShown }, - ); - } -} - -Registry.as( - WorkbenchExtensions.Workbench, -).registerWorkbenchContribution(WhiteboardTelemetryNotice, LifecyclePhase.Restored); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/update/whiteboardUpdate.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/update/whiteboardUpdate.contribution.ts deleted file mode 100644 index fd881f564..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/update/whiteboardUpdate.contribution.ts +++ /dev/null @@ -1,280 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Review's update surface: two toasts, and a command to check on demand. - * - * Review deliberately omits the stock `workbench/contrib/update` — its title bar - * entry depends on the chat service, which Review does not register. This is the - * whole replacement: tell the reader when an update is waiting on a restart, and - * confirm once it has landed. - * - * Linux announces an available package and opens system update instructions. - * Squirrel on macOS installs a staged update whenever the app quits, with or without the - * toast, so the prompt is an invitation to restart now, not a gate on updating. - */ - -import { localize, localize2 } from '../../../nls.js'; -import { toAction } from '../../../base/common/actions.js'; -import { Disposable } from '../../../base/common/lifecycle.js'; -import { isLinux } from '../../../base/common/platform.js'; -import Severity from '../../../base/common/severity.js'; -import { Action2, registerAction2 } from '../../../platform/actions/common/actions.js'; -import type { ServicesAccessor } from '../../../platform/instantiation/common/instantiation.js'; -import { ILogService } from '../../../platform/log/common/log.js'; -import { INotificationService, type INotificationHandle } from '../../../platform/notification/common/notification.js'; -import { IProductService } from '../../../platform/product/common/productService.js'; -import { IStorageService, StorageScope, StorageTarget } from '../../../platform/storage/common/storage.js'; -import { - darwinFailedUpdateNoticeId, - DARWIN_FAILED_UPDATE_STORAGE_KEY, - parseDarwinFailedUpdate, - shouldAnnounceDarwinFailedUpdate, -} from '../../../platform/update/common/darwinUpdateRecovery.js'; -import { IUpdateService, StateType, type State } from '../../../platform/update/common/update.js'; -import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../workbench/common/contributions.js'; -import { - decideUpdateNotice, - parseStagedUpdate, - serializeStagedUpdate, - shouldPromptForUpdate, - stagedUpdateFromReady, - supersedesStagedUpdate, - type IWhiteboardStagedUpdate, -} from '../../common/whiteboardUpdateNotice.js'; - -/** The update downloaded and waiting for a restart. */ -const STAGED_UPDATE_STORAGE_KEY = 'review.update.staged.v1'; -/** Target commit the reader asked not to be prompted about again. */ -const SKIPPED_UPDATE_STORAGE_KEY = 'whiteboard.update.skipped.v1'; -/** Failed update attempt that Review already announced. */ -const FAILED_UPDATE_NOTICE_STORAGE_KEY = 'review.update.failedNotice.v1'; - -class WhiteboardUpdateNotifications extends Disposable { - - static readonly ID = 'review.update.notifications'; - - /** The visible "ready to install" toast, kept so a re-fire cannot stack duplicates. */ - private readyHandle: INotificationHandle | undefined; - /** Which commit `readyHandle` is about. */ - private readyCommit: string | undefined; - - constructor( - @IUpdateService private readonly updateService: IUpdateService, - @INotificationService private readonly notificationService: INotificationService, - @IStorageService private readonly storageService: IStorageService, - @IProductService private readonly productService: IProductService, - @ILogService private readonly logService: ILogService, - ) { - super(); - - this.announceFailedUpdate(); - this.announceCompletedUpdate(); - this._register(this.storageService.onDidChangeValue( - StorageScope.APPLICATION, - DARWIN_FAILED_UPDATE_STORAGE_KEY, - this._store, - )(() => this.announceFailedUpdate())); - - this._register(this.updateService.onStateChange(state => { - this.announceFailedUpdate(); - this.onStateChange(state); - })); - // The channel client replays its initial state, but reading it directly - // keeps this correct regardless of when the contribution is created. - this.onStateChange(this.updateService.state); - } - - private announceFailedUpdate(): void { - const failure = parseDarwinFailedUpdate( - this.storageService.get(DARWIN_FAILED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION), - ); - const announcedNoticeId = this.storageService.get( - FAILED_UPDATE_NOTICE_STORAGE_KEY, - StorageScope.APPLICATION, - ); - if (!shouldAnnounceDarwinFailedUpdate(failure, this.productService.commit, announcedNoticeId)) { - return; - } - - this.storageService.store( - FAILED_UPDATE_NOTICE_STORAGE_KEY, - darwinFailedUpdateNoticeId(failure), - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - this.logService.error(`[WhiteboardUpdate] update failed (${failure.targetCommit})`); - this.notificationService.notify({ - severity: Severity.Error, - message: localize('review.update.installFailed', "Update failed"), - }); - } - - /** - * If this launch is the first one on a build we staged, say so — once. - * - * The record is cleared whether or not it matched: a record for some other - * build is stale (a hand-installed DMG, or an abandoned update) and should - * disappear silently rather than linger and fire later. - */ - private announceCompletedUpdate(): void { - const staged = parseStagedUpdate( - this.storageService.get(STAGED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION), - ); - const notice = decideUpdateNotice(staged, this.productService.commit); - if (notice.kind === 'none') { - return; - } - - this.storageService.remove(STAGED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION); - if (notice.kind === 'clear') { - return; - } - - // The update landed, so any skip recorded against it is spent. - this.storageService.remove(SKIPPED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION); - this.logService.info(`[WhiteboardUpdate] running the staged update (${this.productService.commit})`); - this.notificationService.notify({ - severity: Severity.Info, - message: notice.productVersion - ? localize('review.update.applied', "Whiteboard updated to {0}.", notice.productVersion) - : localize('review.update.applied.unknownVersion', "Whiteboard has been updated."), - }); - } - - /** - * Linux rests at `AvailableForDownload`; macOS prompts at `Ready`. - * - * On macOS the flow is Idle → CheckingForUpdates → Downloading → Downloaded → - * Ready, and the last two are set back to back, so `Downloaded` is never a - * resting state. `AvailableForDownload` occurs only on a metered connection - * and resolves itself on the next check once off metered, so surfacing it - * would add a download-progress story for a state that clears on its own. - */ - private onStateChange(state: State): void { - if (isLinux && state.type === StateType.AvailableForDownload) { - if (this.readyCommit === state.update.version && this.readyHandle) { return; } - this.readyHandle?.close(); - this.readyCommit = state.update.version; - this.readyHandle = this.notificationService.notify({ - severity: Severity.Info, - message: localize('review.update.linuxAvailable', "Whiteboard {0} is available. Update with your system package manager, then reopen Whiteboard.", state.update.productVersion ?? ''), - actions: { primary: [toAction({ - id: 'whiteboard.update.instructions', label: localize('whiteboard.update.instructions', "Update Instructions"), - run: () => this.updateService.downloadUpdate(true), - })] }, - }); - const handle = this.readyHandle; - this._register(handle.onDidClose(() => { - if (this.readyHandle === handle) { this.readyHandle = undefined; this.readyCommit = undefined; } - })); - return; - } - if (state.type !== StateType.Ready) { - return; - } - - const next = stagedUpdateFromReady(state.update); - if (!next) { - this.logService.warn('[WhiteboardUpdate] update is ready but carries no commit; nothing to record'); - return; - } - - // Record before considering the prompt: the update installs on quit even - // when skipped, so the post-restart toast must still be able to fire. - const staged = parseStagedUpdate( - this.storageService.get(STAGED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION), - ); - if (supersedesStagedUpdate(staged, next)) { - this.storageService.store( - STAGED_UPDATE_STORAGE_KEY, - serializeStagedUpdate(next), - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - } - - const skipped = this.storageService.get(SKIPPED_UPDATE_STORAGE_KEY, StorageScope.APPLICATION); - if (!shouldPromptForUpdate(next, skipped)) { - return; - } - if (this.readyHandle && this.readyCommit === next.targetCommit) { - return; - } - - this.showReadyNotification(next); - } - - private showReadyNotification(next: IWhiteboardStagedUpdate): void { - // A newer update superseded whatever was on screen. - this.readyHandle?.close(); - - const handle = this.notificationService.notify({ - severity: Severity.Info, - // Waits for a decision rather than expiring unseen. - sticky: true, - message: next.productVersion - ? localize('review.update.ready', "Whiteboard {0} is ready to install.", next.productVersion) - : localize('review.update.ready.unknownVersion', "A Whiteboard update is ready to install."), - actions: { - primary: [ - toAction({ - id: 'whiteboard.update.restart', - label: localize('whiteboard.update.restart', "Restart to Update"), - run: () => { - void this.updateService.quitAndInstall(); - }, - }), - toAction({ - id: 'whiteboard.update.skip', - label: localize('whiteboard.update.skip', "Skip This Version"), - run: () => { - this.storageService.store( - SKIPPED_UPDATE_STORAGE_KEY, - next.targetCommit, - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - }, - }), - ], - }, - }); - - this.readyHandle = handle; - this.readyCommit = next.targetCommit; - this._register(handle.onDidClose(() => { - this.readyHandle = undefined; - this.readyCommit = undefined; - })); - } -} - -/** - * Checking on demand. Without this the only trigger is the scheduled check, 30 - * seconds after startup and hourly after that. An explicit check also bypasses - * the metered-connection path, so macOS can download immediately; Linux still uses the package manager. - */ -class WhiteboardCheckForUpdatesAction extends Action2 { - - constructor() { - super({ - id: 'whiteboard.checkForUpdates', - title: localize2('whiteboard.checkForUpdates', "Check for Updates..."), - f1: true, - }); - } - - async run(accessor: ServicesAccessor): Promise { - await accessor.get(IUpdateService).checkForUpdates(true); - } -} - -registerAction2(WhiteboardCheckForUpdatesAction); -registerWorkbenchContribution2( - WhiteboardUpdateNotifications.ID, - WhiteboardUpdateNotifications, - WorkbenchPhase.AfterRestored, -); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardApiSelection.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardApiSelection.test.ts deleted file mode 100644 index e0a7e10f3..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardApiSelection.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; - -import { URI } from "../../../base/common/uri.js"; -import { Selection } from "../../../editor/common/core/selection.js"; -import { apiSourceUri } from "../../services/whiteboardApiSourceService.js"; -import { apiSelectionEvent } from "./whiteboardApiSelection.js"; - -test("API diff selections retain side, version and commit without a legacy session", () => { - for (const side of ["base", "head"] as const) { - const resource = apiSourceUri({ view: { sessionId: "review-a", version: 7, commit: "selected-commit" }, side, file: "src/[route].ts" }); - for (const selection of [new Selection(2, 1, 4, 1), new Selection(4, 1, 2, 1)]) { - assert.deepEqual(apiSelectionEvent(resource, selection, { x: 70, y: 140 }), { - event: "editorSelectionChanged", sessionId: "review-a", anchor: { x: 70, y: 140 }, - path: "src/[route].ts", sideContext: side, isEmpty: false, - range: { fromLine: 2, toLine: 3 }, - apiSource: { sessionId: "review-a", version: 7, commit: "selected-commit" }, - }); - } - assert.equal(apiSelectionEvent(resource, new Selection(2, 1, 2, 1))?.isEmpty, true); - } -}); - -test("empty diff sides and unrelated resources cannot produce source-copy actions", () => { - const empty = apiSourceUri({ view: { sessionId: "review-a", version: 0 }, side: "base", file: "new.ts" }, true); - const selection = new Selection(1, 1, 2, 1); - assert.equal(apiSelectionEvent(empty, selection), undefined); - assert.equal(apiSelectionEvent(URI.file("/tmp/file.ts"), selection), undefined); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardApiSelection.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardApiSelection.ts deleted file mode 100644 index dc934249c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardApiSelection.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { URI } from "../../../base/common/uri.js"; -import type { Selection } from "../../../editor/common/core/selection.js"; -import type { WhiteboardSurfaceEvent } from "../../common/whiteboardProtocol.js"; -import { apiSourceTarget } from "../../services/whiteboardApiSourceService.js"; - -/** API-backed editors carry their pins in the URI and have no legacy session. */ -export function apiSelectionEvent( - resource: URI, - selection: Selection, - anchor?: { x: number; y: number }, -): Extract | undefined { - const source = apiSourceTarget(resource); - if (!source || new URLSearchParams(resource.query).has("empty")) return undefined; - const start = selection.getStartPosition(); - const end = selection.getEndPosition(); - const apiSource: NonNullable["apiSource"]> = { - sessionId: source.view.sessionId, version: source.view.version, commit: source.view.commit, - }; - // A source at its own pins says so; one that inherits carries no pins key. - if (source.view.pins) apiSource.pins = source.view.pins; - return { - event: "editorSelectionChanged", sessionId: source.view.sessionId, anchor, - path: source.file, sideContext: source.side, isEmpty: selection.isEmpty(), - range: { - fromLine: start.lineNumber, - toLine: Math.max(start.lineNumber, end.lineNumber - (end.column === 1 && end.lineNumber > start.lineNumber ? 1 : 0)), - }, - apiSource, - }; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardDiffSelection.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardDiffSelection.test.ts deleted file mode 100644 index daefeb61b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardDiffSelection.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import assert from 'node:assert/strict'; -import test from 'node:test'; -import { selectedMonacoDiff } from './whiteboardDiffSelection.js'; - -const model = (...lines: string[]) => ({ getLineCount: () => lines.length, getLineContent: (line: number) => { assert.ok(line >= 1 && line <= lines.length); return lines[line - 1]; } }); -const replacement = { originalStartLineNumber: 2, originalEndLineNumber: 2, modifiedStartLineNumber: 2, modifiedEndLineNumber: 3 }; - -test('copy from either pane retains both sides of a replacement and rename paths', () => { - for (const side of ['base', 'head'] as const) { - const diff = selectedMonacoDiff(model('before', 'old', 'after'), model('before', 'new', 'extra', 'after'), [replacement], side, 2, 2, 'old.ts', 'new.ts'); - assert.deepEqual(diff, { oldPath: 'old.ts', newPath: 'new.ts', oldStart: 2, newStart: 2, rows: [{ kind: 'deleted', text: 'old' }, { kind: 'added', text: 'new' }, { kind: 'added', text: 'extra' }] }); - } -}); - -test('context after a replacement retains correct base/head offsets', () => { - const diff = selectedMonacoDiff(model('before', 'old', 'after'), model('before', 'new', 'extra', 'after'), [replacement], 'head', 4, 4, 'a.ts', 'a.ts'); - assert.equal(diff?.oldStart, 3); assert.equal(diff?.newStart, 4); - assert.deepEqual(diff?.rows, [{ kind: 'unchanged', text: 'after' }]); -}); - -test('added and deleted files use zero-count opposite sides', () => { - const addition = { originalStartLineNumber: 0, originalEndLineNumber: 0, modifiedStartLineNumber: 1, modifiedEndLineNumber: 2 }; - const added = selectedMonacoDiff(model(''), model('a', 'b'), [addition], 'head', 1, 2, '', 'new.ts'); - assert.equal(added?.oldStart, 0); assert.deepEqual(added?.rows.map(row => row.kind), ['added', 'added']); - const removed = selectedMonacoDiff(model('a', 'b'), model(''), [{ originalStartLineNumber: 1, originalEndLineNumber: 2, modifiedStartLineNumber: 0, modifiedEndLineNumber: 0 }], 'base', 1, 2, 'old.ts', ''); - assert.equal(removed?.newStart, 0); assert.deepEqual(removed?.rows.map(row => row.kind), ['deleted', 'deleted']); -}); - -test('selection crossing a deletion includes it, adjacent context alone does not', () => { - const change = { originalStartLineNumber: 2, originalEndLineNumber: 2, modifiedStartLineNumber: 1, modifiedEndLineNumber: 0 }; - const select = (from: number, to: number) => selectedMonacoDiff(model('a', 'removed', 'b'), model('a', 'b'), [change], 'head', from, to, 'a', 'a'); - assert.deepEqual(select(1, 2)?.rows.map(row => row.kind), ['unchanged', 'deleted', 'unchanged']); - assert.deepEqual(select(2, 2)?.rows, [{ kind: 'unchanged', text: 'b' }]); -}); - -test('partial selection of a newly added file copies only selected lines', () => { - const diff = selectedMonacoDiff(model(''), model('a', 'b', 'c'), [{ originalStartLineNumber: 0, originalEndLineNumber: 0, modifiedStartLineNumber: 1, modifiedEndLineNumber: 3 }], 'head', 2, 2, '', 'new.ts'); - assert.equal(diff?.newStart, 2); - assert.deepEqual(diff?.rows, [{ kind: 'added', text: 'b' }]); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardDiffSelection.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardDiffSelection.ts deleted file mode 100644 index e64be3ada..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardDiffSelection.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { ILineChange } from '../../../editor/common/diff/legacyLinesDiffComputer.js'; -import type { WhiteboardSurfaceEvent } from '../../common/whiteboardProtocol.js'; - -type SelectedDiff = NonNullable['selectedDiff']>; -interface Lines { getLineCount(): number; getLineContent(line: number): string } - -/** Expand intersected replacements to both sides so the copied excerpt is a real diff. */ -export function selectedMonacoDiff(original: Lines, modified: Lines, changes: readonly Omit[], side: 'base' | 'head', from: number, to: number, oldPath: string, newPath: string): SelectedDiff | undefined { - const result: SelectedDiff = { oldPath, newPath, oldStart: 0, newStart: 0, rows: [] }; - let oldLine = 1, newLine = 1; - const begin = (oldStart: number, newStart: number) => { - if (!result.rows.length) { result.oldStart = oldStart; result.newStart = newStart; } - }; - const context = (count: number) => { - const line = side === 'base' ? oldLine : newLine; - const first = Math.max(0, from - line), last = Math.min(count - 1, to - line); - if (first <= last) { - begin(oldLine + first, newLine + first); - for (let offset = first; offset <= last; offset++) result.rows.push({ kind: 'unchanged', text: original.getLineContent(oldLine + offset) }); - } - oldLine += count; newLine += count; - }; - for (const change of changes) { - const oldStart = change.originalEndLineNumber === 0 ? change.originalStartLineNumber + 1 : change.originalStartLineNumber; - const newStart = change.modifiedEndLineNumber === 0 ? change.modifiedStartLineNumber + 1 : change.modifiedStartLineNumber; - const oldCount = change.originalEndLineNumber === 0 ? 0 : change.originalEndLineNumber - oldStart + 1; - const newCount = change.modifiedEndLineNumber === 0 ? 0 : change.modifiedEndLineNumber - newStart + 1; - context(Math.max(0, Math.min(oldStart - oldLine, newStart - newLine))); - const start = side === 'base' ? oldStart : newStart; - const count = side === 'base' ? oldCount : newCount; - // A one-sided change belongs only when the selection crosses its insertion point. - if (count ? from <= start + count - 1 && to >= start : from < start && to >= start) { - const selectedOldStart = !newCount && side === 'base' ? Math.max(oldStart, from) : oldStart; - const selectedOldEnd = !newCount && side === 'base' ? Math.min(oldStart + oldCount, to + 1) : oldStart + oldCount; - const selectedNewStart = !oldCount && side === 'head' ? Math.max(newStart, from) : newStart; - const selectedNewEnd = !oldCount && side === 'head' ? Math.min(newStart + newCount, to + 1) : newStart + newCount; - begin(oldCount ? selectedOldStart : oldStart - 1, newCount ? selectedNewStart : newStart - 1); - for (let line = selectedOldStart; line < selectedOldEnd; line++) result.rows.push({ kind: 'deleted', text: original.getLineContent(line) }); - for (let line = selectedNewStart; line < selectedNewEnd; line++) result.rows.push({ kind: 'added', text: modified.getLineContent(line) }); - } - oldLine = oldStart + oldCount; newLine = newStart + newCount; - } - context(Math.max(0, Math.min(oldPath ? original.getLineCount() - oldLine + 1 : 0, newPath ? modified.getLineCount() - newLine + 1 : 0))); - return result.rows.length ? result : undefined; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardVerbs.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardVerbs.ts deleted file mode 100644 index 433735be0..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/contrib/verbs/whiteboardVerbs.ts +++ /dev/null @@ -1,177 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { encodeBase64 } from "../../../base/common/buffer.js"; -import { Emitter, Event } from "../../../base/common/event.js"; -import { Disposable, DisposableStore } from "../../../base/common/lifecycle.js"; -import { type ICodeEditor, type IDiffEditor } from "../../../editor/browser/editorBrowser.js"; -import { ICodeEditorService } from "../../../editor/browser/services/codeEditorService.js"; -import { createDecorator } from "../../../platform/instantiation/common/instantiation.js"; -import { IOpenerService } from "../../../platform/opener/common/opener.js"; -import { IHostService } from "../../../workbench/services/host/browser/host.js"; -import { - type JsonValue, - parseWhiteboardVerbRequest, - WHITEBOARD_DISCORD_URL, - type WhiteboardSurfaceEvent, - type WhiteboardVerbResponse, - type WhiteboardView, -} from "../../common/whiteboardProtocol.js"; -import { IWhiteboardApiCatalogService } from "../../services/whiteboardApiCatalogService.js"; -import { IWhiteboardCanvasEditorTabsService } from "../../services/whiteboardCanvasEditorTabsService.js"; -import { apiSourceTarget } from "../../services/whiteboardApiSourceService.js"; -import { selectedMonacoDiff } from "./whiteboardDiffSelection.js"; -import { apiSelectionEvent } from "./whiteboardApiSelection.js"; - -export const IWhiteboardVerbsService = createDecorator("whiteboardVerbsService"); - -export interface IWhiteboardVerbsService { - readonly _serviceBrand: undefined; - readonly onDidEmitSurfaceEvent: Event; - readonly onDidRequestCanvasFocus: Event; - dispatch(value: JsonValue): Promise; -} - -export class WhiteboardVerbsService extends Disposable implements IWhiteboardVerbsService { - declare readonly _serviceBrand: undefined; - - private readonly _onDidEmitSurfaceEvent = this._register(new Emitter()); - readonly onDidEmitSurfaceEvent = this._onDidEmitSurfaceEvent.event; - private readonly _onDidRequestCanvasFocus = this._register(new Emitter()); - readonly onDidRequestCanvasFocus = this._onDidRequestCanvasFocus.event; - - private readonly selectionEditors = new Map(); - - constructor( - @ICodeEditorService private readonly codeEditorService: ICodeEditorService, - @IWhiteboardCanvasEditorTabsService - private readonly tabsService: IWhiteboardCanvasEditorTabsService, - @IHostService private readonly hostService: IHostService, - @IOpenerService private readonly openerService: IOpenerService, - @IWhiteboardApiCatalogService - private readonly apiCatalog: IWhiteboardApiCatalogService, - ) { - super(); - for (const editor of this.codeEditorService.listCodeEditors()) this.trackSelection(editor); - for (const diff of this.codeEditorService.listDiffEditors()) this.trackDiffSelection(diff); - this._register(this.codeEditorService.onDiffEditorAdd(diff => this.trackDiffSelection(diff))); - this._register(this.codeEditorService.onCodeEditorAdd((editor) => this.trackSelection(editor))); - this._register( - this.codeEditorService.onCodeEditorRemove((editor) => { - this.selectionEditors.get(editor.getId())?.dispose(); - this.selectionEditors.delete(editor.getId()); - }), - ); - } - - private trackDiffSelection(diff: IDiffEditor): void { - const subscription = diff.onDidUpdateDiff(() => { - this.emitSelection(diff.getOriginalEditor()); - this.emitSelection(diff.getModifiedEditor()); - }); - const disposed = diff.onDidDispose(() => { subscription.dispose(); disposed.dispose(); }); - this._register(subscription); - this._register(disposed); - } - - private trackSelection(editor: ICodeEditor): void { - if (this.selectionEditors.has(editor.getId())) return; - const store = this._register(new DisposableStore()); - this.selectionEditors.set(editor.getId(), store); - store.add(editor.onDidChangeCursorSelection(() => this.emitSelection(editor))); - store.add(editor.onDidFocusEditorText(() => this.emitSelection(editor))); - store.add(editor.onDidScrollChange(() => this.emitSelection(editor))); - } - - private emitSelection(editor: ICodeEditor): void { - if (!editor.hasTextFocus()) return; - const model = editor.getModel(); - const selection = editor.getSelection(); - if (!model || !selection) return; - const start = selection.getStartPosition(); - const end = selection.getEndPosition(); - const fromLine = start.lineNumber; - const toLine = Math.max(fromLine, end.lineNumber - (end.column === 1 && end.lineNumber > fromLine ? 1 : 0)); - const rect = editor.getDomNode()?.getBoundingClientRect(); - const position = editor.getScrolledVisiblePosition(selection.getPosition()); - const anchor = rect && position ? { x: rect.left + position.left, y: rect.top + position.top } : undefined; - const apiSelection = apiSelectionEvent(model.uri, selection, anchor); - if (apiSelection) { - const diff = this.codeEditorService.listDiffEditors().find(diff => diff.getOriginalEditor() === editor || diff.getModifiedEditor() === editor); - const models = diff?.getModel(); - const changes = diff?.getLineChanges(); - if (models && changes && !selection.isEmpty()) { - const oldSource = apiSourceTarget(models.original.uri); - const newSource = apiSourceTarget(models.modified.uri); - if (oldSource && newSource) apiSelection.selectedDiff = selectedMonacoDiff( - models.original, models.modified, changes, apiSelection.sideContext, fromLine, toLine, - new URLSearchParams(models.original.uri.query).has("empty") ? "" : oldSource.file, - new URLSearchParams(models.modified.uri.query).has("empty") ? "" : newSource.file, - ); - } - this._onDidEmitSurfaceEvent.fire(apiSelection); - return; - } - } - - async dispatch(value: JsonValue): Promise { - try { - const request = parseWhiteboardVerbRequest(value); - switch (request.name) { - case "joinDiscord": - await this.openerService.open(WHITEBOARD_DISCORD_URL, { openExternal: true }); - break; - case "showWhiteboardView": - await this.showWhiteboardView(request.args.view); - break; - case "openSourceTree": - case "openDiff": - case "reveal": - case "openWhiteboardRevision": - throw new Error("This action requires a pinned session canvas."); - case "focusCanvas": - this._onDidRequestCanvasFocus.fire(); - break; - case "captureScreenshot": - return { ok: true, result: await this.captureScreenshot() }; - case "openWhiteboard": { - const review = this.apiCatalog.reviews.find((review) => review.sessionId === request.args.sessionId); - if (!review) throw new Error("Session not found."); - await this.tabsService.openApiWhiteboard(review.sessionId, review.title, request.args.active); - break; - } - case "openApiWhiteboard": - await this.tabsService.openApiWhiteboard(request.args.sessionId, request.args.title); - break; - } - return { ok: true }; - } catch (error) { - return { - ok: false, - error: error instanceof Error ? error.message : String(error), - }; - } - } - - private async captureScreenshot(): Promise<{ dataUrl: string } | undefined> { - try { - const screenshot = await this.hostService.getScreenshot(); - if (!screenshot) return undefined; - return { - dataUrl: `data:image/jpeg;base64,${encodeBase64(screenshot)}`, - }; - } catch { - return undefined; - } - } - - /** - * The dispatcher reveals the Review tab before asking the app to show a view. - */ - private async showWhiteboardView(view: WhiteboardView): Promise { - this._onDidRequestCanvasFocus.fire(); - this._onDidEmitSurfaceEvent.fire({ event: "showWhiteboardView", view }); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-browser/whiteboard.main.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-browser/whiteboard.main.ts deleted file mode 100644 index 2ab8ed469..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-browser/whiteboard.main.ts +++ /dev/null @@ -1,407 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from '../../nls.js'; -import product from '../../platform/product/common/product.js'; -import { INativeWindowConfiguration, IWindowsConfiguration } from '../../platform/window/common/window.js'; -import { NativeWindow } from '../../workbench/electron-browser/window.js'; -import { setFullscreen } from '../../base/browser/browser.js'; -import { domContentLoaded } from '../../base/browser/dom.js'; -import { onUnexpectedError } from '../../base/common/errors.js'; -import { URI } from '../../base/common/uri.js'; -import { INativeWorkbenchEnvironmentService, NativeWorkbenchEnvironmentService } from '../../workbench/services/environment/electron-browser/environmentService.js'; -import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; -import { ILogService, ILoggerService, LogLevel } from '../../platform/log/common/log.js'; -import { NativeWorkbenchStorageService } from '../../workbench/services/storage/electron-browser/storageService.js'; -import { IAnyWorkspaceIdentifier, IWorkspaceContextService, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, reviveIdentifier } from '../../platform/workspace/common/workspace.js'; -import { IWorkbenchConfigurationService } from '../../workbench/services/configuration/common/configuration.js'; -import { IStorageService } from '../../platform/storage/common/storage.js'; -import { Disposable } from '../../base/common/lifecycle.js'; -import { ISharedProcessService } from '../../platform/ipc/electron-browser/services.js'; -import { IMainProcessService } from '../../platform/ipc/common/mainProcessService.js'; -import { SharedProcessService } from '../../workbench/services/sharedProcess/electron-browser/sharedProcessService.js'; -import { RemoteAuthorityResolverService } from '../../platform/remote/electron-browser/remoteAuthorityResolverService.js'; -import { IRemoteAuthorityResolverService, RemoteConnectionType } from '../../platform/remote/common/remoteAuthorityResolver.js'; -import { RemoteAgentService } from '../../workbench/services/remote/electron-browser/remoteAgentService.js'; -import { IRemoteAgentService } from '../../workbench/services/remote/common/remoteAgentService.js'; -import { FileService } from '../../platform/files/common/fileService.js'; -import { IFileService } from '../../platform/files/common/files.js'; -import { RemoteFileSystemProviderClient } from '../../workbench/services/remote/common/remoteFileSystemProviderClient.js'; -import { ISignService } from '../../platform/sign/common/sign.js'; -import { IProductService } from '../../platform/product/common/productService.js'; -import { IUriIdentityService } from '../../platform/uriIdentity/common/uriIdentity.js'; -import { UriIdentityService } from '../../platform/uriIdentity/common/uriIdentityService.js'; -import { INativeKeyboardLayoutService, NativeKeyboardLayoutService } from '../../workbench/services/keybinding/electron-browser/nativeKeyboardLayoutService.js'; -import { ElectronIPCMainProcessService } from '../../platform/ipc/electron-browser/mainProcessService.js'; -import { LoggerChannelClient } from '../../platform/log/common/logIpc.js'; -import { ProxyChannel } from '../../base/parts/ipc/common/ipc.js'; -import { NativeLogService } from '../../workbench/services/log/electron-browser/logService.js'; -import { WorkspaceTrustEnablementService, WorkspaceTrustManagementService } from '../../workbench/services/workspaces/common/workspaceTrust.js'; -import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService } from '../../platform/workspace/common/workspaceTrust.js'; -import { safeStringify } from '../../base/common/objects.js'; -import { IUtilityProcessWorkerWorkbenchService, UtilityProcessWorkerWorkbenchService } from '../../workbench/services/utilityProcess/electron-browser/utilityProcessWorkerWorkbenchService.js'; -import { isCI, isMacintosh, isTahoeOrNewer } from '../../base/common/platform.js'; -import { Schemas } from '../../base/common/network.js'; -import { DiskFileSystemProvider } from '../../workbench/services/files/electron-browser/diskFileSystemProvider.js'; -import { FileUserDataProvider } from '../../platform/userData/common/fileUserDataProvider.js'; -import { IUserDataProfilesService, reviveProfile } from '../../platform/userDataProfile/common/userDataProfile.js'; -import { UserDataProfilesService } from '../../platform/userDataProfile/common/userDataProfileIpc.js'; -import { PolicyChannelClient } from '../../platform/policy/common/policyIpc.js'; -import { NativeManagedSettingsChannelClient } from '../../platform/policy/common/nativeManagedSettingsIpc.js'; -import { IFileManagedSettingsService, INativeManagedSettingsService } from '../../platform/policy/common/copilotManagedSettings.js'; -import { FileManagedSettingsChannelClient } from '../../platform/policy/common/fileManagedSettingsIpc.js'; -import { IPolicyService } from '../../platform/policy/common/policy.js'; -import { UserDataProfileService } from '../../workbench/services/userDataProfile/common/userDataProfileService.js'; -import { IUserDataProfileService } from '../../workbench/services/userDataProfile/common/userDataProfile.js'; -import { BrowserSocketFactory } from '../../platform/remote/browser/browserSocketFactory.js'; -import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from '../../platform/remote/common/remoteSocketFactoryService.js'; -import { ElectronRemoteResourceLoader } from '../../platform/remote/electron-browser/electronRemoteResourceLoader.js'; -import { IConfigurationService } from '../../platform/configuration/common/configuration.js'; -import { applyZoom } from '../../platform/window/electron-browser/window.js'; -import { mainWindow } from '../../base/browser/window.js'; -import { IDefaultAccountService } from '../../platform/defaultAccount/common/defaultAccount.js'; -import { AccountPolicyService, IAccountPolicyGateService } from '../../workbench/services/policies/common/accountPolicyService.js'; -import { MultiplexPolicyService } from '../../platform/policy/common/multiplexPolicyService.js'; -import { WhiteboardWorkbench } from '../browser/workbench.js'; -import { IWorkspaceEditingService } from '../../workbench/services/workspaces/common/workspaceEditing.js'; -import { WhiteboardConfigurationService } from '../services/configuration/browser/configurationService.js'; -import { ConfigurationCache } from '../../workbench/services/configuration/common/configurationCache.js'; -import { WhiteboardWorkspaceContextService } from '../services/workspace/browser/workspaceContextService.js'; -import { getWorkspaceIdentifier } from '../../platform/workspaces/common/workspaceIdentifier.js'; -import { WhiteboardDefaultAccountService } from '../services/whiteboardDefaultAccountService.js'; -import { whiteboardAgentsWindowDefaultOverrides } from '../common/whiteboardConfigurationDefaults.js'; - -export class WhiteboardMain extends Disposable { - - constructor( - private readonly configuration: INativeWindowConfiguration - ) { - super(); - - this.init(); - } - - private init(): void { - - // Massage configuration file URIs - this.reviveUris(); - - // Apply fullscreen early if configured - setFullscreen(!!this.configuration.fullscreen, mainWindow); - } - - private reviveUris() { - - // Workspace - const workspace = reviveIdentifier(this.configuration.workspace); - if (isWorkspaceIdentifier(workspace) || isSingleFolderWorkspaceIdentifier(workspace)) { - this.configuration.workspace = workspace; - } - - // Files - const filesToWait = this.configuration.filesToWait; - const filesToWaitPaths = filesToWait?.paths; - for (const paths of [filesToWaitPaths, this.configuration.filesToOpenOrCreate, this.configuration.filesToDiff, this.configuration.filesToMerge]) { - if (Array.isArray(paths)) { - for (const path of paths) { - if (path.fileUri) { - path.fileUri = URI.revive(path.fileUri); - } - } - } - } - - if (filesToWait) { - filesToWait.waitMarkerFileUri = URI.revive(filesToWait.waitMarkerFileUri); - } - } - - async open(): Promise { - - // Init services and wait for DOM to be ready in parallel - const [services] = await Promise.all([this.initServices(), domContentLoaded(mainWindow)]); - - // Apply zoom level early - this.applyWindowZoomLevel(services.configurationService); - - // Create Agentic Workbench - const workbench = new WhiteboardWorkbench(mainWindow.document.body, { - extraClasses: this.getExtraClasses(), - }, services.serviceCollection, services.logService); - - // Listeners - this.registerListeners(workbench, services.storageService); - - // Startup - const instantiationService = workbench.startup(); - - // Window - this._register(instantiationService.createInstance(NativeWindow)); - - } - - private applyWindowZoomLevel(configurationService: IConfigurationService) { - let zoomLevel: number | undefined = undefined; - if (this.configuration.isCustomZoomLevel && typeof this.configuration.zoomLevel === 'number') { - zoomLevel = this.configuration.zoomLevel; - } else { - const windowConfig = configurationService.getValue(); - zoomLevel = typeof windowConfig.window?.zoomLevel === 'number' ? windowConfig.window.zoomLevel : 0; - } - - applyZoom(zoomLevel, mainWindow); - } - - private getExtraClasses(): string[] { - if (isMacintosh && isTahoeOrNewer(this.configuration.os.release)) { - return ['macos-tahoe']; - } - - return []; - } - - private registerListeners(workbench: WhiteboardWorkbench, storageService: NativeWorkbenchStorageService): void { - - // Workbench Lifecycle - this._register(workbench.onWillShutdown(event => event.join(storageService.close(), { id: 'join.closeStorage', label: localize('join.closeStorage', "Saving UI state") }))); - this._register(workbench.onDidShutdown(() => this.dispose())); - } - - private async initServices(): Promise<{ serviceCollection: ServiceCollection; logService: ILogService; storageService: NativeWorkbenchStorageService; configurationService: WhiteboardConfigurationService }> { - const serviceCollection = new ServiceCollection(); - - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // - // NOTE: Please do NOT register services here. Use `registerSingleton()` - // from `workbench.common.main.ts` if the service is shared between - // desktop and web. - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - // Main Process - const mainProcessService = this._register(new ElectronIPCMainProcessService(this.configuration.windowId)); - serviceCollection.set(IMainProcessService, mainProcessService); - - // Product - const productService: IProductService = { _serviceBrand: undefined, ...product }; - serviceCollection.set(IProductService, productService); - - // Environment - const environmentService = new NativeWorkbenchEnvironmentService(this.configuration, productService); - serviceCollection.set(INativeWorkbenchEnvironmentService, environmentService); - - // Logger - const loggers = this.configuration.loggers.map(loggerResource => ({ ...loggerResource, resource: URI.revive(loggerResource.resource) })); - const loggerService = new LoggerChannelClient(this.configuration.windowId, this.configuration.logLevel, environmentService.windowLogsPath, loggers, mainProcessService.getChannel('logger')); - serviceCollection.set(ILoggerService, loggerService); - - // Log - const logService = this._register(new NativeLogService(loggerService, environmentService)); - serviceCollection.set(ILogService, logService); - if (isCI) { - logService.info('workbench#open()'); // marking workbench open helps to diagnose flaky integration/smoke tests - } - if (logService.getLevel() === LogLevel.Trace) { - logService.trace('workbench#open(): with configuration', safeStringify({ ...this.configuration, nls: undefined /* exclude large property */ })); - } - - // Default Account - const defaultAccountService = this._register(new WhiteboardDefaultAccountService()); - serviceCollection.set(IDefaultAccountService, defaultAccountService); - - // Policies - let policyService: IPolicyService; - const policyChannel = this.configuration.policiesData ? this._register(new PolicyChannelClient(this.configuration.policiesData, mainProcessService.getChannel('policy'))) : undefined; - const nativeManagedSettings = this._register(new NativeManagedSettingsChannelClient(mainProcessService.getChannel('nativeManagedSettings'))); - serviceCollection.set(INativeManagedSettingsService, nativeManagedSettings); - const fileManagedSettings = this._register(new FileManagedSettingsChannelClient(mainProcessService.getChannel('fileManagedSettings'))); - serviceCollection.set(IFileManagedSettingsService, fileManagedSettings); - const accountPolicy = this._register(new AccountPolicyService(logService, defaultAccountService, policyChannel, nativeManagedSettings, fileManagedSettings)); - if (policyChannel) { - policyService = this._register(new MultiplexPolicyService([policyChannel, accountPolicy], logService)); - } else { - policyService = accountPolicy; - } - serviceCollection.set(IPolicyService, policyService); - serviceCollection.set(IAccountPolicyGateService, accountPolicy); - - // Shared Process - const sharedProcessService = new SharedProcessService(this.configuration.windowId, logService); - serviceCollection.set(ISharedProcessService, sharedProcessService); - - // Utility Process Worker - const utilityProcessWorkerWorkbenchService = new UtilityProcessWorkerWorkbenchService(this.configuration.windowId, logService, mainProcessService); - serviceCollection.set(IUtilityProcessWorkerWorkbenchService, utilityProcessWorkerWorkbenchService); - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // - // NOTE: Please do NOT register services here. Use `registerSingleton()` - // from `workbench.common.main.ts` if the service is shared between - // desktop and web. - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - // Sign - const signService = ProxyChannel.toService(mainProcessService.getChannel('sign')); - serviceCollection.set(ISignService, signService); - - // Files - const fileService = this._register(new FileService(logService)); - serviceCollection.set(IFileService, fileService); - - // Remote - const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, new ElectronRemoteResourceLoader(environmentService.window.id, mainProcessService, fileService)); - serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); - - // Local Files - const diskFileSystemProvider = this._register(new DiskFileSystemProvider(mainProcessService, utilityProcessWorkerWorkbenchService, logService, loggerService)); - fileService.registerProvider(Schemas.file, diskFileSystemProvider); - - // URI Identity - const uriIdentityService = new UriIdentityService(fileService); - serviceCollection.set(IUriIdentityService, uriIdentityService); - - // User Data Profiles - const userDataProfilesService = new UserDataProfilesService(this.configuration.profiles.all, URI.revive(this.configuration.profiles.home).with({ scheme: environmentService.userRoamingDataHome.scheme }), mainProcessService.getChannel('userDataProfiles')); - serviceCollection.set(IUserDataProfilesService, userDataProfilesService); - const userDataProfileService = new UserDataProfileService(reviveProfile(this.configuration.profiles.profile, userDataProfilesService.profilesHome.scheme)); - serviceCollection.set(IUserDataProfileService, userDataProfileService); - - // Use FileUserDataProvider for user data to - // enable atomic read / write operations. - fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))); - - // Remote Agent - const remoteSocketFactoryService = new RemoteSocketFactoryService(); - remoteSocketFactoryService.register(RemoteConnectionType.WebSocket, new BrowserSocketFactory(null)); - serviceCollection.set(IRemoteSocketFactoryService, remoteSocketFactoryService); - const remoteAgentService = this._register(new RemoteAgentService(remoteSocketFactoryService, userDataProfileService, environmentService, productService, remoteAuthorityResolverService, signService, logService)); - serviceCollection.set(IRemoteAgentService, remoteAgentService); - - // Remote Files - this._register(RemoteFileSystemProviderClient.register(remoteAgentService, fileService, logService)); - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // - // NOTE: Please do NOT register services here. Use `registerSingleton()` - // from `workbench.common.main.ts` if the service is shared between - // desktop and web. - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - const workspaceIdentifier = getWorkspaceIdentifier(environmentService.agentSessionsWorkspace); - const workspaceContextService = new WhiteboardWorkspaceContextService(workspaceIdentifier, uriIdentityService); - - // Workspace - serviceCollection.set(IWorkspaceContextService, workspaceContextService); - serviceCollection.set(IWorkspaceEditingService, workspaceContextService); - - const [configurationService, storageService] = await Promise.all([ - this.createConfigurationService(workspaceContextService, userDataProfileService, uriIdentityService, fileService, logService, policyService, environmentService).then(configurationService => { - - // Configuration - serviceCollection.set(IWorkbenchConfigurationService, configurationService); - - return configurationService; - }), - - this.createStorageService(workspaceIdentifier, environmentService, userDataProfileService, userDataProfilesService, mainProcessService).then(service => { - - // Storage - serviceCollection.set(IStorageService, service); - - return service; - }), - - this.createKeyboardLayoutService(mainProcessService).then(service => { - - // KeyboardLayout - serviceCollection.set(INativeKeyboardLayoutService, service); - - return service; - }) - ]); - - // Workspace Trust Service - const workspaceTrustEnablementService = new WorkspaceTrustEnablementService(configurationService, environmentService); - serviceCollection.set(IWorkspaceTrustEnablementService, workspaceTrustEnablementService); - - const workspaceTrustManagementService = new WorkspaceTrustManagementService(configurationService, remoteAuthorityResolverService, storageService, uriIdentityService, environmentService, workspaceContextService, workspaceTrustEnablementService, fileService); - serviceCollection.set(IWorkspaceTrustManagementService, workspaceTrustManagementService); - - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // - // NOTE: Please do NOT register services here. Use `registerSingleton()` - // from `workbench.common.main.ts` if the service is shared between - // desktop and web. - // - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - return { serviceCollection, logService, storageService, configurationService }; - } - - private async createConfigurationService( - workspaceContextService: WhiteboardWorkspaceContextService, - userDataProfileService: IUserDataProfileService, - uriIdentityService: IUriIdentityService, - fileService: FileService, - logService: ILogService, - policyService: IPolicyService, - environmentService: INativeWorkbenchEnvironmentService, - ): Promise { - const configurationCache = new ConfigurationCache([Schemas.file, Schemas.vscodeUserData], environmentService, fileService); - const configurationService = new WhiteboardConfigurationService(userDataProfileService, workspaceContextService, uriIdentityService, fileService, policyService, logService, configurationCache, environmentService, { defaultOverrides: whiteboardAgentsWindowDefaultOverrides }); - try { - await configurationService.initialize(); - } catch (error) { - onUnexpectedError(error); - } - - return configurationService; - } - - private async createStorageService(workspace: IAnyWorkspaceIdentifier, environmentService: INativeWorkbenchEnvironmentService, userDataProfileService: IUserDataProfileService, userDataProfilesService: IUserDataProfilesService, mainProcessService: IMainProcessService): Promise { - const storageService = new NativeWorkbenchStorageService(workspace, userDataProfileService, userDataProfilesService, mainProcessService, environmentService); - - try { - await storageService.initialize(); - - return storageService; - } catch (error) { - onUnexpectedError(error); - - return storageService; - } - } - - private async createKeyboardLayoutService(mainProcessService: IMainProcessService): Promise { - const keyboardLayoutService = new NativeKeyboardLayoutService(mainProcessService); - - try { - await keyboardLayoutService.initialize(); - - return keyboardLayoutService; - } catch (error) { - onUnexpectedError(error); - - return keyboardLayoutService; - } - } -} - -export interface IDesktopMain { - main(configuration: INativeWindowConfiguration): Promise; -} - -export function main(configuration: INativeWindowConfiguration): Promise { - const workbench = new WhiteboardMain(configuration); - - return workbench.open(); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardBackgroundLaunch.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardBackgroundLaunch.test.ts deleted file mode 100644 index b406e163e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardBackgroundLaunch.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { FocusMode } from "../../platform/native/common/native.js"; -import { WhiteboardBackgroundLaunch } from "./whiteboardBackgroundLaunch.js"; - -const background = { DEV_FAST_WHITEBOARD_DESKTOP_BACKGROUND: "1" }; - -function fakeWindow() { - const calls: string[] = []; - let onFocus: (() => void) | undefined; - return { - calls, - focusFromUser: () => onFocus?.(), - win: { - show: () => calls.push("show"), - showInactive: () => calls.push("showInactive"), - once: (_event: "focus", listener: () => void) => { onFocus = listener; }, - }, - }; -} - -test("a normal launch leaves window creation and focus alone", () => { - const launch = new WhiteboardBackgroundLaunch({}); - const options = { show: true }; - const { win, calls } = fakeWindow(); - launch.prepare(options); - launch.attach(win); - launch.show(win); - assert.equal(options.show, true); - assert.deepEqual(calls, ["show"]); - assert.equal(launch.allowsFocus(FocusMode.Transfer), true); -}); - -test("a background launch shows the first window inactive and swallows focus until the user clicks", () => { - const launch = new WhiteboardBackgroundLaunch(background); - const options = { show: true }; - const { win, calls, focusFromUser } = fakeWindow(); - launch.prepare(options); - assert.equal(options.show, false); - launch.attach(win); - assert.deepEqual(calls, ["showInactive"]); - assert.equal(launch.allowsFocus(FocusMode.Transfer), false); - assert.equal(launch.allowsFocus(FocusMode.Notify), true); - focusFromUser(); - assert.equal(launch.suppressesFocus, false); - assert.equal(launch.allowsFocus(FocusMode.Transfer), true); - launch.show(win); - assert.deepEqual(calls, ["showInactive", "show"]); -}); - -test("a window that upstream shows later is shown inactive there instead", () => { - const launch = new WhiteboardBackgroundLaunch(background); - const options = { show: false }; // maximized or fullscreen restore - const { win, calls } = fakeWindow(); - launch.prepare(options); - launch.attach(win); - assert.deepEqual(calls, []); - launch.show(win); - assert.deepEqual(calls, ["showInactive"]); -}); - -test("a forced focus releases the gate", () => { - const launch = new WhiteboardBackgroundLaunch(background); - assert.equal(launch.allowsFocus(FocusMode.Force), true); - assert.equal(launch.suppressesFocus, false); -}); - -test("only the value 1 marks a background launch", () => { - assert.equal(new WhiteboardBackgroundLaunch({ DEV_FAST_WHITEBOARD_DESKTOP_BACKGROUND: "0" }).suppressesFocus, false); - assert.equal(new WhiteboardBackgroundLaunch({ DEV_FAST_WHITEBOARD_DESKTOP_BACKGROUND: "" }).suppressesFocus, false); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardBackgroundLaunch.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardBackgroundLaunch.ts deleted file mode 100644 index 12075689e..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardBackgroundLaunch.ts +++ /dev/null @@ -1,67 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { FocusMode } from "../../platform/native/common/native.js"; - -/** "1" on `review app` launches without --focus. */ -export const WHITEBOARD_DESKTOP_BACKGROUND_ENV = "DEV_FAST_WHITEBOARD_DESKTOP_BACKGROUND"; - -interface BackgroundWindow { - show(): void; - showInactive(): void; - once(event: "focus", listener: () => void): unknown; -} - -/** - * Shows the first window inactive and swallows focus until the user focuses a - * window or a forced focus arrives. Releases once per process. - */ -export class WhiteboardBackgroundLaunch { - private pending: boolean; - private showInactiveOnCreate = false; - - constructor(env: NodeJS.ProcessEnv = process.env) { - this.pending = env[WHITEBOARD_DESKTOP_BACKGROUND_ENV] === "1"; - } - - get suppressesFocus(): boolean { - return this.pending; - } - - /** Defers the initial show to `attach`, which shows the window inactive. */ - prepare(options: { show?: boolean }): void { - if (!this.pending || options.show === false) return; - options.show = false; - this.showInactiveOnCreate = true; - } - - attach(win: BackgroundWindow): void { - if (!this.pending) return; - if (this.showInactiveOnCreate) win.showInactive(); - win.once("focus", () => this.release()); - } - - /** show() activates the app on macOS. */ - show(win: BackgroundWindow | null | undefined): void { - if (this.pending) win?.showInactive(); - else win?.show(); - } - - allowsFocus(mode: FocusMode): boolean { - if (!this.pending) return true; - if (mode === FocusMode.Force) { - this.release(); - return true; - } - return mode === FocusMode.Notify; - } - - private release(): void { - this.pending = false; - this.showInactiveOnCreate = false; - } -} - -export const whiteboardBackgroundLaunch = new WhiteboardBackgroundLaunch(); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardDesktopChannel.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardDesktopChannel.ts deleted file mode 100644 index 2f87bdb00..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardDesktopChannel.ts +++ /dev/null @@ -1,36 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from "../../base/common/event.js"; -import { IServerChannel } from "../../base/parts/ipc/common/ipc.js"; -import type { WhiteboardDesktopConnection } from "../common/whiteboardDesktopBootstrap.js"; -import type { WhiteboardDesktopHost } from "./whiteboardDesktopHost.js"; - -export { WHITEBOARD_DESKTOP_CHANNEL } from "../common/whiteboardDesktopBootstrap.js"; - -/** - * Hands the renderer the endpoint the main process validated. Bootstrap details - * deliberately do not travel through the window configuration or the process - * environment: the main process is the only owner of the server credentials. - */ -export class WhiteboardDesktopChannel implements IServerChannel { - constructor(private readonly host: WhiteboardDesktopHost) {} - - listen(): Event { - return Event.None as Event; - } - - async call(_context: string, command: string): Promise { - if (command === "getConnection") { - const connection: WhiteboardDesktopConnection = await this.host.whenConnected(); - return connection as T; - } - if (command === "stageRustAnalyzer") { - this.host.stageRustAnalyzer(); - return undefined as T; - } - throw new Error(`Unknown Whiteboard channel call: ${command}`); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardDesktopHost.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardDesktopHost.ts deleted file mode 100644 index 73f6ab175..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardDesktopHost.ts +++ /dev/null @@ -1,151 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable, toDisposable } from "../../base/common/lifecycle.js"; -import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; -import { IEnvironmentMainService } from "../../platform/environment/electron-main/environmentMainService.js"; -import { ILifecycleMainService } from "../../platform/lifecycle/electron-main/lifecycleMainService.js"; -import { ILogService } from "../../platform/log/common/log.js"; -import { IProductService } from "../../platform/product/common/productService.js"; -import { getResolvedShellEnv } from "../../platform/shell/node/shellEnv.js"; -import { IApplicationStorageMainService } from "../../platform/storage/electron-main/storageMainService.js"; -import { NullTelemetryService } from "../../platform/telemetry/common/telemetryUtils.js"; -import { IUpdateService } from "../../platform/update/common/update.js"; -import { UtilityProcess } from "../../platform/utilityProcess/electron-main/utilityProcess.js"; -import type { WhiteboardDesktopConnection } from "../common/whiteboardDesktopBootstrap.js"; -import { WHITEBOARD_TELEMETRY_SETTING } from "../common/whiteboardConfigurationDefaults.js"; -import { WhiteboardMainErrorTelemetry } from "./whiteboardMainErrorTelemetry.js"; -import { WhiteboardServerSupervisor } from "./whiteboardServerSupervisor.js"; -import { - darwinShipItLogPath, - WhiteboardUpdateTelemetry, -} from "./whiteboardUpdateTelemetry.js"; - -/** - * Binds the embedded Whiteboard server's lifetime to the application's. All of the - * supervision logic lives in `WhiteboardServerSupervisor`, which holds no Electron - * dependency so it stays testable; this class only supplies the platform. - */ -export class WhiteboardDesktopHost extends Disposable { - private readonly supervisor: WhiteboardServerSupervisor; - private terminating = false; - - private readonly onTerminationSignal = () => { - if (this.terminating) return; - this.terminating = true; - void this.lifecycleMainService.kill(0); - }; - - constructor( - @IConfigurationService - private readonly configurationService: IConfigurationService, - @ILogService private readonly logService: ILogService, - @ILifecycleMainService - private readonly lifecycleMainService: ILifecycleMainService, - @IEnvironmentMainService - private readonly environmentMainService: IEnvironmentMainService, - @IProductService private readonly productService: IProductService, - @IUpdateService private readonly updateService: IUpdateService, - @IApplicationStorageMainService - private readonly applicationStorageMainService: IApplicationStorageMainService, - ) { - super(); - let resolvedEnvironment: Promise | undefined; - this.supervisor = this._register( - new WhiteboardServerSupervisor({ - appRoot: this.environmentMainService.appRoot, - isBuilt: this.environmentMainService.isBuilt, - userExtensionsPath: this.environmentMainService.extensionsPath, - appVersion: - this.productService.reviewVersion ?? this.productService.version, - appUrlProtocol: this.productService.urlProtocol, - serverEntryOverride: process.env["DEV_FAST_WHITEBOARD_SERVER_ENTRY"], - resolveEnvironment: () => - (resolvedEnvironment ??= getResolvedShellEnv( - this.configurationService, - this.logService, - this.environmentMainService.args, - process.env, - )), - logInfo: (message) => this.logService.info(message), - logError: (message) => this.logService.error(message), - createProcess: () => - new UtilityProcess( - this.logService, - NullTelemetryService, - this.lifecycleMainService, - ), - telemetryEnabled: - this.configurationService.getValue(WHITEBOARD_TELEMETRY_SETTING) !== - false, - }), - ); - this._register( - this.configurationService.onDidChangeConfiguration((event) => { - if (!event.affectsConfiguration(WHITEBOARD_TELEMETRY_SETTING)) return; - this.supervisor.setTelemetryEnabled( - this.configurationService.getValue( - WHITEBOARD_TELEMETRY_SETTING, - ) !== false, - ); - }), - ); - this._register( - this.lifecycleMainService.onWillShutdown((event) => { - event.join("whiteboardDesktopHost", this.supervisor.stop()); - }), - ); - // Main-process errors report through the embedded server, so they pass the - // same opt-out checks and the same redaction step as every other event. - const errorTelemetry = new WhiteboardMainErrorTelemetry({ - whenConnected: () => this.whenConnected(), - isTelemetryEnabled: () => - this.configurationService.getValue(WHITEBOARD_TELEMETRY_SETTING) !== - false, - userDataPath: this.environmentMainService.userDataPath, - logError: (message) => this.logService.error(message), - }); - this._register(toDisposable(() => errorTelemetry.dispose())); - this._register( - new WhiteboardUpdateTelemetry({ - updateService: this.updateService, - storageService: this.applicationStorageMainService, - telemetry: errorTelemetry, - isTelemetryEnabled: () => - this.configurationService.getValue( - WHITEBOARD_TELEMETRY_SETTING, - ) !== false, - shipItLogPath: this.productService.darwinBundleIdentifier - ? darwinShipItLogPath( - this.environmentMainService.userHome.fsPath, - this.productService.darwinBundleIdentifier, - ) - : undefined, - logError: (message) => this.logService.error(message), - }), - ); - process.once("SIGINT", this.onTerminationSignal); - process.once("SIGTERM", this.onTerminationSignal); - this.supervisor.start(); - } - - /** - * Resolves once the embedded server has announced a validated endpoint. The - * renderer awaits this instead of reading bootstrap environment variables. - */ - whenConnected(): Promise { - return this.supervisor.whenConnected(); - } - - stageRustAnalyzer(): void { - this.supervisor.stageRustAnalyzer(); - } - - override dispose(): void { - process.off("SIGINT", this.onTerminationSignal); - process.off("SIGTERM", this.onTerminationSignal); - super.dispose(); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMainErrorTelemetry.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMainErrorTelemetry.test.ts deleted file mode 100644 index 0f1d5f516..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMainErrorTelemetry.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { WhiteboardMainErrorTelemetry } from "./whiteboardMainErrorTelemetry.js"; - -test("posts named main-process telemetry through the embedded server", async () => { - const requests: RequestInit[] = []; - const telemetry = new WhiteboardMainErrorTelemetry({ - whenConnected: async () => ({ - version: 3, - url: "http://127.0.0.1:1234/__progressive-review", - token: "secret", - instanceId: "instance", - }), - isTelemetryEnabled: () => true, - fetchImpl: async (_input, init) => { - requests.push(init ?? {}); - return new Response(null, { status: 204 }); - }, - }); - telemetry.capture( - "update_failed", - { phase: "download", message_source: "electron" }, - { - name: "UpdateDownloadError", - message: "Download failed", - stack: "Update lifecycle telemetry", - }, - ); - await new Promise((resolve) => setImmediate(resolve)); - - assert.equal(requests.length, 1); - assert.deepEqual(JSON.parse(String(requests[0].body)), { - name: "update_failed", - properties: { phase: "download", message_source: "electron" }, - error: { - name: "UpdateDownloadError", - message: "Download failed", - stack: "Update lifecycle telemetry", - }, - }); - telemetry.dispose(); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMainErrorTelemetry.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMainErrorTelemetry.ts deleted file mode 100644 index e9938e84c..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMainErrorTelemetry.ts +++ /dev/null @@ -1,170 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { errorHandler } from "../../base/common/errors.js"; -import { generateUuid } from "../../base/common/uuid.js"; -import type { WhiteboardDesktopConnection } from "../common/whiteboardDesktopBootstrap.js"; -import { - WhiteboardErrorReportLimiter, - type WhiteboardErrorReport, -} from "../common/whiteboardErrorReport.js"; -import { whiteboardTelemetryEventRequest } from "../common/whiteboardTelemetryRequest.js"; -import { drainWhiteboardBootstrapBreadcrumbs } from "../node/whiteboardBootstrapBreadcrumb.js"; - -export interface WhiteboardMainErrorTelemetryOptions { - /** Resolves with the loopback endpoint and token of the embedded server. */ - readonly whenConnected: () => Promise; - /** Reads `whiteboard.telemetry.enabled` at the moment of the error. */ - readonly isTelemetryEnabled: () => boolean; - /** - * The Electron user data directory, where a crash that happened before the - * last launch could start leaves its note. Omit it to skip that check. - */ - readonly userDataPath?: string; - readonly logError?: (message: string) => void; - readonly fetchImpl?: typeof fetch; - readonly maxQueued?: number; -} - -const DEFAULT_MAX_QUEUED = 20; -const MAX_BOOTSTRAP_REPORTS = 5; - -interface PendingWhiteboardTelemetryEvent { - readonly name: string; - readonly properties: Readonly>; - readonly error?: WhiteboardErrorReport; -} - -/** - * Reports Electron main-process telemetry through the embedded Whiteboard server. - * - * The upstream `ErrorTelemetry` already routes `uncaughtException` and - * `unhandledRejection` into `onUnexpectedError`, so listening on the shared - * error handler covers every main-process error without touching a vendored - * file. - * - * The report goes to the loopback server, never straight to a vendor. That is - * deliberate: the server holds the opt-out checks and the redaction step, and a - * direct call from here would bypass both. - */ -export class WhiteboardMainErrorTelemetry { - readonly appSessionId = generateUuid(); - - private readonly limiter = new WhiteboardErrorReportLimiter(); - private readonly queued: PendingWhiteboardTelemetryEvent[] = []; - private readonly unbind: () => void; - private connection: WhiteboardDesktopConnection | undefined; - private disposed = false; - - constructor(private readonly options: WhiteboardMainErrorTelemetryOptions) { - this.unbind = errorHandler.addListener((error) => this.report(error)); - this.queueBootstrapBreadcrumbs(); - void this.options - .whenConnected() - .then((connection) => { - this.connection = connection; - this.drain(); - }) - .catch(() => undefined); - } - - /** Report an error that Review packed itself, such as a startup crash note. */ - send(errorSource: string, report: WhiteboardErrorReport): void { - this.capture( - "client_error", - { - error_source: errorSource, - error_process: "main", - }, - report, - ); - } - - /** Queue a named Review telemetry event for the embedded server. */ - capture( - name: string, - properties: Readonly> = {}, - error?: WhiteboardErrorReport, - ): void { - if (this.disposed) return; - const pending = { name, properties, error }; - if (this.connection) { - this.post(pending); - return; - } - this.queued.push(pending); - // The connection never resolves when the server cannot start, so the cap is - // what bounds this queue. - if (this.queued.length > (this.options.maxQueued ?? DEFAULT_MAX_QUEUED)) { - this.queued.shift(); - } - } - - dispose(): void { - this.disposed = true; - this.queued.length = 0; - this.unbind(); - } - - private report(error: unknown): void { - if (this.disposed) return; - this.limiter.report(error, (report) => - this.send("main_unexpected", report), - ); - } - - /** - * Pick up a crash that happened before the last launch could start. The note - * file is always deleted, whether or not these entries are ever sent, so an - * opted-out user never accumulates one. - */ - private queueBootstrapBreadcrumbs(): void { - const userDataPath = this.options.userDataPath; - if (!userDataPath) return; - try { - for (const breadcrumb of drainWhiteboardBootstrapBreadcrumbs( - userDataPath, - ).slice(0, MAX_BOOTSTRAP_REPORTS)) { - this.send("bootstrap", { - name: breadcrumb.name, - message: breadcrumb.message, - stack: breadcrumb.stack, - }); - } - } catch { - // A crash note must never keep the app from starting. - } - } - - private drain(): void { - for (const pending of this.queued.splice(0)) this.post(pending); - } - - private post(pending: PendingWhiteboardTelemetryEvent): void { - const connection = this.connection; - if (!connection) return; - // Read the setting at send time, not at construction: a user may turn - // telemetry off between the two. - if (!this.options.isTelemetryEnabled()) return; - const send = this.options.fetchImpl ?? fetch; - try { - void send( - `${connection.url}/telemetry/event`, - whiteboardTelemetryEventRequest( - { token: connection.token, appSessionId: this.appSessionId }, - { - name: pending.name, - properties: pending.properties, - error: pending.error, - }, - ), - ).catch(() => undefined); - } catch (error) { - this.options.logError?.( - `[Whiteboard] could not report a main-process telemetry event: ${error}`, - ); - } - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMenubar.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMenubar.ts deleted file mode 100644 index 003d32aa3..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardMenubar.ts +++ /dev/null @@ -1,372 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { app, BrowserWindow, Menu, MenuItem } from "electron"; -import { RunOnceScheduler } from "../../base/common/async.js"; -import { CancellationToken } from "../../base/common/cancellation.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import { isMacintosh } from "../../base/common/platform.js"; -import { localize } from "../../nls.js"; -import { - ILifecycleMainService, - LifecycleMainPhase, -} from "../../platform/lifecycle/electron-main/lifecycleMainService.js"; -import { ILogService } from "../../platform/log/common/log.js"; -import type { IMenubarData } from "../../platform/menubar/common/menubar.js"; -import type { IMenubarMainService } from "../../platform/menubar/electron-main/menubarMainService.js"; -import { INativeHostMainService } from "../../platform/native/electron-main/nativeHostMainService.js"; -import { IProductService } from "../../platform/product/common/productService.js"; -import type { INativeRunActionInWindowRequest } from "../../platform/window/common/window.js"; -import { IWindowsMainService } from "../../platform/windows/electron-main/windows.js"; -import { - IUpdateService, - StateType, -} from "../../platform/update/common/update.js"; - -function labelsOf(menu: Menu): string { - return menu.items - .map((item) => { - if (item.type === "separator") return "---"; - // A submenu hides its items from the log, and the log is the only record - // of the native menu the user got. - const nested = item.submenu?.items.length - ? ` (${labelsOf(item.submenu)})` - : ""; - return `${item.label}${nested}`; - }) - .join(" | "); -} - -/** - * Review's native macOS menu bar. - * - * Stock Code OSS builds its menu from `IMenubarData` that the renderer's - * `MenubarControl` pushes over the `menubar` channel. Review replaces the - * workbench and never creates that control, so `Menubar` only ever installed an - * empty menu. This service owns the menu in the main process instead: it needs - * no renderer state, which also keeps "Check for Updates..." working while the - * renderer's `IUpdateService` stays a stub. - * - * The menu is deliberately small — the three menus a Mac application must have. - * Everything else in Review is reachable from the command palette. - */ -export class WhiteboardMenubarMainService - extends Disposable - implements IMenubarMainService -{ - declare readonly _serviceBrand: undefined; - - private readonly scheduler = this._register( - new RunOnceScheduler(() => this.install(), 0), - ); - - constructor( - @ILifecycleMainService lifecycleMainService: ILifecycleMainService, - @IUpdateService private readonly updateService: IUpdateService, - @INativeHostMainService - private readonly nativeHostMainService: INativeHostMainService, - @IProductService private readonly productService: IProductService, - @IWindowsMainService - private readonly windowsMainService: IWindowsMainService, - @ILogService private readonly logService: ILogService, - ) { - super(); - - lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => { - if (this._store.isDisposed) return; - - this.configureAboutPanel(); - this.install(); - - // The update item's label is the update state in disguise, so every - // state change reinstalls the menu. - this._register(this.updateService.onStateChange(() => this.schedule())); - }); - } - - /** - * Fills in the stock macOS About panel. It is a native window, so it needs no - * renderer and it opens even when every window is closed. - */ - private configureAboutPanel(): void { - if (!isMacintosh) return; - - const { reviewVersion, version, commit } = this.productService; - - // `version` is the Code OSS base version, which means nothing to a reader. - // Show Review's own release number and keep the base version in the credits. - app.setAboutPanelOptions({ - applicationName: this.productService.nameLong, - applicationVersion: reviewVersion ?? version, - // macOS prints this in parentheses after the version. The commit is what - // the update feed matches on, so it is the build identity that matters. - version: commit ? commit.substring(0, 10) : "", - copyright: localize("whiteboard.about.copyright", "Copyright © 2026 /dev/fast"), - credits: localize("whiteboard.about.codeOss", "Code OSS {0}", version), - }); - } - - /** - * No-op. The renderer keeps `menubarService` registered, so the channel must - * stay answerable, but Review never sends menu data. - */ - async updateMenubar( - _windowId: number, - _menus: IMenubarData, - ): Promise {} - - private schedule(): void { - // Electron cannot mutate a live menu, so every change reinstalls the whole - // menu. Buffer overlapping changes into one rebuild. - if (!this.scheduler.isScheduled()) { - this.scheduler.schedule(); - } - } - - private install(): void { - if (!isMacintosh) { - // Review hides the menu bar on Windows and Linux - // (`window.menuBarVisibility`), so there is nothing to install there. - Menu.setApplicationMenu(null); - return; - } - - const applicationMenu = this.createApplicationMenu(); - const menubar = new Menu(); - menubar.append( - new MenuItem({ - label: this.productService.nameShort, - submenu: applicationMenu, - }), - ); - const editMenuItem = new MenuItem({ - label: localize("review.menu.edit", "Edit"), - role: "editMenu", - }); - editMenuItem.submenu?.insert( - 2, - new MenuItem({ - label: localize("review.menu.find", "Find"), - accelerator: "Command+F", - // Show the standard shortcut in the native menu, but let the focused - // renderer resolve it. Tree, webview, notebook, source, and - // Review each own a context-specific Find command. - registerAccelerator: false, - click: () => this.runActionInFocusedWindow("whiteboard.action.find"), - }), - ); - menubar.append(editMenuItem); - menubar.append( - new MenuItem({ - label: localize("review.menu.window", "Window"), - role: "windowMenu", - }), - ); - - Menu.setApplicationMenu(menubar); - - // The menu is native, so this log is the only record of what the user got. - // It also names the update item, which is the update state in disguise. - this.logService.info( - `whiteboardMenubar#install - menus [${labelsOf(menubar)}], application menu [${labelsOf(applicationMenu)}]`, - ); - } - - private createApplicationMenu(): Menu { - const name = this.productService.nameLong; - const menu = new Menu(); - - menu.append( - new MenuItem({ - label: localize("review.menu.about", "About {0}", name), - role: "about", - }), - ); - - for (const item of this.createUpdateMenuItems()) { - menu.append(item); - } - - // The macOS settings slot. Every item runs the same renderer action as its - // command palette entry. Electron consumes the accelerator before the web - // contents, so the workbench keybinding on whiteboard.openSettings and this - // item cannot both fire. - const preferences = new Menu(); - preferences.append( - new MenuItem({ - label: localize("review.menu.settings", "Settings..."), - accelerator: "Command+,", - click: () => this.runActionInFocusedWindow("whiteboard.openSettings"), - }), - ); - // The Welcome pane stays reachable after Home fills with reviews: first - // run opens no tab of its own, so this is the durable path back. - preferences.append( - new MenuItem({ - label: localize("review.menu.gettingStarted", "Getting Started..."), - click: () => this.runActionInFocusedWindow("whiteboard.openWelcome"), - }), - ); - preferences.append(new MenuItem({ type: "separator" })); - preferences.append( - new MenuItem({ - label: localize( - "review.menu.uninstall", - "Uninstall Whiteboard...", - ), - click: () => this.runActionInFocusedWindow("whiteboard.uninstallApp"), - }), - ); - - menu.append(new MenuItem({ type: "separator" })); - menu.append( - new MenuItem({ - label: localize("review.menu.preferences", "Preferences"), - submenu: preferences, - }), - ); - - menu.append(new MenuItem({ type: "separator" })); - menu.append( - new MenuItem({ - label: localize("review.menu.services", "Services"), - role: "services", - submenu: [], - }), - ); - menu.append(new MenuItem({ type: "separator" })); - menu.append( - new MenuItem({ - label: localize("review.menu.hide", "Hide {0}", name), - role: "hide", - }), - ); - menu.append( - new MenuItem({ - label: localize("review.menu.hideOthers", "Hide Others"), - role: "hideOthers", - }), - ); - menu.append( - new MenuItem({ - label: localize("review.menu.showAll", "Show All"), - role: "unhide", - }), - ); - menu.append(new MenuItem({ type: "separator" })); - menu.append( - new MenuItem({ - label: localize("review.menu.quit", "Quit {0}", name), - accelerator: "Command+Q", - click: () => this.nativeHostMainService.quit(undefined), - }), - ); - - return menu; - } - - /** - * Runs a renderer command in the focused (or last active) window, mirroring - * stock `Menubar#runActionInRenderer`. Review has no auxiliary windows, so - * the focused Electron window maps straight to a workbench window. - */ - private runActionInFocusedWindow(commandId: string): void { - const focused = BrowserWindow.getFocusedWindow(); - const window = focused - ? this.windowsMainService.getWindowById(focused.id) - : this.windowsMainService.getLastActiveWindow(); - if (!window) { - this.logService.info( - `whiteboardMenubar#runActionInFocusedWindow - no window for ${commandId}`, - ); - return; - } - const payload: INativeRunActionInWindowRequest = { - id: commandId, - from: "menu", - }; - window.sendWhenReady("vscode:runAction", CancellationToken.None, payload); - } - - /** - * The update item, mirroring stock Code OSS's app menu. Updates are disabled - * out of sources, so this contributes nothing to a development run. - */ - private createUpdateMenuItems(): MenuItem[] { - switch (this.updateService.state.type) { - case StateType.Idle: - return [ - new MenuItem({ - label: localize("review.menu.checkForUpdates", "Check for Updates..."), - // Detached so the menu closes before the check's dialog can open. - click: () => - setTimeout(() => { - this.updateService.checkForUpdates(true).catch((error) => { - this.logService.error( - "whiteboardMenubar#checkForUpdates failed", - error, - ); - }); - }, 0), - }), - ]; - - case StateType.CheckingForUpdates: - return [ - new MenuItem({ - label: localize( - "review.menu.checkingForUpdates", - "Checking for Updates...", - ), - enabled: false, - }), - ]; - - case StateType.Downloading: - case StateType.Overwriting: - return [ - new MenuItem({ - label: localize( - "review.menu.downloadingUpdate", - "Downloading Update...", - ), - enabled: false, - }), - ]; - - case StateType.Updating: - return [ - new MenuItem({ - label: localize( - "review.menu.installingUpdate", - "Installing Update...", - ), - enabled: false, - }), - ]; - - case StateType.Ready: - return [ - new MenuItem({ - label: localize("review.menu.restartToUpdate", "Restart to Update"), - click: () => { - this.updateService.quitAndInstall().catch((error) => { - this.logService.error( - "whiteboardMenubar#quitAndInstall failed", - error, - ); - }); - }, - }), - ]; - - // Disabled, Uninitialized, and the macOS-unreachable download states - // contribute nothing. - default: - return []; - } - } - -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardServerSupervisor.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardServerSupervisor.test.ts deleted file mode 100644 index 3d5dd4c17..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardServerSupervisor.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'node:assert/strict'; -import test from 'node:test'; - -import { createWhiteboardServerEnvironment } from './whiteboardServerSupervisor.js'; - -test('the trusted product version overrides inherited environment values', () => { - const environment = createWhiteboardServerEnvironment({ - applicationEnvironment: { - DEV_FAST_WHITEBOARD_APP_VERSION: '0.0.1', - PATH: '/application/bin', - }, - resolvedEnvironment: { - DEV_FAST_WHITEBOARD_APP_VERSION: '99.0.0', - PATH: '/login/bin', - }, - appVersion: '0.0.16', - serverEntry: '/review/server.js', - port: 4321, - token: 'token', - instanceId: 'instance', - appPid: 1234, - telemetryEnabled: true, - }); - - assert.equal(environment.PATH, '/login/bin'); - assert.equal(environment.DEV_FAST_WHITEBOARD_APP_VERSION, '0.0.16'); - assert.equal(environment.DEV_FAST_WHITEBOARD_SERVER_ENTRY, '/review/server.js'); - assert.equal(environment.DEV_FAST_WHITEBOARD_SERVER_PORT, '4321'); - assert.equal(environment.DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED, undefined); -}); - -for (const protocol of ['dev-fast-review', 'dev-fast-review-preview']) { - test(`the app protocol overrides the shell protocol (${protocol})`, () => { - const environment = createWhiteboardServerEnvironment({ - applicationEnvironment: { DEV_FAST_WHITEBOARD_APP_URL_PROTOCOL: 'inherited' }, - resolvedEnvironment: { DEV_FAST_WHITEBOARD_APP_URL_PROTOCOL: 'shell' }, - appVersion: '0.0.16', - appUrlProtocol: protocol, - serverEntry: '/review/server.js', - port: 4321, - token: 'token', - instanceId: 'instance', - appPid: 1234, - telemetryEnabled: true, - }); - assert.equal(environment.DEV_FAST_WHITEBOARD_APP_URL_PROTOCOL, protocol); - }); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardServerSupervisor.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardServerSupervisor.ts deleted file mode 100644 index d165f70be..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardServerSupervisor.ts +++ /dev/null @@ -1,414 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { randomBytes, randomUUID } from "node:crypto"; -import fs from "node:fs"; -import path from "node:path"; -import { DeferredPromise, timeout } from "../../base/common/async.js"; -import { Event } from "../../base/common/event.js"; -import { - Disposable, - DisposableStore, - IDisposable, -} from "../../base/common/lifecycle.js"; -import { join } from "../../base/common/path.js"; -import * as semver from "../../base/common/semver/semver.js"; -import { - type WhiteboardDesktopConnection, - WhiteboardReadyEventReader, - resolveWhiteboardServerEntry, -} from "../common/whiteboardDesktopBootstrap.js"; -import { WHITEBOARD_SERVER_RESTART_DELAYS } from "../common/whiteboardReconnect.js"; - -/** - * The slice of `UtilityProcess` the supervisor drives. Depending on this rather - * than the concrete class keeps the supervisor free of any Electron import, so - * its readiness, restart, and credential-stability behaviour can be tested. - */ -export interface IWhiteboardServerProcess extends IDisposable { - readonly onStdout: Event; - readonly onStderr: Event; - readonly onExit: Event<{ readonly code: number; readonly signal: string }>; - readonly onCrash: Event<{ readonly code: number; readonly reason: string }>; - start(configuration: { - readonly type: string; - readonly name: string; - readonly entryPoint: string; - readonly parentLifecycleBound?: number; - readonly env?: Record; - }): boolean; - postMessage(message: unknown): unknown; - kill(): void; -} - -export interface WhiteboardServerSupervisorOptions { - readonly appRoot: string; - readonly appVersion: string; - readonly appUrlProtocol?: string; - readonly isBuilt: boolean; - readonly serverEntryOverride?: string | undefined; - readonly readyTimeout?: number; - readonly appPid?: number; - readonly resolveEnvironment?: () => Promise; - readonly logInfo: (message: string) => void; - readonly logError: (message: string) => void; - readonly createProcess: () => IWhiteboardServerProcess; - readonly telemetryEnabled?: boolean; - readonly userExtensionsPath?: string; -} - -export function createWhiteboardServerEnvironment(options: { - readonly applicationEnvironment: NodeJS.ProcessEnv; - readonly resolvedEnvironment: NodeJS.ProcessEnv; - readonly appVersion: string; - readonly appUrlProtocol?: string; - readonly serverEntry: string; - readonly port: number; - readonly token: string; - readonly instanceId: string; - readonly appPid: number; - readonly telemetryEnabled: boolean; - readonly rustAnalyzerSource?: string; -}): Record { - return { - ...options.applicationEnvironment, - ...options.resolvedEnvironment, - DEV_FAST_WHITEBOARD_SERVER_ENTRY: options.serverEntry, - DEV_FAST_WHITEBOARD_SERVER_PORT: String(options.port), - DEV_FAST_WHITEBOARD_SERVER_TOKEN: options.token, - DEV_FAST_WHITEBOARD_INSTANCE_ID: options.instanceId, - DEV_FAST_WHITEBOARD_APP_PID: String(options.appPid), - DEV_FAST_WHITEBOARD_APP_VERSION: options.appVersion, - DEV_FAST_WHITEBOARD_APP_URL_PROTOCOL: options.appUrlProtocol, - DEV_FAST_WHITEBOARD_DESKTOP_HOST_AUTOSTART: "1", - DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED: options.telemetryEnabled - ? undefined - : "1", - // The app's own Electron binary doubles as the CLI's Node runtime - // (ELECTRON_RUN_AS_NODE), so an installed `review` command never - // depends on a system Node. - DEV_FAST_WHITEBOARD_CLI_RUNTIME: process.execPath, - DEV_FAST_WHITEBOARD_RUST_ANALYZER: options.rustAnalyzerSource, - }; -} - -function executableName(): string { - return process.platform === "win32" ? "rust-analyzer.exe" : "rust-analyzer"; -} - -function isExecutableFile(file: string): boolean { - try { - if (!fs.statSync(file).isFile()) return false; - fs.accessSync(file, fs.constants.X_OK); - return true; - } catch { - return false; - } -} - -function resolveInstalledRustAnalyzer(userExtensionsPath: string | undefined): string | undefined { - if (!userExtensionsPath) return undefined; - const candidates: { version: string; executable: string }[] = []; - let entries: fs.Dirent[]; - try { - entries = fs.readdirSync(userExtensionsPath, { withFileTypes: true }); - } catch { - return undefined; - } - for (const entry of entries) { - if (!entry.isDirectory() || !entry.name.startsWith("rust-lang.rust-analyzer-")) { - continue; - } - const directory = path.join(userExtensionsPath, entry.name); - try { - const manifest = JSON.parse(fs.readFileSync(path.join(directory, "package.json"), "utf8")) as { version?: unknown }; - if (typeof manifest.version !== "string" || !semver.valid(manifest.version)) { - continue; - } - const executable = path.join(directory, "server", executableName()); - if (isExecutableFile(executable)) { - candidates.push({ version: manifest.version, executable }); - } - } catch { - // Ignore incomplete extension directories left by interrupted installs. - } - } - candidates.sort((left, right) => semver.rcompare(left.version, right.version)); - return candidates[0]?.executable; -} - -function resolveRustAnalyzerSource(options: { - readonly userExtensionsPath?: string; - readonly appRoot: string; - readonly isBuilt: boolean; -}): string | undefined { - const installed = resolveInstalledRustAnalyzer(options.userExtensionsPath); - if (installed) return installed; - if (options.isBuilt) return undefined; - const developmentFallback = path.join( - options.appRoot, - "extensions", - "rust-lang.rust-analyzer", - "server", - executableName(), - ); - return isExecutableFile(developmentFallback) ? developmentFallback : undefined; -} - -/** - * Owns the embedded Whiteboard server's lifetime: resolving its entry point, - * minting its credentials, waiting for it to announce a validated endpoint, and - * restarting it without moving that endpoint. - */ -export class WhiteboardServerSupervisor extends Disposable { - private serverProcess: IWhiteboardServerProcess | undefined; - private processListeners = new DisposableStore(); - private restartTimer: ReturnType | undefined; - private restartCount = 0; - private stopping = false; - private telemetryEnabled: boolean; - - /** - * Credentials are minted once and reused for the life of the application, so - * a restart keeps every renderer's existing connection valid. The port is - * chosen by the OS on first start and then pinned for the same reason. - */ - private readonly token = randomBytes(32).toString("base64url"); - private readonly instanceId = randomUUID(); - private port = 0; - - private readonly connected = new DeferredPromise(); - private readonly readyTimeout: number; - - constructor(private readonly options: WhiteboardServerSupervisorOptions) { - super(); - this.readyTimeout = options.readyTimeout ?? 30_000; - this.telemetryEnabled = options.telemetryEnabled !== false; - } - - setTelemetryEnabled(enabled: boolean): void { - this.telemetryEnabled = enabled; - this.serverProcess?.postMessage({ type: "telemetry-setting", enabled }); - } - - stageRustAnalyzer(): void { - const sourcePath = resolveRustAnalyzerSource(this.options); - if (!sourcePath) { - this.options.logError("[Whiteboard] no installed rust-analyzer source is available to stage."); - return; - } - if (!this.serverProcess) { - this.options.logError("[Whiteboard] the Whiteboard server is unavailable for rust-analyzer staging."); - return; - } - this.serverProcess.postMessage({ type: "stage-rust-analyzer", path: sourcePath }); - } - - /** Resolves once the server has announced an endpoint this process trusts. */ - whenConnected(): Promise { - return this.connected.p; - } - - start(): void { - if (this.stopping) return; - let resolution: Promise | undefined; - try { - resolution = this.options.resolveEnvironment?.(); - } catch (error) { - this.handleEnvironmentResolutionFailure(error); - return; - } - if (!resolution) { - this.startWithEnvironment({}); - return; - } - void resolution.then( - (environment) => this.startWithEnvironment(environment), - (error) => this.handleEnvironmentResolutionFailure(error), - ); - } - - private handleEnvironmentResolutionFailure(error: unknown): void { - const reason = error instanceof Error ? error.message : String(error); - this.options.logError( - `[Whiteboard] unable to resolve the login-shell environment; starting with the application environment: ${reason}`, - ); - this.startWithEnvironment({}); - } - - private startWithEnvironment( - resolvedEnvironment: NodeJS.ProcessEnv, - ): void { - if (this.stopping) return; - const serverEntry = resolveWhiteboardServerEntry({ - isBuilt: this.options.isBuilt, - appRoot: this.options.appRoot, - serverEntryOverride: this.options.serverEntryOverride, - join, - }); - this.processListeners.dispose(); - this.processListeners = new DisposableStore(); - const serverProcess = this.options.createProcess(); - this.serverProcess = serverProcess; - this.processListeners.add(serverProcess); - - const reader = new WhiteboardReadyEventReader({ - token: this.token, - instanceId: this.instanceId, - }); - let ready = false; - this.processListeners.add( - serverProcess.onStdout((value) => { - this.options.logInfo(`[Whiteboard server] ${value.trimEnd()}`); - if (ready) return; - this.armReadyTimeout(); - let connection: WhiteboardDesktopConnection | undefined; - try { - connection = reader.push(value); - } catch (error) { - this.failStartup(error); - return; - } - if (!connection) return; - ready = true; - this.port = Number(new URL(connection.url).port); - this.restartCount = 0; - if (!this.connected.isSettled) { - this.options.logInfo( - `[Whiteboard] server ready at ${connection.url}`, - ); - void this.connected.complete(connection); - } - }), - ); - this.processListeners.add( - serverProcess.onStderr((value) => - this.options.logError(`[Whiteboard server] ${value.trimEnd()}`), - ), - ); - - let terminated = false; - const onTerminated = (detail: string) => { - if (terminated) return; - terminated = true; - this.options.logError( - `[Whiteboard] server host terminated: ${detail}`, - ); - this.serverProcess = undefined; - this.processListeners.dispose(); - if (this.stopping) return; - if (!ready && !this.connected.isSettled) { - this.options.logError( - "[Whiteboard] server host exited before announcing an endpoint.", - ); - } - const delay = WHITEBOARD_SERVER_RESTART_DELAYS[this.restartCount++]; - if (delay === undefined) { - this.failStartup( - new Error( - "The Whiteboard server exhausted its restart budget without becoming ready.", - ), - ); - return; - } - this.restartTimer = setTimeout(() => this.start(), delay); - }; - this.processListeners.add( - serverProcess.onExit((event) => - onTerminated( - `exit ${event.code ?? "unknown"} (${event.signal ?? "no signal"})`, - ), - ), - ); - this.processListeners.add( - serverProcess.onCrash((event) => - onTerminated(`${event.reason} (${event.code ?? "unknown"})`), - ), - ); - - const appPid = this.options.appPid ?? process.pid; - const rustAnalyzerSource = resolveRustAnalyzerSource(this.options); - const environment = createWhiteboardServerEnvironment({ - applicationEnvironment: process.env, - resolvedEnvironment, - appVersion: this.options.appVersion, - appUrlProtocol: this.options.appUrlProtocol, - serverEntry, - port: this.port, - token: this.token, - instanceId: this.instanceId, - appPid, - telemetryEnabled: this.telemetryEnabled, - rustAnalyzerSource, - }); - const started = serverProcess.start({ - type: "review-desktop-host", - name: "Whiteboard host", - entryPoint: "vs/whiteboard/electron-utility/whiteboardDesktopHostMain", - parentLifecycleBound: appPid, - env: environment, - }); - if (!started) { - onTerminated("launch failed"); - return; - } - if (!this.connected.isSettled) this.armReadyTimeout(); - } - - private readyTimeoutEpoch = 0; - - private armReadyTimeout(): void { - const epoch = ++this.readyTimeoutEpoch; - void timeout(this.readyTimeout).then(() => { - if (epoch !== this.readyTimeoutEpoch || this.stopping || this.connected.isSettled) return; - this.failStartup( - new Error( - `The Whiteboard server did not become ready within ${this.readyTimeout}ms.`, - ), - ); - }); - } - - private failStartup(error: unknown): void { - const reason = error instanceof Error ? error : new Error(String(error)); - this.options.logError(`[Whiteboard] ${reason.message}`); - if (!this.connected.isSettled) this.connected.error(reason); - } - - async stop(): Promise { - if (this.stopping) return; - this.stopping = true; - if (this.restartTimer) clearTimeout(this.restartTimer); - const serverProcess = this.serverProcess; - if (!serverProcess) return; - serverProcess.postMessage({ type: "shutdown" }); - await Promise.race([ - new Promise((resolve) => { - const store = new DisposableStore(); - store.add( - serverProcess.onExit(() => { - store.dispose(); - resolve(); - }), - ); - store.add( - serverProcess.onCrash(() => { - store.dispose(); - resolve(); - }), - ); - }), - timeout(2_000), - ]); - serverProcess.kill(); - this.processListeners.dispose(); - this.serverProcess = undefined; - } - - override dispose(): void { - void this.stop(); - super.dispose(); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateDialog.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateDialog.ts deleted file mode 100644 index 1cc4e7b94..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateDialog.ts +++ /dev/null @@ -1,88 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable } from "../../base/common/lifecycle.js"; -import { localize } from "../../nls.js"; -import { IDialogMainService } from "../../platform/dialogs/electron-main/dialogMainService.js"; -import { ILogService } from "../../platform/log/common/log.js"; -import { - IUpdateService, - StateType, -} from "../../platform/update/common/update.js"; - -/** - * Reports the outcome of an explicit "Check for Updates..." with a native - * dialog. - * - * Stock Code OSS reports this from the workbench (`UpdateContribution`) and - * keeps `NotAvailableUpdateDialog` only for the windowless case. Review's - * renderer registers a no-op `IUpdateService`, so a native dialog is the whole - * feedback path here — with a window open or not. - * - * Only explicit checks report. Background checks stay silent, matching stock. - */ -export class WhiteboardUpdateDialog extends Disposable { - private awaitingExplicitResult = false; - - constructor( - @IUpdateService updateService: IUpdateService, - @IDialogMainService private readonly dialogMainService: IDialogMainService, - @ILogService private readonly logService: ILogService, - ) { - super(); - - this._register( - updateService.onStateChange((state) => { - if (state.type === StateType.CheckingForUpdates) { - this.awaitingExplicitResult = state.explicit; - return; - } - - if (!this.awaitingExplicitResult) { - return; - } - this.awaitingExplicitResult = false; - - // Only a check that found nothing, or failed, needs a dialog. A found - // update tells its own story: macOS downloads it and the menu item - // becomes "Restart to Update". - if (state.type !== StateType.Idle) { - return; - } - - if (state.error) { - this.show( - "error", - localize( - "review.update.failed", - "Could not check for updates. Please try again later.", - ), - state.error, - ); - return; - } - - if (state.notAvailable) { - this.show( - "info", - localize( - "review.update.noUpdatesAvailable", - "There are currently no updates available.", - ), - ); - } - }), - ); - } - - private show(type: "info" | "error", message: string, detail?: string): void { - this.logService.info(`whiteboardUpdateDialog#show - ${type}: ${message}`); - this.dialogMainService - .showMessageBox({ type, message, detail }) - .catch((error) => { - this.logService.error("whiteboardUpdateDialog#show failed", error); - }); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateTelemetry.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateTelemetry.test.ts deleted file mode 100644 index 97a3918ca..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateTelemetry.test.ts +++ /dev/null @@ -1,325 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import { appendFile, mkdtemp, rm, writeFile } from "node:fs/promises"; -import { tmpdir } from "node:os"; -import { join } from "node:path"; -import test from "node:test"; - -import { Emitter } from "../../base/common/event.js"; -import { toDisposable } from "../../base/common/lifecycle.js"; -import { - DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, -} from "../../platform/update/common/darwinUpdateRecovery.js"; -import { - State, - type IUpdateService, - type State as UpdateState, - UpdateType, -} from "../../platform/update/common/update.js"; -import { - StorageScope, - type IStorageValueChangeEvent, -} from "../../platform/storage/common/storage.js"; -import type { IApplicationStorageMainService } from "../../platform/storage/electron-main/storageMainService.js"; -import type { WhiteboardMainErrorTelemetry } from "./whiteboardMainErrorTelemetry.js"; -import { - extractDarwinShipItFailureMessage, - readDarwinShipItFailure, - WhiteboardUpdateTelemetry, -} from "./whiteboardUpdateTelemetry.js"; - -const attempt = { - sourceCommit: "source", - targetCommit: "target", - productVersion: "0.0.27", - attemptedAt: 100, - attemptId: "12345678-1234-1234-1234-123456789abc", - shipItLogOffset: 4096, -}; - -test("extracts only the last concise ShipIt NSError summary", () => { - const log = [ - 'Installation error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied" UserInfo={private=/Users/alice/repo}', - "retrying", - 'Installation error: Error Domain=SQRLInstallerErrorDomain Code=-1 "Failed to copy bundle file:///Users/alice/Review.app to directory file:///Applications" UserInfo={private=secret}', - ].join("\n"); - const message = extractDarwinShipItFailureMessage(log); - assert.equal( - message, - 'Error Domain=SQRLInstallerErrorDomain Code=-1 "Failed to copy bundle file:///Users/alice/Review.app to directory file:///Applications"', - ); - assert.equal(message?.includes("UserInfo"), false); - assert.equal(message?.includes("private=secret"), false); -}); - -test("uses the bounded ShipIt retry summary when NSError parsing fails", () => { - assert.equal( - extractDarwinShipItFailureMessage( - "details\nToo many attempts to install, aborting update\n", - ), - "Too many attempts to install, aborting update", - ); -}); - -test("reads only ShipIt output appended after the matching attempt", async () => { - const directory = await mkdtemp(join(tmpdir(), "review-shipit-")); - const path = join(directory, "ShipIt_stderr.log"); - try { - const oldError = - 'Installation error: Error Domain=OldDomain Code=1 "Old failure"\n'; - await writeFile(path, oldError, "utf8"); - await appendFile( - path, - 'Installation error: Error Domain=NewDomain Code=13 "Permission denied" UserInfo={private=secret}\n', - "utf8", - ); - assert.deepEqual(await readDarwinShipItFailure(path, oldError.length), { - message: 'Error Domain=NewDomain Code=13 "Permission denied"', - source: "shipit", - }); - } finally { - await rm(directory, { recursive: true, force: true }); - } -}); - -test("reports staged, immediate failure, and terminal update events", async () => { - const harness = createHarness(); - const telemetry = new WhiteboardUpdateTelemetry(harness.options); - await turn(); - - harness.storage.storeValue( - DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, - JSON.stringify(attempt), - ); - harness.update.setState( - State.Ready( - { version: attempt.targetCommit, productVersion: attempt.productVersion }, - false, - false, - ), - ); - harness.update.setState( - State.Ready( - { version: attempt.targetCommit, productVersion: attempt.productVersion }, - false, - false, - ), - ); - - harness.update.setState(State.CheckingForUpdates(false)); - harness.update.setState( - State.Idle(UpdateType.Archive, "Feed unavailable", undefined, "request"), - ); - - harness.storage.storeValue( - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, - JSON.stringify({ kind: "applied", attempt, resolvedAt: 600 }), - ); - await turn(); - - assert.deepEqual( - harness.events.map((event) => event.name), - ["update_started", "update_failed", "update_completed"], - ); - assert.deepEqual(harness.events[1], { - name: "update_failed", - properties: { phase: "check", message_source: "request" }, - error: { - name: "UpdateCheckError", - message: "Feed unavailable", - stack: "Update lifecycle telemetry", - }, - }); - assert.deepEqual(harness.events[2].properties, { - update_attempt_id: attempt.attemptId, - target_version: attempt.productVersion, - duration_ms: 500, - }); - assert.equal( - harness.storage.getValue(DARWIN_UPDATE_OUTCOME_STORAGE_KEY), - undefined, - ); - telemetry.dispose(); -}); - -test("reports an install failure with the matched ShipIt message", async () => { - const harness = createHarness({ - outcome: { kind: "failed", attempt, resolvedAt: 700 }, - readInstallFailure: async () => ({ - message: 'Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"', - source: "shipit", - }), - }); - const telemetry = new WhiteboardUpdateTelemetry(harness.options); - await turn(); - - assert.deepEqual(harness.events, [ - { - name: "update_failed", - properties: { - update_attempt_id: attempt.attemptId, - target_version: attempt.productVersion, - duration_ms: 600, - phase: "install", - message_source: "shipit", - }, - error: { - name: "UpdateInstallError", - message: 'Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"', - stack: "Update lifecycle telemetry", - }, - }, - ]); - telemetry.dispose(); -}); - -test("consumes disabled lifecycle records without reporting them later", async () => { - let enabled = false; - const harness = createHarness({ - enabled: () => enabled, - outcome: { kind: "applied", attempt, resolvedAt: 600 }, - }); - const telemetry = new WhiteboardUpdateTelemetry(harness.options); - await turn(); - assert.deepEqual(harness.events, []); - assert.equal( - harness.storage.getValue(DARWIN_UPDATE_OUTCOME_STORAGE_KEY), - undefined, - ); - - harness.storage.storeValue( - DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, - JSON.stringify(attempt), - ); - harness.update.setState( - State.Ready( - { version: attempt.targetCommit, productVersion: attempt.productVersion }, - false, - false, - ), - ); - assert.deepEqual(harness.events, []); - - enabled = true; - harness.update.setState( - State.Ready( - { version: attempt.targetCommit, productVersion: attempt.productVersion }, - false, - false, - ), - ); - assert.deepEqual(harness.events, []); - telemetry.dispose(); -}); - -function createHarness(options?: { - readonly enabled?: () => boolean; - readonly outcome?: unknown; - readonly readInstallFailure?: () => Promise<{ - message: string; - source: "shipit"; - }>; -}) { - const storage = new FakeStorage(); - if (options?.outcome) { - storage.storeValue( - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, - JSON.stringify(options.outcome), - ); - } - const update = new FakeUpdateService(); - const events: Array<{ - name: string; - properties: Readonly>; - error?: unknown; - }> = []; - const telemetry = { - capture(name: string, properties: Record, error?: unknown) { - events.push({ name, properties, error }); - }, - } as unknown as WhiteboardMainErrorTelemetry; - return { - storage, - update, - events, - options: { - updateService: update as unknown as IUpdateService, - storageService: storage as unknown as IApplicationStorageMainService, - telemetry, - isTelemetryEnabled: options?.enabled ?? (() => true), - shipItLogPath: "/tmp/ShipIt_stderr.log", - readInstallFailure: options?.readInstallFailure, - }, - }; -} - -class FakeUpdateService { - private readonly emitter = new Emitter(); - readonly onStateChange = this.emitter.event; - state: UpdateState = State.Idle(UpdateType.Archive); - - setState(state: UpdateState): void { - this.state = state; - this.emitter.fire(this.state); - } -} - -class FakeStorage { - readonly whenReady = Promise.resolve(); - private readonly values = new Map(); - private readonly emitters = new Map>(); - - getValue(key: string): string | undefined { - return this.values.get(key); - } - - storeValue(key: string, value: string): void { - this.values.set(key, value); - this.fire(key); - } - - get(key: string): string | undefined { - return this.values.get(key); - } - - store(key: string, value: string): void { - this.storeValue(key, value); - } - - remove(key: string): void { - this.values.delete(key); - this.fire(key); - } - - flush(): Promise { - return Promise.resolve(); - } - - onDidChangeValue(_scope: StorageScope, key: string | undefined) { - if (!key) return () => toDisposable(() => undefined); - let emitter = this.emitters.get(key); - if (!emitter) { - emitter = new Emitter(); - this.emitters.set(key, emitter); - } - return emitter.event; - } - - private fire(key: string): void { - this.emitters.get(key)?.fire({ - key, - scope: StorageScope.APPLICATION, - target: undefined, - external: false, - }); - } -} - -async function turn(): Promise { - await new Promise((resolve) => setImmediate(resolve)); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateTelemetry.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateTelemetry.ts deleted file mode 100644 index 1d277f281..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-main/whiteboardUpdateTelemetry.ts +++ /dev/null @@ -1,310 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { open } from "node:fs/promises"; -import { join } from "node:path"; - -import { Disposable, DisposableStore } from "../../base/common/lifecycle.js"; -import { - DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, - parseDarwinUpdateAttempt, - parseDarwinUpdateOutcomeRecord, - type IDarwinUpdateAttempt, -} from "../../platform/update/common/darwinUpdateRecovery.js"; -import { - type IUpdateService, - type State, - StateType, -} from "../../platform/update/common/update.js"; -import { - StorageScope, - StorageTarget, -} from "../../platform/storage/common/storage.js"; -import type { IApplicationStorageMainService } from "../../platform/storage/electron-main/storageMainService.js"; -import type { WhiteboardMainErrorTelemetry } from "./whiteboardMainErrorTelemetry.js"; - -const UPDATE_STARTED_STORAGE_KEY = "review/update/telemetry/started.v1"; -const MAX_SHIPIT_LOG_BYTES = 64 * 1024; -const INSTALL_FALLBACK_MESSAGE = - "The downloaded update did not replace the running application."; - -export type WhiteboardUpdateFailurePhase = "check" | "download" | "install"; -export type WhiteboardUpdateMessageSource = - | "electron" - | "request" - | "shipit" - | "fallback"; - -interface WhiteboardUpdateTelemetryOptions { - readonly updateService: IUpdateService; - readonly storageService: IApplicationStorageMainService; - readonly telemetry: WhiteboardMainErrorTelemetry; - readonly isTelemetryEnabled: () => boolean; - readonly shipItLogPath?: string; - readonly readInstallFailure?: ( - path: string, - offset: number | undefined, - ) => Promise<{ message: string; source: WhiteboardUpdateMessageSource }>; - readonly logError?: (message: string) => void; -} - -/** - * Converts updater state and persisted Darwin restart outcomes into the three - * Review update lifecycle events. Raw ShipIt output never leaves this module. - */ -export class WhiteboardUpdateTelemetry extends Disposable { - private lastState: State; - - constructor(private readonly options: WhiteboardUpdateTelemetryOptions) { - super(); - this.lastState = options.updateService.state; - this._register( - options.updateService.onStateChange((state) => { - this.onStateChange(state); - this.lastState = state; - }), - ); - - const storageListeners = this._register(new DisposableStore()); - const onOutcomeChanged = options.storageService.onDidChangeValue( - StorageScope.APPLICATION, - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, - storageListeners, - ); - this._register(onOutcomeChanged(() => void this.processOutcome())); - - void options.storageService.whenReady - .then(() => { - if (options.updateService.state.type === StateType.Ready) { - this.recordStarted(); - } - return this.processOutcome(); - }) - .catch((error) => - options.logError?.( - `[Whiteboard] could not process update telemetry: ${error}`, - ), - ); - } - - private onStateChange(state: State): void { - if (state.type === StateType.Ready) { - this.recordStarted(); - return; - } - if (state.type !== StateType.Idle || !state.error) { - return; - } - const phase = updateFailurePhase(this.lastState); - if (!phase || !this.options.isTelemetryEnabled()) { - return; - } - this.captureFailure( - phase, - state.errorSource ?? "electron", - state.error, - ); - } - - private recordStarted(): void { - const attempt = parseDarwinUpdateAttempt( - this.options.storageService.get( - DARWIN_UPDATE_ATTEMPT_STORAGE_KEY, - StorageScope.APPLICATION, - ), - ); - if (!attempt?.attemptId || !attempt.productVersion) { - return; - } - const lastStarted = this.options.storageService.get( - UPDATE_STARTED_STORAGE_KEY, - StorageScope.APPLICATION, - ); - if (lastStarted === attempt.attemptId) { - return; - } - - // Mark it observed even when telemetry is disabled. Enabling telemetry - // later must not send an event for an earlier update. - this.options.storageService.store( - UPDATE_STARTED_STORAGE_KEY, - attempt.attemptId, - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - void this.options.storageService.flush().catch(() => undefined); - if (!this.options.isTelemetryEnabled()) { - return; - } - this.options.telemetry.capture("update_started", { - update_attempt_id: attempt.attemptId, - target_version: attempt.productVersion, - }); - } - - private async processOutcome(): Promise { - const raw = this.options.storageService.get( - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, - StorageScope.APPLICATION, - ); - const outcome = parseDarwinUpdateOutcomeRecord(raw); - if (!outcome) { - return; - } - - // Consume first for both consent states, so a crash or later opt-in cannot - // turn this into a duplicate or retroactive event. - this.options.storageService.remove( - DARWIN_UPDATE_OUTCOME_STORAGE_KEY, - StorageScope.APPLICATION, - ); - void this.options.storageService.flush().catch(() => undefined); - - const { attempt } = outcome; - if ( - !attempt.attemptId || - !attempt.productVersion || - !this.options.isTelemetryEnabled() - ) { - return; - } - const properties = lifecycleProperties(attempt, outcome.resolvedAt); - if (outcome.kind === "applied") { - this.options.telemetry.capture("update_completed", properties); - return; - } - - const failure = await this.readInstallFailure(attempt.shipItLogOffset); - this.captureFailure("install", failure.source, failure.message, properties); - } - - private async readInstallFailure( - offset: number | undefined, - ): Promise<{ message: string; source: WhiteboardUpdateMessageSource }> { - const path = this.options.shipItLogPath; - if (!path) { - return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; - } - try { - return await ( - this.options.readInstallFailure ?? readDarwinShipItFailure - )(path, offset); - } catch { - return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; - } - } - - private captureFailure( - phase: WhiteboardUpdateFailurePhase, - source: WhiteboardUpdateMessageSource, - message: string, - properties: Readonly> = {}, - ): void { - this.options.telemetry.capture( - "update_failed", - { ...properties, phase, message_source: source }, - { - name: `Update${phase[0].toUpperCase()}${phase.slice(1)}Error`, - message, - stack: "Update lifecycle telemetry", - }, - ); - } -} - -export function darwinShipItLogPath( - userHomePath: string, - bundleIdentifier: string, -): string { - return join( - userHomePath, - "Library", - "Caches", - `${bundleIdentifier}.ShipIt`, - "ShipIt_stderr.log", - ); -} - -export function extractDarwinShipItFailureMessage( - appendedLog: string, -): string | undefined { - const lines = appendedLog.split(/\r?\n/); - for (let index = lines.length - 1; index >= 0; index--) { - const line = lines[index]; - const marker = line.lastIndexOf("Installation error:"); - if (marker < 0) continue; - const error = line.slice(marker + "Installation error:".length).trim(); - const summary = error.match( - /Error Domain=([A-Za-z0-9._-]{1,80}) Code=(-?\d{1,10}) "([^"\r\n]{1,2000})"/, - ); - if (summary) { - return `Error Domain=${summary[1]} Code=${summary[2]} "${summary[3]}"`; - } - } - for (let index = lines.length - 1; index >= 0; index--) { - if (lines[index].includes("Too many attempts to install, aborting update")) { - return "Too many attempts to install, aborting update"; - } - } - return undefined; -} - -export async function readDarwinShipItFailure( - path: string, - offset: number | undefined, -): Promise<{ message: string; source: WhiteboardUpdateMessageSource }> { - if (offset === undefined) { - return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; - } - const file = await open(path, "r"); - try { - const size = (await file.stat()).size; - if (size < offset) { - return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; - } - const start = Math.max(offset, size - MAX_SHIPIT_LOG_BYTES); - const length = size - start; - if (length <= 0) { - return { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; - } - const buffer = Buffer.alloc(length); - const { bytesRead } = await file.read(buffer, 0, length, start); - const message = extractDarwinShipItFailureMessage( - buffer.subarray(0, bytesRead).toString("utf8"), - ); - return message - ? { message, source: "shipit" } - : { message: INSTALL_FALLBACK_MESSAGE, source: "fallback" }; - } finally { - await file.close(); - } -} - -function updateFailurePhase( - previous: State, -): Exclude | undefined { - if (previous.type === StateType.CheckingForUpdates) { - return "check"; - } - if ( - previous.type === StateType.Downloading || - previous.type === StateType.Overwriting - ) { - return "download"; - } - return undefined; -} - -function lifecycleProperties( - attempt: IDarwinUpdateAttempt, - resolvedAt: number, -): Record { - return { - update_attempt_id: attempt.attemptId!, - target_version: attempt.productVersion!, - duration_ms: Math.max(0, resolvedAt - attempt.attemptedAt), - }; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-utility/whiteboardDesktopHostMain.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-utility/whiteboardDesktopHostMain.ts deleted file mode 100644 index 602ea9281..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/electron-utility/whiteboardDesktopHostMain.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { pathToFileURL } from "node:url"; - -const serverEntry = process.env["DEV_FAST_WHITEBOARD_SERVER_ENTRY"]; -if (!serverEntry) { - throw new Error("DEV_FAST_WHITEBOARD_SERVER_ENTRY is required."); -} - -await import(pathToFileURL(serverEntry).href); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardBootstrapBreadcrumb.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardBootstrapBreadcrumb.ts deleted file mode 100644 index 7033e1737..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardBootstrapBreadcrumb.ts +++ /dev/null @@ -1,102 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { appendFileSync, mkdirSync, readFileSync, rmSync, statSync } from 'node:fs'; -import * as path from 'node:path'; - -/** - * Records a crash that happens before Review can start. - * - * `src/main.ts` runs before the message table, the service collection, and the - * embedded server exist. A failure there leaves no log and no window: Review - * Desktop 0.0.4 shipped exactly that and could not launch. So this module does - * the least it can — one line of JSON in a file — and the next launch reports - * it through the normal, opted-in path. - * - * Constraints that keep it safe to import from `src/main.ts`: - * - Node built-ins only. No `localize`, no registry, no other module. The - * bootstrap import test walks this file and fails on any of those. - * - Synchronous, because the process is about to die. - * - Never throws. A failure to record a crash must not become the crash. - * - * Writing a local file is not telemetry, so no consent check applies here. The - * consent check happens when the next launch tries to send the line. - */ - -const BREADCRUMB_FILE = 'review-bootstrap-errors.jsonl'; -const MAX_FILE_BYTES = 64 * 1024; -const MAX_STACK_LENGTH = 8 * 1024; - -export interface WhiteboardBootstrapBreadcrumb { - readonly t: number; - readonly name: string; - readonly message: string; - readonly stack: string; -} - -export function whiteboardBootstrapBreadcrumbPath(userDataPath: string): string { - return path.join(userDataPath, BREADCRUMB_FILE); -} - -/** Append one crash note. Silent on every failure. */ -export function writeWhiteboardBootstrapBreadcrumb(userDataPath: string, error: unknown, now: number = Date.now()): void { - try { - const file = whiteboardBootstrapBreadcrumbPath(userDataPath); - let size = 0; - try { - size = statSync(file).size; - } catch { - size = 0; // no file yet - } - if (size >= MAX_FILE_BYTES) { - return; // a crash loop must not fill the disk - } - const candidate = error as { name?: unknown; message?: unknown; stack?: unknown } | undefined; - const breadcrumb: WhiteboardBootstrapBreadcrumb = { - t: now, - name: typeof candidate?.name === 'string' ? candidate.name : 'Error', - message: typeof candidate?.message === 'string' ? candidate.message : String(error), - stack: typeof candidate?.stack === 'string' ? candidate.stack.slice(0, MAX_STACK_LENGTH) : '', - }; - mkdirSync(userDataPath, { recursive: true }); - appendFileSync(file, `${JSON.stringify(breadcrumb)}\n`, 'utf8'); - } catch { - // Recording a crash must never raise one. - } -} - -/** - * Read every recorded crash and delete the file. The file goes whether or not - * the caller reports the entries, so an opted-out user never accumulates one. - */ -export function drainWhiteboardBootstrapBreadcrumbs(userDataPath: string): WhiteboardBootstrapBreadcrumb[] { - const file = whiteboardBootstrapBreadcrumbPath(userDataPath); - let contents: string; - try { - contents = readFileSync(file, 'utf8'); - } catch { - return []; - } - try { - rmSync(file, { force: true }); - } catch { - // A file we cannot delete is capped by MAX_FILE_BYTES anyway. - } - const breadcrumbs: WhiteboardBootstrapBreadcrumb[] = []; - for (const line of contents.split('\n')) { - if (!line) { - continue; - } - try { - const parsed = JSON.parse(line) as WhiteboardBootstrapBreadcrumb; - if (parsed && typeof parsed.stack === 'string') { - breadcrumbs.push(parsed); - } - } catch { - // One unreadable line must not lose the others. - } - } - return breadcrumbs; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionCatalog.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionCatalog.ts deleted file mode 100644 index 3f9071399..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionCatalog.ts +++ /dev/null @@ -1,101 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -// This module is imported by src/main.ts before bootstrapESM() installs the NLS -// table. Keep it free of workbench registries, configuration, and localization. - -export const whiteboardOptionalExtensionCatalog = [ - { - id: 'rust-lang.rust-analyzer', - role: 'primary', - group: 'rust', - version: '0.4.2990', - targets: { - 'darwin-arm64': { - url: 'https://open-vsx.org/api/rust-lang/rust-analyzer/darwin-arm64/0.4.2990/file/rust-lang.rust-analyzer-0.4.2990@darwin-arm64.vsix', - sha256: 'e068ebb88f705491856b91cdbf8b7ead40c22d50f2c24df70e345c889c2b0111', - size: 15445156 - }, - 'linux-x64': { - url: 'https://open-vsx.org/api/rust-lang/rust-analyzer/linux-x64/0.4.2990/file/rust-lang.rust-analyzer-0.4.2990@linux-x64.vsix', - sha256: '317cb128e8caf2495b955ef6612d828fef809187ac445242116ad8e2e32382ff', - size: 16313907 - } - } - }, - { - id: 'swiftlang.swift-vscode', - role: 'primary', - group: 'swift', - version: '2.17.20260702', - targets: { - universal: { - url: 'https://open-vsx.org/api/swiftlang/swift-vscode/2.17.20260702/file/swiftlang.swift-vscode-2.17.20260702.vsix', - sha256: '64fcca2666e033c3934ceeb98b13ff73e30071d32e0795bec891652814ef947b', - size: 14779649 - } - } - }, - { - id: 'llvm-vs-code-extensions.lldb-dap', - role: 'support', - group: 'swift', - version: '0.7.20260804', - targets: { - universal: { - url: 'https://open-vsx.org/api/llvm-vs-code-extensions/lldb-dap/0.7.20260804/file/llvm-vs-code-extensions.lldb-dap-0.7.20260804.vsix', - sha256: '69dad4f902a1a9d96403205e209a9aef760189c93d687e02f568a753148c537f', - size: 819802 - } - } - }, - { - id: 'muhammad-sammy.csharp', - role: 'primary', - group: 'csharp', - version: '2.145.21-g154a82fd27', - targets: { - 'darwin-arm64': { - url: 'https://open-vsx.org/api/muhammad-sammy/csharp/darwin-arm64/2.145.21-g154a82fd27/file/muhammad-sammy.csharp-2.145.21-g154a82fd27@darwin-arm64.vsix', - sha256: '93f61e8b6938cbe8ecda8768bfaf08abed9789db9461177d3d0ab59ccda2528d', - size: 75096042 - }, - 'linux-x64': { - url: 'https://open-vsx.org/api/muhammad-sammy/csharp/linux-x64/2.145.21-g154a82fd27/file/muhammad-sammy.csharp-2.145.21-g154a82fd27@linux-x64.vsix', - sha256: '78bc006683cc998e9fd1a6f2760d8cb3da63096464a217bbd192ecfb490a5516', - size: 78144854 - } - } - }, - { - id: 'golang.go', - role: 'primary', - group: 'go', - version: '0.56.0', - targets: { - universal: { - url: 'https://open-vsx.org/api/golang/Go/0.56.0/file/golang.Go-0.56.0.vsix', - sha256: '9f5959fb17ba0a8dbd804387ddda50975fcaa9dd5267aa33eaaa89912072aacb', - size: 621478 - } - } - }, - { - id: 'ms-dotnettools.vscode-dotnet-runtime', - role: 'support', - group: 'csharp', - version: '3.1.0', - targets: { - universal: { - url: 'https://open-vsx.org/api/ms-dotnettools/vscode-dotnet-runtime/3.1.0/file/ms-dotnettools.vscode-dotnet-runtime-3.1.0.vsix', - sha256: '10fd1e1693a81e2c68f0382ae3cfcf0784c5f3e0da002dd4bfd322575b46941e', - size: 1458566 - } - } - } -] as const; - -export type WhiteboardOptionalExtension = (typeof whiteboardOptionalExtensionCatalog)[number]; -export type WhiteboardOptionalExtensionTarget = keyof WhiteboardOptionalExtension['targets']; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionInstaller.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionInstaller.ts deleted file mode 100644 index 9df77c849..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardOptionalExtensionInstaller.ts +++ /dev/null @@ -1,254 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -// src/main.ts imports this module before bootstrapESM() installs the NLS table. -// Keep it limited to Node modules and the import-free catalog. -import { createHash, randomUUID } from 'node:crypto'; -import { createReadStream, createWriteStream } from 'node:fs'; -import { mkdir, rename, rm, stat } from 'node:fs/promises'; -import path from 'node:path'; -import { Readable, Transform } from 'node:stream'; -import { pipeline } from 'node:stream/promises'; -import { whiteboardOptionalExtensionCatalog } from './whiteboardOptionalExtensionCatalog.js'; - -const DOWNLOAD_CHANNEL = 'vscode:whiteboardDownloadOptionalExtension'; -const MAX_REDIRECTS = 10; - -type WhiteboardNetResponse = Readable & { - readonly statusCode: number; - readonly statusMessage?: string; - readonly headers: Readonly>; -}; - -export interface WhiteboardNetRequest { - on(event: 'redirect', listener: ( - statusCode: number, - method: string, - redirectUrl: string, - responseHeaders: Readonly> - ) => void): this; - once(event: 'response', listener: (response: WhiteboardNetResponse) => void): this; - once(event: 'error', listener: (error: Error) => void): this; - followRedirect(): void; - abort(): void; - end(): void; -} - -export type WhiteboardNetRequestFactory = (options: { - readonly method: 'GET'; - readonly url: string; - readonly redirect: 'manual'; -}) => unknown; - -export interface WhiteboardValidatedIpcMain { - handle(channel: string, listener: (event: unknown, extensionId: unknown) => Promise): unknown; -} - -export interface WhiteboardOptionalExtensionInstallerOptions { - readonly userDataPath: string; - readonly platform: NodeJS.Platform | string; - readonly arch: string; - readonly request: WhiteboardNetRequestFactory; - readonly catalog?: readonly WhiteboardOptionalExtensionCatalogEntry[]; -} - -export interface WhiteboardOptionalExtensionTargetPin { - readonly url: string; - readonly sha256: string; - readonly size: number; -} - -export interface WhiteboardOptionalExtensionCatalogEntry { - readonly id: string; - readonly role: 'primary' | 'support'; - readonly group: string; - readonly version: string; - readonly targets: Readonly>; -} - -function supportedTarget(platform: string, arch: string): 'darwin-arm64' | 'linux-x64' | undefined { - if (platform === 'darwin' && arch === 'arm64') { - return 'darwin-arm64'; - } - if (platform === 'linux' && arch === 'x64') { - return 'linux-x64'; - } - return undefined; -} - -async function sha256File(file: string): Promise { - const hash = createHash('sha256'); - for await (const chunk of createReadStream(file)) { - hash.update(chunk); - } - return hash.digest('hex'); -} - -async function isFile(file: string): Promise { - try { - return (await stat(file)).isFile(); - } catch { - return false; - } -} - -export class WhiteboardOptionalExtensionInstaller { - private readonly cacheDirectory: string; - private readonly inflight = new Map>(); - private readonly catalog: readonly WhiteboardOptionalExtensionCatalogEntry[]; - - constructor(private readonly options: WhiteboardOptionalExtensionInstallerOptions) { - this.cacheDirectory = path.resolve(options.userDataPath, 'optional-extensions', 'cache'); - this.catalog = options.catalog ?? whiteboardOptionalExtensionCatalog; - } - - async download(extensionId: string): Promise { - const extension = this.catalog.find(candidate => candidate.id === extensionId); - if (!extension) { - throw new Error(`Unknown optional extension: ${extensionId}`); - } - - const target = supportedTarget(this.options.platform, this.options.arch); - if (!target) { - throw new Error(`Optional extensions do not support ${this.options.platform}/${this.options.arch}`); - } - const targetPin = extension.targets['universal'] ?? extension.targets[target]; - if (!targetPin) { - throw new Error(`${extension.id} has no optional extension pin for ${target}`); - } - - const targetKey = extension.targets['universal'] ? 'universal' : target; - const inflightKey = `${extension.id}@${extension.version}:${targetKey}`; - const existing = this.inflight.get(inflightKey); - if (existing) { - return existing; - } - - const pending = this.ensureVerifiedVsix(extension.id, extension.version, targetKey, targetPin); - this.inflight.set(inflightKey, pending); - try { - return await pending; - } finally { - if (this.inflight.get(inflightKey) === pending) { - this.inflight.delete(inflightKey); - } - } - } - - private async ensureVerifiedVsix( - extensionId: string, - version: string, - target: string, - pin: { readonly url: string; readonly sha256: string; readonly size: number } - ): Promise { - await mkdir(this.cacheDirectory, { recursive: true }); - const suffix = target === 'universal' ? '' : `@${target}`; - const cached = path.resolve(this.cacheDirectory, `${extensionId}-${version}${suffix}.vsix`); - - if (await isFile(cached)) { - if (await sha256File(cached) === pin.sha256) { - return cached; - } - await rm(cached, { force: true }); - } - - const partial = `${cached}.${process.pid}.${randomUUID()}.part`; - try { - const actualHash = await this.downloadToPartial(pin.url, partial); - if (actualHash !== pin.sha256) { - throw new Error( - `${extensionId} checksum mismatch: expected ${pin.sha256}, received ${actualHash}` - ); - } - await rename(partial, cached); - return cached; - } catch (error) { - await rm(partial, { force: true }); - throw error; - } - } - - private async downloadToPartial(initialUrl: string, partial: string): Promise { - const response = await this.request(initialUrl); - if (response.statusCode !== 200) { - response.resume(); - throw new Error(`GET ${initialUrl} failed with ${response.statusCode} ${response.statusMessage ?? ''}`.trim()); - } - - const hash = createHash('sha256'); - const hashingStream = new Transform({ - transform(chunk, _encoding, callback) { - hash.update(chunk); - callback(null, chunk); - } - }); - await pipeline(response, hashingStream, createWriteStream(partial, { flags: 'wx' })); - return hash.digest('hex'); - } - - private request(initialUrl: string): Promise { - return new Promise((resolve, reject) => { - const request = this.options.request({ method: 'GET', url: initialUrl, redirect: 'manual' }) as WhiteboardNetRequest; - let redirects = 0; - let settled = false; - const fail = (error: Error) => { - if (settled) { - return; - } - settled = true; - reject(error); - request.abort(); - }; - request.on('redirect', (_statusCode, method, redirectUrl) => { - redirects++; - if (redirects > MAX_REDIRECTS) { - fail(new Error(`GET ${initialUrl} exceeded ${MAX_REDIRECTS} redirects`)); - return; - } - const redirected = new URL(redirectUrl); - if (method !== 'GET') { - fail(new Error(`Refused optional extension redirect with method ${method}`)); - return; - } - if (redirected.protocol !== 'https:') { - fail(new Error(`Refused optional extension redirect to ${redirected.protocol}`)); - return; - } - // Electron cancels a manual redirect unless this call happens inside - // the redirect event. Validate first, then follow it synchronously. - request.followRedirect(); - }); - request.once('response', response => { - if (!settled) { - settled = true; - resolve(response); - } else { - response.resume(); - } - }); - request.once('error', error => { - if (!settled) { - settled = true; - reject(error); - } - }); - request.end(); - }); - } -} - -export function registerWhiteboardOptionalExtensionInstaller( - ipcMain: WhiteboardValidatedIpcMain, - options: WhiteboardOptionalExtensionInstallerOptions -): WhiteboardOptionalExtensionInstaller { - const installer = new WhiteboardOptionalExtensionInstaller(options); - ipcMain.handle(DOWNLOAD_CHANNEL, async (_event, extensionId) => { - if (typeof extensionId !== 'string' || extensionId.length === 0) { - throw new Error('Optional extension downloads require one extension ID'); - } - return installer.download(extensionId); - }); - return installer; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigImport.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigImport.test.ts deleted file mode 100644 index 0a304d032..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigImport.test.ts +++ /dev/null @@ -1,265 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from 'assert'; -import { mkdirSync, mkdtempSync, readFileSync, rmSync, utimesSync, writeFileSync } from 'node:fs'; -import * as os from 'node:os'; -import * as path from 'node:path'; -import { afterEach, describe, test } from 'node:test'; -import { - curatedExtensionConfigurationDefaults, - whiteboardConfigurationDefaults, -} from '../common/whiteboardConfigurationDefaults.js'; -import { importWhiteboardUserConfig } from './whiteboardUserConfigImport.js'; - -describe('WhiteboardUserConfigImport', () => { - const fixtures: string[] = []; - - afterEach(() => { - for (const fixture of fixtures.splice(0)) { - rmSync(fixture, { recursive: true, force: true }); - } - }); - - function createFixture(): { root: string; sourceRoot: string; sourceUser: string; target: string } { - const root = mkdtempSync(path.join(os.tmpdir(), 'review-user-config-')); - fixtures.push(root); - const sourceRoot = path.join(root, 'source'); - const sourceUser = path.join(sourceRoot, 'User'); - const target = path.join(root, 'target'); - mkdirSync(sourceUser, { recursive: true }); - return { root, sourceRoot, sourceUser, target }; - } - - test('imports JSONC keybindings verbatim and filters hardened settings', () => { - const fixture = createFixture(); - const keybindings = '[\n\t// Keep this chord and its comment.\n\t{ "key": "ctrl+k ctrl+r", "command": "review.refresh" },\n]\n'; - writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), keybindings); - writeFileSync(path.join(fixture.sourceUser, 'settings.json'), `{ - // User-facing editor and keymap settings survive. - "editor.fontSize": 15, - "vim.useSystemClipboard": true, - "telemetry.telemetryLevel": "all", - "extensions.autoUpdate": true, - "workbench.statusBar.visible": true, - // Would re-arm the install prompt for an extension Review cannot ship. - "python.languageServer": "Pylance", - }`); - - const extensionsDir = path.join(fixture.sourceRoot, 'extensions'); - mkdirSync(path.join(extensionsDir, 'vscodevim.vim-1.32.4'), { recursive: true }); - writeFileSync(path.join(extensionsDir, 'extensions.json'), JSON.stringify([ - { identifier: { id: 'vscodevim.vim' } }, - ])); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - now: () => new Date('2026-07-29T12:00:00.000Z'), - }); - - assert.strictEqual(result.status, 'imported'); - assert.strictEqual(result.keymap, 'vim'); - assert.strictEqual( - readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), - keybindings, - ); - const settings = JSON.parse(readFileSync(path.join(fixture.target, 'User', 'settings.json'), 'utf8')); - assert.deepStrictEqual(settings, { - 'editor.fontSize': 15, - 'vim.useSystemClipboard': true, - 'whiteboard.keymap': 'vim', - }); - assert.deepStrictEqual( - JSON.parse(readFileSync(path.join(fixture.target, 'User', '.review-import.json'), 'utf8')), - { - version: 1, - source: fixture.sourceUser, - importedAt: '2026-07-29T12:00:00.000Z', - keymap: 'vim', - }, - ); - }); - - test('does not import twice after writing the stamp', () => { - const fixture = createFixture(); - writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[]\n'); - const options = { - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - }; - assert.strictEqual(importWhiteboardUserConfig(options).status, 'imported'); - writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[{ "key": "x", "command": "x" }]\n'); - - const second = importWhiteboardUserConfig(options); - assert.strictEqual(second.status, 'skipped'); - assert.strictEqual(second.reason, 'stamp-exists'); - assert.strictEqual(readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), '[]\n'); - }); - - test('never clobbers a pre-existing keybindings file on startup', () => { - const fixture = createFixture(); - writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[{ "key": "source" }]\n'); - mkdirSync(path.join(fixture.target, 'User'), { recursive: true }); - writeFileSync(path.join(fixture.target, 'User', 'keybindings.json'), '[{ "key": "mine" }]\n'); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - }); - - assert.strictEqual(result.status, 'skipped'); - assert.strictEqual(result.reason, 'keybindings-exists'); - assert.strictEqual( - readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), - '[{ "key": "mine" }]\n', - ); - }); - - test('never clobbers a pre-existing settings file on startup', () => { - const fixture = createFixture(); - writeFileSync(path.join(fixture.sourceUser, 'settings.json'), '{ "editor.fontSize": 22 }\n'); - mkdirSync(path.join(fixture.target, 'User'), { recursive: true }); - const targetSettings = path.join(fixture.target, 'User', 'settings.json'); - writeFileSync(targetSettings, '{ "editor.fontSize": 11, "workbench.colorTheme": "MyTheme" }\n'); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - }); - - assert.strictEqual(result.status, 'skipped'); - assert.strictEqual(result.reason, 'settings-exists'); - assert.strictEqual( - readFileSync(targetSettings, 'utf8'), - '{ "editor.fontSize": 11, "workbench.colorTheme": "MyTheme" }\n', - ); - }); - - test('maps a Code Insiders override to its exact extensions directory', () => { - const fixture = createFixture(); - const insidersUser = path.join(fixture.root, 'Code - Insiders', 'User'); - mkdirSync(insidersUser, { recursive: true }); - writeFileSync(path.join(insidersUser, 'settings.json'), '{ "editor.fontSize": 15 }\n'); - mkdirSync(path.join(fixture.root, '.vscode-insiders', 'extensions', 'vscodevim.vim-1.32.4'), { recursive: true }); - mkdirSync(path.join(fixture.root, '.vscode', 'extensions', 'tuttieee.emacs-mcx-0.40.0'), { recursive: true }); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: insidersUser }, - homeDir: fixture.root, - }); - - assert.strictEqual(result.status, 'imported'); - assert.strictEqual(result.source, insidersUser); - assert.strictEqual(result.keymap, 'vim'); - }); - - test('previews manual overwrites without changing them', () => { - const fixture = createFixture(); - writeFileSync(path.join(fixture.sourceUser, 'keybindings.json'), '[]\n'); - mkdirSync(path.join(fixture.target, 'User'), { recursive: true }); - const targetKeybindings = path.join(fixture.target, 'User', 'keybindings.json'); - writeFileSync(targetKeybindings, '[{ "key": "mine" }]\n'); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - mode: 'preview', - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - }); - - assert.strictEqual(result.status, 'ready'); - assert.deepStrictEqual(result.wouldOverwrite, [targetKeybindings]); - assert.strictEqual(readFileSync(targetKeybindings, 'utf8'), '[{ "key": "mine" }]\n'); - - const applied = importWhiteboardUserConfig({ - userDataPath: fixture.target, - mode: 'apply', - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - }); - assert.strictEqual(applied.status, 'imported'); - assert.strictEqual(readFileSync(targetKeybindings, 'utf8'), '[]\n'); - }); - - test('chooses the most recently modified VS Code-family default profile', () => { - const fixture = createFixture(); - const configRoot = path.join(fixture.root, 'config'); - const codeUser = path.join(configRoot, 'Code', 'User'); - const cursorUser = path.join(configRoot, 'Cursor', 'User'); - mkdirSync(codeUser, { recursive: true }); - mkdirSync(cursorUser, { recursive: true }); - writeFileSync(path.join(codeUser, 'keybindings.json'), '[{ "key": "code" }]\n'); - writeFileSync(path.join(cursorUser, 'keybindings.json'), '[{ "key": "cursor" }]\n'); - utimesSync(path.join(codeUser, 'keybindings.json'), new Date(1_000), new Date(1_000)); - utimesSync(path.join(cursorUser, 'keybindings.json'), new Date(2_000), new Date(2_000)); - utimesSync(codeUser, new Date(1_000), new Date(1_000)); - utimesSync(cursorUser, new Date(2_000), new Date(2_000)); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - platform: 'linux', - env: { XDG_CONFIG_HOME: configRoot }, - homeDir: fixture.root, - }); - - assert.strictEqual(result.source, cursorUser); - assert.strictEqual( - readFileSync(path.join(fixture.target, 'User', 'keybindings.json'), 'utf8'), - '[{ "key": "cursor" }]\n', - ); - }); - - test('no Review hardening default survives an import', () => { - // An imported setting beats a default, so any key Review pins here that - // arrives from the user's old profile silently un-hardens the app. - const fixture = createFixture(); - const hardened = [ - ...Object.keys(whiteboardConfigurationDefaults), - ...Object.keys(curatedExtensionConfigurationDefaults), - ]; - assert.ok(hardened.length > 0); - const imported: Record = { 'editor.fontSize': 15 }; - for (const key of hardened) { - imported[key] = `imported:${key}`; - } - writeFileSync( - path.join(fixture.sourceUser, 'settings.json'), - JSON.stringify(imported, undefined, '\t'), - ); - - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: fixture.sourceRoot }, - homeDir: fixture.root, - }); - - assert.strictEqual(result.status, 'imported'); - const settings = JSON.parse( - readFileSync(path.join(fixture.target, 'User', 'settings.json'), 'utf8'), - ) as Record; - assert.deepStrictEqual( - hardened.filter(key => key in settings), - [], - ); - // The filter has to be the hardened key set, not a blanket refusal. - assert.strictEqual(settings['editor.fontSize'], 15); - }); - - test('honours the import opt-out', () => { - const fixture = createFixture(); - const result = importWhiteboardUserConfig({ - userDataPath: fixture.target, - env: { DEV_WHITEBOARD_IMPORT_FROM: 'none' }, - homeDir: fixture.root, - }); - assert.strictEqual(result.status, 'disabled'); - }); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigImport.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigImport.ts deleted file mode 100644 index 85fad094b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigImport.ts +++ /dev/null @@ -1,345 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, copyFileSync } from 'node:fs'; -import * as os from 'node:os'; -import * as path from 'node:path'; -import { parse, type ParseError } from '../../base/common/json.js'; -// Setting keys come from the import-free defaults module, never from -// `whiteboardConfiguration.js`: this runs in the main process before bootstrapESM(), -// so reaching the configuration registry behind it would throw -// `!!! NLS MISSING: !!!` in a packaged build. See whiteboardConfigurationDefaults.ts. -import { curatedExtensionConfigurationDefaults, whiteboardConfigurationDefaults, type WhiteboardKeymap } from '../common/whiteboardConfigurationDefaults.js'; - -export const WHITEBOARD_USER_CONFIG_IMPORT_VERSION = 1; - -export type { WhiteboardKeymap }; -export type WhiteboardUserConfigImportMode = 'startup' | 'preview' | 'apply'; - -export interface WhiteboardUserConfigImportOptions { - readonly userDataPath: string; - readonly mode?: WhiteboardUserConfigImportMode; - readonly homeDir?: string; - readonly platform?: NodeJS.Platform; - readonly env?: NodeJS.ProcessEnv; - readonly now?: () => Date; - readonly log?: (message: string) => void; -} - -export interface WhiteboardUserConfigImportResult { - readonly status: 'disabled' | 'not-found' | 'skipped' | 'ready' | 'imported'; - readonly source?: string; - readonly keymap: WhiteboardKeymap; - readonly files: readonly string[]; - readonly wouldOverwrite: readonly string[]; - readonly reason?: 'stamp-exists' | 'keybindings-exists' | 'settings-exists'; - readonly defaultProfileOnly?: boolean; -} - -interface SourceCandidate { - readonly userDir: string; - readonly extensionsDir?: string; - readonly modifiedAt: number; -} - -interface PreparedImport { - readonly source: SourceCandidate; - readonly keymap: WhiteboardKeymap; - readonly keybindings?: string; - readonly settings?: Record; - readonly defaultProfileOnly: boolean; -} - -const BLOCKED_SETTING_PREFIXES = [ - 'telemetry.', - 'update.', - 'extensions.', - 'chat.', - 'github.', - 'workbench.enableExperiments', - 'security.workspace.trust.', - 'remote.', -] as const; - -const BLOCKED_SETTING_KEYS = new Set([ - ...Object.keys(whiteboardConfigurationDefaults), - // An imported setting beats a default, so a VS Code user who runs Pylance - // would carry `python.languageServer: "Pylance"` in and re-arm the install - // prompt for an extension Review cannot ship. The same holds for every other - // prompt these defaults close. - ...Object.keys(curatedExtensionConfigurationDefaults), -]); - -const SOURCE_INSTALLS = [ - { name: 'Code', extensionsHome: '.vscode' }, - { name: 'Code - Insiders', extensionsHome: '.vscode-insiders' }, - { name: 'VSCodium', extensionsHome: '.vscode-oss' }, - { name: 'Cursor', extensionsHome: '.cursor' }, -] as const; - -const KEYMAP_EXTENSIONS: Readonly, string>> = { - vim: 'vscodevim.vim', - emacs: 'tuttieee.emacs-mcx', -}; - -function existingMtime(target: string): number { - try { - return statSync(target).mtimeMs; - } catch { - return 0; - } -} - -function sourceModifiedAt(userDir: string): number { - return Math.max( - existingMtime(userDir), - existingMtime(path.join(userDir, 'keybindings.json')), - existingMtime(path.join(userDir, 'settings.json')), - ); -} - -function isUsableSource(userDir: string): boolean { - return existsSync(path.join(userDir, 'keybindings.json')) || existsSync(path.join(userDir, 'settings.json')); -} - -function extensionDirectoryForOverride(userDir: string, homeDir: string): string | undefined { - const installName = path.basename(path.dirname(userDir)).toLowerCase(); - for (const install of SOURCE_INSTALLS) { - if (installName === install.name.toLowerCase()) { - return path.join(homeDir, install.extensionsHome, 'extensions'); - } - } - - const fixtureStyleExtensions = path.join(path.dirname(userDir), 'extensions'); - return existsSync(fixtureStyleExtensions) ? fixtureStyleExtensions : undefined; -} - -function discoverSource(options: WhiteboardUserConfigImportOptions): SourceCandidate | 'disabled' | undefined { - const env = options.env ?? process.env; - const homeDir = options.homeDir ?? os.homedir(); - const override = env['DEV_WHITEBOARD_IMPORT_FROM']; - - if (override?.toLowerCase() === 'none') { - return 'disabled'; - } - - if (override) { - const expanded = path.resolve(override); - const userDir = path.basename(expanded) === 'User' ? expanded : path.join(expanded, 'User'); - if (!isUsableSource(userDir)) { - return undefined; - } - return { - userDir, - extensionsDir: extensionDirectoryForOverride(userDir, homeDir), - modifiedAt: sourceModifiedAt(userDir), - }; - } - - const configRoot = options.platform === 'darwin' || (options.platform === undefined && process.platform === 'darwin') - ? path.join(homeDir, 'Library', 'Application Support') - : path.resolve(env['XDG_CONFIG_HOME'] ?? path.join(homeDir, '.config')); - - const candidates = SOURCE_INSTALLS - .map(install => { - const userDir = path.join(configRoot, install.name, 'User'); - return { - userDir, - extensionsDir: path.join(homeDir, install.extensionsHome, 'extensions'), - modifiedAt: sourceModifiedAt(userDir), - }; - }) - .filter(candidate => isUsableSource(candidate.userDir)) - .sort((left, right) => right.modifiedAt - left.modifiedAt); - - return candidates[0]; -} - -function extensionIdsFromMetadata(extensionsDir: string): Set | undefined { - const metadataPath = path.join(extensionsDir, 'extensions.json'); - if (!existsSync(metadataPath)) { - return undefined; - } - - const errors: ParseError[] = []; - const value = parse(readFileSync(metadataPath, 'utf8'), errors); - if (errors.length > 0 || !Array.isArray(value)) { - return new Set(); - } - - const ids = new Set(); - for (const entry of value) { - if (!entry || typeof entry !== 'object') { - continue; - } - const identifier = (entry as { identifier?: unknown }).identifier; - const id = identifier && typeof identifier === 'object' - ? (identifier as { id?: unknown }).id - : (entry as { id?: unknown }).id; - if (typeof id === 'string') { - ids.add(id.toLowerCase()); - } - } - return ids; -} - -function detectKeymap(extensionsDir: string | undefined): WhiteboardKeymap { - if (!extensionsDir || !existsSync(extensionsDir)) { - return 'none'; - } - - const metadataIds = extensionIdsFromMetadata(extensionsDir); - const candidates: { keymap: Exclude; modifiedAt: number }[] = []; - for (const entry of readdirSync(extensionsDir, { withFileTypes: true })) { - if (!entry.isDirectory()) { - continue; - } - const normalizedName = entry.name.toLowerCase(); - for (const [keymap, extensionId] of Object.entries(KEYMAP_EXTENSIONS) as [Exclude, string][]) { - if (!normalizedName.startsWith(`${extensionId}-`)) { - continue; - } - if (metadataIds && !metadataIds.has(extensionId)) { - continue; - } - candidates.push({ - keymap, - modifiedAt: existingMtime(path.join(extensionsDir, entry.name)), - }); - } - } - - candidates.sort((left, right) => right.modifiedAt - left.modifiedAt); - return candidates[0]?.keymap ?? 'none'; -} - -function shouldImportSetting(key: string): boolean { - if (BLOCKED_SETTING_KEYS.has(key)) { - return false; - } - return !BLOCKED_SETTING_PREFIXES.some(prefix => key.startsWith(prefix)); -} - -function filterWhiteboardUserSettings(settings: Record): Record { - return Object.fromEntries(Object.entries(settings).filter(([key]) => shouldImportSetting(key))); -} - -function readSettings(settingsPath: string): Record | undefined { - if (!existsSync(settingsPath)) { - return undefined; - } - - const errors: ParseError[] = []; - const value = parse(readFileSync(settingsPath, 'utf8'), errors); - if (errors.length > 0 || !value || typeof value !== 'object' || Array.isArray(value)) { - throw new Error(`Cannot import invalid VS Code settings from ${settingsPath}`); - } - return filterWhiteboardUserSettings(value as Record); -} - -function prepareImport(source: SourceCandidate, log: (message: string) => void): PreparedImport { - const profilesDir = path.join(source.userDir, 'profiles'); - const defaultProfileOnly = existsSync(profilesDir); - if (defaultProfileOnly) { - log(`Whiteboard user-config import found profiles under ${profilesDir}; importing the default profile only.`); - } - - const keymap = detectKeymap(source.extensionsDir); - const keybindingsPath = path.join(source.userDir, 'keybindings.json'); - const settings = readSettings(path.join(source.userDir, 'settings.json')); - if (settings && keymap !== 'none') { - settings['whiteboard.keymap'] = keymap; - } - - return { - source, - keymap, - keybindings: existsSync(keybindingsPath) ? keybindingsPath : undefined, - settings: settings ?? (keymap !== 'none' ? { 'whiteboard.keymap': keymap } : undefined), - defaultProfileOnly, - }; -} - -function targetFiles(prepared: PreparedImport, userDir: string): string[] { - const files: string[] = []; - if (prepared.keybindings) { - files.push(path.join(userDir, 'keybindings.json')); - } - if (prepared.settings) { - files.push(path.join(userDir, 'settings.json')); - } - files.push(path.join(userDir, '.review-import.json')); - return files; -} - -function writeImport(prepared: PreparedImport, userDir: string, now: () => Date): string[] { - mkdirSync(userDir, { recursive: true }); - const files = targetFiles(prepared, userDir); - if (prepared.keybindings) { - copyFileSync(prepared.keybindings, path.join(userDir, 'keybindings.json')); - } - if (prepared.settings) { - writeFileSync(path.join(userDir, 'settings.json'), `${JSON.stringify(prepared.settings, null, '\t')}\n`, 'utf8'); - } - writeFileSync(path.join(userDir, '.review-import.json'), `${JSON.stringify({ - version: WHITEBOARD_USER_CONFIG_IMPORT_VERSION, - source: prepared.source.userDir, - importedAt: now().toISOString(), - keymap: prepared.keymap, - }, null, '\t')}\n`, 'utf8'); - return files; -} - -export function importWhiteboardUserConfig(options: WhiteboardUserConfigImportOptions): WhiteboardUserConfigImportResult { - const mode = options.mode ?? 'startup'; - const targetUserDir = path.join(options.userDataPath, 'User'); - const stampPath = path.join(targetUserDir, '.review-import.json'); - const keybindingsPath = path.join(targetUserDir, 'keybindings.json'); - const settingsPath = path.join(targetUserDir, 'settings.json'); - const log = options.log ?? (() => undefined); - - if (mode === 'startup' && existsSync(stampPath)) { - return { status: 'skipped', keymap: 'none', files: [], wouldOverwrite: [], reason: 'stamp-exists' }; - } - if (mode === 'startup' && existsSync(keybindingsPath)) { - return { status: 'skipped', keymap: 'none', files: [], wouldOverwrite: [], reason: 'keybindings-exists' }; - } - if (mode === 'startup' && existsSync(settingsPath)) { - return { status: 'skipped', keymap: 'none', files: [], wouldOverwrite: [], reason: 'settings-exists' }; - } - - const source = discoverSource(options); - if (source === 'disabled') { - return { status: 'disabled', keymap: 'none', files: [], wouldOverwrite: [] }; - } - if (!source) { - return { status: 'not-found', keymap: 'none', files: [], wouldOverwrite: [] }; - } - - const prepared = prepareImport(source, log); - const files = targetFiles(prepared, targetUserDir); - const wouldOverwrite = files.filter(file => existsSync(file)); - if (mode === 'preview') { - return { - status: 'ready', - source: source.userDir, - keymap: prepared.keymap, - files, - wouldOverwrite, - defaultProfileOnly: prepared.defaultProfileOnly, - }; - } - - const written = writeImport(prepared, targetUserDir, options.now ?? (() => new Date())); - log(`Whiteboard imported VS Code settings and keybindings from ${source.userDir}.`); - return { - status: 'imported', - source: source.userDir, - keymap: prepared.keymap, - files: written, - wouldOverwrite, - defaultProfileOnly: prepared.defaultProfileOnly, - }; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigMigration.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigMigration.test.ts deleted file mode 100644 index fa83d3d91..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigMigration.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import assert from "node:assert/strict"; -import { - mkdtempSync, - mkdirSync, - writeFileSync, - readFileSync, - rmSync, -} from "node:fs"; -import { tmpdir } from "node:os"; -import * as path from "node:path"; -import { test } from "node:test"; - -import { parse } from "../../base/common/json.js"; -import { migrateWhiteboardUserConfig } from "./whiteboardUserConfigMigration.js"; - -test("upgrades default and named profiles without losing disabled flags, user bindings or comments", () => { - const root = mkdtempSync(path.join(tmpdir(), "whiteboard-settings-")); - try { - for (const profile of ["User", "User/profiles/custom"]) { - const dir = path.join(root, profile); - mkdirSync(dir, { recursive: true }); - writeFileSync( - path.join(dir, "settings.json"), - '{\n // keep my note\n "review.experimental.structuralDiff.enabled": false, "review.keymap": "vim", "whiteboard.keymap": "emacs", "workbench.colorTheme": "Review Dark", "editor.fontSize": 17\n}', - ); - writeFileSync( - path.join(dir, "keybindings.json"), - '[{"key":"ctrl+k","command":"review.openSettings"},{"key":"ctrl+x","command":"-review.openSharedReview"},{"key":"ctrl+j","command":"other.command"}]', - ); - } - migrateWhiteboardUserConfig(root); - const first = readFileSync(path.join(root, "User/settings.json"), "utf8"); - migrateWhiteboardUserConfig(root); - assert.equal( - readFileSync(path.join(root, "User/settings.json"), "utf8"), - first, - ); - for (const profile of ["User", "User/profiles/custom"]) { - const dir = path.join(root, profile); - const text = readFileSync(path.join(dir, "settings.json"), "utf8"); - assert.match(text, /keep my note/); - assert.deepEqual(parse(text), { - "whiteboard.experimental.structuralDiff.enabled": false, - "whiteboard.keymap": "emacs", - "workbench.colorTheme": "Whiteboard Dark", - "editor.fontSize": 17, - }); - assert.deepEqual( - parse(readFileSync(path.join(dir, "keybindings.json"), "utf8")).map( - (v: { command: string }) => v.command, - ), - [ - "whiteboard.openSettings", - "-whiteboard.openSharedSession", - "other.command", - ], - ); - } - } finally { - rmSync(root, { recursive: true, force: true }); - } -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigMigration.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigMigration.ts deleted file mode 100644 index 225741086..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/node/whiteboardUserConfigMigration.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { - existsSync, - readFileSync, - readdirSync, - writeFileSync, - renameSync, - statSync, -} from "node:fs"; -import * as path from "node:path"; - -import { - parse, - parseTree, - findNodeAtLocation, - createScanner, - SyntaxKind, - type ParseError, -} from "../../base/common/json.js"; -import { applyEdits, setProperty } from "../../base/common/jsonEdit.js"; - -// Historical names are accepted only while upgrading saved user configuration. -const renamed: Record = { - "review.toggleFileTree": "whiteboard.toggleFileTree", - "review.openSettings": "whiteboard.openSettings", - "review.openSharedReview": "whiteboard.openSharedSession", - "review.update.instructions": "whiteboard.update.instructions", - "review.update.restart": "whiteboard.update.restart", - "review.update.skip": "whiteboard.update.skip", - "review.checkForUpdates": "whiteboard.checkForUpdates", - "review.openWelcome": "whiteboard.openWelcome", - "review.openTutorial": "whiteboard.openTutorial", - "review.installCliInPath": "whiteboard.installCliInPath", - "review.uninstallApp": "whiteboard.uninstallApp", - "review.selectTheme": "whiteboard.selectTheme", - "review.about": "whiteboard.about", - "review.setKeymap": "whiteboard.setKeymap", - "review.manageExtensions": "whiteboard.manageExtensions", - "review.importUserConfig": "whiteboard.importUserConfig", - "review.action.find": "whiteboard.action.find", - "review.keymap": "whiteboard.keymap", - "review.telemetry.enabled": "whiteboard.telemetry.enabled", - "review.experimental.structuralDiff.enabled": - "whiteboard.experimental.structuralDiff.enabled", - "review.experimental.softwareMap.enabled": - "whiteboard.experimental.softwareMap.enabled", -}; -const formatting = { insertSpaces: false, tabSize: 4, eol: "\n" }; - -function migrateFile(filename: string, bindings: boolean): void { - if (!existsSync(filename)) return; - const original = readFileSync(filename, "utf8"); - const errors: ParseError[] = []; - const value = parse(original, errors); - if (errors.length || !value || typeof value !== "object") - throw new Error(`Cannot migrate invalid configuration: ${filename}`); - let text = original; - const edit = (location: (string | number)[], next: unknown) => { - text = applyEdits(text, setProperty(text, location, next, formatting)); - }; - if (bindings) { - if (!Array.isArray(value)) - throw new Error(`Expected keybinding list: ${filename}`); - value.forEach((binding, index) => { - if (typeof binding?.command !== "string") return; - const negative = binding.command.startsWith("-"); - const command = negative ? binding.command.slice(1) : binding.command; - if (renamed[command]) - edit([index, "command"], `${negative ? "-" : ""}${renamed[command]}`); - }); - } else { - if (Array.isArray(value)) - throw new Error(`Expected settings object: ${filename}`); - for (const [before, after] of Object.entries(renamed)) { - if (!Object.hasOwn(value, before)) continue; - const property = findNodeAtLocation(parseTree(text), [before])!.parent!; - const key = property.children![0]; - if (!Object.hasOwn(value, after)) { - text = - text.slice(0, key.offset) + - JSON.stringify(after) + - text.slice(key.offset + key.length); - } else { - // Delete only syntax tokens, retaining comments and whitespace around them. - const scanner = createScanner(text); - const removals: { offset: number; length: number }[] = []; - let previousComma: { offset: number; length: number } | undefined; - for ( - let token = scanner.scan(); - token !== SyntaxKind.EOF; - token = scanner.scan() - ) { - const offset = scanner.getTokenOffset(); - const length = scanner.getTokenLength(); - if (offset < property.offset) { - if (token === SyntaxKind.CommaToken) - previousComma = { offset, length }; - continue; - } - if (offset >= property.offset + property.length) { - if ( - token === SyntaxKind.Trivia || - token === SyntaxKind.LineBreakTrivia || - token === SyntaxKind.LineCommentTrivia || - token === SyntaxKind.BlockCommentTrivia - ) - continue; - if (token === SyntaxKind.CommaToken) - removals.push({ offset, length }); - else if (previousComma) removals.push(previousComma); - break; - } - if (token < SyntaxKind.LineCommentTrivia) - removals.push({ offset, length }); - } - for (const removal of removals.sort((a, b) => b.offset - a.offset)) - text = - text.slice(0, removal.offset) + - text.slice(removal.offset + removal.length); - } - } - for (const key of [ - "workbench.colorTheme", - "workbench.preferredDarkColorTheme", - "workbench.preferredLightColorTheme", - ]) { - if (value[key] === "Review Dark") edit([key], "Whiteboard Dark"); - if (value[key] === "Review Light") edit([key], "Whiteboard Light"); - } - } - if (text === original) return; - const temporary = `${filename}.whiteboard-${process.pid}.tmp`; - writeFileSync(temporary, text, { mode: statSync(filename).mode }); - renameSync(temporary, filename); -} - -/** Run before configuration/keybinding services load, including named profiles. */ -export function migrateWhiteboardUserConfig(userDataPath: string): void { - const user = path.join(userDataPath, "User"); - const profiles = path.join(user, "profiles"); - const directories = [user]; - if (existsSync(profiles)) - for (const entry of readdirSync(profiles, { withFileTypes: true })) { - if (entry.isDirectory()) - directories.push(path.join(profiles, entry.name)); - } - for (const directory of directories) { - migrateFile(path.join(directory, "settings.json"), false); - migrateFile(path.join(directory, "keybindings.json"), true); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiCatalogService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiCatalogService.ts deleted file mode 100644 index ad098f0c4..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiCatalogService.ts +++ /dev/null @@ -1,112 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; -import { WHITEBOARD_STRUCTURAL_DIFF_SETTING } from "../common/whiteboardConfigurationDefaults.js"; -import { Emitter, type Event } from "../../base/common/event.js"; -import { Disposable, toDisposable } from "../../base/common/lifecycle.js"; -import { generateUuid } from "../../base/common/uuid.js"; -import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; -import { ILogService } from "../../platform/log/common/log.js"; -import { SessionApiClient, type SessionSummary } from "../common/whiteboardProtocol.js"; -import { IWhiteboardDesktopConnectionService } from "./whiteboardDesktopConnectionService.js"; - -export const IWhiteboardApiCatalogService = createDecorator("whiteboardApiCatalogService"); -export interface IWhiteboardApiCatalogService { - readonly _serviceBrand: undefined; - readonly reviews: readonly SessionSummary[]; - /** True once the first list arrived; an empty list is then real, not a failed load. */ - readonly loaded: boolean; - readonly onDidChange: Event; - readonly onDidCloseWhiteboard: Event; - initialize(): Promise; - attention(sessionId: string, action: "view" | "dismiss" | "restore"): Promise; - deleteWhiteboard(sessionId: string): Promise; -} - -/** A live API list for Home and tab restoration; no legacy review sessions. */ -export class WhiteboardApiCatalogService extends Disposable implements IWhiteboardApiCatalogService { - declare readonly _serviceBrand: undefined; - private readonly changed = this._register(new Emitter()); - readonly onDidChange = this.changed.event; - private readonly closed = this._register(new Emitter()); - readonly onDidCloseWhiteboard = this.closed.event; - reviews: SessionSummary[] = []; - loaded = false; - private client?: SessionApiClient; - private started?: Promise; - private connectionAbort?: AbortController; - - constructor( - @IWhiteboardDesktopConnectionService private readonly session: IWhiteboardDesktopConnectionService, - @ILogService private readonly log: ILogService, - @IConfigurationService private readonly configuration: IConfigurationService, - ) { - super(); - this._register(configuration.onDidChangeConfiguration(event => { - if (!event.affectsConfiguration(WHITEBOARD_STRUCTURAL_DIFF_SETTING) || !this.started) return; - this.connectionAbort?.abort(); - this.started = undefined; - this.reviews = this.reviews.map(review => ({ ...review, diffStats: null })); - this.changed.fire(); - void this.initialize().catch(error => this.log.warn("[Whiteboard] Catalog mode change failed:", error)); - })); - } - - initialize(): Promise { - // A failed first list must not stick: Home and the next command retry it. - if (!this.started) { - const pending = this.connect().catch((error) => { - if (this.started === pending) this.started = undefined; - throw error; - }); - this.started = pending; - } - return this.started; - } - - private async connect(): Promise { - const abort = new AbortController(); - this.connectionAbort = abort; - const mode = this.configuration.getValue(WHITEBOARD_STRUCTURAL_DIFF_SETTING) === false ? "textual" : "structural"; - const client = new SessionApiClient({ ...await this.session.getConnection(), apiPath: "/sessions-api" }); - this._register(toDisposable(() => abort.abort())); - const accept = (reviews: SessionSummary[]) => { - if (abort.signal.aborted) return; - const previous = this.reviews; - this.reviews = reviews; - this.loaded = true; - this.changed.fire(); - for (const review of previous) { - const next = this.reviews.find((next) => next.sessionId === review.sessionId); - if (!next || (!review.dismissedAt && next.dismissedAt)) this.closed.fire(review.sessionId); - } - }; - // Surface a failed first list instead of reporting an empty catalog: - // tab restoration would otherwise drop every persisted API tab. - accept(await client.read(`?mode=${mode}`, abort.signal)); - this.client = client; - void client.follow(null, abort.signal, accept, (error) => - this.log.warn("[Whiteboard] API review list disconnected:", error), - mode, - ); - } - - async attention(sessionId: string, action: "view" | "dismiss" | "restore"): Promise { - await this.initialize(); - await this.client!.post("/commands", { - commandId: generateUuid(), - operation: { type: "attention", sessionId, action }, - }); - } - - async deleteWhiteboard(sessionId: string): Promise { - await this.initialize(); - await this.client!.post("/commands", { - commandId: generateUuid(), - operation: { type: "delete", sessionId }, - }); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiSourceService.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiSourceService.test.ts deleted file mode 100644 index ec31e6ddb..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiSourceService.test.ts +++ /dev/null @@ -1,242 +0,0 @@ -import { sourceLocation, sourceTreeUri, sourceTreeRoot } from "../common/whiteboardSourceView.js"; -import assert from "node:assert/strict"; -import test from "node:test"; - -import { URI } from "../../base/common/uri.js"; -import type { ITextModelContentProvider } from "../../editor/common/services/resolverService.js"; -import { apiSourceUri, WhiteboardApiSourceService } from "./whiteboardApiSourceService.js"; -import type { WhiteboardDiffViewSource } from "./whiteboardDiffViewService.js"; -import { resolveWhiteboardSourceView, whiteboardSourceAnchor, whiteboardSourceComparison } from "../common/whiteboardProtocol.js"; -import type { WhiteboardDiffLens } from "../common/whiteboardProtocol.js"; - -const view = (version: number) => resolveWhiteboardSourceView({ sessionId: "review-a", version, pins: {} }); - -function setup() { - let provider: ITextModelContentProvider; - let disposed = 0; - const models = new Map(); - const opened: Array<{ original: { resource: URI }; modified: { resource: URI } }> = []; - const editor = { resource: URI.parse("review-api-source://review-a/file") }; - const registered: string[] = []; - const service = new WhiteboardApiSourceService( - { - getConnection: async () => ({ serverUrl: "http://localhost:5570", token: "secret" }), - } as never, - { - registerTextModelContentProvider: (scheme: string, value: ITextModelContentProvider) => { - if (scheme === "review-api-source") provider = value; - return { dispose() { } }; - }, - createModelReference: async (uri: URI) => ({ - object: { textEditorModel: await provider.provideTextContent(uri) }, - dispose: () => disposed++, - }), - } as never, - { - getModel: (uri: URI) => models.get(uri.toString()), - createModel: (text: string, _: unknown, uri: URI) => { - const model = { uri, text, getLineCount: () => text.split("\n").length }; - models.set(uri.toString(), model); - return model; - }, - } as never, - { createByFilepathOrFirstLine: () => ({ languageId: "typescript" }) } as never, - { - openEditor: async (input: (typeof opened)[number]) => { - opened.push(input); - return { input: editor }; - }, - } as never, - { - registerWhiteboardEditor(sessionId: string) { - registered.push(sessionId); - }, - } as never, - {} as never, - ); - return { - service, - models, - opened, - registered, - disposed: () => disposed, - readModel: (uri: URI) => provider.provideTextContent(uri), - }; -} - -test("a document diff retains its pinned comparison even if the review advances before loading", async (t) => { - const { service, readModel } = setup(); - t.after(() => service.dispose()); - t.mock.method(globalThis, "fetch", async (value: string, init: RequestInit) => { - const url = new URL(value); - assert.equal(new Headers(init.headers).get("x-whiteboard-token"), "secret"); - assert.equal(url.searchParams.get("version"), "3"); - if (url.pathname.endsWith("/diff")) return Response.json([]); - assert.equal(url.searchParams.get("side"), "base"); - assert.equal(url.searchParams.get("file"), "src/[route].ts"); - return Response.json({ text: "old first line\nold second line" }); - }); - let version = 3; - let source!: WhiteboardDiffViewSource; - let lens!: WhiteboardDiffLens; - const canvas = service.canvas(() => view(version), {} as never, { - openComparison: () => undefined, - createDocument: (_: unknown, scope: WhiteboardDiffLens, input: WhiteboardDiffViewSource) => { lens = scope; source = input; return {}; }, - } as never); - canvas.inlineEditors.create({ path: "src/[route].ts", side: "base", ranges: [{ startLine: 2, endLine: 2 }] } as never); - version = 4; - const result = await source.load(undefined, lens); - assert.equal(result.entries.length, 1); - assert.equal(result.entries[0].file.status, "unchanged"); - const model = await readModel(result.entries[0].original!); - assert.equal(model!.getLineCount(), 2); - assert.equal(new URLSearchParams(model!.uri.query).get("version"), "3"); -}); - -test("diff entries keep rename paths and missing sides, even when the review advances during the read", async (t) => { - const { service } = setup(); - t.after(() => service.dispose()); - let version = 7; - let generation = "a".repeat(64); - t.mock.method(globalThis, "fetch", async (value: string) => { - const url = new URL(value); - assert.equal(url.searchParams.get("version"), "7"); - assert.equal(url.searchParams.get("commit"), "selected-commit"); - version = 8; - generation = "b".repeat(64); - return Response.json([ - { path: "new.ts", previousPath: "old.ts", status: "renamed", additions: 0, deletions: 0 }, - { path: "added.ts", status: "added", additions: 1, deletions: 0 }, - { path: "removed.ts", status: "deleted", additions: 0, deletions: 1 }, - ]); - }); - let source!: WhiteboardDiffViewSource; - const canvas = service.canvas( - () => resolveWhiteboardSourceView({ sessionId: "review-a", version, pins: { worktreeRevision: generation } }), - {} as never, - { - openComparison: () => undefined, - create: (_: unknown, input: WhiteboardDiffViewSource) => { - source = input; - return {}; - }, - } as never, - ); - canvas.diffView.create({} as never); - const result = await source.load({ commit: "selected-commit" }); - assert.equal(result.entries.find(entry => entry.file.path === "new.ts")!.original!.path, "/old.ts"); - assert.equal(result.entries.find(entry => entry.file.path === "new.ts")!.modified!.path, "/new.ts"); - assert.equal(result.entries.find(entry => entry.file.path === "added.ts")!.original, undefined); - assert.equal(result.entries.find(entry => entry.file.path === "removed.ts")!.modified, undefined); - for (const entry of result.entries) { - assert.equal(new URLSearchParams(entry.goToFileResource.query).get("version"), "7"); - assert.equal(new URLSearchParams(entry.goToFileResource.query).get("commit"), "selected-commit"); - assert.equal(entry.goToFileResource.scheme, "review-api-source"); - assert.equal(new URLSearchParams(entry.goToFileResource.query).get("generation"), "a".repeat(64)); - assert.equal(new URLSearchParams(entry.goToFileResource.query).has("live"), false); - } -}); - -test("unavailable pinned files report the API error instead of falling back to disk", async (t) => { - const { service, readModel } = setup(); - t.after(() => service.dispose()); - t.mock.method(globalThis, "fetch", async () => Response.json({ error: "File is unavailable at the pinned commit." }, { status: 404 })); - await assert.rejects(Promise.resolve(readModel(apiSourceUri({ view: view(0), side: "head", file: "missing.ts" }))), /unavailable at the pinned commit/); -}); - -test("tree entries retain version, side and selected commit when opening a child", async (t) => { - const { service } = setup(); - t.after(() => service.dispose()); - t.mock.method(globalThis, "fetch", async (value: string) => { - const url = new URL(value); - assert.equal(url.pathname, "/sessions-api/review-a/tree"); - assert.equal(url.searchParams.get("path"), "src"); - assert.equal(url.searchParams.get("version"), "3"); - assert.equal(url.searchParams.get("side"), "base"); - assert.equal(url.searchParams.get("commit"), "chosen-commit"); - return Response.json([ - { path: "src/[route].ts", kind: "file" }, - { path: "src/lib", kind: "directory" }, - ]); - }); - const root = apiSourceUri({ view: whiteboardSourceComparison(view(3), "chosen-commit"), side: "base", file: "src" }); - const [file, folder] = await service.children(root); - assert.equal(file!.resource.path, "/src/[route].ts"); - assert.equal(file!.resource.query, root.query); - assert.equal(file!.readonly, true); - assert.equal(folder!.isDirectory, true); -}); - -test("opening a native diff preserves renames and empty sides at the selected version", async (t) => { - const { service, opened, registered } = setup(); - t.after(() => service.dispose()); - t.mock.method(globalThis, "fetch", async (value: string) => { - assert.equal(new URL(value).searchParams.get("version"), "3"); - return Response.json([ - { path: "new.ts", previousPath: "old.ts", status: "renamed", additions: 0, deletions: 0 }, - { path: "added.ts", status: "added", additions: 1, deletions: 0 }, - { path: "removed.ts", status: "deleted", additions: 0, deletions: 1 }, - ]); - }); - for (const file of ["new.ts", "added.ts", "removed.ts"]) await service.openDiff(view(3), file); - assert.equal(opened[0]!.original.resource.path, "/old.ts"); - assert.equal(opened[0]!.modified.resource.path, "/new.ts"); - assert.equal(new URLSearchParams(opened[1]!.original.resource.query).get("empty"), "true"); - assert.equal(new URLSearchParams(opened[2]!.modified.resource.query).get("empty"), "true"); - assert.deepEqual(registered, ["review-a", "review-a", "review-a"]); - for (const entry of opened) - for (const side of [entry.original, entry.modified]) { - assert.equal(side.resource.scheme, "review-api-source"); - assert.equal(new URLSearchParams(side.resource.query).get("version"), "3"); - } - await assert.rejects(service.openDiff(view(3), "unchanged.ts"), /not changed/); - assert.equal(opened.length, 3); -}); - - -test("a refreshed current tree keeps its root when a file from the newer version opens", async t => { - const { service } = setup(); - t.after(() => service.dispose()); - let version = 3; - const root = sourceTreeUri({ sessionId: "review-a", kind: "current" }); - t.mock.method(globalThis, "fetch", async (value: string) => { - const url = new URL(value); - if (url.pathname.endsWith("/tree")) { - assert.equal(url.pathname, "/sessions-api/review-a/tree"); - assert.equal(url.searchParams.get("version"), String(version)); - return Response.json([{ path: "src", kind: "directory" }, { path: "file.ts", kind: "file" }]); - } - assert.equal(url.searchParams.has("version"), false); - return Response.json({ sessionId: "review-a", version, pins: { worktreeRevision: String(version).repeat(64) } }); - }); - const first = await service.children(root); - version = 4; - const refreshed = await service.children(root); - assert.equal(first[0]!.resource.toString(), refreshed[0]!.resource.toString()); - assert.notEqual(first[1]!.resource.toString(), refreshed[1]!.resource.toString()); - assert.equal(new URLSearchParams(refreshed[1]!.resource.query).get("version"), "4"); - assert.equal(sourceTreeRoot(refreshed[1]!.resource, root).toString(), root.toString()); - const fixed = sourceTreeUri({ sessionId: "review-a", kind: "version", version: 3 }); - assert.notEqual(sourceTreeRoot(refreshed[1]!.resource, fixed).toString(), fixed.toString()); -}); - -test("a source at its own pins keeps them through its URI and reads them back from the server", async t => { - const { service, readModel } = setup(); - t.after(() => service.dispose()); - const pins = { repositoryId: "repo-b", head: "b".repeat(40) }; - const anchored = whiteboardSourceAnchor(whiteboardSourceComparison(view(3), "c".repeat(40)), pins); - assert.equal(anchored.commit, undefined); - const uri = apiSourceUri({ view: anchored, side: "head", file: "src/a.ts" }); - assert.deepEqual(sourceLocation(uri), { view: { sessionId: "review-a", version: 3, generation: undefined, commit: undefined, pins }, side: "head", file: "src/a.ts" }); - const inherited = sourceLocation(apiSourceUri({ view: view(3), side: "head", file: "src/a.ts" })); - assert.equal(inherited.view.pins, undefined); - t.mock.method(globalThis, "fetch", async (value: string) => { - const url = new URL(value); - assert.equal(url.searchParams.get("repositoryId"), "repo-b"); - assert.equal(url.searchParams.get("head"), pins.head); - assert.equal(url.searchParams.has("base"), false); - return Response.json({ text: "at own pins" }); - }); - const model = await readModel(uri); - assert.equal((model as unknown as { text: string }).text, "at own pins"); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiSourceService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiSourceService.ts deleted file mode 100644 index 8fd9a52f8..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardApiSourceService.ts +++ /dev/null @@ -1,302 +0,0 @@ -import { orderWhiteboardDiffFiles } from "../common/whiteboardChangedFilesModel.js"; -import { lensFiles } from "../common/whiteboardLensFiles.js"; -import { StructuralDiffClient } from "./whiteboardStructuralDiffClient.js"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable, DisposableStore } from "../../base/common/lifecycle.js"; -import { URI } from "../../base/common/uri.js"; -import { ILanguageService } from "../../editor/common/languages/language.js"; -import type { ITextModel } from "../../editor/common/model.js"; -import { IModelService } from "../../editor/common/services/model.js"; -import { ITextModelService } from "../../editor/common/services/resolverService.js"; -import { IFileService, type IFileStat } from "../../platform/files/common/files.js"; -import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; -import { IEditorService } from "../../workbench/services/editor/common/editorService.js"; -import type { - WhiteboardInlineFindSpec, - WhiteboardDiffLens, - WhiteboardInlineEditorRange, - WhiteboardDiffFileWire, - WhiteboardInlineEditorFactory, - WhiteboardDiffViewFactory, - SessionSourceEntry, - WhiteboardApiSourceLocation, -} from "../common/whiteboardProtocol.js"; -import { resolveWhiteboardSourceView, whiteboardSourceAnchor, whiteboardSourceComparison, whiteboardSourceQuery, type WhiteboardSourceView } from "../common/whiteboardProtocol.js"; -import { WHITEBOARD_LANGUAGE_SOURCE_SCHEME } from "../common/whiteboardReadonlySource.js"; -import { apiSourceUri, sourceLocation, sourceTreeUri, sourceTreeSelection, WHITEBOARD_API_TREE_SCHEME, WHITEBOARD_API_SOURCE_SCHEME } from "../common/whiteboardSourceView.js"; -import { IWhiteboardCanvasEditorTabsService } from "./whiteboardCanvasEditorTabsService.js"; -import { IWhiteboardDesktopConnectionService, whiteboardResponseError } from "./whiteboardDesktopConnectionService.js"; -import type { WhiteboardDiffViewService, WhiteboardDiffViewSource } from "./whiteboardDiffViewService.js"; -import type { WhiteboardEmbeddedEditors } from "./whiteboardEmbeddedEditors.js"; - -export { apiSourceUri, WHITEBOARD_API_SOURCE_SCHEME } from "../common/whiteboardSourceView.js"; - -/** The query that distinguishes one comparison's diff models from another's. */ -function comparisonQuery(view: WhiteboardSourceView): string | undefined { - const params = new URLSearchParams(); - if (view.commit) params.set("commit", view.commit); - if (view.pins) { - params.set("repositoryId", view.pins.repositoryId); - params.set("head", view.pins.head); - if (view.pins.base) params.set("base", view.pins.base); - } - const query = params.toString(); - return query || undefined; -} - -export type ApiSourceTarget = WhiteboardApiSourceLocation; - -/** Recover the immutable source identity even when no legacy session is active. */ -export function apiSourceTarget(resource: URI): ApiSourceTarget | undefined { - if (resource.scheme !== WHITEBOARD_API_SOURCE_SCHEME) return undefined; - const query = new URLSearchParams(resource.query); - const version = Number(query.get("version")); - const side = query.get("side"); - if ( - !resource.authority || - !query.has("version") || - !Number.isInteger(version) || - version < 0 || - (side !== "base" && side !== "head") - ) - return undefined; - return { - view: { sessionId: resource.authority, version, commit: query.get("commit") ?? undefined, generation: query.get("generation") ?? undefined }, - side, - file: resource.path.slice(1), - }; -} - -export const IWhiteboardApiSourceService = createDecorator("whiteboardApiSourceService"); -export interface IWhiteboardApiSourceService { - readonly _serviceBrand: undefined; - open(target: ApiSourceTarget, range?: WhiteboardInlineEditorRange): Promise; - children(resource: URI): Promise; - openDiff(view: WhiteboardSourceView, path: string): Promise; - canvas( - view: () => WhiteboardSourceView, - inline: WhiteboardEmbeddedEditors, - diff: WhiteboardDiffViewService, - ): { - inlineEditors: WhiteboardInlineEditorFactory; - diffView: WhiteboardDiffViewFactory; - openStructuralComparison(): void; - }; -} - -/** Resolve native or retained resources once; all review surfaces share this path. */ -export class WhiteboardApiSourceService extends Disposable implements IWhiteboardApiSourceService { - declare readonly _serviceBrand: undefined; - - constructor( - @IWhiteboardDesktopConnectionService private readonly session: IWhiteboardDesktopConnectionService, - @ITextModelService models: ITextModelService, - @IModelService modelService: IModelService, - @ILanguageService languages: ILanguageService, - @IEditorService private readonly editors: IEditorService, - @IWhiteboardCanvasEditorTabsService private readonly tabs: IWhiteboardCanvasEditorTabsService, - @IFileService private readonly files: IFileService, - ) { - super(); - this._register( - models.registerTextModelContentProvider(WHITEBOARD_API_SOURCE_SCHEME, { - provideTextContent: async (resource) => { - const existing = modelService.getModel(resource); - if (existing) return existing; - const query = new URLSearchParams(resource.query); - const target = sourceLocation(resource); - const body = query.has("empty") - ? { text: "" } - : await this.read<{ text: string; localPath?: string }>(target.view.sessionId, "/file", { ...whiteboardSourceQuery(target.view), side: target.side, file: target.file }); - const model = ( - modelService.getModel(resource) ?? - modelService.createModel( - body.text, - languages.createByFilepathOrFirstLine(resource, body.text.split("\n", 1)[0]), - resource, - ) - ); - if (body.localPath) { - this.followDisk(model, URI.file(body.localPath), async () => (await this.read<{ text: string }>(target.view.sessionId, "/file", { ...whiteboardSourceQuery(target.view), side: target.side, file: target.file })).text); - } - return model; - }, - }), - ); - this._register(models.registerTextModelContentProvider(WHITEBOARD_LANGUAGE_SOURCE_SCHEME, { - provideTextContent: async resource => { - const existing = modelService.getModel(resource); - if (existing) return existing; - const local = URI.file(resource.path); - const read = async () => (await this.files.readFile(local)).value.toString(); - const model = modelService.createModel(await read(), languages.createByFilepathOrFirstLine(resource), resource); - this.followDisk(model, local, read); - return model; - }, - })); - } - - private followDisk(model: ITextModel, local: URI, read: () => Promise): void { - const owned = this._register(new DisposableStore()); - let revision = 0; - owned.add(this.files.watch(local)); - owned.add(this.files.onDidFilesChange(event => { - if (!event.affects(local)) return; - const request = ++revision; - void read().then(text => { - if (!model.isDisposed() && request === revision && model.getValue() !== text) model.setValue(text); - }).catch(() => { /* A missing file cannot supply fresh source. */ }); - })); - owned.add(model.onWillDispose(() => { this._store.delete(owned); owned.dispose(); })); - } - - private async read( - sessionId: string, - route: string, - query: Record, - ): Promise { - const { serverUrl, token } = await this.session.getConnection(); - const params = new URLSearchParams( - Object.entries(query) - .filter(([key, value]) => key !== "sessionId" && value !== undefined) - .map(([key, value]) => [key, String(value)]), - ); - const response = await fetch(`${serverUrl}/sessions-api/${encodeURIComponent(sessionId)}${route}?${params}`, { - headers: { "x-whiteboard-token": token }, - signal: AbortSignal.timeout(30_000), - }); - if (!response.ok) throw await whiteboardResponseError(response, `Could not read pinned source (${response.status}).`); - // SAFETY: the route selects the response type; only the session metadata envelope changes. - return await response.json() as T; - } - - private async sourceResource(target: ApiSourceTarget, empty = false): Promise { - return apiSourceUri(target, empty); - } - - async open(target: ApiSourceTarget, range?: WhiteboardInlineEditorRange): Promise { - const pane = await this.editors.openEditor({ - resource: await this.sourceResource(target), - options: { - pinned: true, - ...(range - ? { - selection: { - startLineNumber: range.startLine, - startColumn: 1, - endLineNumber: range.endLine, - endColumn: Number.MAX_SAFE_INTEGER, - }, - } - : {}), - }, - }); - if (pane?.input) this.tabs.registerWhiteboardEditor(target.view.sessionId, pane.input); - } - - async openDiff(view: WhiteboardSourceView, path: string): Promise { - const files = await this.read(view.sessionId, "/diff", whiteboardSourceQuery(view)); - const file = files.find((file) => file.path === path); - if (!file) throw new Error(`File is not changed in this review version: ${path}`); - const target = { view, file: path }; - const pane = await this.editors.openEditor({ - original: { - resource: await this.sourceResource({ ...target, file: file.previousPath ?? path, side: "base" }, file.status === "added"), - }, - modified: { resource: await this.sourceResource({ ...target, side: "head" }, file.status === "deleted") }, - options: { pinned: true }, - }); - if (pane?.input) this.tabs.registerWhiteboardEditor(view.sessionId, pane.input); - } - - async children(resource: URI): Promise { - const selection = resource.scheme === WHITEBOARD_API_TREE_SCHEME ? sourceTreeSelection(resource) : undefined; - let target: ApiSourceTarget; - if (selection) { - const snapshot = await this.read[0]>(selection.sessionId, "", { - full: "true", version: selection.kind === "version" ? selection.version : undefined, - }); - target = { view: resolveWhiteboardSourceView(snapshot), side: "head", file: resource.path.slice(1) }; - } else { - target = sourceLocation(resource); - } - - const entries = await this.read(target.view.sessionId, "/tree", { - ...whiteboardSourceQuery(target.view), side: target.side, path: target.file, - }); - return entries.map((entry) => ({ - resource: selection && entry.kind === "directory" ? sourceTreeUri(selection, entry.path) : apiSourceUri({ ...target, file: entry.path }), - name: entry.path.split("/").at(-1)!, - isFile: entry.kind === "file", - isDirectory: entry.kind === "directory", - isSymbolicLink: false, - readonly: true, - children: undefined, - })); - } - - canvas(view: () => WhiteboardSourceView, inline: WhiteboardEmbeddedEditors, diff: WhiteboardDiffViewService) { - const comparisonGeneration = diff.comparisonGeneration; - const lists = new Map>(); - const files = (current: WhiteboardSourceView) => { - const key = JSON.stringify(whiteboardSourceQuery(current)); - let list = lists.get(key); - if (!list) { - list = this.read(current.sessionId, "/diff", whiteboardSourceQuery(current)); - list.catch(() => lists.delete(key)); - lists.set(key, list); - } - return list; - }; - const openComparison = (current: WhiteboardSourceView) => diff.openComparison( - JSON.stringify(whiteboardSourceQuery(current)), new StructuralDiffClient(this.session, current), comparisonGeneration, - ); - const makeSource = (getView: () => WhiteboardSourceView): WhiteboardDiffViewSource => ({ - files: scope => files(whiteboardSourceComparison(getView(), scope?.commit)), - load: async (scope, lens) => { - if (lens && (scope || lens.sessionId !== getView().sessionId)) throw new Error("A lens must use its session comparison."); - // Capture the comparison once; live checkout bytes may change during the load. - const current = whiteboardSourceComparison(getView(), scope?.commit); - const comparisonFiles = await files(current); - const entries = lens ? lensFiles(comparisonFiles, lens).filter(file => lens.ranges.some(range => - range.file === (range.side === "base" ? file.previousPath ?? file.path : file.path))) : orderWhiteboardDiffFiles(comparisonFiles); - - return { - session: openComparison(current), - sourceUri: URI.from({ scheme: "review-api-diff", authority: current.sessionId, path: `/${current.version}/${current.generation ?? ""}`, query: comparisonQuery(current) }), - entries: await Promise.all(entries.map(async file => { - const original = file.status === "added" ? undefined : await this.sourceResource({ view: current, side: "base", file: file.previousPath ?? file.path }); - const modified = file.status === "deleted" ? undefined : await this.sourceResource({ view: current, side: "head", file: file.path }); - return { file, original, modified, goToFileResource: (modified ?? original)! }; - })), - }; - }, - }); - const diffSource = makeSource(view); - const documentScope = (spec: WhiteboardInlineFindSpec) => { - // A source with its own pins is read at them; the review comparison does not apply. - const current = spec.pins ? whiteboardSourceAnchor(view(), spec.pins) : whiteboardSourceComparison(view()); - const lens: WhiteboardDiffLens = { - id: "document:" + JSON.stringify([spec.path, spec.ranges, spec.pins]), title: spec.path, - sessionId: current.sessionId, version: current.version, - ranges: spec.ranges.map(range => ({ file: spec.path, side: range.side ?? spec.side, fromLine: range.startLine, toLine: range.endLine })), - }; - return { lens, source: makeSource(() => current) }; - }; - return { - openStructuralComparison: () => diff.structuralRenderingEnabled ? openComparison(whiteboardSourceComparison(view())) : undefined, - inlineEditors: { - create: (spec) => { const { lens, source } = documentScope(spec); return diff.createDocument(spec, lens, source); }, - find: async (spec, query) => { const { lens, source } = documentScope(spec); return { matchCount: (await diff.findDocument(lens, source, query)).length }; }, - } satisfies WhiteboardInlineEditorFactory, - diffView: { - create: (spec) => diff.create(spec, diffSource), - files: diffSource.files, - } satisfies WhiteboardDiffViewFactory, - }; - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardCanvasEditorTabsService.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardCanvasEditorTabsService.test.ts deleted file mode 100644 index a31b07ac8..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardCanvasEditorTabsService.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { Event } from "../../base/common/event.js"; -import { WhiteboardCanvasEditorInput } from "../browser/parts/canvas/whiteboardCanvasEditorInput.js"; -import { WhiteboardCanvasEditorTabsService } from "./whiteboardCanvasEditorTabsService.js"; - -async function closeWelcome(updateNeeded: boolean): Promise { - let finished = 0; - const instantiation = { - createInstance(_ctor: unknown, target: never) { - return new WhiteboardCanvasEditorInput(target, {} as never); - }, - }; - const editors = { onDidCloseEditor: Event.None, async openEditor() {} }; - const groups = { groups: [], mainPart: { activeGroup: undefined } }; - const connection = { - async getCliInstallStatus() { - return { updateNeeded }; - }, - async finishCliInstallUpdate() { - finished += 1; - }, - }; - const tabs = new WhiteboardCanvasEditorTabsService( - instantiation as never, - editors as never, - groups as never, - connection as never, - { warn() {} } as never, - ); - try { - const welcome = await tabs.openWelcome(true); - welcome.dispose(); - await new Promise((resolve) => setImmediate(resolve)); - return finished; - } finally { - tabs.dispose(); - } -} - -test("closing Welcome finishes the CLI install update only when one is pending", async () => { - assert.equal(await closeWelcome(true), 1); - assert.equal(await closeWelcome(false), 0); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardCanvasEditorTabsService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardCanvasEditorTabsService.ts deleted file mode 100644 index 64e1fbea4..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardCanvasEditorTabsService.ts +++ /dev/null @@ -1,200 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from "../../base/common/event.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import { createDecorator, IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; -import { ILogService } from "../../platform/log/common/log.js"; -import type { EditorInput } from "../../workbench/common/editor/editorInput.js"; -import { IEditorGroupsService } from "../../workbench/services/editor/common/editorGroupsService.js"; -import { IEditorService } from "../../workbench/services/editor/common/editorService.js"; -import { - WhiteboardCanvasEditorInput, - type WhiteboardCanvasEditorTarget, -} from "../browser/parts/canvas/whiteboardCanvasEditorInput.js"; - -import type { WhiteboardSourceSelection } from "../common/whiteboardProtocol.js"; -import { sourceSelectionIdentity } from "../common/whiteboardSourceView.js"; -import { IWhiteboardDesktopConnectionService } from "./whiteboardDesktopConnectionService.js"; - -export const IWhiteboardCanvasEditorTabsService = createDecorator( - "whiteboardCanvasEditorTabsService", -); - -export interface IWhiteboardCanvasEditorTabsService { - readonly _serviceBrand: undefined; - inputFor(target: Extract): WhiteboardCanvasEditorInput; - openApiWhiteboard(sessionId: string, title: string, active?: boolean): Promise; - openApiSource(selection: WhiteboardSourceSelection, title: string): Promise; - openHome(active: boolean): Promise; - openWelcome(active: boolean): Promise; - openSettings(active: boolean): Promise; - registerWhiteboardEditor(sessionId: string, input: EditorInput): void; - closeWhiteboard(sessionId: string): Promise; -} - -export class WhiteboardCanvasEditorTabsService extends Disposable implements IWhiteboardCanvasEditorTabsService { - declare readonly _serviceBrand: undefined; - - private readonly inputs = new Map(); - private readonly whiteboardEditors = new Map>(); - - constructor( - @IInstantiationService - private readonly instantiationService: IInstantiationService, - @IEditorService private readonly editorService: IEditorService, - @IEditorGroupsService - private readonly editorGroupsService: IEditorGroupsService, - @IWhiteboardDesktopConnectionService - private readonly desktopConnection: IWhiteboardDesktopConnectionService, - @ILogService private readonly logService: ILogService, - ) { - super(); - this._register( - this.editorService.onDidCloseEditor((event) => { - queueMicrotask(() => this.pruneWhiteboardEditor(event.editor)); - }), - ); - } - - async openHome(active: boolean): Promise { - const input = await this.openSingleton({ kind: "home" }, active); - this.editorGroupsService.groups.find((group) => group.contains(input))?.stickEditor(input); - return input; - } - - inputFor( - target: Extract, - ): WhiteboardCanvasEditorInput { - const key = - target.kind === "home" - ? "home" - : target.kind === "api" - ? `api:${target.sessionId}` - : `api:${target.sessionId}:source:${sourceSelectionIdentity(target.selection)}`; - let input = this.inputs.get(key); - if (!input || input.isDisposed()) { - input = this.instantiationService.createInstance(WhiteboardCanvasEditorInput, target); - this.inputs.set(key, input); - } - if (target.kind !== "home") input.setApiTitle(target.title); - return input; - } - - async openApiWhiteboard(sessionId: string, title: string, active = true): Promise { - const input = this.inputFor({ kind: "api", sessionId, title }); - await this.openWhiteboardInput(input, active); - return input; - } - - openWelcome(active: boolean): Promise { - return this.openSingleton({ kind: "welcome" }, active); - } - - async openApiSource(selection: WhiteboardSourceSelection, title: string): Promise { - const input = this.inputFor({ kind: "api-source", sessionId: selection.sessionId, selection, title }); - await this.openWhiteboardInput(input, true); - return input; - } - - openSettings(active: boolean): Promise { - return this.openSingleton({ kind: "settings" }, active); - } - - /** One tab per non-review kind; `configure` runs before the tab opens. */ - private async openSingleton( - target: { kind: "home" } | { kind: "welcome" } | { kind: "settings" }, - active: boolean, - configure?: (input: WhiteboardCanvasEditorInput) => void, - ): Promise { - let input = this.inputs.get(target.kind); - if (!input || input.isDisposed()) { - input = this.instantiationService.createInstance(WhiteboardCanvasEditorInput, target); - this.inputs.set(target.kind, input); - if (target.kind === "welcome") { - Event.once(input.onWillDispose)(() => void this.finishCliInstallUpdate()); - } - } - configure?.(input); - // A control command may arrive while an Ask's loading pane has focus. - // Reuse the review's group instead of mounting a second canvas there. - const existingGroup = this.editorGroupsService.groups.find((group) => group.contains(input)); - const targetGroup = existingGroup === undefined ? this.editorGroupsService.mainPart.activeGroup : existingGroup; - await this.editorService.openEditor(input, { pinned: true, inactive: !active, revealIfVisible: true }, targetGroup); - return input; - } - - /** - * Closing Welcome while it shows the update screen counts as finishing the - * update, so an upgrader is not sent back to it on the next launch. - */ - private async finishCliInstallUpdate(): Promise { - try { - const status = await this.desktopConnection.getCliInstallStatus(); - if (status.updateNeeded) await this.desktopConnection.finishCliInstallUpdate(); - } catch (error) { - this.logService.warn("[Whiteboard] Could not finish the CLI install update:", error); - } - } - - private async openWhiteboardInput(input: WhiteboardCanvasEditorInput, active: boolean): Promise { - // A control command may arrive while an Ask's loading pane has focus. - // Reuse the review's group instead of mounting a second canvas there. - const existingGroup = this.editorGroupsService.groups.find((group) => group.contains(input)); - const targetGroup = existingGroup === undefined ? this.editorGroupsService.mainPart.activeGroup : existingGroup; - await this.editorService.openEditor(input, { pinned: true, inactive: !active, revealIfVisible: true }, targetGroup); - } - - async closeWhiteboard(sessionId: string): Promise { - const keys = [...this.inputs.keys()].filter( - (key) => - key === sessionId || - key === `api:${sessionId}` || - key.startsWith(`api:${sessionId}:source:`) || - key.startsWith(`${sessionId}@`), - ); - const whiteboardInputs = keys - .map((key) => this.inputs.get(key)) - .filter((input): input is WhiteboardCanvasEditorInput => Boolean(input && !input.isDisposed())); - const whiteboardEditors = [...(this.whiteboardEditors.get(sessionId) ?? [])]; - for (const key of keys) this.inputs.delete(key); - this.whiteboardEditors.delete(sessionId); - const editors = [ - ...whiteboardInputs.flatMap((input) => - this.editorGroupsService.groups - .filter((group) => group.contains(input)) - .map((group) => ({ editor: input, groupId: group.id })), - ), - ...whiteboardEditors.flatMap((editor) => - this.editorGroupsService.groups - .filter((group) => group.contains(editor)) - .map((group) => ({ editor, groupId: group.id })), - ), - ]; - if (editors.length === 0) return; - await this.editorService.closeEditors(editors); - } - - registerWhiteboardEditor(sessionId: string, input: EditorInput): void { - let editors = this.whiteboardEditors.get(sessionId); - if (!editors) { - editors = new Set(); - this.whiteboardEditors.set(sessionId, editors); - } - editors.add(input); - } - - private pruneWhiteboardEditor(input: EditorInput): void { - if (this.editorGroupsService.groups.some((group) => group.contains(input))) { - return; - } - for (const [sessionId, editors] of this.whiteboardEditors) { - editors.delete(input); - if (editors.size === 0) { - this.whiteboardEditors.delete(sessionId); - } - } - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDefaultAccountService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDefaultAccountService.ts deleted file mode 100644 index 15a3091f0..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDefaultAccountService.ts +++ /dev/null @@ -1,38 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ICopilotTokenInfo, IDefaultAccount, IDefaultAccountAuthenticationProvider, IPolicyData } from '../../base/common/defaultAccount.js'; -import { Event } from '../../base/common/event.js'; -import { Disposable } from '../../base/common/lifecycle.js'; -import { IDefaultAccountProvider, IDefaultAccountService, ManagedSettingsFetchStatus } from '../../platform/defaultAccount/common/defaultAccount.js'; - -/** - * Review has no account or Copilot surface. Keeping account startup inert also - * prevents the curated extension host from waiting for an authentication - * provider that Review intentionally does not expose. - */ -export class WhiteboardDefaultAccountService extends Disposable implements IDefaultAccountService { - declare readonly _serviceBrand: undefined; - - readonly onDidChangeDefaultAccount = Event.None; - readonly onDidChangePolicyData = Event.None; - readonly onDidChangeCopilotTokenInfo = Event.None; - readonly policyData: IPolicyData | null = null; - readonly currentDefaultAccount: IDefaultAccount | null = null; - readonly copilotTokenInfo: ICopilotTokenInfo | null = null; - readonly managedSettingsFetchStatus: ManagedSettingsFetchStatus = null; - readonly managedSettingsFetchedAt: number | null = null; - readonly managedSettingsRawResponse: unknown = null; - - getDefaultAccount(): Promise { return Promise.resolve(null); } - getDefaultAccountAuthenticationProvider(): IDefaultAccountAuthenticationProvider { - return { id: 'github', name: 'GitHub', enterprise: false }; - } - setDefaultAccountProvider(_provider: IDefaultAccountProvider): void { } - refresh(): Promise { return Promise.resolve(null); } - signIn(): Promise { return Promise.resolve(null); } - signOut(): Promise { return Promise.resolve(); } - resolveGitHubUrl(path: string): string { return `https://github.com/${path}`; } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDesktopConnectionService.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDesktopConnectionService.test.ts deleted file mode 100644 index 5bba162e4..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDesktopConnectionService.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { WhiteboardDesktopConnectionService } from "./whiteboardDesktopConnectionService.js"; - -const uuid = "11111111-1111-4111-8111-111111111111"; -class TestStorage { - private readonly values = new Map(); - - getBoolean(key: string, _scope: unknown, fallback: boolean): boolean { - return this.values.get(key) ?? fallback; - } - - store(key: string, value: boolean): void { - this.values.set(key, value); - } - - remove(key: string): void { - this.values.delete(key); - } -} - -function serviceWith(storage = new TestStorage()): WhiteboardDesktopConnectionService { - const service = new WhiteboardDesktopConnectionService({} as never, storage as never); - Object.assign(service, { - connection: { - version: 1, - url: "http://127.0.0.1:5000", - token: "token", - instanceId: "instance", - }, - initializePromise: Promise.resolve(), - }); - return service; -} - -function mockFetch(t: { after(callback: () => void): void }, handler: typeof fetch): void { - const original = globalThis.fetch; - globalThis.fetch = handler; - t.after(() => { - globalThis.fetch = original; - }); -} - -test("install status shares concurrent scans and refreshes on subsequent checks", async (t) => { - const service = serviceWith(); - t.after(() => service.dispose()); - let requests = 0; - mockFetch(t, async () => { - requests += 1; - if (requests === 3) return Response.json({ error: "scan failed" }, { status: 500 }); - return Response.json({ - fingerprint: "test", stamp: null, stale: requests > 1, updateNeeded: false, - shim: { path: "/tmp/whiteboard", installed: false, profileConfigured: false, onPath: false }, - trace: { enabled: false, configured: false, autoActivateRepositories: false, envPath: "/tmp/env", settingsPath: "/tmp/settings" }, - cli: null, - connect: { command: "whiteboard", args: ["mcp"], prompts: { claude: "c", codex: "c", cursor: "c", opencode: "c", pi: "c" }, plugins: { claude: { label: "c" }, codex: { label: "c" }, cursor: { label: "c" }, opencode: { label: "c" }, pi: { label: "c" } } }, - legacySkills: [], - }); - }); - - const [first, second] = await Promise.all([ - service.getCliInstallStatus(), - service.getCliInstallStatus(), - ]); - assert.equal(first.stale, false); - assert.equal(second.stale, false); - assert.equal(requests, 1); - assert.equal((await service.getCliInstallStatus()).stale, true); - assert.equal(requests, 2); - await assert.rejects(service.getCliInstallStatus(), /scan failed/); - assert.equal((await service.getCliInstallStatus()).stale, true); - assert.equal(requests, 4); -}); - -test("tutorial auto-prepare runs at most once per app process", async (t) => { - const service = serviceWith(); - let requests = 0; - mockFetch(t, async () => { - requests += 1; - return Response.json({ ok: true }); - }); - - const first = service.prepareTutorial(); - assert.strictEqual(service.prepareTutorial(), first); - await first; - await service.prepareTutorial(); - - assert.equal(requests, 1); - service.dispose(); -}); - -test("a failed tutorial auto-prepare is not retried on Welcome activation", async (t) => { - const service = serviceWith(); - let requests = 0; - mockFetch(t, async () => { - requests += 1; - return Response.json({ error: "no agent" }, { status: 409 }); - }); - - await assert.rejects(service.prepareTutorial(), /no agent/); - await service.prepareTutorial(); - - assert.equal(requests, 1); - service.dispose(); -}); - -test("tutorial deletion suppresses auto-prepare across restarts until explicit open", async (t) => { - const storage = new TestStorage(); - const requests: string[] = []; - mockFetch(t, async (input, init) => { - const url = String(input); - requests.push(`${init?.method ?? "GET"} ${url}`); - if (url.endsWith("/tutorial/open")) { - return Response.json({ - kind: "api", - sessionId: uuid, - title: "Tutorial", - }); - } - return Response.json({ ok: true }); - }); - - const deletingService = serviceWith(storage); - await deletingService.deleteTutorial(); - deletingService.dispose(); - - const suppressedService = serviceWith(storage); - await suppressedService.prepareTutorial(); - assert.equal(requests.length, 1); - await suppressedService.openTutorial(); - assert.equal(requests.length, 2); - assert.match(requests[1] ?? "", /POST .*\/tutorial\/open$/); - suppressedService.dispose(); - - const restoredService = serviceWith(storage); - await restoredService.prepareTutorial(); - assert.equal(requests.length, 3); - assert.match(requests[2] ?? "", /POST .*\/tutorial\/prepare$/); - restoredService.dispose(); -}); - -test("passes automatic command updates to the server without enabling optional integrations", async (t) => { - const service = serviceWith(); - let requestBody: unknown; - mockFetch(t, async (_url, init) => { - requestBody = JSON.parse(String(init?.body)); - return Response.json({ ok: true, output: "updated" }); - }); - await service.applyCliInstall({ shim: false, autoUpdate: true }); - assert.deepEqual(requestBody, { shim: false, autoUpdate: true }); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDesktopConnectionService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDesktopConnectionService.ts deleted file mode 100644 index 83bc57bd3..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDesktopConnectionService.ts +++ /dev/null @@ -1,550 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Emitter,Event } from "../../base/common/event.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; -import { IMainProcessService } from "../../platform/ipc/common/mainProcessService.js"; -import { IStorageService,StorageScope,StorageTarget } from "../../platform/storage/common/storage.js"; -import { -WHITEBOARD_DESKTOP_CHANNEL, -WHITEBOARD_DESKTOP_CONNECTION_VERSION, -type WhiteboardDesktopConnection, -} from "../common/whiteboardDesktopBootstrap.js"; -import { consumeWhiteboardEventStream } from "../common/whiteboardEventStream.js"; -import { -type JsonValue, - type WhiteboardDiffrConfig, - type WhiteboardDiffrSummarizerInput, - isJsonObject, - parseWhiteboardDiffrConfig, -parseWhiteboardCliInstallApplyResponse, -parseWhiteboardCliInstallStatus, -parseWhiteboardDesktopVerbFrame, -parseWhiteboardTutorialOpenResponse, -type WhiteboardCliInstallApplyResponse, -type WhiteboardCliInstallStatus, -type WhiteboardTutorialOpenResponse, -type WhiteboardVerbResponse -} from "../common/whiteboardProtocol.js"; -import { reconnectUntilAborted } from "../common/whiteboardReconnect.js"; - -const WHITEBOARD_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY = "review.tutorial.autoPrepareSuppressed.v1"; - -export interface WhiteboardServerConnection { - readonly serverUrl: string; - readonly token: string; -} - - -export const IWhiteboardDesktopConnectionService = createDecorator( - "whiteboardDesktopConnectionService", -); - -export interface IWhiteboardDesktopConnectionService { - readonly _serviceBrand: undefined; - readonly onDidFail: Event; - readonly onDidChangeLists: Event; - /** Fires at control-stream connection/disconnection boundaries, before reuse. */ - readonly onDidChangeConnection: Event; - initialize(): Promise; - getConnection(): Promise; - readDiffrConfig(): Promise; - saveDiffrSummarizer(input: WhiteboardDiffrSummarizerInput): Promise; - testDiffrSummarizer(input: WhiteboardDiffrSummarizerInput): Promise; - setDiffrConfigValue(key: string, value: JsonValue): Promise; - /** The scratchpad preference: a server preference, since the whiteboard server reads it. */ - readScratchpadEnabled(): Promise; - setScratchpadEnabled(enabled: boolean): Promise; - getTutorialStatus(): Promise<{ version: 1; sessionId: string | null }>; - prepareTutorial(): Promise; - openTutorial(): Promise; - deleteTutorial(): Promise; - getCliInstallStatus(): Promise; - applyCliInstall(request: { - autoUpdate?: boolean; - shim?: boolean; - trace?: true | { endpoint?: string; bucket?: string; key?: string; secret?: string }; - }): Promise; - removeCliInstall(request: { shim?: boolean; trace?: true }): Promise; - removeLegacySkills(): Promise; - finishCliInstallUpdate(): Promise; - declineCliInstall(): Promise; - skipCliInstallPrompts(): Promise; - resetCliInstallPrompts(): Promise; - attachControl(dispatch: (value: JsonValue) => Promise): void; -} - -export class WhiteboardDesktopConnectionService extends Disposable implements IWhiteboardDesktopConnectionService { - declare readonly _serviceBrand: undefined; - - private readonly _onDidChangeLists = this._register(new Emitter()); - readonly onDidChangeLists = this._onDidChangeLists.event; - private readonly _onDidFail = this._register(new Emitter()); - readonly onDidFail = this._onDidFail.event; - private readonly connectionChanged = this._register(new Emitter()); - readonly onDidChangeConnection = this.connectionChanged.event; - - private initializePromise: Promise | null = null; - private tutorialPreparePromise: Promise | undefined; - private tutorialPrepareAttempted = false; - private cliInstallStatusPromise: Promise | undefined; - private readonly controller = new AbortController(); - private controlAttached = false; - private controlDispatch: ((value: JsonValue) => Promise) | undefined; - /** - * The main process owns the embedded server's endpoint and credentials and - * publishes them only once it has validated the server's ready event. - */ - private connection: WhiteboardDesktopConnection | undefined; - private get serverUrl(): string { - return this.requireConnection().url; - } - private get token(): string { - return this.requireConnection().token; - } - private get instanceId(): string { - return this.requireConnection().instanceId; - } - - constructor( - @IMainProcessService - private readonly mainProcessService: IMainProcessService, - @IStorageService private readonly storageService: IStorageService, - ) { - super(); - } - - private requireConnection(): WhiteboardDesktopConnection { - if (!this.connection) { - throw new Error("The Whiteboard connection is not established yet."); - } - return this.connection; - } - - private async connect(): Promise { - if (this.connection) return; - const connection = (await this.mainProcessService - .getChannel(WHITEBOARD_DESKTOP_CHANNEL) - .call("getConnection")) as WhiteboardDesktopConnection; - if (connection?.version !== WHITEBOARD_DESKTOP_CONNECTION_VERSION) { - throw new Error(`Unsupported Whiteboard connection version: ${String(connection?.version)}.`); - } - this.connection = connection; - } - - initialize(): Promise { - this.initializePromise ??= this.initializeGlobalState().catch((error) => { - this.initializePromise = null; - throw error; - }); - return this.initializePromise; - } - - async getConnection(): Promise { - await this.initialize(); - return { serverUrl: this.serverUrl, token: this.token }; - } - - /** - * The dismissed review retention window. It is a server preference rather - * than a workbench setting because the reaper runs inside the review server. - * `null` means never reap. - */ - async readDiffrConfig(): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/diffr-config`, { - headers: this.authHeaders(), - signal: AbortSignal.timeout(30_000), - }); - await this.requireOk(response, "diffr configuration"); - return parseWhiteboardDiffrConfig(await response.json()); - } - - async setDiffrConfigValue(key: string, value: JsonValue): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/diffr-config`, { - method: "PUT", - headers: { - ...this.authHeaders(), - "content-type": "application/json", - }, - body: JSON.stringify({ key, value }), - signal: AbortSignal.timeout(30_000), - }); - await this.requireOk(response, "diffr configuration"); - return parseWhiteboardDiffrConfig(await response.json()); - } - - async readScratchpadEnabled(): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/preferences/scratchpad`, { - headers: this.authHeaders(), - signal: AbortSignal.timeout(30_000), - }); - await this.requireOk(response, "scratchpad preference"); - return parseScratchpadPreference(await response.json()); - } - - async setScratchpadEnabled(enabled: boolean): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/preferences/scratchpad`, { - method: "PUT", - headers: { ...this.authHeaders(), "content-type": "application/json" }, - body: JSON.stringify({ enabled }), - signal: AbortSignal.timeout(120_000), - }); - await this.requireOk(response, "scratchpad preference"); - return parseScratchpadPreference(await response.json()); - } - - async saveDiffrSummarizer(input: WhiteboardDiffrSummarizerInput): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/diffr-config/summarizer`, { - method: "PUT", - headers: { ...this.authHeaders(), "content-type": "application/json" }, - body: JSON.stringify(input), - signal: AbortSignal.timeout(120_000), - }); - await this.requireOk(response, "summary settings"); - return parseWhiteboardDiffrConfig(await response.json()); - } - - async testDiffrSummarizer(input: WhiteboardDiffrSummarizerInput): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/diffr-config/summarizer/test`, { - method: "POST", - headers: { ...this.authHeaders(), "content-type": "application/json" }, - body: JSON.stringify(input), - signal: AbortSignal.timeout(95_000), - }); - await this.requireOk(response, "summary test"); - const result: unknown = await response.json(); - if (!isJsonObject(result) || typeof result.summary !== "string") throw new Error("Malformed summary test response."); - return result.summary; - } - - async getTutorialStatus(): Promise<{ version: 1; sessionId: string | null }> { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/tutorial/status`, { - headers: this.authHeaders(), - signal: AbortSignal.timeout(5_000), - }); - await this.requireOk(response, "Whiteboard tutorial status"); - const payload = (await response.json()) as { - version?: unknown; - sessionId?: unknown; - }; - if (payload.version !== 1 || (payload.sessionId !== null && typeof payload.sessionId !== "string")) { - throw new Error("Whiteboard tutorial status is invalid."); - } - return { version: 1, sessionId: payload.sessionId as string | null }; - } - - prepareTutorial(): Promise { - if (this.storageService.getBoolean(WHITEBOARD_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY, StorageScope.APPLICATION, false)) { - return Promise.resolve(); - } - if (this.tutorialPreparePromise) return this.tutorialPreparePromise; - if (this.tutorialPrepareAttempted) return Promise.resolve(); - this.tutorialPrepareAttempted = true; - const operation = this.requestTutorialPreparation(); - this.tutorialPreparePromise = operation; - const clearOperation = () => { - if (this.tutorialPreparePromise === operation) { - this.tutorialPreparePromise = undefined; - } - }; - void operation.then(clearOperation, clearOperation); - return operation; - } - - private async requestTutorialPreparation(): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/tutorial/prepare`, { - method: "POST", - headers: this.authHeaders(), - signal: AbortSignal.timeout(120_000), - }); - await this.requireOk(response, "Whiteboard tutorial preparation"); - } - - async openTutorial(): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/tutorial/open`, { - method: "POST", - headers: this.authHeaders(), - signal: AbortSignal.timeout(120_000), - }); - await this.requireOk(response, "Whiteboard tutorial open"); - const payload = parseWhiteboardTutorialOpenResponse(await response.json()); - this.tutorialPrepareAttempted = true; - this.storageService.remove(WHITEBOARD_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY, StorageScope.APPLICATION); - return payload; - } - - async deleteTutorial(): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/tutorial`, { - method: "DELETE", - headers: this.authHeaders(), - signal: AbortSignal.timeout(30_000), - }); - await this.requireOk(response, "Whiteboard tutorial delete"); - this.tutorialPreparePromise = undefined; - this.tutorialPrepareAttempted = true; - this.storageService.store( - WHITEBOARD_TUTORIAL_AUTOPREPARE_SUPPRESSED_KEY, - true, - StorageScope.APPLICATION, - StorageTarget.MACHINE, - ); - this._onDidChangeLists.fire(); - } - - /** Raises the server's own error message when it sends one. */ - private async requireOk(response: Response, what: string): Promise { - if (response.ok) { - return; - } - const payload = (await response.json().catch(() => ({}))) as { - error?: unknown; - }; - throw new Error(typeof payload.error === "string" ? payload.error : `${what} returned ${response.status}.`); - } - - async getCliInstallStatus(): Promise { - await this.initialize(); - this.cliInstallStatusPromise ??= (async () => { - const response = await fetch(`${this.serverUrl}/install/status`, { - headers: this.authHeaders(), - signal: AbortSignal.timeout(30_000), - }); - await this.requireOk(response, "Whiteboard install status"); - return parseWhiteboardCliInstallStatus(await response.json()); - })().finally(() => { - this.cliInstallStatusPromise = undefined; - }); - return this.cliInstallStatusPromise; - } - - async applyCliInstall(request: { - autoUpdate?: boolean; - shim?: boolean; - trace?: true | { endpoint?: string; bucket?: string; key?: string; secret?: string }; - }): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/install/apply`, { - method: "POST", - headers: { - ...this.authHeaders(), - "content-type": "application/json", - }, - body: JSON.stringify({ - ...(request.autoUpdate ? { autoUpdate: true } : {}), - ...(request.shim !== undefined ? { shim: request.shim } : {}), - ...(request.trace !== undefined ? { trace: request.trace } : {}), - }), - signal: AbortSignal.timeout(120_000), - }); - const payload: JsonValue = await response.json().catch(() => ({})); - if (!response.ok) { - const detail = payload as { output?: unknown; error?: unknown }; - throw new Error( - typeof detail.output === "string" && detail.output - ? detail.output - : typeof detail.error === "string" - ? detail.error - : `Whiteboard install returned ${response.status}.`, - ); - } - return parseWhiteboardCliInstallApplyResponse(payload); - } - - async removeCliInstall(request: { shim?: boolean; trace?: true }): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/install/remove`, { - method: "POST", - headers: { - ...this.authHeaders(), - "content-type": "application/json", - }, - body: JSON.stringify({ - ...(request.shim ? { shim: true } : {}), - ...(request.trace ? { trace: true } : {}), - }), - signal: AbortSignal.timeout(30_000), - }); - if (!response.ok) { - throw new Error(`Whiteboard install remove returned ${response.status}.`); - } - } - - async removeLegacySkills(): Promise { - await this.postCliInstallVerb("legacy-skills/remove"); - } - - async finishCliInstallUpdate(): Promise { - await this.postCliInstallVerb("finish-update"); - } - - async declineCliInstall(): Promise { - await this.postCliInstallVerb("decline"); - } - - async skipCliInstallPrompts(): Promise { - await this.postCliInstallVerb("skip"); - } - - async resetCliInstallPrompts(): Promise { - await this.postCliInstallVerb("reset"); - } - - private async postCliInstallVerb(verb: "decline" | "skip" | "reset" | "legacy-skills/remove" | "finish-update"): Promise { - await this.initialize(); - const response = await fetch(`${this.serverUrl}/install/${verb}`, { - method: "POST", - headers: this.authHeaders(), - signal: AbortSignal.timeout(30_000), - }); - if (!response.ok) { - throw new Error(`Whiteboard install ${verb} returned ${response.status}.`); - } - } - - attachControl(dispatch: (value: JsonValue) => Promise): void { - this.controlDispatch = dispatch; - if (this.controlAttached) return; - this.controlAttached = true; - void this.initializeAndMaintainControl((value) => { - const current = this.controlDispatch; - return current - ? current(value) - : Promise.resolve({ - ok: false, - error: "Whiteboard control handler is unavailable.", - }); - }); - } - - override dispose(): void { - this.controller.abort(); - super.dispose(); - } - - private async initializeGlobalState(): Promise { - await this.connect(); - await this.waitForHealth(); - } - - private async initializeAndMaintainControl( - dispatch: (value: JsonValue) => Promise, - ): Promise { - await reconnectUntilAborted( - this.controller.signal, - async () => { - await this.initialize(); - await this.maintainControl(dispatch); - }, - { - onRetry: (error) => console.error("[Whiteboard] control channel stopped", error), - }, - ); - } - - private async waitForHealth(): Promise { - const deadline = Date.now() + 10_000; - while (Date.now() < deadline) { - try { - const response = await fetch(`${this.serverUrl}/health`, { - signal: AbortSignal.timeout(1_000), - }); - const value = (await response.json()) as { instanceId?: unknown }; - if (response.ok && value.instanceId === this.instanceId) return; - } catch { - // The utility host may still be starting. - } - await new Promise((resolve) => setTimeout(resolve, 100)); - } - throw new Error("The embedded Whiteboard server did not become healthy."); - } - - - private async maintainControl(dispatch: (value: JsonValue) => Promise): Promise { - await reconnectUntilAborted( - this.controller.signal, - async (onConnected) => { - await this.consumeControl(dispatch, onConnected); - if (this.controller.signal.aborted) return; - throw new Error("The Whiteboard control stream ended."); - }, - { - onExhausted: (error) => { - throw error; - }, - }, - ); - } - - private async consumeControl( - dispatch: (value: JsonValue) => Promise, - onConnected: () => void, - ): Promise { - const url = new URL("/control", this.serverUrl); - url.searchParams.set("token", this.token); - const response = await fetch(url, { signal: this.controller.signal }); - if (!response.ok || !response.body) { - throw new Error(`Desktop control returned ${response.status}.`); - } - this.connectionChanged.fire(); - onConnected(); - await consumeWhiteboardEventStream( - response.body, - async (value) => { - const frame = parseWhiteboardDesktopVerbFrame(value); - let verbResponse: WhiteboardVerbResponse; - try { - verbResponse = await dispatch(frame.request); - } catch (error) { - verbResponse = { - ok: false, - error: error instanceof Error ? error.message : String(error), - }; - } - await fetch(`${this.serverUrl}/control/result`, { - method: "POST", - headers: { - ...this.authHeaders(), - "content-type": "application/json", - }, - body: JSON.stringify({ - id: frame.id, - response: verbResponse, - }), - signal: this.controller.signal, - }); - }, - this.controller.signal, - ).finally(() => this.connectionChanged.fire()); - } - - private authHeaders(): Record { - return { "x-whiteboard-token": this.token }; - } -} - -export async function whiteboardResponseError(response: Response, fallback: string): Promise { - const payload = (await response.json().catch(() => null)) as { - error?: unknown; - } | null; - return new Error(typeof payload?.error === "string" && payload.error ? payload.error : fallback); -} - -function parseScratchpadPreference(value: unknown): boolean { - if (typeof value !== "object" || value === null || !("enabled" in value) || typeof value.enabled !== "boolean") { - throw new Error("scratchpad preference response is malformed."); - } - return value.enabled; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffLayout.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffLayout.test.ts deleted file mode 100644 index da730c0d2..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffLayout.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { Emitter } from "../../base/common/event.js"; -import { - ConfigurationTarget, - type IConfigurationChangeEvent, -} from "../../platform/configuration/common/configuration.js"; -import type { WhiteboardDiffLayout } from "../common/whiteboardProtocol.js"; -import { WhiteboardDiffLayoutSetting } from "./whiteboardDiffLayout.js"; - -function createService() { - const values = new Map(); - const writes: Array<{ key: string; value: unknown; target: unknown }> = []; - const changes = new Emitter(); - const configurationService = { - getValue: (key: string) => values.get(key), - updateValue: async (key: string, value: unknown, target: unknown) => { - values.set(key, value); - writes.push({ key, value, target }); - changes.fire({ - affectsConfiguration: (section: string) => section === key, - } as IConfigurationChangeEvent); - }, - onDidChangeConfiguration: changes.event, - }; - const service = new WhiteboardDiffLayoutSetting(configurationService as never); - return { service, values, writes, changes }; -} - -test("side by side is the default and inline maps to unified", () => { - const { service, values } = createService(); - assert.equal(service.get(), "split"); - values.set("diffEditor.renderSideBySide", false); - assert.equal(service.get(), "unified"); -}); - -test("set writes the user setting and announces the new layout", async () => { - const { service, writes } = createService(); - const announced: WhiteboardDiffLayout[] = []; - service.onDidChange((layout) => announced.push(layout)); - - await service.set("unified"); - - assert.deepEqual(writes, [ - { - key: "diffEditor.renderSideBySide", - value: false, - target: ConfigurationTarget.USER, - }, - ]); - assert.deepEqual(announced, ["unified"]); - assert.equal(service.get(), "unified"); -}); - -test("toggle flips between the two layouts", async () => { - const { service, writes } = createService(); - await service.toggle(); - assert.equal(service.get(), "unified"); - await service.toggle(); - assert.equal(service.get(), "split"); - assert.deepEqual( - writes.map((write) => write.value), - [false, true], - ); -}); - -test("unrelated setting changes do not announce a layout", () => { - const { service, changes } = createService(); - const announced: WhiteboardDiffLayout[] = []; - service.onDidChange((layout) => announced.push(layout)); - changes.fire({ - affectsConfiguration: (section: string): boolean => - section === "editor.fontSize", - } as IConfigurationChangeEvent); - assert.deepEqual(announced, []); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffLayout.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffLayout.ts deleted file mode 100644 index e332cb6ef..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffLayout.ts +++ /dev/null @@ -1,61 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Emitter } from "../../base/common/event.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import { - ConfigurationTarget, - IConfigurationService, -} from "../../platform/configuration/common/configuration.js"; -import type { WhiteboardDiffLayout } from "../common/whiteboardProtocol.js"; - -const RENDER_SIDE_BY_SIDE_KEY = "diffEditor.renderSideBySide"; - -/** - * The unified/split choice, kept as the stock diff-editor setting rather than - * widget-local state: every embedded diff (the multi-diff view and the inline - * editors) already reads it, the Toggle Inline View command already writes it, - * and the user setting is what makes the choice outlive the app. - */ -export class WhiteboardDiffLayoutSetting extends Disposable { - private readonly _onDidChange = this._register( - new Emitter(), - ); - readonly onDidChange = this._onDidChange.event; - - constructor( - @IConfigurationService - private readonly configurationService: IConfigurationService, - ) { - super(); - this._register( - configurationService.onDidChangeConfiguration((event) => { - if (event.affectsConfiguration(RENDER_SIDE_BY_SIDE_KEY)) { - this._onDidChange.fire(this.get()); - } - }), - ); - } - - get(): WhiteboardDiffLayout { - return this.configurationService.getValue( - RENDER_SIDE_BY_SIDE_KEY, - ) === false - ? "unified" - : "split"; - } - - set(layout: WhiteboardDiffLayout): Promise { - return this.configurationService.updateValue( - RENDER_SIDE_BY_SIDE_KEY, - layout === "split", - ConfigurationTarget.USER, - ); - } - - toggle(): Promise { - return this.set(this.get() === "split" ? "unified" : "split"); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffViewService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffViewService.ts deleted file mode 100644 index ddfb0ec1f..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardDiffViewService.ts +++ /dev/null @@ -1,395 +0,0 @@ -import { orderWhiteboardDiffFiles } from "../common/whiteboardChangedFilesModel.js"; -import { CancellationToken } from "../../base/common/cancellation.js"; -import { Range } from "../../editor/common/core/range.js"; -import { USUAL_WORD_SEPARATORS } from "../../editor/common/core/wordHelper.js"; -import { ITextModelService } from "../../editor/common/services/resolverService.js"; -import { IDiffProviderFactoryService } from "../../editor/browser/widget/diffEditor/diffProviderFactoryService.js"; -import { alignmentRows } from "../common/whiteboardLens.js"; -import type { WhiteboardInlineEditorSpec, WhiteboardInlineEditorHandle, WhiteboardFindQuery } from "../common/whiteboardProtocol.js"; -import { structuralChangeCounts } from "../common/whiteboardProtocol.js"; -import type { WhiteboardDiffProgress, WhiteboardDiffViewport } from "../common/whiteboardProtocol.js"; -import { lensRanges, withLens } from "./whiteboardLens.js"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Emitter } from "../../base/common/event.js"; -import { Disposable, DisposableStore, isDisposable } from "../../base/common/lifecycle.js"; -import type { URI } from "../../base/common/uri.js"; -import type { ICodeEditor } from "../../editor/browser/editorBrowser.js"; -import type { IMultiDiffEditorViewState } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.js"; -import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; -import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; -import { WHITEBOARD_STRUCTURAL_DIFF_SETTING } from "../common/whiteboardConfigurationDefaults.js"; -import type { - WhiteboardCommitScope, - WhiteboardDiffLens, - WhiteboardDiffFileWire, - WhiteboardDiffViewHandle, - WhiteboardDiffViewSpec, -} from "../common/whiteboardProtocol.js"; -import { WhiteboardDiffLayoutSetting } from "./whiteboardDiffLayout.js"; -import { markWhiteboardEmbeddedEditor } from "./whiteboardEmbeddedNavigation.js"; -import { WhiteboardFilesDiffView, WhiteboardFilesEditorInput, type WhiteboardFilesEditorEntry } from "./whiteboardFilesDiffView.js"; -import { WhiteboardEmbeddedEditors } from "./whiteboardEmbeddedEditors.js"; - -import { createStructuralDiffEditors } from "./whiteboardStructuralDiff.js"; -import { StructuralDiffSession } from "./whiteboardStructuralDiffSession.js"; -import type { StructuralDiffStream } from "./whiteboardStructuralDiffClient.js"; - -export interface WhiteboardDiffViewSource { - load(scope?: WhiteboardCommitScope, lens?: WhiteboardDiffLens): Promise<{ - sourceUri: URI; entries: readonly WhiteboardFilesEditorEntry[]; - session?: StructuralDiffSession; - }>; - files(scope?: WhiteboardCommitScope): Promise; -} - -/** - * Mounts the changed-files diff UI inside the Review canvas. One instance - * belongs to one canvas pane, so its view-state cache and its live handles - * follow that pane's lifetime. - */ -export class WhiteboardDiffViewService extends Disposable { - private overflowWidgetsDomNode: HTMLElement | undefined; - private readonly handles = new Set(); - comparisonGeneration = 0; - private readonly sessions = new Map(); - readonly diffLayout: WhiteboardDiffLayoutSetting; - /** - * Scroll and expansion state per session document. The Diff view is a - * conditionally rendered React sibling: a toggle away disposes the widget, - * so the state must survive outside it. - */ - private readonly viewStates = new Map(); - - constructor( - private readonly inlineEditors: WhiteboardEmbeddedEditors, - @IInstantiationService - private readonly instantiationService: IInstantiationService, - ) { - super(); - this.diffLayout = this._register(instantiationService.createInstance(WhiteboardDiffLayoutSetting)); - } - - get structuralRenderingEnabled(): boolean { - return this.instantiationService.invokeFunction(a => a.get(IConfigurationService).getValue(WHITEBOARD_STRUCTURAL_DIFF_SETTING) === true); - } - - /** Shared by every view of this comparison; reset/dispose follows the canvas lifetime. */ - openComparison(key: string, client: StructuralDiffStream, generation: number): StructuralDiffSession | undefined { - if (generation !== this.comparisonGeneration || !this.structuralRenderingEnabled) return undefined; - let session = this.sessions.get(key); - if (!session) { - session = new StructuralDiffSession(client); - this.sessions.set(key, session); - void session.start(); - } - return session; - } - - override dispose(): void { this.reset(); super.dispose(); } - - setOverflowWidgetsDomNode(node: HTMLElement): void { - this.overflowWidgetsDomNode = node; - } - - create(spec: WhiteboardDiffViewSpec, source: WhiteboardDiffViewSource): WhiteboardDiffViewHandle { - const handle = new DiffViewController( - spec, - this.instantiationService, - this.inlineEditors, - this.overflowWidgetsDomNode, - this.diffLayout, - this.viewStates, - () => this.handles.delete(handle), - source, - ); - this.handles.add(handle); - return handle; - } - - /** Document peeks use the same controller, providers and widget as the Diff tab. */ - createDocument(spec: WhiteboardInlineEditorSpec, lens: WhiteboardDiffLens, source: WhiteboardDiffViewSource): WhiteboardInlineEditorHandle { - const lifetime = new DisposableStore(); - const heightChanged = lifetime.add(new Emitter()); - let height = 400; - let generation = 0; - let matches: DocumentMatch[] = []; - const view = this.create({ - container: spec.container, lens, progress: spec.progress, - document: { - heightMode: spec.heightMode, - onDidChangeHeight: value => { height = value; heightChanged.fire(value); }, - onDidFocus: spec.onDidFocus, onDidOpen: spec.onDidOpen, - }, - }, source) as DiffViewController; - lifetime.add(view); - return { - get height() { return height; }, - setProgress: progress => view.setProgress(progress), - onDidChangeHeight: heightChanged.event, - onDidError: view.onDidError, - setActive: active => spec.container.classList.toggle("review-document-code-active", active), - setCollapsed: collapsed => view.setCollapsed(collapsed), - setFindQuery: async query => { - const request = ++generation; - const result = await this.findDocument(lens, source, query); - if (lifetime.isDisposed || request !== generation) return { matchCount: 0 }; - matches = result; - view.decorateMatches(matches); - return { matchCount: matches.length }; - }, - revealFindMatch: index => { - const match = matches[index]; - if (!match) return; - view.setCollapsed(false); - view.revealSource({ file: match.file, side: match.side, fromLine: match.range.startLineNumber, toLine: match.range.endLineNumber }); - view.decorateMatches(matches, index); - }, - clearActiveFindMatch: () => view.decorateMatches(matches), - clearFind: () => { generation++; matches = []; view.decorateMatches([]); }, - dispose: () => { generation++; lifetime.dispose(); }, - }; - } - - /** Search pinned models through the same diff provider; no synthetic text/model is built. */ - async findDocument(lens: WhiteboardDiffLens, source: WhiteboardDiffViewSource, query: WhiteboardFindQuery): Promise { - if (!query.text) return []; - const lifetime = new DisposableStore(); - try { - const data = await source.load(undefined, lens); - const entries = data.entries.filter(entry => lensRanges(lens, entry).length > 0); - const structural = data.session ? createStructuralDiffEditors(this.instantiationService, entries, lifetime, data.session) - : { instantiation: this.instantiationService, entries }; - const instantiation = withLens(structural.instantiation, structural.entries, lens, lifetime, () => undefined, () => ({ dispose() {} })); - const resolver = instantiation.invokeFunction(a => a.get(ITextModelService)); - const factory = instantiation.invokeFunction(a => a.get(IDiffProviderFactoryService)); - const matches: DocumentMatch[] = []; - for (const entry of structural.entries) { - const original = entry.original ? lifetime.add(await resolver.createModelReference(entry.original)).object.textEditorModel : undefined; - const modified = entry.modified ? lifetime.add(await resolver.createModelReference(entry.modified)).object.textEditorModel : undefined; - const provider = factory.createDiffProvider({ diffAlgorithm: "advanced" }); - if (isDisposable(provider)) lifetime.add(provider); - const diff = original && modified ? await provider.computeDiff(original, modified, { ignoreTrimWhitespace: false, maxComputationTimeMs: 0, computeMoves: false }, CancellationToken.None) : undefined; - const pairs = diff && original && modified ? new Map(alignmentRows(diff, original.getLineCount(), modified.getLineCount()).filter((row): row is [number, number] => row[0] !== null && row[1] !== null)) : new Map(); - for (const [side, model] of [["base", original], ["head", modified]] as const) { - if (!model) continue; - const ranges = lensRanges(lens, entry).filter(range => range.side === side); - const found = model.findMatches(query.text, false, query.isRegex, query.matchCase, query.wholeWord ? USUAL_WORD_SEPARATORS : null, false); - for (const match of found) { - const line = match.range.startLineNumber; - const outside = diff?.contextGaps?.some(gap => gap.label === "Outside lens" && line >= (side === "base" ? gap.originalStart : gap.modifiedStart) && line < (side === "base" ? gap.originalStart + gap.originalCount : gap.modifiedStart + gap.modifiedCount)); - if (outside || (!diff && !ranges.some(range => line >= range.fromLine && line <= range.toLine))) continue; - const headLine = pairs.get(line - 1); - if (side === "base" && headLine !== undefined && modified && match.range.startLineNumber === match.range.endLineNumber && model.getLineContent(line) === modified.getLineContent(headLine + 1)) continue; - matches.push({ file: side === "base" ? entry.file.previousPath ?? entry.file.path : entry.file.path, side, range: match.range }); - } - } - } - return matches; - } finally { lifetime.dispose(); } - } - - reset(): void { - this.comparisonGeneration++; - for (const handle of [...this.handles]) handle.dispose(); - this.handles.clear(); - this.viewStates.clear(); - for (const session of this.sessions.values()) session.dispose(); - this.sessions.clear(); - } - - toggleRenderSideBySide(): void { - void this.diffLayout.toggle(); - } -} - -interface DocumentMatch { - file: string; - side: "base" | "head"; - range: Range; -} - -class DiffViewController extends Disposable implements WhiteboardDiffViewHandle { - private readonly _onDidError = this._register(new Emitter()); - readonly onDidError = this._onDidError.event; - private readonly activeControlStore = this._register(new DisposableStore()); - private view: WhiteboardFilesDiffView | undefined; - private progress: WhiteboardDiffProgress | undefined; - private readonly progressChanged = this._register(new Emitter()); - private pendingSectionId: string | undefined; - private pendingSource: WhiteboardDiffLens['ranges'][number] | undefined; - setProgress(progress: WhiteboardDiffProgress): void { this.progress = progress; this.view?.setProgress(progress); this.progressChanged.fire(); } - revealSource(source: WhiteboardDiffLens['ranges'][number], sectionId?: string): void { this.pendingSource = source; this.pendingSectionId = sectionId; this.view?.revealSource(source, sectionId); } - private readonly _onDidScroll = this._register(new Emitter()); - readonly onDidScroll = this._onDidScroll.event; - sourceOffset(source: WhiteboardDiffLens['ranges'][number]): number | undefined { return this.view?.sourceOffset(source); } - private viewStateKey: string | undefined; - private adoptedEditors: readonly ICodeEditor[] = []; - private disposed = false; - private collapsed = false; - private matches: DocumentMatch[] = []; - private activeMatch: number | undefined; - private readonly findDecorations = this._register(new DisposableStore()); - setCollapsed(collapsed: boolean): void { this.collapsed = collapsed; this.view?.setCollapsed(collapsed); } - decorateMatches(matches: DocumentMatch[], active?: number): void { - this.matches = matches; this.activeMatch = active; - this.findDecorations.clear(); - const control = this.view?.getActiveControl(); - if (!control) return; - for (const [side, editor] of [["base", control.getOriginalEditor()], ["head", control.getModifiedEditor()]] as const) { - const collection = editor.createDecorationsCollection(matches.flatMap((match, index) => match.side === side ? [{ range: match.range, options: { description: "review-document-find", className: index === active ? "currentFindMatch" : "findMatch" } }] : [])); - this.findDecorations.add({ dispose: () => collection.clear() }); - } - } - - constructor( - private readonly spec: WhiteboardDiffViewSpec, - private readonly instantiationService: IInstantiationService, - private readonly inlineEditors: WhiteboardEmbeddedEditors, - private readonly overflowWidgetsDomNode: HTMLElement | undefined, - private readonly diffLayout: WhiteboardDiffLayoutSetting, - private readonly viewStates: Map, - private readonly onDispose: () => void, - private readonly source: WhiteboardDiffViewSource, - ) { - super(); - this.progress = spec.progress; - void this.initialize(); - } - - focus(): void { - this.view?.focus(); - } - - override dispose(): void { - if (this.disposed) return; - this.disposed = true; - this.captureViewState(); - // A view toggle disposes these editors. The composite must not keep one - // of them as its active editor afterwards. - for (const editor of this.adoptedEditors) { - this.inlineEditors.clearExternalActiveEditor(editor); - } - this.adoptedEditors = []; - this.view = undefined; - super.dispose(); - this.onDispose(); - } - - private async initialize(): Promise { - try { - const data = await this.source.load(this.spec.scope, this.spec.lens); - const { sourceUri, entries } = data; - const session = data.session; - const structuralEnabled = session !== undefined && this.instantiationService.invokeFunction(a => a.get(IConfigurationService).getValue(WHITEBOARD_STRUCTURAL_DIFF_SETTING) === true); - this.viewStateKey = `${sourceUri.toString()}:${structuralEnabled}:${JSON.stringify(this.spec.lens ?? null)}`; - if (this.disposed) return; - const store = this._register(new DisposableStore()); - const structural = session && structuralEnabled ? createStructuralDiffEditors(this.instantiationService, entries, store, session) - : { instantiation: this.instantiationService, entries }; - - if (this.disposed) return; - const lens = this.spec.lens; - const sections = this.progress?.sections; - let selected = lens && sections?.length ? sections.flatMap(section => { - const matches = structural.entries.filter(entry => lensRanges({ ...lens, ranges: section.sources }, entry).length > 0); - return matches.map((entry, index) => ({ ...entry, sectionId: section.id, sectionStart: index === 0, original: entry.original?.with({ fragment: section.id }), modified: entry.modified?.with({ fragment: section.id }) })); - }) : lens ? structural.entries.filter(entry => lensRanges(lens, entry).length > 0) : structural.entries; - // File lenses have no authored sections; follow the same order as their file tree. - if (lens && !sections?.length) { - const byFile = new Map(selected.map(entry => [entry.file, entry])); - selected = orderWhiteboardDiffFiles([...byFile.keys()]).map(file => byFile.get(file)!); - } - const instantiation = withLens(structural.instantiation, selected, lens, store, () => this.progress, this.progressChanged.event); - // The input owns the text-model references its view model resolves, so - // this handle disposes it alongside the view. - const input = store.add(instantiation.createInstance(WhiteboardFilesEditorInput, sourceUri, selected, - structuralEnabled, !!lens || !!this.spec.onToggleViewed)); - const view = store.add( - instantiation.createInstance( - WhiteboardFilesDiffView, - this.spec.container, - this.overflowWidgetsDomNode, - this.diffLayout, - this.spec.fileTreeContainer, this.spec.onToggleViewed, this.spec.onToggleSection, this.spec.document, - ), - ); - this.view = view; - if (this.progress) view.setProgress(this.progress); - if (structuralEnabled) view.startLoading(selected); - store.add(view.onDidChangeActiveControl(() => this.bindActiveControl(view))); - store.add(view.onDidScroll(() => this._onDidScroll.fire({ height: view.viewportHeight }))); - // A saved whole-list offset cannot be restored into a partial streamed list. - await view.setInput(input, structuralEnabled ? undefined : this.viewStates.get(this.viewStateKey), - ); - if (this.disposed) return; - this.bindActiveControl(view); - view.setCollapsed(this.collapsed); - if (this.pendingSource) view.revealSource(this.pendingSource, this.pendingSectionId); - if (!session) for (const entry of selected) view.fileCounts(entry.file.path, { added: entry.file.additions, removed: entry.file.deletions }); - if (session) this.observeSession(session, selected, view, store, structuralEnabled); - - } catch (error) { - if (this.disposed) return; - this._onDidError.fire(error instanceof Error ? error.message : String(error)); - } - } - - private observeSession(session: StructuralDiffSession, entries: readonly WhiteboardFilesEditorEntry[], view: WhiteboardFilesDiffView, store: DisposableStore, structuralEnabled: boolean): void { - const rendered = new Set(); - const annotationWarnings = new Set(); - const renderCurrentState = (change?: import("./whiteboardStructuralDiffSession.js").StructuralSessionChange) => { - if (this.disposed) return; - for (const entry of entries) { - const path = entry.file.path; - if (change && !change.files.has(path) && !change.labels.has(path)) continue; - const result = entry.file.status === "unchanged" ? {} : session.getFileResult(path); - if (result?.annotationError && !annotationWarnings.has(path)) { - annotationWarnings.add(path); - this._onDidError.fire(`Summary unavailable for ${path}: ${result.annotationError}`); - } - if (!result || rendered.has(path)) continue; - rendered.add(path); - if (structuralEnabled && result.hidden !== undefined) view.hideFile(path, result.hidden); - if (result.diff) view.fileCounts(path, result.diff.type === "text" ? structuralChangeCounts(result.diff.structural_changes) : { added: 0, removed: 0 }); - if (structuralEnabled) view.fileLoaded(path, result.error); - } - if (session.error) view.loadingFailed(session.error); - else if (session.complete) view.loadingFailed("diffr did not supply a result for this file."); - }; - store.add(session.onDidChange(renderCurrentState)); - renderCurrentState(); - } - - /** - * Joins the embedded diff's inner editors to the canvas composite. Find and - * the editor context keys act on the composite's active editor, so a focused - * inner editor has to become that editor. - */ - private bindActiveControl(view: WhiteboardFilesDiffView): void { - this.activeControlStore.clear(); - const diffEditor = view.getActiveControl(); - if (!diffEditor) return; - const editors: readonly ICodeEditor[] = [diffEditor.getOriginalEditor(), diffEditor.getModifiedEditor(), - ]; - this.adoptedEditors = editors; - for (const editor of editors) { - this.activeControlStore.add(markWhiteboardEmbeddedEditor(editor)); - if (this.spec.document) WhiteboardEmbeddedEditors.markDocumentEditor(editor); - this.activeControlStore.add( - editor.onDidFocusEditorText(() => { this.inlineEditors.setExternalActiveEditor(editor); this.spec.document?.onDidFocus?.(); }), - ); - } - this.decorateMatches(this.matches, this.activeMatch); - } - - private captureViewState(): void { - const key = this.viewStateKey; - const state = this.view?.getViewState(); - if (!key || !state) return; - this.viewStates.set(key, state); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardEmbeddedEditors.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardEmbeddedEditors.ts deleted file mode 100644 index 4d59ded7b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardEmbeddedEditors.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ -import { Emitter } from "../../base/common/event.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import type { ICodeEditor } from "../../editor/browser/editorBrowser.js"; -import type { ICompositeCodeEditor } from "../../editor/common/editorCommon.js"; - -/** Tracks focus and retained selections for all native editors embedded in a review. */ -export class WhiteboardEmbeddedEditors extends Disposable implements ICompositeCodeEditor { - private readonly changed = this._register(new Emitter()); - readonly onDidChangeActiveEditor = this.changed.event; - private active: ICodeEditor | undefined; - private selected: ICodeEditor | undefined; - private static readonly documentEditors = new WeakSet(); - - get activeCodeEditor(): ICodeEditor | undefined { return this.active; } - get selectionCodeEditor(): ICodeEditor | undefined { return this.active ?? this.selected; } - static owns(editor: ICodeEditor): boolean { return this.documentEditors.has(editor); } - static markDocumentEditor(editor: ICodeEditor): void { this.documentEditors.add(editor); } - - setExternalActiveEditor(editor: ICodeEditor | undefined): void { - if (editor) this.selected = editor; - if (this.active === editor) return; - this.active = editor; - this.changed.fire(this); - } - clearExternalActiveEditor(editor: ICodeEditor): void { - if (this.selected === editor) this.selected = undefined; - if (this.active === editor) this.setExternalActiveEditor(undefined); - } - reset(): void { this.selected = undefined; this.setExternalActiveEditor(undefined); } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardEmbeddedNavigation.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardEmbeddedNavigation.ts deleted file mode 100644 index cc3a8dc78..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardEmbeddedNavigation.ts +++ /dev/null @@ -1,184 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type { IDisposable } from "../../base/common/lifecycle.js"; -import { - getWindow, - scheduleAtNextAnimationFrame, -} from "../../base/browser/dom.js"; -import { KeyCode, KeyMod } from "../../base/common/keyCodes.js"; -import type { ICodeEditor } from "../../editor/browser/editorBrowser.js"; -import { ICodeEditorService } from "../../editor/browser/services/codeEditorService.js"; -import { SymbolNavigationAnchor } from "../../editor/contrib/gotoSymbol/browser/goToCommands.js"; -import { EditorContextKeys } from "../../editor/common/editorContextKeys.js"; -import { Position } from "../../editor/common/core/position.js"; -import { CommandsRegistry, ICommandService } from "../../platform/commands/common/commands.js"; -import { ContextKeyExpr, RawContextKey } from "../../platform/contextkey/common/contextkey.js"; -import { - KeybindingsRegistry, - KeybindingWeight, -} from "../../platform/keybinding/common/keybindingsRegistry.js"; -import type { IEditorOptions } from "../../platform/editor/common/editor.js"; -import { IHistoryService } from "../../workbench/services/history/common/history.js"; -import { - EditorPaneSelectionCompareResult, - type IEditorPaneSelection, -} from "../../workbench/common/editor.js"; - -export const WhiteboardEmbeddedEditorFocus = new RawContextKey( - "whiteboardEmbeddedEditorFocus", - false, -); - -const whiteboardEmbeddedEditors = new WeakSet(); - -export interface WhiteboardEmbeddedNavigationLocation { - readonly view: "review" | "diff"; - readonly path: string; - readonly side: "base" | "head"; - readonly lineNumber: number; - readonly column: number; - readonly section?: string; -} - -interface WhiteboardEmbeddedEditorOptions extends IEditorOptions { - readonly whiteboardEmbeddedSelection?: WhiteboardEmbeddedEditorSelection; -} - -export function markWhiteboardEmbeddedEditor(editor: ICodeEditor): IDisposable { - whiteboardEmbeddedEditors.add(editor); - const focus = WhiteboardEmbeddedEditorFocus.bindTo(editor.contextKeyService); - focus.set(true); - return { - dispose: () => { - whiteboardEmbeddedEditors.delete(editor); - focus.reset(); - }, - }; -} - -export class WhiteboardEmbeddedEditorSelection implements IEditorPaneSelection { - constructor( - readonly editor: ICodeEditor, - readonly location: WhiteboardEmbeddedNavigationLocation, - ) {} - - compare(other: IEditorPaneSelection): EditorPaneSelectionCompareResult { - if (!(other instanceof WhiteboardEmbeddedEditorSelection)) { - return EditorPaneSelectionCompareResult.DIFFERENT; - } - const left = this.location; - const right = other.location; - return left.view === right.view && - left.path === right.path && - left.side === right.side && - left.lineNumber === right.lineNumber && - left.column === right.column && - left.section === right.section - ? EditorPaneSelectionCompareResult.IDENTICAL - : EditorPaneSelectionCompareResult.DIFFERENT; - } - - restore(options: IEditorOptions): IEditorOptions { - return { - ...options, - whiteboardEmbeddedSelection: this, - } as WhiteboardEmbeddedEditorOptions; - } - - restoreInCanvas(): boolean { - const domNode = this.editor.getDomNode(); - if (!domNode?.isConnected || !this.editor.hasModel()) return false; - const restore = () => { - const position = new Position( - this.location.lineNumber, - this.location.column, - ); - const section = domNode.closest("[data-whiteboard-section]"); - section?.dispatchEvent(new CustomEvent("whiteboard-section-expand")); - domNode.scrollIntoView({ block: "center", inline: "nearest" }); - this.editor.setPosition(position, "review.navigationHistory"); - this.editor.revealPositionInCenterIfOutsideViewport(position); - this.editor.focus(); - }; - restore(); - scheduleAtNextAnimationFrame(getWindow(domNode), restore); - return true; - } - - log(): string { - const location = this.location; - return `${location.view}:${location.side}:${location.path}:${location.lineNumber}:${location.column}`; - } -} - -export function whiteboardEmbeddedSelectionFromOptions( - options: IEditorOptions | undefined, -): WhiteboardEmbeddedEditorSelection | undefined { - return (options as WhiteboardEmbeddedEditorOptions | undefined) - ?.whiteboardEmbeddedSelection; -} - -const goToDefinitionCommand = "review.action.embeddedGoToDefinition"; -const showReferencesCommand = "review.action.embeddedShowReferences"; - -CommandsRegistry.registerCommand(goToDefinitionCommand, (accessor) => { - runEmbeddedSymbolCommand( - accessor.get(ICodeEditorService), - accessor.get(IHistoryService), - accessor.get(ICommandService), - "editor.action.revealDefinition", - true, - ); -}); -CommandsRegistry.registerCommand(showReferencesCommand, (accessor) => { - runEmbeddedSymbolCommand( - accessor.get(ICodeEditorService), - accessor.get(IHistoryService), - accessor.get(ICommandService), - "editor.action.referenceSearch.trigger", - false, - ); -}); - -KeybindingsRegistry.registerKeybindingRule({ - id: goToDefinitionCommand, - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyCode.F12, - when: ContextKeyExpr.and( - WhiteboardEmbeddedEditorFocus, - EditorContextKeys.editorTextFocus, - ), -}); -KeybindingsRegistry.registerKeybindingRule({ - id: showReferencesCommand, - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyMod.Shift | KeyCode.F12, - when: ContextKeyExpr.and( - WhiteboardEmbeddedEditorFocus, - EditorContextKeys.editorTextFocus, - ), -}); - -function runEmbeddedSymbolCommand( - codeEditorService: ICodeEditorService, - historyService: IHistoryService, - commandService: ICommandService, - commandId: string, - recordsHistory: boolean, -): void { - const editor = codeEditorService.getActiveCodeEditor(); - if (!editor || !whiteboardEmbeddedEditors.has(editor) || !editor.hasModel()) return; - const model = editor.getModel(); - const position = editor.getPosition(); - editor.focus(); - if (recordsHistory) { - historyService.addActiveEditorNavigation(); - } - void commandService.executeCommand( - commandId, - new SymbolNavigationAnchor(model, position), - ); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardFilesDiffView.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardFilesDiffView.ts deleted file mode 100644 index ee5807429..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardFilesDiffView.ts +++ /dev/null @@ -1,629 +0,0 @@ -import type { WhiteboardDiffProgress, WhiteboardDiffLens, WhiteboardDiffViewSpec } from "../common/whiteboardProtocol.js"; -import { Range } from "../../editor/common/core/range.js"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import "../browser/media/whiteboard.css"; -import { $, append, Dimension } from "../../base/browser/dom.js"; -import { Orientation, SplitView } from "../../base/browser/ui/splitview/splitview.js"; -import { Emitter, Event } from "../../base/common/event.js"; -import { Disposable, toDisposable } from "../../base/common/lifecycle.js"; -import { autorun } from "../../base/common/observable.js"; -import { isEqual } from "../../base/common/resources.js"; -import { URI } from "../../base/common/uri.js"; -import { ElementSizeObserver } from "../../editor/browser/config/elementSizeObserver.js"; -import type { IDiffEditor } from "../../editor/browser/editorBrowser.js"; -import { MultiDiffEditorViewModel } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorViewModel.js"; -import { MultiDiffEditorWidget } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorWidget.js"; -import type { IMultiDiffEditorViewState } from "../../editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl.js"; -import { IDiffEditorOptions } from "../../editor/common/config/editorOptions.js"; -import { ITextModelService } from "../../editor/common/services/resolverService.js"; -import { ITextResourceConfigurationService } from "../../editor/common/services/textResourceConfiguration.js"; -import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; -import { MultiDiffEditorInput } from "../../workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.js"; -import { - IMultiDiffSourceResolverService, - MultiDiffEditorItem, -} from "../../workbench/contrib/multiDiffEditor/browser/multiDiffSourceResolverService.js"; -import { IEditorGroupsService } from "../../workbench/services/editor/common/editorGroupsService.js"; -import { IEditorService } from "../../workbench/services/editor/common/editorService.js"; -import { ITextFileService } from "../../workbench/services/textfile/common/textfiles.js"; -import { WhiteboardChangedFilesTree } from "../browser/whiteboardChangedFilesTree.js"; -import { type WhiteboardDiffFileWire, type StructuralLineCounts } from "../common/whiteboardProtocol.js"; -import type { WhiteboardDiffLayoutSetting } from "./whiteboardDiffLayout.js"; -import { whiteboardMultiDiffLabelUris, WhiteboardMultiDiffUIElementFactory } from "./whiteboardMultiDiff.js"; - -const FILE_TREE_MINIMUM_WIDTH = 180; -const DIFF_MINIMUM_WIDTH = 320; -const FILE_TREE_COLLAPSE_WIDTH = FILE_TREE_MINIMUM_WIDTH + DIFF_MINIMUM_WIDTH; -const WHITEBOARD_FILES_DIFF_EDITOR_OPTIONS = { - hideUnchangedRegions: { enabled: true }, - originalEditable: false, - readOnly: true, - glyphMargin: false, - lineNumbersMinChars: 3, - // A peek or diff on the page is read until it is clicked into; the current - // line highlight belongs to the cursor, not to the first revealed line. - renderLineHighlightOnlyWhenFocus: true, -} satisfies IDiffEditorOptions; - -export interface WhiteboardFilesEditorEntry { - readonly sectionId?: string; - readonly sectionStart?: boolean; - readonly file: WhiteboardDiffFileWire; - readonly original: URI | undefined; - readonly modified: URI | undefined; - readonly goToFileResource: URI; -} - -export class WhiteboardFilesEditorInput extends MultiDiffEditorInput { - static override readonly ID = "workbench.input.devfast.whiteboardFiles"; - static readonly EDITOR_ID = "workbench.editor.devfast.whiteboardFiles"; - - private readonly updateResources: (paths: ReadonlySet, loading: boolean) => void; - - setReadyFiles(paths: ReadonlySet, loading: boolean): void { - this.updateResources(paths, loading); - } - - constructor( - source: URI, - readonly entries: readonly WhiteboardFilesEditorEntry[], - readonly structural: boolean = false, - lens: boolean = false, - @ITextModelService textModelService: ITextModelService, - @ITextResourceConfigurationService - textResourceConfigurationService: ITextResourceConfigurationService, - @IInstantiationService instantiationService: IInstantiationService, - @IMultiDiffSourceResolverService - multiDiffSourceResolverService: IMultiDiffSourceResolverService, - @ITextFileService textFileService: ITextFileService, - ) { - const items = entries.map( - (entry) => - new MultiDiffEditorItem( - entry.original, - entry.modified, - entry.goToFileResource, - undefined, - undefined, - whiteboardMultiDiffLabelUris(entry.file), - // Every hidden line comes from the one fold model: diffr's regions, never the diff editor's own unchanged-region hiding. - // Every collapsed region diffr sends is a hidden-region band; the editor's own folding stays off. - (structural || lens) - ? { - ...WHITEBOARD_FILES_DIFF_EDITOR_OPTIONS, - hideOriginalLineNumbers: entry.file.status === "added", - hideUnchangedRegions: { - enabled: true, - minimumLineCount: 1, - contextLineCount: 0, - }, - folding: false, - glyphMargin: true, - experimental: { useTrueInlineView: false }, - } - : { ...WHITEBOARD_FILES_DIFF_EDITOR_OPTIONS, hideOriginalLineNumbers: entry.file.status === "added" }, - ), - ); - const changes = new Emitter(); - let current: readonly MultiDiffEditorItem[] = []; - let loading = items.length > 0; - const streamSource = { - isLoading: { get value() { return loading; }, onDidChange: changes.event }, - resources: { - get value() { - return current; - }, - onDidChange: changes.event, - }, - }; - super( - source, - "Files", - structural ? undefined : items, - true, - textModelService, - textResourceConfigurationService, - instantiationService, - structural - ? { - _serviceBrand: undefined, - registerResolver: (resolver) => - multiDiffSourceResolverService.registerResolver(resolver), - resolve: async () => streamSource, - } - : multiDiffSourceResolverService, - textFileService, - ); - this._register(changes); - this.updateResources = (paths, pending) => { - loading = pending; current = items.filter((_, index) => paths.has(entries[index].file.path)); - changes.fire(); - }; - } - - override get typeId(): string { - return WhiteboardFilesEditorInput.ID; - } - - override get editorId(): string { - return WhiteboardFilesEditorInput.EDITOR_ID; - } -} - -/** - * The changed-files diff UI — a file list beside a multi-diff widget — as a - * plain widget. It owns no editor pane, so the Review canvas can mount it into - * a container the app supplies. The container's size drives the layout: the - * canvas gives the host element its bounds through CSS, not through a pane - * layout call. - */ -export class WhiteboardFilesDiffView extends Disposable { - private readonly _onDidChangeActiveControl = this._register(new Emitter()); - readonly onDidChangeActiveControl = this._onDidChangeActiveControl.event; - private readonly _onDidScroll = this._register(new Emitter()); - /** The list scrolled or its topmost file changed. */ - readonly onDidScroll = this._onDidScroll.event; - private readonly diffContainer: HTMLElement; - - private readonly root: HTMLElement; - private readonly splitView: SplitView; - private readonly changedFilesTree: WhiteboardChangedFilesTree | undefined; - private readonly widget: MultiDiffEditorWidget; - private viewModel: MultiDiffEditorViewModel | undefined; - private input: WhiteboardFilesEditorInput | undefined; - private readonly readyFiles = new Set(); - private readonly fileStates = new Map(); - /** Full structural counts for views without persisted coverage. */ - private readonly streamStats = new Map< - string, - { counts: StructuralLineCounts; title: string } - >(); - private readonly headerFactory: WhiteboardMultiDiffUIElementFactory; - private readonly summary: HTMLElement; - /** Files the stream says start hidden, with the reason shown in their header. */ - private readonly hiddenFiles = new Map(); - private readonly hiddenApplied = new Set(); - private pendingPath: string | undefined; - private pendingSectionId: string | undefined; - private pendingSource: WhiteboardDiffLens["ranges"][number] | undefined; - private progress: WhiteboardDiffProgress | undefined; - private documentCollapsed = false; - private readonly initializedDocumentItems = new WeakSet(); - private readonly viewedApplied = new Map(); - private readonly streamStatus: HTMLElement; - - constructor( - private readonly container: HTMLElement, - overflowWidgetsDomNode: HTMLElement | undefined, - layout: WhiteboardDiffLayoutSetting, - private readonly fileTreeContainer: HTMLElement | undefined, - private readonly onToggleViewed: ((path: string, sectionId?: string) => void) | undefined, - private readonly onToggleSection: ((id: string) => void) | undefined, - private readonly document: WhiteboardDiffViewSpec["document"], - @IInstantiationService - private readonly whiteboardInstantiationService: IInstantiationService, - @IEditorService private readonly editorService: IEditorService, - @IEditorGroupsService - private readonly editorGroupService: IEditorGroupsService, - ) { - super(); - this.root = append(container, $(".whiteboard-files-editor")); - const fileTree = document ? container.ownerDocument.createElement("div") : append(this.fileTreeContainer ?? this.root, $(".whiteboard-files-editor-tree")); - const diffContainer = append(this.root, $(".whiteboard-files-editor-diffs")); - this.diffContainer = diffContainer; - if (document) fileTree.hidden = true; - - const factory = this.whiteboardInstantiationService.createInstance( - WhiteboardMultiDiffUIElementFactory, - () => - this.input - ? this.input.entries.map((entry) => ({ - original: entry.original, - modified: entry.modified, - additions: entry.file.status === "unchanged" ? undefined : this.entryProgress(entry)?.remaining.additions ?? (this.fileTreeContainer || this.document ? undefined : this.streamStats.get(entry.file.path)?.counts.added), - deletions: entry.file.status === "unchanged" ? undefined : this.entryProgress(entry)?.remaining.deletions ?? (this.fileTreeContainer || this.document ? undefined : this.streamStats.get(entry.file.path)?.counts.removed), - countsTitle: this.progressTitle(entry) ?? this.streamStats.get(entry.file.path)?.title, - viewedState: this.entryProgress(entry)?.state, - onToggleViewed: entry.file.status !== "unchanged" && this.onToggleViewed ? () => this.onToggleViewed!(entry.file.path, entry.sectionId) : undefined, - sectionId: entry.sectionId, - sectionCollapsed: !!entry.sectionId && this.collapsedSections.has(entry.sectionId), - onToggleSectionCollapsed: () => { if (entry.sectionId) { if (this.collapsedSections.has(entry.sectionId)) this.collapsedSections.delete(entry.sectionId); else this.collapsedSections.add(entry.sectionId); this.headerFactory.refreshHeaders(); } }, - section: entry.sectionStart ? this.progress?.sections?.find(section => section.id === entry.sectionId) : undefined, - onToggleSection: () => entry.sectionId && this.onToggleSection?.(entry.sectionId), - note: entry.file.status === "unchanged" ? "Unchanged" : this.hiddenFiles.get(entry.file.path), - onDidOpen: () => { - if (document?.onDidOpen) { document.onDidOpen(); return; } - void this.editorService.openEditor( - { - resource: entry.goToFileResource, - options: { pinned: true, revealIfVisible: true }, - }, - this.editorGroupService.mainPart.activeGroup, - ); - }, - })) - : [], - "auto", - // Hover and definition widgets must escape the canvas root, whose - // container-query containment clips position: fixed descendants. - overflowWidgetsDomNode, - false, - undefined, - ); - this.headerFactory = factory; - - this.widget = this._register( - this.whiteboardInstantiationService.createInstance(MultiDiffEditorWidget, diffContainer, factory, undefined), - ); - // The widget's own switch, not the per-item option refresh: it pins the - // width heuristic off, so the chosen layout is what renders at any width. - const applyLayout = () => this.widget.setRenderSideBySide(!document && layout.get() === "split"); - this._register(layout.onDidChange(applyLayout)); - applyLayout(); - if (document) { - this._register(this.widget.onDidChangeContentHeight(() => { - const height = Math.max(40, this.widget.getContentHeight()); - document.onDidChangeHeight(document.heightMode === "capped" ? Math.min(400, height) : height); - })); - } - this.streamStatus = append(diffContainer, - $(".whiteboard-structural-stream-status")); - this.streamStatus.setAttribute("role", "status"); - this.streamStatus.hidden = true; - this._register(this.widget.onDidChangeActiveControl(() => this._onDidChangeActiveControl.fire())); - this._register(this.widget.onDidScroll(() => this._onDidScroll.fire())); - this._register(this.widget.onDidChangeActiveItem(() => this.syncFileSelectionFromWidget())); - this.summary = append(fileTree, $(".whiteboard-files-editor-summary")); - this.summary.hidden = true; - this.changedFilesTree = document ? undefined : this._register( - this.whiteboardInstantiationService.createInstance(WhiteboardChangedFilesTree, fileTree), - ); - if (this.changedFilesTree) this._register( - this.changedFilesTree.onDidOpenFile((file) => { - const element = this.input?.entries.find((entry) => entry.file.path === file.path); - if (!element) return; - if (this.fileStates.has(file.path)) { - this.pendingPath = file.path; - this.showStreamStatus(); - return; - } - this.pendingPath = undefined; - this.showStreamStatus(); - this.reveal({ - original: element.original, - modified: element.modified, - }); - }), - ); - this.splitView = this._register( - new SplitView(this.root, { - orientation: Orientation.HORIZONTAL, - proportionalLayout: true, - }), - ); - if (!this.fileTreeContainer && !document) this.splitView.addView( - { - element: fileTree, - layout: (width, _offset, height) => { - fileTree.style.width = `${width}px`; - this.changedFilesTree?.layout((height ?? 0) - - (this.summary.hidden ? 0 : this.summary.offsetHeight), width, - ); - }, - maximumSize: 380, - minimumSize: FILE_TREE_MINIMUM_WIDTH, - onDidChange: Event.None, - }, - 260, - ); - this.splitView.addView( - { - element: diffContainer, - layout: (width, _offset, height) => { - diffContainer.style.width = `${width}px`; - this.widget.layout(new Dimension(width, height ?? 0)); - }, - maximumSize: Number.POSITIVE_INFINITY, - minimumSize: DIFF_MINIMUM_WIDTH, - onDidChange: Event.None, - }, - 740, - ); - - if (this.fileTreeContainer) { - const treeSize = this._register(new ElementSizeObserver(this.fileTreeContainer, undefined)); - this._register(treeSize.onDidChange(() => this.layout())); - treeSize.startObserving(); - this._register(toDisposable(() => fileTree.remove())); - } - const sizeObserver = this._register(new ElementSizeObserver(this.container, undefined)); - this._register(sizeObserver.onDidChange(() => this.layout())); - sizeObserver.startObserving(); - this.layout(); - // Registered last so it runs last: the widgets above tear their own DOM - // down, and they must do that while the tree is still attached. - this._register(toDisposable(() => this.root.remove())); - } - - async setInput(input: WhiteboardFilesEditorInput, viewState: IMultiDiffEditorViewState | undefined): Promise { - this.input = input; - this.changedFilesTree?.setFiles(Array.from(new Map(input.entries.map(entry => [entry.file.path, entry.file])).values())); - const viewModel = await input.getViewModel(); - if (this._store.isDisposed) return; - this.viewModel = viewModel; - // The canvas mounts this view without a user gesture, so the widget's - // first-change navigation must never take keyboard focus. - this.widget.setViewModel(viewModel, { preserveFocus: true, viewState, initialScrollPosition: this.document ? "top" : "firstChange" }); - this.changedFilesTree?.setFiles(Array.from(new Map(input.entries.map(entry => [entry.file.path, entry.file])).values())); - this.syncFileSelectionFromWidget(); - this._register( - autorun((reader) => { - const items = viewModel.items.read(reader); - if (this.document) for (const item of items) { - if (this.initializedDocumentItems.has(item)) continue; - this.initializedDocumentItems.add(item); - item.collapsed.set(this.documentCollapsed, undefined); - } - this.applyHiddenFiles(items); - this.applyViewedFiles(); - const entry = this.input?.entries.find( - (e) => e.file.path === this.pendingPath, - ); - if (!entry || !this.readyFiles.has(entry.file.path)) return; - if ( - !items.some( - (item) => - sameResource(item.originalUri, entry.original) && - sameResource(item.modifiedUri, entry.modified), - ) - ) - return; - this.pendingPath = undefined; - this.showStreamStatus(); - queueMicrotask(() => { - if (!this._store.isDisposed) { if (this.pendingSource) this.revealSource(this.pendingSource, this.pendingSectionId); else this.reveal(entry); } - }); - }), - ); - } - - startLoading(entries: readonly WhiteboardFilesEditorEntry[]): void { - this.changedFilesTree?.setFiles(Array.from(new Map(entries.map(entry => [entry.file.path, entry.file])).values())); - for (const entry of entries) { - this.fileStates.set(entry.file.path, "Loading diff…"); - this.changedFilesTree?.setFileState(entry.file.path, "loading"); - } - this.showStreamStatus(); - } - - fileLoaded( - path: string, - error?: string, - ): void { - if (error) { - this.fileStates.set(path, error); - this.changedFilesTree?.setFileState(path, "error", error); - } else { - this.fileStates.delete(path); - this.readyFiles.add(path); - this.changedFilesTree?.setFileState(path, undefined); - } - this.input?.setReadyFiles(this.readyFiles, [...this.fileStates.values()].some(state => state === "Loading diff…")); - this.showStreamStatus(); - } - - /** Coverage counts are independent of fold state. */ - fileCounts(path: string, counts: StructuralLineCounts): void { - this.streamStats.set(path, { - counts, - title: `Changes +${counts.added} −${counts.removed}`, - }); - if (!this.fileTreeContainer) this.changedFilesTree?.setCounts(path, counts); - this.headerFactory.refreshHeaders(); - this.renderSummary(); - } - - private renderSummary(): void { - if (this.fileTreeContainer) return; - const paths = new Set((this.input?.entries ?? []).map(entry => entry.file.path)); - const complete = [...paths].every(path => this.streamStats.has(path)); - const total = { added: 0, removed: 0 }; - for (const path of paths) { - const counts = this.streamStats.get(path)?.counts; - if (counts) { total.added += counts.added; total.removed += counts.removed; } - } - this.summary.replaceChildren(); - const files = append(this.summary, $("span.review-files-editor-summary-files")); - files.textContent = `${paths.size} files`; - if (complete) { - const format = new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }); - append(this.summary, $("span.whiteboard-files-editor-summary-added")).textContent = `+${format.format(total.added).toLowerCase()}`; - append(this.summary, $("span.whiteboard-files-editor-summary-removed")).textContent = `−${format.format(total.removed).toLowerCase()}`; - } else append(this.summary, $("span")).textContent = "Counting changes…"; - this.summary.title = complete ? `Changes +${total.added} −${total.removed}` : "Waiting for structural coverage"; - const wasHidden = this.summary.hidden; - this.summary.hidden = false; - if (wasHidden) this.layout(); - } - - /** A file the stream says starts collapsed, and why: its record's `visibility`. */ - hideFile(path: string, label: string): void { - this.hiddenFiles.set(path, label); - this.headerFactory.refreshHeaders(); - if (this.viewModel) this.applyHiddenFiles(this.viewModel.items.get()); - } - - /** GitHub's shape for a hidden file: the header stays, the body waits for a click. */ - private applyHiddenFiles( - items: readonly { - originalUri: URI | undefined; - modifiedUri: URI | undefined; - collapsed: { set(value: boolean, tx: undefined): void }; - }[], - ): void { - for (const entry of this.input?.entries ?? []) { - if ( - !this.hiddenFiles.has(entry.file.path) || - this.hiddenApplied.has(entry.file.path) - ) - continue; - const item = items.find( - (item) => - sameResource(item.originalUri, entry.original) && - sameResource(item.modifiedUri, entry.modified), - ); - if (!item) continue; - item.collapsed.set(true, undefined); - this.hiddenApplied.add(entry.file.path); - } - } - - private readonly collapsedSections = new Set(); - private readonly sectionViewed = new Map(); - private entryProgress(entry: WhiteboardFilesEditorEntry) { - return (entry.sectionId ? this.progress?.sections?.find(section => section.id === entry.sectionId)?.files : this.progress?.files)?.find(file => file.path === entry.file.path); - } - private progressTitle(entry: WhiteboardFilesEditorEntry): string | undefined { - const file = this.entryProgress(entry); - return file ? `Remaining +${file.remaining.additions} −${file.remaining.deletions} · Total +${file.total.additions} −${file.total.deletions}` : undefined; - } - setProgress(progress: WhiteboardDiffProgress): void { - this.progress = progress; - for (const section of progress.sections ?? []) { - const previous = this.sectionViewed.get(section.id); - if (section.state === 'viewed' && previous !== 'viewed') this.collapsedSections.add(section.id); - else if (previous === 'viewed' && section.state !== 'viewed') this.collapsedSections.delete(section.id); - this.sectionViewed.set(section.id, section.state); - } - - this.changedFilesTree?.setProgressFiles(progress.files); - this.headerFactory.refreshHeaders(); - this.applyViewedFiles(); - } - private applyViewedFiles(): void { - for (const entry of this.input?.entries ?? []) { - const file = this.entryProgress(entry); - if (!file) continue; - const key = `${entry.sectionId ?? ''}:${file.path}`; - const previous = this.viewedApplied.get(key); - if (previous === file.state) continue; - const item = this.viewModel?.items.get().find(item => sameResource(item.originalUri, entry.original) && sameResource(item.modifiedUri, entry.modified)); - if (!item) continue; - if (file.state === 'viewed') item.collapsed.set(true, undefined); - else if (previous === 'viewed' || this.progress?.changedPaths?.includes(file.path)) item.collapsed.set(false, undefined); - this.viewedApplied.set(key, file.state); - } - } - revealSource(source: WhiteboardDiffLens['ranges'][number], sectionId?: string): void { - const entry = this.input?.entries.find(entry => (!sectionId || entry.sectionId === sectionId) && (!entry.sectionId || this.progress?.sections?.find(section => section.id === entry.sectionId)?.sources.some(range => range.file === source.file && range.side === source.side && range.fromLine <= source.fromLine && range.toLine >= source.fromLine)) && source.file === (source.side === 'base' ? entry.file.previousPath ?? entry.file.path : entry.file.path)); - if (!entry) return; - if (entry.sectionId && this.collapsedSections.delete(entry.sectionId)) this.headerFactory.refreshHeaders(); - this.pendingSource = source; this.pendingSectionId = sectionId; - if (this.fileStates.has(entry.file.path)) { this.pendingPath = entry.file.path; return; } - this.viewModel?.items.get().find(item => sameResource(item.originalUri, entry.original) && sameResource(item.modifiedUri, entry.modified))?.collapsed.set(false, undefined); - this.widget.reveal(entry, { highlight: true, side: source.side === 'base' ? 'original' : 'modified', range: new Range(source.fromLine, 1, source.toLine, 1) }); - this.pendingSource = undefined; - } - - get viewportHeight(): number { return this.diffContainer.clientHeight; } - - /** - * Pixels from the reading line (the list's top edge) to the first line of - * `source`, negative once scrolled past. Rendered files measure their - * editor; the rest are placed by file order around the topmost file, a - * million pixels per file, which keeps them sorted and on the right side. - */ - sourceOffset(source: WhiteboardDiffLens['ranges'][number]): number | undefined { - const entries = this.input?.entries ?? []; - const pathOf = (entry: (typeof entries)[number]) => source.side === 'base' ? entry.file.previousPath ?? entry.file.path : entry.file.path; - const index = entries.findIndex(entry => pathOf(entry) === source.file); - if (index < 0) return undefined; - const entry = entries[index]!; - const resource = source.side === 'base' ? entry.original : entry.modified; - const editor = resource && this.widget.tryGetCodeEditor(resource)?.editor; - const node = editor?.getDomNode(); - if (editor && node) { - return node.getBoundingClientRect().top - this.diffContainer.getBoundingClientRect().top - + editor.getTopForLineNumber(source.fromLine) - editor.getScrollTop(); - } - const active = this.viewModel?.activeDiffItem.get(); - const activeIndex = active ? entries.findIndex(e => sameResource(active.modifiedUri, e.modified) && sameResource(active.originalUri, e.original)) : 0; - return (index - Math.max(0, activeIndex)) * 1_000_000 + source.fromLine; - } - - loadingFailed(message: string): void { - for (const [path, state] of this.fileStates) - if (state === "Loading diff…") this.fileLoaded(path, message); - this.showStreamStatus(); - } - - private showStreamStatus(): void { - const message = this.pendingPath - ? this.fileStates.get(this.pendingPath) - : undefined; - this.streamStatus.hidden = - (!message && this.readyFiles.size > 0) || this.fileStates.size === 0; - this.streamStatus.textContent = message - ? `${this.pendingPath}: ${message}` - : this.readyFiles.size === 0 - ? ([...this.fileStates.values()][0] ?? "") - : ""; - this.streamStatus.classList.toggle( - "loading", - [...this.fileStates.values()].some((s) => s === "Loading diff…"), - ); - } - - getViewState(): IMultiDiffEditorViewState | undefined { - return this.viewModel ? this.widget.getViewState() : undefined; - } - - getActiveControl(): IDiffEditor | undefined { - return this.widget.getActiveControl(); - } - - setCollapsed(collapsed: boolean): void { - this.documentCollapsed = collapsed; - for (const item of this.viewModel?.items.get() ?? []) item.collapsed.set(collapsed, undefined); - } - - focus(): void { - this.widget.getActiveControl()?.focus(); - } - - layout(): void { - const width = this.container.clientWidth; - const height = this.container.clientHeight; - if (width <= 0 || height <= 0) return; - - const fileTreeVisible = !this.fileTreeContainer && width >= FILE_TREE_COLLAPSE_WIDTH; - if (!this.fileTreeContainer && !this.document && this.splitView.isViewVisible(0) !== fileTreeVisible) { - this.splitView.setViewVisible(0, fileTreeVisible); - } - - this.splitView.layout(width, height); - if (this.fileTreeContainer) this.changedFilesTree?.layout(this.fileTreeContainer.clientHeight, this.fileTreeContainer.clientWidth); - } - private reveal(resource: { original: URI | undefined; modified: URI | undefined }): void { - this.widget.reveal(resource, { highlight: true }); - } - - private syncFileSelectionFromWidget(): void { - const resource = this.widget.getActiveItem(); - const input = this.input; - if (!resource || !input || this.pendingPath) return; - const index = input.entries.findIndex( - (entry) => sameResource(entry.original, resource.original) && sameResource(entry.modified, resource.modified), - ); - if (index === -1) return; - // Passive editor updates must not move a sidebar the reader scrolled independently. - this.changedFilesTree?.setActiveFile(input.entries[index].file.path, false); - } -} -function sameResource(left: URI | undefined, right: URI | undefined): boolean { - return left === undefined ? right === undefined : !!right && isEqual(left, right); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLanguageEnvironmentRequests.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLanguageEnvironmentRequests.test.ts deleted file mode 100644 index 059e169be..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLanguageEnvironmentRequests.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; -import { WhiteboardLanguageEnvironmentRequests } from "./whiteboardLanguageEnvironmentRequests.js"; -import { withCurrentLocalContext } from "./whiteboardLocalRequest.js"; - -const view = { sessionId: "review", version: 3 }; -const ready = { rootPath: "/project", identity: "first" }; -function deferred() { - let resolve!: (value: T) => void; - const promise = new Promise(done => { resolve = done; }); - return { promise, resolve }; -} - -test("simultaneous providers share one environment lookup across source refresh tokens", async () => { - const requests = new WhiteboardLanguageEnvironmentRequests(); - const response = deferred(); - let count = 0; - const load = () => { count++; return response.promise; }; - const wave = Array.from({ length: 20 }, (_, index) => requests.read("session", { ...view, generation: String(index) }, "head", load)); - await Promise.resolve(); - assert.equal(count, 1); - response.resolve(ready); - assert.deepEqual(await Promise.all(wave), Array(20).fill(ready)); - await requests.read("session", view, "head", load); - assert.equal(count, 2, "completed lookups are revalidated until lifecycle events are authoritative"); -}); - -test("a post-query check never joins an HTTP request that started before the provider finished", async () => { - const requests = new WhiteboardLanguageEnvironmentRequests(); - const first = deferred(); - const next = deferred(); - let count = 0; - const load = () => ++count === 1 ? first.promise : next.promise; - const before = requests.read("session", view, "head", load); - await Promise.resolve(); - const validations = Array.from({ length: 10 }, () => requests.read("session", view, "head", load, true)); - await Promise.resolve(); - assert.equal(count, 2); - first.resolve(ready); - assert.deepEqual(await before, ready); - next.resolve({ ...ready, identity: "replaced" }); - assert.ok((await Promise.all(validations)).every(result => result?.identity === "replaced")); -}); - -test("sessions, authored versions, sides and selected commits never share lookups", async () => { - const requests = new WhiteboardLanguageEnvironmentRequests(); - let count = 0; - const load = async () => ({ ...ready, identity: String(++count) }); - const results = await Promise.all([ - requests.read("one", view, "head", load), - requests.read("two", view, "head", load), - requests.read("one", { ...view, version: 4 }, "head", load), - requests.read("one", view, "base", load), - requests.read("one", { ...view, commit: "selected" }, "head", load), - requests.read("one", { ...view, sessionId: "other" }, "head", load), - ]); - assert.equal(new Set(results.map(result => result?.identity)).size, 6); -}); - -test("unavailable and failed lookups recover on the next query", async () => { - const requests = new WhiteboardLanguageEnvironmentRequests(); - assert.equal(await requests.read("session", view, "head", async () => undefined), undefined); - await assert.rejects(requests.read("session", view, "head", async () => { throw new Error("offline"); }), /offline/); - assert.deepEqual(await requests.read("session", view, "head", async () => ready), ready); -}); - -test("disconnect discards a pending response and a delayed provider even when identity is unchanged", async () => { - const requests = new WhiteboardLanguageEnvironmentRequests(); - const response = deferred(); - const pending = requests.read("session", view, "head", () => response.promise); - await Promise.resolve(); - const provider = deferred(); - const result = withCurrentLocalContext([{ getVersionId: () => 1, isDisposed: () => false }], { isCancellationRequested: false }, () => requests.generation, () => provider.promise); - requests.invalidate(); - response.resolve(ready); - provider.resolve("stale hover"); - assert.equal(await pending, undefined); - assert.equal(await result, undefined); - assert.deepEqual(await requests.read("session", view, "head", async () => ready), ready); -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLanguageEnvironmentRequests.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLanguageEnvironmentRequests.ts deleted file mode 100644 index 9faea970d..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLanguageEnvironmentRequests.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { WhiteboardLanguageEnvironment, WhiteboardSourceView } from "../common/whiteboardProtocol.js"; - -/** In-flight reuse only: the event channel does not yet order environment changes. */ -export class WhiteboardLanguageEnvironmentRequests { - private readonly pending = new Map }>(); - private epoch = 0; - - get generation(): number { return this.epoch; } - - invalidate(): void { - this.epoch++; - this.pending.clear(); - } - - read(session: string, view: WhiteboardSourceView, side: string, load: () => Promise, validate = false): Promise { - // Source generations separate display models, not language environments. - const key = JSON.stringify([session, view.sessionId, view.version, side, view.commit]); - const cached = this.pending.get(key); - // Post-provider validation must start AFTER that provider finished. A queued - // request can coalesce a wave of validations; an already-started one cannot. - if (cached && (!validate || !cached.started)) return cached.promise; - const epoch = this.epoch; - const entry = { started: false, promise: undefined! as Promise }; - entry.promise = Promise.resolve().then(async () => { - entry.started = true; - if (epoch !== this.epoch) return undefined; - const result = await load(); - return epoch === this.epoch ? result : undefined; - }).finally(() => { - if (this.pending.get(key) === entry) this.pending.delete(key); - }); - this.pending.set(key, entry); - return entry.promise; - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLens.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLens.ts deleted file mode 100644 index 616b4152a..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLens.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ -import { isDisposable, type DisposableStore } from '../../base/common/lifecycle.js'; -import { IDiffProviderFactoryService } from '../../editor/browser/widget/diffEditor/diffProviderFactoryService.js'; -import { IInstantiationService } from '../../platform/instantiation/common/instantiation.js'; -import { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; -import { Event } from '../../base/common/event.js'; -import { alignmentRows, lensContextGaps, viewedContextGaps } from '../common/whiteboardLens.js'; -import type { WhiteboardDiffLens, WhiteboardDiffProgress } from '../common/whiteboardProtocol.js'; -import type { WhiteboardFilesEditorEntry } from './whiteboardFilesDiffView.js'; - -export function lensRanges(lens: WhiteboardDiffLens, entry: WhiteboardFilesEditorEntry): WhiteboardDiffLens['ranges'] { - return lens.ranges.filter(range => range.file === (range.side === 'base' ? entry.file.previousPath ?? entry.file.path : entry.file.path)); -} - -export function withLens(instantiation: IInstantiationService, entries: readonly WhiteboardFilesEditorEntry[], lens: WhiteboardDiffLens | undefined, lifetime: DisposableStore, progress: () => WhiteboardDiffProgress | undefined, onProgress: Event): IInstantiationService { - const delegate = instantiation.invokeFunction(a => a.get(IDiffProviderFactoryService)); - const factory: IDiffProviderFactoryService = { - _serviceBrand: undefined, - createDiffProvider(options) { - const provider = delegate.createDiffProvider(options); - if (isDisposable(provider)) lifetime.add(provider); - let activeEntry: WhiteboardFilesEditorEntry | undefined; - let previousScope: string | undefined; - const scope = () => { - if (!activeEntry) return undefined; - const snapshot = progress(); - const file = snapshot?.files.find(file => file.path === activeEntry!.file.path); - const section = snapshot?.sections?.find(section => section.id === activeEntry!.sectionId); - return JSON.stringify([file?.viewedRanges, file?.changedRanges, file?.unfoldRanges, section?.sources]); - }; - const relevantProgress = Event.filter(onProgress, () => { - const next = scope(); - if (next === previousScope) return false; - previousScope = next; - return true; - }); - return { - onDidChange: Event.any(provider.onDidChange, Event.debounce(relevantProgress, () => undefined, 16)), - async computeDiff(original, modified, options, token) { - let diff = await provider.computeDiff(original, modified, options, token); - const entry = entries.find(entry => entry.original?.toString() === original.uri.toString() || entry.modified?.toString() === modified.uri.toString()); - if (!entry) return diff; - activeEntry = entry; - previousScope = scope(); - // Both filtering and layout must use the same correspondence. Without diffr, - // project Monaco's existing mappings once; do not run a second matching algorithm. - if (!diff.sourceLineAlignment) diff = { ...diff, sourceLineAlignment: alignmentRows(diff, original.getLineCount(), modified.getLineCount()) }; - const file = progress()?.files.find(file => file.path === entry.file.path); - if (file && (!lens || lens.wholeFiles) && !diff.contextGaps) diff = { ...diff, contextGaps: lensContextGaps(diff, original.getLineCount(), modified.getLineCount(), file.changedRanges).map(gap => ({ ...gap, label: 'Unchanged' })) }; - if (file) diff = { ...diff, contextGaps: viewedContextGaps(diff, original.getLineCount(), modified.getLineCount(), file.viewedRanges, file.changedRanges) }; - if (file?.unfoldRanges?.length) diff = { - ...diff, contextGaps: diff.contextGaps?.map(gap => file.unfoldRanges!.some(range => { - const start = range.side === 'base' ? gap.originalStart : gap.modifiedStart; - const count = range.side === 'base' ? gap.originalCount : gap.modifiedCount; - return count > 0 && range.fromLine < start + count && range.toLine >= start; - }) ? { ...gap, collapsed: false } : gap) - }; - const section = progress()?.sections?.find(section => section.id === entry.sectionId); - return lens && !lens.wholeFiles ? { ...diff, contextGaps: lensContextGaps(diff, original.getLineCount(), modified.getLineCount(), lensRanges(section ? { ...lens, ranges: section.sources } : lens, entry)) } : diff; - }, - }; - }, - }; - return lifetime.add(instantiation.createChild(new ServiceCollection([IDiffProviderFactoryService, factory]))); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLensProgress.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLensProgress.test.ts deleted file mode 100644 index 6cc92900b..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLensProgress.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import assert from 'node:assert/strict'; -import test from 'node:test'; -import { Emitter } from '../../base/common/event.js'; -import { DisposableStore } from '../../base/common/lifecycle.js'; -import { URI } from '../../base/common/uri.js'; -import { CancellationToken } from '../../base/common/cancellation.js'; -import type { IDiffProviderFactoryService } from '../../editor/browser/widget/diffEditor/diffProviderFactoryService.js'; -import { IDiffProviderFactoryService as Factory } from '../../editor/browser/widget/diffEditor/diffProviderFactoryService.js'; -import type { IInstantiationService } from '../../platform/instantiation/common/instantiation.js'; -import type { ServiceCollection } from '../../platform/instantiation/common/serviceCollection.js'; -import type { WhiteboardDiffProgress } from '../common/whiteboardProtocol.js'; -import type { WhiteboardFilesEditorEntry } from './whiteboardFilesDiffView.js'; -import { withLens } from './whiteboardLens.js'; - -test('progress invalidates only relevant file ranges and coalesces a burst', async () => { - const store = new DisposableStore(); - const progressChanged = store.add(new Emitter()); - const providerChanged = store.add(new Emitter()); - let factory!: IDiffProviderFactoryService; - const instantiation = { - invokeFunction: (fn: (accessor: { get(): unknown }) => unknown) => fn({ - get: () => ({ - createDiffProvider: () => ({ - onDidChange: providerChanged.event, computeDiff: async () => ({ - changes: [], moves: [], identical: true, quitEarly: false, sourceLineAlignment: [[0, 0]], contextGaps: [], - }) - }), - }) - }), - createChild: (services: ServiceCollection) => { - factory = services.get(Factory) as IDiffProviderFactoryService; - return { dispose() { } }; - }, - } as unknown as IInstantiationService; - const file = (path: string) => ({ - path, state: 'unread' as const, remaining: { additions: 1, deletions: 0 }, - total: { additions: 1, deletions: 0 }, viewedRanges: [], changedRanges: [], - }); - let progress: WhiteboardDiffProgress = { files: [file('a.ts'), file('b.ts')] }; - const original = URI.parse('test:/base/a.ts'), modified = URI.parse('test:/head/a.ts'); - const entry = { original, modified, file: { path: 'a.ts' } } as WhiteboardFilesEditorEntry; - withLens(instantiation, [entry], undefined, store, () => progress, progressChanged.event); - const provider = factory.createDiffProvider({}); - try { - await provider.computeDiff( - { uri: original, getLineCount: () => 1 } as Parameters[0], - { uri: modified, getLineCount: () => 1 } as Parameters[1], - { ignoreTrimWhitespace: false, maxComputationTimeMs: 0, computeMoves: false }, CancellationToken.None, - ); - let invalidations = 0; - store.add(provider.onDidChange(() => invalidations++)); - progress = { files: [file('a.ts'), { ...file('b.ts'), viewedRanges: [{ side: 'head', file: 'b.ts', fromLine: 1, toLine: 1 }] }] }; - progressChanged.fire(); - progress.files[0].remaining.additions = 0; - progressChanged.fire(); - await new Promise(resolve => setTimeout(resolve, 30)); - assert.equal(invalidations, 0, 'other files and counts do not alter this editor’s ranges'); - const notified = new Promise(resolve => { - const sub = provider.onDidChange(() => { sub.dispose(); resolve(); }); - }); - for (const toLine of [1, 2, 3]) { - progress.files[0].viewedRanges = [{ side: 'head', file: 'a.ts', fromLine: 1, toLine }]; - progressChanged.fire(); - } - await notified; - assert.equal(invalidations, 1); - } finally { store.dispose(); } -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalLanguageFeatures.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalLanguageFeatures.ts deleted file mode 100644 index 5d10c3b6f..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalLanguageFeatures.ts +++ /dev/null @@ -1,281 +0,0 @@ -import type { CancellationToken } from "../../base/common/cancellation.js"; -import { Disposable, DisposableStore, type IReference } from "../../base/common/lifecycle.js"; -import { URI } from "../../base/common/uri.js"; -import { Position } from "../../editor/common/core/position.js"; -import type { Hover, LocationLink } from "../../editor/common/languages.js"; -import type { ITextModel } from "../../editor/common/model.js"; -import { ILanguageFeaturesService } from "../../editor/common/services/languageFeatures.js"; -import { IModelService } from "../../editor/common/services/model.js"; -import { ITextModelService, type IResolvedTextEditorModel } from "../../editor/common/services/resolverService.js"; -import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from "../../editor/contrib/gotoSymbol/browser/goToSymbol.js"; -import { getHoversPromise } from "../../editor/contrib/hover/browser/getHover.js"; -import { IFileService } from "../../platform/files/common/files.js"; -import { ILogService } from "../../platform/log/common/log.js"; -import { registerWorkbenchContribution2, WorkbenchPhase } from "../../workbench/common/contributions.js"; -import { IExtensionService } from "../../workbench/services/extensions/common/extensions.js"; -import { ITextFileService } from "../../workbench/services/textfile/common/textfiles.js"; -import { IWorkspaceEditingService } from "../../workbench/services/workspaces/common/workspaceEditing.js"; -import { whiteboardSourceQuery, type WhiteboardLanguageEnvironment } from "../common/whiteboardProtocol.js"; -import { sourceLocation } from "../common/whiteboardSourceView.js"; -import { WHITEBOARD_LANGUAGE_SOURCE_SCHEME } from "../common/whiteboardReadonlySource.js"; -import { WHITEBOARD_API_SOURCE_SCHEME } from "./whiteboardApiSourceService.js"; -import { IWhiteboardDesktopConnectionService } from "./whiteboardDesktopConnectionService.js"; -import { withCurrentLocalContext } from "./whiteboardLocalRequest.js"; -import { acquireWhiteboardLanguageRoot } from "./whiteboardLocalWorkspace.js"; -import { WhiteboardLanguageEnvironmentRequests } from "./whiteboardLanguageEnvironmentRequests.js"; - -interface LocalSource { - identity: string; - root: URI; - reference: IReference; - dispose(): void; -} - -/** Review bytes remain pinned; language queries use the resolved project environment. */ -export class WhiteboardLocalLanguageFeatures extends Disposable { - static readonly ID = "review.localLanguageFeatures"; - private readonly sources = new Map }>(); - private readonly environments = new WhiteboardLanguageEnvironmentRequests(); - private readonly roots = new Map(); - private readonly uncertainRoots = new Set(); - private generation = 0; - - constructor( - @IWhiteboardDesktopConnectionService private readonly connection: IWhiteboardDesktopConnectionService, - @ITextModelService private readonly models: ITextModelService, - @IModelService modelService: IModelService, - @ILanguageFeaturesService private readonly languages: ILanguageFeaturesService, - @IExtensionService private readonly extensions: IExtensionService, - @IWorkspaceEditingService private readonly workspace: IWorkspaceEditingService, - @ITextFileService private readonly textFiles: ITextFileService, - @IFileService private readonly files: IFileService, - @ILogService private readonly log: ILogService, - ) { - super(); - this._register(connection.onDidChangeConnection(() => { - this.environments.invalidate(); - this.generation++; - for (const entry of this.sources.values()) { - this.uncertainRoots.add(URI.file(entry.rootPath).toString()); - void entry.pending.then(source => source?.dispose()); - } - this.sources.clear(); - })); - this._register(files.onDidFilesChange(event => { - if ([...this.roots.keys()].some(root => event.affects(URI.parse(root)))) this.generation++; - })); - // Warm language servers while source is being displayed, not at the first click. - const warm = (model: ITextModel) => { - if ([WHITEBOARD_API_SOURCE_SCHEME, WHITEBOARD_LANGUAGE_SOURCE_SCHEME].includes(model.uri.scheme)) void this.localSource(model); - }; - this._register(modelService.onModelAdded(warm)); - modelService.getModels().forEach(warm); - for (const scheme of [WHITEBOARD_API_SOURCE_SCHEME, WHITEBOARD_LANGUAGE_SOURCE_SCHEME]) { - const selector = { scheme, exclusive: true }; - this._register(languages.hoverProvider.register(selector, { provideHover: (model, position, token) => this.hover(model, position, token) })); - this._register(languages.definitionProvider.register(selector, { provideDefinition: (model, position, token) => this.locations(model, position, token, "definition") })); - } - // Unified hover/definition already delegate to the pinned side model. - for (const scheme of [WHITEBOARD_API_SOURCE_SCHEME, WHITEBOARD_LANGUAGE_SOURCE_SCHEME]) { - const target = { scheme, exclusive: true }; - this._register(languages.typeDefinitionProvider.register(target, { provideTypeDefinition: (model, position, token) => this.locations(model, position, token, "type") })); - this._register(languages.implementationProvider.register(target, { provideImplementation: (model, position, token) => this.locations(model, position, token, "implementation") })); - this._register(languages.referenceProvider.register(target, { - provideReferences: (model, position, context, token) => this.withSource(model, position, token, async (local, at, pinned) => { - const results = await Promise.all(languages.referenceProvider.ordered(local).map(provider => provider.provideReferences(local, at, context, token))); - return this.whiteboardLocations(pinned, results.flatMap(result => result ?? []), token); - }), - })); - } - } - - private async environment(model: ITextModel, validate = false): Promise { - const { serverUrl, token } = await this.connection.getConnection(); - const target = sourceLocation(model.uri); - return this.environments.read(JSON.stringify([serverUrl, token]), target.view, target.side, async () => { - const params = new URLSearchParams({ side: target.side }); - for (const [key, value] of Object.entries(whiteboardSourceQuery(target.view))) { - if (value !== undefined) params.set(key, String(value)); - } - const response = await fetch(`${serverUrl}/sessions-api/${encodeURIComponent(model.uri.authority)}/language-context?${params}`, { - headers: { "x-whiteboard-token": token }, signal: AbortSignal.timeout(10_000), - }); - return response.ok ? response.json() : undefined; - }, validate); - } - - private async localSource(model: ITextModel): Promise { - if (new URLSearchParams(model.uri.query).has("empty")) return undefined; - try { - const epoch = this.environments.generation; - const context = await this.environment(model); - if (epoch !== this.environments.generation || model.isDisposed()) return undefined; - const cached = this.sources.get(model); - if (cached && cached.identity === context?.identity && cached.rootPath === context.rootPath) return cached.pending; - if (cached) { - this.uncertainRoots.add(URI.file(cached.rootPath).toString()); - void cached.pending.then(source => source?.dispose()); - this.sources.delete(model); - this.generation++; - } - if (!context?.rootPath) return undefined; - const pending = this.acquire(model, { rootPath: context.rootPath, identity: context.identity }).catch(error => { - this.log.debug("[Whiteboard] Language model unavailable", error); - return undefined; - }); - const entry = { identity: context.identity, rootPath: context.rootPath, pending }; - this.sources.set(model, entry); - const result = await pending; - if (this.sources.get(model) !== entry || epoch !== this.environments.generation) { result?.dispose(); return undefined; } - if (!result) this.sources.delete(model); - return result; - } catch (error) { - const cached = this.sources.get(model); - if (cached) this.uncertainRoots.add(URI.file(cached.rootPath).toString()); - this.log.debug("[Whiteboard] Language environment unavailable", error); - return undefined; - } - } - - private async acquire(model: ITextModel, context: { rootPath: string; identity: string }): Promise { - const root = URI.file(context.rootPath); - const relative = model.uri.path.slice(1); - if (!relative || relative.split(/[\\/]/).some(part => part === "..")) return undefined; - const resource = model.uri.scheme === WHITEBOARD_LANGUAGE_SOURCE_SCHEME ? URI.file(model.uri.path) : URI.joinPath(root, relative); - if (!await this.files.exists(resource) || model.isDisposed()) return undefined; - const owned = new DisposableStore(); - try { - owned.add(await acquireWhiteboardLanguageRoot(this.workspace, root)); - this.roots.set(root.toString(), (this.roots.get(root.toString()) ?? 0) + 1); - owned.add({ - dispose: () => { - const count = (this.roots.get(root.toString()) ?? 1) - 1; - if (count > 0) this.roots.set(root.toString(), count); - else this.roots.delete(root.toString()); - } - }); - const reference = owned.add(await this.models.createModelReference(resource)); - owned.add(reference.object.textEditorModel.onDidChangeContent(() => this.generation++)); - owned.add(model.onWillDispose(() => { this.sources.delete(model); owned.dispose(); })); - if (model.isDisposed()) { owned.dispose(); return undefined; } - await this.extensions.activateByEvent(`onLanguage:${reference.object.textEditorModel.getLanguageId()}`); - if (model.isDisposed()) { owned.dispose(); return undefined; } - return { root, reference, identity: context.identity, dispose: () => owned.dispose() }; - } catch (error) { owned.dispose(); throw error; } - } - - private async withSource(model: ITextModel, position: Position, token: CancellationToken, run: (local: ITextModel, at: Position, review: ITextModel) => Promise): Promise { - if (token.isCancellationRequested || model.isDisposed()) return undefined; - if (model.uri.scheme === "file") return withCurrentLocalContext([model], token, () => this.generation, async () => run(model, position, model)); - const epoch = this.environments.generation; - const source = await this.localSource(model); - if (!source || token.isCancellationRequested || model.isDisposed()) return undefined; - const local = source.reference.object.textEditorModel; - if (!await this.files.exists(local.uri)) { this.uncertainRoots.add(source.root.toString()); return undefined; } - if (this.uncertainRoots.has(source.root.toString())) { - // An open dependency can outlive a removed checkout and miss subsequent - // watcher updates. Until watcher readiness is authoritative, revalidate - // clean native buffers before querying; never replace a dirty buffer. - const prefix = source.root.path.replace(/\/$/, "") + "/"; - await Promise.all(this.textFiles.files.models.filter(file => !file.isDirty() && file.resource.scheme === "file" && file.resource.path.startsWith(prefix)) - .map(file => this.textFiles.files.resolve(file.resource, { reload: { async: false } }))); - } - // Resolve current disk contents, preserving any unsaved local editor buffer. - await this.textFiles.files.resolve(local.uri, { reload: { async: false } }); - return withCurrentLocalContext([model, local], token, () => this.generation, async () => { - // The language server must see exactly the source displayed in the review. - if (!model.equalsTextBuffer(local.getTextBuffer())) return undefined; - const result = await run(local, position, model); - const current = await this.environment(model, true).catch(() => undefined); - if (epoch === this.environments.generation && current?.rootPath === source.root.fsPath && current.identity === source.identity) return result; - // Failed validation must also release the old workspace/watchers. Keeping - // them after deletion can leave the language server blind to later edits. - const cached = this.sources.get(model); - if (cached?.identity === source.identity && cached.rootPath === source.root.fsPath) { - this.uncertainRoots.add(source.root.toString()); - this.sources.delete(model); - void cached.pending.then(value => value?.dispose()); - this.generation++; - } - return undefined; - }); - } - - private hover(model: ITextModel, position: Position, token: CancellationToken): Promise { - return this.withSource(model, position, token, async (local, at) => { - const hovers = await getHoversPromise(this.languages.hoverProvider, local, at, token); - if (!hovers.length) return undefined; - const range = hovers[0].range; - if (!range) return undefined; - return { range, contents: hovers.flatMap(hover => hover.contents) }; - }); - } - - private async locations(model: ITextModel, position: Position, token: CancellationToken, kind: "definition" | "type" | "implementation"): Promise { - return this.withSource(model, position, token, async (local, at, pinned) => { - const results = kind === "definition" ? await getDefinitionsAtPosition(this.languages.definitionProvider, local, at, false, token) - : kind === "type" ? await getTypeDefinitionsAtPosition(this.languages.typeDefinitionProvider, local, at, false, token) - : await getImplementationsAtPosition(this.languages.implementationProvider, local, at, false, token); - return this.whiteboardLocations(pinned, results, token); - }); - } - - /** Keep navigation in the same saved version/side only when destination contents match. */ - private async whiteboardLocations(pinned: ITextModel, locations: T[], token: CancellationToken): Promise { - if (![WHITEBOARD_API_SOURCE_SCHEME, WHITEBOARD_LANGUAGE_SOURCE_SCHEME].includes(pinned.uri.scheme)) return locations; - const source = await this.sources.get(pinned)?.pending; - if (!source) return []; - const prefix = source.root.path.replace(/\/$/, "") + "/"; - // References often share a file. Resolve and compare each destination once per request. - const groups = new Map(); - for (const location of locations) { - const key = location.uri.toString(); - const group = groups.get(key) ?? []; - group.push(location); - groups.set(key, group); - } - const mapped = new Map(); - await Promise.all([...groups.values()].map(async group => { - const target = group[0].uri; - if (target.scheme !== "file") return; - const owned = new DisposableStore(); - try { - const local = owned.add(await this.models.createModelReference(target)).object.textEditorModel; - await this.textFiles.files.resolve(target, { reload: { async: false } }); - let original: ITextModel | undefined; - if (target.authority === source.root.authority && target.path.startsWith(prefix)) { - const candidate = pinned.uri.with({ scheme: WHITEBOARD_API_SOURCE_SCHEME, path: "/" + target.path.slice(prefix.length) }); - try { original = owned.add(await this.models.createModelReference(candidate)).object.textEditorModel; } - catch { /* Dependencies and generated files may have no review counterpart. */ } - } - if (!original?.equalsTextBuffer(local.getTextBuffer())) { - const candidate = pinned.uri.with({ scheme: WHITEBOARD_LANGUAGE_SOURCE_SCHEME, path: target.path }); - original = owned.add(await this.models.createModelReference(candidate)).object.textEditorModel; - } - const destination = original; - const results = await withCurrentLocalContext([original, local], token, () => this.generation, async () => { - if (!destination.equalsTextBuffer(local.getTextBuffer())) return []; - return group.map(location => [location, { ...location, uri: destination.uri }] as const); - }); - for (const [before, after] of results ?? []) mapped.set(before, after); - } catch { - // Missing destinations cannot be presented at the provider's coordinates. - } finally { - owned.dispose(); - } - })); - return locations.flatMap(location => { - const match = mapped.get(location); - return match ? [match] : []; - }); - } - - override dispose(): void { - this.environments.invalidate(); - for (const entry of this.sources.values()) void entry.pending.then(source => source?.dispose()); - this.sources.clear(); - super.dispose(); - } -} - -registerWorkbenchContribution2(WhiteboardLocalLanguageFeatures.ID, WhiteboardLocalLanguageFeatures, WorkbenchPhase.BlockRestore); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalRequest.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalRequest.test.ts deleted file mode 100644 index aa9d2d3e9..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalRequest.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; -import { withCurrentLocalContext } from "./whiteboardLocalRequest.js"; - -for (const change of ["source", "dependency", "disposed", "cancelled", "none"] as const) { - test(`pending language result is ${change === "none" ? "returned" : "discarded"} after ${change}`, async () => { - let version = 1, generation = 1, disposed = false; - const token = { isCancellationRequested: false }; - let finish!: (value: string) => void; - const provider = new Promise(resolve => { finish = resolve; }); - const result = withCurrentLocalContext([ - { getVersionId: () => version, isDisposed: () => disposed }, - ], token, () => generation, () => provider); - if (change === "source") version++; - if (change === "dependency") generation++; - if (change === "disposed") disposed = true; - if (change === "cancelled") token.isCancellationRequested = true; - finish("definition from previous project state"); - assert.equal(await result, change === "none" ? "definition from previous project state" : undefined); - }); -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalWorkspace.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalWorkspace.ts deleted file mode 100644 index 58ee0fa42..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardLocalWorkspace.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Queue } from "../../base/common/async.js"; -import type { IDisposable } from "../../base/common/lifecycle.js"; -import { URI } from "../../base/common/uri.js"; -import type { IWorkspaceEditingService } from "../../workbench/services/workspaces/common/workspaceEditing.js"; - -const sessions = new WeakMap; roots: Map }>(); - -/** Native live files and retained-source language adapters share folder ownership. */ -export async function acquireWhiteboardLanguageRoot(workspace: IWorkspaceEditingService, root: URI): Promise { - let session = sessions.get(workspace); - if (!session) { - session = { queue: new Queue(), roots: new Map() }; - sessions.set(workspace, session); - } - const { queue, roots } = session; - const key = root.toString(); - await queue.queue(async () => { - if (!roots.has(key)) await workspace.addFolders([{ uri: root }]); - roots.set(key, (roots.get(key) ?? 0) + 1); - }); - let disposed = false; - return { - dispose() { - if (disposed) return; - disposed = true; - void queue.queue(async () => { - const count = (roots.get(key) ?? 1) - 1; - if (count > 0) roots.set(key, count); - else { roots.delete(key); await workspace.removeFolders([root]); } - }); - } - }; -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardMultiDiff.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardMultiDiff.ts deleted file mode 100644 index c0b914219..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardMultiDiff.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { observableValue } from "../../base/common/observable.js"; -import type { WhiteboardDiffProgressState, WhiteboardDiffSection } from "../common/whiteboardProtocol.js"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Button } from "../../base/browser/ui/button/button.js"; -import { isEqual } from "../../base/common/resources.js"; -import { URI } from "../../base/common/uri.js"; -import type { - IResourceLabel, - IResourceHeaderMetadata, - IWorkbenchUIElementFactory, -} from "../../editor/browser/widget/multiDiffEditor/workbenchUIElementFactory.js"; -import type { IDiffCodeEditorWidgetOptions } from "../../editor/browser/widget/diffEditor/diffEditorWidget.js"; -import { FileKind } from "../../platform/files/common/files.js"; -import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; -import { ResourceLabel } from "../../workbench/browser/labels.js"; -import type { WhiteboardDiffFileWire } from "../common/whiteboardProtocol.js"; - -export interface WhiteboardMultiDiffHeaderEntry { - readonly original: URI | undefined; - readonly modified: URI | undefined; - readonly additions?: number; - readonly deletions?: number; - /** Why the file starts collapsed, e.g. "Generated file · hidden by default". */ - readonly note?: string; - /** Hover text for the counts: visible, structural and textual rows. */ - readonly countsTitle?: string; - readonly sectionId?: string; - readonly section?: WhiteboardDiffSection; - readonly sectionCollapsed?: boolean; - readonly onToggleSectionCollapsed?: () => void; - readonly onToggleSection?: () => void; - readonly onDidOpen?: () => void; - readonly viewedState?: WhiteboardDiffProgressState; - readonly onToggleViewed?: () => void; -} - -export class WhiteboardMultiDiffUIElementFactory - implements IWorkbenchUIElementFactory -{ - - get headerClickToCollapse(): boolean { - return !this.hideResourceHeader; - } - - - private readonly headers = new Set<() => void>(); - - /** Re-reads every live header's entry, for counts that change without the items changing. */ - refreshHeaders(): void { - for (const refresh of this.headers) refresh(); - } - - constructor( - private readonly entries: () => readonly WhiteboardMultiDiffHeaderEntry[], - readonly horizontalScrollbar: "auto" | "hidden", - readonly overflowWidgetsDomNode: HTMLElement | undefined, - readonly hideResourceHeader = false, - readonly codeEditorWidgetOptions: IDiffCodeEditorWidgetOptions | undefined, - @IInstantiationService - private readonly instantiationService: IInstantiationService, - ) {} - - getResourceSectionId(uris: Parameters[0]): string | undefined { - // Lens entries encode their section identity in both source URI fragments. - return uris?.modified?.fragment || uris?.original?.fragment || undefined; - } - - createResourceSectionHeader(element: HTMLElement, sticky = false) { - const height = observableValue(this, 0); - const bodyHidden = observableValue(this, false); - let uris: Parameters[0]; - const refresh = () => { - const entry = uris && this.entries().find(entry => sameResource(entry.original, uris!.original) && sameResource(entry.modified, uris!.modified)); - const section = sticky && entry?.sectionId - ? this.entries().find(candidate => candidate.sectionId === entry.sectionId && candidate.section)?.section - : entry?.section; - bodyHidden.set(entry?.sectionCollapsed ?? false, undefined); - element.replaceChildren(); element.className = 'whiteboard-diff-group'; element.hidden = !section; - height.set(section ? 48 : 0, undefined); - if (!section) return; - const toggle = document.createElement('button'); toggle.className = 'whiteboard-diff-group-toggle'; - toggle.setAttribute('aria-expanded', String(!entry?.sectionCollapsed)); - toggle.setAttribute('aria-label', `${entry?.sectionCollapsed ? 'Expand' : 'Collapse'} section: ${section.label}`); - toggle.onclick = () => entry?.onToggleSectionCollapsed?.(); - const chevron = document.createElement('span'); chevron.className = `codicon codicon-chevron-${entry?.sectionCollapsed ? 'right' : 'down'}`; - const title = document.createElement('span'); title.className = 'whiteboard-diff-group-title'; title.textContent = section.label; - const counts = document.createElement('span'); counts.className = 'whiteboard-diff-group-counts'; - counts.textContent = section.total.additions + section.total.deletions === 0 ? 'Unchanged' : section.state === 'viewed' ? '✓' : section.state === 'folded' ? 'Folded' : `+${compactCount(section.remaining.additions)} −${compactCount(section.remaining.deletions)}`; - counts.title = `Remaining +${section.remaining.additions} −${section.remaining.deletions} · Total +${section.total.additions} −${section.total.deletions}`; - const button = document.createElement('button'); button.className = 'whiteboard-header-viewed'; button.setAttribute('role', 'checkbox'); - button.setAttribute('aria-checked', section.state === 'partial' ? 'mixed' : String(section.state === 'viewed')); - button.setAttribute('aria-label', `${section.state === 'viewed' ? 'Mark unviewed' : 'Mark viewed'}: ${section.label}`); - button.textContent = section.state === 'viewed' ? '✓' : section.state === 'partial' ? '−' : ''; - button.hidden = section.total.additions + section.total.deletions === 0; - button.onclick = () => entry?.onToggleSection?.(); - element.classList.toggle('is-viewed', section.state === 'viewed'); - toggle.append(chevron, title); element.append(toggle, counts, button); - }; - this.headers.add(refresh); - return { height, bodyHidden, setUris: (value: typeof uris) => { uris = value; refresh(); }, dispose: () => { this.headers.delete(refresh); element.remove(); } }; - } - - createResourceLabel(element: HTMLElement): IResourceLabel { - element.classList.add("whiteboard-path-label"); - const label = this.instantiationService.createInstance( - ResourceLabel, - element, - {}, - ); - // A deleted file keeps a legible name: the tree's minus already says - // deleted, so the header never strikes the path through. - return { - setUri: (uri) => { - if (!uri) { - label.element.clear(); - return; - } - // `setFile` splits the URI into a file name and a folder. The header - // prints the whole path instead, and the CSS elides it from the left. - label.element.setResource( - { resource: uri, name: whiteboardMultiDiffLabelPath(uri) }, - { fileKind: FileKind.FILE, forceLabel: true }, - ); - }, - setLabel: (name, description, resource) => { - if (resource) { - label.element.setResource({ resource, name, description }); - } else { - label.element.setLabel(name, description); - } - }, - dispose() { - label.dispose(); - }, - }; - } - - createResourceHeaderMetadata(element: HTMLElement): IResourceHeaderMetadata { - const ownerDocument = element.ownerDocument; - const additions = ownerDocument.createElement("span"); - additions.className = "whiteboard-multidiff-additions"; - const deletions = ownerDocument.createElement("span"); - deletions.className = "whiteboard-multidiff-deletions"; - const counts = ownerDocument.createElement("span"); - counts.className = "whiteboard-multidiff-counts"; - counts.append(additions, deletions); - element.append(counts); - const note = ownerDocument.createElement("span"); - note.className = "whiteboard-multidiff-note"; - element.append(note); - - const openContainer = ownerDocument.createElement("span"); - openContainer.className = "whiteboard-multidiff-open-container"; - element.append(openContainer); - const open = new Button(openContainer, { - ariaLabel: "Open File", - title: "Open File", - supportIcons: true, - }); - open.label = "Open file"; - open.element.classList.add("whiteboard-multidiff-open"); - const viewed = ownerDocument.createElement("button"); - viewed.className = "whiteboard-header-viewed"; - viewed.setAttribute("role", "checkbox"); - element.append(viewed); - const toggleViewed = (event: MouseEvent) => { event.stopPropagation(); current?.onToggleViewed?.(); }; - viewed.addEventListener("click", toggleViewed); - let current: WhiteboardMultiDiffHeaderEntry | undefined; - let lastUris: Parameters[0]; - const openListener = open.onDidClick(() => current?.onDidOpen?.()); - const refresh = () => setUris(lastUris); - this.headers.add(refresh); - - const setUris: IResourceHeaderMetadata["setUris"] = (uris) => { - lastUris = uris; - current = uris - ? this.entries().find( - (entry) => - sameResource(entry.original, uris.original) && - sameResource(entry.modified, uris.modified), - ) - : undefined; - element.hidden = !current; - if (!current) return; - const hasCounts = - current.additions !== undefined && current.deletions !== undefined; - counts.hidden = !hasCounts; - if (hasCounts) { - additions.textContent = `+${compactCount(current.additions!)}`; - deletions.textContent = `−${compactCount(current.deletions!)}`; - counts.setAttribute( - "aria-label", - `${current.additions} lines added, ${current.deletions} lines removed`, - ); - } - counts.title = current.countsTitle ?? ""; - viewed.hidden = !current.onToggleViewed; - viewed.textContent = current.viewedState === "viewed" ? "✓" : current.viewedState === "partial" ? "−" : ""; - viewed.setAttribute("aria-checked", current.viewedState === "partial" ? "mixed" : String(current.viewedState === "viewed")); - viewed.title = current.viewedState === "viewed" ? "Mark unviewed and unfold" : "Mark visible scope viewed"; - viewed.setAttribute("aria-label", viewed.title); - counts.classList.toggle("whiteboard-counts-viewed", current.viewedState === "viewed" || current.viewedState === "folded"); - counts.classList.toggle("whiteboard-counts-folded", current.viewedState === "folded"); - if (current.viewedState === "viewed") { additions.textContent = "✓"; deletions.textContent = ""; } - else if (current.viewedState === "folded") { - // A hidden file's note already says why it is folded. - additions.textContent = "Folded"; deletions.textContent = ""; - counts.hidden ||= !!current.note; - } - - note.hidden = !current.note; - note.textContent = current.note ?? ""; - openContainer.hidden = !current.onDidOpen; - }; - return { - setUris, - dispose: () => { - this.headers.delete(refresh); - viewed.removeEventListener("click", toggleViewed); - openListener.dispose(); - open.dispose(); - element.replaceChildren(); - }, - }; - } -} - -function sameResource(left: URI | undefined, right: URI | undefined): boolean { - return left === undefined - ? right === undefined - : !!right && isEqual(left, right); -} - -export function whiteboardMultiDiffLabelUris(file: WhiteboardDiffFileWire): { - readonly original: URI | undefined; - readonly modified: URI | undefined; -} { - return { - original: - file.status === "added" - ? undefined - : whiteboardFileLabelUri(file.previousPath ?? file.path), - modified: - file.status === "deleted" - ? undefined - : whiteboardFileLabelUri(file.path), - }; -} - -function whiteboardFileLabelUri(path: string): URI { - return URI.from({ scheme: "file", path: `/${path}` }); -} - -function whiteboardMultiDiffLabelPath(uri: URI): string { - return uri.path.startsWith("/") ? uri.path.slice(1) : uri.path; -} - -const compactCount = (count: number) => new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }).format(count).toLowerCase(); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardSourceEditorInput.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardSourceEditorInput.ts deleted file mode 100644 index 65ffa61fc..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardSourceEditorInput.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { EditorInputCapabilities } from "../../workbench/common/editor.js"; -import { TextResourceEditorInput } from "../../workbench/common/editor/textResourceEditorInput.js"; - -/** Virtual review buffers cannot delegate Save or Save As to a workspace file. */ -export class WhiteboardSourceEditorInput extends TextResourceEditorInput { - override get capabilities(): EditorInputCapabilities { - return EditorInputCapabilities.Readonly | EditorInputCapabilities.CanSplitInGroup; - } - override async save(): Promise { return undefined; } - override async saveAs(): Promise { return undefined; } - override async revert(): Promise { } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiff.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiff.ts deleted file mode 100644 index 90b409b9d..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiff.ts +++ /dev/null @@ -1,199 +0,0 @@ -import type { IDocumentDiffProvider, IDocumentDiff } from "../../editor/common/diff/documentDiffProvider.js"; -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { StructuralDiffSession } from "./whiteboardStructuralDiffSession.js"; -import { IModelService } from "../../editor/common/services/model.js"; -import { ITextModelService } from "../../editor/common/services/resolverService.js"; -import { URI } from "../../base/common/uri.js"; -import { Event } from "../../base/common/event.js"; -import { DisposableStore } from "../../base/common/lifecycle.js"; -import { CancellationError } from "../../base/common/errors.js"; -import { IInstantiationService } from "../../platform/instantiation/common/instantiation.js"; -import { ServiceCollection } from "../../platform/instantiation/common/serviceCollection.js"; -import { IDiffProviderFactoryService } from "../../editor/browser/widget/diffEditor/diffProviderFactoryService.js"; -import { ICodeEditorService } from "../../editor/browser/services/codeEditorService.js"; -import type { IDiffEditor } from "../../editor/browser/editorBrowser.js"; -import { LineRange } from "../../editor/common/core/ranges/lineRange.js"; -import { DetailedLineRangeMapping } from "../../editor/common/diff/rangeMapping.js"; -import { autorun, derived, type IObservable } from "../../base/common/observable.js"; -import type { UnchangedRegion } from "../../editor/browser/widget/diffEditor/diffEditorViewModel.js"; -import { - structuralContextGaps, - structuralContextScopes, - structuralRows, - structuralHighlights, -} from "../common/whiteboardStructuralDiff.js"; -import type { WhiteboardFilesEditorEntry } from "./whiteboardFilesDiffView.js"; - -/** View-owned Monaco providers and editor listeners; comparison state lives in session. */ -export function createStructuralDiffEditors( - instantiation: IInstantiationService, - entries: readonly WhiteboardFilesEditorEntry[], - lifetime: DisposableStore, - session: StructuralDiffSession, -): { instantiation: IInstantiationService; entries: readonly WhiteboardFilesEditorEntry[] } { - // Use pinned checkout resources so native language providers see real project files. - // Revision-only resources retain their virtual snapshot identity. - const modelService = instantiation.invokeFunction((a) => a.get(IModelService)); - const resolver = instantiation.invokeFunction((a) => a.get(ITextModelService)); - lifetime.add(resolver.registerTextModelContentProvider("review-structural-empty", { - provideTextContent: async uri => modelService.getModel(uri) ?? modelService.createModel("", null, uri), - })); - const resolvedEntries = entries.map(entry => ({ - ...entry, - original: entry.original ?? URI.from({ scheme: "review-structural-empty", path: "/base/" + entry.file.path, query: entry.modified!.toString() }), - modified: entry.modified ?? URI.from({ scheme: "review-structural-empty", path: "/head/" + entry.file.path, query: entry.original!.toString() }), - })); - const unchanged = new Set(entries.filter(e => e.file.status === "unchanged").map(e => e.file.path)); - const pairs = new Map(resolvedEntries.map(e => [e.original!.toString() + "\n" + e.modified!.toString(), e.file.path])); - const factory: IDiffProviderFactoryService = { - _serviceBrand: undefined, - createDiffProvider: () => new StructuralDiffProvider(session, pairs, unchanged), - }; - const child = lifetime.add( - instantiation.createChild(new ServiceCollection([IDiffProviderFactoryService, factory])), - ); - attachStructuralEditors(instantiation, resolvedEntries, session, lifetime); - return { instantiation: child, entries: resolvedEntries }; -} - -/** Adapts session snapshots and fold state to Monaco's diff interface. */ -export class StructuralDiffProvider implements IDocumentDiffProvider { - private path: string | undefined; - readonly onDidChange: Event; - constructor(private readonly session: StructuralDiffSession, private readonly pairs: ReadonlyMap, private readonly unchanged: ReadonlySet) { - this.onDidChange = Event.map(Event.filter(session.onDidChange, change => this.path !== undefined && change.files.has(this.path)), () => undefined); - } - async computeDiff(...[original, modified, _options, token]: Parameters): Promise { - if (token.isCancellationRequested) throw new CancellationError(); - const path = this.pairs.get(original.uri.with({ fragment: "" }).toString() + "\n" + modified.uri.with({ fragment: "" }).toString()); - this.path = path; - if (path !== undefined && this.unchanged.has(path)) { - if (original.getValue() !== modified.getValue()) throw new Error("Referenced context file changed; reload the session."); - return { changes: [], moves: [], identical: true, quitEarly: false }; - } - if (path !== undefined && this.session.getFileResult(path)?.diff?.type === "binary") { - return { changes: [], moves: [], identical: false, quitEarly: false, changeHighlights: { original: [], modified: [] } }; - } - const diff = path === undefined ? undefined : this.session.getTextDiff(path); - if (!diff) throw new Error("diffr did not supply a result for this file."); - const left = (diff.lhs?.text ?? "").replace(/\r\n/g, "\n"); - const right = (diff.rhs?.text ?? "").replace(/\r\n/g, "\n"); - if ( - original.getLinesContent().join("\n") !== left || - modified.getLinesContent().join("\n") !== right - ) { - throw new Error( - "diffr sources differ from Whiteboard's editor snapshots; reload the session.", - ); - } - const rows = structuralRows(diff); - // Changed-ness comes from the wire: a one-sided row, or a paired row whose line carries a changed span. - const highlights = structuralHighlights(diff); - const changedLeft = new Set(highlights.originalLines), changedRight = new Set(highlights.modifiedLines); - const changes: DetailedLineRangeMapping[] = []; - let l = 0, - r = 0; - let start: [number, number] | undefined; - const flush = () => { - if (start) - changes.push( - new DetailedLineRangeMapping( - new LineRange(start[0] + 1, l + 1), - new LineRange(start[1] + 1, r + 1), - undefined, - ), - ); - start = undefined; - }; - for (const [a, b] of rows) { - const changed = a === null || b === null || changedLeft.has(a + 1) || changedRight.has(b + 1); - if (changed) start ??= [l, r]; - else flush(); - if (a !== null) l = a + 1; - if (b !== null) r = b + 1; - } - flush(); - return { - changes, - moves: [], - identical: left === right, - quitEarly: false, - sourceLineAlignment: rows, - contextScopes: structuralContextScopes(diff), - // Every collapsed region is a hidden-region band, labelled by the wire. - contextGaps: structuralContextGaps( - diff, - (id) => this.session.isRegionCollapsed(path!, id) === true, - (id) => this.session.isRegionCollapsed(path!, id), - ).map(gap => ({ - ...gap, labelObservable: derived(reader => { - for (const id of gap.regionIds) { - const label = this.session.regionLabel(path!, id).read(reader); - if (label) return label; - } - const count = Math.max(gap.originalCount, gap.modifiedCount); - return `${count} hidden line${count === 1 ? "" : "s"}`; - }) - })), - changeHighlights: highlights, - }; - } -} - -/** - * Keeps each structural diff editor's bands in step with the collapse state: - * a band a reader reveals (its arrows, or double-click) marks its fold state - * open, which covers both sides by construction, and the visible counts follow. - */ -function attachStructuralEditors( - instantiation: IInstantiationService, - entries: readonly WhiteboardFilesEditorEntry[], - session: StructuralDiffSession, - lifetime: DisposableStore, -): void { - const editors = instantiation.invokeFunction((a) => a.get(ICodeEditorService)); - const pairs = new Map(entries.map((e) => [e.original!.toString() + "\n" + e.modified!.toString(), e.file.path])); - function watch(editor: IDiffEditor) { - const store = lifetime.add(new DisposableStore()); - store.add(editor.onDidDispose(() => store.dispose())); - const widget = editor as unknown as { unchangedRegions?: IObservable }; - if (!widget.unchangedRegions) return; - let revealed = new Set(); - store.add( - autorun((reader) => { - const model = editor.getModel(); - const path = model && pairs.get(model.original.uri.with({ fragment: "" }).toString() + "\n" + model.modified.uri.with({ fragment: "" }).toString()); - const regions = widget.unchangedRegions!.read(reader); - if (!path || !session.getTextDiff(path)) return; - const gaps = structuralContextGaps(session.getTextDiff(path)!, (id) => session.isRegionCollapsed(path, id) === true, (id) => session.isRegionCollapsed(path, id)); - const next = new Set(); - const gapOf = (region: UnchangedRegion) => - gaps.find((g) => g.originalStart === region.originalLineNumber && g.modifiedStart === region.modifiedLineNumber && g.foldStateId === region.foldStateId); - for (const region of regions) { - const fullyShown = region.visibleLineCountTop.read(reader) + region.visibleLineCountBottom.read(reader) >= region.lineCount; - if (fullyShown) { - next.add(region); - if (revealed.has(region)) continue; - const gap = gapOf(region); - if (!gap) continue; - session.setRegionCollapsed(path, gap.foldStateId, false); - } else if (revealed.has(region)) { - // Monaco's own fold control closed a region we had marked open. - const gap = gapOf(region); - if (!gap) continue; - session.setRegionCollapsed(path, gap.foldStateId, true); - } - } - revealed = next; - }), - ); - } - - lifetime.add(editors.onDiffEditorAdd(watch)); - for (const editor of editors.listDiffEditors()) watch(editor); -} - diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffClient.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffClient.ts deleted file mode 100644 index 2853c2b86..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffClient.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { decodeWhiteboardStructuralDiffEvent, whiteboardSourceQuery, type WhiteboardSourceView } from "../common/whiteboardProtocol.js"; -import type { StructuralEvent } from "../common/whiteboardStructuralDiff.js"; -import type { IWhiteboardDesktopConnectionService } from "./whiteboardDesktopConnectionService.js"; - -/** The transport seam: callers consume records, never Response objects or byte chunks. */ -export interface StructuralDiffStream { - streamComparison(signal: AbortSignal): AsyncIterable; -} - -export class StructuralDiffClient implements StructuralDiffStream { - constructor(private readonly connection: IWhiteboardDesktopConnectionService, private readonly comparison: WhiteboardSourceView) { } - - async *streamComparison(signal: AbortSignal): AsyncGenerator { - const { serverUrl, token } = await this.connection.getConnection(); - signal.throwIfAborted(); - const query = new URLSearchParams(Object.entries(whiteboardSourceQuery(this.comparison)).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)])); - const response = await fetch(`${serverUrl}/sessions-api/${encodeURIComponent(this.comparison.sessionId)}/structural-diff?${query}`, { - headers: { "x-whiteboard-token": token }, signal, - }); - if (!response.ok) throw new Error((await response.json()).error ?? "Structural diff request failed."); - if (!response.body || !response.headers.get("content-type")?.includes("ndjson")) { - await response.body?.cancel(); - throw new Error("The Whiteboard host must be updated to stream structural diffs."); - } - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - let buffer = ""; - try { - while (true) { - const chunk = await reader.read(); - buffer += decoder.decode(chunk.value, { stream: !chunk.done }); - const lines = buffer.split("\n"); - buffer = lines.pop()!; - if (chunk.done && buffer.trim()) { lines.push(buffer); buffer = ""; } - for (const line of lines) { - if (!line.trim()) continue; - const event = decodeWhiteboardStructuralDiffEvent(line); - if (event.type === "error") throw new Error(event.message); - yield event; - } - if (chunk.done) break; - } - } finally { - await reader.cancel().catch(() => { }); - reader.releaseLock(); - } - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffSession.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffSession.test.ts deleted file mode 100644 index a954a2593..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffSession.test.ts +++ /dev/null @@ -1,173 +0,0 @@ -import assert from 'node:assert/strict'; -import test from 'node:test'; -import { StructuralDiffSession } from './whiteboardStructuralDiffSession.js'; -import type { StructuralEvent } from '../common/whiteboardStructuralDiff.js'; - -const file = { rhs: { path: 'a.ts', oid: 'abc', mode: '100644' } }; -const start: StructuralEvent = { type: 'start', version: 4, lhs: { type: 'empty_tree' }, rhs: { type: 'revision', rev: 'head' }, files: [{ file, status: 'added' }] }; -const result: StructuralEvent = { type: 'file', file, diff: { type: 'text', structural_changes: { base: [], head: [[0, 1]] }, rhs: { text: 'a', regions: [{ kind: 'leaf', id: 1, fold_state_id: 2, alignment_id: 1, start: { line: 0, column: 0 }, end: { line: 0, column: 1 }, visibility: { collapsed: true } }] }, stats: { textual: { added: 1, removed: 0 }, visible: { added: 0, removed: 0 } } } }; -const complete: StructuralEvent = { type: 'complete', succeeded: 1, failed: 0 }; - -test('views detach and reattach without restarting a comparison or losing folds', async () => { - let requests = 0; - const session = new StructuralDiffSession({ async *streamComparison() { requests++; yield start; yield result; yield complete; } }); - try { - let observedFile = false; - const view = session.onDidChange(change => { if (change.files.has("a.ts")) observedFile = !!session.getFileResult("a.ts"); }); - await session.start(); - assert.equal(observedFile, true); - view.dispose(); - session.setRegionCollapsed('a.ts', 2, false); - await session.start(); - assert.equal(requests, 1); - assert.equal(session.isRegionCollapsed('a.ts', 2), false); - assert.equal(session.complete, true); - } finally { session.dispose(); } -}); - -test('closing the review aborts a running request and ignores late events', async () => { - let signal: AbortSignal | undefined; - let release!: () => void; - const gate = new Promise(resolve => release = resolve); - const session = new StructuralDiffSession({ async *streamComparison(s) { signal = s; yield start; await gate; yield result; } }); - const task = session.start(); - await Promise.resolve(); - session.dispose(); - assert.equal(signal?.aborted, true); - release(); await task; - assert.equal(session.getFileResult('a.ts'), undefined); -}); - -test('per-file failures and run abortion remain observable after the stream finishes', async () => { - const session = new StructuralDiffSession({ - async *streamComparison() { - yield start; - yield { type: 'file', file, error: { code: 'parse', message: 'bad file' } } as StructuralEvent; - yield { ...complete, aborted: { code: 'cancel', message: 'stopped' } } as StructuralEvent; - } - }); - try { await session.start(); assert.equal(session.getFileResult('a.ts')?.error, 'bad file'); assert.match(session.error!, /stopped/); } - finally { session.dispose(); } -}); - -test('truncation and missing manifest results are visible to later subscribers', async () => { - for (const events of [[start], [start, complete]]) { - const session = new StructuralDiffSession({ async *streamComparison() { yield* events; } }); - try { - await session.start(); - assert.equal(session.complete, true); - assert.ok(session.error || session.getFileResult('a.ts')?.error); - } finally { session.dispose(); } - } -}); - -test('deferred annotations retain source identity, counts and user fold choices', async () => { - let release!: () => void; - const gate = new Promise(resolve => release = resolve); - const session = new StructuralDiffSession({ - async *streamComparison() { - yield start; yield structuredClone(result); - await gate; - yield { type: 'annotations', file, annotations: [{ region_id: 1, label: 'summarized' }] } as StructuralEvent; - yield complete; - } - }); - const task = session.start(); - while (!session.getTextDiff('a.ts')) await new Promise(resolve => setTimeout(resolve, 0)); - try { - const initial = session.getTextDiff('a.ts')!; - assert.equal(session.complete, false); - session.setRegionCollapsed('a.ts', 2, false); - release(); await task; - assert.equal(session.getTextDiff('a.ts'), initial); - assert.equal(initial.rhs!.regions![0].visibility?.label, 'summarized'); - assert.equal(initial.rhs!.text, 'a'); - assert.deepEqual(initial.structural_changes, { base: [], head: [[0, 1]] }); - assert.equal(session.isRegionCollapsed('a.ts', 2), false); - assert.equal(session.error, undefined); - } finally { release(); session.dispose(); } -}); - -test('invalid annotation batches are atomic and enrichment failure keeps the initial diff usable', async () => { - for (const invalid of [false, true]) { - const session = new StructuralDiffSession({ - async *streamComparison() { - yield start; yield structuredClone(result); - yield { - type: 'annotations', file, - annotations: invalid ? [{ region_id: 1, label: 'must not apply' }, { region_id: 99, label: 'bad' }] : [], - error: invalid ? undefined : { code: 'enrichment_failed', message: 'offline' }, - } as StructuralEvent; - yield complete; - } - }); - try { - await session.start(); - assert.equal(session.getTextDiff('a.ts')!.rhs!.regions![0].visibility?.label, undefined); - assert.equal(session.isRegionCollapsed('a.ts', 2), true); - if (invalid) assert.match(session.error!, /Unknown annotation region/); - else { - assert.equal(session.getFileResult('a.ts')?.annotationError, 'offline'); - assert.equal(session.error, undefined); - } - } finally { session.dispose(); } - } -}); - -test('streamed labels update existing bands without invalidating either file provider', async () => { - const { StructuralDiffProvider } = await import('./whiteboardStructuralDiff.js'); - const { URI } = await import('../../base/common/uri.js'); - const { CancellationToken } = await import('../../base/common/cancellation.js'); - const other = { rhs: { path: 'b.ts', oid: 'def', mode: '100644' } }; - let release!: () => void; - const gate = new Promise(resolve => release = resolve); - const session = new StructuralDiffSession({ - async *streamComparison() { - yield { ...start, files: [...start.files, { file: other, status: 'added' as const }] }; - yield structuredClone(result); - yield { ...structuredClone(result), file: other }; - await gate; - yield { type: 'annotations', file, annotations: [{ region_id: 1, label: 'first' }] } as StructuralEvent; - yield { type: 'annotations', file, annotations: [{ region_id: 1, label: '// pseudocode\nfinal summary' }] } as StructuralEvent; - yield { ...complete, succeeded: 2 }; - } - }); - const task = session.start(); - const ready = new Promise(resolve => { - const sub = session.onDidChange(change => { if (change.files.has('b.ts')) { sub.dispose(); resolve(); } }); - }); - try { - await ready; - const models = (path: string) => [ - { uri: URI.parse(`test:/base/${path}`), getLinesContent: () => [''] }, - { uri: URI.parse(`test:/head/${path}`), getLinesContent: () => ['a'] }, - ] as const; - const a = models('a.ts'), b = models('b.ts'); - const pairs = new Map([[`${a[0].uri}\n${a[1].uri}`, 'a.ts'], [`${b[0].uri}\n${b[1].uri}`, 'b.ts']]); - const pa = new StructuralDiffProvider(session, pairs, new Set()); - const pb = new StructuralDiffProvider(session, pairs, new Set()); - const compute = (provider: typeof pa, pair: ReturnType) => provider.computeDiff( - pair[0] as Parameters[0], pair[1] as Parameters[1], - { ignoreTrimWhitespace: false, maxComputationTimeMs: 0, computeMoves: false }, CancellationToken.None, - ); - const diff = await compute(pa, a); - await compute(pb, b); - let invalidationsA = 0, invalidationsB = 0, labelBatches = 0; - const subscriptions = [pa.onDidChange(() => invalidationsA++), pb.onDidChange(() => invalidationsB++), - session.onDidChange(change => { if (change.labels.has('a.ts')) labelBatches++; })]; - const band = diff.contextGaps![0]; - release(); await task; - assert.equal(band.labelObservable!.get(), '// pseudocode\nfinal summary'); - assert.equal(invalidationsA, 0); - assert.equal(invalidationsB, 0); - assert.equal(labelBatches, 1, 'a burst publishes only the latest presentation state'); - const folded = new Promise(resolve => { - const sub = pa.onDidChange(() => { sub.dispose(); resolve(); }); - }); - session.setRegionCollapsed('a.ts', 2, false); - await folded; - assert.equal(invalidationsA, 1); - assert.equal(invalidationsB, 0, 'folding a file does not invalidate unrelated editors'); - subscriptions.forEach(sub => sub.dispose()); - } finally { release(); session.dispose(); await task; } -}); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffSession.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffSession.ts deleted file mode 100644 index aa5180458..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardStructuralDiffSession.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { RunOnceScheduler } from "../../base/common/async.js"; -import { observableValue, transaction, type IObservable, type ISettableObservable } from "../../base/common/observable.js"; -import { Emitter } from "../../base/common/event.js"; -import { Disposable } from "../../base/common/lifecycle.js"; -import { structuralFilePath, STRUCTURAL_WIRE_VERSION, type StructuralEvent, type StructuralRegion, type StructuralTextDiff } from "../common/whiteboardStructuralDiff.js"; -import type { StructuralDiff } from "../common/whiteboardProtocol.js"; -import type { StructuralDiffStream } from "./whiteboardStructuralDiffClient.js"; - -export interface StructuralFileResult { - diff?: StructuralDiff; - error?: string; - hidden?: string; - annotationError?: string; -} - -export interface StructuralSessionChange { - /** Files whose diff or fold state changed. */ - readonly files: ReadonlySet; - /** Files with new summary labels or summary errors; their diff is unchanged. */ - readonly labels: ReadonlySet; - readonly status: boolean; -} - -/** One comparison, owned by the review. Views only observe it and change fold state. */ -export class StructuralDiffSession extends Disposable { - private readonly changed = this._register(new Emitter()); - readonly onDidChange = this.changed.event; - private readonly pendingFiles = new Set(); - private readonly pendingLabels = new Set(); - private pendingStatus = false; - private readonly regions = new Map(); - private readonly labels = new Map>(); - private readonly pendingLabelValues = new Map(); - private readonly notification = this._register(new RunOnceScheduler(() => this.flushChanges(), 16)); - private readonly abort = new AbortController(); - private readonly results = new Map(); - private readonly folds = new Map(); - private manifest: Set | undefined; - private task: Promise | undefined; - private finished = false; - private disposed = false; - error: string | undefined; - get complete(): boolean { return this.finished; } - - constructor(private readonly client: StructuralDiffStream) { super(); } - - start(): Promise { return this.task ??= this.consume(); } - getFileResult(path: string): StructuralFileResult | undefined { return this.results.get(path); } - getTextDiff(path: string): StructuralTextDiff | undefined { - const diff = this.results.get(path)?.diff; - return diff?.type === "text" ? diff : undefined; - } - isRegionCollapsed(path: string, id: number): boolean | undefined { return this.folds.get(`${path}:${id}`); } - setRegionCollapsed(path: string, id: number, collapsed: boolean): void { - const key = `${path}:${id}`; - if (this.disposed || this.folds.get(key) === collapsed) return; - this.folds.set(key, collapsed); - this.notify(path); - } - - private async consume(): Promise { - try { - for await (const event of this.client.streamComparison(this.abort.signal)) { - if (this.disposed) return; - this.applyEvent(event); - } - if (!this.finished) throw new Error("diffr stream ended before completion."); - } catch (error) { - if (!this.disposed) { - this.error = error instanceof Error ? error.message : String(error); - this.finished = true; - this.notify(undefined, true); - } - } finally { - this.notification.cancel(); - if (!this.disposed) this.flushChanges(); - } - } - - private applyEvent(event: StructuralEvent): void { - if (this.finished) throw new Error("diffr emitted data after completion."); - if (!this.manifest) { - if (event.type !== "start" || event.version !== STRUCTURAL_WIRE_VERSION) throw new Error("Unsupported diffr stream protocol."); - this.acceptManifest(event); - } else if (event.type === "file") this.storeFileResult(event); - else if (event.type === "annotations") this.applyAnnotations(event); - else if (event.type === "complete") this.finishLoading(event); - else throw new Error(`Unexpected diffr event: ${event.type}`); - if (event.type === "file") this.notify(structuralFilePath(event.file)); - else if (event.type === "annotations") { - this.pendingLabels.add(structuralFilePath(event.file)); - this.notify(); - } else this.notify(undefined, true); - } - - /** Stable presentation state, shared by all editors displaying this region. */ - regionLabel(path: string, id: number): IObservable { - const key = `${path}:${id}`; - let label = this.labels.get(key); - if (!label) { - label = observableValue(this, this.regions.get(key)?.visibility?.label); - this.labels.set(key, label); - } - return label; - } - - private notify(path?: string, status = false): void { - if (path) this.pendingFiles.add(path); - this.pendingStatus ||= status; - if (!this.notification.isScheduled()) this.notification.schedule(); - } - - private flushChanges(): void { - if (!this.pendingFiles.size && !this.pendingLabels.size && !this.pendingStatus) return; - const change: StructuralSessionChange = { - files: new Set(this.pendingFiles), labels: new Set(this.pendingLabels), status: this.pendingStatus, - }; - const labels = new Map(this.pendingLabelValues); - this.pendingFiles.clear(); this.pendingLabels.clear(); this.pendingLabelValues.clear(); this.pendingStatus = false; - transaction(tx => { - for (const [key, value] of labels) this.labels.get(key)?.set(value, tx); - }); - this.changed.fire(change); - } - - private acceptManifest(event: Extract): void { - this.manifest = new Set(event.files.map(file => structuralFilePath(file.file))); - if (this.manifest.size !== event.files.length) throw new Error("diffr repeated a file in its manifest."); - } - - private storeFileResult(event: Extract): void { - const path = structuralFilePath(event.file); - if (!this.manifest!.has(path) || this.results.has(path)) throw new Error(`Unexpected or repeated diffr result: ${path}`); - if (event.error) { this.results.set(path, { error: event.error.message }); return; } - const diff = event.diff; - if (diff.type === "text") { - const seed = (region: StructuralRegion) => { - this.regions.set(`${path}:${region.id}`, region); - const key = `${path}:${region.fold_state_id}`; - if (!this.folds.has(key)) this.folds.set(key, region.visibility?.collapsed === true); - if (region.kind === "fold") region.children.forEach(seed); - }; - for (const side of [diff.lhs, diff.rhs]) side?.regions?.forEach(seed); - } - this.results.set(path, { - diff, - hidden: event.visibility?.collapsed ? event.visibility.label || "Hidden by default" : undefined - }); - } - - private applyAnnotations(event: Extract): void { - const path = structuralFilePath(event.file); - const result = this.results.get(path); - if (result?.diff?.type !== "text") throw new Error(`Annotations precede a text result: ${path}`); - // Validate the entire batch before applying it. Labels do not replace the - // source, correspondence, region identities, or the reader's fold choices. - for (const annotation of event.annotations) { - if (!this.regions.has(`${path}:${annotation.region_id}`)) throw new Error(`Unknown annotation region: ${annotation.region_id}`); - } - for (const annotation of event.annotations) { - const region = this.regions.get(`${path}:${annotation.region_id}`)!; - region.visibility = { ...region.visibility, label: annotation.label }; - this.pendingLabelValues.set(`${path}:${region.id}`, annotation.label); - } - result.annotationError = event.error?.message; - } - - private finishLoading(event: Extract): void { - for (const path of this.manifest!) if (!this.results.has(path)) { this.results.set(path, { error: "diffr did not supply a result for this file." }); this.pendingFiles.add(path); } - this.finished = true; - if (event.aborted) this.error = `diffr stopped early: ${event.aborted.message}`; - } - - override dispose(): void { - this.disposed = true; - this.abort.abort(); - this.results.clear(); - this.folds.clear(); - this.labels.clear(); - this.regions.clear(); - this.pendingFiles.clear(); - this.pendingLabels.clear(); - this.pendingLabelValues.clear(); - super.dispose(); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardTelemetryService.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardTelemetryService.ts deleted file mode 100644 index 9cd53e377..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardTelemetryService.ts +++ /dev/null @@ -1,127 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { generateUuid } from "../../base/common/uuid.js"; -import { IConfigurationService } from "../../platform/configuration/common/configuration.js"; -import { createDecorator } from "../../platform/instantiation/common/instantiation.js"; -import { IMainProcessService } from "../../platform/ipc/common/mainProcessService.js"; -import { ILifecycleService } from "../../workbench/services/lifecycle/common/lifecycle.js"; -import { - WHITEBOARD_DESKTOP_CHANNEL, - type WhiteboardDesktopConnection, -} from "../common/whiteboardDesktopBootstrap.js"; -import { WHITEBOARD_TELEMETRY_SETTING } from "../common/whiteboardConfigurationDefaults.js"; -import type { WhiteboardErrorReport } from "../common/whiteboardErrorReport.js"; -import { whiteboardTelemetryEventRequest } from "../common/whiteboardTelemetryRequest.js"; - -type WhiteboardTelemetryProperties = Record; - -interface QueuedWhiteboardTelemetryEvent { - readonly name: string; - readonly properties: WhiteboardTelemetryProperties | undefined; - readonly error?: WhiteboardErrorReport; -} - -export const IWhiteboardTelemetryService = createDecorator( - "whiteboardTelemetryService", -); - -export interface IWhiteboardTelemetryService { - readonly _serviceBrand: undefined; - /** The per-window session id all workbench events carry. */ - readonly appSessionId: string; - /** - * Fire-and-forget. Never throws. Drops when telemetry is off. - * - * `error` carries the raw name, message, and stack beside the allowlisted - * properties, never inside them. It reaches only the loopback server on this - * machine, which replaces the message with a digest and keeps only the stack - * frames that resolve inside the shipped bundle. - */ - capture(name: string, properties?: WhiteboardTelemetryProperties, error?: WhiteboardErrorReport): void; - /** Best-effort flush. Resolves within approximately 500 ms. */ - flush(): Promise; -} - -export class WhiteboardTelemetryService implements IWhiteboardTelemetryService { - declare readonly _serviceBrand: undefined; - readonly appSessionId = generateUuid(); - - private readonly queued: QueuedWhiteboardTelemetryEvent[] = []; - private readonly inFlight = new Set>(); - private readonly connectionPromise: Promise; - private connection: WhiteboardDesktopConnection | undefined; - - constructor( - @IMainProcessService mainProcessService: IMainProcessService, - @IConfigurationService - private readonly configurationService: IConfigurationService, - @ILifecycleService lifecycleService: ILifecycleService, - ) { - this.connectionPromise = mainProcessService - .getChannel(WHITEBOARD_DESKTOP_CHANNEL) - .call("getConnection") - .then((connection) => { - this.connection = connection; - this.drainQueue(); - return connection; - }) - .catch(() => undefined); - lifecycleService.onWillShutdown((event) => { - event.join(this.flush(), { - id: "whiteboardTelemetryService.flush", - label: "Sending Whiteboard telemetry", - }); - }); - } - - capture(name: string, properties?: WhiteboardTelemetryProperties, error?: WhiteboardErrorReport): void { - if (this.configurationService.getValue(WHITEBOARD_TELEMETRY_SETTING) === false) { - return; - } - const event = { name, properties, ...(error ? { error } : {}) }; - if (this.connection) { - this.send(event); - return; - } - this.queued.push(event); - if (this.queued.length > 100) this.queued.shift(); - } - - async flush(): Promise { - const flushPending = async (): Promise => { - await this.connectionPromise; - this.drainQueue(); - await Promise.all([...this.inFlight]); - }; - await Promise.race([ - flushPending(), - new Promise((resolve) => setTimeout(resolve, 500)), - ]); - } - - private drainQueue(): void { - if (!this.connection) return; - for (const event of this.queued.splice(0)) this.send(event); - } - - private send(event: QueuedWhiteboardTelemetryEvent): void { - const connection = this.connection; - if (!connection) return; - let request: Promise; - request = fetch( - `${connection.url}/telemetry/event`, - whiteboardTelemetryEventRequest( - { token: connection.token, appSessionId: this.appSessionId }, - event, - { keepalive: true }, - ), - ) - .then(() => undefined) - .catch(() => undefined) - .finally(() => this.inFlight.delete(request)); - this.inFlight.add(request); - } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardWorkbenchServices.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardWorkbenchServices.ts deleted file mode 100644 index 808b881a6..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/services/whiteboardWorkbenchServices.ts +++ /dev/null @@ -1,143 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from '../../base/common/event.js'; -import { DisposableStore, toDisposable } from '../../base/common/lifecycle.js'; -import type { URI } from '../../base/common/uri.js'; -import { InstantiationType, registerSingleton } from '../../platform/instantiation/common/extensions.js'; -import type { IInstantiationService } from '../../platform/instantiation/common/instantiation.js'; -import { type IBannerItem, IBannerService } from '../../workbench/services/banner/browser/bannerService.js'; -import type { IAuxiliaryStatusbarPart, IStatusbarEntryContainer } from '../../workbench/browser/parts/statusbar/statusbarPart.js'; -import { IExtensionsWorkbenchService } from '../../workbench/contrib/extensions/common/extensions.js'; -import { - IMultiDiffSourceResolverService, - MultiDiffSourceResolverService, -} from '../../workbench/contrib/multiDiffEditor/browser/multiDiffSourceResolverService.js'; -import { - IQuickDiffModelService, - type QuickDiffModelOptions, -} from '../../workbench/contrib/scm/browser/quickDiffModel.js'; -import { - type IStatusbarEntry, - type IStatusbarEntryAccessor, - type IStatusbarEntryLocation, - type IStatusbarEntryPriority, - IStatusbarService, - type IStatusbarStyleOverride, - type StatusbarAlignment, -} from '../../workbench/services/statusbar/browser/statusbar.js'; - -/** Accepts status messages from editor services without creating stock chrome. */ -class WhiteboardStatusbarService implements IStatusbarService { - declare readonly _serviceBrand: undefined; - readonly onDidChangeEntryVisibility = Event.None as Event<{ id: string; visible: boolean }>; - - getPart(_container: HTMLElement): IStatusbarEntryContainer { return this; } - createAuxiliaryStatusbarPart(_container: HTMLElement, _instantiationService: IInstantiationService): IAuxiliaryStatusbarPart { - throw new Error('Whiteboard does not provide status bar parts'); - } - createScoped(_statusbarEntryContainer: IStatusbarEntryContainer, _disposables: DisposableStore): IStatusbarService { return this; } - addEntry( - _entry: IStatusbarEntry, - _id: string, - _alignment: StatusbarAlignment, - _priority?: number | IStatusbarEntryPriority | IStatusbarEntryLocation, - ): IStatusbarEntryAccessor { - return { update() { }, dispose() { } }; - } - isEntryVisible(_id: string): boolean { return false; } - updateEntryVisibility(_id: string, _visible: boolean): void { } - overrideEntry(_id: string, _override: Partial) { return toDisposable(() => { }); } - focus(_preserveEntryFocus?: boolean): void { } - focusNextEntry(): void { } - focusPreviousEntry(): void { } - isEntryFocused(): boolean { return false; } - overrideStyle(_style: IStatusbarStyleOverride) { return toDisposable(() => { }); } - dispose(): void { } -} - -class WhiteboardBannerService implements IBannerService { - declare readonly _serviceBrand: undefined; - focus(): void { } - focusNextAction(): void { } - focusPreviousAction(): void { } - hide(_id: string): void { } - show(_item: IBannerItem): void { } -} - -/** - * MainThreadTextEditors asks for quick-diff metadata while synchronizing every - * editor. Review has no SCM provider surface, so there are no quick diffs to - * expose and constructing the stock model would incorrectly require SCM. - */ -class WhiteboardQuickDiffModelService implements IQuickDiffModelService { - declare readonly _serviceBrand: undefined; - - createQuickDiffModelReference(_resource: URI, _options?: QuickDiffModelOptions): undefined { - return undefined; - } -} - -/** - * MainThreadExtensionService needs the extension-workbench token in order to - * complete the extension-host handshake. Review deliberately has no extension - * marketplace UI, so expose only the inert management surface while the stock - * extension scanner and language-provider APIs remain fully available. - */ -class WhiteboardExtensionsWorkbenchService implements IExtensionsWorkbenchService { - declare readonly _serviceBrand: undefined; - readonly onChange = Event.None as IExtensionsWorkbenchService['onChange']; - readonly onReset = Event.None as IExtensionsWorkbenchService['onReset']; - readonly local: IExtensionsWorkbenchService['local'] = []; - readonly installed: IExtensionsWorkbenchService['installed'] = []; - readonly outdated: IExtensionsWorkbenchService['outdated'] = []; - readonly whenInitialized = Promise.resolve(); - readonly onDidChangeExtensionsNotification = Event.None as IExtensionsWorkbenchService['onDidChangeExtensionsNotification']; - - queryLocal(): Promise { return Promise.resolve([]); } - queryGallery(..._args: unknown[]): Promise { return this.unavailable(); } - getExtensions(..._args: unknown[]): Promise { return Promise.resolve([]); } - getResourceExtensions(): Promise { return Promise.resolve([]); } - canInstall(): Promise { return Promise.resolve(true); } - install(..._args: unknown[]): Promise { return this.unavailable(); } - installInServer(): Promise { return this.unavailable(); } - downloadVSIX(): Promise { return this.unavailable(); } - uninstall(): Promise { return this.unavailable(); } - togglePreRelease(): Promise { return this.unavailable(); } - canSetLanguage(): boolean { return false; } - setLanguage(): Promise { return this.unavailable(); } - setEnablement(): Promise { return Promise.resolve(); } - isAutoUpdateEnabledFor(): boolean { return false; } - updateAutoUpdateEnablementFor(): Promise { return Promise.resolve(); } - shouldRequireConsentToUpdate(): Promise { return Promise.resolve(undefined); } - updateAutoUpdateForAllExtensions(): Promise { return Promise.resolve(); } - open(): Promise { return this.unavailable(); } - openSearch(): Promise { return this.unavailable(); } - getAutoUpdateValue(): 'off' { return 'off'; } - isAutoUpdateDelayed(): boolean { return false; } - getAutoUpdateDelayRemaining(): number { return 0; } - getAutoUpdateDelay(): number { return 0; } - checkForUpdates(): Promise { return Promise.resolve(); } - getExtensionRuntimeStatus(): undefined { return undefined; } - updateAll(): Promise { return Promise.resolve([]); } - updateRunningExtensions(): Promise { return Promise.resolve(); } - getExtensionsNotification(): undefined { return undefined; } - isExtensionIgnoredToSync(): boolean { return false; } - toggleExtensionIgnoredToSync(): Promise { return Promise.resolve(); } - toggleApplyExtensionToAllProfiles(): Promise { return Promise.resolve(); } - - private unavailable(): Promise { - return Promise.reject(new Error('Whiteboard does not expose extension management')); - } -} - -registerSingleton(IStatusbarService, WhiteboardStatusbarService, InstantiationType.Eager); -registerSingleton(IBannerService, WhiteboardBannerService, InstantiationType.Eager); -registerSingleton(IExtensionsWorkbenchService, WhiteboardExtensionsWorkbenchService, InstantiationType.Eager); -registerSingleton(IQuickDiffModelService, WhiteboardQuickDiffModelService, InstantiationType.Eager); -// The in-tab diff builds a MultiDiffEditorInput, which resolves its sources -// through this service. Review never imports the upstream multi-diff editor -// contribution, so this is its only registration. -registerSingleton(IMultiDiffSourceResolverService, MultiDiffSourceResolverService, InstantiationType.Delayed); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboard.common.main.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboard.common.main.ts deleted file mode 100644 index 7eeb189a5..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboard.common.main.ts +++ /dev/null @@ -1,285 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Review's curated workbench manifest. Keep this list explicit: importing the -// stock or Sessions manifests re-registers the chrome and product surfaces that -// Review intentionally does not ship. - -import { Event } from "../base/common/event.js"; -import { Disposable, type IDisposable } from "../base/common/lifecycle.js"; -import type { URI } from "../base/common/uri.js"; -import "../editor/editor.all.js"; -import { getColorRegistry } from "../platform/theme/common/colorUtils.js"; -import { agentsPanelBackground } from "../workbench/common/agentTheme.js"; -import { PANEL_BACKGROUND } from "../workbench/common/theme.js"; - -getColorRegistry().updateDefaultColor(PANEL_BACKGROUND, agentsPanelBackground); - -// Core editor/workbench API. -import "../workbench/api/browser/viewsExtensionPoint.js"; -import "../workbench/api/common/configurationExtensionPoint.js"; -import "../workbench/browser/actions/listCommands.js"; -import "../workbench/browser/actions/navigationActions.js"; -import "../workbench/browser/actions/quickAccessActions.js"; -import "../workbench/browser/actions/textInputActions.js"; -import "../workbench/browser/actions/widgetNavigationCommands.js"; -import "../workbench/browser/actions/windowActions.js"; -import "../workbench/browser/actions/workspaceActions.js"; -import "../workbench/browser/actions/workspaceCommands.js"; -import "../workbench/browser/parts/editor/diffEditor.workbench.contribution.js"; -import "../workbench/browser/parts/editor/editor.contribution.js"; -import "../workbench/browser/workbench.contribution.js"; -import "../workbench/services/actions/common/menusExtensionPoint.js"; -import "./whiteboardExtensionHost.contribution.js"; -// Core services required by editors, language features, webviews, and files. -import { OpenerService } from "../editor/browser/services/openerService.js"; -import "../editor/common/services/languageFeaturesService.js"; -import { IMarkerDecorationsService } from "../editor/common/services/markerDecorations.js"; -import { MarkerDecorationsService } from "../editor/common/services/markerDecorationsService.js"; -import "../editor/common/services/semanticTokensStylingService.js"; -import { ITextResourceConfigurationService } from "../editor/common/services/textResourceConfiguration.js"; -import { TextResourceConfigurationService } from "../editor/common/services/textResourceConfigurationService.js"; -import "../editor/common/services/treeViewsDndService.js"; -import "../platform/actions/common/actions.contribution.js"; -import { ContextKeyService } from "../platform/contextkey/browser/contextKeyService.js"; -import { IContextKeyService } from "../platform/contextkey/common/contextkey.js"; -import { IContextViewService } from "../platform/contextview/browser/contextView.js"; -import { ContextViewService } from "../platform/contextview/browser/contextViewService.js"; -import { IDownloadService } from "../platform/download/common/download.js"; -import { DownloadService } from "../platform/download/common/downloadService.js"; -import { AllowedExtensionsService } from "../platform/extensionManagement/common/allowedExtensionsService.js"; -import { GlobalExtensionEnablementService } from "../platform/extensionManagement/common/extensionEnablementService.js"; -import { - IAllowedExtensionsService, - IGlobalExtensionEnablementService, -} from "../platform/extensionManagement/common/extensionManagement.js"; -import { - ExtensionStorageService, - IExtensionStorageService, -} from "../platform/extensionManagement/common/extensionStorage.js"; -import "../platform/hover/browser/hoverService.js"; -import { InstantiationType, registerSingleton } from "../platform/instantiation/common/extensions.js"; -import { IListService, ListService } from "../platform/list/browser/listService.js"; -import { IMarkerService } from "../platform/markers/common/markers.js"; -import { MarkerService } from "../platform/markers/common/markerService.js"; -import { IOpenerService } from "../platform/opener/common/opener.js"; -import "../platform/undoRedo/common/undoRedoService.js"; -import { - IgnoredExtensionsManagementService, - IIgnoredExtensionsManagementService, -} from "../platform/userDataSync/common/ignoredExtensions.js"; -import { IUserDataSyncLogService } from "../platform/userDataSync/common/userDataSync.js"; -import { UserDataSyncLogService } from "../platform/userDataSync/common/userDataSyncLog.js"; -import "../platform/userInteraction/browser/userInteractionServiceImpl.js"; -import { IWebWorkerService } from "../platform/webWorker/browser/webWorkerService.js"; -import { WebWorkerService } from "../platform/webWorker/browser/webWorkerServiceImpl.js"; -import { - ChatContextPickService, - IChatContextPickService, -} from "../workbench/contrib/chat/browser/attachments/chatContextPickService.js"; -import { type IChatWidget, IChatWidgetService } from "../workbench/contrib/chat/browser/chat.js"; -import type { IChatEditorOptions } from "../workbench/contrib/chat/browser/widgetHosts/editor/chatEditor.js"; -import type { ChatAgentLocation } from "../workbench/contrib/chat/common/constants.js"; -import "../workbench/contrib/output/browser/output.contribution.js"; -import "../workbench/services/activity/browser/activityService.js"; -import "../workbench/services/authentication/browser/authenticationAccessService.js"; -import "../workbench/services/authentication/browser/authenticationExtensionsService.js"; -import "../workbench/services/authentication/browser/authenticationService.js"; -import "../workbench/services/authentication/browser/authenticationUsageService.js"; -import "../workbench/services/commands/common/commandService.js"; -import "../workbench/services/configuration/common/jsonEditingService.js"; -import "../workbench/services/dataChannel/browser/dataChannelService.js"; -import "../workbench/services/decorations/browser/decorationsService.js"; -import "../workbench/services/dialogs/common/dialogService.js"; -import "../workbench/services/editor/browser/codeEditorService.js"; -import "../workbench/services/editor/browser/editorPaneService.js"; -import "../workbench/services/editor/browser/editorResolverService.js"; -import "../workbench/services/editor/browser/editorService.js"; -import "../workbench/services/editor/common/customEditorLabelService.js"; -import type { PreferredGroup } from "../workbench/services/editor/common/editorService.js"; -import "../workbench/services/extensionManagement/browser/builtinExtensionsScannerService.js"; -import "../workbench/services/extensionManagement/browser/extensionEnablementService.js"; -import "../workbench/services/extensionManagement/common/extensionFeaturesManagemetService.js"; -import "../workbench/services/extensionManagement/common/extensionGalleryService.js"; -import "../workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.js"; -import "../workbench/services/extensionRecommendations/common/workspaceExtensionsConfig.js"; -import "../workbench/services/extensions/browser/extensionUrlHandler.js"; -import "../workbench/services/extensions/common/extensionManifestPropertiesService.js"; -import "../workbench/services/filesConfiguration/common/filesConfigurationService.js"; -import "../workbench/services/history/browser/historyService.js"; -import "../workbench/services/inlineCompletions/common/inlineCompletionsUnification.js"; -import "../workbench/services/keybinding/browser/keybindingService.js"; -import "../workbench/services/keybinding/common/keybindingEditing.js"; -import "../workbench/services/label/common/labelService.js"; -import "../workbench/services/language/common/languageService.js"; -import "../workbench/services/languageDetection/browser/languageDetectionWorkerServiceImpl.js"; -import "../workbench/services/log/common/defaultLogLevels.js"; -import "../workbench/services/model/common/modelService.js"; -import "../workbench/services/notification/common/notificationService.js"; -import "../workbench/services/preferences/browser/preferencesService.js"; -import "../workbench/services/progress/browser/progressService.js"; -import "../workbench/services/quickinput/browser/quickInputService.js"; -import "../workbench/services/remote/common/remoteExtensionsScanner.js"; -import "../workbench/services/textfile/common/textEditorService.js"; -import "../workbench/services/textMate/browser/textMateTokenizationFeature.contribution.js"; -import "../workbench/services/textmodelResolver/common/textModelResolverService.js"; -import "../workbench/services/textresourceProperties/common/textResourcePropertiesService.js"; -import "../workbench/services/themes/browser/workbenchThemeService.js"; -import "../workbench/services/treeSitter/browser/treeSitter.contribution.js"; -import "../workbench/services/untitled/common/untitledTextEditorService.js"; -import "../workbench/services/userActivity/browser/userActivityBrowser.js"; -import "../workbench/services/userActivity/common/userActivityService.js"; -import "../workbench/services/userAttention/browser/userAttentionBrowser.js"; -import "../workbench/services/userDataProfile/browser/userDataProfileImportExportService.js"; -import "../workbench/services/userDataProfile/browser/userDataProfileManagement.js"; -import "../workbench/services/userDataProfile/common/remoteUserDataProfiles.js"; -import "../workbench/services/userDataSync/browser/userDataSyncWorkbenchService.js"; -import "../workbench/services/userDataSync/common/userDataSyncUtil.js"; -import "../workbench/services/views/browser/viewDescriptorService.js"; -import "../workbench/services/views/browser/viewsService.js"; -import "../workbench/services/workingCopy/common/workingCopyEditorService.js"; -import "../workbench/services/workingCopy/common/workingCopyFileService.js"; -import "../workbench/services/workingCopy/common/workingCopyService.js"; -import "../workbench/services/workspaces/common/canonicalUriService.js"; -import "../workbench/services/workspaces/common/editSessionIdentityService.js"; - -class WhiteboardChatWidgetService implements IChatWidgetService { - declare readonly _serviceBrand: undefined; - - readonly lastFocusedWidget = undefined; - readonly onDidAddWidget = Event.None; - readonly onDidBackgroundSession = Event.None; - readonly onDidChangeFocusedWidget = Event.None; - readonly onDidChangeFocusedSession = Event.None; - - reveal(_widget: IChatWidget, _preserveFocus?: boolean): Promise { - return Promise.resolve(false); - } - - revealWidget(_preserveFocus?: boolean): Promise { - return Promise.resolve(undefined); - } - - getAllWidgets(): readonly IChatWidget[] { - return []; - } - - getWidgetByInputUri(_uri: URI): undefined { - return undefined; - } - - openSession(_sessionResource: URI): Promise; - openSession(_sessionResource: URI, _target?: PreferredGroup, _options?: IChatEditorOptions): Promise; - openSession(): Promise { - return Promise.resolve(undefined); - } - - getWidgetBySessionResource(_sessionResource: URI): undefined { - return undefined; - } - - getWidgetsByLocations(_location: ChatAgentLocation): readonly IChatWidget[] { - return []; - } - - register(_newWidget: IChatWidget): IDisposable { - return Disposable.None; - } -} - -registerSingleton(IUserDataSyncLogService, UserDataSyncLogService, InstantiationType.Delayed); -registerSingleton(IAllowedExtensionsService, AllowedExtensionsService, InstantiationType.Delayed); -registerSingleton(IIgnoredExtensionsManagementService, IgnoredExtensionsManagementService, InstantiationType.Delayed); -registerSingleton(IGlobalExtensionEnablementService, GlobalExtensionEnablementService, InstantiationType.Delayed); -registerSingleton(IExtensionStorageService, ExtensionStorageService, InstantiationType.Delayed); -registerSingleton(IContextViewService, ContextViewService, InstantiationType.Delayed); -registerSingleton(IListService, ListService, InstantiationType.Delayed); -registerSingleton(IMarkerDecorationsService, MarkerDecorationsService, InstantiationType.Delayed); -registerSingleton(IMarkerService, MarkerService, InstantiationType.Delayed); -registerSingleton(IContextKeyService, ContextKeyService, InstantiationType.Delayed); -registerSingleton(IChatContextPickService, ChatContextPickService, InstantiationType.Delayed); -registerSingleton(IChatWidgetService, WhiteboardChatWidgetService, InstantiationType.Delayed); -registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService, InstantiationType.Delayed); -registerSingleton(IDownloadService, DownloadService, InstantiationType.Delayed); -registerSingleton(IOpenerService, OpenerService, InstantiationType.Delayed); -registerSingleton(IWebWorkerService, WebWorkerService, InstantiationType.Delayed); - -// Curated contributions: editor/files/theme/webview/outline/logs only. -import "../workbench/contrib/bulkEdit/browser/bulkEditService.js"; -import "../workbench/contrib/files/browser/fileActions.contribution.js"; -import "../workbench/contrib/files/browser/files.contribution.js"; -import "../workbench/contrib/logs/common/logs.contribution.js"; -import "./browser/parts/canvas/whiteboardCanvasEditor.contribution.js"; -import "./browser/parts/canvas/whiteboardFind.contribution.js"; -import "./browser/whiteboardCommunity.contribution.js"; -import "./browser/whiteboardTheme.contribution.js"; -import "./contrib/explorer/whiteboardFileTree.contribution.js"; -import "./contrib/extensions/whiteboardCuratedExtensions.contribution.js"; -import "./contrib/install/whiteboardCliInstall.contribution.js"; -import "./contrib/quickaccess/whiteboardQuickAccess.contribution.js"; -import "./contrib/settings/whiteboardSettings.contribution.js"; -import "./contrib/telemetry/whiteboardLspTelemetry.contribution.js"; -import "./contrib/telemetry/whiteboardTelemetry.contribution.js"; -// editor.all instantiates RenameSymbolProcessor; keep its service-only peer. -import "../workbench/contrib/accessibility/browser/accessibility.contribution.js"; -import "../workbench/contrib/accessibilitySignals/browser/accessibilitySignal.contribution.js"; -import "../workbench/contrib/codeActions/browser/codeActions.contribution.js"; -import "../workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.js"; -import "../workbench/contrib/codeEditor/browser/workbenchReferenceSearch.js"; -import "../workbench/contrib/commands/common/commands.contribution.js"; -import { IDebugService } from "../workbench/contrib/debug/common/debug.js"; -import { IDebugVisualizerService } from "../workbench/contrib/debug/common/debugVisualizers.js"; -import { NullDebugService, NullDebugVisualizerService } from "../workbench/contrib/debug/common/nullDebugService.js"; -import "../workbench/contrib/folding/browser/folding.contribution.js"; -import "../workbench/contrib/format/browser/format.contribution.js"; -import "../workbench/contrib/inlineCompletions/browser/renameSymbolTrackerService.js"; -import "../workbench/contrib/keybindings/browser/keybindings.contribution.js"; -import "../workbench/contrib/list/browser/list.contribution.js"; -import "../workbench/contrib/opener/browser/opener.contribution.js"; -import "../workbench/contrib/sash/browser/sash.contribution.js"; -import "../workbench/contrib/search/browser/searchQuickAccess.contribution.js"; -import "../workbench/contrib/snippets/browser/snippets.service.contribution.js"; -import "../workbench/contrib/speech/browser/speech.contribution.js"; -import "../workbench/contrib/themes/browser/themes.contribution.js"; -import "../workbench/contrib/webview/browser/webview.contribution.js"; -import "../workbench/contrib/webviewPanel/browser/webviewPanel.contribution.js"; -import "../workbench/contrib/workspace/browser/workspace.contribution.js"; -import "../workbench/services/outline/browser/outlineService.js"; -registerSingleton(IDebugService, NullDebugService, InstantiationType.Delayed); -registerSingleton(IDebugVisualizerService, NullDebugVisualizerService, InstantiationType.Delayed); -// Sessions supplies the native fixed-grid shell; Review replaces its session -// model, setup flow, and content part and deliberately imports no Agents UI. -import "../workbench/browser/parts/editor/editorParts.js"; -import { IWhiteboardCanvasPartsService, WhiteboardCanvasParts } from "./browser/parts/canvas/whiteboardCanvasPart.js"; -import { IWhiteboardExplorerPartsService, WhiteboardExplorerParts } from "./browser/parts/explorer/whiteboardExplorerPart.js"; -import "./browser/whiteboardPaneCompositePartService.js"; -import "./common/whiteboardConfiguration.js"; -import { IWhiteboardVerbsService, WhiteboardVerbsService } from "./contrib/verbs/whiteboardVerbs.js"; -import { IWhiteboardApiCatalogService, WhiteboardApiCatalogService } from "./services/whiteboardApiCatalogService.js"; -import { IWhiteboardApiSourceService, WhiteboardApiSourceService } from "./services/whiteboardApiSourceService.js"; -import { - IWhiteboardCanvasEditorTabsService, - WhiteboardCanvasEditorTabsService, -} from "./services/whiteboardCanvasEditorTabsService.js"; -import { - IWhiteboardDesktopConnectionService, - WhiteboardDesktopConnectionService, -} from "./services/whiteboardDesktopConnectionService.js"; -import { IWhiteboardTelemetryService, WhiteboardTelemetryService } from "./services/whiteboardTelemetryService.js"; -import "./services/whiteboardWorkbenchServices.js"; -import "./services/whiteboardLocalLanguageFeatures.js"; - -registerSingleton(IWhiteboardDesktopConnectionService, WhiteboardDesktopConnectionService, InstantiationType.Eager); -registerSingleton(IWhiteboardTelemetryService, WhiteboardTelemetryService, InstantiationType.Delayed); - -registerSingleton(IWhiteboardCanvasEditorTabsService, WhiteboardCanvasEditorTabsService, InstantiationType.Delayed); - -registerSingleton(IWhiteboardApiSourceService, WhiteboardApiSourceService, InstantiationType.Delayed); -registerSingleton(IWhiteboardApiCatalogService, WhiteboardApiCatalogService, InstantiationType.Delayed); -registerSingleton(IWhiteboardVerbsService, WhiteboardVerbsService, InstantiationType.Delayed); -registerSingleton(IWhiteboardCanvasPartsService, WhiteboardCanvasParts, InstantiationType.Eager); -registerSingleton(IWhiteboardExplorerPartsService, WhiteboardExplorerParts, InstantiationType.Eager); - -import "./contrib/sharing/whiteboardSharing.contribution.js"; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboard.desktop.main.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboard.desktop.main.ts deleted file mode 100644 index faf5be7d7..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboard.desktop.main.ts +++ /dev/null @@ -1,81 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Desktop-only service manifest. Product contributions such as chat, SCM, -// terminal, tasks, remote, surveys, profiles, and settings editors are -// intentionally absent. -// -// Updates are the exception: the update service is wired so Review can surface -// its own two toasts (see contrib/update). The stock update contribution stays -// out — its title bar entry requires the chat service, which Review omits. -import './whiteboard.common.main.js'; -import './electron-browser/whiteboard.main.js'; -import '../workbench/electron-browser/desktop.contribution.js'; -import '../workbench/electron-browser/parts/dialogs/dialog.contribution.js'; - -import '../workbench/services/textfile/electron-browser/nativeTextFileService.js'; -import '../workbench/services/dialogs/electron-browser/fileDialogService.js'; -import '../workbench/services/workspaces/electron-browser/workspacesService.js'; -import '../workbench/services/menubar/electron-browser/menubarService.js'; -import '../workbench/services/update/electron-browser/updateService.js'; -import '../workbench/services/url/electron-browser/urlService.js'; -import '../workbench/services/lifecycle/electron-browser/lifecycleService.js'; -import '../workbench/services/host/electron-browser/nativeHostService.js'; -import '../platform/meteredConnection/electron-browser/meteredConnectionService.js'; -import '../workbench/services/request/electron-browser/requestService.js'; -import '../workbench/services/clipboard/electron-browser/clipboardService.js'; -import '../workbench/services/contextmenu/electron-browser/contextmenuService.js'; -import '../workbench/services/configurationResolver/electron-browser/configurationResolverService.js'; -import '../workbench/services/accessibility/electron-browser/accessibilityService.js'; -import '../workbench/services/keybinding/electron-browser/nativeKeyboardLayout.js'; -import '../workbench/services/path/electron-browser/pathService.js'; -import '../workbench/services/themes/electron-browser/nativeHostColorSchemeService.js'; -import '../workbench/services/extensionManagement/electron-browser/extensionManagementService.js'; -import '../workbench/services/encryption/electron-browser/encryptionService.js'; -import '../workbench/services/imageResize/electron-browser/imageResizeService.js'; -import '../workbench/services/secrets/electron-browser/secretStorageService.js'; -import '../workbench/services/localization/electron-browser/languagePackService.js'; -import '../workbench/services/telemetry/electron-browser/telemetryService.js'; -import '../workbench/services/extensions/electron-browser/extensionHostStarter.js'; -import '../platform/extensionResourceLoader/common/extensionResourceLoaderService.js'; -import '../workbench/services/localization/electron-browser/localeService.js'; -import '../workbench/services/extensions/electron-browser/extensionsScannerService.js'; -import '../workbench/services/extensionManagement/electron-browser/extensionManagementServerService.js'; -import '../workbench/services/extensionManagement/electron-browser/extensionGalleryManifestService.js'; -import '../workbench/services/userDataSync/electron-browser/userDataSyncService.js'; -import '../workbench/services/userDataSync/browser/userDataSyncEnablementService.js'; -import '../workbench/services/timer/electron-browser/timerService.js'; -import '../workbench/services/environment/electron-browser/shellEnvironmentService.js'; -import '../workbench/services/integrity/electron-browser/integrityService.js'; -import '../workbench/services/workingCopy/electron-browser/workingCopyBackupService.js'; -import '../workbench/services/checksum/electron-browser/checksumService.js'; -import '../workbench/services/files/electron-browser/elevatedFileService.js'; -import '../workbench/services/search/electron-browser/searchService.js'; -import '../workbench/services/workingCopy/electron-browser/workingCopyHistoryService.js'; -import '../workbench/services/extensions/electron-browser/nativeExtensionService.js'; -import '../platform/userDataProfile/electron-browser/userDataProfileStorageService.js'; -import '../workbench/services/auxiliaryWindow/electron-browser/auxiliaryWindowService.js'; -import '../platform/extensionManagement/electron-browser/extensionsProfileScannerService.js'; -import '../platform/sandbox/electron-browser/sandboxHelperService.js'; -import '../workbench/services/process/electron-browser/processService.js'; -import '../platform/remote/electron-browser/sharedProcessTunnelService.js'; -import '../workbench/services/tunnel/electron-browser/tunnelService.js'; -import '../workbench/contrib/debug/electron-browser/extensionHostDebugService.js'; -import '../platform/diagnostics/electron-browser/diagnosticsService.js'; - -import { registerSingleton } from '../platform/instantiation/common/extensions.js'; -import { IUserDataInitializationService, UserDataInitializationService } from '../workbench/services/userData/browser/userDataInit.js'; -import { SyncDescriptor } from '../platform/instantiation/common/descriptors.js'; -registerSingleton(IUserDataInitializationService, new SyncDescriptor(UserDataInitializationService, [[]], true)); - -import '../workbench/contrib/logs/electron-browser/logs.contribution.js'; -import '../workbench/contrib/files/electron-browser/fileActions.contribution.js'; -import '../workbench/contrib/codeEditor/electron-browser/codeEditor.contribution.js'; -import '../workbench/services/themes/electron-browser/themes.contribution.js'; -import '../workbench/contrib/webview/electron-browser/webview.contribution.js'; -import '../workbench/contrib/splash/electron-browser/splash.contribution.js'; -import './contrib/update/whiteboardUpdate.contribution.js'; - -export { main } from './electron-browser/whiteboard.main.js'; diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboardExtensionHost.contribution.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboardExtensionHost.contribution.ts deleted file mode 100644 index cb1a650cf..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboardExtensionHost.contribution.ts +++ /dev/null @@ -1,76 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IInstantiationService } from '../platform/instantiation/common/instantiation.js'; -import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from '../workbench/common/contributions.js'; -import { LanguageConfigurationFileHandler } from '../workbench/contrib/codeEditor/common/languageConfigurationExtensionPoint.js'; -import { JSONValidationExtensionPoint } from '../workbench/api/common/jsonValidationExtensionPoint.js'; -import { StatusBarItemsExtensionPoint } from '../workbench/api/browser/statusBarExtensionPoint.js'; -import { CSSExtensionPoint } from '../workbench/services/themes/browser/cssExtensionPoint.js'; -import { ColorExtensionPoint } from '../workbench/services/themes/common/colorExtensionPoint.js'; -import { IconExtensionPoint } from '../workbench/services/themes/common/iconExtensionPoint.js'; -import { TokenClassificationExtensionPoints } from '../workbench/services/themes/common/tokenClassificationExtensionPoint.js'; - -// Review exposes the generic editor/document/provider bridge. The stock Node -// extension host eagerly initializes a small set of additional API services; -// Review registers explicit unsupported peers for those APIs rather than -// pulling their terminal/task/authentication/chat product graphs into the app. -import './whiteboardExtensionHostUnsupportedApiPeers.js'; -import '../workbench/api/browser/mainThreadLocalization.js'; -import '../workbench/api/browser/mainThreadBulkEdits.js'; -import '../workbench/api/browser/mainThreadClipboard.js'; -import '../workbench/api/browser/mainThreadCommands.js'; -import '../workbench/api/browser/mainThreadConfiguration.js'; -import '../workbench/api/browser/mainThreadConsole.js'; -import '../workbench/api/browser/mainThreadDebugService.js'; -import '../workbench/api/browser/mainThreadDecorations.js'; -import '../workbench/api/browser/mainThreadDiagnostics.js'; -import '../workbench/api/browser/mainThreadDialogs.js'; -import '../workbench/api/browser/mainThreadDocumentContentProviders.js'; -import '../workbench/api/browser/mainThreadDocuments.js'; -import '../workbench/api/browser/mainThreadDocumentsAndEditors.js'; -import '../workbench/api/browser/mainThreadEditor.js'; -import '../workbench/api/browser/mainThreadEditors.js'; -import '../workbench/api/browser/mainThreadEditorTabs.js'; -import '../workbench/api/browser/mainThreadErrors.js'; -import '../workbench/api/browser/mainThreadExtensionService.js'; -import '../workbench/api/browser/mainThreadFileSystem.js'; -import '../workbench/api/browser/mainThreadFileSystemEventService.js'; -import '../workbench/api/browser/mainThreadLanguageFeatures.js'; -import '../workbench/api/browser/mainThreadLanguages.js'; -import '../workbench/api/browser/mainThreadLogService.js'; -import '../workbench/api/browser/mainThreadMessageService.js'; -import '../workbench/api/browser/mainThreadOutputService.js'; -import '../workbench/api/browser/mainThreadProgress.js'; -import '../workbench/api/browser/mainThreadQuickOpen.js'; -import '../workbench/api/browser/mainThreadRemoteConnectionData.js'; -import '../workbench/api/browser/mainThreadSaveParticipant.js'; -import '../workbench/api/browser/mainThreadSearch.js'; -import '../workbench/api/browser/mainThreadStatusBar.js'; -import '../workbench/api/browser/mainThreadStorage.js'; -import '../workbench/api/browser/mainThreadTelemetry.js'; -import '../workbench/api/browser/mainThreadTheming.js'; -import '../workbench/api/browser/mainThreadTreeViews.js'; -import '../workbench/api/browser/mainThreadDownloadService.js'; -import '../workbench/api/browser/mainThreadWindow.js'; -import '../workbench/api/browser/mainThreadWorkspace.js'; -import '../workbench/api/browser/mainThreadLabelService.js'; -import '../workbench/api/browser/mainThreadSecretState.js'; - -class WhiteboardExtensionPoints implements IWorkbenchContribution { - static readonly ID = 'review.contrib.extensionPoints'; - - constructor(@IInstantiationService instantiationService: IInstantiationService) { - instantiationService.createInstance(JSONValidationExtensionPoint); - instantiationService.createInstance(ColorExtensionPoint); - instantiationService.createInstance(IconExtensionPoint); - instantiationService.createInstance(TokenClassificationExtensionPoints); - instantiationService.createInstance(LanguageConfigurationFileHandler); - instantiationService.createInstance(StatusBarItemsExtensionPoint); - instantiationService.createInstance(CSSExtensionPoint); - } -} - -registerWorkbenchContribution2(WhiteboardExtensionPoints.ID, WhiteboardExtensionPoints, WorkbenchPhase.BlockStartup); diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboardExtensionHostUnsupportedApiPeers.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboardExtensionHostUnsupportedApiPeers.ts deleted file mode 100644 index 80421c51d..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/whiteboardExtensionHostUnsupportedApiPeers.ts +++ /dev/null @@ -1,100 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { UriComponents } from '../base/common/uri.js'; -import { MainContext } from '../workbench/api/common/extHost.protocol.js'; -import { extHostNamedCustomer, IExtHostContext } from '../workbench/services/extensions/common/extHostCustomers.js'; - -function unavailable(api: string): Promise { - return Promise.reject(new Error(`Whiteboard does not expose the ${api} API`)); -} - -@extHostNamedCustomer(MainContext.MainThreadAuthentication) -export class WhiteboardMainThreadAuthentication { - constructor(_context: IExtHostContext) { } - dispose(): void { } - $registerAuthenticationProvider(): Promise { return Promise.resolve(); } - $unregisterAuthenticationProvider(): Promise { return Promise.resolve(); } - $ensureProvider(): Promise { return Promise.resolve(); } - $sendDidChangeSessions(): Promise { return Promise.resolve(); } - $getSession(): Promise { return Promise.resolve(undefined); } - $getAccounts(): Promise { return Promise.resolve([]); } - $removeSession(): Promise { return Promise.resolve(); } - $waitForUriHandler(expectedUri: UriComponents): Promise { return Promise.resolve(expectedUri); } - $showContinueNotification(): Promise { return Promise.resolve(false); } - $showDeviceCodeModal(): Promise { return Promise.resolve(false); } - $promptForClientRegistration(): Promise { return Promise.resolve(undefined); } - $promptForResourceClientSecret(): Promise { return Promise.resolve(undefined); } - $registerDynamicAuthenticationProvider(): Promise { return Promise.resolve(); } - $setSessionsForDynamicAuthProvider(): Promise { return Promise.resolve(); } - $sendDidChangeDynamicProviderInfo(): Promise { return Promise.resolve(); } -} - -@extHostNamedCustomer(MainContext.MainThreadTerminalService) -export class WhiteboardMainThreadTerminalService { - constructor(_context: IExtHostContext) { } - dispose(): void { } - $createTerminal(): Promise { return unavailable('terminal'); } - $dispose(): void { } - $hide(): void { } - $sendText(): void { } - $show(): void { } - $registerProcessSupport(): void { } - $registerProfileProvider(): void { } - $unregisterProfileProvider(): void { } - $registerCompletionProvider(): void { } - $unregisterCompletionProvider(): void { } - $registerQuickFixProvider(): void { } - $unregisterQuickFixProvider(): void { } - $setEnvironmentVariableCollection(): void { } - $startSendingDataEvents(): void { } - $stopSendingDataEvents(): void { } - $startSendingCommandEvents(): void { } - $stopSendingCommandEvents(): void { } - $startLinkProvider(): void { } - $stopLinkProvider(): void { } - $sendProcessData(): void { } - $sendProcessReady(): void { } - $sendProcessProperty(): void { } - $sendProcessExit(): void { } -} - -@extHostNamedCustomer(MainContext.MainThreadTask) -export class WhiteboardMainThreadTask { - constructor(_context: IExtHostContext) { } - dispose(): void { } - $createTaskId(): Promise { return unavailable('task'); } - $registerTaskProvider(): Promise { return Promise.resolve(); } - $unregisterTaskProvider(): Promise { return Promise.resolve(); } - $fetchTasks(): Promise { return Promise.resolve([]); } - $getTaskExecution(): Promise { return unavailable('task'); } - $executeTask(): Promise { return unavailable('task'); } - $terminateTask(): Promise { return Promise.resolve(); } - $registerTaskSystem(): void { } - $customExecutionComplete(): Promise { return Promise.resolve(); } - $registerSupportedExecutions(): Promise { return Promise.resolve(); } -} - -@extHostNamedCustomer(MainContext.MainThreadLanguageModelTools) -export class WhiteboardMainThreadLanguageModelTools { - constructor(_context: IExtHostContext) { } - dispose(): void { } - $getTools(): Promise { return Promise.resolve([]); } - $acceptToolProgress(): void { } - $invokeTool(): Promise { return unavailable('language model tools'); } - $countTokensForInvocation(): Promise { return unavailable('language model tools'); } - $registerTool(): void { } - $registerToolWithDefinition(): void { } - $unregisterTool(): void { } -} - -@extHostNamedCustomer(MainContext.MainThreadUrls) -export class WhiteboardMainThreadUrls { - constructor(_context: IExtHostContext) { } - dispose(): void { } - $registerUriHandler(): Promise { return Promise.resolve(); } - $unregisterUriHandler(): Promise { return Promise.resolve(); } - $createAppUri(uri: UriComponents): Promise { return Promise.resolve(uri); } -} diff --git a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/workspaceTrustConfigurationFilter.test.ts b/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/workspaceTrustConfigurationFilter.test.ts deleted file mode 100644 index 227a76ea9..000000000 --- a/apps/whiteboard-desktop/code-oss/src/vs/whiteboard/workspaceTrustConfigurationFilter.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) dev.fast. All rights reserved. - * Licensed under the MIT License. See LICENSE in the repository root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Behavioural guard for the CVE-2026-81376 / CVE-2026-70334 backport -// (upstream 0684cb5905a3f23156f45a28135326e09310ff4d). An untrusted workspace -// could express a restricted setting as a nested object instead of a dotted -// key and slip past the Restricted Mode filter. These assertions fail against -// the unpatched parser, so they prove the fix rather than merely detecting a -// change to it. See apps/whiteboard-desktop/UPSTREAM. - -import assert from "node:assert/strict"; -import test from "node:test"; - -import { ConfigurationModelParser } from "../platform/configuration/common/configurationModels.js"; -import { - ConfigurationScope, - Extensions as ConfigurationExtensions, - type IConfigurationRegistry, -} from "../platform/configuration/common/configurationRegistry.js"; -import { NullLogService } from "../platform/log/common/log.js"; -import { Registry } from "../platform/registry/common/platform.js"; - -Registry.as( - ConfigurationExtensions.Configuration, -).registerConfiguration({ - id: "whiteboardTrustFilterFixture", - type: "object", - properties: { - "whiteboardTrustFixture.restricted": { - type: "string", - restricted: true, - scope: ConfigurationScope.RESOURCE, - }, - "whiteboardTrustFixture.safe": { - type: "string", - scope: ConfigurationScope.RESOURCE, - }, - "whiteboardTrustFixture.object": { - type: "object", - scope: ConfigurationScope.RESOURCE, - }, - }, -}); - -function parseUntrusted(content: object) { - const parser = new ConfigurationModelParser("test", new NullLogService()); - parser.parse(JSON.stringify(content), { skipRestricted: true }); - return parser; -} - -test("filters a restricted setting written as a dotted key", () => { - const parsed = parseUntrusted({ - "whiteboardTrustFixture.restricted": "attacker", - "whiteboardTrustFixture.safe": "kept", - }); - - assert.equal( - parsed.configurationModel.getValue("whiteboardTrustFixture.restricted"), - undefined, - ); - assert.equal( - parsed.configurationModel.getValue("whiteboardTrustFixture.safe"), - "kept", - ); - assert.deepEqual(parsed.restrictedConfigurations, [ - "whiteboardTrustFixture.restricted", - ]); -}); - -test("filters the same setting written as a nested object", () => { - const parsed = parseUntrusted({ - whiteboardTrustFixture: { restricted: "attacker", safe: "kept" }, - }); - - assert.equal( - parsed.configurationModel.getValue("whiteboardTrustFixture.restricted"), - undefined, - ); - assert.equal( - parsed.configurationModel.getValue("whiteboardTrustFixture.safe"), - "kept", - ); - assert.deepEqual(parsed.restrictedConfigurations, [ - "whiteboardTrustFixture.restricted", - ]); -}); - -test("leaves an object-valued setting intact", () => { - const parsed = parseUntrusted({ - "whiteboardTrustFixture.object": { a: 1, b: { c: 2 } }, - }); - - assert.deepEqual( - parsed.configurationModel.getValue("whiteboardTrustFixture.object"), - { a: 1, b: { c: 2 } }, - ); -}); - -test("leaves unregistered nested values reachable", () => { - const parsed = parseUntrusted({ unregistered: { deep: { value: 5 } } }); - - assert.equal( - parsed.configurationModel.getValue("unregistered.deep.value"), - 5, - ); -}); diff --git a/apps/whiteboard-desktop/package.json b/apps/whiteboard-desktop/package.json deleted file mode 100644 index 8aaddf83b..000000000 --- a/apps/whiteboard-desktop/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "@dev.fast/whiteboard-desktop", - "version": "0.0.33", - "private": true, - "license": "MIT", - "type": "module", - "scripts": { - "app:build": "bash scripts/build.sh", - "app:package:linux": "bash scripts/package-linux.sh", - "app:package:linux:distributions": "bash scripts/package-linux-distributions.sh", - "app:package:macos": "bash scripts/package-macos.sh", - "app:notarize:macos": "bash scripts/notarize-macos.sh", - "app:run": "bash scripts/run.sh", - "app:watch": "pnpm run protocol:sync && npm --prefix code-oss run watch", - "protocol:sync": "node scripts/protocol-sync.mjs", - "smoke:error-telemetry": "node scripts/smoke-error-telemetry.mjs", - "smoke:telemetry-delivery": "node scripts/smoke-telemetry-delivery.mjs", - "test:e2e:lsp": "node scripts/lsp-e2e.mjs", - "pretest": "pnpm run protocol:sync", - "test": "node --test \"scripts/**/*.test.mjs\" && TSX_TSCONFIG_PATH=tsconfig.test.json node --import tsx --test \"code-oss/src/vs/whiteboard/**/*.test.ts\"", - "pretypecheck": "pnpm run protocol:sync", - "typecheck": "npm --prefix code-oss run typecheck-client" - }, - "dependencies": { - "@dev.fast/whiteboard": "workspace:*", - "@dev.fast/whiteboard-protocol": "workspace:*" - }, - "devDependencies": { - "@dev.fast/whiteboard-canvas": "workspace:*", - "@types/node": "24.12.2", - "jsdom": "29.1.1", - "playwright": "1.62.1", - "tsx": "4.21.0", - "typescript": "6.0.3" - }, - "engines": { - "node": ">=24 <25" - } -} diff --git a/apps/whiteboard-desktop/scripts/canvas-host-layout.test.mjs b/apps/whiteboard-desktop/scripts/canvas-host-layout.test.mjs deleted file mode 100644 index 78864202a..000000000 --- a/apps/whiteboard-desktop/scripts/canvas-host-layout.test.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import assert from "node:assert/strict"; -import { readFile } from "node:fs/promises"; -import test from "node:test"; - -const whiteboardCanvasPart = await readFile( - new URL( - "../code-oss/src/vs/whiteboard/browser/parts/canvas/whiteboardCanvasPart.ts", - import.meta.url, - ), - "utf8", -); - -const whiteboardCss = await readFile( - new URL("../code-oss/src/vs/whiteboard/browser/media/whiteboard.css", import.meta.url), - "utf8", -); - -test("peek overflow widgets host lives outside the canvas root", () => { - // Inside the workbench container (theme variables are scoped to - // .monaco-workbench), never inside the canvas surface. - assert.match( - whiteboardCanvasPart, - /layoutService\s*\.getContainer\(getWindow\(parent\)\)\s*\.appendChild\(overflowWidgets\)/, - ); - assert.match( - whiteboardCanvasPart, - /setOverflowWidgetsDomNode\(overflowWidgets\)/, - ); - assert.match( - whiteboardCss, - /\.whiteboard-overflow-widgets\s*{[^}]*position:\s*fixed;/s, - ); -}); - -test("Review canvas restores text selection inside the workbench", () => { - assert.match( - whiteboardCss, - /\.whiteboard-canvas-part \.whiteboard-canvas-host\s*{[^}]*-webkit-user-select:\s*text;[^}]*user-select:\s*text;/s, - ); -}); diff --git a/apps/whiteboard-desktop/scripts/curated-keymap-and-quick-access.test.mjs b/apps/whiteboard-desktop/scripts/curated-keymap-and-quick-access.test.mjs deleted file mode 100644 index 43e4ba977..000000000 --- a/apps/whiteboard-desktop/scripts/curated-keymap-and-quick-access.test.mjs +++ /dev/null @@ -1,33 +0,0 @@ -import assert from "node:assert/strict"; -import { readFile } from "node:fs/promises"; -import test from "node:test"; - -const quickAccess = await readFile( - new URL( - "../code-oss/src/vs/whiteboard/contrib/quickaccess/whiteboardQuickAccess.contribution.ts", - import.meta.url, - ), - "utf8", -); - -const curatedExtensions = await readFile( - new URL( - "../code-oss/src/vs/whiteboard/contrib/extensions/whiteboardCuratedExtensions.contribution.ts", - import.meta.url, - ), - "utf8", -); - -test("keeps extension-contributed commands visible in Review quick access", () => { - assert.match(quickAccess, /IExtensionService/); - assert.match(quickAccess, /extension\.contributes\?\.commands/); - assert.match(quickAccess, /extensionCommands\.has\(commandId\)/); -}); - -test("drives curated keymap defaults from whiteboard.keymap", () => { - assert.match( - curatedExtensions, - /getValue\(WHITEBOARD_KEYMAP_SETTING\)/, - ); - assert.match(curatedExtensions, /defaultsApplied\.v2/); -}); diff --git a/apps/whiteboard-desktop/scripts/darwin-payload-manifest.sh b/apps/whiteboard-desktop/scripts/darwin-payload-manifest.sh deleted file mode 100644 index 75c8e5db7..000000000 --- a/apps/whiteboard-desktop/scripts/darwin-payload-manifest.sh +++ /dev/null @@ -1,24 +0,0 @@ -# shellcheck shell=bash -# This file exports variables to the scripts that source it. -# shellcheck disable=SC2034 - -# Paths are relative to the monorepo root. macOS packaging checks every -# required path after it extracts the Linux-built Darwin payload. -DARWIN_PAYLOAD_CURATED_EXTENSIONS_PATH="apps/whiteboard-desktop/code-oss/.build/review-curated-extensions/darwin-arm64" - -DARWIN_PAYLOAD_REQUIRED_PATHS=( - "apps/whiteboard-desktop/code-oss/out-vscode-min" - "apps/whiteboard-desktop/code-oss/.build/extensions" - "$DARWIN_PAYLOAD_CURATED_EXTENSIONS_PATH" - "packages/whiteboard/app/dist/desktop" - "packages/whiteboard/dist" - "packages/whiteboard/tutorial" - "packages/local-vcs/dist" -) - -# These build intermediates belong in the archive, but the macOS wrapper does -# not read them directly before Gulp assembles the application. -DARWIN_PAYLOAD_ARCHIVE_ONLY_PATHS=( - "apps/whiteboard-desktop/code-oss/out-build" - "apps/whiteboard-desktop/code-oss/out" -) diff --git a/apps/whiteboard-desktop/scripts/desktop-branding.test.mjs b/apps/whiteboard-desktop/scripts/desktop-branding.test.mjs deleted file mode 100644 index c298d40f6..000000000 --- a/apps/whiteboard-desktop/scripts/desktop-branding.test.mjs +++ /dev/null @@ -1,16 +0,0 @@ -import assert from "node:assert/strict"; -import { readFile } from "node:fs/promises"; -import test from "node:test"; - -const readSource = (relativePath) => - readFile(new URL(relativePath, import.meta.url), "utf8"); - -const product = JSON.parse(await readSource("../code-oss/product.json")); - -test("keeps compatibility-sensitive Desktop identifiers unchanged", () => { - assert.equal(product.darwinBundleIdentifier, "dev.fast.review"); - assert.equal(product.updateUrl, "https://update.dev.fast"); - assert.equal(product.urlProtocol, "dev-fast-review"); - assert.equal(product.dataFolderName, ".dev-fast-review"); - assert.equal(product.sharedDataFolderName, ".dev-fast-review-shared"); -}); diff --git a/apps/whiteboard-desktop/scripts/e2e/journeys/home-multi-whiteboard.mjs b/apps/whiteboard-desktop/scripts/e2e/journeys/home-multi-whiteboard.mjs deleted file mode 100644 index d385a9f41..000000000 --- a/apps/whiteboard-desktop/scripts/e2e/journeys/home-multi-whiteboard.mjs +++ /dev/null @@ -1,203 +0,0 @@ -/** Three reviews over two worktrees: Home groups, filters and opens them, and dismiss / restore / delete reach the store. */ -import assert from "node:assert/strict"; -import { writeFile } from "node:fs/promises"; -import path from "node:path"; - -import { - createWhiteboard, - openHome, - orderWhiteboardBlocks, - pickWhiteboard, -} from "../harness.mjs"; - -export const name = "home-multi-whiteboard"; - -export const phase = 1; - -export const options = {}; - -/** Every locator this journey uses, rebuilt from the current `ctx.page` after each return to Home. */ -function homeUi(ctx) { - const home = ctx.page.locator("main.whiteboard-home"); - - return { - home, - cards: home.locator(".whiteboard-home-card"), - rows: home.locator(".whiteboard-home-list-row"), - tabs: ctx.page.locator(".tabs-container .tab"), - // One canvas part renders whichever review tab is active, so the heading says which review the reader is on. - canvas: ctx.page.locator(".whiteboard-canvas-root [data-whiteboard-api]"), - }; -} - -/** The review ids the store lists; `apiOk` keeps "the deleted review is gone" from passing on an error body. */ -async function listedWhiteboardIds(ctx) { - return (await ctx.apiOk("/sessions-api")).map((summary) => summary.sessionId); -} - -export async function run(ctx) { - const { git, root, until } = ctx; - - const first = await createWhiteboard(ctx, { - title: "Order review", - blocks: orderWhiteboardBlocks, - }); - - const second = await createWhiteboard(ctx, { - title: "Second review", - blocks: [{ type: "markdown", markdown: "Second look at the same change." }], - }); - - // Home groups by checkout, not by repository, so a second worktree makes two groups out of three reviews. - const other = path.join(root, "repo-b"); - - await git("worktree", "add", "-q", "-b", "feature-b", other, ctx.head); - await writeFile( - path.join(other, "order.ts"), - 'export const status = "shipped";\n', - ); - await git("-C", other, "commit", "-qam", "Ship"); - - const headB = await git("-C", other, "rev-parse", "HEAD"); - - const third = await createWhiteboard(ctx, { - title: "Worktree B review", - repoPath: other, - base: ctx.head, - head: headB, - blocks: [{ type: "markdown", markdown: "Shipped." }], - }); - - await openHome(ctx); - - let { home, cards, rows, tabs, canvas } = homeUi(ctx); - - await until( - async () => (await home.locator(".whiteboard-home-workspace").count()) === 2, - "two workspace groups", - ); - await until(async () => { - const seen = await cards.count(); - - assert.equal(seen, 3, `saw ${seen}`); - - return true; - }, "three review cards"); - ctx.check("Home groups three reviews under two worktrees"); - - await home.locator('[aria-label="Search sessions"]').fill("Worktree B"); - await until( - async () => (await cards.count()) === 1, - "search narrows to one card", - ); - - // The list view replaces the cards with `.whiteboard-home-list-row`, so the same reviews are counted as rows here. - await home.locator('[aria-label="List view"]').click(); - await until( - async () => (await home.getAttribute("data-view")) === "list", - "the list view", - ); - await until( - async () => (await rows.count()) === 1, - "one row under the search", - ); - await home.locator('[aria-label="Clear search"]').click(); - await until( - async () => (await rows.count()) === 3, - "clear restores three rows", - ); - await home.locator('[aria-label="Card view"]').click(); - await until( - async () => (await home.getAttribute("data-view")) === "cards", - "the card view", - ); - await until(async () => (await cards.count()) === 3, "clear restores three"); - ctx.check("Home search, list view and clear behave"); - - for (const title of [first.title, second.title, third.title]) - assert.equal( - await tabs.filter({ hasText: title }).count(), - 1, - `one editor tab for ${title}`, - ); - - await cards.filter({ hasText: second.title }).click(); - await canvas.getByRole("heading", { name: second.title }).waitFor(); - await pickWhiteboard(ctx, first.sessionId); - await canvas.getByRole("heading", { name: first.title }).waitFor(); - ctx.check( - "two reviews open as separate tabs and app pick switches between them", - ); - - await openHome(ctx); - ({ home, cards } = homeUi(ctx)); - - // The dismiss button is a sibling of the card button inside the shell, not a descendant of `.whiteboard-home-card`. - const shellB = home - .locator(".whiteboard-home-card-shell") - .filter({ hasText: third.title }); - - const dismissedRow = home - .locator(".whiteboard-home-dismissed-row") - .filter({ hasText: third.title }); - - // Dismissed rows sit behind a disclosure that keeps its state across re-renders, so only open it when it is shut. - const expandDismissed = async () => { - const toggle = home.locator(".whiteboard-home-dismissed-toggle"); - - await toggle.waitFor(); - - if ((await toggle.getAttribute("aria-expanded")) !== "true") - await toggle.click(); - await dismissedRow.waitFor(); - }; - - const dismiss = async () => { - await shellB.hover(); - await shellB.locator('[title="Dismiss review"]').click(); - await home.locator('section[aria-label="Dismissed sessions"]').waitFor(); - }; - - await dismiss(); - await until( - async () => (await cards.count()) === 2, - "the dismissed review leaves the cards", - ); - await expandDismissed(); - await dismissedRow.locator(".whiteboard-home-restore").click(); - await until(async () => (await cards.count()) === 3, "restored"); - - // Delete is offered only in a dismissed review's row, so the permanent action always follows the reversible one. - await dismiss(); - await expandDismissed(); - assert.ok( - (await listedWhiteboardIds(ctx)).includes(third.sessionId), - `${third.sessionId} is not listed before the delete`, - ); - await dismissedRow.locator('[title="Delete review"]').click(); - await dismissedRow.locator('[title="Click again to delete"]').click(); - await until( - async () => (await dismissedRow.count()) === 0, - "the deleted review leaves Home", - ); - await until(async () => { - const seen = await cards.count(); - - assert.equal(seen, 2, `saw ${seen}`); - - return true; - }, "two review cards after the delete"); - - const remaining = await listedWhiteboardIds(ctx); - - assert.ok( - !remaining.includes(third.sessionId), - `${third.sessionId} is still listed after deletion`, - ); - assert.deepEqual( - [first.sessionId, second.sessionId].filter((id) => !remaining.includes(id)), - [], - "deleting one review must not unlist the others", - ); - ctx.check("dismiss, restore and two-click delete update Home and the store"); -} diff --git a/apps/whiteboard-desktop/scripts/linux-package.test.mjs b/apps/whiteboard-desktop/scripts/linux-package.test.mjs deleted file mode 100644 index 94f868fc6..000000000 --- a/apps/whiteboard-desktop/scripts/linux-package.test.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; - -import { whiteboardPackage } from "../code-oss/build/linux/review-package.ts"; -import { releaseIdentityFor } from "./release-channel.mjs"; - -const product = (quality) => ({ quality, ...releaseIdentityFor(quality) }); - -test("stable versions package as dev-fast-review", () => { - assert.deepEqual(whiteboardPackage(product("stable"), "1.2.3", "2"), { - name: "dev-fast-review", - app: "review", - appName: "Whiteboard", - appId: "dev.fast.review", - rpmVersion: "1.2.3", - revision: "2", - file: "dev-fast-review-1.2.3-2.x86_64.rpm", - }); -}); - -test("preview versions package separately with a tilde RPM version", () => { - assert.deepEqual( - whiteboardPackage(product("preview"), "1.2.4-preview.20260922.7", "1"), - { - name: "dev-fast-review-preview", - app: "review-preview", - appName: "Whiteboard Preview", - appId: "dev.fast.review.preview", - rpmVersion: "1.2.4~preview.20260922.7", - revision: "1", - file: "dev-fast-review-preview-1.2.4~preview.20260922.7-1.x86_64.rpm", - }, - ); -}); - -test("the payload quality must match the version shape", () => { - assert.throws( - () => whiteboardPackage(product("stable"), "1.2.4-preview.20260922.7", "1"), - /quality "stable" does not match/, - ); - assert.throws( - () => whiteboardPackage(product("preview"), "1.2.4", "1"), - /quality "preview" does not match/, - ); - assert.throws(() => whiteboardPackage(product("stable"), "1.2.4-rc.1", "1")); - assert.throws(() => whiteboardPackage(product("stable"), "1.2.4", "0")); -}); diff --git a/apps/whiteboard-desktop/scripts/package-linux.sh b/apps/whiteboard-desktop/scripts/package-linux.sh deleted file mode 100755 index 31295092e..000000000 --- a/apps/whiteboard-desktop/scripts/package-linux.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" -APP_DIR="$MONOREPO_ROOT/apps/whiteboard-desktop" -CHECKOUT="$APP_DIR/code-oss" -PACKAGED_ROOT="$APP_DIR/VSCode-linux-x64" - -if (( $# > 0 )); then - echo "usage: $0" >&2 - exit 2 -fi -if [[ "$(uname -s)" != "Linux" ]]; then - echo "Review Desktop Linux packaging must run on Linux" >&2 - exit 1 -fi -if [[ "$(uname -m)" != "x86_64" ]]; then - echo "Review Desktop Linux packaging currently requires x86_64" >&2 - exit 1 -fi -if [[ ! -f "$CHECKOUT/node_modules/gulp/bin/gulp.js" ]]; then - echo "code-oss dependencies are missing; run pnpm --filter @dev.fast/whiteboard-desktop app:build first" >&2 - exit 1 -fi - -node "$APP_DIR/scripts/curated-extensions.mjs" --target=linux-x64 - -export BUILD_SOURCEVERSION="${BUILD_SOURCEVERSION:-$(git -C "$MONOREPO_ROOT" rev-parse HEAD)}" - -npm --prefix "$CHECKOUT" run gulp -- vscode-linux-x64 - -APPLICATION_NAME="$(node -p 'require(process.argv[1]).applicationName' "$PACKAGED_ROOT/resources/app/product.json")" -if [[ ! -x "$PACKAGED_ROOT/$APPLICATION_NAME" ]]; then - echo "Review Desktop packaging did not create $PACKAGED_ROOT/$APPLICATION_NAME" >&2 - exit 1 -fi -node "$APP_DIR/scripts/copy-canvas.mjs" --packaged-root "$PACKAGED_ROOT" -node "$APP_DIR/scripts/curated-extensions.mjs" \ - --target=linux-x64 \ - --copy-to "$PACKAGED_ROOT/resources/app/extensions" - -# The installed app embeds its own Whiteboard server runtime (server, CLI, and -# docs) so it never reaches back into this checkout. -pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/whiteboard build -pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/whiteboard ensure:diffr --required -node "$APP_DIR/scripts/stage-whiteboard-runtime.mjs" --packaged-root "$PACKAGED_ROOT" - -node "$APP_DIR/scripts/stage-whiteboard-runtime.mjs" --verify --packaged-root "$PACKAGED_ROOT" diff --git a/apps/whiteboard-desktop/scripts/run.sh b/apps/whiteboard-desktop/scripts/run.sh deleted file mode 100755 index dbb07f946..000000000 --- a/apps/whiteboard-desktop/scripts/run.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -MONOREPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd -P)" -APP_DIR="$MONOREPO_ROOT/apps/whiteboard-desktop" -CHECKOUT="$APP_DIR/code-oss" -WHITEBOARD_PACKAGE="$MONOREPO_ROOT/packages/whiteboard" -WHITEBOARD_SERVER="$WHITEBOARD_PACKAGE/dist/server/desktop-host.js" - -if (( $# > 0 )); then - echo "usage: $0" >&2 - exit 2 -fi - -if [[ ! -f "$CHECKOUT/product.json" ]]; then - echo "the tracked Code OSS fork is missing; restore the checkout before running Review Desktop" >&2 - exit 1 -fi -PACKAGED_ROOT="${DEV_FAST_WHITEBOARD_PACKAGED_ROOT:-}" -if [[ -n "$PACKAGED_ROOT" ]]; then - PACKAGED_ROOT="$(cd "$PACKAGED_ROOT" && pwd -P)" - CODE_EXE_NAME="$( - cd "$CHECKOUT" - node -p "require('./product.json').applicationName" - )" - CODE_BINARY="$PACKAGED_ROOT/$CODE_EXE_NAME" -elif [[ "$OSTYPE" == "darwin"* ]]; then - CODE_APP_NAME="$( - cd "$CHECKOUT" - node -p "require('./product.json').nameShort" - )" - CODE_EXE_NAME="$( - cd "$CHECKOUT" - node -p "require('./product.json').nameShort" - )" - CODE_BINARY="$CHECKOUT/.build/electron/$CODE_APP_NAME.app/Contents/MacOS/$CODE_EXE_NAME" -else - CODE_APP_NAME="$( - cd "$CHECKOUT" - node -p "require('./product.json').applicationName" - )" - CODE_BINARY="$CHECKOUT/.build/electron/$CODE_APP_NAME" -fi -if [[ ! -x "$CODE_BINARY" ]]; then - echo "Review Desktop binary is not built at $CODE_BINARY" >&2 - exit 1 -fi - -# shellcheck source=freshness.sh -source "$APP_DIR/scripts/freshness.sh" - -WHITEBOARD_USER_HOME="$(node -p "require('node:os').homedir()")" -WHITEBOARD_BASE_HOME="${DEV_WHITEBOARD_HOME:-$WHITEBOARD_USER_HOME/.dev}" -STATE_ROOT="${DEV_FAST_WHITEBOARD_DESKTOP_STATE_ROOT:-$WHITEBOARD_BASE_HOME/review-desktop/state}" -mkdir -p "$STATE_ROOT/user-data" "$STATE_ROOT/extensions" "$STATE_ROOT/logs" - -# Curated extensions are downloaded, not committed. Materialize the selected -# groups before launch. `all` is the bundled set. Explicit optional groups are -# available for development launches. Set DEV_WHITEBOARD_EXTENSIONS to all -# (default), none, or a comma-separated subset of -# rust,swift,csharp,python,go,vim,emacs. Enablement is a persisted in-app choice. -# `pnpm dev` runs build.sh (which also materializes this selection) right -# before this script; skip the repeat call when the manifest is unchanged and -# the selection matches the one already materialized. -EXTENSIONS_SELECTION="${DEV_WHITEBOARD_EXTENSIONS:-all}" -EXTENSIONS_SELECTION_STAMP="$CHECKOUT/.build/dev-fast/curated-extensions.stamp" -mkdir -p "$(dirname "$EXTENSIONS_SELECTION_STAMP")" -if [[ "$(cat "$EXTENSIONS_SELECTION_STAMP" 2>/dev/null)" != "$EXTENSIONS_SELECTION" ]] || - needs_rebuild "$EXTENSIONS_SELECTION_STAMP" "$APP_DIR/scripts/curated-extensions.manifest.mjs"; then - node "$APP_DIR/scripts/curated-extensions.mjs" --only="$EXTENSIONS_SELECTION" - echo "$EXTENSIONS_SELECTION" >"$EXTENSIONS_SELECTION_STAMP" -fi - -# Development launches use the checkout runtime, not the staged release bundle. -# Check the pinned binary even when all compiled outputs are already current. -# An explicit developer override supplies its own executable. -if [[ -z "$PACKAGED_ROOT" && -z "${WHITEBOARD_DIFFR_BINARY:-}" ]]; then - pnpm --dir "$MONOREPO_ROOT" --filter @dev.fast/whiteboard ensure:diffr --required -fi - -rebuild_review_desktop_outputs "$MONOREPO_ROOT" "$WHITEBOARD_PACKAGE" -if [[ -z "$PACKAGED_ROOT" ]]; then - node "$APP_DIR/scripts/copy-canvas.mjs" - export DEV_FAST_WHITEBOARD_SERVER_ENTRY="$WHITEBOARD_SERVER" - export DEV_FAST_WHITEBOARD_TOOLING_ROOT="$MONOREPO_ROOT" -fi - -CODE_ARGS=( - --disable-telemetry - --skip-welcome - "--user-data-dir=$STATE_ROOT/user-data" - "--extensions-dir=$STATE_ROOT/extensions" -) -if [[ -n "${DEV_FAST_WHITEBOARD_SHARED_DATA_DIR:-}" ]]; then - CODE_ARGS+=("--shared-data-dir=$DEV_FAST_WHITEBOARD_SHARED_DATA_DIR") -fi -if [[ -n "${DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT:-}" ]]; then - CODE_ARGS+=( - "--remote-debugging-port=$DEV_FAST_WHITEBOARD_REMOTE_DEBUGGING_PORT" - ) -fi -if [[ "${DEV_FAST_WHITEBOARD_DISABLE_GPU:-0}" == "1" ]]; then - CODE_ARGS+=(--disable-gpu) -fi -if [[ "${DEV_FAST_WHITEBOARD_FORCE_ACCESSIBILITY:-0}" == "1" ]]; then - # Keeps Chromium's renderer accessibility tree alive for the generic Linux - # AT-SPI Computer Use backend. It is deliberately opt-in outside DevBoxes. - CODE_ARGS+=(--force-renderer-accessibility) -fi - -if [[ -n "$PACKAGED_ROOT" ]]; then - unset DEV_FAST_WHITEBOARD_TOOLING_ROOT - unset NODE_ENV VSCODE_DEV VSCODE_CLI -else - ( - cd "$CHECKOUT" - node build/lib/preLaunch.ts - ) - export NODE_ENV=development - export VSCODE_DEV=1 - export VSCODE_CLI=1 -fi -export ELECTRON_ENABLE_STACK_DUMPING=1 -export ELECTRON_ENABLE_LOGGING=1 -cd "$CHECKOUT" -exec "$CODE_BINARY" \ - --disable-extension=vscode.vscode-api-tests \ - "${CODE_ARGS[@]}" \ - . diff --git a/apps/whiteboard-desktop/scripts/stage-whiteboard-runtime-docs.test.mjs b/apps/whiteboard-desktop/scripts/stage-whiteboard-runtime-docs.test.mjs deleted file mode 100644 index 61c6a80f0..000000000 --- a/apps/whiteboard-desktop/scripts/stage-whiteboard-runtime-docs.test.mjs +++ /dev/null @@ -1,126 +0,0 @@ -import assert from "node:assert/strict"; -import { - access, - mkdir, - mkdtemp, - readFile, - readdir, - rm, - writeFile, -} from "node:fs/promises"; -import os from "node:os"; -import path from "node:path"; -import { after, test } from "node:test"; -import { fileURLToPath } from "node:url"; - -import { stageWhiteboardDocs } from "./stage-whiteboard-runtime.mjs"; - -const temporaryRoots = []; - -const repositoryRoot = path.resolve( - path.dirname(fileURLToPath(import.meta.url)), - "../../..", -); - -after(async () => { - await Promise.all( - temporaryRoots.map((root) => rm(root, { recursive: true, force: true })), - ); -}); - -async function temporaryRoot(prefix) { - const root = await mkdtemp(path.join(os.tmpdir(), prefix)); - temporaryRoots.push(root); - - return root; -} - -test("stages the complete Whiteboard documentation tree under the runtime root", async () => { - const root = await temporaryRoot("whiteboard-runtime-docs-"); - const runtimeRoot = path.join(root, "whiteboard-runtime"); - const docsRoot = path.join(root, "source-docs"); - await mkdir(path.join(runtimeRoot, "docs"), { recursive: true }); - await mkdir(path.join(docsRoot, "assets"), { recursive: true }); - await writeFile(path.join(runtimeRoot, "docs", "stale.md"), "stale\n"); - await writeFile(path.join(docsRoot, "README.md"), "# Review docs\n"); - await writeFile(path.join(docsRoot, "guide.md"), "# Guide\n"); - await writeFile( - path.join(docsRoot, "assets", "image.png"), - Buffer.from([0, 1, 2, 3]), - ); - - const destination = await stageWhiteboardDocs(runtimeRoot, docsRoot); - assert.equal(destination, path.join(runtimeRoot, "docs")); - - assert.equal( - await readFile(path.join(destination, "README.md"), "utf8"), - "# Review docs\n", - ); - assert.equal( - await readFile(path.join(destination, "guide.md"), "utf8"), - "# Guide\n", - ); - assert.deepEqual( - await readFile(path.join(destination, "assets", "image.png")), - Buffer.from([0, 1, 2, 3]), - ); - await assert.rejects(readFile(path.join(destination, "stale.md")), /ENOENT/); -}); - -test("bundled Review documentation has no escaping or broken relative links", async () => { - const docsRoot = path.join(repositoryRoot, "docs"); - const markdownFiles = await listMarkdownFiles(docsRoot); - const missing = []; - - for (const file of markdownFiles) { - const source = await readFile(file, "utf8"); - const links = source.matchAll(/!?\[[^\]]*\]\(([^)]+)\)/g); - - for (const match of links) { - const target = match[1].trim(); - - if (target.startsWith("#") || /^[a-z][a-z0-9+.-]*:/i.test(target)) { - continue; - } - - const relativeTarget = target.split("#", 1)[0]; - const resolved = path.resolve(path.dirname(file), relativeTarget); - - if ( - resolved !== docsRoot && - !resolved.startsWith(`${docsRoot}${path.sep}`) - ) { - missing.push(`${path.relative(docsRoot, file)} -> ${target} (escapes)`); - continue; - } - - try { - await access(resolved); - } catch { - missing.push(`${path.relative(docsRoot, file)} -> ${target}`); - } - } - } - - assert.deepEqual(missing, []); -}); - -async function listMarkdownFiles(root) { - const files = []; - - const walk = async (directory) => { - const entries = await readdir(directory, { withFileTypes: true }); - - for (const entry of entries) { - const absolute = path.join(directory, entry.name); - - if (entry.isDirectory()) await walk(absolute); - else if (entry.isFile() && entry.name.endsWith(".md")) - files.push(absolute); - } - }; - - await walk(root); - - return files; -} diff --git a/apps/whiteboard-desktop/scripts/stage-whiteboard-runtime.mjs b/apps/whiteboard-desktop/scripts/stage-whiteboard-runtime.mjs deleted file mode 100644 index b1d618076..000000000 --- a/apps/whiteboard-desktop/scripts/stage-whiteboard-runtime.mjs +++ /dev/null @@ -1,508 +0,0 @@ -import { execFile } from "node:child_process"; -import { - access, - chmod, - copyFile, - cp, - mkdir, - open, - readFile, - readdir, - realpath, - rm, - stat, -} from "node:fs/promises"; -import { createRequire } from "node:module"; -import path from "node:path"; -import { fileURLToPath, pathToFileURL } from "node:url"; -import { promisify } from "node:util"; - -const execFileAsync = promisify(execFile); - -const appDirectory = path.resolve( - path.dirname(fileURLToPath(import.meta.url)), - "..", -); - -const monorepoRoot = path.resolve(appDirectory, "../.."); - -/** - * The installed application must not reach back into the build checkout, so the - * Review server ships as a self-contained production dependency closure rather - * than as a single bundled file: the runtime intentionally depends on native - * binaries and external Node libraries. The canvas is built and copied separately. - */ -export const RUNTIME_DIRECTORY_NAME = "review-runtime"; - -export const RUNTIME_SERVER_ENTRY = "dist/server/desktop-host.js"; - -export const RUNTIME_CLI_ENTRY = "dist/cli.js"; - -export const REQUIRED_RUNTIME_ENTRIES = [ - "package.json", - "LICENSE", - "THIRD_PARTY_NOTICES.md", - RUNTIME_SERVER_ENTRY, - RUNTIME_CLI_ENTRY, - "bin/diffr", - "dist/whiteboard-cli.js", - "docs/README.md", - "instructions/authoring.md", - "tutorial/runtime-manifest.json", - "node_modules", -]; - -export function runtimeRootForPackagedRoot(packagedRoot) { - const resolved = path.resolve(packagedRoot); - - if (resolved === path.parse(resolved).root) { - throw new Error("The packaged Review root cannot be a filesystem root."); - } - - const packagedAppRoot = resolved.endsWith(".app") - ? path.join(resolved, "Contents/Resources/app") - : path.join(resolved, "resources/app"); - - return path.join(packagedAppRoot, RUNTIME_DIRECTORY_NAME); -} - -export function requiredPackagedArtifacts(packagedRoot) { - const runtimeRoot = runtimeRootForPackagedRoot(packagedRoot); - const packagedAppRoot = path.dirname(runtimeRoot); - - const entries = [ - "out/vs/whiteboard/whiteboard.desktop.main.js", - "out/vs/whiteboard/whiteboard.desktop.main.css", - "out/vs/whiteboard/electron-utility/whiteboardDesktopHostMain.js", - "out/vs/whiteboard/canvas/canvas-loader.js", - ...REQUIRED_RUNTIME_ENTRIES.map((entry) => - path.join(RUNTIME_DIRECTORY_NAME, entry), - ), - ]; - - if (!path.resolve(packagedRoot).endsWith(".app")) { - entries.push("extensions/vscodevim.vim/package.json"); - } - - return entries.map((entry) => path.join(packagedAppRoot, entry)); -} - -export async function assertPackagedArtifacts(packagedRoot) { - await assertNoRuntimeBundler(packagedRoot); - - for (const artifact of requiredPackagedArtifacts(packagedRoot)) { - try { - await access(artifact); - } catch { - throw new Error(`Review Desktop package is missing ${artifact}.`); - } - } -} - -export async function stageWhiteboardRuntime(packagedRoot) { - const runtimeRoot = runtimeRootForPackagedRoot(packagedRoot); - const packagedAppRoot = path.dirname(runtimeRoot); - - if (!(await isDirectory(packagedAppRoot))) { - throw new Error( - `Refusing to stage the Review runtime outside a packaged app: ${packagedAppRoot}`, - ); - } - - await rm(runtimeRoot, { recursive: true, force: true }); - await execFileAsync( - "pnpm", - [ - "--config.allow-unused-patches=true", - // This workspace pins `nodeLinker: hoisted`, under which a plain deploy - // links workspace dependencies back to the checkout and never resolves - // their own dependency graphs. Injecting copies them in with their deps. - "--config.inject-workspace-packages=true", - "--filter", - "@dev.fast/whiteboard", - "--prod", - "deploy", - "--legacy", - // Keeps the root prepare/Husky lifecycle out of packaging. - "--ignore-scripts", - runtimeRoot, - ], - { cwd: monorepoRoot, maxBuffer: 64 * 1024 * 1024 }, - ); - - await stageWhiteboardDocs(runtimeRoot); - await stageDiffrBinary(runtimeRoot); - await makeTreeOwnerWritable(path.join(runtimeRoot, "tutorial", "git-stub")); - await assertRuntimeClosure(runtimeRoot); - - return runtimeRoot; -} - -export async function stageWhiteboardDocs( - runtimeRoot, - sourceDocsRoot = path.join(monorepoRoot, "docs"), -) { - if (!(await isDirectory(sourceDocsRoot))) { - throw new Error( - `Review documentation source is missing: ${sourceDocsRoot}`, - ); - } - - const destination = path.join(runtimeRoot, "docs"); - await rm(destination, { recursive: true, force: true }); - await cp(sourceDocsRoot, destination, { recursive: true }); - await assertMatchingFileTrees(sourceDocsRoot, destination); - - return destination; -} - -export async function stageDiffrBinary( - runtimeRoot, - source = path.join(monorepoRoot, "packages", "whiteboard", "bin", "diffr"), -) { - if (!(await stat(source).catch(() => null))?.isFile()) { - throw new Error( - `Missing ${source}. Run pnpm --filter @dev.fast/whiteboard ensure:diffr before packaging.`, - ); - } - - const require = createRequire( - path.join(monorepoRoot, "packages/whiteboard/package.json"), - ); - - const packageRoot = path.dirname( - require.resolve("@dev.fast/diffr/package.json"), - ); - - await execFileAsync(process.execPath, [ - path.join(packageRoot, "bin/fetch.mjs"), - "--check", - "--into", - path.dirname(source), - ]); - - const destination = path.join(runtimeRoot, "bin", "diffr"); - await mkdir(path.dirname(destination), { recursive: true }); - await copyFile(source, destination); - await chmod(destination, 0o755); -} - -async function assertMatchingFileTrees(sourceRoot, destinationRoot) { - const [sourceFiles, destinationFiles] = await Promise.all([ - listRelativeFiles(sourceRoot), - listRelativeFiles(destinationRoot), - ]); - - if (sourceFiles.join("\n") !== destinationFiles.join("\n")) { - throw new Error( - "The staged Review documentation file list does not match.", - ); - } - - for (const relative of sourceFiles) { - const [source, destination] = await Promise.all([ - readFile(path.join(sourceRoot, relative)), - readFile(path.join(destinationRoot, relative)), - ]); - - if (!source.equals(destination)) { - throw new Error( - `The staged Review documentation differs at ${relative}.`, - ); - } - } -} - -async function listRelativeFiles(root) { - const files = []; - - const walk = async (directory) => { - const entries = await readdir(directory, { withFileTypes: true }); - entries.sort((a, b) => a.name.localeCompare(b.name)); - - for (const entry of entries) { - const absolute = path.join(directory, entry.name); - - if (entry.isDirectory()) { - await walk(absolute); - } else if (entry.isFile()) { - files.push(path.relative(root, absolute)); - } else { - throw new Error( - `Review documentation contains an unsupported entry: ${absolute}`, - ); - } - } - }; - - await walk(root); - - return files; -} - -async function makeTreeOwnerWritable(directory) { - for (const entry of await readdir(directory, { withFileTypes: true })) { - const absolute = path.join(directory, entry.name); - - if (entry.isDirectory()) { - await makeTreeOwnerWritable(absolute); - continue; - } - - if (!entry.isFile()) continue; - - const current = await stat(absolute); - - if ((current.mode & 0o200) === 0) { - await chmod(absolute, current.mode | 0o200); - } - } -} - -export async function assertRuntimeClosure(runtimeRoot) { - for (const entry of REQUIRED_RUNTIME_ENTRIES) { - const target = path.join(runtimeRoot, entry); - - try { - await access(target); - } catch { - throw new Error(`The staged Review runtime is missing ${entry}.`); - } - } - - const tutorialRoot = path.join(runtimeRoot, "tutorial"); - const tutorialManifest = await readTutorialRuntimeManifest(tutorialRoot); - - for (const entry of tutorialManifest.requiredPaths) { - try { - await access(path.join(tutorialRoot, entry)); - } catch { - throw new Error( - `The staged Review runtime is missing tutorial/${entry}.`, - ); - } - } - - await assertRuntimeContents(runtimeRoot); -} - -export async function readTutorialRuntimeManifest(tutorialRoot) { - const value = JSON.parse( - await readFile(path.join(tutorialRoot, "runtime-manifest.json"), "utf8"), - ); - - const validEntries = (entries) => - Array.isArray(entries) && - entries.length > 0 && - entries.every(isSafeManifestPath); - - if ( - value?.version !== 1 || - !validEntries(value.whiteboardFiles) || - !validEntries(value.requiredPaths) || - value.whiteboardFiles.some((entry) => !value.requiredPaths.includes(entry)) - ) { - throw new Error("Tutorial runtime manifest is invalid."); - } - - return { - version: 1, - whiteboardFiles: [...new Set(value.whiteboardFiles)], - requiredPaths: [...new Set(value.requiredPaths)], - }; -} - -/** A manifest entry that names a file inside the tutorial tree. */ -function isSafeManifestPath(entry) { - // Only a JSON string equals its own String() rendering by identity. - return ( - String(entry) === entry && - entry.length > 0 && - !path.isAbsolute(entry) && - !entry.split(/[\\/]/u).includes("..") - ); -} - -/** Final package verification includes files outside the staged runtime, such - * as extension dependencies and ASAR archives, after all package mutations. */ -export async function assertNoRuntimeBundler(runtimeRoot) { - await inspectRuntimeTree(runtimeRoot, false); -} - -/** Validate the staged dependency closure in one traversal. */ -export async function assertRuntimeContents(runtimeRoot) { - await inspectRuntimeTree(runtimeRoot, true); -} - -async function inspectRuntimeTree(root, checkCheckoutReferences) { - const runtimeRoot = await realpath(root); - const offenders = []; - - const visit = async (directory) => { - for (const entry of await readdir(directory, { withFileTypes: true })) { - const absolute = path.join(directory, entry.name); - - if (entry.name === "esbuild" || entry.name === "esbuild.exe") { - throw new Error( - `The Review runtime must not ship esbuild: ${path.relative(runtimeRoot, absolute)}`, - ); - } - - if (entry.isSymbolicLink()) { - if (checkCheckoutReferences) { - const real = await realpathOrNull(absolute); - - if (!real) { - offenders.push( - `${path.relative(runtimeRoot, absolute)} (broken link)`, - ); - } else if ( - real !== runtimeRoot && - !real.startsWith(runtimeRoot + path.sep) - ) { - offenders.push( - `${path.relative(runtimeRoot, absolute)} -> ${real} (escapes runtime)`, - ); - } - } - - continue; - } - - if (entry.isDirectory()) { - await visit(absolute); - continue; - } - - if (!entry.isFile()) continue; - - if (entry.name.endsWith(".asar")) { - await assertNoArchivedBundler(absolute); - continue; - } - - const isManifest = entry.name === "package.json"; - - // Declarations and source maps can embed checkout paths just as emitted - // JavaScript can. Read manifests once for both closure checks. - const checkContents = - checkCheckoutReferences && - (isManifest || - /\.[cm]?js\.map$/.test(entry.name) || - (/\.(?:[cm]?js|d\.[cm]?ts)$/.test(entry.name) && - absolute.includes(`${path.sep}dist${path.sep}`))); - - if (!isManifest && !checkContents) continue; - const contents = await readFile(absolute, "utf8"); - - if (isManifest) { - const manifest = JSON.parse(contents); - - if ( - manifest.name === "esbuild" || - manifest.name?.startsWith("@esbuild/") - ) - throw new Error( - `The Review runtime must not ship ${manifest.name}: ${path.relative(runtimeRoot, absolute)}`, - ); - } - - if (checkContents && contents.includes(monorepoRoot)) { - offenders.push( - `${path.relative(runtimeRoot, absolute)} (build checkout path)`, - ); - } - } - }; - - await visit(runtimeRoot); - - if (offenders.length > 0) { - throw new Error( - `The staged Review runtime is not relocatable:\n ${offenders.join("\n ")}`, - ); - } -} - -// ASAR headers are two Chromium pickles: an 8-byte size pickle followed by -// a string pickle containing the JSON tree. Inspect the directory without -// extracting the app or requiring an archive tool in the installed runtime. -async function assertNoArchivedBundler(archive) { - const file = await open(archive, "r"); - - try { - const prefix = Buffer.alloc(16); - - if ((await file.read(prefix, 0, 16, 0)).bytesRead !== 16) - throw new Error(`Invalid ASAR header: ${archive}`); - const headerBytes = prefix.readUInt32LE(4); - const jsonBytes = prefix.readUInt32LE(12); - - if (jsonBytes > headerBytes - 8 || headerBytes > 64 * 1024 * 1024) - throw new Error(`Invalid ASAR header size: ${archive}`); - const contents = Buffer.alloc(jsonBytes); - - if ((await file.read(contents, 0, jsonBytes, 16)).bytesRead !== jsonBytes) - throw new Error(`Truncated ASAR header: ${archive}`); - - const visit = (node, parent = "") => { - for (const [name, child] of Object.entries(node.files ?? {})) { - const relative = `${parent}/${name}`; - - if (name === "esbuild" || name === "esbuild.exe" || name === "@esbuild") - throw new Error( - `The Review runtime must not ship esbuild: ${archive}:${relative}`, - ); - visit(child, relative); - } - }; - - visit(JSON.parse(contents.toString("utf8"))); - } finally { - await file.close(); - } -} - -async function realpathOrNull(target) { - try { - return await realpath(target); - } catch { - return null; - } -} - -async function isDirectory(candidate) { - try { - return (await stat(candidate)).isDirectory(); - } catch { - return false; - } -} - -if ( - process.argv[1] && - import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href -) { - const args = process.argv.slice(2); - const verifyOnly = args[0] === "--verify"; - const packagedRootIndex = verifyOnly ? 1 : 0; - - if ( - args.length !== packagedRootIndex + 2 || - args[packagedRootIndex] !== "--packaged-root" - ) { - throw new Error( - "usage: stage-whiteboard-runtime.mjs [--verify] --packaged-root ", - ); - } - - const packagedRoot = args[packagedRootIndex + 1]; - - if (verifyOnly) { - await assertPackagedArtifacts(packagedRoot); - process.stdout.write(`Verified the Review package at ${packagedRoot}\n`); - } else { - const runtimeRoot = await stageWhiteboardRuntime(packagedRoot); - process.stdout.write(`Staged the Review runtime at ${runtimeRoot}\n`); - } -} diff --git a/apps/whiteboard-desktop/scripts/titlebar-navigation-contract.test.mjs b/apps/whiteboard-desktop/scripts/titlebar-navigation-contract.test.mjs deleted file mode 100644 index fda26d363..000000000 --- a/apps/whiteboard-desktop/scripts/titlebar-navigation-contract.test.mjs +++ /dev/null @@ -1,72 +0,0 @@ -import assert from "node:assert/strict"; -import { readFileSync } from "node:fs"; -import test from "node:test"; - -const whiteboardTitlebar = readFileSync( - new URL( - "../code-oss/src/vs/whiteboard/browser/parts/whiteboardTitlebarPart.ts", - import.meta.url, - ), - "utf8", -); - -const whiteboardConfiguration = readFileSync( - new URL( - "../code-oss/src/vs/whiteboard/common/whiteboardConfigurationDefaults.ts", - import.meta.url, - ), - "utf8", -); - -const whiteboardMain = readFileSync( - new URL( - "../code-oss/src/vs/whiteboard/electron-browser/whiteboard.main.ts", - import.meta.url, - ), - "utf8", -); - -const commandCenterControl = readFileSync( - new URL( - "../code-oss/src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts", - import.meta.url, - ), - "utf8", -); - -test("Review mounts VS Code's native back and forward controls", () => { - assert.match( - whiteboardMain, - /new WhiteboardConfigurationService\([\s\S]*?\{ defaultOverrides: whiteboardAgentsWindowDefaultOverrides \}\)/, - "Review's navigation defaults must survive Review configuration initialization", - ); - - assert.match( - whiteboardTitlebar, - /createInstance\(\s*CommandCenterControl,/, - "Review should mount VS Code's native titlebar control", - ); - assert.doesNotMatch( - whiteboardTitlebar, - /workbench\.action\.navigate(?:Back|Forward)/, - "Review must not recreate or manually dispatch native navigation actions", - ); - assert.doesNotMatch( - whiteboardTitlebar, - /review-title\b/, - "the titlebar carries no product label; the branding lives in the macOS application menu", - ); -}); - -test("the native control can omit the command launcher without hiding navigation", () => { - const centerMenuItem = commandCenterControl.match( - /MenuRegistry\.appendMenuItem\(MenuId\.CommandCenter, \{[\s\S]*?submenu: MenuId\.CommandCenterCenter,[\s\S]*?\n\}\);/, - )?.[0]; - - assert.match( - centerMenuItem ?? "", - /when: ContextKeyExpr\.has\('config\.window\.commandCenter'\)/, - "expected the native command-center menu item gated on config.window.commandCenter", - ); - assert.match(whiteboardConfiguration, /'window\.commandCenter': false,/); -}); diff --git a/apps/whiteboard-desktop/scripts/whiteboard-network-policy.mjs b/apps/whiteboard-desktop/scripts/whiteboard-network-policy.mjs deleted file mode 100644 index fc381dec4..000000000 --- a/apps/whiteboard-desktop/scripts/whiteboard-network-policy.mjs +++ /dev/null @@ -1,71 +0,0 @@ -// This is a blocklist, not an allowlist. `update.dev.fast` and `open-vsx.org` -// are sanctioned hosts and must stay reachable. Do not add them here when -// tightening this policy. -const BLOCKED_HOSTS = new Set([ - "aka.ms", - "marketplace.visualstudio.com", - "update.code.visualstudio.com", - "vscode.blob.core.windows.net", - "vscode.download.prss.microsoft.com", -]); - -const BLOCKED_HOST_SUFFIXES = [ - ".data.microsoft.com", - ".mai.microsoft.com", - ".vsassets.io", - ".vscode-cdn.net", -]; - -export function blockedWhiteboardRequestReason(value) { - let url; - - try { - url = new URL(value); - } catch { - return undefined; - } - - const hostname = url.hostname.toLowerCase(); - - if (BLOCKED_HOSTS.has(hostname)) { - return `blocked service host ${hostname}`; - } - - const suffix = BLOCKED_HOST_SUFFIXES.find( - (candidate) => - hostname === candidate.slice(1) || hostname.endsWith(candidate), - ); - - if (suffix) { - return `blocked service host ${hostname}`; - } - - if ( - hostname === "api.github.com" && - /^\/copilot(?:_internal)?(?:\/|$)/.test(url.pathname) - ) { - return `blocked Copilot endpoint ${url.pathname}`; - } - - return undefined; -} - -export function assertNoBlockedWhiteboardRequests(requestUrls) { - const blocked = [ - ...new Map( - requestUrls.flatMap((url) => { - const reason = blockedWhiteboardRequestReason(url); - - return reason ? [[url, reason]] : []; - }), - ), - ].sort(([left], [right]) => left.localeCompare(right)); - - if (blocked.length === 0) return; - throw new Error( - [ - "Review Desktop contacted disabled Microsoft or Copilot services:", - ...blocked.map(([url, reason]) => `- ${reason}: ${url}`), - ].join("\n"), - ); -} diff --git a/apps/whiteboard-desktop/scripts/whiteboard-network-policy.test.mjs b/apps/whiteboard-desktop/scripts/whiteboard-network-policy.test.mjs deleted file mode 100644 index ffbb75c23..000000000 --- a/apps/whiteboard-desktop/scripts/whiteboard-network-policy.test.mjs +++ /dev/null @@ -1,79 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; - -import { - assertNoBlockedWhiteboardRequests, - blockedWhiteboardRequestReason, -} from "./whiteboard-network-policy.mjs"; - -test("blocks disabled Microsoft service and asset hosts", () => { - for (const url of [ - "https://mobile.events.data.microsoft.com/OneCollector/1.0", - "https://update.code.visualstudio.com/api/update/darwin-universal/stable/latest", - "https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery", - "https://cdn.vsassets.io/v/M123/file.js", - "https://abc.vscode-cdn.net/stable/pre/index.html", - "wss://falcon-caas.mai.microsoft.com/voice-code/api/v1/realtime/voice", - "https://aka.ms/github-copilot-overview", - "https://vscode.blob.core.windows.net/gallery/index", - "https://vscode.download.prss.microsoft.com/dbazure/download/stable/file", - ]) { - assert.ok(blockedWhiteboardRequestReason(url), url); - } -}); - -test("blocks Copilot API paths without blocking ordinary GitHub API use", () => { - assert.ok( - blockedWhiteboardRequestReason( - "https://api.github.com/copilot_internal/v2/token", - ), - ); - assert.ok( - blockedWhiteboardRequestReason("https://api.github.com/copilot/mcp_registry"), - ); - assert.equal( - blockedWhiteboardRequestReason( - "https://api.github.com/repos/Fix-Fast/dev/pulls/1", - ), - undefined, - ); -}); - -test("allows local Review resources and non-service protocols", () => { - for (const url of [ - "http://localhost:3000/api/review", - "http://127.0.0.1:3000/api/review", - "vscode-file://vscode-app/out/vs/code/electron-sandbox/workbench/workbench.html", - "vscode-webview://review/index.html", - "data:text/plain,review", - "https://open-vsx.org/api/swiftlang/swift-vscode", - ]) { - assert.equal(blockedWhiteboardRequestReason(url), undefined, url); - } - - assert.doesNotThrow(() => - assertNoBlockedWhiteboardRequests([ - "http://localhost:3000/api/review", - "https://api.github.com/repos/Fix-Fast/dev", - ]), - ); -}); - -test("reports each blocked request once", () => { - assert.throws( - () => - assertNoBlockedWhiteboardRequests([ - "https://mobile.events.data.microsoft.com/OneCollector/1.0", - "https://mobile.events.data.microsoft.com/OneCollector/1.0", - ]), - (error) => { - assert.match(error.message, /disabled Microsoft or Copilot services/); - assert.equal( - error.message.match(/mobile\.events\.data\.microsoft\.com/g)?.length, - 2, - ); - - return true; - }, - ); -}); diff --git a/docs/adr/0001-headless-authoring-boundary.md b/docs/adr/0001-headless-authoring-boundary.md index c6f01a53c..2cba8b423 100644 --- a/docs/adr/0001-headless-authoring-boundary.md +++ b/docs/adr/0001-headless-authoring-boundary.md @@ -5,7 +5,7 @@ > tools, the `dev-review-batch` skill and the `author-and-share` action are in > git history. -Headless authoring will provide a separately installable Review runtime and compatible authoring skill instructions, usable on a fresh Linux runner without a desktop installation, display server, or desktop session. CI supplies the agent harness, model credentials, and a prepared local checkout with explicit base and head revisions; missing commits must produce actionable errors. This boundary lets existing CI agent workflows author Whiteboards without making Review responsible for agent execution, PR discovery, authentication for checkout provisioning, cloning, or fetching. +Headless authoring will provide a separately installable Review runtime and compatible authoring skill instructions, usable on a fresh Linux runner without a desktop installation, display server, or desktop session. CI supplies the agent harness, model credentials, and a prepared local checkout with explicit base and head revisions; missing commits must produce actionable errors. This boundary lets existing CI agent workflows author Reviews without making Review responsible for agent execution, PR discovery, authentication for checkout provisioning, cloning, or fetching. This PR focuses on authoring. Its output is persistent local state and a review ID that a subsequent sharing step can consume. Portable export, uploading, sharing, and deep links belong to the separate sharing work. diff --git a/docs/adr/0002-headless-authoring-store-ownership.md b/docs/adr/0002-headless-authoring-store-ownership.md index 18ef6d6d0..f20b3a1bf 100644 --- a/docs/adr/0002-headless-authoring-store-ownership.md +++ b/docs/adr/0002-headless-authoring-store-ownership.md @@ -5,7 +5,7 @@ > below is in git history. Desktop and the foreground headless server share `review-api.db` under the same -profile directory, defaulting to `DEV_WHITEBOARD_HOME`. This makes locally authored +profile directory, defaulting to `DEV_REVIEW_HOME`. This makes locally authored reviews visible in Desktop without copying content or assigning new review IDs. Independent CI jobs can select separate profiles. diff --git a/docs/agents.md b/docs/agents.md index a4b548d39..96092b0ec 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -1,176 +1,112 @@ # Coding agents Whiteboard instructions -> Change review -> Architecture review -> Provider boundary. +Outline: Built-in setup -> Installed skills -> Change review -> Architecture review +-> Headless install -> Provider boundary. --> -Whiteboard works with Claude Code, Codex, Cursor, OpenCode, and Pi. Each agent -connects to Whiteboard's MCP server; the running Whiteboard server supplies the -authoring instructions. +Review works with Claude Code, Codex, and other coding agents. The desktop app +installs a small set of skills that teaches the agent how to create, author, +validate, and update a Review through the Review API and MCP tools. -## Connect an agent +## Built-in setup -Whiteboard does not edit agent configuration. Instead, it gives you a prompt that -tells the agent to connect itself. +Review Desktop provides setup shortcuts for these agent-specific skill +locations: -1. Open Whiteboard. Use the **Welcome** tab, or **Settings → Agents**. -2. Choose **Install whiteboard in PATH** if Whiteboard offers it. The connection - runs `~/.local/bin/whiteboard`. -3. Choose **Copy prompt** next to your agent. **Show prompt** reveals the text - so you can read it first. -4. Paste the prompt into a session of that agent. - -The agent registers an MCP server named `whiteboard` in its user-level -configuration, not in the project. It replaces an existing `whiteboard` entry. The -server runs this command: - -```text -command: sh -args: ["-c", "exec \"$HOME/.local/bin/whiteboard\" mcp"] -``` - -Agents started from an app do not see your shell `PATH`, so the prompt uses -the full path through `sh`. When Whiteboard has no launcher in `~/.local/bin`, as -when it runs from source, the prompt registers `whiteboard` with args `["mcp"]` -instead. That form needs `whiteboard` on the agent's `PATH`. - -The agent then deletes old skills that Whiteboard Desktop installed, reloads its -MCP tools or asks for a restart, and calls `session_get_instructions` to confirm -the connection. - -Whiteboard does not check which agents are connected. Paste the prompt again at -any time; it replaces the existing entry. To disconnect an agent, remove its -`whiteboard` MCP server with that agent's own settings. - -Whiteboard and Whiteboard Preview share one launcher, which connects to whichever app -is open. Run one at a time. - -### From a terminal - -`whiteboard connect` prints the same prompt that Desktop copies: - -```sh -whiteboard connect codex -whiteboard connect claude cursor -whiteboard connect -``` - -With no agent, it prints the prompts for all five agents. Pass `--json` for a -`connect` event that maps each agent to its prompt. - -### Agent differences - -| Agent | Target | What the prompt sets up | -| --- | --- | --- | -| Claude Code | `claude` or `claude-code` | `whiteboard` MCP server | -| Codex | `codex` | `whiteboard` MCP server and one line in `~/.codex/AGENTS.md` | -| Cursor | `cursor` | `whiteboard` MCP server | -| OpenCode | `opencode` | `whiteboard` MCP server | -| Pi | `pi` | `whiteboard` skill in `~/.agents/skills` | - -Codex finds MCP tools only when its instructions name them. Its prompt adds -this line to `~/.codex/AGENTS.md`: "For code reviews and explaining code, use -the `whiteboard` MCP server: call `session_get_instructions` first." - -Pi has no MCP support. Its prompt writes a small `whiteboard` skill that runs -`whiteboard api session_get_instructions` through `~/.local/bin/whiteboard`. - -## Plugins - -Each agent also has a plugin or package that registers the same `whiteboard` MCP -server. Installing it replaces the paste step. The connect card shows the -install command, or the Cursor link, above **or paste this prompt**. - -The npm packages and the Cursor listing are not published yet; the Claude Code -and Codex marketplace commands work once the plugins are on `main`. - -| Agent | What installs | Install | +| Agent | Install target | Skill location | | --- | --- | --- | -| Claude Code | plugin with the `whiteboard` MCP server | `/plugin marketplace add devdotfast/review`, then `/plugin install whiteboard@devfast` | -| Codex | plugin with the `whiteboard` MCP server and a `whiteboard` skill | `codex plugin marketplace add devdotfast/review`, then `codex plugin add whiteboard@devfast` | -| Cursor | `whiteboard` MCP server | **Install in Cursor** on the connect card | -| OpenCode | npm plugin `@dev.fast/opencode-whiteboard` | add `"@dev.fast/opencode-whiteboard"` to `"plugin"` in `~/.config/opencode/opencode.json` | -| Pi | npm package `@dev.fast/pi-whiteboard` with the `whiteboard` skill | `pi install npm:@dev.fast/pi-whiteboard` | - -Where each install comes from: - -- Claude Code and Codex read the marketplace files at this repository's root - (`.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`) from - the default branch on GitHub. What is on `main` is what installs; there is no - release or package. -- OpenCode and Pi install from npm. -- Cursor uses the link on the connect card. A marketplace listing is separate. - -Every plugin runs the same command as the prompt. Claude Code hides the -plugin's server when a user-level `whiteboard` server has the identical command, -so installing both does not create two servers. - -The Cursor link needs `~/.local/bin/whiteboard`. Install the whiteboard command first. +| Claude Code | `claude` or `claude-code` | `~/.claude/skills` | +| Codex | `codex` | `~/.agents/skills` | +| Cursor | `cursor` | `~/.cursor/skills` | -Pi has no MCP support, so its package ships the skill instead of a server. +Other coding agents that follow the shared Agent Skills convention can load the +same Review skills from `~/.agents/skills`. -## Update from an earlier version +Review Desktop is the recommended installation path. On first launch it detects +installed agents, asks which integrations to enable, and keeps their skills in +sync with app updates. Generated skills carry the Review Desktop release version in +`SKILL.md` frontmatter. On the first launch after an update, Desktop replaces +older skills for enabled integrations automatically, including local edits. +Skills already at the bundled version are left alone. Start a new agent session +to load refreshed skills. Reinstall from settings to repair same-version edits +or missing supporting files; terminal-only installs are not automatically enrolled. You can manage the integrations later from Review +settings. -Earlier versions of Whiteboard installed skills into agent configuration. After -the update, Whiteboard opens an update screen once. It explains the change and -shows the same **Copy prompt** rows. +For Codex and Claude Code, Desktop setup also registers a user-level `review` +MCP connection. It launches a small adapter using Review's bundled runtime; no +separate Node installation, agent CLI, port, or token configuration is needed. +The desktop server remains the owner of every review. Other agents can use the +installed `review api` command. -**Remove old Whiteboard skills** lists the skill directories it will delete, then -reports what it removed and what it left. It deletes only skills that Whiteboard -installed, which have `whiteboard-version` in their `SKILL.md` frontmatter. Skills -you wrote are left alone. Until nothing is left to remove, the button also -appears in **Settings → Agents**. +App updates refresh the adapter along with enabled integrations and repair missing +MCP entries. Reinstall in settings runs the same setup again. Review leaves +customized MCP entries alone and explains how to replace them if desired; +uninstall removes only unchanged entries it created. Restart the agent or +reconnect its MCP server after setup. Start a new session for updated skills. -Choose **Done**, or close the tab, to dismiss the update screen. +This automatic MCP setup belongs to the Desktop integration flow. The +terminal-only `review install` command still installs skills and the CLI only. -## Trace search +## Installed skills -While trace capture is on, the prompts for Claude Code, Codex, and Pi also set -up trace search with fff. The agent installs `~/.local/bin/fff-mcp` if it is -missing and registers a second MCP server named `fff` over Whiteboard's trace -search folder. Pi installs the `@ff-labs/pi-fff` package instead. +- `dev-review` authors change and architecture reviews, including software maps. -The prompt is generated when you copy it. If you turn on trace capture later, -copy the prompt again. Trace capture itself needs hooks in each agent; see -[Trace storage](cli-reference.md#trace-storage). +The authoring skill coordinates the whole workflow. In normal use, ask your +agent for a Review instead of running the lower-level CLI commands yourself. -## Whiteboard instructions +## Start a change review -Agents call the `session_get_instructions` tool; from a terminal, run -`whiteboard api session_get_instructions '{}'`. The default topic returns the authoring workflow. -Other topics are `file-lenses`, `scratchpad`, and `trace-archaeology`. +Codex: -In normal use, ask your agent for a Whiteboard instead of running the lower-level -CLI commands yourself. +```text +Use $dev-review to review my current branch against up to date main, then open +it in Review. +``` -## Start a change whiteboard +Claude Code: ```text -Create a Whiteboard of my current branch against up to date main, then open it -in Whiteboard. +Use the dev-review skill to review my current branch against up to date main, +then open it in Review. ``` +In Cursor, choose `dev-review` from the `/` menu and give it the same request. + You can replace “current branch” with a pull request URL or tell the agent which base and head revisions to compare. ## Start an architecture review -An architecture session uses the same canvas without requiring a code diff. Ask +An architecture Review uses the same canvas without requiring a code diff. Ask for the questions and system boundaries you care about: ```text -Create a Whiteboard that explains the main data flows, storage boundaries, and -critical code paths in this repository. Open it in Whiteboard when it is ready. +Use the Review skill to explain the main data flows, storage boundaries, and +critical code paths in this repository. Open it in Review when it is ready. ``` -Specific context produces a better session. Tell the agent what you already +Specific context produces a better Review. Tell the agent what you already believe, which risks you care about, and where you want sequence or database views. +## Install from the terminal + +The desktop app is primary, but headless environments can install integrations +explicitly: + +```sh +review install codex +review install claude cursor +review install all +``` + +With no target, `review install` installs every supported integration. Run +`review install --help` for the current target list. + ## Provider boundary -Whiteboard runs locally, but a connected coding agent may send source code, prompts, -and context to its own model provider. Whiteboard does not change that provider's +Review runs locally, but a connected coding agent may send source code, prompts, +and context to its own model provider. Review does not change that provider's privacy, retention, or billing terms. See [Privacy](privacy.md) for the data -Whiteboard itself sends. +Review itself sends. diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 8e5ddaefc..65274c130 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -2,50 +2,51 @@ Maps -> Agent connection and migration. +-> Maps -> Agent installation and migration. --> -The `whiteboard` command is the control surface shared by Whiteboard and coding -agents. Whiteboard installs the preferred CLI in `~/.local/bin` and keeps +The `review` command is the control surface shared by Review Desktop and coding +agents. Review Desktop installs the preferred CLI in `~/.local/bin` and keeps it matched to the running app. -Run `whiteboard --help` for the authoritative options in your installed +Run `review --help` for the authoritative options in your installed version. ## Compatibility -Whiteboard is in beta. Before 1.0, command syntax and JSON event fields may change -between releases. Whiteboard installs an app-managed CLI that matches the +Review is in beta. Before 1.0, command syntax and JSON event fields may change +between releases. Review Desktop installs an app-managed CLI that matches the running app; use that copy instead of relying on compatibility between different CLI and Desktop versions. -The `whiteboard map` command group is experimental. Its verbs, Git-notes storage +The `review map` command group is experimental. Its verbs, Git-notes storage model, and JSON events may change without a migration period before 1.0. -The `whiteboard trace` command group and trace capture are experimental and off -by default. `whiteboard trace storage use s3` configures S3/R2 capture and -`whiteboard trace install` installs the per-agent hooks; Whiteboard Desktop exposes it -under Settings ▸ Experimental Features. See [Trace storage](#trace-storage) -for the hosted store and the storage selection commands. +The `review trace` command group and trace capture are experimental and off +by default. `review install` configures S3/R2 capture only when +`--trace-*` credentials are given; Review Desktop exposes it under Settings ▸ +Experimental Features. See [Trace storage](#trace-storage) for the hosted +store and the storage selection commands. ## Common workflow ```sh -whiteboard app launch -whiteboard info -whiteboard api tools -whiteboard app pick --session +review app launch +review info +review api tools +review app pick --review ``` -Most people let their coding agent drive this workflow: it authors through -`whiteboard api` or the Whiteboard MCP tools. See [Coding agents](agents.md). +Most people let the installed Review skill drive this workflow: it authors +through `review api` or the Review MCP tools. See +`packages/review/skills/dev-review/SKILL.md`. -`whiteboard api` prints a tool's JSON result, except for text replies such as -`session_get` and `session_diff` patches, which print as-is. List arguments are +`review api` prints a tool's JSON result, except for text replies such as +`review_get` and `review_diff` patches, which print as-is. List arguments are JSON arrays: ```sh -whiteboard api session_diff '{"sessionId":"","format":"patch","paths":["src/app.ts","docs"]}' +review api review_diff '{"reviewId":"","format":"patch","paths":["src/app.ts","docs"]}' ``` ## Machine-readable output @@ -53,10 +54,10 @@ whiteboard api session_diff '{"sessionId":"","format":"patch","paths":["sr Commands that expose `--json` accept it after the complete command path: ```sh -whiteboard info --json -whiteboard app pick --json -whiteboard map check --json -whiteboard version --json +review info --json +review app pick --json +review map check --json +review version --json ``` Stdout then contains newline-delimited JSON events only. Human progress moves @@ -66,7 +67,7 @@ for coding agents and automation. For example, the installed CLI reports its version as one JSONL event: ```console -$ whiteboard version --json +$ review version --json {"event":"version","version":"0.0.1"} ``` @@ -74,78 +75,80 @@ $ whiteboard version --json | Command | Purpose | | ---------------------- | ----------------------------------------------------------------- | -| `whiteboard app` | Start Whiteboard (background unless `--focus`). Bare `whiteboard app` aliases `app launch`. | -| `whiteboard app launch` | Start Whiteboard, or activate a running one with `--focus`. | -| `whiteboard app pick` | Select a published session and optionally choose its opened view. | -| `whiteboard info` | List sessions associated with the current checkout. | -| `whiteboard api` | Call a JSON Whiteboard authoring tool; `whiteboard api tools` lists them. | -| `whiteboard mcp` | Serve the same authoring tools over stdio MCP. | -| `whiteboard server start` | Run the foreground authoring server without Desktop. | -| `whiteboard server status` | Check readiness of the selected headless server. | -| `whiteboard map` | Author, validate, and share experimental software maps. | -| `whiteboard connect` | Print the prompt that connects a coding agent to Whiteboard. | -| `whiteboard migrate apply` | Migrate supported legacy Whiteboard data. | -| `whiteboard version` | Print the Whiteboard package version. | +| `review app` | Start Review Desktop (background unless `--focus`). Bare `review app` aliases `app launch`. | +| `review app launch` | Start Review Desktop, or activate a running one with `--focus`. | +| `review app pick` | Select a published Review and optionally choose its opened view. | +| `review info` | List Reviews associated with the current checkout. | +| `review api` | Call a JSON Review authoring tool; `review api tools` lists them. | +| `review mcp` | Serve the same authoring tools over stdio MCP. | +| `review server start` | Run the foreground authoring server without Desktop. | +| `review server status` | Check readiness of the selected headless server. | +| `review map` | Author, validate, and share experimental software maps. | +| `review install` | Install Review skills for supported coding agents. | +| `review migrate apply` | Migrate supported legacy Review data. | +| `review version` | Print the Review package version. | ## Headless authoring -`whiteboard server start` runs the authoring server in the foreground without a -Desktop installation. `whiteboard server status --json` checks readiness. Stop the +`review server start` runs the authoring server in the foreground without a +Desktop installation. `review server status --json` checks readiness. Stop the server with Ctrl-C or SIGTERM. CLI and MCP clients use the same authoring tools -and instructions as Desktop. +and shared `dev-review` skill as Desktop. -Set `DEV_WHITEBOARD_SERVER_DIR` for the server and clients to select a job's saved -state, or use `whiteboard --state-dir server start` and -`whiteboard --state-dir api …`. The default is -`$DEV_WHITEBOARD_HOME` (`~/.dev` by default), shared with Desktop. Optional map generation requires starting with +Set `DEV_REVIEW_SERVER_DIR` for the server and clients to select a job's saved +state, or use `review --state-dir server start` and +`review --state-dir api …`. The default is +`$DEV_REVIEW_HOME` (`~/.dev` by default), shared with Desktop. Optional map generation requires starting with `--software-maps`; existing map uploads remain supported. CI supplies the agent and a prepared checkout with explicit base/head revisions. Each accepted edit is saved as a version immediately; the author holds a -`session_activity` lease while writing, exactly as with Desktop. +`review_activity` lease while writing, exactly as with Desktop. -For local testing, open Desktop on the same `DEV_WHITEBOARD_HOME` and select the -session from Home. Both hosts use `review-api.db`; edits appear live with the same -session ID, history, and resources. The headless server may be stopped after -authoring. For a custom `--state-dir` or `DEV_WHITEBOARD_SERVER_DIR`, launch Desktop -with `DEV_WHITEBOARD_HOME` set to that directory. From this checkout, use `pnpm dev` -to launch the matching Desktop build. `whiteboard server open` has been removed. +For local testing, open Desktop on the same `DEV_REVIEW_HOME` and select the +review from Home. Both hosts use `review-api.db`; edits appear live with the same +review ID, history, and resources. The headless server may be stopped after +authoring. For a custom `--state-dir` or `DEV_REVIEW_SERVER_DIR`, launch Desktop +with `DEV_REVIEW_HOME` set to that directory. From this checkout, use `pnpm dev` +to launch the matching Desktop build. `review server open` has been removed. ## Desktop and discovery ```sh -whiteboard app launch -whiteboard app pick -whiteboard app pick --session --view diff -whiteboard info -whiteboard info --all +review app launch +review app pick +review app pick --review --view diff +review info +review info --all ``` Launches stay in the background; add `--focus` to bring the window forward. -`whiteboard app pick` opens an interactive picker when no UUID is given. `whiteboard +`review app pick` opens an interactive picker when no UUID is given. `review info` reports titles, UUIDs, status, and whether each -Whiteboard is in sync. It requires Whiteboard to be running. `--all` includes -active sessions for every worktree in the current repository. +Review is in sync. It requires Review Desktop to be running. `--all` includes +active Reviews for every worktree in the current repository. -The legacy `whiteboard app --session ` form remains a compatibility alias for -`whiteboard app pick --session `. +The legacy `review app --review ` form remains a compatibility alias for +`review app pick --review `. -`whiteboard app pick` accepts `--view` with one of `whiteboard`, `commits`, `diff`, +`review app pick` accepts `--view` with one of `review`, `commits`, `diff`, `map`, or `trace`. ## Authoring -Whiteboards are created and edited through the JSON API: `whiteboard api` or the Whiteboard -MCP tools. See `packages/whiteboard/src/session-api/README.md` for the authoring -workflow and the full tool/route list. `whiteboard api tools` prints the current -tool catalog. +Reviews are created and edited through the JSON API: `review api`, the Review +MCP tools, or the installed dev-review skill. See +`packages/review/skills/dev-review/SKILL.md` +and `packages/review/src/review-api/README.md` +for the authoring workflow and the full tool/route list. `review api tools` +prints the current tool catalog. -### Session targets +### Review targets -Register a local checkout with `session_register_repository({path})`, then pass -its `repositoryId` in `target` to `session_create`. Use `session_set_target` to -change an existing session's target while preserving its authored content. -These tools are available through `whiteboard api` and MCP. +Register a local checkout with `review_register_repository({path})`, then pass +its `repositoryId` in `target` to `review_create`. Use `review_set_target` to +change an existing review's target while preserving its authored content. +These tools are available through `review api` and MCP. Live source follows the checkout even in older authored versions; update references as source changes. Choose a commit target when source must stay fixed. @@ -156,23 +159,23 @@ as source changes. Choose a commit target when source must stay fixed. Revisions resolve when the command is accepted. To review the changes introduced by one commit, use its parent as `base`; omitting the base is equivalent to -`base=head`. For a GitHub PR, `session_create({pullRequestUrl})` needs no -target: Whiteboard fetches the PR into a registered checkout of its repository +`base=head`. For a GitHub PR, `review_create({pullRequestUrl})` needs no +target: Review fetches the PR into a registered checkout of its repository (using `gh`, or the public GitHub API for metadata) and pins GitHub's head and diff base, titled from the PR. The pins stay fixed; a later create for the same -PR returns the session with `headMoved` when the PR has moved on. +PR returns the review with `headMoved` when the PR has moved on. See [live and pinned worktrees](how-review-works.md#live-and-pinned-worktrees) for how each target runs language services. ## Software maps ```sh -whiteboard map open -whiteboard map open --force -whiteboard map check [] [--session ] -whiteboard map prune -whiteboard map push -whiteboard map fetch +review map open +review map open --force +review map check [] [--review ] +review map prune +review map push +review map fetch ``` Maps are stored per commit in Git notes under `refs/notes/dev-fast/*`. @@ -183,30 +186,30 @@ Maps are stored per commit in Git notes under `refs/notes/dev-fast/*`. - `prune` removes unreachable notes and fully flushed scratch buffers. - `push` and `fetch` share map notes through `origin`. -Every map verb accepts `--json`. Run `whiteboard map --help` for the storage model +Every map verb accepts `--json`. Run `review map --help` for the storage model and exact verb syntax. ## Trace storage ```sh -whiteboard trace status -whiteboard trace storage use s3 [--endpoint --bucket --key --secret [--region ]] -whiteboard trace storage use hosted [--origin ] -whiteboard trace config migrate [--dry-run] [--keep-legacy] -whiteboard trace list|show|pull|blame ... [--storage s3|hosted] -whiteboard trace sessions [--limit ] [--cursor ] [--storage s3|hosted] [--json] -whiteboard login [--traces] [--origin ] [--no-browser] [--json] -whiteboard logout -whiteboard whoami -whiteboard trace store create|delete|info [path] -whiteboard trace install [--no-harness-hooks] [--all-harnesses] [--json] -whiteboard trace uninstall-hooks [--json] -whiteboard trace allow [path] [--no-harness-hooks] [--all-harnesses] -whiteboard trace deny [path] +review trace status +review trace storage use s3 [--endpoint --bucket --key --secret [--region ]] +review trace storage use hosted [--origin ] +review trace config migrate [--dry-run] [--keep-legacy] +review trace list|show|pull|blame ... [--storage s3|hosted] +review trace sessions [--limit ] [--cursor ] [--storage s3|hosted] [--json] +review login [--traces] [--origin ] [--no-browser] [--json] +review logout +review whoami +review trace store create|delete|info [path] +review trace install [--no-harness-hooks] [--all-harnesses] [--json] +review trace uninstall-hooks [--json] +review trace allow [path] [--no-harness-hooks] [--all-harnesses] +review trace deny [path] ``` -`whiteboard login` signs in with GitHub identity and verified email access. It does -not enable trace collection. `whiteboard login --traces` also requests GitHub +`review login` signs in with GitHub identity and verified email access. It does +not enable trace collection. `review login --traces` also requests GitHub repository access. Use `--no-browser` on a remote machine, then open the printed URL on your desktop. Repository access does not replace per-repository trace capture consent. @@ -214,31 +217,31 @@ capture consent. A foreground hosted trace command offers to authorize repositories and resumes once login succeeds. With `--json`, redirected input, or a hook, it never prompts. A missing grant produces `repository_authorization_required` and the remedy -`whiteboard login --traces`. Local and direct S3 operations do not request GitHub -permissions. `whiteboard login` supplies credentials for both sharing and hosted traces. +`review login --traces`. Local and direct S3 operations do not request GitHub +permissions. `review login` supplies credentials for both sharing and hosted traces. -### Sharing a session +### Sharing a review ```sh -whiteboard share --session [--version ] [--request-id ] [--json] -whiteboard share revoke [--json] +review share --review [--version ] [--request-id ] [--json] +review share revoke [--json] ``` -The local Whiteboard host must be running. Sharing uploads one immutable saved +The local Review host must be running. Sharing uploads one immutable saved version; an omitted version is resolved once when the request starts. The result -contains `shareId`, `version`, and `url`. Running Share again creates a new link unless the same `--request-id` is reused with the same session/version. -Recipients do not need a session account. They do need Git access to the GitHub -repository. Open the link in Whiteboard, or use **Open Shared Session** in -the command palette. The app downloads the session and fetches its exact base +contains `shareId`, `version`, and `url`. Running Share again creates a new link unless the same `--request-id` is reused with the same review/version. +Recipients do not need a Review account. They do need Git access to the GitHub +repository. Open the link in Review Desktop, or use **Open Shared Review** in +the command palette. The app downloads the review and fetches its exact base and head commits into a dedicated managed checkout before opening it. Pin live worktree reviews to commits before sharing. Push the reviewed commits to GitHub before sharing. Publication verifies both commits through a fresh fetch and never pushes them for you. Git uses the machine's existing credentials. Sharing does not request hosted-trace scopes; -use `whiteboard login --traces` only when enabling hosted traces. +use `review login --traces` only when enabling hosted traces. -A share includes the saved session, sender attribution, images, retained maps, +A share includes the saved review, sender attribution, images, retained maps, and whole retained trace conversations. Code, diffs, and commit lists come from Git. Anyone with the link can download retained resources, while GitHub separately controls repository access. Imported reviews are read-only and @@ -250,20 +253,20 @@ Revocation stops new downloads. Already-issued object URLs may work for up to five minutes, and saved copies remain readable. Branch movement and later edits do not change a published snapshot. -`whiteboard server start` supports publishing without Desktop. The CLI selects the -same server/profile as `whiteboard api`, including `--state-dir`. CI can supply -`DEV_WHITEBOARD_SHARE_TOKEN` instead of a saved `whiteboard login`; optional -`DEV_WHITEBOARD_SHARE_ORIGIN` selects its bare HTTPS service origin. Environment +`review server start` supports publishing without Desktop. The CLI selects the +same server/profile as `review api`, including `--state-dir`. CI can supply +`DEV_REVIEW_SHARE_TOKEN` instead of a saved `review login`; optional +`DEV_REVIEW_SHARE_ORIGIN` selects its bare HTTPS service origin. Environment credentials are not written to the profile. Git credentials are still needed for the verification fetch. The exporter, importer and hosted client remain available from -`@dev.fast/whiteboard/sharing` for other hosts. +`@dev.fast/review/sharing` for other hosts. -Whiteboard stores traces in one selected place per machine: an **s3** store (an +Review stores traces in one selected place per machine: an **s3** store (an S3-compatible bucket you own, R2 included) or the **hosted** store at `https://app.dev.fast`. The configuration lives in -`$DEV_WHITEBOARD_HOME/trace/config.json`: +`$DEV_REVIEW_HOME/trace/config.json`: ```json { @@ -272,7 +275,7 @@ S3-compatible bucket you own, R2 included) or the **hosted** store at "stores": { "s3": { "endpoint": "https://.r2.cloudflarestorage.com", - "bucket": "whiteboard-traces", + "bucket": "review-traces", "accessKeyId": "…", "secretAccessKey": "…", "region": "auto", @@ -302,16 +305,16 @@ S3-compatible bucket you own, R2 included) or the **hosted** store at - `repositories` is hosted-only consent: the repositories you allowed to publish complete session transcripts, and the hosted origins each may publish to (`enabledOrigins` defaults to `https://app.dev.fast`). Written by - `whiteboard trace allow` and `whiteboard trace deny`. Bucket uploads never read it. + `review trace allow` and `review trace deny`. Bucket uploads never read it. An existing bucket setup keeps working unchanged. Without a config file, `~/.config/dev-trace/env` and `settings.json` (or exported `TRACE_R2_*` variables) select the bucket exactly as before; no login, migration, or new configuration is required. -`whiteboard trace storage use s3` selects the bucket. With `--endpoint`, +`review trace storage use s3` selects the bucket. With `--endpoint`, `--bucket`, `--key`, and `--secret` it also saves `stores.s3` after checking -the bucket is reachable. `whiteboard trace config migrate` copies an existing +the bucket is reachable. `review trace config migrate` copies an existing legacy setup into `stores.s3`, refusing to overwrite a different entry or to switch away from a hosted selection; `--dry-run` previews without writing and never prints secrets. After a successful migration the legacy `env` and @@ -320,25 +323,18 @@ their originals so the new file is the only active source; pass `--keep-legacy` to leave them in place. To roll back, rename them back and delete the config file. -`whiteboard trace store` manages the hosted store of one repository. `store create` +`review trace store` manages the hosted store of one repository. `store create` creates it, one time for each repository, and needs push access. `store info` reports the store id, the status, and the stored bytes. `store delete` asks the store to delete the hosted copies, which a repository admin may do; the consent -of this machine stays until `whiteboard trace deny` removes it. `whiteboard trace -install` installs the harness hooks of this machine for every detected agent, -or for all of them with `--all-harnesses`, and touches no repository. Claude -Code, Codex, OpenCode, and Pi have hooks; Cursor has none. For a bucket: +of this machine stays until `review trace deny` removes it. `review trace +install` installs the harness hooks of this machine and touches no repository. -```sh -whiteboard trace storage use s3 --endpoint --bucket --key --secret -whiteboard trace install -``` - -`whiteboard trace uninstall-hooks` removes tracing hooks while keeping the CLI, +`review trace uninstall-hooks` removes tracing hooks while keeping the CLI, login, consent, and captured traces. -`whiteboard trace storage use hosted` requires `whiteboard login` for the origin, -a store that answers the current contract, and `whiteboard trace allow` for the +`review trace storage use hosted` requires `review login` for the origin, +a store that answers the current contract, and `review trace allow` for the checkout's repository at that origin; only then does it persist the selection. Bucket credentials stay saved and inactive. Logging in or creating a store never selects hosted storage by itself, a legacy bucket always @@ -350,17 +346,17 @@ Before setup, review [hosted trace consent and access](privacy.md#hosted-trace-s Use a Desktop release that supports v2 configuration before migration. `--keep-legacy` does not prevent older apps from uploading to their saved bucket. -`whiteboard version --verbose [--json]` reports CLI paths, delegation, and build -identity. Set `DEV_FAST_WHITEBOARD_CLI_NO_DELEGATE=1` to inspect the invoked CLI directly. +`review version --verbose [--json]` reports CLI paths, delegation, and build +identity. Set `DEV_FAST_REVIEW_CLI_NO_DELEGATE=1` to inspect the invoked CLI directly. Read commands accept `--storage s3|hosted` to inspect the other store for one operation. The override never changes the selection, capture -settings, or consent. `whiteboard trace status` names the effective store, the +settings, or consent. `review trace status` names the effective store, the configuration sources in use, and the config file, without revealing secrets. On a hosted machine it also prints `Stored bytes`, the size of every completed upload in the repository's store. -`whiteboard trace sessions` lists every published session of the current +`review trace sessions` lists every published session of the current repository's hosted store, ordered by session id, 50 per page. The command needs the hosted store. On a machine that selects s3, pass `--storage hosted`. `--limit` selects a different page size, from 1 to 200. @@ -369,43 +365,43 @@ bytes. When more sessions follow, the last line names the `--cursor` value of the next page, and repeats `--limit` when you gave one. The command refuses a bad `--limit` or `--cursor` before it reads the store. -The command reads the store live. It needs `whiteboard login` for the hosted +The command reads the store live. It needs `review login` for the hosted origin and GitHub read access to the repository. It does not need -`whiteboard trace allow`. It never serves saved copies and prints no signed +`review trace allow`. It never serves saved copies and prints no signed download URL. The hosted store is the only store it lists, so it refuses `--storage s3`. Under `--json` the command prints one `trace.sessions` event. A store older than contract 0.3.0 answers "does not support listing every -session yet"; use `whiteboard trace list --commit ` there. +session yet"; use `review trace list --commit ` there. ### Desktop and npm installed together -Trace hooks keep the absolute executable of the first working Whiteboard +Trace hooks keep the absolute executable of the first working Review installation. Installing or refreshing the other installation preserves those harness and repository hooks. If the old executable is missing, setup can -replace it. Without a Desktop launcher, npm tracing resolves `whiteboard` from PATH +replace it. Without a Desktop launcher, npm tracing resolves `review` from PATH and records that absolute path. -Desktop preserves an existing npm launcher at `~/.local/bin/whiteboard`. Removing +Desktop preserves an existing npm launcher at `~/.local/bin/review`. Removing Desktop's trace setup leaves another working installation's hooks and shared -capture settings enabled. `whiteboard trace uninstall-hooks` is an explicit reset -of Whiteboard hooks in the selected profile, regardless of which installation +capture settings enabled. `review trace uninstall-hooks` is an explicit reset +of Review hooks in the selected profile, regardless of which installation created them. ### Tracing without Desktop -The `whiteboard trace` commands run without a desktop installation or session. -Install the `@dev.fast/whiteboard` npm package with Node 24, then run: +The `review trace` commands run without a desktop installation or session. +Install the `@dev.fast/review` npm package with Node 24, then run: ```sh -whiteboard login -whiteboard trace store create -whiteboard trace allow . -whiteboard trace status +review login +review trace store create +review trace allow . +review trace status ``` `allow` writes hooks only for harnesses present on the machine. Use `--all-harnesses` to write all four or `--no-harness-hooks` to write none. -These flags also work with `whiteboard trace install`. +These flags also work with `review trace install`. ## Environment variables @@ -414,40 +410,34 @@ and telemetry administration: | Variable | Meaning, precedence, and default | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `TRACE_ENV_FILE` | Selects the legacy direct-bucket environment file. The default is `~/.config/dev-trace/env`. Setting either legacy file variable also makes `whiteboard trace setup` update the legacy files unless an S3 profile already exists. | -| `TRACE_SETTINGS_FILE` | Selects the legacy capture settings file. The default is `~/.config/dev-trace/settings.json`. Setting either legacy file variable also makes `whiteboard trace setup` update the legacy files unless an S3 profile already exists. | +| `TRACE_ENV_FILE` | Selects the legacy direct-bucket environment file. The default is `~/.config/dev-trace/env`. Setting either legacy file variable also makes `review trace setup` update the legacy files unless an S3 profile already exists. | +| `TRACE_SETTINGS_FILE` | Selects the legacy capture settings file. The default is `~/.config/dev-trace/settings.json`. Setting either legacy file variable also makes `review trace setup` update the legacy files unless an S3 profile already exists. | | `TRACE_HOME_DIR` | Replaces the operating-system home used to find the installed trace command and the trace repository registry under `.config/dev-trace`. The default is the operating-system home. | -| `TRACE_OPENCODE_TRACES_ROOT` | Selects where Whiteboard writes fresh OpenCode session exports. The default is `$DEV_WHITEBOARD_HOME/opencode-traces`. | -| `DEV_FAST_WHITEBOARD_DESKTOP_STATE_ROOT` | Gives a launched Whiteboard instance separate `user-data` and `extensions` directories beneath this root. Empty or unset uses the normal Desktop state. | -| `DEV_FAST_WHITEBOARD_DESKTOP_BACKGROUND` | Set to `1` by `whiteboard app` launches without `--focus`. Whiteboard then shows its first window without taking focus and ignores focus requests until you click it or run `whiteboard app launch --focus`. | -| `PROGRESSIVE_WHITEBOARD_TELEMETRY_INTERNAL` | `1` marks telemetry as internal and `0` marks it as external. Either value overrides the stored internal marker and workspace-checkout detection. | -| `POSTHOG_KEY` | Legacy PostHog project key alias. The first non-empty value wins in this order: `PROGRESSIVE_WHITEBOARD_POSTHOG_KEY`, `DEV_FAST_POSTHOG_KEY`, `POSTHOG_KEY`, then the embedded key. | -| `POSTHOG_HOST` | Legacy PostHog host alias. The first non-empty value wins in this order: `PROGRESSIVE_WHITEBOARD_POSTHOG_HOST`, `DEV_FAST_POSTHOG_HOST`, then `POSTHOG_HOST`. When none is set, the host defaults to `https://us.i.posthog.com`. | +| `TRACE_OPENCODE_TRACES_ROOT` | Selects where Review writes fresh OpenCode session exports. The default is `$DEV_REVIEW_HOME/opencode-traces`. | +| `DEV_FAST_REVIEW_DESKTOP_STATE_ROOT` | Gives a launched Review Desktop instance separate `user-data` and `extensions` directories beneath this root. Empty or unset uses the normal Desktop state. | +| `DEV_FAST_REVIEW_DESKTOP_BACKGROUND` | Set to `1` by `review app` launches without `--focus`. Review Desktop then shows its first window without taking focus and ignores focus requests until you click it or run `review app launch --focus`. | +| `PROGRESSIVE_REVIEW_TELEMETRY_INTERNAL` | `1` marks telemetry as internal and `0` marks it as external. Either value overrides the stored internal marker and workspace-checkout detection. | +| `POSTHOG_KEY` | Legacy PostHog project key alias. The first non-empty value wins in this order: `PROGRESSIVE_REVIEW_POSTHOG_KEY`, `DEV_FAST_POSTHOG_KEY`, `POSTHOG_KEY`, then the embedded key. | +| `POSTHOG_HOST` | Legacy PostHog host alias. The first non-empty value wins in this order: `PROGRESSIVE_REVIEW_POSTHOG_HOST`, `DEV_FAST_POSTHOG_HOST`, then `POSTHOG_HOST`. When none is set, the host defaults to `https://us.i.posthog.com`. | | `DO_NOT_TRACK` | Disables passive telemetry when set to `1` or `true`. | | `DNT` | Disables passive telemetry when set to `1` or `true`. | -| `PROGRESSIVE_WHITEBOARD_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | +| `PROGRESSIVE_REVIEW_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | | `DEV_FAST_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | -| `DEV_FAST_PROGRESSIVE_WHITEBOARD_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | -| `DEV_FAST_WHITEBOARD_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | +| `DEV_FAST_PROGRESSIVE_REVIEW_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | +| `DEV_FAST_REVIEW_TELEMETRY_DISABLED` | Disables passive telemetry when set to `1` or `true`. | See [Telemetry and privacy](telemetry.md) for the complete telemetry controls and data policy. -## Agent connection and migration +## Agent integration and migration ```sh -whiteboard connect [...] [--json] -whiteboard migrate apply -whiteboard migrate apply --force -whiteboard version +review install [claude|claude-code|codex|cursor|all] +review migrate apply +review migrate apply --force +review version ``` -`whiteboard connect` prints the prompt that connects an agent to Whiteboard, the same -text Whiteboard Desktop copies. Paste it into a session of that agent. Agents are -`claude` (or `claude-code`), `codex`, `cursor`, `opencode`, `pi`, and `all`. -With no agent, it prints every prompt under a heading per agent. `--json` emits one -`connect` event whose `prompts` field maps each agent to its prompt. See -[Coding agents](agents.md#connect-an-agent). - -Migration is only for legacy Whiteboard state; use `--force` only to restart an -interrupted migration. +The app normally installs and updates agent skills. Use `review install` for a +headless environment. Migration is only for legacy Review state; use `--force` +only to restart an interrupted migration. diff --git a/docs/cli-releases.md b/docs/cli-releases.md index 6bd77a1c8..e15d7ea79 100644 --- a/docs/cli-releases.md +++ b/docs/cli-releases.md @@ -1,15 +1,15 @@ -# Publishing the Whiteboard CLI +# Publishing the Review CLI -The `Whiteboard CLI Release` workflow publishes the public `@dev.fast/whiteboard` npm -package. The package contains `whiteboard server`, `whiteboard share`, `whiteboard trace`, -and the agent instructions. It runs independently of Desktop releases and requires +The `Review CLI Release` workflow publishes the public `@dev.fast/review` npm +package. The package contains `review server`, `review share`, `review trace`, +and the agent skills. It runs independently of Desktop releases and requires Node 24; building it does not install or launch Desktop. ## Release from GitHub After this workflow reaches `main`: -1. Open the repository's **Actions** tab and select **Whiteboard CLI Release**. +1. Open the repository's **Actions** tab and select **Review CLI Release**. 2. Click **Run workflow**, select **main**, and choose **patch**, **minor**, or **major**. Check **dry_run** to rehearse without creating a tag or publishing. 3. Run it. The summary reports the version, source commit, and installation @@ -19,7 +19,7 @@ GitHub provides the [manual workflow form](https://docs.github.com/en/actions/ho this workflow supplies the bump calculation. The next version is calculated from the highest stable version among npm's -published versions, existing `whiteboard-vX.Y.Z` tags, and the source package version. +published versions, existing `review-vX.Y.Z` tags, and the source package version. For example, from `0.2.10`: | Selection | Next version | @@ -28,13 +28,13 @@ For example, from `0.2.10`: | minor | `0.3.0` | | major | `1.0.0` | -CLI tags use **`whiteboard-vX.Y.Z`**; Desktop tags keep **`vX.Y.Z`**. Prerelease tags +CLI tags use **`review-vX.Y.Z`**; Desktop tags keep **`vX.Y.Z`**. Prerelease tags are not supported by this workflow. Releases always use a commit already on `main`. A manual run uses the SHA selected when that run started, so a rerun does not silently publish newer source. Tags are the CLI release history. The workflow stamps the selected version -into the packed manifest and build metadata without committing +into the packed manifest, build metadata, and bundled skills without committing a version bump back to `main`. The source package version is a development baseline, not the latest published version. @@ -43,8 +43,8 @@ baseline, not the latest published version. You can also tag an existing commit on `main` and push it: ```sh -git tag whiteboard-v0.3.0 -git push origin whiteboard-v0.3.0 +git tag review-v0.3.0 +git push origin review-v0.3.0 ``` That tag triggers the same build, clean-install smoke test, and publication. @@ -58,7 +58,7 @@ so publication does not depend on a second tag event. ## Credentials and validation Set the repository Actions secret **`NPM_TOKEN`** to an npm token permitted to -publish `@dev.fast/whiteboard` under the `@dev.fast` scope. For unattended publishing, +publish `@dev.fast/review` under the `@dev.fast` scope. For unattended publishing, use a [granular token with bypass 2FA enabled](https://docs.npmjs.com/using-private-packages-in-a-ci-cd-workflow/). Only the authentication and publishing steps receive the token. Dry runs do not need it. The workflow also uses `GITHUB_TOKEN` to create the release tag and @@ -67,15 +67,15 @@ GitHub OIDC to attach npm provenance; no release deploy key is needed. Before publishing, the workflow tests release planning, trace behavior, and headless authoring. It then builds one tarball, installs it in a temporary prefix outside the workspace, and checks that its installed CLI can install -and remove agent hooks and commit a headless whiteboard without a display or Desktop. -The tarball includes the bundled product documentation. +and remove agent hooks and commit a headless review without a display or Desktop. +The tarball includes the bundled product documentation and stamped skills. The tested tarball is the one passed to `npm publish`. -The published `@dev.fast/whiteboard` package is the Node runtime shared by the CLI +The published `@dev.fast/review` package is the Node runtime shared by the CLI and Desktop. Its production dependencies are declared directly in its manifest. Workspace libraries and Git code that tsdown bundles are build dependencies. -The private `@dev.fast/whiteboard-canvas` workspace at `packages/whiteboard/app` owns +The private `@dev.fast/review-canvas` workspace at `packages/review/app` owns React, layout libraries, Vite, and browser tests. Desktop builds and copies that canvas separately; the CLI neither builds nor ships it. Release packaging only stamps metadata and stages docs; it never rewrites the dependency graph. @@ -101,6 +101,6 @@ next version. An explicitly pushed tag is retried by rerunning its workflow. ## Install and use in CI ```sh -npm install --global @dev.fast/whiteboard@ -whiteboard server start +npm install --global @dev.fast/review@ +review server start ``` diff --git a/docs/how-review-works.md b/docs/how-review-works.md index 1232dc9be..48105ac4f 100644 --- a/docs/how-review-works.md +++ b/docs/how-review-works.md @@ -1,23 +1,23 @@ -# How Whiteboard works +# How Review works -Whiteboard separates authoring from reading. A coding agent studies a change and -writes a guided document; Whiteboard gives the human reviewer live code, +Review separates authoring from reading. A coding agent studies a change and +writes a guided document; Review Desktop gives the human reviewer live code, and system views around that document. ```mermaid flowchart LR - A[Branch, change, or PR] --> B[Agent authors a session] - B --> C[Server saves each edit through the Whiteboard API] - C --> D[Whiteboarder reads in Whiteboard] + A[Branch, change, or PR] --> B[Agent authors a Review] + B --> C[Server saves each edit through the Review API] + C --> D[Reviewer reads in Review Desktop] ``` -## A session is more than a diff +## A Review is more than a diff -Each session can combine: +Each Review can combine: - concise prose about intent, architecture, data flow, and risk; - source links and code peeks anchored to exact files and line ranges; @@ -30,59 +30,57 @@ evidence rather than the only way to understand the change. ## Live and pinned worktrees -A live session follows saved files in your existing worktree, including when viewing +A live review follows saved files in your existing worktree, including when viewing older authored versions. You are responsible for updating references as source changes. -Language services use that checkout’s project and dependencies. A commit session keeps source fixed -and uses Whiteboard-owned worktrees pinned to its commits, running `devfast.prepare` +Language services use that checkout’s project and dependencies. A commit review keeps source fixed +and uses Review-owned worktrees pinned to its commits, running `devfast.prepare` to set up dependencies. Choose live for ongoing work and pinned for a fixed comparison. -Session source is read-only. +Review source is read-only. Language services require matching environment buffers and use the current -project's dependencies for live sessions. -See [session targets](cli-reference.md#session-targets) for the API options. +project's dependencies for live reviews. +See [review targets](cli-reference.md#review-targets) for the API options. ## Every edit saves immediately -Authoring goes through the JSON API: `whiteboard api` or the Whiteboard MCP tools. -Every accepted edit is saved as soon as it is applied; there is no publish, -checkpoint, or render-report step. See `packages/whiteboard/src/session-api/README.md` +Authoring goes through the JSON API: `review api`, the Review MCP tools, or +the dev-review skill. Every accepted edit is saved as soon as it is applied; +there is no publish, checkpoint, or render-report step. See +`packages/review/skills/dev-review/SKILL.md` +and `packages/review/src/review-api/README.md` for the full authoring workflow. -Agents connect to the MCP tools by registering `whiteboard mcp` themselves, from a -prompt that Whiteboard gives you; Whiteboard does not edit agent configuration. See -[Coding agents](agents.md#connect-an-agent). - -The published document is `.bundle/document/whiteboard-document.json`, with format -`whiteboard-document/1` and a version-2 manifest. Software-map bundles contain +The published document is `.bundle/document/review-document.json`, with format +`review-document/1` and a version-2 manifest. Software-map bundles contain `head-map.json` and `base-map.json`, with format `software-map/1`. The server serves JSON and the canvas renders it with built-in components, without executing authored document or map JavaScript. The local server may evaluate legacy sealed JavaScript during migration to this JSON format; the renderer remains JSON-only. -## Sessions have an explicit lifecycle +## Reviews have an explicit lifecycle | State | What happens next | | ----------------- | ------------------------------------------------------------------------------------ | -| `draft` | The agent authors the session through the Whiteboard API; every accepted edit is saved. | -| `awaiting-review` | The reviewer reads the session or dismisses it. | +| `draft` | The agent authors the Review through the Review API; every accepted edit is saved. | +| `awaiting-review` | The reviewer reads the Review or dismisses it. | -Sessions created by earlier versions may also be `awaiting-agent-updates`, -`accepted`, or `rejected`. Accepted and rejected sessions cannot be republished. +Reviews created by earlier versions may also be `awaiting-agent-updates`, +`accepted`, or `rejected`. Accepted and rejected Reviews cannot be republished. Explicit artifact repair is not a lifecycle transition. An accepted or rejected -session can have its current artifacts repaired while remaining terminal; -ordinary document and map publication still reject terminal sessions. +Review can have its current artifacts repaired while remaining terminal; +ordinary document and map publication still reject terminal Reviews. ## Migration and current-presentation repair -Whiteboard upgrades supported schema-2/3/4 records to schema 5 on the first ordinary -store read: a Home scan, opening the session, or a CLI lookup. It converts the +Review upgrades supported schema-2/3/4 records to schema 5 on the first ordinary +store read: a Home scan, opening the Review, or a CLI lookup. It converts the exact sealed artifacts at the current document and independent map pointers, -including terminal sessions. It never recompiles editable `review.mdx` or +including terminal Reviews. It never recompiles editable `review.mdx` or `data.ts`, or converts every private historical revision. Valid JSON artifacts and absent maps are preserved; drafts without a presentation only need a record -upgrade. Repeat reads need no further migration. `whiteboard migrate apply` runs +upgrade. Repeat reads need no further migration. `review migrate apply` runs the same per-review upgrade across the store and also performs repository-level cleanup. @@ -93,27 +91,27 @@ a reason to repair. If sealed conversion fails, the record, authoring inputs, candidates, and private refs stay unchanged. Home lists an attention entry: the review was published with the removed MDX toolchain and its stored files are damaged, so -it cannot be imported. Delete it from Home and recreate it with your coding -agent. Malformed or unsupported records remain explicit list errors. A -current-schema Whiteboard with broken artifacts shows the same guidance in its +it cannot be imported. Delete it from Home and recreate it with the Review +skill. Malformed or unsupported records remain explicit list errors. A +current-schema Review with broken artifacts shows the same guidance in its document or map load state. Already-JSON historical revisions remain readable. Older pre-data revisions -show “This older revision is unavailable in this version of Whiteboard” with +show “This older revision is unavailable in this version of Review” with **Open current review**, not a command to repair history. -## sessions live locally +## Reviews live locally -Authored sessions are stored under: +Authored Reviews are stored under: ```text -${DEV_WHITEBOARD_HOME:-~/.dev}/reviews// +${DEV_REVIEW_HOME:-~/.dev}/reviews// ``` The directory contains the document, supporting TypeScript, pinned state, -sealed revisions, and disposable build output. Whiteboard owns the infrastructure -files; agents author content through the JSON API (`whiteboard api` or the Whiteboard -MCP tools), never by editing files in this directory +sealed revisions, and disposable build output. Review owns the infrastructure +files; agents author content through the JSON API (`review api`, the Review +MCP tools, or the dev-review skill), never by editing files in this directory directly. `review.json` uses store schema 5 and records the independent document and map @@ -126,8 +124,8 @@ that legacy code into the canvas. Software maps are stored per commit in Git notes under `refs/notes/dev-fast/*`. They do not add generated map files to the reviewed -branch. Map notes can be shared explicitly with `whiteboard map push` and -`whiteboard map fetch`. +branch. Map notes can be shared explicitly with `review map push` and +`review map fetch`. See the [CLI reference](cli-reference.md) for the lifecycle commands and the [privacy overview](privacy.md) for the local and network boundaries. diff --git a/docs/privacy.md b/docs/privacy.md index 806e8b9aa..4be2e60f3 100644 --- a/docs/privacy.md +++ b/docs/privacy.md @@ -5,87 +5,87 @@ Outline: Local data -> Anonymous telemetry -> Errors -> Agent providers -> Explicit bug reports -> Opt-out -> Developer inspection. --> -Whiteboard reads source code and agent-authored documents from your machine. This +Review reads source code and agent-authored documents from your machine. This page separates the local product data, anonymous telemetry, connected coding agents, and explicit bug reports. Read the [dev.fast privacy policy](https://dev.fast/privacy) for the public -policy governing Whiteboard. +policy governing Review. For the exact event schemas and implementation references, see the full [telemetry reference](telemetry.md). ## What stays local -Whiteboard stores authored sessions under +Review stores authored Reviews under `~/.dev/reviews//` and keeps desktop discovery and state under `~/.dev/review-desktop/` by default. Passive product telemetry never includes: - source code or changed-file diffs; -- paths, repository names, Session titles, refs, revision hashes, symbols, or +- paths, repository names, Review titles, refs, revision hashes, symbols, or declarations; - review document text; - prompts or model output; or -- email, username, hostname, machine identifier, raw session UUID, or coding-agent +- email, username, hostname, machine identifier, raw Review UUID, or coding-agent session identifier. -The canvas talks to Whiteboard's local server. It does not connect directly to +The canvas talks to Review's local server. It does not connect directly to PostHog. ## Anonymous product telemetry -Anonymous telemetry is enabled by default. Whiteboard creates a random installation +Anonymous telemetry is enabled by default. Review creates a random installation UUID and does not associate it with a person profile. -Telemetry can include closed enums, booleans, counts, durations, the Whiteboard and +Telemetry can include closed enums, booleans, counts, durations, the Review and app versions, operating-system and architecture categories, feature usage, opaque lifecycle-correlation identifiers, and sanitized product errors. -Whiteboard derives session and presentation correlation IDs locally with a -namespaced HMAC keyed by the random installation ID. Raw session UUIDs and -Desktop presentation IDs never reach PostHog. PostHog may derive coarse +Review derives Review and presentation correlation IDs locally with a +namespaced HMAC keyed by the random installation ID. Raw Review UUIDs and +Desktop Review-session IDs never reach PostHog. PostHog may derive coarse location at ingestion, but the project discards the source IP. Pending events are stored in a bounded local queue under -`~/.dev/telemetry/events` by default. Whiteboard retries temporary +`~/.dev/telemetry/events` by default. Review retries temporary delivery failures and removes pending events after seven days. ## Error reports -Whiteboard can automatically report failures in its own app, canvas, server, or +Review can automatically report failures in its own app, canvas, server, or background process. These reports may contain an error class, a cleaned message, -a one-way fingerprint, and up to ten stack frames from Whiteboard's own program. +a one-way fingerprint, and up to ten stack frames from Review's own program. Update telemetry records when an update is staged, when that exact target next launches, or when checking, downloading, or installing fails. For a macOS -install failure, Whiteboard reads only log bytes appended after that update was +install failure, Review reads only log bytes appended after that update was staged, extracts one concise ShipIt error summary, and passes it through the same local cleaner. The raw ShipIt log is never stored in telemetry or sent. -Before sending, Whiteboard cleans paths, home and temporary directories, web +Before sending, Review cleans paths, home and temporary directories, web addresses, email addresses, and known secret formats. It drops repository, dependency, and extension stack frames. It also drops any message that quotes a -session document or does not pass a second local path-and-secret check. +Review document or does not pass a second local path-and-secret check. ## User-initiated bug reports The **Report bug** dialog sends a report only after you select **Send**. Under **Include diagnostic attachments**, three independent checkboxes control -whether Whiteboard attaches: +whether Review attaches: -- **Session**: the current session source and head software-map source +- **Review**: the current Review source and head software-map source - changed-file diffs used by the review codepeeks (only the diff lines) - **Agent session trace**: the complete local trace records for the session that - authored the session and available ancestor-session history through each fork + authored the Review and available ancestor-session history through each fork point -The session and changed-file diff attachments are selected by default. **The +The Review and changed-file diff attachments are selected by default. **The agent session trace is off by default and is included only when you explicitly select it for that report.** -Whiteboard captures a screenshot before the dialog opens, so the dialog itself is +Review captures a screenshot before the dialog opens, so the dialog itself is not in the image. The screenshot is attached by default with a visible preview. You can remove it with the × button, or paste or drag an image to replace it. Pasted and dropped PNG, JPEG, and WebP images are normalized to JPEG and limited @@ -99,7 +99,7 @@ up to ten of the most recently modified subagent trace tails. This data can contain prompts, model output, source code, file paths, URLs, and email addresses. -Whiteboard replaces recognizable Google API keys, JWTs, Slack tokens, GitHub +Review replaces recognizable Google API keys, JWTs, Slack tokens, GitHub tokens, and Microsoft Entra tokens before attaching the trace. Other credentials or secrets may remain. Passive telemetry and trace-sync settings do not enable this attachment. @@ -110,17 +110,17 @@ versions, operating-system category, a random app-session ID, and up to 20 sanitized JavaScript error class names seen during that canvas session. It does not include error messages in that list. -If a selected Whiteboard, map, or diff attachment is unavailable, Whiteboard omits it +If a selected Review, map, or diff attachment is unavailable, Review omits it and sends the other available data. The source session's own trace is sent -complete or the report fails. Ancestor history is sent as far as Whiteboard can +complete or the report fails. Ancestor history is sent as far as Review can read it, and the report names any ancestor it omits. If the compressed report -would exceed the upload limit, Whiteboard drops the trace and sends the rest. +would exceed the upload limit, Review drops the trace and sends the rest. -The report never attaches Whiteboard metadata. Whiteboard stores completed reports in a private /dev/fast Cloudflare R2 +The report never attaches Review metadata. Review stores completed reports in a private /dev/fast Cloudflare R2 bucket and deletes them after 90 days. An explicit bug report is separate from passive telemetry and is sent even when -anonymous telemetry is disabled. Whiteboard shows the attachment choices before +anonymous telemetry is disabled. Review shows the attachment choices before submission. ## Hosted trace store @@ -132,12 +132,12 @@ hosted consent. Trace capture is off by default. Hosted uploads start when this machine's selected store is the hosted store and the repository is allowed. Selection -happens explicitly with `whiteboard trace storage use hosted`, or implicitly when +happens explicitly with `review trace storage use hosted`, or implicitly when a machine that has no bucket configured allows a repository with -`whiteboard trace allow`. After that, complete agent session transcripts for the +`review trace allow`. After that, complete agent session transcripts for the allowed repositories are uploaded to the /dev/fast hosted store at the origin you logged in to. One conversation can contain work from several -repositories; Whiteboard publishes a session automatically only when its captured +repositories; Review publishes a session automatically only when its captured provenance places it in the allowed repository, and a commit trailer alone never authorizes an upload. Transcripts can contain prompts, model output, source code, file paths, URLs, and email addresses. Each publication also @@ -149,10 +149,10 @@ Read-only collaborators, former contributors, and the public cannot. Making a repository public does not widen access. Deleting a store is admin-only and is a logical deletion followed by operator cleanup; issued download links and retained object versions expire on a bounded schedule rather than instantly. -`whiteboard trace deny` removes this machine's consent for the repository and keeps -prior uploads. `whiteboard trace store delete` asks the store to delete the +`review trace deny` removes this machine's consent for the repository and keeps +prior uploads. `review trace store delete` asks the store to delete the repository's hosted copies (admins only) and leaves the consent as it is. -`whiteboard logout` forgets the local login only. +`review logout` forgets the local login only. Objects are encrypted with server-controlled keys, so /dev/fast can decrypt stored traces. The GitHub OAuth app requests the `repo` scope to check access. @@ -160,26 +160,26 @@ S3/R2 bucket storage sends nothing to /dev/fast. ## Turn telemetry off -In Whiteboard, open **Preferences → Settings** and disable **Share anonymous +In Review Desktop, open **Preferences → Settings** and disable **Share anonymous usage data**. That setting controls both the app and CLI on the same installation. For a process or headless environment, set a supported opt-out variable: ```sh -DO_NOT_TRACK=1 whiteboard info +DO_NOT_TRACK=1 review info ``` -`DNT=1` and the Whiteboard-specific variables listed in the +`DNT=1` and the Review-specific variables listed in the [telemetry reference](telemetry.md#identity-and-control) are also supported. ## Inspect events during development -Set the debug sink before launching Whiteboard: +Set the debug sink before launching Review Desktop: ```sh -DEV_FAST_WHITEBOARD_TELEMETRY_DEBUG=1 whiteboard app launch +DEV_FAST_REVIEW_TELEMETRY_DEBUG=1 review app launch ``` -Whiteboard prints each event to stderr instead of sending it to PostHog. See +Review prints each event to stderr instead of sending it to PostHog. See [Developer sink](telemetry.md#developer-sink) for its exact behavior. diff --git a/docs/quickstart.md b/docs/quickstart.md index 6be04d346..e07bf3aa1 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -13,22 +13,20 @@ This guide takes you from a fresh install to a completed first review. to review. - Claude Code, Codex, and other coding agents. -## 1. Install Whiteboard +## 1. Install Review [Download the latest disk image](https://install.dev.fast), open it, and launch -Whiteboard. The app updates itself after installation. +Review. The app updates itself after installation. -On first launch, Whiteboard opens the welcome screen. Its first step connects your -coding agents: +On first launch, Review opens the welcome screen. It detects supported coding +agents and offers to install: -1. Choose **Install whiteboard in PATH**. -2. Choose **Copy prompt** next to an agent you use. -3. Paste the prompt into a session of that agent. The agent registers Whiteboard's - MCP server and confirms that it can reach Whiteboard. +- the `review` command in `~/.local/bin`; +- the `dev-review` skill for authoring reviews and software maps; and +- the Review MCP connection for Codex and Claude Code. -Repeat for each agent. You can copy the prompts again later from -**Settings → Agents**. See [Coding agents](agents.md#connect-an-agent) for -what the prompt does. +Choose **Install** for the agents you use. Review keeps the app-managed command +and skills in sync after updates. ## 2. Take the tour @@ -40,38 +38,36 @@ sample repository to show: - sequence and database views; and - the full architecture map. -## 3. Create a session +## 3. Create a review Open the repository you want to review in your coding agent and tell it to review it! ```text -Create a Whiteboard of my current branch against up to date main, then open it -in Whiteboard. +Use the dev-review skill to review my current branch against up to date main, +then open it in Review. ``` The agent registers the repository, resolves the base and head pins, creates -the session through the Whiteboard API, writes and validates the walkthrough, and -opens it in Whiteboard. You can also review a specific GitHub pull request +the review through the Review API, writes and validates the walkthrough, and +opens it in Review Desktop. You can also review a specific GitHub pull request or ask for an architecture review of a repository. - +### Add Review guidance -### Add Whiteboard guidance +You can add optional guidance for generated Review documents: -You can add optional guidance for generated session documents: - -- User-level guidance: `$DEV_WHITEBOARD_HOME/DEV-REVIEW.md`. Whiteboard uses +- User-level guidance: `$DEV_REVIEW_HOME/DEV-REVIEW.md`. Review uses `~/.dev/DEV-REVIEW.md` by default. - Repository guidance: `DEV-REVIEW.md` at the source repository root. Repository guidance takes precedence over user-level guidance. -## 4. Read the session +## 4. Read the review Use the three main surfaces together: -- **Session** explains the change and links every code claim to its evidence. +- **Review** explains the change and links every code claim to its evidence. - **Map** lets you move from systems to containers, components, and code (experimental). - **Files** shows the underlying changed-file diff. @@ -81,17 +77,17 @@ Use the three main surfaces together: The app normally manages the CLI. These commands are useful for checking it: ```sh -whiteboard version -whiteboard app launch -whiteboard info +review version +review app launch +review info ``` -If the command is missing or behaves like an older browser-based Whiteboard, see +If the command is missing or behaves like an older browser-based Review, see [Troubleshooting](troubleshooting.md). ## Next steps -- Learn [how Whiteboard works](how-review-works.md). +- Learn [how Review works](how-review-works.md). - Read about [coding-agent setup](agents.md). - Use the [CLI reference](cli-reference.md) for explicit or automated flows. -- Read the [privacy boundaries](privacy.md). +- Review the [privacy boundaries](privacy.md). diff --git a/docs/superpowers/plans/2026-09-09-trace-storage-review-fixes.md b/docs/superpowers/plans/2026-09-09-trace-storage-review-fixes.md index 12a53b044..aed1c5023 100644 --- a/docs/superpowers/plans/2026-09-09-trace-storage-review-fixes.md +++ b/docs/superpowers/plans/2026-09-09-trace-storage-review-fixes.md @@ -20,7 +20,7 @@ - **Shell.** `ls` is aliased to `exa`; use `command ls`. `grep` is `ugrep`; quote globs. BSD `sed` has no `\b`; use `perl -pi -e` for word-boundary edits. - **Dev tests.** `pnpm --filter @dev-fast/review-web test` (unit), `pnpm --filter @dev-fast/review-web test:worker` (D1 worker tests, applies `drizzle/migrations`), `pnpm --filter @dev-fast/review-web typecheck`. The Dev worktree has an uncommitted, deliberate override in `pnpm-workspace.yaml` and `pnpm-lock.yaml` pointing `@dev.fast/trace-shared` at a local tarball. Never commit those two files. Never remove the override. - **Vocabulary.** User-facing word is `s3`, never `direct`. -- **Protocol mirror.** After any change to `packages/whiteboard-protocol/src/contracts.ts`, run `pnpm --filter @dev.fast/whiteboard-desktop protocol:sync` and commit the regenerated `apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardProtocol.ts`. +- **Protocol mirror.** After any change to `packages/review-protocol/src/contracts.ts`, run `pnpm --filter @dev.fast/review-desktop protocol:sync` and commit the regenerated `apps/review-desktop/code-oss/src/vs/review/common/reviewProtocol.ts`. --- @@ -232,11 +232,11 @@ Findings: a `forbidden`/`store_deleted` answer at target resolution became `null - Modify: `packages/progressive-review/src/trace-storage/hosted.ts` (the `catch` at the end of `resolve`, read branch) - Modify: `packages/progressive-review/src/review-agent-traces.ts` (`reachable`, `findNormalizedTraceFile`) - Modify: `packages/progressive-review/src/server/review-api.ts` (`traceStorageOverride`, `resolveTraceStorageFor`, `agentTraces`, `agentTraceDetail`) -- Modify: `packages/whiteboard-protocol/src/contracts.ts` (`WhiteboardAgentTraceListResponseSchema`) -- Modify: `packages/progressive-review/app/src/WhiteboardTraceView.tsx` (list state, unconfigured block) +- Modify: `packages/review-protocol/src/contracts.ts` (`ReviewAgentTraceListResponseSchema`) +- Modify: `packages/progressive-review/app/src/ReviewTraceView.tsx` (list state, unconfigured block) - Modify: `packages/progressive-review/src/trace-storage/hosted.test.ts` - Create: `packages/progressive-review/src/server/review-api-traces.test.ts` -- Regenerate: `apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardProtocol.ts` +- Regenerate: `apps/review-desktop/code-oss/src/vs/review/common/reviewProtocol.ts` **Interfaces:** @@ -262,7 +262,7 @@ it("reports a refusal at target resolution instead of serving another copy", asy traces: { "main.jsonl.gz": `${sessionRecord(sessionId, "cached")}\n` }, }); expect( - await loadWhiteboardAgentTrace({ sessionId, cwd: repoDir, storage: first }), + await loadReviewAgentTrace({ sessionId, cwd: repoDir, storage: first }), ).not.toBeNull(); // Access is revoked: findStore answers forbidden. @@ -296,7 +296,7 @@ it("reports a refusal at target resolution instead of serving another copy", asy ).rejects.toBeInstanceOf(TraceStorageDeniedError); // The saved copy is not served through a null storage either. await expect( - loadWhiteboardAgentTrace({ sessionId, cwd: repoDir }), + loadReviewAgentTrace({ sessionId, cwd: repoDir }), ).rejects.toBeInstanceOf(TraceStorageDeniedError); }); ``` @@ -360,7 +360,7 @@ Expected: PASS for all tests, including the new one. - [ ] **Step 6: Add `storageError` to the protocol and regenerate the mirror** -In `packages/whiteboard-protocol/src/contracts.ts`, in `WhiteboardAgentTraceListResponseSchema`'s `ok: true` object, after `sources: ...optional(),` add: +In `packages/review-protocol/src/contracts.ts`, in `ReviewAgentTraceListResponseSchema`'s `ok: true` object, after `sources: ...optional(),` add: ```ts // Why the selected store answered nothing: a refusal, a missing login @@ -368,7 +368,7 @@ In `packages/whiteboard-protocol/src/contracts.ts`, in `WhiteboardAgentTraceList storageError: requiredString.optional(), ``` -Run: `pnpm --filter @dev.fast/whiteboard-protocol build && pnpm --filter @dev.fast/whiteboard-desktop protocol:sync` +Run: `pnpm --filter @dev.fast/review-protocol build && pnpm --filter @dev.fast/review-desktop protocol:sync` - [ ] **Step 7: Write the failing API route test** @@ -384,7 +384,7 @@ import { promisify } from "node:util"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { clearTraceEnvCache } from "../review-agent-traces"; -import { createWhiteboardDir } from "../whiteboard-home"; +import { createReviewDir } from "../review-home"; import { traceConfigPath } from "../trace-storage/config"; import { createReviewApi } from "./review-api"; @@ -404,8 +404,8 @@ describe("agent trace routes", () => { beforeEach(async () => { home = await mkdtemp(path.join(os.tmpdir(), "review-api-traces-home-")); root = await mkdtemp(path.join(os.tmpdir(), "review-api-traces-repo-")); - vi.stubEnv("DEV_WHITEBOARD_HOME", home); - vi.stubEnv("WHITEBOARD_TEST_TRACE_SEARCH_DIR", path.join(home, "trace-search")); + vi.stubEnv("DEV_REVIEW_HOME", home); + vi.stubEnv("REVIEW_TEST_TRACE_SEARCH_DIR", path.join(home, "trace-search")); await git(root, ["init", "-b", "main"]); await git(root, ["config", "user.email", "review@example.test"]); await git(root, ["config", "user.name", "Review Test"]); @@ -433,19 +433,19 @@ describe("agent trace routes", () => { async function api() { const commit = await git(root, ["rev-parse", "HEAD"]); - const created = await createWhiteboardDir({ + const created = await createReviewDir({ worktreePath: root, baseRef: "main", baseCommit: commit, sourceCommit: commit, }); - const whiteboardPath = path.join(created.dir, "review.mdx"); - await writeFile(whiteboardPath, "# Review\n", "utf8"); + const reviewPath = path.join(created.dir, "review.mdx"); + await writeFile(reviewPath, "# Review\n", "utf8"); return createReviewApi({ - whiteboardPath, - stateReviewPath: whiteboardPath, - whiteboardRootPath: created.dir, - whiteboardDocumentsDir: created.dir, + reviewPath, + stateReviewPath: reviewPath, + reviewRootPath: created.dir, + reviewDocumentsDir: created.dir, rootPath: root, toolingRoot: root, reviewToken: "test", @@ -453,7 +453,7 @@ describe("agent trace routes", () => { rootPath: root, baseRef: "main", appUrl: "http://localhost:4000", - whiteboardPath, + reviewPath, startedAt: 1, agent: { harness: "claude-code", sessionId: "author" }, }, @@ -546,7 +546,7 @@ describe("agent trace routes", () => { }); ``` -If `createReviewApi` needs a `reviewToken` or `toolingRoot` of a different type, copy the exact option set from `packages/progressive-review/src/server/review-agent-flow.test.ts` lines 122-141 and keep `whiteboardRootPath: created.dir`. +If `createReviewApi` needs a `reviewToken` or `toolingRoot` of a different type, copy the exact option set from `packages/progressive-review/src/server/review-agent-flow.test.ts` lines 122-141 and keep `reviewRootPath: created.dir`. - [ ] **Step 8: Run it to verify it fails** @@ -569,7 +569,7 @@ type TraceStorageOverride = /** The `?storage=` read override; invalid names never fall back silently. */ function traceStorageOverride( - context: Context, + context: Context, ): TraceStorageOverride { const value = new URL(context.req.url).searchParams.get("storage"); if (value === null) return { kind: "none" }; @@ -590,7 +590,7 @@ type TraceStorageResolution = * config is returned as a message instead of thrown. */ async function resolveTraceStorageFor( - context: Context, + context: Context, cwd: string, ): Promise { const override = traceStorageOverride(context); @@ -635,8 +635,8 @@ if (override.kind === "invalid") { error: "storage must be s3 or hosted.", }); } -const review = readWhiteboardStoreRecord(whiteboardRootPath); -const repoRootPath = resolveWhiteboardRepoRootFromStore(whiteboardRootPath, review); +const review = readReviewStoreRecord(reviewRootPath); +const repoRootPath = resolveReviewRepoRootFromStore(reviewRootPath, review); const headCommit = review.sourceCommit ?? review.baseCommit; const selection = selectTraceStorage(); const sources: TraceStorageKind[] = []; @@ -657,9 +657,9 @@ if (resolved.error !== null) { sessions: [], }); } -let sessions: Awaited>; +let sessions: Awaited>; try { - sessions = await listWhiteboardTraceSessions({ + sessions = await listReviewTraceSessions({ rootPath: repoRootPath, baseCommit: review.baseCommit, headCommit, @@ -695,14 +695,14 @@ if (override.kind === "invalid") { error: "storage must be s3 or hosted.", }); } -const repoRootPath = resolveWhiteboardRepoRootFromStore(whiteboardRootPath); +const repoRootPath = resolveReviewRepoRootFromStore(reviewRootPath); const resolved = await resolveTraceStorageFor(context, repoRootPath); if (resolved.error !== null) { return reviewApiJsonResponse(404, { ok: false, error: resolved.error }); } -let loaded: Awaited>; +let loaded: Awaited>; try { - loaded = await loadWhiteboardAgentTrace({ + loaded = await loadReviewAgentTrace({ sessionId, trace, cwd: repoRootPath, @@ -727,7 +727,7 @@ Expected: PASS. - [ ] **Step 11: Show `storageError` in the Desktop trace view** -In `packages/progressive-review/app/src/WhiteboardTraceView.tsx`: +In `packages/progressive-review/app/src/ReviewTraceView.tsx`: In `TraceListState`'s `loaded` branch add `storageError: string | null;`. In the fetch effect's `setList({ status: "loaded", ... })` add `storageError: result.storageError ?? null,`. @@ -735,14 +735,14 @@ Replace the unconfigured block: ```tsx {list.status === "loaded" && (list.storageError || !list.configured) && ( -
- Agent trace +
+ Agent trace {list.storageError ? (

{list.storageError}

) : ( <>

Agent traces are not configured.

-

+

Open Agent Setup in Review Desktop to enable trace capture.

@@ -766,12 +766,12 @@ useEffect(() => { }, [list]); ``` -Add a test to `packages/progressive-review/app/src/WhiteboardTraceView.test.tsx` after the source-control test: +Add a test to `packages/progressive-review/app/src/ReviewTraceView.test.tsx` after the source-control test: ```tsx it("shows the storage error instead of the unconfigured hint", async () => { const requestMock = vi - .fn() + .fn() .mockImplementation((url) => { if (url.includes("/agent-traces")) { return Promise.resolve( @@ -788,12 +788,12 @@ it("shows the storage error instead of the unconfigured hint", async () => { } return Promise.reject(new Error(`Unexpected URL: ${url}`)); }); - const session = testWhiteboardSession({}, { request: requestMock }); + const session = testReviewSession({}, { request: requestMock }); await act(async () => { root?.render( - - - , + + + , ); }); await act(async () => { @@ -806,7 +806,7 @@ it("shows the storage error instead of the unconfigured hint", async () => { }); ``` -Run: `pnpm --filter @dev.fast/review exec vitest run app/src/WhiteboardTraceView.test.tsx` +Run: `pnpm --filter @dev.fast/review exec vitest run app/src/ReviewTraceView.test.tsx` Expected: PASS. - [ ] **Step 12: Full checks and commit** @@ -814,7 +814,7 @@ Expected: PASS. ```bash pnpm --filter @dev.fast/review typecheck && pnpm -w lint && pnpm -w format:check GITHUB_REPOSITORY=devdotfast/review pnpm --filter @dev.fast/review test -git add -A packages/progressive-review packages/whiteboard-protocol apps/whiteboard-desktop/code-oss/src/vs/whiteboard/common/whiteboardProtocol.ts +git add -A packages/progressive-review packages/review-protocol apps/review-desktop/code-oss/src/vs/review/common/reviewProtocol.ts git commit -m "Report hosted refusals and read-override failures instead of serving a saved copy" ``` @@ -971,7 +971,7 @@ describe("runReviewTraceGitHook", () => { repo = await mkdtemp(path.join(os.tmpdir(), "trace-git-hook-")); devHome = path.join(repo, ".dev"); stderrText = ""; - vi.stubEnv("DEV_WHITEBOARD_HOME", devHome); + vi.stubEnv("DEV_REVIEW_HOME", devHome); vi.stubEnv("HOME", repo); await git(repo, ["init", "-b", "main"]); await git(repo, ["config", "user.name", "Test"]); @@ -1254,7 +1254,7 @@ git commit -m "Match hosted consent by repository id only and honor homeDir in t - [ ] **Step 1: Move the dependency** -In `packages/progressive-review/package.json` delete the line `"@dev.fast/trace-shared": "workspace:*",` from `dependencies` and add it to `devDependencies` next to `"@dev.fast/whiteboard-protocol": "workspace:*",`. Run `pnpm install` (updates `pnpm-lock.yaml`). +In `packages/progressive-review/package.json` delete the line `"@dev.fast/trace-shared": "workspace:*",` from `dependencies` and add it to `devDependencies` next to `"@dev.fast/review-protocol": "workspace:*",`. Run `pnpm install` (updates `pnpm-lock.yaml`). Verify the bundle still inlines it: `pnpm --filter @dev.fast/review build && grep -c "TRACE_STORE_API_PREFIX\|/api/trace/v1" packages/progressive-review/dist/cli.js` must print a number greater than 0. @@ -1315,7 +1315,7 @@ Append inside `describe("TraceCaptureSection")`: ```tsx it("hides the bucket fields and the S3 copy on a hosted machine", async () => { - const hostedStatus: WhiteboardCliInstallStatus = { + const hostedStatus: ReviewCliInstallStatus = { ...traceStatus, trace: { ...traceStatus.trace, @@ -1324,13 +1324,13 @@ it("hides the bucket fields and the S3 copy on a hosted machine", async () => { storageMode: "hosted", }, }; - const install: WhiteboardCanvasInstallContent = { + const install: ReviewCanvasInstallContent = { status: hostedStatus, - apply: vi.fn(), - remove: vi.fn(), - decline: vi.fn(), - skip: vi.fn(), - enablePrompts: vi.fn(), + apply: vi.fn(), + remove: vi.fn(), + decline: vi.fn(), + skip: vi.fn(), + enablePrompts: vi.fn(), }; await act(async () => root.render()); expect( @@ -1361,7 +1361,7 @@ Add before the component: ```tsx /** What capture records and where, for the selected store. */ -function traceDestinationCopy(trace: WhiteboardCliInstallStatus["trace"]): string { +function traceDestinationCopy(trace: ReviewCliInstallStatus["trace"]): string { if (trace.storageMode === "hosted") { return "Records agent sessions from allowed repositories to the hosted /dev/fast trace store so reviews can quote them. Session hooks activate each Git or Jujutsu repository when an agent session starts."; } @@ -1374,12 +1374,12 @@ Inside the component, after `useEffect(() => setStatus(install.status), ...)` ad Replace the copy span: ```tsx - + {traceDestinationCopy(status.trace)} ``` -Wrap the `
...
` in `{hosted ? null : ( ... )}`. +Wrap the `
...
` in `{hosted ? null : ( ... )}`. Wrap the Enable/Repair ` + ))} +
+
+
+
+ {!scratchpad && ( + + )} + applyReviewView(view)} + /> +
+ {!scratchpad && } + + + + + {!scratchpad && + !review.historicalRevision && + !review.submissionOutcome && ( +
+ )} + {!scratchpad && + !review.historicalRevision && + !review.submissionOutcome ? ( + + ) : null} +
+ + {review.historicalRevision ? ( +
+ You are viewing an older version of this review. + +
+ ) : null} + {activeView === "review" && documentState.state === "ready" && ( + + )} +
+ + {softwareMapEnabled && activeView === "map" && ( +
+
+ {softwareMapState.state === "ready" || + softwareMapState.state === "absent" ? ( + <> + + + + + ) : ( + + )} +
+
+ )} + {activeView === "commits" && ( + { + setDiffScope(commit); + captureUiEvent(session, "commit_diff_opened", { via }); + applyReviewView("diff"); + }} + /> + )} +
+ +
+ {activeView === "diff" && diffScope !== null && ( +
+ { + setDiffScope(null); + applyReviewView("commits"); + }} + /> + +
+ )} + {activeView === "trace" && ( + + )} +
+ + + {rightPanelOpen && ( +
+ )} +
+ +
+
+ ); +} + +function ReviewDocumentLoadState({ + state, +}: { + state: Exclude; +}): ReactElement | null { + switch (state.state) { + case "loading": + return null; + case "unavailable": + return ( + + ) : null + } + /> + ); + default: { + const unhandled: never = state; + throw new Error( + `Unhandled review document state ${JSON.stringify(unhandled)}.`, + ); + } + } +} + +function ReviewSoftwareMapLoadState({ + state, +}: { + state: Exclude< + ReviewSoftwareMapAppState, + { state: "ready" } | { state: "absent" } + >; +}): ReactElement | null { + switch (state.state) { + case "loading": + return null; + case "unavailable": + return ( + + ) : null + } + /> + ); + default: { + // A new software-map state has to choose here: the map chrome renders + // for ready and absent (an absent map still shows document-authored + // models), everything else is a load state. + const unhandled: never = state; + throw new Error( + `Unhandled software map state ${JSON.stringify(unhandled)}.`, + ); + } + } +} + +function OpenCurrentReview({ + reviewUuid, +}: { + reviewUuid: string; +}): ReactElement { + const session = useReviewSession(); + + return ( + + ); +} + +function CommitDiffScopeBar({ + commit, + onBack, +}: { + commit: ReviewCommitSummary; + onBack: () => void; +}) { + return ( +
+
+ Viewing + {commit.commit.slice(0, 8)} +
+ +
+ ); +} + +/** + * Reports where the baton sits after the reader acts. It renders nothing while + * the review is simply waiting: the corner action already says what to do, and + * a standing "awaiting your review" chip was noise on every review. + */ +function ReviewBatonChip({ + outcome, +}: { + outcome: ReviewSubmissionOutcome | null; +}): ReactElement | null { + const tooltip = useTooltip( + outcome === "changes-requested" + ? "Changes requested" + : outcome === "approved" + ? "Approved" + : "Dismissed", + ); + + if (!outcome) return null; + + const label = + outcome === "changes-requested" + ? "changes requested" + : outcome === "approved" + ? "approved" + : "dismissed"; + + return ( + + {outcome === "approved" && ( + + )} + {outcome === "dismissed" && ( + + )} + {label} + + ); +} + +/** + * Map settings, floating over the map canvas. They used to sit behind a topbar + * gear that held nothing else, which put map-only controls in front of readers + * who never open the map. + */ +function MapSettingsControl(): ReactElement { + const { + showModifiedOnly, + setShowModifiedOnly, + showRemovedNodes, + setShowRemovedNodes, + nodeTint, + setNodeTint, + } = useReviewDebugSettings(); + + const controlRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); + + useEffect(() => { + if (!isOpen) return; + + const closeOnOutsidePointerDown = (event: PointerEvent) => { + const target = event.target; + + if (target instanceof Node && controlRef.current?.contains(target)) + return; + setIsOpen(false); + }; + + const closeOnEscape = (event: KeyboardEvent) => { + if (event.key === "Escape") setIsOpen(false); + }; + + document.addEventListener("pointerdown", closeOnOutsidePointerDown, true); + document.addEventListener("keydown", closeOnEscape); + + return () => { + document.removeEventListener( + "pointerdown", + closeOnOutsidePointerDown, + true, + ); + document.removeEventListener("keydown", closeOnEscape); + }; + }, [isOpen]); + + return ( +
+ {isOpen && ( +
+ + +
+ Map node tint + {(["none", "slate", "mineral"] as const).map((option) => ( + + ))} +
+
+ )} + +
+ ); +} + +function DebugSwitch({ + label, + checked, + onChange, +}: { + label: string; + checked: boolean; + onChange: (checked: boolean) => void; +}): ReactElement { + return ( +