Commit graph

12 commits

Author SHA1 Message Date
yoniebans
25f4ba7b3c Merge remote-tracking branch 'origin/main' into feat/desktop-remote-ssh-current
# Conflicts:
#	apps/desktop/electron/connection-config.test.ts
#	apps/desktop/electron/connection-config.ts
#	apps/desktop/electron/main.ts
2026-07-21 10:16:01 +02:00
Brooklyn Nicholson
fb0c6d9ee1 fix(desktop): de-dupe cross-window cues so peers don't spam
With multiple full windows, each renderer independently reacts to the
same backend event, so one-shot cues fired N times: OS notifications
(the per-renderer throttle can't see other windows), the turn-end sound
(playCompletionSound runs on every message.complete, ungated by focus),
and auto-spoken replies (double voice when a chat is open in two windows).

Add a single race-free owner in the main process (electron/event-dedupe.ts):
main handles IPC serially, so the first window to claim a key within a
short window wins and peers stay quiet. Notifications collapse at the
hermes:notify choke point; the sound and spoken replies claim via a new
hermes:ambient:claim IPC (keyed by session / reply id). Off Electron the
claim falls back to "emit", preserving single-window behavior.

The sound's mute check runs before the claim so a muted window can't win
the cue and silence an audible peer.
2026-07-20 18:33:14 -05:00
Brooklyn Nicholson
a90ca7fe34 feat(desktop): wire New Window to ⌘⇧N + command palette
Repoint session.newWindow (⌘⇧N) from the compact new-session pop-out to
openNewWindow(), which opens a full peer instance via the new openWindow
bridge, and add a "New Window" entry to the ⌘K palette (shown with its
hotkey hint, gated on canOpenNewWindow()). Relabel the action "New window".

Drops the retired openNewSessionWindow bridge and the vestigial
isNewSessionWindow()/new=1 flag; renames the shared opener helper.
2026-07-20 18:02:48 -05:00
yoniebans
578374675e Merge origin/main into feat/desktop-remote-ssh-current
Sync with main after the contribution-shell refactor (#60638) and the backendConnectionState extraction (#65885) landed. Seven conflicts, all resolved in favor of main's new architecture with the SSH lifecycle ported on top:

- electron/main.ts: adopt backendConnectionState (attempt tokens, attachProcess, clearPromiseForAttempt) as the sole owner of the primary backend; drop the branch's raw hermesProcess/connectionPromise globals and commitConnectionFailure call site. SSH liveness-streak classification, teardown, and the SSH quit path are layered onto the new ownership model; before-quit combines SSH transactional teardown with the Windows sandbox marker (#38216).
- desktop-controller.tsx: deleted on main; its SSH beforeConnectionSwitch cleanup (preserved-route fresh draft, overlay return-route reset, project-tree reset, close-all-terminals) moves to contrib/wiring.tsx's useGatewayBoot call.
- use-session-actions/index.ts: keep main's onFreshDraftRouteIntent (fires unconditionally); preserveRoute gates only the navigate.
- gateway-settings.tsx: keep main's acceptSavedConfig/connectedCloudUrl; every save/sign-in/sign-out success path routes through acceptSavedConfig with the branch's stale-async seq guards intact.
- boot-failure-reauth.ts: keep both sshFailureMessage and main's isRemoteReauthFailure formatting.
- Both test harnesses take the union of props.

Validation: tsc -b clean; desktop suite 1704 passed / 1 skipped; electron SSH/connection modules 225 passed; python SSH + web_server suites 508 passed.
2026-07-20 22:46:39 +02:00
Brooklyn Nicholson
9399839dd4 feat(desktop): keep-computer-awake toggle + System settings section
Add a "keep computer awake" toggle (Claude-style) for long/overnight runs:
the renderer owns the device-local pref and mirrors it to the Electron main
process, which holds a single `powerSaveBlocker('prevent-app-suspension')` —
the same authority split as translucency. Surfaced as a statusbar quick-toggle
and a Settings row.

Introduce a dedicated System settings section (device-local machine prefs) and
de-crowd Appearance by moving Window Translucency + UI Scale into it (both are
main-process/window-owned, not visual theme). Give Haptic Feedback its first
Settings home there too (the titlebar quick-toggle stays). Relocated i18n copy
into `settings.system` across en/zh/zh-hant/ja; wired the `system` route into
the SettingsView union + allowlist + nav.
2026-07-20 11:50:22 -05:00
yoniebans
195d4557fc feat(desktop): add SSH to Gateway settings and recovery
Expose typed SSH discovery IPC, compose SSH alongside Local, Cloud, and Remote URL modes, preserve embedded recovery and soft switching, add stable host selection, status identity, first-contact trust disclosure, and four-locale copy.
2026-07-16 15:18:09 +02:00
Brooklyn Nicholson
10fbade64b feat(desktop): electron — openDir IPC + ⌘W menu bridge (tabs, not windows) 2026-07-13 17:57:54 -04:00
ethernet
6f7ee72be5 feat(desktop): base-branch picker for new worktree dialog
The sidebar "New worktree" button branched off whatever HEAD you were
on — now a filterable Popover+Command combobox lets you pick any local
or remote-tracking branch as the base, defaulting to origin/HEAD.

Backend listBaseBranches() queries refs/heads + refs/remotes via
for-each-ref, flags origin/HEAD (falling back to the local default for
no-remote repos). Mirrored on the Python REST API side
(base_branch_list + /api/git/base-branches route).
2026-07-13 14:53:34 -04:00
Brooklyn Nicholson
1a3b220651 fix(desktop-terminal): reopen terminal tabs in the last-used directory
A reopened tab restarted the shell in its original launch dir, so the fresh
prompt showed the wrong folder after a prior `cd` (the issue's "separate
thing" note). Track the shell's working directory and restart the PTY there.

Two independent signals feed a persisted per-tab restoreCwd:
- a main-side PTY cwd probe (shell-agnostic; /proc on Linux, lsof on macOS;
  Windows has no cheap per-process query so it falls back to the launch dir)
- cwd-reporting OSC sequences parsed in the renderer (OSC 7 file URIs, OSC 9;9
  ConEmu/Windows-Terminal paths) for shells configured to emit them

On relaunch the fresh shell boots in restoreCwd, falling back to the launch
cwd (then home) when it no longer exists.
2026-07-12 02:49:26 -04:00
Brooklyn Nicholson
b3bde1fbee feat(desktop): soft gateway switch + gateway-settings polish
Switching connection mode (local / cloud agent / remote) no longer
full-window-reloads into the cold-boot CONNECTING screen. The primary
backend is torn down in place (no renderer reload); the shell + Settings
stay up while session lists are wiped so sidebar skeletons retrigger, then
the socket re-dials and config/sessions refresh. Cold-boot CONNECTING
latches off after the first successful boot; the intentional teardown
suppresses the backend-exit toast. Dev affordance: a "Preview soft switch"
button under Gateway diagnostics (Electron has no ?query= entry).

Gateway settings UI brought in line with the rest of Settings:
- Mode cards use the shared selectableCardClass on an equal-height
  auto-rows-fr grid, stacking 1→3 (never an orphaned 2+1); titles wrap
  instead of truncating.
- Remote gateway's auth detail moves into a ? tooltip in the title; drop
  the redundant "connects to the one you choose" from the cloud card.
- textStrong buttons force px-0 so the underline sits flush with the label.
- Tooltip chip uses box-decoration-break: clone so the background hugs each
  wrapped line (bg only on the text), capped at max-w-64.

Fully i18n'd (en + zh; ja/zh-hant inherit via defineLocale).
2026-07-10 02:57:02 -05:00
Ben
c101207b99 feat(desktop): Hermes Cloud connection mode — one sign-in, agent discovery, silent connect
Adds a third "Hermes Cloud" gateway mode to the desktop app: one portal
sign-in auto-discovers the agents on your account and connects to any of
them with no second interactive prompt.

- Electron: widen connection mode to 'local' | 'remote' | 'cloud', routed
  through a centralized modeIsRemoteLike() so every resolution site treats
  cloud exactly like remote; portal discovery (GET /api/agents over the
  OAuth partition), Privy-cookie liveness, multi-org picker (NAS 409), and a
  silent per-agent /oauth cascade (load protected root, not /login).
- Persist a cloudOrg on the cloud block; unselect cloud on mode switch.
- Renderer: Hermes Cloud ModeCard + agent picker (signed-out/loading/empty/
  list), org picker, Change-org, connected-highlight + Connected pill.
- i18n (en + zh full; ja/zh-hant inherit via defineLocale), Cloud icon.
- IPC: hermes☁️{status,login,logout,discover,agent-sign-in}.

Salvage of #55402 onto current main: the original branch predates the
desktop electron .cjs -> .ts migration (39d09453f), so the electron half
was re-authored against the .ts files. Authorship preserved.

cloud-auto-discovery Phases 3 + 4.
2026-07-10 01:37:43 -05:00
ethernet
39d09453f9 feat(desktop): ts-ify everything 2026-07-08 16:24:16 -07:00
Renamed from apps/desktop/electron/preload.cjs (Browse further)