feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: allow selecting terminal shell on Windows - #6073

Closed
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select
Closed

feat: allow selecting terminal shell on Windows#6073
mohamedmastouri-hue wants to merge 1 commit into
pingdotgg:mainfrom
mohamedmastouri-hue:feature-shell-select

Conversation

@mohamedmastouri-hue

@mohamedmastouri-huemohamedmastouri-hue commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes issue #123. Adds a setting to select terminal shell on Windows.


Note

Medium Risk
Changes how every terminal session picks its shell at spawn time; wrong resolution or incomplete settings wiring could break terminal startup on Windows.

Overview
Prepares terminal shell selection on Windows by resolving the preferred shell asynchronously when a PTY session starts, instead of reading it synchronously at manager construction time.

shellResolver is now an Effect (tests can still inject Effect.succeed(...)). resolveShellCandidates takes a resolved preferredShell string; startSession runs yield* shellResolver on each spawn so a user-configured shell can be read from settings at launch. Existing Windows fallback order (custom choice → pwsh.exe → Windows PowerShell → ComSpec / cmd) is unchanged.

The diff also adds a ServerSettingsService import (not wired in this hunk) and is largely formatting across Manager.ts.

Reviewed by Cursor Bugbot for commit 8150931. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add terminal shell selector for Windows in General settings

  • Adds a WindowsTerminalShellRow component to the General settings panel, visible only on Windows, letting users pick their preferred terminal shell from a predefined list.
  • Persists the selection as windowsTerminalShell in ServerSettings (defaults to empty string) and supports reset to default.
  • Adds a "Terminal shell" entry to the settings search index.
  • The TerminalManagerOptions.shellResolver type changes from a synchronous function to an Effect.Effect<string>, evaluated at session start to resolve the preferred shell.
  • stopProcess no longer immediately marks a session as exited; cleanup is now deferred until the process exit event is observed via drainProcessEvents.
📊 Macroscope summarized 8150931. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 86794a3a-9506-446e-940e-04b50b4c964e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 10, 2026

@macroscopeappmacroscopeappBot 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.

Two Effect service convention issues in apps/server/src/terminal/Manager.ts: the new serverSettings.ts import uses a named service import (and is never used/wired), and the shellResolver option was switched to an Effect without updating existing callers.

Posted via Macroscope — Effect Service Conventions

import { ServerSettingsService } from "../serverSettings.ts";

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.

At a service boundary the local service module should be imported as a namespace (ServerSettings.ServerSettingsService), not as a named import. This import is also currently unused — production make() never does yield* ServerSettings.ServerSettingsService, so the new windowsTerminalShell setting is never fed into shellResolver and the dependency is not reflected in make/layer requirements. Consider either wiring it up or dropping the import.

-import { ServerSettingsService } from "../serverSettings.ts";+import * as ServerSettings from "../serverSettings.ts";

Posted via Macroscope — Effect Service Conventions

shellResolver?: Effect.Effect<string, never, never>;

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.

Changing this seam from () => string to an Effect leaves existing consumers on the old shape: apps/server/src/terminal/Manager.test.ts still declares shellResolver?: () => string (line 205) and passes thunks (lines 1287, 1344, 1482), which no longer type-check against this option. Consider updating those callers mechanically (e.g. shellResolver: Effect.succeed("/bin/zsh")) as part of this change.

Posted via Macroscope — Effect Service Conventions

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

const baseEnv = options.env ?? process.env;
const shellResolver =
options.shellResolver ??
Effect.succeed(defaultShellResolver(platform, baseEnv));

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.

Terminal shell setting unused

High Severity

ServerSettingsService is imported but never used, and make() never passes a shellResolver that reads windowsTerminalShell. Production terminals always fall back to defaultShellResolver, so the Windows shell setting persists in UI/settings but has no effect on spawned PTYs.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 8150931. Configure here.

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.

🟡 Medium

changedSettingLabels reads settings.windowsTerminalShell but the useMemo dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add settings.windowsTerminalShell to the dependency array.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 654:
`changedSettingLabels` reads `settings.windowsTerminalShell` but the `useMemo` dependency array omits it. When the user changes only the terminal-shell setting, the memo stays stale, so the restore-defaults control fails to include "Terminal shell" in the confirmation until another listed dependency changes. Add `settings.windowsTerminalShell` to the dependency array.

const settings = usePrimarySettings();
const updateSettings = useUpdatePrimarySettings();

if (

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.

🟡 Mediumsettings/SettingsPanels.tsx:1887

WindowsTerminalShellRow gates visibility on navigator.platform (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets null and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/settings/SettingsPanels.tsx around line 1887:
`WindowsTerminalShellRow` gates visibility on `navigator.platform` (the client's browser OS), but the setting configures the connected server's terminal. A user on macOS/Linux browsing to a Windows server gets `null` and never sees the shell selector, and a user on Windows connected to a non-Windows server sees a control that doesn't apply. Visibility should be driven by the server platform, not the browser platform.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. This PR introduces a new terminal shell selection feature for Windows, which is a new user-facing capability requiring human review. Additionally, unresolved findings indicate the feature is incomplete - the shell setting is persisted in the UI but is not wired up to actually affect terminal spawning.

You can customize Macroscope's approvability policy. Learn more.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

#5268 is the retained shell setting implementation and limits choices to shells reported by the connected host. This Windows-only branch adds a much larger shell parser without focused tests, so it has no unique behavior to keep.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotggt3dotgg closed this Aug 28, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mohamedmastouri-hue@t3dotgg