Skip to content

Commit 360cbb2

Browse files
garthvhclaude
andcommitted
apps: 'Open Project in VS Code' — pick a folder, isolated local instance
The button opened a fixed throwaway folder in a fresh profile (a blank session). Now it prompts for a project folder (NSOpenPanel / FolderBrowserDialog) and opens THAT project in an isolated VS Code instance pointed at the shim. The --user-data-dir profile is now a stable, reused location outside any project (Application Support/ FauxClaude on mac, %LOCALAPPDATA%\fauxclaude on Windows), so it keeps the local routing and remembers its state instead of starting blank each time. Still a separate instance (env can't be injected into an already-running window), so it doesn't disturb your normal VS Code. Verified on macOS: opens the chosen project and the process carries ANTHROPIC_BASE_URL; Windows compile-checked (0 errors). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent c5542ab commit 360cbb2

2 files changed

Lines changed: 52 additions & 36 deletions

File tree

mac-app/main.swift

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ final class ShimController: ObservableObject {
4141
FileManager.default.homeDirectoryForCurrentUser
4242
.appendingPathComponent("Library/Logs/fauxclaude.log")
4343
}
44-
var vscodeWorkspaceURL: URL {
44+
// Reused VS Code profile for the local instance — stable so it isn't a blank
45+
// session each time (remembers recents/layout); kept out of any project folder.
46+
var vscodeProfileURL: URL {
4547
FileManager.default.homeDirectoryForCurrentUser
46-
.appendingPathComponent("fauxclaude-test")
48+
.appendingPathComponent("Library/Application Support/FauxClaude/vscode-profile")
4749
}
4850
var modelMapURL: URL {
4951
FileManager.default.homeDirectoryForCurrentUser
@@ -165,30 +167,35 @@ final class ShimController: ObservableObject {
165167
}
166168
}
167169

168-
// Open VS Code pointed at the shim. Claude Code (CLI or the VS Code extension)
169-
// reads ANTHROPIC_BASE_URL from its PROCESS environment — settings.json can't
170-
// redirect it — so we must launch VS Code with the env set. A dedicated
171-
// --user-data-dir makes this a separate instance that reliably inherits the
172-
// env even if VS Code is already open (extensions are shared from the default
173-
// location). The shim ignores auth, so a dummy token stands in for the login.
170+
// Open a chosen PROJECT in VS Code pointed at the shim. Claude Code (CLI or the
171+
// VS Code extension) reads ANTHROPIC_BASE_URL from its PROCESS environment —
172+
// settings.json can't redirect it — so we launch VS Code with the env set. A
173+
// dedicated (reused) --user-data-dir keeps this a separate, isolated instance
174+
// that inherits the env even if your normal VS Code is open, and stays pointed
175+
// local across projects. Extensions are shared from the default location; the
176+
// shim ignores auth, so a dummy token stands in for the login.
174177
func openVSCode() {
175-
let ws = vscodeWorkspaceURL
176-
try? FileManager.default.createDirectory(at: ws, withIntermediateDirectories: true)
177-
let readme = ws.appendingPathComponent("README.md")
178-
if !FileManager.default.fileExists(atPath: readme.path) {
179-
try? "# FauxClaude local test workspace\n\nClaude Code here talks to your local FauxClaude shim (\(shimURL)).\n"
180-
.write(to: readme, atomically: true, encoding: .utf8)
181-
}
178+
let panel = NSOpenPanel()
179+
panel.canChooseDirectories = true
180+
panel.canChooseFiles = false
181+
panel.allowsMultipleSelection = false
182+
panel.prompt = "Open in FauxClaude"
183+
panel.message = "Choose a project folder to open in VS Code pointed at your local shim."
184+
panel.directoryURL = FileManager.default.homeDirectoryForCurrentUser
185+
NSApp.activate(ignoringOtherApps: true)
186+
guard panel.runModal() == .OK, let folder = panel.url else { return }
187+
182188
let vscode = "/Applications/Visual Studio Code.app/Contents/MacOS/Electron"
183189
guard FileManager.default.isExecutableFile(atPath: vscode) else {
184190
alert("VS Code not found",
185-
"Install VS Code in /Applications, then reopen. Or open \(ws.path) manually with ANTHROPIC_BASE_URL=\(shimURL) set.")
191+
"Install VS Code in /Applications. Or open \(folder.path) manually with ANTHROPIC_BASE_URL=\(shimURL) set.")
186192
return
187193
}
194+
let profile = vscodeProfileURL
195+
try? FileManager.default.createDirectory(at: profile, withIntermediateDirectories: true)
188196
let p = Process()
189197
p.executableURL = URL(fileURLWithPath: vscode)
190-
p.arguments = [ws.path, "--new-window",
191-
"--user-data-dir", ws.appendingPathComponent(".vscode-profile").path]
198+
p.arguments = [folder.path, "--user-data-dir", profile.path]
192199
var env = ProcessInfo.processInfo.environment
193200
env.removeValue(forKey: "ANTHROPIC_API_KEY")
194201
env["ANTHROPIC_BASE_URL"] = shimURL
@@ -359,7 +366,7 @@ struct MenuContent: View {
359366
.keyboardShortcut("d")
360367
Button("Run Claude Code in Terminal") { shim.runClaude() }
361368
.keyboardShortcut("t")
362-
Button("Open in VS Code") { shim.openVSCode() }
369+
Button("Open Project in VS Code") { shim.openVSCode() }
363370
.keyboardShortcut("v")
364371
Button("View Log") { shim.openLog() }
365372
Button("Edit Model Map…") { shim.editModelMap() }

windows-app/Program.cs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public TrayApp()
9090

9191
menu.Items.Add("Open Dashboard", null, (_, _) => OpenUrl($"{ShimUrl}/"));
9292
menu.Items.Add("Run Claude Code in Terminal", null, (_, _) => RunClaude());
93-
menu.Items.Add("Open in VS Code", null, (_, _) => OpenVSCode());
93+
menu.Items.Add("Open Project in VS Code", null, (_, _) => OpenVSCode());
9494
menu.Items.Add("View Log", null, (_, _) => OpenLog());
9595
menu.Items.Add("Edit Model Map…", null, (_, _) => EditModelMap());
9696
menu.Items.Add(new ToolStripSeparator());
@@ -267,22 +267,27 @@ private void RunClaude()
267267
}
268268
}
269269

270-
// Open VS Code pointed at the shim. Claude Code (CLI or the VS Code extension)
271-
// reads ANTHROPIC_BASE_URL from its PROCESS environment — settings.json can't
272-
// redirect it — so we launch VS Code with the env set. A dedicated
273-
// --user-data-dir makes it a separate instance that reliably inherits the env
274-
// even if VS Code is already open (extensions are shared from the default
275-
// location). The shim ignores auth, so a dummy token stands in for the login.
270+
// Open a chosen PROJECT in VS Code pointed at the shim. Claude Code (CLI or the
271+
// VS Code extension) reads ANTHROPIC_BASE_URL from its PROCESS environment —
272+
// settings.json can't redirect it — so we launch VS Code with the env set. A
273+
// reused --user-data-dir keeps this an isolated instance that inherits the env
274+
// even if your normal VS Code is open and stays pointed local across projects.
275+
// Extensions are shared; the shim ignores auth, so a dummy token stands in.
276276
private void OpenVSCode()
277277
{
278278
if (_shim is not { HasExited: false } && !_running) StartShim();
279279

280-
var ws = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "fauxclaude-test");
281-
Directory.CreateDirectory(ws);
282-
var readme = Path.Combine(ws, "README.md");
283-
if (!File.Exists(readme))
284-
try { File.WriteAllText(readme, $"# FauxClaude local test workspace\r\n\r\nClaude Code here talks to your local FauxClaude shim ({ShimUrl}).\r\n"); }
285-
catch { /* best effort */ }
280+
// Pick a project folder.
281+
string folder;
282+
using (var dlg = new FolderBrowserDialog
283+
{
284+
Description = "Choose a project folder to open in VS Code pointed at your local shim.",
285+
UseDescriptionForTitle = true,
286+
})
287+
{
288+
if (dlg.ShowDialog() != DialogResult.OK || string.IsNullOrEmpty(dlg.SelectedPath)) return;
289+
folder = dlg.SelectedPath;
290+
}
286291

287292
// Find Code.exe (user install first, then machine-wide).
288293
var lad = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
@@ -297,17 +302,21 @@ private void OpenVSCode()
297302

298303
if (code == null)
299304
{
300-
MessageBox.Show($"VS Code (Code.exe) not found. Install it, or open this folder manually with " +
301-
$"ANTHROPIC_BASE_URL={ShimUrl} set:\n\n{ws}", "FauxClaude");
305+
MessageBox.Show($"VS Code (Code.exe) not found. Install it, or open {folder} manually with " +
306+
$"ANTHROPIC_BASE_URL={ShimUrl} set.", "FauxClaude");
302307
return;
303308
}
304309

305-
var profile = Path.Combine(ws, ".vscode-profile");
310+
// Reused profile (outside any project) so it's an isolated instance that
311+
// stays pointed local and isn't a blank session each time.
312+
var profile = Path.Combine(lad, "fauxclaude", "vscode-profile");
313+
Directory.CreateDirectory(profile);
314+
306315
// UseShellExecute must be false so the Environment dictionary is applied.
307316
var psi = new ProcessStartInfo(code)
308317
{
309318
UseShellExecute = false,
310-
Arguments = $"\"{ws}\" --new-window --user-data-dir \"{profile}\"",
319+
Arguments = $"\"{folder}\" --user-data-dir \"{profile}\"",
311320
};
312321
psi.Environment.Remove("ANTHROPIC_API_KEY");
313322
psi.Environment["ANTHROPIC_BASE_URL"] = ShimUrl;

0 commit comments

Comments
 (0)