Commit Graph

37 Commits

Author SHA1 Message Date
vasyansk 614d7fea06 Add cloud download icon and improve update UI handling
Build / Build & push landing (push) Successful in 14s
Build / Deploy to prod (push) Successful in 6s
Build / Notify Max (push) Successful in 2s
Update UI to use CloudDownload icon instead of RefreshCw
Improve error handling for update checks
Add better visual feedback for update states
Change GitHub link to RealManual repository
2026-06-15 14:36:30 +07:00
vasyansk 9db52595c7 Add update check functionality
Implement version checking and update notifications in the GUI
2026-06-15 14:23:30 +07:00
vasyansk 1b8dd9bd93 feat(app): make 'Mark all read' an icon (CheckCheck) next to the trash
Matches the clear-all trash icon; dimmed/disabled when there are no unread events.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 14:12:45 +07:00
vasyansk 5d7a80e2a2 feat(app): collapsed sidebar becomes an icon rail (keeps activity visible)
Toggling the sidebar off used to hide it entirely, losing the per-workspace
status rings. It now collapses to a 48px rail showing each workspace's
aggregate status ring (and unread dot), still clickable to switch, plus the
new-workspace button and the daemon live/offline dot. Full sidebar returns
when toggled back on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:41:05 +07:00
vasyansk f9a565a712 feat(app): clear all events from the Event Center (red trash icon)
Adds Cmd::ClearEvents + Evt::EventsCleared: the daemon drops the persistent
event log (keeping next_id monotonic), persists, and broadcasts so every
client empties its list. A red trash icon next to 'Mark all read' triggers it;
disabled when the list is empty. Threaded through proto, the daemon handler,
the Tauri bridge, and socketBridge. Includes an EventLog::clear test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:38:35 +07:00
vasyansk bcc88b6be7 fix(app): add a close (X) button to the settings modal
Esc and click-outside already closed it, but there was no visible affordance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:38:35 +07:00
vasyansk 3dc3da072c fix(app): make the bell badge click-through (number opens the log too)
pointer-events:none lets clicks/hover pass through the unread badge to the
bell button beneath, which the badge was previously swallowing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:31:47 +07:00
vasyansk cf7410b46a feat(app): version handshake — GUI restarts a stale running daemon
The daemon outlives the GUI, so after an update an OLD daemon can keep serving
the socket and the new GUI just connects to it (stale code — e.g. the missing
TERM fix). Both binaries are now stamped with the git build id (build.rs):
the daemon reports it in `health.build`, and on connect the bridge compares it
to the GUI's own SPACESH_BUILD; on mismatch it shuts the daemon down and lets
ensure_daemon respawn the bundled (matching) one. No-op for unstamped dev
builds or daemons too old to report a build. Build id is shown in Settings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 12:39:46 +07:00
vasyansk a929c166a3 feat(app): rename a workspace by double-clicking its name
Double-click a sidebar workspace name to edit it inline; Enter/blur commits
via setWorkspaceMeta({name}) (empty/unchanged is a no-op), Esc cancels. The
input stops pointer/key propagation so it doesn't trigger select or drag.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:47:21 +07:00
vasyansk 9ca0164d0b fix(app): bridge auto-reconnect so daemon restart no longer bricks the GUI
The Tauri bridge connected to the daemon once at startup and held a single
stream with no recovery: when the daemon exited (Restart/Stop, crash, or an
update), the reader emitted spacesh:disconnected and died, and every later
request went through the dead writer forever — the GUI was permanently stuck
(settings frozen, offline). Since the bridge is Rust-side state that survives
a webview reload, even Cmd+R didn't recover it.

- bridge.rs: requests now reconnect-and-retry on failure with a single-flight
  guard (generation counter) so concurrent failures collapse into one
  reconnect and never open duplicate connections; a 5s reply timeout catches
  silently-dropped connections. ensure_daemon respawns the daemon if it
  exited. On success the bridge emits spacesh:reconnected.
- App.tsx: on spacesh:reconnected, bump a connection epoch that keys
  LayoutEngine, remounting terminals so they re-attach (snapshot + live stream)
  to the restarted daemon; also reload health/config/status.
- Settings: drop the Stop button — with lazy daemon spawn any GUI request
  resurrects the daemon, so an in-GUI "stop" is contradictory. Restart now
  works end to end (shutdown → reconnect respawns → panels re-attach).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 10:22:24 +07:00
vasyansk f8d3876c68 fix(app): settings live-apply — font on open terminals, daemon uptime
- Font change now applies to already-open terminals: the WebGL renderer
  caches glyphs in a texture atlas keyed by the old font/size, so the live
  re-apply effect now calls webglAddon.clearTextureAtlas() (via a new ref)
  after updating fontFamily/fontSize, before refitting.
- Daemon uptime now reflects a restart: the Settings daemon section ticks
  every second for live uptime, and Stop/Restart trigger an onReload callback
  that re-fetches health/status in App so a restarted daemon's new
  started_at_ms is shown instead of the stale value.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 10:08:59 +07:00
vasyansk 5e6cf4d982 fix(app): settings review — startup theme default, slider/shell input UX, dedupe accents, memoize palette
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 19:10:19 +07:00
vasyansk 9ca1ff3bc5 feat(app): daemon status with Stop/Restart in settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 18:57:53 +07:00
vasyansk a2087a0de5 feat(app): settings modal — terminal, appearance, shell
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 18:34:14 +07:00
vasyansk 61c69adb17 feat(app): terminal font and xterm theme from daemon config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 09:43:38 +07:00
vasyansk 0f28be1300 feat(app): apply theme from daemon config on load and live
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 09:41:15 +07:00
vasyansk dc95381870 feat(app): CSS-variable theming with dark/light palettes and accents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 09:39:07 +07:00
vasyansk b9f46a407d feat(app): socketBridge getConfig/setConfig + config_changed 2026-06-14 09:37:45 +07:00
vasyansk a55555983b feat(app): sidebar favorites, drag-reorder, and delete-with-confirm
- FAVORITES section at the top collects pinned workspaces (removed from their
  group listing); a star toggle on each row pins/unpins via setWorkspaceMeta.
- Drag-to-reorder within a section using raw pointer events (HTML5 DnD is
  unreliable in the macOS WKWebView), with a drop-line indicator; on drop the
  section's `order` is reassigned sequentially and persisted. Cross-section
  drops are ignored (group membership unchanged).
- Trash icon on row hover opens a ConfirmDelete modal that shows the live
  terminal count and warns before terminating them, then calls close_workspace
  and re-points the active workspace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 08:56:20 +07:00
vasyansk 04ac7cdec2 fix(app): working scrollback search + stop prompt duplication on focus
Search fixes:
- TerminalView sets allowProposedApi (the search addon's match decorations
  use registerMarker/registerDecoration); without it findNext threw before
  firing results, so the counter was stuck at 0/0.
- The search bar now renders inside the panel it targets (in the header)
  instead of a global top-right overlay, so it's obvious which panel is
  searched.
- Search is anchored to the panel it was opened on (searchSurfaceId) and no
  longer follows focus — opening it in one panel and switching away no longer
  shows it open elsewhere.

Prompt duplication:
- The focus border was 1px when unfocused, 2px when focused; with border-box
  that resized the content on every focus switch, firing ResizeObserver -> fit
  -> PTY SIGWINCH and making zsh/powerlevel10k reprint its prompt. The border
  is now a constant 2px, color-only on focus.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 08:34:43 +07:00
vasyansk 58c75c71ae feat(app): GUI backlog — splitter, drag-reorder, fit, persist, modal focus
- LayoutEngine: fix splitter resize (track pointer 1:1 via delta-from-start)
  and add panel drag-to-reorder using raw pointer events with drop indicators
- TerminalView: auto-fit xterm to container via FitAddon + ResizeObserver
- App/TopBar: toggleable sidebar; persist sidebar/events collapse in
  localStorage; bell icon opens the activity log
- Wizard: new-workspace modal now grabs focus and handles keyboard
- deps: add @xterm/addon-fit

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 08:01:15 +07:00
vasyansk 89373676e8 fix(app): incremental scrollback search
Search only ran on Enter; typing merely reset the counter to 0/0, so a
visible term showed no matches until the user pressed Enter. run() now takes
an optional query override and onChange fires it on every keystroke for
search-as-you-type, while Enter/Shift+Enter still navigate matches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 08:00:45 +07:00
vasyansk 8ea680d0df docs: SP1/SP3/SP4 manual scenarios and updated limitations 2026-06-10 12:55:07 +07:00
vasyansk ac3f0886d5 feat(app): scrollback search bar (⌘F) on the focused panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 12:48:03 +07:00
vasyansk 52a502c38b feat(app): load xterm search addon + surface→addon registry 2026-06-10 12:35:41 +07:00
vasyansk daf87d3c09 feat(app): panel zoom — full-grid render + header toggle
Wire Cmd::SetZoom through Tauri bridge (set_zoom command), add zoomed
field to WorkspaceView, short-circuit LayoutEngine to render only the
zoomed panel full-grid, and toggle Maximize2/Minimize2 in panel header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 12:33:46 +07:00
vasyansk defceb1169 feat(app): real daemon health footer (live, uptime, version)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 12:09:35 +07:00
vasyansk 834d61c69a feat(app): daemon-sourced Event Center feed, read-model, bell badge
Source Event Center from daemon event_log (seed + live event/events_read push).
Unread/Errors tabs filter real EventRecord flags; bell shows numeric unread badge;
clicking an entry calls focusSurface + markEventsRead(ids). notify.ts param widened
to string so exit kind type-checks without breaking existing NOTIFY_STATES guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 08:28:35 +07:00
vasyansk 36964c9f21 feat(app): UI parity with Pencil mockup — top bar, panel cards, sidebar/event-center polish
Top bar (breadcrumb + actions + account), rounded panel cards with active
accent + rich headers, sidebar count pills/collapsible groups/daemon footer,
preset chips + scrollback pill, Event Center tabs + external-notify footer,
JetBrains Mono + Inter via @fontsource, shared theme tokens. Backend-absent
pieces are mocked (search, zoom, uptime, channels) pending SP1–SP5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 06:47:38 +07:00
vasyansk 1ecefdeb80 feat(app): Event Center, native notifications, auto-unread, state wiring in App
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 23:13:00 +07:00
vasyansk d36548ff39 feat(app): status rings on panels + sidebar aggregate badge from state events
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 23:11:46 +07:00
vasyansk c9c3ba1fcd feat(app): wire set_group/delete_group bridge commands
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 21:41:34 +07:00
vasyansk 7ec0c84685 feat(app): sidebar, preset picker, wizard, App rewired around workspaces + LayoutEngine
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 21:31:49 +07:00
vasyansk 4b88d269e3 feat(app): LayoutEngine — recursive split render, splitter resize, stopped overlay
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 21:29:26 +07:00
vasyansk ee2f7097ce feat(app): M2 layout TS types + bridge commands
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 21:28:54 +07:00
vasyansk 56893c51d0 feat(app): UDS bridge (channel/invoke/emit) + xterm.js terminal, M0 e2e works
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 20:24:57 +07:00
vasyansk 1579686fdd chore(app): scaffold tauri 2 + react + vite, window launches
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 20:22:46 +07:00