Skip to content

feat(dashboard): multi-panel workspace with terminal, inline diffs, and mentions#291

Merged
alexk-dev merged 13 commits intomainfrom
feat/webui-ide-improvement
Apr 17, 2026
Merged

feat(dashboard): multi-panel workspace with terminal, inline diffs, and mentions#291
alexk-dev merged 13 commits intomainfrom
feat/webui-ide-improvement

Conversation

@alexk-dev
Copy link
Copy Markdown
Owner

@alexk-dev alexk-dev commented Apr 15, 2026

Summary

Turns the dashboard into a unified workspace that combines files, chat, and terminal in one flow.

  • adds a new Workspace page with resizable editor, chat, and terminal panels
  • adds integrated terminal support over /ws/terminal with multi-tab terminal sessions
  • adds multi-session workspace chat with keyboard navigation between chat tabs
  • adds IDE-focused agent affordances: inline diff review, file @ mentions, and /run <cmd> handoff into terminal
  • adds backend and frontend support required for the workspace UX, plus unit and Playwright coverage for the new flows

alexk-dev and others added 4 commits April 15, 2026 16:12
…nd mentions

Turn the dashboard into a unified workspace that brings Files, multi-session
Agent Chats, and an integrated terminal together in a single resizable layout,
and layer agent-facing IDE affordances on top.

- Add pty-backed terminal WebSocket endpoint (TerminalSession/TerminalConnection)
  and wire xterm.js TerminalPane + TerminalTabs on the frontend.
- Introduce WorkspacePage with react-resizable-panels, persisted layout via
  workspaceLayoutStore, Ctrl+` terminal toggle, and multi-session chat tabs
  powered by chatSessionStore + useChatSessionHotkeys.
- Ship @-mention file autocomplete in ChatInput driven by getFileTree, inline
  accept/reject for proposed edits via @codemirror/merge (proposedEditStore +
  InlineDiffView + ProposedEditsPanel), and a /run command in ChatWindow that
  routes into the active terminal tab through terminalStore.
- Forward ideStore.openedTabs and activePath as chat turn context from
  chatRuntimeMessageActions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Terminal backend:
- TerminalConnection: replace waitFor(1 day) with exit-wait strategy
  that loops until the pty actually terminates
- TerminalSessionLimiter: new per-user lease tracker backing the
  terminal feature flag, concurrency cap, idle timeout, and max
  session duration
- TerminalWebSocketHandler: gate on bot.dashboard.terminal.enabled,
  acquire a lease per connection, apply idle timeout via Flux.timeout
  and absolute cap via Flux.take, release lease in doFinally
- BotProperties: add DashboardProperties.terminal with enabled,
  maxSessionsPerUser, idleTimeout, maxSessionDuration

Terminal frontend:
- TerminalPane: consolidate duplicated sendInputChunk logic and
  subscribe to terminalStore with a selector so unrelated state
  changes no longer re-drain pending input
- terminalStore: wrap with subscribeWithSelector middleware

File mentions:
- useFileMentions: replace eager full-tree fetch with a shallow
  initial load and lazy per-directory subtree loading, deduped via
  fetched/in-flight refs
- fileMentions: rewrite flattenFileTree as O(n) push/pop traversal

Tests added for every behavior above (red->green) including race-free
lease release assertions via short polling loop.
- TerminalSessionLimiter: acquire/release via ConcurrentHashMap.compute
  so the bin lock serializes concurrent acquire and release. Lease uses
  AtomicBoolean for idempotent double-release and delegates decrement
  back to the limiter, which now evicts the user entry when the last
  lease is released (added trackedUserCount() for test visibility).
- ExitWatcher: extracted from TerminalConnection into its own daemon
  helper with a dedicated ExitWatcherTest, eliminating the nullable
  TerminalSession and the test-only openWithStrategy seam.
- TerminalConnection: drop null-session guards now that the exit-wait
  loop lives in ExitWatcher; emitExit is suppressed after close.
- BotProperties.TerminalProperties: default enabled=true (override via
  BOT_DASHBOARD_TERMINAL_ENABLED or bot.dashboard.terminal.enabled) and
  document that idle timeout is measured on inbound frames only.
- useFileMentions: remove dead fetchedDirsRef.add('').
- TerminalWebSocketHandlerTest: document why awaitLeaseReleased polls.

Red->green tests:
- shouldEvictUserEntryWhenAllLeasesReleased
- shouldTreatDoubleReleaseAsIdempotentUnderConcurrency (32 threads)
- ExitWatcherTest.shouldLoopUntilStrategySignalsTermination
- ExitWatcherTest.shouldSuppressExitCallbackWhenStoppedBeforeTermination
- ExitWatcher.start() guarded by an AtomicBoolean so a redundant
  second call is a no-op instead of IllegalThreadStateException.
- TerminalSessionLimiter.releaseSlot() simplified to decrementAndGet
  now that double-release is CAS-gated at the Lease level.
- TerminalSessionLimiter.tryAcquire() cap-rejected branch returns
  the locally-held counter for clarity.
- BotProperties.TerminalProperties.enabled javadoc now calls out the
  production security posture (disable unless browser-shell access is
  an explicit requirement).
- ExitWatcherTest adds a red-to-green idempotent-start test and
  hardens the stop-before-exit assertion into a 300ms polling window.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
alexk-dev added a commit that referenced this pull request Apr 15, 2026
Tracks the TDD-driven phases behind PR #291: multi-session chat tabs,
the three-pillar workspace (files / chats / terminal), inline diff
review, and file-mention autocomplete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tracks the TDD-driven phases behind PR #291: multi-session chat tabs,
the three-pillar workspace (files / chats / terminal), inline diff
review, and file-mention autocomplete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@alexk-dev alexk-dev force-pushed the feat/webui-ide-improvement branch from bd614e8 to 4ed3694 Compare April 15, 2026 22:00
@sonarqubecloud
Copy link
Copy Markdown

@alexk-dev alexk-dev merged commit fa5b739 into main Apr 17, 2026
22 checks passed
@alexk-dev alexk-dev deleted the feat/webui-ide-improvement branch April 17, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants