Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: OpenSource03/harnss
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.21.5
Choose a base ref
...
head repository: OpenSource03/harnss
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.22.0-beta.1
Choose a head ref
  • 7 commits
  • 358 files changed
  • 2 contributors

Commits on Mar 20, 2026

  1. feat: progressive chat rendering, deferred mount, and diff viewer con…

    …solidation
    
    Improve chat performance with progressive hydration (render bottom rows
    first, hydrate older rows in background batches), deferred content mount
    (shows spinner for one frame to avoid UI freeze on session/space switch),
    and smarter scroll-to-bottom locking that respects user intent.
    
    Consolidate LightDiffViewer into DiffViewer with Monaco-based rendering
    and fix measurement timing via settle delays for hideUnchangedRegions.
    Add chat-ui-state context for persisting expand/collapse state across
    re-renders. Optimize MessageBubble with CSS containment, lazy syntax
    highlighting, and extracted ToolCall/ToolGroupBlock rendering.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude committed Mar 20, 2026
    Configuration menu
    Copy the full SHA
    a83c2aa View commit details
    Browse the repository at this point in the history
  2. fix: default allowPrereleaseUpdates to false

    Pre-release updates were opted-in by default during beta. Now that
    stable releases are available, default to false so users only receive
    stable updates unless they explicitly enable pre-release in settings.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude committed Mar 20, 2026
    Configuration menu
    Copy the full SHA
    3ec4248 View commit details
    Browse the repository at this point in the history

Commits on Mar 21, 2026

  1. feat: native liquid glass tinting and theme-controlled appearance (#39)

    * feat: native liquid glass tinting, theme-controlled appearance, and focus veil
    
    Use electron-liquid-glass tintColor API to tint the glass material natively
    on macOS instead of CSS overlays. Switch to darkkatarsis fork which adds
    hasKeyAppearance isa-swizzle to prevent glass state change on window blur.
    
    - Add OKLCh-to-hex-RGBA color conversion utility (src/lib/color-utils.ts)
    - Add glass IPC: set-tint-color (native tint) and set-theme (nativeTheme.themeSource)
    - Sync app theme to main process so glass light/dark follows app setting, not OS
    - Bootstrap theme from localStorage in preload for correct first-frame appearance
    - Add subtle unfocused veil overlay on macOS (darken/brighten when window inactive)
    - Unify light mode glass sidebar to use dark text (same as Windows)
    - Fall back to CSS overlay tinting on non-macOS platforms
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * fix: harden glass tinting from PR review feedback
    
    - Guard clampByte against NaN/Infinity inputs (corrupted space data)
    - Validate tintColor hex format in IPC handler before passing to native
    - Fix unfocused veil transition: keep element mounted, toggle opacity
    - Align preload theme default with useSettings ("dark") to avoid flash
    - Add unit tests for oklchToHexRGBA and computeGlassTintColor
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude authored Mar 21, 2026
    Configuration menu
    Copy the full SHA
    8bc05ac View commit details
    Browse the repository at this point in the history

Commits on Apr 5, 2026

  1. Split view, chat organization, UI overhaul & refactor (#41)

    * feat: chat organization with folders, pinning, and sidebar grouping
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: unified engine picker, session record helpers, and cross-platform polish
    
    Merge model/config/effort dropdowns into a single engine picker
    dropdown alongside agent switching. Extract toChatSession() and
    buildPersistedSession() helpers to eliminate inline duplication.
    
    Fix empty folders missing in branch-grouped sidebar, sync Electron
    nativeTheme with app theme for Windows Mica, and add light-mode
    glass sidebar text overrides for macOS.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: split view with drag-to-split, resizable panes, and per-pane tool drawers
    
    Add multi-pane split view system allowing up to 4 concurrent chat
    sessions side by side. Sessions can be opened in split view via
    sidebar context menu or by dragging from sidebar onto the chat area.
    
    Each pane hosts its own engine triple (Claude/ACP/Codex) via the
    new useSessionPane hook, with independent tool drawers, scroll
    state, and permission handling. Background event routing is updated
    to skip sessions that are actively rendered in split panes.
    
    Also adds release skill for automated version bumping and GitHub
    release creation.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: tool icons, ANSI rendering, mac background effects, and chat UI polish
    
    Add tool glyph system with per-tool icons and colored/monochrome modes,
    ANSI SGR color rendering for bash output, switchable mac background
    effects (liquid glass / vibrancy / off), assistant turn duration
    dividers, diff stats on edit/write tool cards, browser per-tab color
    scheme, TodoPanel redesign with progress bar, Git panel streamlining,
    and extracted shared chat layout constants. Expand appearance settings
    with tool icon, background effect, and edit expansion options.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: worktree bar, inline space creation, and independent split pane controls
    
    Add a WorktreeBar above the composer that shows branch chips for
    switching between worktrees, with inline create/remove and
    .harnss/worktree.json setup automation.  Replace the modal
    SpaceCreator dialog with an inline sidebar draft flow and a
    SpaceCustomizer popover for editing existing spaces.
    
    Split view panes now send, stop, and control engine settings
    independently — each pane resolves its own project path, git panel,
    and permission/plan-mode state.
    
    Also: simplified macOS background effect handling (transparency toggle
    is now independent of native material), fixed chat scroll bottom
    padding via ResizeObserver on the composer, stopped fabricating a
    200k context window when the real value is unknown, added softer
    flat-layout dividers, and extracted welcome-screen logic into
    testable modules.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: ACP authentication, per-session settings persistence, and independent split pane controls
    
    Implement the ACP auth protocol (initialize → authenticate → newSession)
    with an auth dialog UI, auth-required error detection, and Cursor-specific
    guidance. Per-session effort, permissionMode, and model are now persisted
    and restored on session switch. Split panes get their own independent
    controls for model, effort, permissions, plan mode, and agent switching
    instead of being read-only mirrors. Also improves model resolution with
    family-based fallback, adds platform-aware agent store download links,
    and wraps ACP protocol calls with timeouts.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: tool docking islands system with drag-and-drop split view arrangement
    
    Replace per-pane tool drawers with a full island-based docking system.
    Tool panels can now be docked as independent islands in the top row
    (stacked vertically in resizable columns) or bottom row, dragged between
    positions, and remembered across open/close cycles. Narrow ToolPicker
    strip (48/44px) with visual side/bottom separation. Add PanelDockControls,
    PanelDockPreview, and SplitPaneToolStrip components. BrowserPanel gains
    per-persistKey session persistence across instances.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * refactor: decompose AppLayout into focused sub-components and hooks
    
    Extract ~2,350 lines from AppLayout into 5 new components
    (SplitChatPane, MainTopToolArea, MainBottomToolDock, RightPanel,
    ToolIslandContent) and 10 new hooks (useGlassTheme, usePaneController,
    useToolIslandContext, useMainToolWorkspace, useMainToolPaneResize,
    useBottomHeightResize, useToolColumnResize, useSpaceSwitchCooldown,
    useJiraBoard, useToolDragDrop). Add shared types (pane-controller,
    tool-islands) and utility modules (tool-island-utils, workspace-drag).
    Main workspace now uses the same tool island system as split view,
    replacing the old side-column/bottom-row tool placement. Add
    clean-code-refactor and refactor-analyst agent definitions.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * refactor: massive codebase restructuring — decompose god components, reorganize lib into domains, add Zustand settings store
    
    Complete refactoring pass that decomposes god components and hooks into
    focused sub-modules, reorganizes the flat src/lib/ directory into domain
    subdirectories, introduces a Zustand settings store, extracts shared
    types to canonical locations, and rewires all imports across the codebase.
    
    128 new files added, 64 old files deleted, ~150 existing files modified.
    Net result: -16,233 lines from monolithic files, code redistributed into
    focused, independently testable modules.
    
    == Component decompositions ==
    
    InputBar (1,900 → 10-line re-export shim):
      → src/components/input-bar/ (11 files): InputBar orchestrator,
        AttachmentPreview, CommandPicker + useCommandAutocomplete hook,
        ContextGauge (SVG ring + tooltip), EngineControls (per-engine
        plan/permission UI), EnginePickerDropdown (model/effort/agent/ACP
        config), MentionPicker + useMentionAutocomplete hook, constants,
        input-bar-utils with in-source vitest tests, barrel index
    
    BrowserPanel (1,010 → ~350 lines):
      → src/components/browser/ (6 files): BrowserNavBar, BrowserStartPage,
        BrowserUrlBar (shared between start page and nav bar — eliminates
        duplicated URL input), WebviewInstance, browser-types (typed
        ElectronWebviewElement interface replacing inline casts),
        browser-utils (URL resolution, history persistence, tab reordering)
    
    JiraBoardPanel (1,098 → ~300 lines):
      → src/components/jira/ (3 files): JiraBoardSetup wizard,
        JiraIssueCard with React.memo, KanbanBoard with column
        sub-component and drag-and-drop
      → src/hooks/useJiraBoardData (530 lines): all data fetching,
        column building from board config or inference, sort, drag-drop
        transition execution
    
    McpPanel (612 → ~200 lines):
      → src/components/mcp/ (4 files): AddServerDialog, McpAuthStatus
        (4-state auth with shared AuthenticateButton/ReconnectButton),
        McpServerRow, mcp-utils (transport/status display config,
        parseKeyValuePairs)
    
    AppLayout (2,316 → ~1,000 lines):
      renderSplitTopRowItem (352-line useCallback) → SplitTopRowItem
        component with module-level helpers for island rendering, stack
        entry building, and column wrapper layout
      renderSplitBottomToolIsland (113-line useCallback) →
        SplitBottomToolIsland component
      Inline tool drag state → useToolDragDrop hook
      Layout computation → useMainToolAreaLayout hook
      Resize handlers → useMainToolAreaResize hook
      Agent props → AgentContext (React context)
      Theme props → ThemeProvider (React context)
      Sidebar props restructured into grouped sub-objects
    
    AppSidebar:
      Session callbacks → SidebarActionsContext (eliminates prop drilling)
      Sessions pre-grouped by projectId in a Map (O(n) vs O(n*m))
      Settings polling (5s setInterval) → event-driven settings.onChanged
    
    ChatView:
      6 display prefs + 2 grouping props → Zustand store selectors
      Agent props → useAgentContext()
      Manual ref-based structural caching → primitive structKey string
    
    SettingsView: ~30 individual setting props → Zustand store direct reads
    WelcomeWizard: ~15 props removed → Zustand store + AgentContext
    CodexAuthDialog: rewritten with AuthDialogShell, proper event-driven
      auth (waitForLoginCompletion) replacing setTimeout(500)
    ACPAuthDialog: now uses AuthDialogShell shared component
    
    == Hook decompositions ==
    
    useAppOrchestrator (1,130 → ~400 lines):
      → src/hooks/app-layout/ (6 files):
        useAppContextualPanels — todo/agent panel auto-show
        useAppEnvironmentState — glass, notifications, dev settings
        useAppLayoutUIState — window focus, welcome, grabbed elements
        useAppSessionActions — send, model change, agent change, new chat
        useAppSpaceWorkflow — space CRUD, switching with session restore
        session-utils — buildSessionOptions, getSyncedPlanMode
    
    useSessionLifecycle (1,586 → ~400 lines):
      → src/hooks/session/ (4 new files):
        useSessionCache — LRU payload cache with idle-time prefetch
        useSessionCrud — create/switch/delete/rename/deselect/import
        useSessionRestart — ACP restart with session/load fallback,
          worktree restart across all 3 engines, full revert with SDK fork
        useSessionSettings — all setActive*/setSession* mutations
    
    New standalone hooks:
      useBrowserWebviewEvents, useClickOutside, useContextMenuPosition,
      useFolderManager, useGlassOrchestrator, useInlineRename,
      useKeyboardShortcuts, useSettingsCompat (compat bridge for
      Zustand ↔ legacy useSettings API)
    
    == Library reorganization (src/lib/ flat → domain subdirectories) ==
    
    src/lib/background/ (8 files): BackgroundSessionStore, per-engine
      handlers (claude, acp, codex), BackgroundAgentStore, agent-store-utils
    src/lib/chat/ (7 files): annotation-types, assistant-turn-divider,
      scroll, thinking-animation, todo-utils, turn-changes, virtualization
    src/lib/diff/ (3 files): diff-stats, patch-utils, unified-diff
    src/lib/engine/ (10 files): acp-adapter, acp-agent-registry,
      acp-agent-updates, acp-task-adapter, acp-utils, codex-adapter,
      permission-queue, protocol, streaming-buffer
    src/lib/layout/ (3 files): constants, split-layout, split-view-state
    src/lib/session/ (3 files): derived-data, records, space-projects
    src/lib/sidebar/ (2 files): dnd, grouping
    src/lib/workspace/ (6 files): drag, main-tool-widths, tool-docking,
      tool-groups, tool-island-utils
    src/lib/analytics/ (2 files): analytics, posthog
    src/lib/git/ (1 file): discover-repos-cache
    
    All 44 old flat src/lib/ files deleted; all imports across ~150 files
    rewired to new paths.
    
    == Zustand settings store ==
    
    src/stores/settings-store.ts (667 lines): replaces 777-line useSettings
    hook. Per-project settings keyed by projectId with stable frozen
    DEFAULT_PROJECT_SETTINGS reference (prevents infinite re-render from
    Zustand selector reference changes). Legacy localStorage migration runs
    once on first boot. Components subscribe to individual slices — changing
    theme only re-renders theme consumers, not the entire app.
    
    useSettingsCompat bridge preserves the old useSettings() API shape for
    files not yet migrated to direct Zustand selectors.
    
    == Shared types extraction ==
    
    shared/types/git.ts — GitFileStatus, GitFileChange, GitBranch,
      GitRepoInfo, GitStatus, GitLogEntry
    shared/types/settings.ts — AppSettings, NotificationSettings,
      ThemeOption, MacBackgroundEffect, PreferredEditor, VoiceDictationMode,
      CodexBinarySource, ClaudeBinarySource (eliminates 4x MacBackgroundEffect
      and 3x ThemeOption duplications across electron/renderer)
    shared/types/registry.ts — InstalledAgent, BinaryCheckResult (moved
      from electron/src/lib/agent-registry.ts)
    
    src/types/ domain split (9 new files): agents, attachments,
      engine-hook (React-dependent, moved from shared/), mcp, permissions
      (added codexRpcId field), search, session (ClaudeEffort as union
      type), spaces, tools (ToolId, PanelToolId)
    src/types/ui.ts gutted to pure re-exports
    src/types/index.ts reorganized into categorized re-export blocks
    src/types/window.d.ts — IpcResult type alias replacing ~40 inline
      signatures; Jira IPC returns now use | { error: string } unions
    
    == Electron changes ==
    
    jira.ts: ~400 lines of fetch handlers → 1-line delegates to new
      jira-client.ts; returns { error } unions instead of throwing
    json-file-store.ts: generic JsonFileStore<T> with optional safeStorage
      encryption; jira-oauth-store, jira-store, mcp-oauth-store, mcp-store
      all rewritten to use it (each ~70 lines → ~30 lines)
    settings.ts: pushes settings:changed events to renderer (replaces
      5-second polling in AppSidebar)
    claude-sessions.ts / acp-sessions.ts: McpServerInput and
      buildSdkMcpConfig imported from shared instead of duplicated;
      added stopAll() exports for graceful shutdown
    main.ts: cleanup in window-all-closed uses stopAll() instead of
      inline session iteration
    app-settings.ts: types moved to @shared/types/settings, re-exports kept
    
    == Build/config changes ==
    
    package.json: added zustand@^5.0.12, dompurify@^3.3.3, @types/dompurify
    vite.config.ts: added @shared path alias
    shared/lib/mcp-config.ts: added onWarn callback for diagnostic logging
    
    == Dead code removed ==
    
    src/components/GitPanel.tsx (2-line shim, 0 consumers)
    src/components/split/PaneToolDrawer.tsx + PaneToolTabBar.tsx
    src/hooks/useResolvedThemeClass.ts (replaced by useTheme.tsx)
    src/hooks/useTheme.ts (deleted and rewritten with ThemeProvider)
    src/lib/events.ts (constant moved to layout/constants.ts)
    Deprecated type aliases in tool-islands.ts (MainToolIsland, etc.)
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: workspace constraint system for split view and tool island resizing
    
    Add workspace-constraints module that enforces minimum widths for chat
    panes and tool panels during resize operations. Refactor split-layout,
    tool-island, and main-tool-area hooks to use centralized constraint
    logic instead of ad-hoc per-site clamping. Expand main-tool-widths with
    full test coverage for edge cases.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * fix: debounce terminal backend resizes and eliminate redundant resize IPC
    
    Add scheduleTerminalResize helper that deduplicates and debounces
    resize calls to the PTY backend, preventing resize storms during panel
    drags. Skip no-op resizes in the main process, return cols/rows from
    snapshot so xterm initializes at the correct dimensions, and subscribe
    to PTY events before awaiting snapshot to avoid missed data.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    * feat: pre-release version banner, settings store tests, and space workflow refinements
    
    Add GitHub Releases API-based pre-release detection in the main process
    with a sidebar banner prompting users to switch to stable via settings.
    Migrate organize-by-branch setting to the Zustand settings store and add
    test coverage for the settings store and space-project resolution logic.
    Refine space switching and remembered session handling across the
    orchestrator hooks.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude authored Apr 5, 2026
    Configuration menu
    Copy the full SHA
    20069d9 View commit details
    Browse the repository at this point in the history
  2. chore: bump version to 0.22.0-beta.1

    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude committed Apr 5, 2026
    Configuration menu
    Copy the full SHA
    7efb871 View commit details
    Browse the repository at this point in the history
  3. fix: update layout-constants test expectations to match current values

    TOOL_PICKER_WIDTH_ISLAND changed from 58 to 48 and
    BOTTOM_CHAT_MAX_WIDTH_CLASS from max-w-[61.5rem] to max-w-[52.5rem]
    but the test assertions were not updated.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude committed Apr 5, 2026
    Configuration menu
    Copy the full SHA
    13acc76 View commit details
    Browse the repository at this point in the history
  4. fix: skip electron-liquid-glass rebuild on non-macOS platforms

    The module uses Objective-C (objc/runtime.h) which only exists on
    macOS. On Windows/Linux, electron-rebuild now ignores it while still
    rebuilding all other native modules like node-pty.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    OpenSource03 and claude committed Apr 5, 2026
    Configuration menu
    Copy the full SHA
    06ed10b View commit details
    Browse the repository at this point in the history
Loading