Skip to content

Commit 8714585

Browse files
authored
Merge pull request #28 from semantic-developer/feature/sd-30
adjusted functionality and documentation around windows WSL usage
2 parents 03f8fb5 + eeabcbb commit 8714585

File tree

5 files changed

+145
-86
lines changed

5 files changed

+145
-86
lines changed

README.md

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ A cross‑platform desktop UI (Avalonia/.NET 8) for driving the Codex CLI app se
88
- Start a Codex session and stream assistant output in real time
99
- Send user input that is wrapped as protocol `Submission`s (app server)
1010
- Auto‑approve exec/patch requests (automatic)
11-
- Select a Codex profile (from `config.toml`) and load MCP servers from a JSON config
11+
- Pick a model (built-in or from `config.toml` profiles) and load MCP servers from a JSON config (see [Windows setup](README.windows.md) for a WSL recipe)
1212
- Keep multiple Codex sessions active at once using the tabbed header (each tab title shows its live status, e.g., `Session 2 – thinking…`)
1313
– See live token usage and estimated context remaining in the header
1414

@@ -23,37 +23,26 @@ A cross‑platform desktop UI (Avalonia/.NET 8) for driving the Codex CLI app se
2323

2424
## Platform Setup & CLI Modes
2525

26-
Semantic Developer can drive the Codex CLI from Linux, macOS, or Windows. On Windows you can choose to run Codex natively or through WSL; toggle this at runtime in **CLI Settings → Use WSL**.
26+
Semantic Developer can drive the Codex CLI from Linux, macOS, or Windows.
2727

2828
### Linux
2929

3030
- Install the .NET 8 SDK and the Codex CLI in your Linux environment.
3131
- Profiles live under `~/.codex/config.toml`; prompts under `~/.codex/prompts/`.
3232
- MCP config file: `~/.config/SemanticDeveloper/mcp_servers.json`.
33-
- Leave **Use WSL** off (Linux builds interact with the native tooling directly).
3433

3534
### macOS
3635

3736
- Install .NET 8 (e.g., `brew install dotnet-sdk`) and the Codex CLI (`brew install codex` or the official installer).
3837
- Profiles/prompts: `~/.codex/config.toml` and `~/.codex/prompts/`.
3938
- MCP config file: `~/Library/Application Support/SemanticDeveloper/mcp_servers.json`.
40-
- Keep **Use WSL** off; the CLI launches natively on macOS.
4139

42-
### Windows (native CLI)
40+
### Windows
4341

42+
- RECOMMENDED see [Windows setup](README.windows.md) recipe
4443
- Install the Windows .NET 8 SDK and Codex CLI for Windows, ensuring `codex.exe` is on your Windows `PATH`.
4544
- Profiles/prompts default to `%USERPROFILE%\.codex\config.toml` and `%USERPROFILE%\.codex\prompts\` (respect `CODEX_HOME` if set).
4645
- MCP config file: `%AppData%\SemanticDeveloper\mcp_servers.json`.
47-
- Leave **Use WSL** unchecked—MCP commands and the Codex process execute as Windows binaries, so use Windows paths in `mcp_servers.json`.
48-
49-
### Windows (Codex inside WSL)
50-
51-
- Install the Codex CLI inside your WSL distribution along with any MCP servers you want to run (for example `pip install`, `npm install`, etc.).
52-
- In **CLI Settings** enable **Use WSL**. When checked:
53-
- The Codex CLI and MCP servers launch through `wsl.exe`, so command paths in `mcp_servers.json` should be Linux paths (for example `~/.local/bin/mcp-atlassian`).
54-
- Profiles/prompts remain in the WSL home (`~/.codex/config.toml`, `~/.codex/prompts/`). The app bridges to them automatically.
55-
- The MCP configuration file stays on the Windows side (`%AppData%\SemanticDeveloper\mcp_servers.json`); only the command execution happens in WSL.
56-
- Leave **Use WSL** on only when the Codex CLI is installed in WSL. Disable it if you want to run the Windows binaries instead.
5746

5847
## Build & Run
5948

@@ -70,18 +59,17 @@ Semantic Developer can drive the Codex CLI from Linux, macOS, or Windows. On Win
7059
2. Click “Restart Session” to launch `codex app-server` in the workspace directory (a session also starts automatically after you select a workspace).
7160
3. Type into the input box and press Enter to send. Output appears in the right panel.
7261
4. “CLI Settings” lets you change:
73-
- Profile (from Codex `config.toml`) — passed via `-c profile=<name>`
74-
- `config.toml` path: `$CODEX_HOME/config.toml` (defaults to `~/.codex/config.toml`)
75-
- Default model & reasoning effort
62+
- Model & reasoning effort
7663
- Before a session starts, the picker loads from `SemanticDeveloper/SemanticDeveloper/models.json` so you can choose models offline. Keep this file updated as Codex releases new entries.
77-
- Once a session is running the dialog refreshes with the live catalog. Configured profiles from `config.toml` are appended and marked with an asterisk; selecting a profile disables the reasoning picker and lets the profile decide the model/effort.
64+
- When the app connects to Codex, the dialog refreshes with the live catalog.
65+
- Any profiles defined in `config.toml` (e.g., `$CODEX_HOME/config.toml`, defaulting to `~/.codex/config.toml`) are appended to the list and marked with an asterisk (`*`). Selecting a profile locks the reasoning controls and lets the profile determine the model/effort.
66+
- Profiles are optional—if you don’t have one, simply pick a built-in model.
7867
- Verbose logging (show suppressed output)
7968
- Enable MCP support (loads MCP servers from your JSON config and passes them directly to Codex)
8069
- MCP config locations:
8170
- Linux: `~/.config/SemanticDeveloper/mcp_servers.json`
8271
- macOS: `~/Library/Application Support/SemanticDeveloper/mcp_servers.json`
8372
- Windows: `%AppData%\SemanticDeveloper\mcp_servers.json`
84-
- When **Use WSL** is enabled, keep the config file in the Windows location above but supply Linux paths in the `command`/`cwd` fields—the app relays each server through WSL.
8573
- Use API Key for Codex CLI (pipes the key to `codex login --with-api-key` before sessions; does not rely on existing CLI auth)
8674
- Allow network access for tools (sets sandbox_policy.network_access=true on turns so MCP tools can reach the network)
8775
- Without API key enabled, the app proactively authenticates with `codex auth login` (falling back to `codex login`) before sessions so your chat/GPT token is used.
@@ -98,6 +86,8 @@ Semantic Developer can drive the Codex CLI from Linux, macOS, or Windows. On Win
9886

9987
### Profiles (config.toml) example
10088

89+
If you define profiles in `config.toml`, Semantic Developer surfaces them in the model picker (marked with `*`) alongside the built-in catalog. They’re entirely optional—the app works out of the box with the bundled models.
90+
10191
Example `config.toml` profiles:
10292

10393
```toml
@@ -275,7 +265,7 @@ Selection behavior:
275265
## Project Layout
276266

277267
- `SemanticDeveloper/` — App source (UI, services, models).
278-
- `proto-reference/`Rust protocol reference for Codex (not built by this project). Includes MCP/client protocol shapes.
268+
- `Installers/`Installer projects for Linux, Mac OS and Windows - untested as of yet...
279269

280270
## Notes
281271

README.windows.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Semantic Developer on Windows via WSL2 + WSLg
2+
3+
The recommended Windows setup runs both the Codex CLI and Semantic Developer inside WSL2 so you get a consistent Linux environment while still launching the Avalonia UI through WSLg. The steps below assume Windows 11 or Windows 10 22H2 (build 19045) with administrative rights.
4+
5+
## 1. Install WSL (Ubuntu)
6+
1. Open an elevated PowerShell window.
7+
2. Enable WSL + the Virtual Machine Platform:
8+
```powershell
9+
wsl --install -d Ubuntu
10+
```
11+
> If you already have WSL installed, ensure it’s version 2 (`wsl --set-default-version 2`).
12+
3. Reboot when prompted.
13+
4. Launch the new Ubuntu instance from the Start menu and create your Linux user.
14+
15+
## 2. Update packages inside Ubuntu
16+
```bash
17+
sudo apt update && sudo apt upgrade -y
18+
```
19+
20+
## 3. Install Node.js 22 (required by the Codex CLI)
21+
```bash
22+
wget -qO- https://deb.nodesource.com/setup_22.x | sudo -E bash -
23+
sudo apt install -y nodejs
24+
node --version # should print v22.x
25+
```
26+
27+
## 4. Install .NET 8 SDK
28+
```bash
29+
wget https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb
30+
sudo dpkg -i packages-microsoft-prod.deb
31+
sudo apt update
32+
sudo apt install -y dotnet-sdk-8.0
33+
34+
dotnet --info # confirm it reports .NET 8
35+
```
36+
37+
## 5. Install the Codex CLI
38+
```bash
39+
sudo npm install -g @openai/codex
40+
codex app-server --help # quick sanity check
41+
```
42+
43+
## 6. Prepare Semantic Developer
44+
1. Pick a workspace directory inside WSL (e.g., `~/code`).
45+
2. Clone or copy this repository there:
46+
```bash
47+
mkdir -p ~/code
48+
cd ~/code
49+
git clone https://github.com/semantic-developer/SemanticDeveloper.git
50+
cd SemanticDeveloper
51+
```
52+
3. Restore/build to ensure dependencies are ready:
53+
```bash
54+
dotnet build SemanticDeveloper/SemanticDeveloper.sln
55+
```
56+
57+
## 7. Enable WSLg (GUI support)
58+
WSLg ships enabled by default on Windows 11. To double‑check:
59+
Run C:\Program Files\WSL\wslsettings\wslsettings.exe and check that 'Enable GUI applications' is turned on under 'Optional Features'
60+
61+
## 8. Install X11 client libraries (required for Avalonia on some distros)
62+
Inside Ubuntu:
63+
```bash
64+
sudo apt install -y libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxrender-dev
65+
```
66+
67+
## 9. Launch Semantic Developer
68+
From Ubuntu:
69+
```bash
70+
cd ~/code/SemanticDeveloper
71+
dotnet run --project SemanticDeveloper/SemanticDeveloper
72+
```
73+
WSLg should display the Semantic Developer UI on Windows. If the window fails to appear, check `wsl --status` to confirm WSLg is running and verify the X11 libraries are installed.
74+
75+
## 10. Notes & Tips
76+
- Store Codex profiles and prompts inside the WSL home (`~/.codex/config.toml`, `~/.codex/prompts/`); Semantic Developer detects them automatically.
77+
- MCP server definitions live at `~/.config/SemanticDeveloper/mcp_servers.json` within Ubuntu.
78+
- Access Windows files from WSL using `/mnt/c/...`, but for best performance keep your workspace inside the Linux filesystem (e.g., `~/code`).
79+
- To update Codex or Node.js later:
80+
```bash
81+
sudo npm update -g @openai/codex
82+
sudo npm cache verify
83+
```
84+
- If you prefer the UI to launch quickly from Windows Terminal, create a profile that runs `wsl.exe -d Ubuntu -- cd ~/code/SemanticDeveloper && dotnet run --project SemanticDeveloper/SemanticDeveloper`.
85+
86+
Happy coding!
87+
88+
## 11. RECOMMENDED - For browser access to links directly from WSL and SemanticDeveloper
89+
- Install a browser - I like Brave
90+
```bash
91+
sudo apt update
92+
sudo apt install -y curl apt-transport-https
93+
94+
sudo curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg
95+
echo "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main" | sudo tee /etc/apt/sources.list.d/brave-browser-release.list
96+
97+
sudo apt update
98+
sudo apt install -y brave-browser
99+
100+
# test it
101+
brave-browser
102+
```

SemanticDeveloper/SemanticDeveloper/MainWindow.axaml.cs

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Runtime.CompilerServices;
66
using Avalonia.Controls;
77
using Avalonia.Interactivity;
8-
using Avalonia.Threading;
98
using SemanticDeveloper.Models;
109
using SemanticDeveloper.Services;
1110
using SemanticDeveloper.Views;
@@ -19,7 +18,6 @@ public partial class MainWindow : Window, INotifyPropertyChanged
1918
private SessionTab? _selectedSession;
2019
private int _sessionCounter = 0;
2120
private AppSettings _sharedSettings;
22-
private bool _profileCheckPerformed;
2321

2422
public MainWindow()
2523
{
@@ -146,43 +144,6 @@ private void OnOpenReadmeClick(object? sender, RoutedEventArgs e)
146144
private void OnPropertyChanged([CallerMemberName] string? name = null)
147145
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
148146

149-
protected override void OnOpened(EventArgs e)
150-
{
151-
base.OnOpened(e);
152-
Dispatcher.UIThread.Post(async () => await EnsureProfilesConfiguredAsync());
153-
}
154-
155-
private async Task EnsureProfilesConfiguredAsync()
156-
{
157-
if (_profileCheckPerformed)
158-
return;
159-
_profileCheckPerformed = true;
160-
161-
try
162-
{
163-
var profiles = CodexConfigService.TryGetProfiles();
164-
if (profiles.Count > 0)
165-
return;
166-
167-
var info = new InfoDialog
168-
{
169-
Title = "Add a Codex Profile",
170-
Message = BuildNoProfileMessage()
171-
};
172-
173-
await info.ShowDialog(this);
174-
175-
if (SelectedSession is not null)
176-
{
177-
await OpenCliSettingsAsync(SelectedSession);
178-
}
179-
}
180-
catch (Exception ex)
181-
{
182-
Debug.WriteLine($"Failed to prompt for profile setup: {ex.Message}");
183-
}
184-
}
185-
186147
private async Task OpenCliSettingsAsync(SessionTab session)
187148
{
188149
var updated = await session.View.ShowCliSettingsDialogAsync(_sharedSettings);
@@ -198,21 +159,6 @@ private async Task OpenCliSettingsAsync(SessionTab session)
198159
}
199160
}
200161

201-
private static string BuildNoProfileMessage()
202-
{
203-
var baseMessage = "No Codex CLI profiles were found in ~/.codex/config.toml.\n\nCreate a profile under [profiles.<name>] with the model you want to use, for example:\n\n[profiles.default]\nmodel = \"gpt-5-codex\"\nmodel_provider = \"openai\"\n\napproval_policy = \"never\"\nmodel_reasoning_effort = \"high\"\nmodel_reasoning_summary = \"auto\"\n\nAfter you add a profile, select it in CLI Settings so sessions know which model to run.";
204-
205-
var source = CodexConfigService.LastProfileSource;
206-
var error = CodexConfigService.LastProfileError;
207-
if (string.IsNullOrWhiteSpace(source) && string.IsNullOrWhiteSpace(error))
208-
return baseMessage;
209-
210-
var diagnostics = "\n\nDiagnostics:\n" + (string.IsNullOrWhiteSpace(source) ? " • Source: (unknown)" : $" • Source: {source}");
211-
if (!string.IsNullOrWhiteSpace(error))
212-
diagnostics += $"\n • Error: {error}";
213-
return baseMessage + diagnostics;
214-
}
215-
216162
private async Task CloseSessionAsync(SessionTab tab)
217163
{
218164
if (!_sessions.Contains(tab))

SemanticDeveloper/SemanticDeveloper/Views/AboutDialog.axaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
x:Class="SemanticDeveloper.Views.AboutDialog"
77
Width="420"
88
Height="420"
9+
MinWidth="420"
10+
MinHeight="420"
911
WindowStartupLocation="CenterOwner"
1012
CanResize="False"
1113
SystemDecorations="Full"

SemanticDeveloper/SemanticDeveloper/Views/CliSettingsDialog.axaml

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,48 @@
5353
</ComboBox.ItemTemplate>
5454
</ComboBox>
5555
</StackPanel>
56-
<CheckBox Content="Verbose logging (show suppressed content)" IsChecked="{Binding VerboseLoggingEnabled, Mode=TwoWay}"/>
56+
<CheckBox Content="Verbose logging (show suppressed content)"
57+
IsChecked="{Binding VerboseLoggingEnabled, Mode=TwoWay}"
58+
HorizontalAlignment="Stretch"
59+
Margin="0,0,24,0"/>
5760
<Separator/>
5861
<StackPanel>
59-
<CheckBox Content="Use API Key for Codex CLI" IsChecked="{Binding UseApiKey, Mode=TwoWay}"/>
62+
<CheckBox Content="Use API Key for Codex CLI"
63+
IsChecked="{Binding UseApiKey, Mode=TwoWay}"
64+
HorizontalAlignment="Stretch"
65+
Margin="0,0,24,0"/>
6066
<TextBlock Text="API Key" Margin="0,8,0,4"/>
6167
<TextBox Text="{Binding ApiKey, Mode=TwoWay}"
6268
PasswordChar=""
6369
Watermark="Enter API key"
6470
ToolTip.Tip="When enabled, the app pipes your key to 'codex login --with-api-key' before sessions"
65-
MaxWidth="550"/>
66-
<TextBlock Margin="0,6,0,0" Foreground="#888" FontSize="12" Text="Stored in settings.json. When enabled, the app authenticates with your key and does not rely on existing CLI login." MaxWidth="550" TextWrapping="Wrap"/>
71+
HorizontalAlignment="Stretch"
72+
Margin="0,0,24,0"/>
73+
<TextBlock Margin="0,6,24,0" Foreground="#888" FontSize="12" Text="Stored in settings.json. When enabled, the app authenticates with your key and does not rely on existing CLI login." TextWrapping="Wrap"/>
6774
</StackPanel>
6875
<Separator/>
6976
<StackPanel>
70-
<CheckBox Content="Enable MCP support (load servers from config)" IsChecked="{Binding McpEnabled, Mode=TwoWay}"/>
71-
<TextBlock Margin="0,4,0,6" Foreground="#888" FontSize="12" Text="Loads MCP servers from mcp_servers.json in your app data folder and passes them directly to Codex." MaxWidth="550" TextWrapping="Wrap"/>
77+
<CheckBox Content="Enable MCP support (load servers from config)"
78+
IsChecked="{Binding McpEnabled, Mode=TwoWay}"
79+
HorizontalAlignment="Stretch"
80+
Margin="0,0,24,0"/>
81+
<TextBlock Margin="0,4,24,6" Foreground="#888" FontSize="12" Text="Loads MCP servers from mcp_servers.json in your app data folder and passes them directly to Codex." TextWrapping="Wrap"/>
7282
<StackPanel IsEnabled="{Binding McpEnabled}">
73-
<CheckBox Content="Allow network access for tools (MCP, web fetches)" IsChecked="{Binding AllowNetworkAccess, Mode=TwoWay}"/>
74-
<TextBlock Margin="0,4,0,6" Foreground="#888" FontSize="12" Text="Enables outbound network for tool calls (e.g., MCP servers) by setting sandbox_policy.network_access=true on turns." MaxWidth="550" TextWrapping="Wrap"/>
83+
<CheckBox Content="Allow network access for tools (MCP, web fetches)"
84+
IsChecked="{Binding AllowNetworkAccess, Mode=TwoWay}"
85+
HorizontalAlignment="Stretch"
86+
Margin="0,0,24,0"/>
87+
<TextBlock Margin="0,4,24,6" Foreground="#888" FontSize="12" Text="Enables outbound network for tool calls (e.g., MCP servers) by setting sandbox_policy.network_access=true on turns." TextWrapping="Wrap"/>
7588
<TextBlock Text="MCP Results" FontWeight="SemiBold"/>
76-
<CheckBox Content="Show MCP results in log" IsChecked="{Binding ShowMcpResultsInLog, Mode=TwoWay}"/>
77-
<CheckBox Content="Only show when not editing (auto)" IsChecked="{Binding ShowMcpResultsOnlyWhenNoEdits, Mode=TwoWay}"/>
78-
<TextBlock Margin="0,4,0,0" Foreground="#888" FontSize="12" Text="When enabled, the app surfaces top results (titles + URLs) for search-like tools. During code-editing turns, it suppresses unless disabled." MaxWidth="550" TextWrapping="Wrap"/>
89+
<CheckBox Content="Show MCP results in log"
90+
IsChecked="{Binding ShowMcpResultsInLog, Mode=TwoWay}"
91+
HorizontalAlignment="Stretch"
92+
Margin="0,0,24,0"/>
93+
<CheckBox Content="Only show when not editing (auto)"
94+
IsChecked="{Binding ShowMcpResultsOnlyWhenNoEdits, Mode=TwoWay}"
95+
HorizontalAlignment="Stretch"
96+
Margin="0,0,24,0"/>
97+
<TextBlock Margin="0,4,24,0" Foreground="#888" FontSize="12" Text="When enabled, the app surfaces top results (titles + URLs) for search-like tools. During code-editing turns, it suppresses unless disabled." TextWrapping="Wrap"/>
7998
</StackPanel>
8099
</StackPanel>
81100
</StackPanel>

0 commit comments

Comments
 (0)