Skip to content

fix(shell): add Fish shell integration for listening port detection - #1749

Closed
BillionClaw wants to merge 2 commits into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/listening-port-sidebar-1773831039
Closed

BillionClaw wants to merge 2 commits into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/listening-port-sidebar-1773831039

Conversation

@BillionClaw

@BillionClaw BillionClaw commented Mar 18, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1669

Adds Fish shell integration to enable listening port detection in the sidebar for Fish users. The implementation mirrors the existing Bash and Zsh integrations.

Changes:

  • Create cmux-fish-integration.fish with ports_kick, report_tty, and report_pwd functions
  • Add Fish shell detection in GhosttyTerminalView.swift
  • Set up Fish conf.d/ snippet for automatic loading via XDG_CONFIG_HOME

The port scanner hooks are triggered on fish_preexec (when a command starts) and fish_prompt (when returning to prompt), matching the behavior of the Bash/Zsh integrations.


Summary by cubic

Add Fish shell integration for listening port detection in the sidebar. Mirrors Bash/Zsh behavior and fixes #1669.

  • New Features
    • Fish script hooks fish_preexec and fish_prompt to send ports_kick, report_tty, and report_pwd (plus shell state) over the cmux socket; non-blocking with short timeouts and minimal repeats.
    • Integration loads via Fish vendor_conf.d using XDG_DATA_DIRS; we ship Resources/shell-integration/fish/vendor_conf.d/cmux.fish and set XDG_DATA_DIRS in GhosttyTerminalView.swift (no XDG_CONFIG_HOME writes).

Written for commit f128bf6. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Added Fish shell integration to enable communication between the shell and the app for directory tracking, terminal state synchronization, activity-state reporting, and periodic maintenance triggers.
    • Ensures Fish integration is discovered and loaded alongside existing shell integrations for consistent behavior.

@vercel

vercel Bot commented Mar 18, 2026

Copy link
Copy Markdown

@BillionClaw is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai

coderabbitai Bot commented Mar 18, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6721139d-bfa5-471d-8f16-1cb5a3132ea1

📥 Commits

Reviewing files that changed from the base of the PR and between 5cd876b and f128bf6.

📒 Files selected for processing (2)
  • Resources/shell-integration/fish/vendor_conf.d/cmux.fish
  • Sources/GhosttyTerminalView.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • Sources/GhosttyTerminalView.swift

📝 Walkthrough

Walkthrough

Adds Fish shell integration for cmux: a new Fish integration script communicating with the cmux UNIX socket to report TTY, activity state, ports, and working directory; a conf.d snippet to source it; and Swift-side logic to register the Fish vendor_conf.d path so the snippet is loaded.

Changes

Cohort / File(s) Summary
Fish integration script
Resources/shell-integration/cmux-fish-integration.fish
New Fish integration implementing _cmux_send, _cmux_restore_scrollback_once, state globals, _cmux_report_tty_once, _cmux_report_shell_activity_state, _cmux_ports_kick, and event handlers _cmux_preexec and _cmux_precmd to report tty, activity, ports, and cwd over CMUX socket.
Fish conf.d snippet
Resources/shell-integration/fish/vendor_conf.d/cmux.fish
Adds a conf.d file that conditionally sources the main integration script (cmux-fish-integration.fish) when CMUX_SHELL_INTEGRATION and CMUX_SHELL_INTEGRATION_DIR allow.
Shell initialization (Swift)
Sources/GhosttyTerminalView.swift
Extends shell integration logic to recognize fish, normalize env values, and prepend integrationDir/fish/vendor_conf.d into XDG_DATA_DIRS so the Fish conf.d snippet is discoverable at startup.

Sequence Diagram(s)

sequenceDiagram
    participant Fish as Fish Shell
    participant Conf as conf.d/cmux.fish
    participant Script as cmux-fish-integration.fish
    participant Socket as CMUX Socket
    participant App as cmux App

    Fish->>Conf: Source on startup
    Conf->>Script: Load integration
    activate Script
    Script->>Script: Init state & restore scrollback
    deactivate Script

    Note over Fish,App: On command start (fish_preexec)
    Fish->>Script: fish_preexec event
    activate Script
    Script->>Script: resolve tty, record cmd start
    Script->>Socket: _cmux_send(tty & ready)
    Socket->>App: deliver tty/ready
    Script->>Socket: _cmux_send(ports_kick)
    Socket->>App: trigger port scan
    deactivate Script

    Note over Fish,App: On prompt (fish_prompt)
    Fish->>Script: fish_prompt event
    activate Script
    Script->>Script: check connectivity, resolve cwd
    Script->>Socket: _cmux_send(activity state & cwd if changed)
    Socket->>App: update UI (activity/cwd)
    Script->>Socket: periodic _cmux_ports_kick if needed
    Socket->>App: maintenance port scan
    deactivate Script
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hop in fishy waters, tiny paws a-tap,
Squeaking sockets, whispering map,
TTY and ports I proudly send,
So cmux and shell can be good friends.
(— a rabbit, sending bytes with a hop ✨)

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main change and references the linked issue, but lacks testing details and omits several checklist items that are required by the template. Add a Testing section describing how the change was tested, complete the Checklist (mark items appropriately or complete missing ones), and consider requesting bot reviews.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding Fish shell integration for listening port detection, which directly addresses the PR's primary objective.
Linked Issues check ✅ Passed The implementation fully addresses issue #1669 by adding Fish shell integration with port detection hooks that mirror existing Bash/Zsh integrations, enabling listening port reporting in the sidebar.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing Fish shell integration for port detection as required by issue #1669, with no extraneous modifications present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
Resources/shell-integration/cmux-fish-integration.fish (1)

92-94: Consider extracting TTY resolution to a helper function.

The TTY resolution logic is duplicated in both _cmux_preexec (lines 74-76) and _cmux_precmd (lines 92-94). While the guard test -z "$_cmux_tty_name" ensures it only executes once, extracting this to a small helper would improve maintainability.

♻️ Optional: Extract TTY resolution helper
+function _cmux_resolve_tty_name
+    if test -z "$_cmux_tty_name"
+        set -g _cmux_tty_name (tty 2>/dev/null | string replace -r '^.*/' '')
+    end
+end
+
 function _cmux_preexec --on-event fish_preexec
-    # Resolve TTY name once
-    if test -z "$_cmux_tty_name"
-        set -g _cmux_tty_name (tty 2>/dev/null | string replace -r '^.*/' '')
-    end
+    _cmux_resolve_tty_name

     set -g _cmux_cmd_start (date +%s)

