Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
61cb5f7
Add code editor surface type
austinywang May 26, 2026
f0187eb
Merge remote-tracking branch 'origin/main' into issue-648-add-vscode-…
austinywang May 26, 2026
f70af7f
Fix code editor closed history title
austinywang May 26, 2026
5ed8f3c
Address code editor review feedback
austinywang May 26, 2026
254ed0d
Fix code editor directory fallback compile
austinywang May 26, 2026
2447b26
Return code editor panel id during async open
austinywang May 26, 2026
8234af7
Merge origin/main into issue-648-add-vscode-cursor-like-code-editor-as-a
austinywang Jun 6, 2026
63f4b46
Fix code editor cwd resolution
austinywang Jun 6, 2026
ba42617
Fix editor surface routing and metadata
austinywang Jun 6, 2026
c3bce0b
Fix sidebar editor surface kind
austinywang Jun 6, 2026
3821ea0
Handle code editor serve-web failures
austinywang Jun 6, 2026
0f59d90
Fix provisional editor discard test setup
austinywang Jun 6, 2026
e2304d0
Route code editor splits through folder-aware open path
austinywang Jun 6, 2026
74e3192
Guard async code editor folder navigation
austinywang Jun 6, 2026
6260a00
Align code editor labels and icons
austinywang Jun 6, 2026
09e7889
Honor code editor surface defaults
austinywang Jun 6, 2026
d28f34f
Merge remote-tracking branch 'origin/main' into issue-648-add-vscode-…
austinywang Jun 14, 2026
2322b83
Merge remote-tracking branch 'origin/main' into issue-648-add-vscode-…
austinywang Jun 14, 2026
0d93de6
chore: refresh Swift file length budget
austinywang Jun 14, 2026
cdba88c
fix: handle code editor canvas icon
austinywang Jun 14, 2026
391cd0a
fix: stabilize code editor async handling
austinywang Jun 14, 2026
8a9bfed
Merge remote-tracking branch 'origin/main' into issue-648-add-vscode-…
austinywang Jun 14, 2026
1661c10
merge: resolve conflicts with main
austinywang Jun 18, 2026
4bde2d7
fix: use raw surface kind for editor tab action
austinywang Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions .github/swift-file-length-budget.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@
# Format: max_lines<TAB>relative path
# Reduce counts as files shrink. CI fails if tracked files exceed this budget.
34475 CLI/cmux.swift
17604 Sources/AppDelegate.swift
15933 Sources/ContentView.swift
17753 Sources/AppDelegate.swift
15986 Sources/ContentView.swift
14104 Sources/TerminalController.swift
12658 Sources/Workspace.swift
12832 Sources/Workspace.swift
12115 cmuxTests/AppDelegateShortcutRoutingTests.swift
11833 Sources/GhosttyTerminalView.swift
11413 Sources/Panels/BrowserPanel.swift
11493 Sources/Panels/BrowserPanel.swift
9331 cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
7953 Sources/Panels/BrowserPanelView.swift
7356 cmuxTests/WorkspaceUnitTests.swift
7957 Sources/Panels/BrowserPanelView.swift
7434 cmuxTests/WorkspaceUnitTests.swift
7221 cmuxTests/WorkspaceRemoteConnectionTests.swift
6317 cmuxTests/SessionPersistenceTests.swift
6290 Sources/TabManager.swift
6223 cmuxTests/GhosttyConfigTests.swift
6172 Sources/TabManager.swift
6153 CLI/cmux_open.swift
6074 Sources/TextBoxInput.swift
5925 cmuxTests/TerminalAndGhosttyTests.swift
5566 Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift
5526 cmuxTests/BrowserConfigTests.swift
4516 Sources/cmuxApp.swift
4521 Sources/cmuxApp.swift
4467 Sources/Panels/FilePreviewPanel.swift
4401 cmuxTests/BrowserPanelTests.swift
4413 cmuxTests/BrowserPanelTests.swift
4225 Sources/BrowserWindowPortal.swift
4001 cmuxTests/TabManagerUnitTests.swift
3937 Sources/Feed/FeedPanelView.swift
3926 cmuxTests/TabManagerUnitTests.swift
3896 cmuxTests/WindowAndDragTests.swift
3734 Packages/iOS/CmuxMobileTerminal/Sources/CmuxMobileTerminal/GhosttySurfaceView.swift
3699 cmuxTests/CLIGenericHookPersistenceTests.swift
3397 Sources/CmuxConfig.swift
3361 cmuxTests/TabManagerSessionSnapshotTests.swift
3434 Sources/CmuxConfig.swift
3392 cmuxTests/TabManagerSessionSnapshotTests.swift
3055 Sources/Update/UpdateTitlebarAccessory.swift
2878 Sources/SessionIndexView.swift
2871 cmuxTests/CMUXOpenCommandTests.swift
Expand Down Expand Up @@ -63,11 +63,11 @@
1497 cmuxTests/OmnibarAndToolsTests.swift
1496 cmuxUITests/MultiWindowNotificationsUITests.swift
1446 Sources/FileExplorerStore.swift
1441 cmuxTests/AppDelegateIssue2907RoutingTests.swift
1426 Sources/VaultAgentProcessScanner.swift
1412 Sources/RemoteTmuxControlConnection.swift
1384 cmuxTests/KeyboardShortcutSettingsFileStoreStartupTests.swift
1380 cmuxUITests/MenuKeyEquivalentRoutingUITests.swift
1373 cmuxTests/AppDelegateIssue2907RoutingTests.swift
1366 Sources/Feed/FeedButtonStyleDebugWindowController.swift
1362 Sources/CMUXInstalledExtensionSidebarHostView.swift
1292 Packages/macOS/CmuxTerminalCore/Sources/CmuxTerminalCore/Config/GhosttyConfig.swift
Expand All @@ -88,7 +88,7 @@
1021 cmuxUITests/TerminalCmdClickUITests.swift
1006 cmuxTests/CmuxSSHURLRequestTests.swift
1000 cmuxTests/CmuxTopSnapshotScopeTests.swift
951 Sources/App/TerminalDirectoryOpenSupport.swift
958 Sources/App/TerminalDirectoryOpenSupport.swift
947 Sources/TerminalNotificationPolicy.swift
945 Sources/SessionIndexRegisteredAgents.swift
937 Sources/TextBoxMentionIndexStore.swift
Expand All @@ -105,11 +105,11 @@
859 Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Workspace/ControlCommandCoordinator+Workspace.swift
847 cmuxTests/AgentSessionAutoResumeSettingsTests.swift
845 cmuxTests/SSHStartupSignalLifecycleTests.swift
830 Sources/TaskManagerTypes.swift
833 Sources/TaskManagerTypes.swift
825 Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalComposerView.swift
818 Sources/WorkspaceContentView.swift
810 Packages/macOS/CmuxSwiftRender/Tests/CmuxSwiftRenderTests/SwiftViewInterpreterTests.swift
802 Sources/WorkspaceContentView.swift
797 Sources/ClosedItemHistory.swift
799 Sources/ClosedItemHistory.swift
779 cmuxUITests/BrowserOmnibarSuggestionsUITests.swift
774 cmuxUITests/BrowserFixtureInteractionUITests.swift
773 Sources/MainWindowFocusController.swift
Expand All @@ -124,10 +124,10 @@
746 Sources/App/MenuBarExtraController.swift
738 Packages/macOS/CMUXProjectModel/Sources/CMUXProjectModel/XcodeProjectAdapter.swift
736 Packages/Shared/CmuxAuthRuntime/Sources/CmuxAuthRuntime/Coordinator/AuthCoordinator.swift
728 Sources/TaskManagerSnapshot.swift
726 cmuxTests/CLICodexHookTimeoutRegressionTests.swift
725 Sources/RightSidebarPanelView.swift
722 Packages/Shared/CmuxAgentChat/Sources/CmuxAgentChat/Store/ChatConversationStore.swift
716 Sources/TaskManagerSnapshot.swift
715 Sources/AppleScriptSupport.swift
710 Sources/TerminalSSHSessionDetector.swift
707 CLI/CMUXCLI+AgentHookDefinitions.swift
Expand All @@ -151,8 +151,8 @@
653 Packages/macOS/CmuxBrowserImport/Sources/CmuxBrowserImport/Detection/BrowserInstalledBrowserDetector.swift
650 Sources/Panels/MarkdownRemoteImageLoader.swift
649 Sources/CmuxTopSnapshot.swift
648 Sources/TerminalController+ControlPaneContext.swift
641 cmuxTests/CommandPaletteNucleoFFITests.swift
636 Sources/TerminalController+ControlPaneContext.swift
630 Packages/macOS/CmuxSettings/Sources/CmuxSettings/Values/ShortcutWhenClause.swift
621 cmuxTests/FinderFileDropRegressionTests.swift
621 cmuxUITests/RightSidebarChromeHeightUITests.swift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ struct SurfaceInsight: Identifiable {
return "terminal"
case .browser:
return "globe"
case .codeEditor:
return "curlybraces.square"
case .markdown:
return "doc.text"
case .filePreview:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ struct TabsVisibleSidebarView: View {
return "terminal"
case .browser:
return "globe"
case .codeEditor:
return "curlybraces.square"
case .markdown:
return "doc.text"
case .filePreview:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ extension ControlCommandCoordinator {
return "ERROR: TabManager not available"
}

// Parse arguments: --type=terminal|browser --direction=left|right|up|down --url=...
// Parse arguments: --type=terminal|browser|editor --direction=left|right|up|down --url=...
var isBrowser = false
var isCodeEditor = false
var direction: ControlSidebarSplitDirectionV1 = .right
var urlRaw: String? = nil
var url: URL? = nil
Expand All @@ -157,7 +158,9 @@ extension ControlCommandCoordinator {
let partStr = String(part)
if partStr.hasPrefix("--type=") {
let typeStr = String(partStr.dropFirst(7))
isBrowser = typeStr == "browser"
let normalizedType = normalizedToken(typeStr)
isBrowser = normalizedType == "browser"
isCodeEditor = ["editor", "code", "codeeditor", "vscode", "vscodeinline"].contains(normalizedType)
} else if partStr.hasPrefix("--direction=") {
let dirStr = String(partStr.dropFirst(12))
if let parsed = ControlSidebarSplitDirectionV1.parse(dirStr) {
Expand All @@ -175,12 +178,13 @@ extension ControlCommandCoordinator {
if invalidDirection {
return "ERROR: Invalid direction. Use left, right, up, or down."
}
if isBrowser, !(browserPanelContext?.controlBrowserPanelAvailabilityEnabled() ?? true) {
if (isBrowser || isCodeEditor), !(browserPanelContext?.controlBrowserPanelAvailabilityEnabled() ?? true) {
return browserPanelOpenExternallyWhenDisabled(rawURL: urlRaw, url: url)
}

switch sidebarContext?.controlSidebarCreatePaneSplit(
isBrowser: isBrowser,
isCodeEditor: isCodeEditor,
orientationIsHorizontal: direction.isHorizontal,
insertFirst: direction.insertFirst,
url: url
Expand All @@ -204,8 +208,9 @@ extension ControlCommandCoordinator {
return "ERROR: TabManager not available"
}

// Parse arguments: --type=terminal|browser --pane=<pane_id> --url=...
// Parse arguments: --type=terminal|browser|editor --pane=<pane_id> --url=...
var isBrowser = false
var isCodeEditor = false
var paneArg: String? = nil
var urlRaw: String? = nil
var url: URL? = nil
Expand All @@ -215,7 +220,9 @@ extension ControlCommandCoordinator {
let partStr = String(part)
if partStr.hasPrefix("--type=") {
let typeStr = String(partStr.dropFirst(7))
isBrowser = typeStr == "browser"
let normalizedType = normalizedToken(typeStr)
isBrowser = normalizedType == "browser"
isCodeEditor = ["editor", "code", "codeeditor", "vscode", "vscodeinline"].contains(normalizedType)
} else if partStr.hasPrefix("--pane=") {
paneArg = String(partStr.dropFirst(7))
} else if partStr.hasPrefix("--url=") {
Expand All @@ -224,11 +231,16 @@ extension ControlCommandCoordinator {
url = urlRaw.flatMap { URL(string: $0) }
}
}
if isBrowser, !(browserPanelContext?.controlBrowserPanelAvailabilityEnabled() ?? true) {
if (isBrowser || isCodeEditor), !(browserPanelContext?.controlBrowserPanelAvailabilityEnabled() ?? true) {
return browserPanelOpenExternallyWhenDisabled(rawURL: urlRaw, url: url)
}

switch sidebarContext?.controlSidebarNewSurface(isBrowser: isBrowser, paneArg: paneArg, url: url) ?? .noTabSelected {
switch sidebarContext?.controlSidebarNewSurface(
isBrowser: isBrowser,
isCodeEditor: isCodeEditor,
paneArg: paneArg,
url: url
) ?? .noTabSelected {
case .noTabSelected, .failed:
return "ERROR: Failed to create tab"
case .paneNotFound:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,20 @@ public protocol ControlSidebarContext: AnyObject {
/// that from failure.
func controlSidebarCreatePaneSplit(
isBrowser: Bool,
isCodeEditor: Bool,
orientationIsHorizontal: Bool,
insertFirst: Bool,
url: URL?
) -> ControlSidebarPaneSplitResolution

/// Creates a `new_surface` in a pane (UUID-or-index argument, focused
/// pane otherwise).
func controlSidebarNewSurface(isBrowser: Bool, paneArg: String?, url: URL?) -> ControlSidebarNewSurfaceResolution
func controlSidebarNewSurface(
isBrowser: Bool,
isCodeEditor: Bool,
paneArg: String?,
url: URL?
) -> ControlSidebarNewSurfaceResolution

/// Closes a surface (`close_surface`; empty argument = focused surface).
func controlSidebarCloseSurface(surfaceArg: String?) -> ControlSidebarCloseSurfaceResolution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,18 @@ extension ControlSidebarContext {

func controlSidebarCreatePaneSplit(
isBrowser: Bool,
isCodeEditor: Bool,
orientationIsHorizontal: Bool,
insertFirst: Bool,
url: URL?
) -> ControlSidebarPaneSplitResolution { .failed }

func controlSidebarNewSurface(isBrowser: Bool, paneArg: String?, url: URL?) -> ControlSidebarNewSurfaceResolution {
func controlSidebarNewSurface(
isBrowser: Bool,
isCodeEditor: Bool,
paneArg: String?,
url: URL?
) -> ControlSidebarNewSurfaceResolution {
.noTabSelected
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public enum CmuxSidebarSurfaceKind: String, Codable, CaseIterable, Equatable, Se
case terminal
/// A browser surface.
case browser
/// A code editor surface.
case codeEditor
/// A markdown preview surface.
case markdown
/// A file preview surface.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public struct SurfaceKind: RawRepresentable, Hashable, Sendable {
public static let terminal = SurfaceKind(rawValue: "terminal")
/// A browser pane.
public static let browser = SurfaceKind(rawValue: "browser")
/// A code editor pane.
public static let codeEditor = SurfaceKind(rawValue: "editor")
/// A markdown preview pane.
public static let markdown = SurfaceKind(rawValue: "markdown")
/// A file (Quick Look style) preview pane.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Testing
@Test func kindStringsAreFrozenWireValues() {
#expect(SurfaceKind.terminal.rawValue == "terminal")
#expect(SurfaceKind.browser.rawValue == "browser")
#expect(SurfaceKind.codeEditor.rawValue == "editor")
#expect(SurfaceKind.markdown.rawValue == "markdown")
#expect(SurfaceKind.filePreview.rawValue == "filePreview")
#expect(SurfaceKind.rightSidebarTool.rawValue == "rightSidebarTool")
Expand Down
Loading
Loading