Skip to content

fix(desktop): consolidate sidebar, i18n, stale-build, session fixes#42951

Closed
OmarB97 wants to merge 27 commits into
NousResearch:mainfrom
OmarB97:pr/desktop-fixes
Closed

fix(desktop): consolidate sidebar, i18n, stale-build, session fixes#42951
OmarB97 wants to merge 27 commits into
NousResearch:mainfrom
OmarB97:pr/desktop-fixes

Conversation

@OmarB97

@OmarB97 OmarB97 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Consolidated desktop fixes — i18n, stale build detection, sidebar improvements, session management.

Changes

i18n & build

  • Add missing update copy keys (en, zh)
  • Fix TypeScript build errors in i18n
  • Detect stale build before git fetch, rebuildNeeded i18n keys

electron/main.cjs

  • Stale build detection + fork remote auto-detect for updates

Sidebar

  • Always-visible age (was hover-only)
  • Presence integration (cross-device session discovery)
  • Source labels on session rows
  • Removed deprecated device grouping/nickname system (replaced by Discord-style group chat)

Session management

  • Session actions: archive helpers, presence-aware discovery
  • Session presence hook + state cache improvements
  • Session eligibility for archive preservation

Other

  • Layout: persist cron open state, session/workspace order
  • Statusbar: backend version display
  • YOLO session support, model metadata display
  • Various: keybinds, profiles, updates overlay, model picker

Cleanup

  • Removed device-nickname.ts (device grouping deprecated)
  • Removed session-source.ts (replaced with upstream handoffOriginSource)
  • Cleaned up showDeviceBadge props throughout sidebar

Why

PR 3 of consolidated rebased set replacing the 9 overlapping PRs flagged by @austinpickett. Clean diff against current upstream/main.

Omar B added 25 commits June 9, 2026 06:40
…Live sidebar

- hermes_cli/session_presence.py: core presence records with TTL/dedup
- tui_gateway/server.py: publishes on session init/activate/activity, clears on finalize, session.presence_list RPC
- tests: 5 passing (3 unit + 2 integration)
- Desktop:  atom, useSessionPresence hook, Live sidebar section
- Sidebar: grouped by host/OS/profile/client with search filter, OS icons, This Device badge
- Styles: text-sidebar-foreground utilities for visible button text
- sidebar.tsx: base text color on menu buttons (fixes invisible labels)

Fixes #session-presence
- Remove orphaned JSX block from bad merge
- Inline Live presence section, Pinned, and Recents sections
- Live section shows at top with accent dot indicator grouped by device
- Pinned sessions in middle section
- Recents/sessions in scrollable section below
- Fixes invisible sidebar button labels (already committed)
- Fixes build failure from missing SidebarSectionsWithLive component
…ions

- Add device-nickname.ts: hostname → friendly nickname resolver
  (Omars-MacBook-Pro-3.local → Mac Pro, Taro → Taro, etc.)
- Replace profile source badges with device nickname badges on session rows
- Thread presenceBySession map through sidebar → sections → rows
- Parallelize profile DB queries with ThreadPoolExecutor
- Reduce per-profile fetch cap from 500 to 100
- Add in-flight request guard + skip autoArchive on cascade
- Remove redundant refreshSessions call in desktop-controller
…debar layout

- Fix streaming text not rendering until focus change: add 100ms
  setTimeout safety net in syncSessionStateToView as fallback when
  requestAnimationFrame is throttled (background tab, compositor stall)

- Change compression threshold default from 0.50 to 0.85 across all
  code paths (agent_init, context_compressor, config, setup, tips)
  so context compression only fires at 85% window capacity

- Sidebar: merge Live/Sessions into unified list with 2-line rows
  (device/OS context on line 2, session title on line 1)
  to fix truncation and improve visual hierarchy
…ions

- Add device-nickname.ts: hostname → friendly nickname resolver
  (Omars-MacBook-Pro-3.local → Mac Pro, Taro → Taro, etc.)
- Replace profile source badges with device nickname badges on session rows
- Thread presenceBySession map through sidebar → sections → rows
- Parallelize profile DB queries with ThreadPoolExecutor
- Reduce per-profile fetch cap from 500 to 100
- Add in-flight request guard + skip autoArchive on cascade
- Remove redundant refreshSessions call in desktop-controller
…debar layout

- Fix streaming text not rendering until focus change: add 100ms
  setTimeout safety net in syncSessionStateToView as fallback when
  requestAnimationFrame is throttled (background tab, compositor stall)

- Change compression threshold default from 0.50 to 0.85 across all
  code paths (agent_init, context_compressor, config, setup, tips)
  so context compression only fires at 85% window capacity

- Sidebar: merge Live/Sessions into unified list with 2-line rows
  (device/OS context on line 2, session title on line 1)
  to fix truncation and improve visual hierarchy
