Update sidebar repository spacing#3
Merged
Conversation
zvadaadam
added a commit
that referenced
this pull request
Feb 23, 2026
1. **inject-mode.ts: var() scan now covers padding/gap (#3)** Renamed colorProps → varScanProps, added padding/gap so getMatchedVarDeclarations captures var() tokens for spacing props. 2. **inject-mode.ts: font-weight fallback added (#10)** Added font-weight to the fallback conditional alongside font-size and border-radius. Filters out 'normal' (CSS default) as noise. 3. **BrowserPanel.tsx: DevTools state races with async invoke (#4)** Moved handleUpdateTab into .then() so devtoolsOpen only updates after the Rust command succeeds. Prevents UI desync on failure. 4. **BrowserTab.tsx: safeListen missing .catch() (#5)** Added .catch() to the listen() promise chain to prevent unhandled rejections if Tauri listener registration fails. 5. **BrowserTab.tsx: injectionFailed not cleared on success (#7)** Changed onUpdateTab to also set injectionFailed: false after successful injection, clearing stale error indicators. 6. **webview.rs: eprintln! gated for release builds (#8)** All 4 eprintln! calls in eval_browser_webview_with_result wrapped with cfg!(debug_assertions). Prevents leaking JS content, URLs, tokens, or page console data in production. 7. **webview.rs: DevTools error propagation (#9)** open/close_browser_devtools now use Arc<Mutex<Option<String>>> to propagate null-pointer errors out of with_webview closures. Frontend receives Err() instead of silent Ok(()) when DevTools unavailable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Feb 23, 2026
* feat: Fix browser inspect element pills with code quality improvements ## Changes ### 1. Fix DevTools Expansion Bug (Tauri Native Layer) When clicking the DevTools button, the browser view would unexpectedly expand. Root cause: `_inspector.show()` docks by splitting WKWebView's superview, resizing the webview. After `detach()` moves inspector to floating window, frame isn't restored. **Fix:** Save WKWebView frame before show(), restore after detach(). - Modified: src-tauri/src/commands/webview.rs (lines 570-582) ### 2. Fix Cursor Animation Attribute Mismatch (Issue #1 - HIGH) Cursor visual effects (move, ripple, pin) were silently failing because they searched for `data-cursor-ref` but elements were marked with `data-hive-ref`. **Fix:** Replace all `data-cursor-ref` references with `data-hive-ref` to match the actual attribute used in inject-mode.ts. - Modified: src/features/browser/automation/visual-effects.ts - Line 18: JSDoc comment - Line 25: buildMoveCursorAndRippleJs() - Line 45: buildPinCursorJs() - Line 96: buildHighlightElementJs() ### 3. Add IME Composition Guard to MessageInput (Issue #2 - MEDIUM) CJK (Chinese, Japanese, Korean) users using Input Method Editors (IME) would lose their input when pressing Enter during composition, since the handler didn't check if composition was in progress. **Fix:** Add `!e.nativeEvent.isComposing` guard to Enter key handler to prevent message send during active IME composition. - Modified: src/features/session/ui/MessageInput.tsx (line 286) ### 4. Fix Element Selector Injection Exception Handling (Issue #3 - MEDIUM) When `verify_injection` script threw an exception, the catch block didn't return, causing exception object to fall through to `eval_browser_webview_with_result`, which would parse it as a result string instead of error. **Fix:** Add explicit `return;` in catch block to prevent fall-through. - Modified: src/features/browser/ui/BrowserTab.tsx (line 521) ### 5. Fix Selector Toggle State on Eval Failure (Issue #4 - MEDIUM) When element selector injection failed, `selectorActive` was set in the UI store but outside the try block, so errors during injection were silently swallowed. **Fix:** Move state update inside try block to fail-fast on injection errors. - Modified: src/features/browser/ui/BrowserTab.tsx (line 563) ### 6. Add Polling Guard to Inspect Event Drain (Issue #5 - MEDIUM) Inspect event drain was polling unconditionally every 200ms, consuming ~5 IPC calls/second unnecessarily. With multiple tabs this compounds quickly. **Fix:** Only poll when selector is active. Add `!tab.selectorActive` guard and add to dependency array. - Modified: src/features/browser/ui/BrowserTab.tsx (lines 396-458) ### 7. Replace if/else with ts-pattern (Issue #6 - LOW) Long if/else chain for event type dispatch violates CLAUDE.md requirement to use ts-pattern for discriminated union dispatch. **Fix:** Import ts-pattern and use `.with()` / `.otherwise()` for event type matching. - Modified: src/features/browser/ui/BrowserTab.tsx (lines 26, 427-444) ### 8. Fix Hover Animation Timing (Issue #7 - LOW) InspectedElementCard hover transition was `duration-150` instead of `duration-200`, violating CLAUDE.md animation standard of 200-300ms default duration. **Fix:** Update to `duration-200 ease` to match project animation guidelines. - Modified: src/features/session/ui/InspectedElementCard.tsx (line 48) ## Verification - TypeScript compilation: ✓ (pre-existing Lucide icon issue unrelated to changes) - All fixes verified and applied by parallel code-reviewer agents - Changes preserve existing functionality while fixing correctness issues - Performance improvement: Eliminates ~5 IPC calls/second from unconditional polling ## Impact - **Bug fixes:** 3 (DevTools expansion, cursor animations, IME composition) - **Correctness improvements:** 2 (exception handling, state sync) - **Performance:** Reduced IPC quota consumption from inspect event drain - **Code quality:** Full CLAUDE.md compliance (ts-pattern, animation timing) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: Address PR review — ts-pattern console dispatch + comment consistency 1. Replace nested ternary on log.l with ts-pattern match() in console drain loop (BrowserTab.tsx:365). Consistent with inspect event drain at line 428 which already uses match(). CLAUDE.md requires ts-pattern for all discriminator field dispatch. 2. Fix contradictory architecture comments across 3 files: - inject/inspect-mode.ts: Remove "DUAL mechanism: PRIMARY title-channel" language and phantom serialization queue details. Buffer+drain via eval_browser_webview_with_result is the sole path. - BrowserTab.tsx: Change "FALLBACK path" to "sole delivery path". - webview.rs: Remove reference to non-existent sendViaTitle(), mark title-channel handler as backward-compat only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: Address PR review — 7 issues across 4 files 1. **inject-mode.ts: var() scan now covers padding/gap (#3)** Renamed colorProps → varScanProps, added padding/gap so getMatchedVarDeclarations captures var() tokens for spacing props. 2. **inject-mode.ts: font-weight fallback added (#10)** Added font-weight to the fallback conditional alongside font-size and border-radius. Filters out 'normal' (CSS default) as noise. 3. **BrowserPanel.tsx: DevTools state races with async invoke (#4)** Moved handleUpdateTab into .then() so devtoolsOpen only updates after the Rust command succeeds. Prevents UI desync on failure. 4. **BrowserTab.tsx: safeListen missing .catch() (#5)** Added .catch() to the listen() promise chain to prevent unhandled rejections if Tauri listener registration fails. 5. **BrowserTab.tsx: injectionFailed not cleared on success (#7)** Changed onUpdateTab to also set injectionFailed: false after successful injection, clearing stale error indicators. 6. **webview.rs: eprintln! gated for release builds (#8)** All 4 eprintln! calls in eval_browser_webview_with_result wrapped with cfg!(debug_assertions). Prevents leaking JS content, URLs, tokens, or page console data in production. 7. **webview.rs: DevTools error propagation (#9)** open/close_browser_devtools now use Arc<Mutex<Option<String>>> to propagate null-pointer errors out of with_webview closures. Frontend receives Err() instead of silent Ok(()) when DevTools unavailable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ci): build inject scripts before sidecar unit tests browser-templates.test.ts imports browser-utils.ts which reads dist-inject/browser-utils.js via ?raw import. The dist-inject/ directory is gitignored and must be built first. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(test): update browser-templates tests for inject refactor - Remove dead BROWSER_UTILS import (renamed to BROWSER_UTILS_SETUP) - Remove incorrect buildPressKeyJs BROWSER_UTILS test (it intentionally doesn't use browser utils — operates on document.activeElement directly) - Update assertIsIIFE to accept both classic IIFEs (function(){...})() and arrow IIFEs (() => {...})() — esbuild format: "iife" emits the latter for compiled inject scripts like VISUAL_EFFECTS_SETUP Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address code review round 3 — security, a11y, concurrency - Gate getReactProps() and getShallowInnerHTML() to local context only; external sites can leak PII/tokens via React fiber props and innerHTML - Remove 'value' from ATTR_WHITELIST (can contain passwords) - Add in-flight guards to console and inspect drain intervals to prevent overlapping async invokes when eval_browser_webview is slow - Add aria-hidden + sr-only text for injection failure indicator - Add aria-label to screenshot button - Remove duplicate comment blocks in inject-mode.ts - Fix stale "title-channel" comment in BrowserTab.tsx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(browser): add screenshot button + mobile viewport toggle Add two new browser panel toolbar features: 1. Screenshot button (Camera icon): captures WKWebView as JPEG via Rust IPC and attaches to chat input via CustomEvent bridge. 2. Mobile/Desktop viewport toggle (Smartphone/Monitor icon): constrains browser area to 390px (iPhone 14 logical width) centered with mx-auto. The mobile view required replacing the tab stacking strategy — absolute positioning (inset-0) didn't reliably inherit width constraints during parent restructuring, causing getBoundingClientRect() to return stale full-width values. Tabs now stack via CSS Grid ([grid-area:1/1]) which keeps them in normal document flow. A useLayoutEffect with hide → setBounds → show cycle ensures the native WKWebView repositions synchronously on toggle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Feb 26, 2026
…antic colors Replace muted text with tinted pills and state-colored links. PR status is now visually discoverable at a glance: amber tint for "Checks running", blue tint for "Awaiting review", solid colors for action states (red=fix, green=merge). Architecture change: Pure state machine pattern using derivePRActionState() that maps PRStatus to a discriminated union (PRActionState), then exhaustive pattern matching in JSX. Eliminates conditional logic scattered across component. Changes: - New src/features/workspace/lib/prState.ts: pure derivation function - Rewritten PRActions.tsx: state machine UI, no redundant chips or status bars - Deleted PRStatusBar.tsx (dead code, confirmed via grep) - PR link promoted from text-text-tertiary to state-colored at 80% opacity with PR icon (#N → [icon] #3) - StatusText now renders tinted pills: pending=amber, review=blue - GhWarning gets amber tint to match visual system - Review button moved to DiffFilesTree footer in prior session (inserts prompt) Consensus design synthesized from 5-designer exploration: - Fukasawa's state-colored link philosophy - 4 designers agreed on tinted pills for non-actionable states - 3-tier hierarchy: solid bg (act) → tinted bg (aware) → tinted text (navigate) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Feb 26, 2026
* refactor: redesign PR status indicator with visual prominence and semantic colors Replace muted text with tinted pills and state-colored links. PR status is now visually discoverable at a glance: amber tint for "Checks running", blue tint for "Awaiting review", solid colors for action states (red=fix, green=merge). Architecture change: Pure state machine pattern using derivePRActionState() that maps PRStatus to a discriminated union (PRActionState), then exhaustive pattern matching in JSX. Eliminates conditional logic scattered across component. Changes: - New src/features/workspace/lib/prState.ts: pure derivation function - Rewritten PRActions.tsx: state machine UI, no redundant chips or status bars - Deleted PRStatusBar.tsx (dead code, confirmed via grep) - PR link promoted from text-text-tertiary to state-colored at 80% opacity with PR icon (#N → [icon] #3) - StatusText now renders tinted pills: pending=amber, review=blue - GhWarning gets amber tint to match visual system - Review button moved to DiffFilesTree footer in prior session (inserts prompt) Consensus design synthesized from 5-designer exploration: - Fukasawa's state-colored link philosophy - 4 designers agreed on tinted pills for non-actionable states - 3-tier hierarchy: solid bg (act) → tinted bg (aware) → tinted text (navigate) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address CodeRabbit review — false network error + stale ghStatus edge case Backend: A successful `gh pr list` response on the origin attempt no longer surfaces a stale `lastError` from a failed upstream attempt. Adds `hadSuccessfulResponse` flag so `error: "network"` is only returned when every attempt actually failed. Frontend: `derivePRActionState` now handles `gh_not_installed` and `gh_not_authenticated` errors from the PR status endpoint directly, covering the 5-minute `ghStatus` stale window where gh could be uninstalled/deauthed between status checks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Mar 2, 2026
…uncation Addresses 3 actionable findings from CodeRabbit review: 1. **Redact raw prompts from logs** (comments #2 + #5): Replace `prompt.slice(0, 80)` with `promptLength` in timing logs in both claude-handler.ts and index.ts. User prompts were being written to /tmp log files — now only the length is logged. 2. **Fix messageCount ReferenceError** (comment #3): Move `let messageCount` declaration from inside the `try` block to before it. In JS, `let` inside `try {}` is NOT accessible in `catch {}` — they are separate block scopes. This caused a ReferenceError in the catch block, masking the actual error. 3. **Safe UTF-8 truncation in Rust** (comment #6): Replace `&error[..error.len().min(80)]` with `error.chars().take(80).collect::<String>()` in socket.rs. Byte-index slicing can panic on multibyte UTF-8 boundaries. (session_id truncation left as-is — UUIDv7 is guaranteed ASCII.) Dismissed as not actionable: - Comment #4 (error redaction in session-writer): Error messages are already sanitized by classifyError(). Redacting would lose debuggability for zero security gain. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Mar 2, 2026
…ocess (#163) * fix(session): implement proper cancel/stop flow with force-kill subprocess ## Problem When user clicked stop, two things failed: 1. Agent kept running — `query.interrupt()` sends graceful message but doesn't guarantee stop 2. No visual feedback — cancelled message only persisted in catch block, which never ran on interrupt ## Solution Replace `query.interrupt()` (graceful) with `query.close()` (force-kill subprocess + children): - Terminates entire process tree, no need to track individual sub-agent tasks - Synchronous operation, immediate subprocess death Add `cancelledByUser` flag to SessionState: - Set by `handleCancel` before close - Checked in post-loop path to save cancelled message + send Tauri event - Checked in catch block for early return (avoid duplicate error handling) ## Changes **Sidecar (agent cancellation):** - `handleCancel`: Use `close()` instead of `interrupt()`, set `cancelledByUser=true` - Post-loop: When `cancelledByUser`, save cancelled message to DB with `stop_reason: "cancelled"` envelope format - Catch block: Return early if `cancelledByUser` to avoid error handling path - Add TIMING instrumentation throughout for observability **Backend (cleanup dead code):** - Remove `cancelled_at` column updates from POST `/sessions/:id/stop` - Delete unused `getLatestUserMessage` function **Frontend:** - Remove `window.confirm()` blocking confirmation dialog - In AssistantTurn: When cancelled, strip sentinel message from array, put all real messages in hiddenMessages, render warning-styled "Response stopped" badge instead of summary message **Networking/IPC:** - Add RPC logging to understand cancel flow - Socket.rs: Log cancel events ## Testing - `bun run test:sidecar` — all 198 tests pass - `bun run test:backend` — all tests pass - Manual: Start session → click Stop → agent stops immediately, "Response stopped" appears, session idle - Manual: Restart app → cancelled session persists, shows "Response stopped" badge Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix: address PR review — redact prompts, fix scope bug, safe UTF-8 truncation Addresses 3 actionable findings from CodeRabbit review: 1. **Redact raw prompts from logs** (comments #2 + #5): Replace `prompt.slice(0, 80)` with `promptLength` in timing logs in both claude-handler.ts and index.ts. User prompts were being written to /tmp log files — now only the length is logged. 2. **Fix messageCount ReferenceError** (comment #3): Move `let messageCount` declaration from inside the `try` block to before it. In JS, `let` inside `try {}` is NOT accessible in `catch {}` — they are separate block scopes. This caused a ReferenceError in the catch block, masking the actual error. 3. **Safe UTF-8 truncation in Rust** (comment #6): Replace `&error[..error.len().min(80)]` with `error.chars().take(80).collect::<String>()` in socket.rs. Byte-index slicing can panic on multibyte UTF-8 boundaries. (session_id truncation left as-is — UUIDv7 is guaranteed ASCII.) Dismissed as not actionable: - Comment #4 (error redaction in session-writer): Error messages are already sanitized by classifyError(). Redacting would lose debuggability for zero security gain. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix(test): add mockDbAll to session-writer test mock reconcileStuckSessions now calls .prepare().all() for diagnostic logging before the UPDATE. The test mock only had run/get methods, causing .all() to be undefined and the function to hit the catch block. This is a test mock gap, not a production bug. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Mar 12, 2026
- #3: Log query:invalidate emit errors in backend.rs (was silent `let _ =`) - #5: Guard malformed payload in useQueryInvalidation with `?.` fallback - #6: Update CLAUDE.md — useSession is event-driven, not polled - #7: Move misplaced ChatInsert JSDoc to correct position above its schema Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Mar 12, 2026
* feat(events): centralized event catalog with Zod runtime validation Implement a single source of truth for all Tauri/sidecar events with compile-time type safety and runtime validation: - Add shared/events.ts with 17 event constants, 13 Zod schemas, 3 domain arrays (QUERY_RESOURCES, MUTATION_NAMES, SIDECAR_NOTIFY_EVENTS), and AppEventMap/AppEventName types - Wire Zod validation into listen() wrapper — validates payloads at Rust→TS boundary, logs drift, still delivers on failure - Fix 3 raw string emit() calls to use BROWSER_WORKSPACE_CHANGE and CHAT_INSERT constants - Consolidate message-writing to writeUserMessage() service to eliminate duplication - Remove web polling fallback code (getWorkspacesByRepoRefetchInterval, getStatsRefetchInterval) — desktop-only app - Fix type narrowing for INVALIDATION_MAP in notify route - Tighten ChatInsertSchema element variant with proper InspectElement Zod schema - Add 32 tests: events schema validation (19), listen() Zod validation (5), notify route (8) - All 286 backend + 131 frontend + 442 sidecar tests pass Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(CLAUDE.md): document event catalog pattern and update polling guidance - Add Event Catalog section explaining shared/events.ts, AppEventMap, Zod validation, createListenerGroup, and how to add new events - Update request volume table to reflect event-driven invalidation (workspaces/stats no longer polled) - Update polling discipline to reference push-first invalidation pipeline - Update read-layer migration priorities (no longer referenced as "polled every 2s") Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address code review feedback (#3, #5, #6, #7) - #3: Log query:invalidate emit errors in backend.rs (was silent `let _ =`) - #5: Guard malformed payload in useQueryInvalidation with `?.` fallback - #6: Update CLAUDE.md — useSession is event-driven, not polled - #7: Move misplaced ChatInsert JSDoc to correct position above its schema Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: tighten QueryInvalidateSchema and clear error fields on retry (#2, #5) - #2: Clear error_message/error_category in writeUserMessage() to align with sidecar's saveUserMessage() — prevents stale error fields on retry - #5: Tighten QueryInvalidateSchema resources to z.enum(QUERY_RESOURCES) instead of z.string() — catches misspelled resource names at runtime Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Mar 22, 2026
PairGatePage: - Remove last "relay" jargon from error message (#3) - PulsingDots respects prefers-reduced-motion via `reduced` prop (#4) - Add sr-only label, aria-invalid, aria-describedby, role=alert for a11y (#5) - Store success timeout in ref + cleanup on unmount (#6) - Cancel paste auto-submit timer on type and explicit submit (#8) AccessSection: - Use onOpenChangeRef to prevent stale closure in success setTimeout (#7) - Detect new devices by ID set comparison instead of count (#9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 089f8af05d92
zvadaadam
added a commit
that referenced
this pull request
Mar 22, 2026
) * feat: redesign device pairing UX with two-word codes, QR dialog, and animated gate page Replaces WORD-NNNN pairing codes with two uppercase words (e.g. SOFT TIGER) from a 250-word list for better dictation and mobile typing. Consolidates the split two-field input into a single field with smart paste handling. Adds a centered dialog with QR code hero for desktop pairing flow, and redesigns the remote PairGatePage with three animated states (auto-connecting, success, manual entry). Codes are now reusable within their 15-minute TTL for multi-device sharing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: replace hardcoded color classes with semantic tokens Use bg-success, text-success, text-warning, bg-warning, bg-destructive instead of bg-emerald-500, text-emerald-500, text-amber-500, bg-red-400. These semantic tokens are already defined in global.css and adapt to light/dark mode via OKLCH values. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 9ffb5ff87432 * fix: update integration tests for two-word codes and reusable TTL The integration test still expected the old WORD-NNNN format regex and one-time-use code behavior. Updated to match two-word format and verify that codes are reusable within their TTL for multi-device sharing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 36c4f0b6f8fc * fix: address code review findings for pairing UX PairGatePage: - Remove last "relay" jargon from error message (#3) - PulsingDots respects prefers-reduced-motion via `reduced` prop (#4) - Add sr-only label, aria-invalid, aria-describedby, role=alert for a11y (#5) - Store success timeout in ref + cleanup on unmount (#6) - Cancel paste auto-submit timer on type and explicit submit (#8) AccessSection: - Use onOpenChangeRef to prevent stale closure in success setTimeout (#7) - Detect new devices by ID set comparison instead of count (#9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 089f8af05d92 * fix: gate device success detection on query resolution Pass isDevicesLoaded (from devicesQuery.isFetched) to ConnectDeviceDialog. When the query hasn't resolved yet, just update the baseline IDs without triggering success detection. This prevents false positives when the dialog opens while devices are still loading ([] → existing devices). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: f34b15c1a77e * fix: differentiate QR placeholder states in connect dialog Show "Generating..." only when the relay URL is available but the code is still being created. Show "Waiting for connection..." when the relay itself hasn't connected yet (no accessUrl). Previously both states showed "Generating..." which was misleading. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 43c76b5ad359 * fix: await clipboard writes and use curated error messages - Await navigator.clipboard.writeText() and show error toast on failure instead of assuming success (all 3 clipboard call sites) - Replace raw backend error messages in toasts with curated user-facing copy ("Couldn't generate a code", "Couldn't remove device") - Remove unused getErrorMessage import Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 60d8c8e60b18 --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7 tasks
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
…mentation Fixes 9 out of 10 code review issues (#1-5, #7, #9-10): - Remove dead Claude transformer accumulation (Issue #1) - Add graceful fallback for full_message column detection (Issue #2) - Use process.argv[1] for bundle-safe vendor path resolution (Issue #3) - Static import of execSync instead of dynamic require (Issue #4) - Add platform support guard instead of silently mapping to Linux (Issue #5) - Add null check on child.stdout before readline (Issue #7) - Add identity check in finally block to prevent race condition (Issue #9) - Capture thread_id for Codex message correlation (Issue #10) The in-place mutation in codex-adapter.ts (Issue #6) is verified safe because blocks are JSON-serialized before reaching the frontend, making the mutation internal to adapter lifecycle and invisible to consumers. All 193 sidecar tests pass. Zero type errors. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
- #3: Log query:invalidate emit errors in backend.rs (was silent `let _ =`) - #5: Guard malformed payload in useQueryInvalidation with `?.` fallback - #6: Update CLAUDE.md — useSession is event-driven, not polled - #7: Move misplaced ChatInsert JSDoc to correct position above its schema Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
…antic colors Replace muted text with tinted pills and state-colored links. PR status is now visually discoverable at a glance: amber tint for "Checks running", blue tint for "Awaiting review", solid colors for action states (red=fix, green=merge). Architecture change: Pure state machine pattern using derivePRActionState() that maps PRStatus to a discriminated union (PRActionState), then exhaustive pattern matching in JSX. Eliminates conditional logic scattered across component. Changes: - New src/features/workspace/lib/prState.ts: pure derivation function - Rewritten PRActions.tsx: state machine UI, no redundant chips or status bars - Deleted PRStatusBar.tsx (dead code, confirmed via grep) - PR link promoted from text-text-tertiary to state-colored at 80% opacity with PR icon (#N → [icon] #3) - StatusText now renders tinted pills: pending=amber, review=blue - GhWarning gets amber tint to match visual system - Review button moved to DiffFilesTree footer in prior session (inserts prompt) Consensus design synthesized from 5-designer exploration: - Fukasawa's state-colored link philosophy - 4 designers agreed on tinted pills for non-actionable states - 3-tier hierarchy: solid bg (act) → tinted bg (aware) → tinted text (navigate) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
## Changes ### 1. Fix DevTools Expansion Bug (Tauri Native Layer) When clicking the DevTools button, the browser view would unexpectedly expand. Root cause: `_inspector.show()` docks by splitting WKWebView's superview, resizing the webview. After `detach()` moves inspector to floating window, frame isn't restored. **Fix:** Save WKWebView frame before show(), restore after detach(). - Modified: src-tauri/src/commands/webview.rs (lines 570-582) ### 2. Fix Cursor Animation Attribute Mismatch (Issue #1 - HIGH) Cursor visual effects (move, ripple, pin) were silently failing because they searched for `data-cursor-ref` but elements were marked with `data-hive-ref`. **Fix:** Replace all `data-cursor-ref` references with `data-hive-ref` to match the actual attribute used in inject-mode.ts. - Modified: src/features/browser/automation/visual-effects.ts - Line 18: JSDoc comment - Line 25: buildMoveCursorAndRippleJs() - Line 45: buildPinCursorJs() - Line 96: buildHighlightElementJs() ### 3. Add IME Composition Guard to MessageInput (Issue #2 - MEDIUM) CJK (Chinese, Japanese, Korean) users using Input Method Editors (IME) would lose their input when pressing Enter during composition, since the handler didn't check if composition was in progress. **Fix:** Add `!e.nativeEvent.isComposing` guard to Enter key handler to prevent message send during active IME composition. - Modified: src/features/session/ui/MessageInput.tsx (line 286) ### 4. Fix Element Selector Injection Exception Handling (Issue #3 - MEDIUM) When `verify_injection` script threw an exception, the catch block didn't return, causing exception object to fall through to `eval_browser_webview_with_result`, which would parse it as a result string instead of error. **Fix:** Add explicit `return;` in catch block to prevent fall-through. - Modified: src/features/browser/ui/BrowserTab.tsx (line 521) ### 5. Fix Selector Toggle State on Eval Failure (Issue #4 - MEDIUM) When element selector injection failed, `selectorActive` was set in the UI store but outside the try block, so errors during injection were silently swallowed. **Fix:** Move state update inside try block to fail-fast on injection errors. - Modified: src/features/browser/ui/BrowserTab.tsx (line 563) ### 6. Add Polling Guard to Inspect Event Drain (Issue #5 - MEDIUM) Inspect event drain was polling unconditionally every 200ms, consuming ~5 IPC calls/second unnecessarily. With multiple tabs this compounds quickly. **Fix:** Only poll when selector is active. Add `!tab.selectorActive` guard and add to dependency array. - Modified: src/features/browser/ui/BrowserTab.tsx (lines 396-458) ### 7. Replace if/else with ts-pattern (Issue #6 - LOW) Long if/else chain for event type dispatch violates CLAUDE.md requirement to use ts-pattern for discriminated union dispatch. **Fix:** Import ts-pattern and use `.with()` / `.otherwise()` for event type matching. - Modified: src/features/browser/ui/BrowserTab.tsx (lines 26, 427-444) ### 8. Fix Hover Animation Timing (Issue #7 - LOW) InspectedElementCard hover transition was `duration-150` instead of `duration-200`, violating CLAUDE.md animation standard of 200-300ms default duration. **Fix:** Update to `duration-200 ease` to match project animation guidelines. - Modified: src/features/session/ui/InspectedElementCard.tsx (line 48) ## Verification - TypeScript compilation: ✓ (pre-existing Lucide icon issue unrelated to changes) - All fixes verified and applied by parallel code-reviewer agents - Changes preserve existing functionality while fixing correctness issues - Performance improvement: Eliminates ~5 IPC calls/second from unconditional polling ## Impact - **Bug fixes:** 3 (DevTools expansion, cursor animations, IME composition) - **Correctness improvements:** 2 (exception handling, state sync) - **Performance:** Reduced IPC quota consumption from inspect event drain - **Code quality:** Full CLAUDE.md compliance (ts-pattern, animation timing) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
1. **inject-mode.ts: var() scan now covers padding/gap (#3)** Renamed colorProps → varScanProps, added padding/gap so getMatchedVarDeclarations captures var() tokens for spacing props. 2. **inject-mode.ts: font-weight fallback added (#10)** Added font-weight to the fallback conditional alongside font-size and border-radius. Filters out 'normal' (CSS default) as noise. 3. **BrowserPanel.tsx: DevTools state races with async invoke (#4)** Moved handleUpdateTab into .then() so devtoolsOpen only updates after the Rust command succeeds. Prevents UI desync on failure. 4. **BrowserTab.tsx: safeListen missing .catch() (#5)** Added .catch() to the listen() promise chain to prevent unhandled rejections if Tauri listener registration fails. 5. **BrowserTab.tsx: injectionFailed not cleared on success (#7)** Changed onUpdateTab to also set injectionFailed: false after successful injection, clearing stale error indicators. 6. **webview.rs: eprintln! gated for release builds (#8)** All 4 eprintln! calls in eval_browser_webview_with_result wrapped with cfg!(debug_assertions). Prevents leaking JS content, URLs, tokens, or page console data in production. 7. **webview.rs: DevTools error propagation (#9)** open/close_browser_devtools now use Arc<Mutex<Option<String>>> to propagate null-pointer errors out of with_webview closures. Frontend receives Err() instead of silent Ok(()) when DevTools unavailable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
PairGatePage: - Remove last "relay" jargon from error message (#3) - PulsingDots respects prefers-reduced-motion via `reduced` prop (#4) - Add sr-only label, aria-invalid, aria-describedby, role=alert for a11y (#5) - Store success timeout in ref + cleanup on unmount (#6) - Cancel paste auto-submit timer on type and explicit submit (#8) AccessSection: - Use onOpenChangeRef to prevent stale closure in success setTimeout (#7) - Detect new devices by ID set comparison instead of count (#9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 089f8af05d92
zvadaadam
added a commit
that referenced
this pull request
Apr 2, 2026
…uncation Addresses 3 actionable findings from CodeRabbit review: 1. **Redact raw prompts from logs** (comments #2 + #5): Replace `prompt.slice(0, 80)` with `promptLength` in timing logs in both claude-handler.ts and index.ts. User prompts were being written to /tmp log files — now only the length is logged. 2. **Fix messageCount ReferenceError** (comment #3): Move `let messageCount` declaration from inside the `try` block to before it. In JS, `let` inside `try {}` is NOT accessible in `catch {}` — they are separate block scopes. This caused a ReferenceError in the catch block, masking the actual error. 3. **Safe UTF-8 truncation in Rust** (comment #6): Replace `&error[..error.len().min(80)]` with `error.chars().take(80).collect::<String>()` in socket.rs. Byte-index slicing can panic on multibyte UTF-8 boundaries. (session_id truncation left as-is — UUIDv7 is guaranteed ASCII.) Dismissed as not actionable: - Comment #4 (error redaction in session-writer): Error messages are already sanitized by classifyError(). Redacting would lose debuggability for zero security gain. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 10, 2026
…ngine.ts by extracting pushSnapshot() and pushWorkspaceDelta() helpers, and deduplicated identical turn/cancel and session/stop handlers in agent-server/index.ts into a shared cancelAll function (-20 net lines, nesting reduced from 5 to 3 levels).
zvadaadam
added a commit
that referenced
this pull request
Apr 10, 2026
…236) * gnhf #1: Simplified query-engine.ts (the most complex backend file) by adding a requireParam helper and wsGet/repoGet closures, eliminating 70 lines of repetitive parameter extraction boilerplate across runQuery, runRequest, and runMutation. * gnhf #2: Deduplicated repos.ts and agent-server/index.ts by extracting 3 helpers: resolveTargetPath (path guard), pipeGitStderr (stderr streaming), and getInitializedAgents (agent listing), eliminating 3 instances of code duplication across 2 files (-11 net lines). * gnhf #3: Flattened the deeply nested invalidate() function in query-engine.ts by extracting pushSnapshot() and pushWorkspaceDelta() helpers, and deduplicated identical turn/cancel and session/stop handlers in agent-server/index.ts into a shared cancelAll function (-20 net lines, nesting reduced from 5 to 3 levels). * gnhf #4: Extracted groupWorkspacesByRepo helper from query-engine.ts and consolidated resolveParentBranch in git.service.ts by eliminating 3x duplicated cache-set calls and merging two structurally identical loops into one (-9 net lines, 68 insertions / 77 deletions). * fix: correct addMethod type signature to accept sync handlers and drop unnecessary async from cancelAll The addMethod signature incorrectly required Promise<unknown> return type, but 6+ handlers are synchronous. Updated to unknown | Promise<unknown> to match actual usage. Removed the async keyword from cancelAll since it doesn't await anything. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 12, 2026
…write: created a new CodexSdkTransformer that works directly with the SDK's ThreadEvent lifecycle (item.started/updated/completed), producing unified Parts alongside legacy events, with 23 new tests all passing (371 total agent-server tests).
zvadaadam
added a commit
that referenced
this pull request
Apr 12, 2026
* hmmm * gnhf #1: Created the complete unified message transformation layer: Part types in shared/messages/, Claude Code and Codex adapters in agent-server/messages/, with 29 passing tests covering text/reasoning/tool streaming, subagent tracking, compaction, and token usage — all without breaking any of the 347 existing tests. * gnhf #2: Wired the Claude adapter into the handler's streaming loop with dual-write: SDK events now produce unified Parts alongside legacy events, with new and canonical events flowing through EventBroadcaster to the backend. * gnhf #3: Wired the Codex SDK adapter into codex-handler.ts with dual-write: created a new CodexSdkTransformer that works directly with the SDK's ThreadEvent lifecycle (item.started/updated/completed), producing unified Parts alongside legacy events, with 23 new tests all passing (371 total agent-server tests). * gnhf #4: Added backend persistence for unified Parts: PartsAccumulator collects streaming parts, persistMessagePartsFinished attaches them to the last assistant message row via UPDATE (parts TEXT column), wired into the event handler with proper invalidation — 15 new tests, all 445 backend + 371 agent-server tests passing. * gnhf #5: Created MessagePartsEnvelope schema and parseMessageParts() safe parser in shared/messages/, added parts field to the shared Message type, and aligned backend persistence serialization with the shared schema — 14 new tests, all 459 backend + 371 agent-server tests passing. * gnhf #6: Wired parsed Parts into the frontend by adding partsMap (Map<messageId, MessagePartsEnvelope>) to useSessionWithMessages, SessionContext, and SessionProvider — components can now access typed Parts via useSession().partsMap for gradual adoption of the new rendering path, with TypeScript compilation and all 830 tests passing. * Unified message & parts architecture: agent-server events, backend persistence, DB schema Complete rewrite of the agent-server event model and backend persistence layer. The agent-server now emits 7 canonical lifecycle events that flow through the backend to the frontend, replacing the legacy dual-write system. ## Agent-Server (standalone event model) - 7 lifecycle events: turn.started → message.created → part.created/delta/done → message.done → turn.completed - 3 adapters (Claude Code, Codex CLI, Codex SDK) produce identical event types - Delta streaming: O(n) bandwidth — only new tokens sent, full text on done - Message boundaries: separate messages per API call (Claude: multi-message turns, Codex: single) - includePartialMessages: true for Claude SDK streaming - Turn boundary detection with turnVersion for session reuse - Debug CLI (bun run cli:agent-server) for testing both harnesses - PartEvent type in shared/agent-events.ts shared by agent-server and backend - Removed legacy sendMessage/sendError/sendStatusChanged from production code ## Backend (persistence + event forwarding) - Separate parts table (append-only, crash-safe) — one INSERT per part.done - message.created → INSERT message row; part.done → INSERT part row; message.done → UPDATE stop_reason - Zod schemas for all 7 events in AgentEventSchema - Part events forwarded to frontend via q:event WebSocket frames - Messages query JOINs parts via attachParts() - Legacy persistence functions deleted (persistAssistantMessage, persistToolResultMessage, etc.) - Backend debug CLI (bun run cli:backend) for end-to-end persistence testing - 12 integration tests verify event → DB pipeline ## Database Schema - New parts table: id, message_id, session_id, seq, type, data (JSON), tool_call_id, tool_name - messages table: added stop_reason, removed parts JSON column ## Tests 363 agent-server + 513 backend = 876 tests passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: CI failures — TypeScript errors, ESLint, e2e test, integration test skip - SessionPanel: use empty string instead of null for synthetic message content - ToolPartBlock: use createElement() instead of direct call (ComponentClass compat) - E2E test: wait for canonical session.idle/session.error instead of legacy message/queryError - Integration tests: gracefully skip when better-sqlite3 is compiled for Electron ABI Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address code review findings — TS error, lifecycle gaps, streaming overlay - Remove stop_reason from synthetic Message (TS2353 fix) - Remove dead emitMessageResult from Codex turn.completed handler - Add message.done emission to finish() in both Codex adapters - Fix streaming overlay preferring stale DB parts over live deltas - Fix synthetic message seq ordering (incrementing offset) - Forward all args in prepare-commit-msg hook - Mark stale agent memory doc as resolved Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update Codex E2E test to use canonical events instead of legacy The Codex E2E test was still waiting for legacy `message`/`queryError` notifications which are no longer emitted. Updated to wait for canonical `session.idle`/`session.error` events, matching the Claude E2E test. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update agent-server event model memory — remove stale findings All previously documented issues have been resolved. Rewrote to reflect current architecture: canonical lifecycle events, backend persistence, known patterns. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zvadaadam
added a commit
that referenced
this pull request
Apr 14, 2026
…both agent handlers, extracted helper replacing 5 identical repo-lookup patterns in repos.ts, unified duplicate git progress push functions, and removed dead export — net reduction of 23 lines across 7 files with all 825 tests passing.
zvadaadam
added a commit
that referenced
this pull request
Apr 14, 2026
* gnhf #1: Extracted two helper methods in claude-adapter.ts (closeActiveParts, accumulateStreamDelta) to eliminate 5 repeated close-text/close-thinking call sites and 2 duplicate 25-line streaming delta handlers; also replaced a duplicate 15-line formatTime function in WorkspaceItem.tsx with the existing shared formatTimeAgo utility — net reduction of 49 lines with all 375 agent-server tests passing. * gnhf #2: Extracted duplicate workspace-grouping logic (85 lines across query-engine.ts and workspaces.ts route) into shared lib/workspace-grouping.ts, and consolidated duplicate parameter-reading helpers (readString/readNumber across query-engine.ts and commands.ts) into shared lib/query-params.ts — net reduction of 41 lines with all 825 tests passing. * gnhf #3: Removed unused parameter from cancellation functions across both agent handlers, extracted helper replacing 5 identical repo-lookup patterns in repos.ts, unified duplicate git progress push functions, and removed dead export — net reduction of 23 lines across 7 files with all 825 tests passing. * gnhf #4: Removed 5 dead exports/functions and un-exported 2 internal-only functions across 6 files — net reduction of 112 lines with all 825 tests passing. * gnhf #5: Removed 2 dead exported functions (getRepoInitials, getRepoColor), un-exported 3 internal-only symbols (RECENT_PROJECT_LIMIT, resolveGitProjectRoot, setLastOpenInAppId), and replaced duplicate timeAgo in AccessSection.tsx with shared formatTimeAgo — net reduction of 41 lines across 5 files with all 825 tests passing. * gnhf #6: Un-exported 14 dead Zod schema validators (6 from shared/events.ts, 8 from shared/agent-events.ts), un-exported 6 dead type aliases from shared/events.ts, and consolidated duplicate parseGitHubRepo function from gh.service.ts and deus-import.ts into shared/lib/github.ts — reducing public API surface by 20 exports and eliminating 1 duplicate function across 5 files with all 825 tests passing. * gnhf #7: Deleted 2 dead component files (OpenInDropdown 214 lines, EmptyState 39 lines), removed 3 dead API type definitions (ApiResponse, PaginatedResponse, WorkspaceQueryParams) from shared/types/api.ts, removed 4 dead session type aliases (SessionMessageEvent, SessionErrorEvent, SessionEnterPlanModeEvent, SessionStatusEvent) from shared/types/session.ts, and cleaned up 3 barrel re-export files — net reduction of 330 lines across 7 files with all 825 tests passing. * gnhf #8: Deleted 2 dead platform files (updates.ts 31 lines, listenerGroup.ts 38 lines), removed dead function from dialog.ts, removed the entire dead StatusChanged notification pipeline across 5 files (method, schema, type, constant, test builder, union), un-exported from electron barrel, and cleaned up 3 barrel re-export files — net reduction of 121 lines across 11 files with all 825 tests passing. * gnhf #9: Removed 3 dead query hooks (useStats, useUncommittedFiles, useLastTurnFiles) with their stub service methods and query keys, removed 4 dead type definitions (ChangedFilesResult, BranchInfo, PaginationParams, DevServer) and their barrel re-exports, un-exported internal-only connectToRelay function, and cleaned up 2 dead barrel re-exports (clearToken, ConnectionIllustration) — net reduction of 121 lines across 12 files with all 825 tests passing and clean tsc. * gnhf #10: Removed 6 dead visual effect builder functions (98 lines) from visual-effects.ts, un-exported 5 internal-only symbols (resolveClaudeDir, getAgentConfig, StatusPriority, StatusConfig, WorkflowStatusConfig), and removed dead barrel re-exports (createAgentEventHandler, AgentEventHandler) from agent/index.ts — net reduction of 98 lines across 5 files with all 825 tests passing and clean tsc. * gnhf #11: Consolidated inline path validation in files.ts to use shared resolveWorkspaceRelativePath from git.service.ts, and replaced 10 hand-rolled readString+throw param validation patterns in commands.ts with the existing requireParam utility — net reduction of 17 lines across 2 files with all 825 tests passing and clean tsc. * gnhf #12: Removed 211 lines of dead CSS from global.css: the entire glitch-swap effect system (6 classes, 6 @Keyframes, 2 media queries) and the empty tool-use-enter class — none referenced by any component, with all 825 tests passing. * gnhf #13: Deleted 2 dead component files (RepoGroup.tsx 102 lines, WorkspaceItem.tsx 123 lines) from repository/ui that were never rendered anywhere, removed 14 dead barrel re-exports across 4 barrel files (repository/ui, sidebar/ui, sidebar feature, session/ui/blocks), and cleaned up knip.json — net reduction of 242 lines across 7 files with all 825 tests passing and clean tsc. * gnhf #14: Deleted the dead agent-server/messages/index.ts barrel (30 lines), removed 4 dead type exports from shared/messages/types.ts (ToolLocation, ToolOutputContent, PartType, PartTypeSchema), removed dead ToolResultMap type from chat-types.ts, and cleaned up 15 dead barrel re-exports across 4 barrel files (session/hooks, session/ui, workspace/ui, shared/hooks) — net reduction of 51 lines across 8 files with all 825 tests passing and clean tsc. * gnhf #15: Removed 10 dead type aliases from shared/agent-events.ts, un-exported 2 dead Zod schemas from shared/enums.ts, removed the dead useWindowFocus hook and its useSyncExternalStore infrastructure (50 lines) from useWindowFocus.ts, and removed dead BaseToolRendererProps barrel re-export — net reduction of 62 lines across 4 files with all 825 tests passing and clean tsc. * refactor: extract backend helpers and fix typecheck * Address CodeRabbit review feedback * Fix Claude adapter message handoff
zvadaadam
added a commit
that referenced
this pull request
May 31, 2026
…both agent handlers, extracted helper replacing 5 identical repo-lookup patterns in repos.ts, unified duplicate git progress push functions, and removed dead export — net reduction of 23 lines across 7 files with all 825 tests passing.
zvadaadam
added a commit
that referenced
this pull request
May 31, 2026
…write: created a new CodexSdkTransformer that works directly with the SDK's ThreadEvent lifecycle (item.started/updated/completed), producing unified Parts alongside legacy events, with 23 new tests all passing (371 total agent-server tests).
zvadaadam
added a commit
that referenced
this pull request
May 31, 2026
…ngine.ts by extracting pushSnapshot() and pushWorkspaceDelta() helpers, and deduplicated identical turn/cancel and session/stop handlers in agent-server/index.ts into a shared cancelAll function (-20 net lines, nesting reduced from 5 to 3 levels).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Reviewing the collapsed sidebar, the spacing between repository items felt too close, impacting visual separation and aesthetics.
Changes
src/components/app-sidebar.tsxto increase the vertical gap between repository items in the collapsed sidebar.gap-1togap-2(from 4px to 8px). This provides more breathing room between each repository squircle, improving scannability and overall visual balance.Testing
Greptile Overview
Updated On: 2025-10-17 23:12:32 UTC
Greptile Summary
This PR implements a comprehensive sidebar design update with the primary focus on improving repository item spacing in the collapsed sidebar (gap-1 to gap-2, from 4px to 8px). However, the changes extend far beyond the simple spacing adjustment described in the PR description. The PR introduces a complete sidebar component architecture using shadcn/ui patterns, adds new UI components (Avatar, TextShimmer, Collapsible), integrates Framer Motion for animations, and refactors the Dashboard component to use the new AppSidebar system. The changes also include infrastructure updates like modifying .gitignore to exclude package-lock.json, updating Tailwind config with shimmer animations, and adding comprehensive design specifications. This represents a significant migration towards a more professional design system inspired by Linear, Vercel, and similar modern applications, aligning with the project's goal of achieving "beautiful aesthetic design of a pro consumer product."
Important Files Changed
Changed Files
Confidence score: 3/5
Context used:
dashboard- CLAUDE.md (source)Summary by CodeRabbit
New Features
UI Changes
Documentation