Then apply the same change in _cmux_precmd.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Resources/shell-integration/cmux-fish-integration.fish` around lines 92 - 94,
Extract the duplicated TTY resolution into a new helper function (e.g.,
_cmux_resolve_tty) that checks and sets _cmux_tty_name using the existing logic
(test -z "$_cmux_tty_name" then set -g _cmux_tty_name (tty 2>/dev/null | string
replace -r '^.*/' '')). Replace the inline blocks in both _cmux_preexec and
_cmux_precmd with a call to _cmux_resolve_tty so both functions reuse the same
implementation; keep the guard inside the helper to preserve the one-time
execution behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 3232-3241: Remove the runtime bundle writes (references to
fishConfDir, fishIntegrationContent, fishConfFile) and stop setting
XDG_CONFIG_HOME; instead prefix our integrationDir onto XDG_DATA_DIRS via
setManagedEnvironmentValue so Fish can discover vendor data, normalizing values
so empty or whitespace-only currentXdgDataDirs are treated as unset (no trailing
colons) and using "integrationDir" when nothing exists; also ensure
"XDG_DATA_DIRS" remains listed in protectedStartupEnvironmentKeys so it cannot
be overridden at startup.
- Line 3236: The current code computes currentXdgConfig using optional chaining
on FileManager.default.homeDirectoryForCurrentUser and sets XDG_CONFIG_HOME for
the Fish integration; replace this with logic that builds an XDG_DATA_DIRS value
instead (prefixing integrationDir/fish/vendor_conf.d) and do not use optional
chaining on the non-optional FileManager.default.homeDirectoryForCurrentUser
(use it directly). Before prefixing integrationDir, treat any empty or
whitespace-only env["XDG_DATA_DIRS"] value as unset so you don’t produce
malformed paths; update the environment construction where currentXdgConfig/env
is used to set XDG_DATA_DIRS (not XDG_CONFIG_HOME), and ensure XDG_DATA_DIRS
remains included in protectedStartupEnvironmentKeys so it cannot be overridden.

---

Nitpick comments:
In `@Resources/shell-integration/cmux-fish-integration.fish`:
- Around line 92-94: Extract the duplicated TTY resolution into a new helper
function (e.g., _cmux_resolve_tty) that checks and sets _cmux_tty_name using the
existing logic (test -z "$_cmux_tty_name" then set -g _cmux_tty_name (tty
2>/dev/null | string replace -r '^.*/' '')). Replace the inline blocks in both
_cmux_preexec and _cmux_precmd with a call to _cmux_resolve_tty so both
functions reuse the same implementation; keep the guard inside the helper to
preserve the one-time execution behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5464a11d-9432-4d48-b59f-da0aa5abf479

📥 Commits

Reviewing files that changed from the base of the PR and between e4ded73 and 5cd876b.

📒 Files selected for processing (2)
  • Resources/shell-integration/cmux-fish-integration.fish
  • Sources/GhosttyTerminalView.swift

Comment thread Sources/GhosttyTerminalView.swift Outdated
Comment thread Sources/GhosttyTerminalView.swift Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Sources/GhosttyTerminalView.swift">

<violation number="1" location="Sources/GhosttyTerminalView.swift:3238">
P2: Fish integration incorrectly treats `XDG_CONFIG_HOME` as colon-delimited, which can prevent `conf.d` snippet loading and break user Fish config resolution.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Sources/GhosttyTerminalView.swift Outdated
- Fish vendor_conf.d discovery uses XDG_DATA_DIRS (colon-separated), not XDG_CONFIG_HOME (single path)
- Remove runtime bundle writes; add Resources/shell-integration/fish/vendor_conf.d/cmux.fish instead
- Prefix integrationDir/fish/vendor_conf.d onto XDG_DATA_DIRS with proper normalization
- Remove XDG_CONFIG_HOME usage for Fish integration

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Sources/GhosttyTerminalView.swift">

<violation number="1" location="Sources/GhosttyTerminalView.swift:3230">
P2: Fish `XDG_DATA_DIRS` is set to `.../fish/vendor_conf.d` instead of a base data dir, breaking vendor snippet discovery and potentially overriding default vendor paths when unset.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

normalizedEnvValue(env["XDG_DATA_DIRS"]) ??
normalizedEnvValue(ProcessInfo.processInfo.environment["XDG_DATA_DIRS"])
if let currentXdgDataDirs {
setManagedEnvironmentValue("XDG_DATA_DIRS", integrationDir + "/fish/vendor_conf.d:" + currentXdgDataDirs)

@cubic-dev-ai cubic-dev-ai Bot Mar 18, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Fish XDG_DATA_DIRS is set to .../fish/vendor_conf.d instead of a base data dir, breaking vendor snippet discovery and potentially overriding default vendor paths when unset.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Sources/GhosttyTerminalView.swift, line 3230:

<comment>Fish `XDG_DATA_DIRS` is set to `.../fish/vendor_conf.d` instead of a base data dir, breaking vendor snippet discovery and potentially overriding default vendor paths when unset.</comment>

<file context>
@@ -3215,33 +3215,21 @@ final class TerminalSurface: Identifiable, ObservableObject {
+                    normalizedEnvValue(env["XDG_DATA_DIRS"]) ??
+                    normalizedEnvValue(ProcessInfo.processInfo.environment["XDG_DATA_DIRS"])
+                if let currentXdgDataDirs {
+                    setManagedEnvironmentValue("XDG_DATA_DIRS", integrationDir + "/fish/vendor_conf.d:" + currentXdgDataDirs)
+                } else {
+                    setManagedEnvironmentValue("XDG_DATA_DIRS", integrationDir + "/fish/vendor_conf.d")
</file context>
Fix with Cubic

@okuuva

okuuva commented Mar 19, 2026

Copy link
Copy Markdown

To me it seems #1528 solves this and more.

@BillionClaw

Copy link
Copy Markdown
Contributor Author

Thank you for the review and merge! Glad to help.

@BillionClaw

Copy link
Copy Markdown
Contributor Author

Closing per repository blocklist: maintainer threatened to ban. All submissions to this repo have been suspended.

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.

Listening port not displaying in sidebar

2 participants