…t SQL

UI fixes:
- Increase session row min-height from 1.625rem to 2.375rem (fits two lines)
- Change items-center to items-start with self-center on dot (proper alignment)
- Increase button padding py-0.5 → py-1 (vertical breathing room)
- Increase source line top padding pt-0.5 → pt-[3px] (gap between lines)
- Show device nickname for remote sessions (from presence record)
- Show source type for local sessions (Terminal, API, Cron, etc.)
- Add srcMap for platform names (telegram, discord, slack, etc.)

Performance:
- Add covering indexes for last_active and preview subqueries
- Replace correlated subqueries in chain_max CTE with pre-aggregated msg_max CTE
- Replace correlated subquery in outer SELECT with msg_max reference
- Same optimization applied to non-recursive query path
- Group sessions by source (Terminal, Cron, Hermes Desktop, etc.)
  under PINNED and SESSIONS sections with collapsible sub-group headers
- Fix pinned section flex layout: flex-1 → flex-none to prevent
  50/50 vertical split with Sessions section
- Always render pinned section header with empty state placeholder
  instead of conditional rendering that causes layout shift
- Add source icon + label + count to sub-group headers using Codicons
- Suppress per-row source badge when inside source groups (header
  already shows the source)
- Update SessionSourceLine with full source→label mapping (tui,
  cron, desktop, api_server, telegram, discord, etc.)
- Order source groups by activity: working/active groups first,
  then alphabetically
- Add device_name column to sessions table, populated at creation time
- Device name resolution: config device.name → MeshBoard devices.json
  labels → socket.gethostname() fallback
- Expose device_name in gateway API session response
- Sidebar groups sessions by device name (ko-mac, Taro, etc.)
- Source badge still shown on each row (Terminal, Cron, Desktop)
- Toggle switches between device and workspace grouping; line 2
  adapts to avoid showing duplicate info
- Virtual session list updated with showDeviceBadge support
…le integration

- Fix MeshBoard device matching: compare by lan_hint IP, host-id
  marker file, MESHBOARD_LOCAL_HOST env var, ssh_alias (case-insensitive),
  and device id — instead of comparing platform.node() against device id
  which never matches (e.g. 'Omars-MacBook-Pro-3' != 'ko-mac')
- Add Tailscale integration as fallback: runs tailscale status --json
  and extracts self HostName
- Cross-platform IP detection: hostname -I (Linux) + ifconfig (macOS)
- Resolution chain: config.yaml device.name → MeshBoard → Tailscale → hostname
- All integrations are opt-in and gracefully degrade when unavailable
- Auto-detect fork remote in resolveUpdateTarget: when HEAD tracks
  a non-origin remote (e.g., fork/main), prefer that remote for
  update checks instead of origin/main. Prevents false 'N behind'
  notifications and protects unmerged fork PRs from being overwritten.

- Add 'remote' field to desktop update config (updates.json) alongside
  'branch'. Users can explicitly set update remote via getRemote/setRemote.

- Add hermes:updates:remote:get and hermes:updates:remote:set IPC handlers.

- Extend preload bridge with getRemote/setRemote for renderer access.

- Update TypeScript types for bridge (getBranch/setBranch now return
  remote alongside branch, plus getRemote/setRemote methods).
Sessions are grouped by device, so the device name is already the
group header. Line 2 now only shows the source/client (Terminal,
Cron, Hermes Desktop, etc.) instead of 'MacBook Pro · Terminal'.
- Add idx_sessions_sidebar composite index (archived, message_count,
  started_at DESC) to avoid full table scans on the sidebar session
  list query and auto-archive queries
- Replace list_sessions_rich(limit=100000) in archive_old_sessions
  with targeted SQL that only finds candidate IDs eligible for
  archiving — avoids materializing the entire session list through
  expensive recursive CTEs
- Add _surfaced_session_filter_sql() shared helper to ensure
  archive_old_sessions and list_sessions_rich agree on surfaced
  session definition
- Bump SCHEMA_VERSION to 16 with v16 migration for the new index

Before: list_sessions_rich(100K) on every boot walked all sessions
through recursive CTEs (seconds on large DBs)
After: targeted SQL queries using composite index (7ms on 2GB DB)
Desktop-created sessions were labeled as "tui" (terminal) instead of
"desktop", causing incorrect source attribution in the sidebar and
session history.
…eded

When source changes (merge, local edits) leave the running .app behind,
the update UI now shows an actionable 'rebuild needed' state instead
of 'all set'. The checkUpdates IPC handler compares the embedded
install-stamp commit (baked into the .app at build time) against git
HEAD. When they differ, it sets rebuildNeeded: true, which the UI
surfaces as a rebuild prompt with the same 'Update now' button flow.

