Skip to content

feat(app): open a local terminal - #167

Merged
TooonyChen merged 2 commits into
mainfrom
feature/local-terminal
Nov 10, 2026
Merged

TooonyChen merged 2 commits into
mainfrom
feature/local-terminal

Conversation

@TooonyChen

@TooonyChen TooonyChen commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds local terminal tabs. A local terminal runs a shell on this computer instead of connecting to a server. It uses MyGo's terminal plugin with no Conn, so it gets a pseudo-terminal on macOS and Linux and ConPTY on Windows. No new dependency.

  • Opening one: a terminal button (square-terminal, tooltip "Local terminal") sits between Options and "+" in the session list header. It opens a local terminal at the end of the list, and NoAutoSelectTab applies as it does for a new session. The start page has a "Local terminal" button too, on the page with hosts and on the empty one. It opens the terminal in that same tab. There is no shortcut.
  • Session model: Session.local and isLocal() mark a local terminal. Host stays nil and isNewTab() is false for it. Checks sit at the entry points: reconnect, duplicate, the Files/Tunnels/Processes/Network pages, the monitor, the panel corner button, openPanelTab, Tab completion and server history. execAllowed(nil) is now false, and sessionDot in the Connections tree skips sessions with no host. historyID() and target() give a local terminal its own history key and its own subtitle.
  • What it shows:
    • The row has a laptop icon in the status color where the dot would be. It is drawn in white on the selected row. The name is "Local terminal". The line under it is "This computer" or the program's OSC title.
    • Rename, Duplicate session (opens another local terminal), Disconnect, Reconnect and Close all work.
    • The command bar works and keeps its history under local (history/local.txt). Tab completes nothing and there is no server history.
    • The Commands tab and the command editor send to it.
    • The Transfers tab shows every session's transfers, as on any tab, because the queue belongs to the whole app. Retry and Open act on each transfer's own session.
    • Files, Tunnels, Processes and Network say "Not available in a local terminal".
    • The monitor shows one muted line, "Local terminal", and nothing polls.
    • There is no "Open in its own tab" button and no coding-agent icon.
  • Send to: allSessions() (All sessions) leaves local terminals out, even when the send comes from a local terminal's own bar or Commands tab. targetSessions() (Choose sessions…) lists them.
  • Exit: when the program exits, the tab shows "Exited". Reconnect, a double click on the row, or Enter in the terminal area starts it again in the same tab. If the program can't be found, the tab shows "Could not start X: error". An unclosed quote in the setting shows its own error.
  • Quit: the quit question adds a line of its own for running local terminals.
  • Setting: Options › Terminal has a new "Local terminal" section with the "Local terminal program" field (localShell, in localSettings, so it is not synced). config.SplitCommandLine is a small splitter that understands quotes. No splitter existed in the repo or the module graph. Single and double quotes work as in sh, and a backslash escapes the next character, except on Windows, where it is a literal path separator.
  • Splits: the terminal area has no split panes (splits.go is only the window's dividers), so there is nothing to split for a local terminal.
  • Header width: with three icon buttons, "Sessions (N) | Connections" was cut off at the default sidebar width. The header's icon buttons are now 20 DIPs wide, and the switch's segment padding is a little smaller. I regenerated docs/screenshots/ (main, connections, quick-connect).
  • Docs: a new "Local terminal" section in features.md, plus the Options › Terminal setting; localShell and history/local.txt in configuration.md; the new files in development.md. All in both languages, with the same headings. The README has a new "And also" bullet in both languages.

Closes #164

Testing

  • go fmt ./... (no changes), go build ./..., go vet ./..., GOOS=windows go vet ./..., GOOS=darwin go vet ., go tool mygo vet, go test -race ./...: all pass after rebasing onto main.
  • New tests in internal/app/local_test.go use a real PTY with localShell set to sh -c 'echo ready; cat'. They skip on Windows and when the terminal library can't load.
    • The header button opens a local terminal, and the NoAutoSelectTab case works. The start page entry works, on the page with hosts and the empty one.
    • The command bar sends to the shell and keeps the local history; Tab opens nothing. A quick command sends to it.
    • Every bottom tab in five layouts: Files, Tunnels, Processes and Network show the not-available text, Transfers lists another session's transfers, Commands works, and nothing polls. Retry on that session's failed transfer is disabled, because that session has no SFTP. It does not use the local tab's session.
    • The row menu: rename, duplicate, disconnect, reconnect and close.
    • When the program exits the tab shows Exited, and both the Reconnect button and Enter start it again.
    • The setting is split into words. A missing program and an unclosed quote each show their error.
    • All sessions and Choose sessions behave as described above.
    • The quit question shows its line.
    • The Options field saves what is typed.
  • internal/config/localshell_test.go tests the splitter, including the Windows cases, and that localShell is not synced.
  • Screenshots, English and Simplified Chinese, looked at and not committed (except the README ones): a local terminal on the Commands, Files and Transfers tabs, the session list header, the start page entry, and the Options setting.
  • Not tested: real Windows (ConPTY, pwsh, wsl.exe) and macOS pseudo-terminals, and the default login shell with no setting. The tests always set localShell.

🤖 Generated with Claude Code

https://claude.ai/code/session_015nMqJHsqtndDSqJDPp1qYv

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-10T01:00:20.828206Z ffee3b6 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

A local terminal is a tab whose terminal runs a program on this
computer, through MyGo's terminal plugin without a Conn: the new
Options > Terminal "Local terminal program" (localShell, per device,
split into words with quotes), else the login shell or PowerShell.

It opens from a button next to "+" in the session list's header and
from the start page. Its row, terminal, command bar (with a history of
its own), Commands tab and command editor work as a session's; the
monitor and the Files, Transfers, Tunnels, Processes and Network pages
say it has no server. It is not in "All sessions" but can be chosen.
When the program exits the tab shows Exited and Reconnect starts it
again; quitting asks about running ones.

Closes #164

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015nMqJHsqtndDSqJDPp1qYv
The Transfers tab lists every session's transfers, so it shows them on
a local terminal too; only Files, Tunnels, Processes and Network say
they are not available there. Retry and Open act on each transfer's own
session, as before.

Refs #164

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015nMqJHsqtndDSqJDPp1qYv
@TooonyChen
TooonyChen force-pushed the feature/local-terminal branch from ffee3b6 to d437330 Compare November 10, 2026 01:06
@TooonyChen
TooonyChen merged commit 7bdf605 into main Nov 10, 2026
1 check passed
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.

feat(app): open a local terminal

2 participants