From 57870bae98740e8a51ecf76a7f7c75a4821888d8 Mon Sep 17 00:00:00 2001
From: mohammadrezwankhan
<3.326051e+07+mohammadrezwankhan@users.noreply.github.com>
Date: Tue, 25 Aug 2026 06:11:59 +0000
Subject: [PATCH 1/3] fix(desktop): preserve preview scroll bounds
---
.changeset/fix-preview-scaling.md | 5 +++++
.../src/components/PreviewPane.test.ts | 10 ++++++++++
.../renderer/src/components/PreviewPane.tsx | 20 ++++++++++++-------
3 files changed, 28 insertions(+), 7 deletions(-)
create mode 100644 .changeset/fix-preview-scaling.md
diff --git a/.changeset/fix-preview-scaling.md b/.changeset/fix-preview-scaling.md
new file mode 100644
index 00000000..c22c744b
--- /dev/null
+++ b/.changeset/fix-preview-scaling.md
@@ -0,0 +1,5 @@
+---
+'@open-codesign/desktop': patch
+---
+
+Preserve preview artboard scroll bounds at scaled zoom levels to prevent desktop and tablet previews from being clipped.
diff --git a/apps/desktop/src/renderer/src/components/PreviewPane.test.ts b/apps/desktop/src/renderer/src/components/PreviewPane.test.ts
index b433f7b1..d2ec2ad3 100644
--- a/apps/desktop/src/renderer/src/components/PreviewPane.test.ts
+++ b/apps/desktop/src/renderer/src/components/PreviewPane.test.ts
@@ -13,6 +13,7 @@ import {
previewArtboardStyle,
previewPaneLayoutClasses,
previewViewportDimensions,
+ scaledPreviewFrameStyle,
scaleRectForZoom,
stablePreviewSourceKey,
} from './PreviewPane';
@@ -116,6 +117,15 @@ describe('preview artboard frame', () => {
}),
).toBe(100);
});
+
+ it('preserves scaled desktop dimensions as minimum scroll bounds', () => {
+ expect(scaledPreviewFrameStyle('desktop', 150)).toEqual({
+ width: '2160px',
+ height: '1350px',
+ minWidth: '2160px',
+ minHeight: '1350px',
+ });
+ });
});
describe('preview pane welcome state', () => {
diff --git a/apps/desktop/src/renderer/src/components/PreviewPane.tsx b/apps/desktop/src/renderer/src/components/PreviewPane.tsx
index a7125b39..0fe12b1e 100644
--- a/apps/desktop/src/renderer/src/components/PreviewPane.tsx
+++ b/apps/desktop/src/renderer/src/components/PreviewPane.tsx
@@ -167,6 +167,18 @@ export function previewArtboardFrameClass(): string {
return ARTBOARD_FRAME_CLASS;
}
+export function scaledPreviewFrameStyle(
+ viewport: PreviewSlotProps['viewport'],
+ zoom: number,
+): CSSProperties {
+ const frame = previewViewportDimensions(viewport);
+ const scale = zoom / 100;
+ const width = `${Math.round(frame.width * scale)}px`;
+ const height = `${Math.round(frame.height * scale)}px`;
+
+ return { width, height, minWidth: width, minHeight: height };
+}
+
function ScaledPreviewFrame({
viewport,
zoom,
@@ -179,13 +191,7 @@ function ScaledPreviewFrame({
const frame = previewViewportDimensions(viewport);
const scale = zoom / 100;
return (
-
+
Date: Wed, 26 Aug 2026 17:37:27 +0200
Subject: [PATCH 2/3] ci: fall back to Codex when DeepSeek review is empty
---
.github/workflows/codex-pr-review.yml | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/codex-pr-review.yml b/.github/workflows/codex-pr-review.yml
index 5d8b7c28..784a6967 100644
--- a/.github/workflows/codex-pr-review.yml
+++ b/.github/workflows/codex-pr-review.yml
@@ -121,6 +121,11 @@ jobs:
[ -n "$effort" ] || effort="$DEFAULT_EFFORT"
[ -n "$effort" ] || effort='high'
+ fallback_model="$DEFAULT_MODEL"
+ [ -n "$fallback_model" ] || fallback_model='gpt-5.4'
+ fallback_effort="$DEFAULT_EFFORT"
+ [ -n "$fallback_effort" ] || fallback_effort='high'
+
is_deepseek='false'
case "$base_url" in
*api.deepseek.com*)
@@ -134,6 +139,10 @@ jobs:
echo "model=$model"
echo "effort=$effort"
echo "is_deepseek=$is_deepseek"
+ echo "fallback_api_key=$DEFAULT_API_KEY"
+ echo "fallback_base_url=$DEFAULT_BASE_URL"
+ echo "fallback_model=$fallback_model"
+ echo "fallback_effort=$fallback_effort"
} >> "$GITHUB_OUTPUT"
- name: Set up Node.js for DeepSeek review
@@ -143,7 +152,9 @@ jobs:
node-version: "20"
- name: Run DeepSeek for PR Review
+ id: run_deepseek
if: steps.check_bot.outputs.has_review_for_current_head != 'true' && steps.review_config.outputs.is_deepseek == 'true'
+ continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
GITHUB_TOKEN: ${{ github.token }}
@@ -159,7 +170,7 @@ jobs:
- name: Run Codex for PR Review
id: run_codex
- if: steps.check_bot.outputs.has_review_for_current_head != 'true' && steps.review_config.outputs.is_deepseek != 'true'
+ if: steps.check_bot.outputs.has_review_for_current_head != 'true' && (steps.review_config.outputs.is_deepseek != 'true' || steps.run_deepseek.outcome == 'failure')
uses: openai/codex-action@e0fdf01220eb9a88167c4898839d273e3f2609d1 # v1
env:
GH_TOKEN: ${{ github.token }}
@@ -169,10 +180,10 @@ jobs:
LATEST_BOT_REVIEW_COMMIT: ${{ steps.check_bot.outputs.latest_bot_review_commit }}
IS_FOLLOW_UP_REVIEW: ${{ steps.check_bot.outputs.is_follow_up_review }}
with:
- openai-api-key: ${{ steps.review_config.outputs.api_key }}
- responses-api-endpoint: ${{ steps.review_config.outputs.base_url }}
- model: ${{ steps.review_config.outputs.model }}
- effort: ${{ steps.review_config.outputs.effort }}
+ openai-api-key: ${{ steps.review_config.outputs.fallback_api_key }}
+ responses-api-endpoint: ${{ steps.review_config.outputs.fallback_base_url }}
+ model: ${{ steps.review_config.outputs.fallback_model }}
+ effort: ${{ steps.review_config.outputs.fallback_effort }}
sandbox: danger-full-access
safety-strategy: drop-sudo
prompt-file: .github/prompts/codex-pr-review.md
From 339807ebc93f8603dbc5cc190f1b72144888c6ee Mon Sep 17 00:00:00 2001
From: Mohammad Rezwan Khan
<33260510+mohammadrezwankhan@users.noreply.github.com>
Date: Wed, 26 Aug 2026 17:45:32 +0200
Subject: [PATCH 3/3] ci: run Codex fallback after DeepSeek failure
---
.github/workflows/codex-pr-review.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/codex-pr-review.yml b/.github/workflows/codex-pr-review.yml
index 784a6967..918a261f 100644
--- a/.github/workflows/codex-pr-review.yml
+++ b/.github/workflows/codex-pr-review.yml
@@ -170,7 +170,7 @@ jobs:
- name: Run Codex for PR Review
id: run_codex
- if: steps.check_bot.outputs.has_review_for_current_head != 'true' && (steps.review_config.outputs.is_deepseek != 'true' || steps.run_deepseek.outcome == 'failure')
+ if: always() && steps.check_bot.outputs.has_review_for_current_head != 'true' && (steps.review_config.outputs.is_deepseek != 'true' || steps.run_deepseek.outcome == 'failure')
uses: openai/codex-action@e0fdf01220eb9a88167c4898839d273e3f2609d1 # v1
env:
GH_TOKEN: ${{ github.token }}