Changes:
- main.cjs: compare running app stamp vs git HEAD in checkUpdates()
- global.d.ts: add rebuildNeeded? to DesktopUpdateStatus
- en.ts: new i18n strings for rebuild-needed state (3 sections)
- updates-overlay.tsx: show rebuild prompt when behind=0 & rebuildNeeded
- about-settings.tsx: show rebuild status line and Rebuild Now button
- use-statusbar-items.tsx: highlight version badge for rebuild
…dits

Move rebuildNeeded detection ahead of git fetch so it works offline
and add git diff --name-only HEAD -- apps/desktop/ to catch local
uncommitted edits that don't change the commit SHA.

Bug 1: rebuildNeeded was gated behind git fetch success. If fetch
failed (offline, unreachable remote), the function returned early
with error: 'fetch-failed' and never set rebuildNeeded.

Bug 2: Only git commit SHA was compared, so local edits were
invisible to the stale-build indicator.

Now detects stale builds in ALL scenarios:
- git pull / merge (commit SHA changes)
- git checkout / branch switch (commit SHA changes)
- local uncommitted edits (git diff shows changes)
- offline / fetch-failed (detection runs before the fetch)
…r threshold regression

When the auxiliary compression model has smaller context than the main
model's compression threshold, Hermes auto-lowers the threshold to fit
the aux model's context.  This can silently override the user's explicit
config and drag compression from 0.85 down to ~0.50.

New config option:
  compression.min_threshold: 0.0

This acts as a floor for the auto-lowered ratio.  Setting, for example,
min_threshold: 0.75 would clamp auto-lowering to at most 75% of the
main model's context, even if the aux model is smaller.  Users can set
this explicitly in config.yaml to defend their preferred threshold
across app updates or model switches (which lose the previous
per-session override).

Default 0.0 preserves current behavior for users who don't set it.
Inject usage dict into tool.start and tool.complete callbacks so the
frontend can update the context bar mid-turn instead of waiting for
message boundaries.

Changes:
- agent/tool_executor.py: construct usage dict with context stats
  (used/max/percent) in both concurrent and sequential execution paths,
  pass as usage= kwarg to tool_start/complete callbacks
- tui_gateway/server.py: accept usage kwarg in _on_tool_start/complete,
  forward to payload; update callback lambdas and preview restart callbacks
- apps/desktop: read payload.usage on tool.start/complete events,
  merge into current usage state
- cli.py, api_server.py, gateway/run.py: add **kwargs to all callback
  implementations for forward compatibility
- Remove device grouping from sidebar, flatten to simple list
- Remove 2nd line (device/source badge) from session rows
- Show right-aligned timestamps always visible (not just on hover)
- Add agent.reasoning_effort to settings enum options for 'none' value
- Pass custom_providers to get_model_context_length in gateway
- Fixes context window showing 256k instead of 131072 for custom providers
store@0.2.14 dropped tapClientResource export and requires tap@^0.6.0
which lacks ./react-shim. Pin to last compatible versions.
@OmarB97 OmarB97 requested a review from a team June 9, 2026 16:29
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have labels Jun 9, 2026
@OmarB97 OmarB97 force-pushed the pr/desktop-fixes branch from 618ac3f to ccc401d Compare June 9, 2026 16:41
@OmarB97

OmarB97 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Fork PR: OmarB97#123

# Conflicts:
#	apps/desktop/src/app/chat/sidebar/index.tsx
#	apps/desktop/src/app/chat/sidebar/session-row.tsx
#	apps/desktop/src/app/desktop-controller.tsx
#	apps/desktop/src/store/session.ts
#	scripts/release.py
@OmarB97 OmarB97 force-pushed the pr/desktop-fixes branch 2 times, most recently from 372da63 to 1d7b88b Compare June 9, 2026 17:15
- i18n: add missing update copy keys (en, zh), fix TypeScript build errors
- stale build detection: detect stale build before git fetch, rebuildNeeded
- electron/main.cjs: stale build detection + fork remote auto-detect
- sidebar: always-visible age, presence, source labels; remove device grouping
- session-row: fix timestamp overlap, vertical center alignment
- session actions: archive helpers, presence-aware discovery
- session presence hook + state cache improvements
- yolo session, session eligibility, statusbar backend version
- layout: persist cron open state; keybinds, profiles, model picker fixes
@OmarB97 OmarB97 force-pushed the pr/desktop-fixes branch from 1d7b88b to 1dff62b Compare June 9, 2026 17:22
@OmarB97

OmarB97 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Closing to recreate as a clean, focused PR with only our changes. Reopening as a single-commit branch on upstream/main to eliminate fork divergence noise.

@OmarB97 OmarB97 closed this Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants