spb/forge-studio Public
The Instruments of LLM training — a native macOS cockpit for Forge. Train language models from scratch on Apple Silicon without a terminal.
Swift 95.7%
Shell 4.3%
1// Author: Simon-Pierre Boucher — contact@spboucher.ai2//3// Paths (forge binary, workspace) with live validation via `forge info`.4import SwiftUI5import UniformTypeIdentifiers67struct SettingsView: View {8 @Environment(AppModel.self) private var app9 @State private var binaryPath = ForgeBinaryLocator.savedBinaryURL?.path ?? ""10 @State private var workspacePath = ForgeBinaryLocator.savedWorkspaceURL?.path ?? ""1112 var body: some View {13 Form {14 Section("Binaire forge") {15 HStack {16 TextField("Chemin", text: $binaryPath)17 .font(.callout.monospaced())18 Button("Choisir…") { pickBinary() }19 }20 if let device = app.forgeDevice {21 Label("Validé — \(device)", systemImage: "checkmark.circle.fill")22 .foregroundStyle(.green)23 } else if let error = app.forgeError {24 Label(error, systemImage: "xmark.circle.fill")25 .foregroundStyle(.red)26 }27 Button("Revalider") {28 ForgeBinaryLocator.save(binary: URL(fileURLWithPath: binaryPath))29 Task { await app.validateForge() }30 }31 }32 Section("Espace de travail") {33 HStack {34 TextField("Dossier (runs/, data/)", text: $workspacePath)35 .font(.callout.monospaced())36 Button("Choisir…") { pickWorkspace() }37 }38 Text("Runs : \(app.store.workspaceURL.path)/runs")39 .font(.caption)40 .foregroundStyle(.secondary)41 }42 }43 .formStyle(.grouped)44 .frame(width: 560, height: 320)45 }4647 private func pickBinary() {48 let panel = NSOpenPanel()49 panel.allowedContentTypes = [.unixExecutable, .executable]50 panel.canChooseDirectories = false51 if panel.runModal() == .OK, let url = panel.url {52 binaryPath = url.path53 ForgeBinaryLocator.save(binary: url)54 Task { await app.validateForge() }55 }56 }5758 private func pickWorkspace() {59 let panel = NSOpenPanel()60 panel.canChooseDirectories = true61 panel.canChooseFiles = false62 panel.canCreateDirectories = true63 if panel.runModal() == .OK, let url = panel.url {64 workspacePath = url.path65 ForgeBinaryLocator.save(workspace: url)66 }67 }68}69