Skip to content

Add embedded workspace terminal#1099

Closed
franksong2702 wants to merge 11 commits intonesquena:masterfrom
franksong2702:franksong2702/embedded-workspace-terminal
Closed

Add embedded workspace terminal#1099
franksong2702 wants to merge 11 commits intonesquena:masterfrom
franksong2702:franksong2702/embedded-workspace-terminal

Conversation

@franksong2702
Copy link
Copy Markdown
Contributor

@franksong2702 franksong2702 commented Apr 26, 2026

Thinking Path

Hermes WebUI needs a power-user path for running quick workspace commands without leaving the active conversation. The feature is useful only if it preserves the chat workflow instead of turning the composer into a crowded control strip.

This PR originally explored a composer-adjacent terminal. After Aron’s Discord feedback and the UI/UX philosophy doc, the implementation pivoted:

  • no permanent terminal icon in the composer primary row
  • /terminal is the V1 entry point
  • the terminal renders as a separate conversation-pane utility window, visually similar to the approval-card layer
  • the card can expand, collapse into a dock, or close completely
  • terminal output stays outside chat history and model context by default

UI/UX Alignment

This follows the direction in Aron’s UI/UX philosophy:

  • Keep primary surfaces quiet: the title bar, sidebar session rows, message lines, and composer row do not get another always-visible control.
  • Use progressive disclosure: /terminal keeps the feature reachable without making every user see it all the time.
  • Show detail where detail belongs: terminal output lives in a dedicated workspace utility surface, not as transcript content.
  • Separate concerns: the terminal is neither an assistant message nor a composer footer extension. It is a conversation-pane utility window that sits near the composer because it supports the current conversation’s workspace.
  • Preserve mobile/narrow-surface discipline: V1 avoids adding another small unlabeled icon to the crowded composer row.

Alternatives considered and rejected:

  • Permanent composer toolbar button: too much pressure on an already crowded primary surface.
  • Full panel below the composer: visually reads as a composer attachment and weakens separation of concerns.
  • Transcript message/card: misleading, because terminal output is not conversation history.
  • Topbar/sidebar entry: potentially valid later, but broader than V1 and not clearly session/workspace scoped.

What Changed

  • Adds a /terminal slash command that opens the workspace terminal.
  • Adds backend PTY endpoints for terminal lifecycle:
    • start
    • input
    • output streaming
    • resize
    • close
  • Adds an xterm.js-powered frontend terminal surface.
  • Opens the shell in the active session workspace through the trusted workspace resolution path.
  • Adds terminal actions:
    • Clear
    • Copy output
    • Restart
    • Collapse
    • Expand
    • Close
  • Adds a collapsed dock state so users can keep a running terminal without leaving the full terminal window open.
  • Adds bounded desktop resizing for the expanded terminal card.
  • Reserves transcript/composer space so the terminal does not cover the latest assistant response during command/chat alternation.
  • Keeps terminal output independent from chat history. V1 does not auto-send output to the composer or transcript.
  • Adds theme and locale coverage for the new terminal UI.
  • Adds service-worker coverage for the new terminal module.

Visual Validation Notes

The latest local visual pass covered these states:

  1. Slash-command entry: typing /te shows /terminal as a command option without adding a permanent composer icon.
  2. Expanded terminal: the terminal appears as a narrower conversation-pane utility window, slightly behind/above the composer, with Clear / Copy output / Restart / Collapse / Close actions.
  3. Command output: commands such as ls and pwd render inside the xterm surface with readable dark-theme output.
  4. Collapsed dock: the terminal can collapse into a compact dock attached above the composer, with explicit Expand and Close actions.

Why It Matters

  • Power users can run quick workspace commands without switching to an external terminal and manually cd-ing into the active workspace.
  • The terminal stays tied to the current conversation workspace, which makes the selected workspace more actionable.
  • The UI remains restrained: the feature is available on demand, not permanently visible.
  • The transcript remains clean because shell output is not automatically inserted into model context.

Technical Notes

  • The backend uses a per-session PTY process instead of subprocess.run, so prompts, ANSI output, interactive programs, and resize behavior work like a real shell.
  • Terminal environment setup is per process and does not mutate global os.environ.
  • Output streams over SSE and is written into xterm on the frontend.
  • Restart ignores stale output events from the previous terminal instance.
  • Close releases the PTY. Collapse only hides the expanded surface and keeps the terminal available.
  • The frontend refits xterm after open, resize, collapse/expand, and theme changes.
  • xterm assets remain pinned CDN assets with SRI, matching the app’s no-build-step architecture.

Verification

Passed:

node --check static/terminal.js static/i18n.js static/commands.js static/ui.js static/messages.js static/workspace.js static/sessions.js static/panels.js static/boot.js
pytest -q tests/test_embedded_workspace_terminal.py tests/test_approval_card_layering.py tests/test_workspace_panel_session_list.py tests/test_mobile_layout.py tests/test_chinese_locale.py::test_chinese_locale_covers_english_keys tests/test_korean_locale.py::test_korean_locale_matches_english_key_coverage tests/test_russian_locale.py::test_russian_locale_covers_english_keys tests/test_spanish_locale.py::test_spanish_locale_covers_english_keys
git diff --check origin/master...HEAD

Result:

60 passed

Additional verification already performed during the PR iteration:

  • focused terminal and approval-card tests passed
  • locale key coverage failures introduced by the terminal strings were fixed
  • local browser/manual validation covered open, command execution, collapse, expand, resize, and close
  • user visual testing confirmed the final expanded and collapsed states behave as expected

Full-suite note:

  • The documented pytest tests/ -v --timeout=60 command could not run in this local environment because the pytest-timeout plugin is not installed here.
  • A fallback full-suite run was executed earlier. It exposed PR-related locale coverage gaps, which are now fixed. The remaining failures were in unrelated model resolver, redaction, and CSRF areas and were not changed in this PR.

Risks / Follow-ups

  • This adds a browser-accessible shell for trusted workspaces, so the security boundary should be reviewed carefully.
  • V1 does not include terminal tabs, persisted terminal history, or terminal-output-to-chat insertion.
  • A future explicit “send terminal output to chat” action can be discussed separately, but this PR intentionally keeps terminal output out of model context.
  • If Hermes later introduces a formal secondary composer row or workspace command center, the entry point can move there without changing the PTY foundation.

Model Used

  • OpenAI GPT-5 via Codex desktop
  • Coordinator/worker workflow with local shell verification and user manual visual testing

@nesquena nesquena added hold ux User experience / visual polish labels Apr 26, 2026
@franksong2702 franksong2702 marked this pull request as ready for review April 27, 2026 06:33
@aronprins
Copy link
Copy Markdown
Contributor

Still discussing this in discord <3

@franksong2702 franksong2702 force-pushed the franksong2702/embedded-workspace-terminal branch from b787771 to 20cb351 Compare April 28, 2026 15:11
@franksong2702
Copy link
Copy Markdown
Contributor Author

franksong2702 commented Apr 28, 2026

Visual review notes

I updated the implementation to match the conversation-pane / approval-card direction discussed with Aron.

The screenshots cover four states:

  1. Slash command entry/terminal appears in the command menu when typing /te, so the feature is discoverable without adding another permanent composer-row icon.
截屏2026-04-28 22 42 40
  1. Expanded terminal window — the terminal opens as a separate conversation-pane utility window, slightly narrower than the composer and visually tucked behind it, with Clear / Copy output / Restart / Collapse / Close controls.
截屏2026-04-28 22 42 56
  1. Terminal output — workspace commands render inside the xterm surface, keeping shell output separate from the chat transcript.
截屏2026-04-28 22 43 13
  1. Collapsed dock — Collapse keeps the running terminal attached above the composer with explicit Expand and Close actions, so users can keep context without a full terminal window occupying the pane.
截屏2026-04-28 22 43 24

This is the intended V1 interaction model: reachable on demand, visually separated from the transcript, and not competing with the composer’s primary controls.

@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Hold — awaiting @aronprins UX sign-off

Thanks for the updates, @franksong2702! The implementation direction looks great and the visual updates are appreciated.

We're currently waiting for explicit UX approval from @aronprins before this can proceed to technical review. The last Discord discussion (April 27) noted this was still being discussed.

@aronprins — once you've had a chance to review the updated screenshots and implementation direction, please post an approval comment here when you're happy with the UX approach. We'll proceed with the full technical review immediately after.

@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Merged in v0.50.237 via #1243. Thank you @franksong2702! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold ux User experience / visual polish

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants