Conversation
webview の zoom API を直接操作し、ツールバーに [-] [%] [+] ボタンを配置。 50%〜200% の範囲でズーム可能、パーセント表示クリックで 100% にリセット。
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 26 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughA new browser tab zoom feature is introduced with UI controls in the BrowserPane component and corresponding tRPC backend procedures to manage zoom levels across a 50%–200% range with 100% reset capability. Documentation is updated accordingly. Changes
Sequence DiagramsequenceDiagram
actor User
participant BrowserPane as BrowserPane<br/>Component
participant tRPC as tRPC<br/>Client
participant Server as Browser<br/>Router
participant WebContents as Electron<br/>WebContents
User->>BrowserPane: Click zoom button
BrowserPane->>BrowserPane: Calculate new zoom level<br/>(clamp to min/max)
BrowserPane->>tRPC: applyZoom(level)
tRPC->>Server: electronTrpc.browser.setZoomLevel
Server->>WebContents: setZoomLevel(level)
WebContents-->>Server: Zoom applied
Server-->>tRPC: { success: true, level }
tRPC-->>BrowserPane: Response received
BrowserPane->>BrowserPane: Update zoomLevel state
BrowserPane-->>User: Display updated zoom %
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/BrowserPane.tsx (1)
105-111: Addaria-labelto icon-only zoom buttons.The minus/plus controls are icon-only; adding labels improves screen-reader usability without changing behavior.
♿ Proposed accessibility tweak
<button type="button" onClick={zoomOut} + aria-label="Zoom out" className="rounded p-0.5 text-muted-foreground/60 transition-colors hover:text-muted-foreground" > @@ <button type="button" onClick={zoomIn} + aria-label="Zoom in" className="rounded p-0.5 text-muted-foreground/60 transition-colors hover:text-muted-foreground" >Also applies to: 133-139
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/BrowserPane.tsx` around lines 105 - 111, Add accessible labels to the icon-only zoom buttons in BrowserPane by adding aria-label attributes to the button elements that call zoomOut and zoomIn (the button with onClick={zoomOut} and the corresponding button with onClick={zoomIn}); set descriptive values like "Zoom out" and "Zoom in" respectively so screen readers convey the control purpose without changing visual behavior or handlers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts`:
- Around line 468-491: The zoom state is currently hardcoded to 0 which causes
the UI to show 100% after remount even if a persisted webview has a different
zoom; change initialization to read the current zoom from the persisted webview
in webviewRegistry using paneId (or run a sync useEffect on mount) and call
setZoomLevelState with webview.getZoomLevel() when a webview exists (e.g.,
replace useState(0) with an initializer that returns
webviewRegistry.get(paneId)?.getZoomLevel() ?? 0 or add a one-time effect to
setZoomLevelState(webview.getZoomLevel())); keep zoomIn/zoomOut/reset logic
as-is but ensure initial sync uses the same webview.getZoomLevel() value.
---
Nitpick comments:
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/BrowserPane.tsx`:
- Around line 105-111: Add accessible labels to the icon-only zoom buttons in
BrowserPane by adding aria-label attributes to the button elements that call
zoomOut and zoomIn (the button with onClick={zoomOut} and the corresponding
button with onClick={zoomIn}); set descriptive values like "Zoom out" and "Zoom
in" respectively so screen readers convey the control purpose without changing
visual behavior or handlers.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d2774ad1-77a2-49c9-a726-3738132d7450
📒 Files selected for processing (3)
README.mdapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/BrowserPane.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts
| const [zoomLevel, setZoomLevelState] = useState(0); | ||
|
|
||
| const zoomIn = useCallback(() => { | ||
| const webview = webviewRegistry.get(paneId); | ||
| if (!webview) return; | ||
| const next = Math.min(ZOOM_MAX, webview.getZoomLevel() + ZOOM_STEP); | ||
| webview.setZoomLevel(next); | ||
| setZoomLevelState(next); | ||
| }, [paneId]); | ||
|
|
||
| const zoomOut = useCallback(() => { | ||
| const webview = webviewRegistry.get(paneId); | ||
| if (!webview) return; | ||
| const next = Math.max(ZOOM_MIN, webview.getZoomLevel() - ZOOM_STEP); | ||
| webview.setZoomLevel(next); | ||
| setZoomLevelState(next); | ||
| }, [paneId]); | ||
|
|
||
| const resetZoom = useCallback(() => { | ||
| const webview = webviewRegistry.get(paneId); | ||
| if (!webview) return; | ||
| webview.setZoomLevel(0); | ||
| setZoomLevelState(0); | ||
| }, [paneId]); |
There was a problem hiding this comment.
Initialize zoom state from the persistent webview instead of hardcoding 0.
Line 468 resets UI state to 100% on remount even when the persisted webview is still zoomed, so the displayed percentage can drift from actual zoom after pane/tab lifecycle changes.
💡 Proposed fix
- const [zoomLevel, setZoomLevelState] = useState(0);
+ const [zoomLevel, setZoomLevelState] = useState(() => {
+ const webview = webviewRegistry.get(paneId);
+ return webview ? webview.getZoomLevel() : 0;
+ });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts`
around lines 468 - 491, The zoom state is currently hardcoded to 0 which causes
the UI to show 100% after remount even if a persisted webview has a different
zoom; change initialization to read the current zoom from the persisted webview
in webviewRegistry using paneId (or run a sync useEffect on mount) and call
setZoomLevelState with webview.getZoomLevel() when a webview exists (e.g.,
replace useState(0) with an initializer that returns
webviewRegistry.get(paneId)?.getZoomLevel() ?? 0 or add a one-time effect to
setZoomLevelState(webview.getZoomLevel())); keep zoomIn/zoomOut/reset logic
as-is but ensure initial sync uses the same webview.getZoomLevel() value.
webview タグの setZoomLevel() がホストページに効いてしまう問題を修正。 tRPC 経由でメインプロセスの webContents.setZoomLevel() を呼ぶ方式に変更。
Electron の webContents.setZoomLevel() がホストページにも影響する問題を修正。 executeJavaScript で guest ページの document.documentElement.style.zoom を 直接設定する方式に変更。tRPC のズームプロシージャは不要となったため削除。
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/desktop/src/lib/trpc/routers/browser/browser.ts (1)
153-160: Consider adding bounds validation forlevelas a defensive measure.The PR specifies a zoom level range of -3 to 3. While the UI enforces these limits, adding server-side validation would prevent unexpected behavior if called with out-of-range values.
🛡️ Optional: Add bounds validation
setZoomLevel: publicProcedure - .input(z.object({ paneId: z.string(), level: z.number() })) + .input(z.object({ paneId: z.string(), level: z.number().min(-3).max(3) })) .mutation(({ input }) => {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/lib/trpc/routers/browser/browser.ts` around lines 153 - 160, Validate the zoom `level` input in the setZoomLevel publicProcedure (the z.object({ paneId, level }) handler) to enforce the -3..3 bounds before calling browserManager.getWebContents and wc.setZoomLevel; if level is out of range, either return { success: false, level: currentOr0 } or clamp to the nearest bound and proceed—update the mutation to check input.level against -3 and 3, handle the invalid case consistently (return failure or clamp) and ensure the response reflects the applied level.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/desktop/src/lib/trpc/routers/browser/browser.ts`:
- Around line 153-160: Validate the zoom `level` input in the setZoomLevel
publicProcedure (the z.object({ paneId, level }) handler) to enforce the -3..3
bounds before calling browserManager.getWebContents and wc.setZoomLevel; if
level is out of range, either return { success: false, level: currentOr0 } or
clamp to the nearest bound and proceed—update the mutation to check input.level
against -3 and 3, handle the invalid case consistently (return failure or clamp)
and ensure the response reflects the applied level.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d458f895-b5c1-46a2-a4bc-dd7ffa1fd072
📒 Files selected for processing (2)
apps/desktop/src/lib/trpc/routers/browser/browser.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/BrowserPane.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/BrowserPane.tsx
CSS zoom はページ読み込み時にリセットされるため、zoomFactorRegistry に 現在のズーム値を保持し、did-stop-loading 時に再注入するように修正。
…uperset-sh#3517) * remove 7 day rule * Upgrade mastra * upgrade ai * Ad mastra * refactor(desktop): remove dead provider-diagnostics plumbing The provider-diagnostics store was fed by callSmallModel's per-attempt reporting, which was removed when small-model tasks moved to direct AI-SDK + mastracode's AuthStorage. Nothing writes to the issue map anymore, so the clearIssue mutation, getStatuses query, and diagnosticStatus plumbing in ModelsSettings were all no-ops. Settings still surfaces "Session expired / Reconnect" via auth-status alone. ProviderIssue type collapsed from 8 codes to just "expired" to match. * fix(auth): auto-refresh expired Anthropic OAuth tokens Anthropic credentials were read via authStorage.get() everywhere, so mastracode's built-in refresh flow never ran. Once the 1-hour access token expired, status flipped to "Reconnect" and users had to do a full PKCE re-auth, even though a valid refresh token was already stored. Resolvers now call authStorage.getApiKey() for oauth creds on expiry, which triggers refreshToken() and persists the refreshed credential. getAnthropicAuthStatus does the same before declaring issue: "expired". Mirrors the pattern already used for OpenAI small-model auth. * review: address PR feedback from cubic + coderabbit + greptile - host-service ai-branch-name: run trailing-trim after slice so a 100-char truncation can't re-introduce a bare "." or "-" that git rejects as an invalid ref (coderabbit / cubic #2, #7). - host-service workspace-creation.generateBranchName: reuse the existing listBranchNames helper instead of the inline git walk, which classified off the short refname and could conflate a local "origin/foo" with refs/remotes/origin/foo (coderabbit #3). - packages/chat shared/small-model: drop the unused hasSmallModelCredentials export; only a test mock consumed it (greptile #4). - resolveAnthropicCredential: on refresh failure, return null instead of kind:"oauth" with a stale expiresAt so callers fall back cleanly (cubic #8). - chat-service.getAnthropicAuthStatus: log context when refresh throws instead of silently swallowing (cubic #9). * fix(chat): read auth.json directly instead of importing mastracode Importing createAuthStorage from mastracode loads the entire CLI tree (fastembed → onnxruntime-node's 208 MB native binary) via eager top-level requires in mastracode's CJS entry. This crashed electron-vite bundling and bloated the get-small-model chunk. getSmallModel now reads mastracode's auth.json file directly using the same path resolution logic (~/Library/Application Support/mastracode/ on macOS). Zero mastracode import, zero bundle impact. The chunk stays at 1.2 MB (just @ai-sdk/anthropic + @ai-sdk/openai). Production build verified: compile:app succeeds, Electron main process boots with no onnxruntime error. * docs(desktop): add manual testing plan for PR superset-sh#3517 * fix api key storage slot * fix(auth): store API keys in dedicated slot so OAuth doesn't clobber them setApiKeyForProvider and setStoredAnthropicApiKeyFromEnvVariables now use authStorage.setStoredApiKey() (writes to "apikey:<provider>") instead of authStorage.set() (writes to the main "<provider>" slot shared with OAuth). This way connecting/disconnecting OAuth doesn't overwrite or delete a stored API key. resolveAuthMethodForProvider falls back to hasStoredApiKey() after checking the main slot, so status correctly reports authenticated when only an API key is stored. * fix(auth): backup/restore API keys across OAuth connect/disconnect mastracode's resolveModel only reads API keys from the main authStorage slot (authStorage.get("anthropic")). OAuth login overwrites this slot, and disconnect removes it — losing any previously saved API key. Fix: backup the API key to the dedicated apikey: slot before OAuth connect, restore it after disconnect. setApiKeyForProvider now writes to both slots (main for resolveModel compatibility, apikey: for backup). resolveAuthMethodForProvider checks both. Applies to both Anthropic and OpenAI providers. * chore: add upstream PR reference to auth workaround Point to mastra-ai/mastra#15483 so the backup/restore code can be removed once upstream lands and we bump mastracode. * refactor(desktop): derive settings provider action from status Replace the cascade of if/else + canDisconnect flag with a single getProviderAction(status) → connect | reconnect | logout | null. Fixes "Active" badge + "Connect" button showing simultaneously when authenticated via API key. * fix(desktop): always show Logout when provider is active Active providers now always show a Logout button. Clears OAuth or API key depending on authMethod — no more "Active" badge with no way to disconnect. * fix(desktop): simplify OpenAI OAuth dialog + auto-open browser Match Anthropic dialog's layout: remove the raw OAuth URL display and "Tip" block, auto-open the browser on OAuth start. Change "Back" to "Cancel" for consistency. * refactor(desktop): unify OAuth dialogs into shared OAuthDialog Extract shared OAuthDialog component with provider config object. AnthropicOAuthDialog and OpenAIOAuthDialog become thin wrappers that pass provider-specific labels and options. * fix(desktop): show 'Copied!' feedback on Copy URL button * refactor(desktop): merge provider account + API key into single card Each provider section now renders AccountCard + ConfigRow inside one rounded card with a divider, instead of two separate cards. Removes the standalone "API Keys" collapsible section. * refactor(desktop): compact OAuth row in provider settings card OAuth row is now a single inline row (label + status + action) instead of a stacked AccountCard. Both providers share the same 2-row card layout: OAuth row + API key row with divider. * fix(desktop): contextual buttons in provider settings Connect is now primary (filled). Save only shows when there's input. Clear only shows when a key is saved. Removes visual noise from empty-state provider cards. * ui(desktop): add provider icons to settings section headers * ui(desktop): show 'Not connected' badge instead of subtitle for disconnected providers * ui: remove redundant disconnected subtitle * ui: remove subtitle text from OAuth rows * chore: remove dead AccountCard + getProviderSubtitle * docs: update test plan to match current UI * chore: move shipped plans to done/ --------- Co-authored-by: AviPeltz <aj.peltz@gmail.com>
…uperset-sh#3517) * remove 7 day rule * Upgrade mastra * upgrade ai * Ad mastra * refactor(desktop): remove dead provider-diagnostics plumbing The provider-diagnostics store was fed by callSmallModel's per-attempt reporting, which was removed when small-model tasks moved to direct AI-SDK + mastracode's AuthStorage. Nothing writes to the issue map anymore, so the clearIssue mutation, getStatuses query, and diagnosticStatus plumbing in ModelsSettings were all no-ops. Settings still surfaces "Session expired / Reconnect" via auth-status alone. ProviderIssue type collapsed from 8 codes to just "expired" to match. * fix(auth): auto-refresh expired Anthropic OAuth tokens Anthropic credentials were read via authStorage.get() everywhere, so mastracode's built-in refresh flow never ran. Once the 1-hour access token expired, status flipped to "Reconnect" and users had to do a full PKCE re-auth, even though a valid refresh token was already stored. Resolvers now call authStorage.getApiKey() for oauth creds on expiry, which triggers refreshToken() and persists the refreshed credential. getAnthropicAuthStatus does the same before declaring issue: "expired". Mirrors the pattern already used for OpenAI small-model auth. * review: address PR feedback from cubic + coderabbit + greptile - host-service ai-branch-name: run trailing-trim after slice so a 100-char truncation can't re-introduce a bare "." or "-" that git rejects as an invalid ref (coderabbit / cubic #2, #7). - host-service workspace-creation.generateBranchName: reuse the existing listBranchNames helper instead of the inline git walk, which classified off the short refname and could conflate a local "origin/foo" with refs/remotes/origin/foo (coderabbit #3). - packages/chat shared/small-model: drop the unused hasSmallModelCredentials export; only a test mock consumed it (greptile #4). - resolveAnthropicCredential: on refresh failure, return null instead of kind:"oauth" with a stale expiresAt so callers fall back cleanly (cubic #8). - chat-service.getAnthropicAuthStatus: log context when refresh throws instead of silently swallowing (cubic #9). * fix(chat): read auth.json directly instead of importing mastracode Importing createAuthStorage from mastracode loads the entire CLI tree (fastembed → onnxruntime-node's 208 MB native binary) via eager top-level requires in mastracode's CJS entry. This crashed electron-vite bundling and bloated the get-small-model chunk. getSmallModel now reads mastracode's auth.json file directly using the same path resolution logic (~/Library/Application Support/mastracode/ on macOS). Zero mastracode import, zero bundle impact. The chunk stays at 1.2 MB (just @ai-sdk/anthropic + @ai-sdk/openai). Production build verified: compile:app succeeds, Electron main process boots with no onnxruntime error. * docs(desktop): add manual testing plan for PR superset-sh#3517 * fix api key storage slot * fix(auth): store API keys in dedicated slot so OAuth doesn't clobber them setApiKeyForProvider and setStoredAnthropicApiKeyFromEnvVariables now use authStorage.setStoredApiKey() (writes to "apikey:<provider>") instead of authStorage.set() (writes to the main "<provider>" slot shared with OAuth). This way connecting/disconnecting OAuth doesn't overwrite or delete a stored API key. resolveAuthMethodForProvider falls back to hasStoredApiKey() after checking the main slot, so status correctly reports authenticated when only an API key is stored. * fix(auth): backup/restore API keys across OAuth connect/disconnect mastracode's resolveModel only reads API keys from the main authStorage slot (authStorage.get("anthropic")). OAuth login overwrites this slot, and disconnect removes it — losing any previously saved API key. Fix: backup the API key to the dedicated apikey: slot before OAuth connect, restore it after disconnect. setApiKeyForProvider now writes to both slots (main for resolveModel compatibility, apikey: for backup). resolveAuthMethodForProvider checks both. Applies to both Anthropic and OpenAI providers. * chore: add upstream PR reference to auth workaround Point to mastra-ai/mastra#15483 so the backup/restore code can be removed once upstream lands and we bump mastracode. * refactor(desktop): derive settings provider action from status Replace the cascade of if/else + canDisconnect flag with a single getProviderAction(status) → connect | reconnect | logout | null. Fixes "Active" badge + "Connect" button showing simultaneously when authenticated via API key. * fix(desktop): always show Logout when provider is active Active providers now always show a Logout button. Clears OAuth or API key depending on authMethod — no more "Active" badge with no way to disconnect. * fix(desktop): simplify OpenAI OAuth dialog + auto-open browser Match Anthropic dialog's layout: remove the raw OAuth URL display and "Tip" block, auto-open the browser on OAuth start. Change "Back" to "Cancel" for consistency. * refactor(desktop): unify OAuth dialogs into shared OAuthDialog Extract shared OAuthDialog component with provider config object. AnthropicOAuthDialog and OpenAIOAuthDialog become thin wrappers that pass provider-specific labels and options. * fix(desktop): show 'Copied!' feedback on Copy URL button * refactor(desktop): merge provider account + API key into single card Each provider section now renders AccountCard + ConfigRow inside one rounded card with a divider, instead of two separate cards. Removes the standalone "API Keys" collapsible section. * refactor(desktop): compact OAuth row in provider settings card OAuth row is now a single inline row (label + status + action) instead of a stacked AccountCard. Both providers share the same 2-row card layout: OAuth row + API key row with divider. * fix(desktop): contextual buttons in provider settings Connect is now primary (filled). Save only shows when there's input. Clear only shows when a key is saved. Removes visual noise from empty-state provider cards. * ui(desktop): add provider icons to settings section headers * ui(desktop): show 'Not connected' badge instead of subtitle for disconnected providers * ui: remove redundant disconnected subtitle * ui: remove subtitle text from OAuth rows * chore: remove dead AccountCard + getProviderSubtitle * docs: update test plan to match current UI * chore: move shipped plans to done/ --------- Co-authored-by: AviPeltz <aj.peltz@gmail.com>
upstream 取り込み PR #9: 計画後前進分 12 commits + bun.lock regen
… upstream superset-sh#3697) upstream superset-sh#3697 の split 構造 (24 ファイル) を fork に取り込み、fork 独自拡張を新 split 構造に再配置。workspace-creation.ts を 1758 行から 28 行の facade に縮小。 - schemas.ts: 全 procedure の zod schemas (baseBranchSource, workspaceNameWasAutoGenerated, checkoutPrSchema XOR refine を保持) - shared/: 11 ファイル (types, project-helpers, local-project, progress-store, git-config, setup-terminal, worktree-paths, start-point, branch-search, finish-checkout, types) - procedures/: 11 ファイル (adopt, checkout, create, generate-branch-name, get-context, get-github-issue-content, get-github-pull-request-content, get-progress, search-branches, search-github-issues, search-pull-requests) - utils/: 追加 (ai-workspace-names.ts, list-branch-names.ts) 1. **baseBranchSource** (picker hint: local/remote-tracking) → schemas.ts + procedures/create.ts + procedures/adopt.ts 2. **PR checkout mode** (derivePrLocalBranchName, detached worktree, gh pr checkout --force, pre-existing branch/closed/merged warnings) → procedures/checkout.ts 3. **FORK NOTE** コメント群 → 関連 procedure に復元 4. **GitHub link command wiring** (gh issue develop, gh pr create) → 各 procedure 5. **normalize-github-query.ts** (fork-only URL normalization) → 維持 6. **applyAiWorkspaceRename** + updateNameFromHost no-op detection → utils/ai-workspace-names.ts で復元 (PR #9 で fork main から欠落して いた関数を本 PR で供給) 7. **worktree path 方針**: <repoPath>/.worktrees/<branch> を維持 (upstream の ~/.superset/worktrees/<projectId>/<branch> は採用しない。 既存 workspace/file watcher/migration 互換性のため) packages/trpc/src/router/v2-workspace/v2-workspace.ts に `updateNameFromHost` JWT procedure を追加。expectedCurrentName WHERE guard で並行 user rename の race を検出し、no-op 時は既存 row を 返して host-service 側で git branch rollback できるようにする。 - ai-workspace-names.ts: getSmallModel() が unknown を返すため、 Agent の model parameter に biome-ignore 付きで cast - v2-workspace.updateNameFromHost: findFirst の columns に branch を追加 (no-op 時の caller での branch 比較に必要) - bun run typecheck: 27/27 successful - bun run lint: pass (rg 未 install の環境警告除く) - fork 固有機能: 19 procedure, ansi_up/@vscode/ripgrep/@xyflow/react, TERMINAL_OPTIONS, SUPERSET_WORKSPACE_NAME, dmg.size=4g, desktop 1.5.10 全健在 packages/host-service/package.json に @mastra/core: 1.25.0 を追加 (applyAiWorkspaceRename が Agent を使うため)。packages/chat が既に 同 version を持つため workspace 共有で解決される。 Closes #415
概要
ブラウザタブのツールバーにズーム機能(拡大・縮小・リセット)を追加しました。
変更内容
usePersistentWebview.ts:zoomIn,zoomOut,resetZoom,zoomLevelを追加。webview のsetZoomLevel()/getZoomLevel()API を直接操作BrowserPane.tsx: DevTools ボタンの左側に[-][100%][+]ボタンを配置仕様
UI 配置
コンフリクトリスク
バックエンドや型定義は変更なし。レンダラー側の2ファイルのみ(うち1ファイルはフォーク変更済み)。
テスト計画
Summary by CodeRabbit