Repository navigation
Open
Labels
on holdParked deliberately; not abandoned. See latest comment for resumption state.Parked deliberately; not abandoned. See latest comment for resumption state.
Description
Goal
Ship CodeShellManager on Windows, macOS, and Linux from a single codebase while preserving the current feature set (multi-PTY tabbed/grid layout, FTS5 search, alert detection, git integration, session persistence, sleep/wake, SSH remote sessions).
Three Windows-only pillars to replace
- WPF → Avalonia 11 — the entire UI layer
- ConPTY P/Invoke → Pty.Net —
Terminal/PseudoTerminal.cs - WebView2 → cross-platform terminal host — biggest unknown, needs a spike
The MVVM layer (MainViewModel, SessionViewModel) and most services (SessionManager, StateService, SearchService, ColorService, GitService, AlertDetector, OutputIndexer, AlertDetector) should port largely unchanged — they don't depend on WPF or Win32 types.
Strategy by layer
UI: WPF → Avalonia
- Avalonia 11 uses similar XAML + MVVM, though its dialect differs (no WPF
Triggers,Styleswork differently,BordervsBorderare mostly congruent). - Files to port:
MainWindow.xaml/.cs,Views/NewSessionDialog.xaml/.cs,Views/SettingsWindow.xaml/.cs. - Heavy lift:
MainWindow.xaml.cshas substantial imperative code-behind (sidebar building, layout switching, drag-reorder, search panel, dormant entries). Most of it is platform-agnostic logic that just calls into WPF visuals — port is largely mechanical. - Catppuccin hex literals carry over as-is (just
SolidColorBrushdeclarations). TrayIconis built into Avalonia — replaces the current Windows tray helper.INotifyPropertyChanged+ObservableCollection<T>work identically in Avalonia.
PTY: ConPTY → Pty.Net
- Microsoft's Pty.Net wraps ConPTY on Windows and
forkptyon Mac/Linux behind a single API. - Replace the body of
Terminal/PseudoTerminal.cs; keep the public surface stable soTerminalBridgeandOutputIndexerdon't change. - SSH support already works cross-platform — system
sshis the PTY command, nothing else to change there. - Default shell selection needs platform branching:
cmd/pwshon Windows,$SHELL(fallbackbash/zsh) on Unix.
Terminal host: WebView2 → ?
This is the riskiest part. Three candidate paths:
| Option | Pros | Cons |
|---|---|---|
| Avalonia.WebView (per-platform native web views: WebView2 / WKWebView / WebKitGTK) | Reuses existing Assets/terminal.html + xterm.js with minimal changes |
Per-platform behavior differs; transparency/font rendering may not match across all 3 |
| Photino.NET | Lighter, well-maintained, embedded native web runtime | Less Avalonia integration; would need a custom host |
| Native terminal control (port/integrate a managed xterm equivalent) | No web stack | Major undertaking; loses existing xterm.js investment |
Recommended: spike Avalonia.WebView first, fall back to Photino if blocking issues surface.
Smaller cross-platform concerns
- Default shells: detect from
$SHELL; sensible per-OS fallbacks. - State path:
%AppData%/~/Library/Application Support/~/.configviaEnvironment.SpecialFolder.ApplicationData— already works. - SQLite:
Microsoft.Data.Sqliteis already cross-platform ✓. - Windows Terminal profile import: gate behind
OperatingSystem.IsWindows()— feature is Windows-specific by nature. - Keyboard shortcuts: Avalonia's
KeyGesturehandles Ctrl ↔ Cmd mapping; revisitCtrl+T/Ctrl+W/Ctrl+Fto useMetaon macOS. - Font fallback chain: Cascadia Code → Menlo (macOS) → DejaVu Sans Mono (Linux) → generic monospace.
- Crash log path: already uses
SpecialFolder— should work unchanged. - Tray icon parity: Linux tray support varies by desktop environment (GNOME requires extensions). Treat as best-effort.
Packaging & distribution
- Windows: keep existing signed MSI + winget pipeline (
.github/workflows/winget.yml). - macOS:
.appbundle →.dmg. Requires Apple Developer cert + notarization. Distribute via Homebrew Cask. - Linux: AppImage (universal) as default; consider Flathub for desktop integration;
.deb/.rpmoptional.
CI/CD changes
.github/workflows/build.yml: matrix overwindows-latest/macos-latest/ubuntu-latest.- macOS notarization step (needs
APPLE_ID,APPLE_APP_PASSWORD,APPLE_TEAM_IDsecrets). - AppImage build step on Linux.
- New Homebrew tap workflow on
release: releasedevent. winget.ymlunchanged (Windows-only path).
Suggested phases
- Spike (~1–2 weeks) — prove the three risky pieces in isolation: Avalonia + Pty.Net + Avalonia.WebView running xterm.js with a trivial PTY echo on all 3 OSes. No feature parity, just "does the stack work."
- Avalonia port on Windows (~3–4 weeks) — full feature parity, still Windows-only build target. Validates the rewrite doesn't lose anything before adding OS surface area.
- macOS (~1–2 weeks) — cross-build, manual smoke test, signing + notarization, tray icon, fonts, shortcuts.
- Linux (~1–2 weeks) — same, plus a distro test matrix (Ubuntu, Fedora, Arch).
- CI/CD + packaging (~1 week) — multi-OS matrix, installers, release automation.
Risks
- WebView2 replacement — biggest unknown. If Avalonia.WebView falls short on perf/transparency/fonts, terminal UX may regress.
- ConPTY ↔ forkpty behavior gaps — some edge cases (resize signals, mouse modes, signals like SIGWINCH) may behave subtly differently.
- macOS notarization — first-time setup is tedious; can stall a release.
- Linux tray — GNOME parity is poor without user-installed extensions.
MainWindow.xaml.csvolume — port is mostly mechanical but there's a lot of code; risk of subtle regressions in sidebar/layout/drag-reorder logic.
Out of scope (for this issue)
- Mobile (iOS/Android).
- Web/cloud deployment.
- Rewriting search, alert, or persistence subsystems — they should port unchanged.
Metadata
Metadata
Assignees
Labels
on holdParked deliberately; not abandoned. See latest comment for resumption state.Parked deliberately; not abandoned. See latest comment for resumption state.
Activity
AThraen commentedon Jun 12, 2026
Phase 1 spike verdict: conditional GO
Spike branch:
feat/cross-platform-spike(spikes/CrossPlatformSpike/— full findings log in its README).Stack validated: Avalonia 12 + Avalonia.Controls.WebView (first-party, MIT — supersedes the community wrapper this issue suggested) + Porta.Pty (Pty.Net is not on nuget.org). Everything MIT end to end.
app.manifestwith the supportedOS GUID is mandatory or NativeWebView crashes at attach.libwebkit2gtk-4.1-0+PreferWebKitGtkInstead) is the only first-party path there. Follow-ups: retest on a native Linux desktop, test WPE on a distro that has it, file upstream, else fall back (community WebView.Avalonia / CefGlue).Recommendation: start Phase 2 (full Avalonia port, Windows-only target) now — it doesn't depend on the Linux web-view fix. Resolve Linux presentation in parallel before Phase 4.
🤖 Generated with Claude Code
AThraen commentedon Jul 27, 2026
Pushed
feat/2a-shared-core— Phase 2a (shared-core extraction) perdocs/superpowers/plans/2026-06-15-shared-core-extraction.md.Progress: Tasks 1–6 done (Core project created; Models, WPF-free Services/Terminal, ColorService, ITerminalBridge + SessionViewModel, and MainViewModel host seams all moved to
CodeShellManager.Core).Remaining: Task 7 — verify Core has zero WPF/WinForms/WebView2 references, confirm it builds standalone on a non-Windows TFM, full solution build + test run, manual smoke test, then merge back per the plan's merge commit.
Branch: https://github.com/umage-ai/CodeShellManager/tree/feat/2a-shared-core
AThraen commentedon Aug 7, 2026
⏸️ On hold as of 2026-08-07
Parking the cross-platform effort deliberately to focus on stability and bugfixes for the shipped Windows build. This is a pause, not an abandonment — the work below is intact and this comment is the resumption checklist.
Where the work actually lives
Nothing from this effort is on
main. Both phases exist only on branches. Do not delete these:feat/cross-platform-spikespikes/CrossPlatformSpike/(Avalonia 12 + Porta.Pty + NativeWebView + xterm.js)feat/2a-shared-coresrc/CodeShellManager.Core/, plus a merge of the spike branch (35f8538)cross-platformfeat/2a-shared-coreis the one that matters: 22 commits, 69 files, +2734/-52, and at time of parking only 2 commits behindmain.Phase 2a: what's done
Tasks 1–6 of
docs/superpowers/plans/2026-06-15-shared-core-extraction.md(that plan and its design spec atdocs/superpowers/specs/2026-06-12-shared-core-extraction-design.mdare themselves only on the branch).src/CodeShellManager.Core/now holds:ShellSession,AppState,SessionGroup,AlertEvent,RecentlyClosedEntry,RunCommandItem,WindowsTerminalProfileSessionManager,StateService,SearchService,ColorService,GitService,AlertDetector,ClaudeSessionService,CommandPresetsService,UpdateService,ImportExportService,SessionRunner,RunInstance,RunCommandTemplatesService,WindowsTerminalProfileService,BuiltInTerminalSchemes,SchemeMapper,CursorShapeMapper,PaddingParser,CommandLineSplitter, plus the newIDispatcher/IToastNotifierhost seamsPseudoTerminal,IPseudoTerminal,OutputIndexer, and the newITerminalBridgeseamMainViewModelandSessionViewModel, decoupled from the WPF hostNew abstractions introduced to break the WPF dependency:
IDispatcher(note:Postis a blocking UI-thread marshal — see b26c493),IToastNotifier,ITerminalBridge. New test coverage:MainViewModelSeamTests.cs.Phase 2a: the single remaining task
Task 7 — verify & merge. Never run. To resume:
CodeShellManager.Corehas zero WPF / WinForms / WebView2 referencesdotnet teston both test projectsResumption risk (the reason this note is detailed)
Corerelocated Models, Services, Terminal, and both ViewModels wholesale. Every bugfix landing onmainagainst those files while this is parked will conflict on rebase. Two consequences to plan for:feat/2a-shared-coreontomainperiodically even while parked, purely to keep the delta small.mainthat touchesTerminal/PseudoTerminal.cs,Services/*, orViewModels/*should be assumed to need re-application. In particular PR fix(pty): prefer pwsh.exe over powershell.exe in BuildCmdLine wrapper #68 (prefer pwsh.exe in BuildCmdLine) and PR feat: first-class WSL session support #65 (WSL sessions) both touch the PTY layer.Also parked by extension
AThraen commentedon Sep 6, 2026
Status:
feat/2a-shared-coreexists and is going staleRecording this here because it isn't visible from the issue and the branch is easy to lose.
Phase 2a — extracting the WPF-free core this port depends on — was started and is unmerged:
What's on it:
89da7c1a9e4b3fColorServiceWPF members and move to Core6ea76eaITerminalBridgeseam, moveSessionViewModelto Core1a62b6bMainViewModelfrom the WPF host, move to Coreb26c493IDispatcher.Postis a blocking UI-thread marshalThat's the "MVVM layer and most services should port largely unchanged" claim from this issue actually cashed out — the seams (
ITerminalBridge,IDispatcher) are the part worth not redoing.The risk is drift. Since that branch was last touched,
mainhas taken 36 commits, several of them landing directly in the files it moved —SessionViewModel(ApplyShellIntegration, #119),MainViewModel(SaveStateDebounced, #119),PseudoTerminal(HasExited, #115), plusPwshLocatorand the newSessionConfigEditor/ShellIntegrationPayloadservices. Every one of those is a rebase conflict waiting in a file that was moved wholesale.Worth deciding soon which way this goes: rebase and land the extraction as its own PR while the conflicts are still tractable, or abandon the branch and redo it later against whatever
mainlooks like then. Leaving it where it is costs more every release.The three-pillar strategy in the issue body (Avalonia 11 / Pty.Net / a cross-platform terminal host) is unaffected — no spike has been done on the WebView2 replacement, which remains the open risk.