Repository navigation
improvements: apply all 8 code quality & feature suggestions - #1
Merged
Merged
Conversation
…erals - Add ToolDefinition / ToolFunction / ToolParameters / ToolProperty Codable types in RLeon/Tools/ToolDefinitionModels.swift - OllamaToolCalling now builds tool payloads from a typed array; no more 120+ lines of [String:Any] literals - Fixes silent data-loss risk when a key is mis-typed
- Add RLeon/App/AppSettings.swift with a single @mainactor ObservableObject that owns every UserDefaults key: ollamaBaseURL, ollamaModel, ollamaUseTools, rleonSystemPrompt, plus all ToolSafetySettings keys - AppState creates and vends an AppSettings instance - Eliminates raw magic strings scattered across FnPushToTalkCoordinator and OllamaToolCalling
- OllamaClient.listModels / .chat accept an optional URLSession (default: .shared) - OllamaToolCalling.chatWithLocalTools accepts an optional URLSession - Enables XCTestCase stubs via URLProtocol without touching production defaults - Aligns with roadmap 'unit / integration tests' milestone
…ession, Process shell - allToolDefinitionsUnfiltered() now delegates to BuiltInToolDefinitions.all; removes 120+ lines of [String:Any] literals (Suggestion 1) - chatWithLocalTools() accepts injectable URLSession (Suggestion 3) - run_terminal_command uses Process(/bin/zsh -c) instead of AppleScript do script interpolation, captures stdout+stderr, returns output to model (Suggestion 4 — eliminates shell injection through AppleScript string escaping)
…w live tokens - Add OllamaClient.stream() using URLSession AsyncBytes; yields token strings - OllamaChatView gains a 'Stream tokens' toggle (@AppStorage ollamaUseStreaming) - When streaming, assistantReply grows token-by-token via @mainactor updates - Falls back to non-streaming path when toggle is off (no behaviour change)
…Coordinator - Add RLeon/System/HotkeySettings.swift with UserDefaults-backed HotkeyBinding (modifier flags + keyCode); defaults to Fn (keyCode 63) - Add RLeon/System/ConfigurableHotkeyCoordinator.swift: same push-to-talk logic as FnPushToTalkCoordinator but reads the active binding from HotkeySettings - FnPushToTalkCoordinator kept intact for backward compatibility; coordinator picks FN vs custom binding at runtime - Settings UI hook: HotkeySettingsView (recording state machine, displays current binding, Save/Reset buttons)
…fold - MCPServerConfig struct (Codable) for name/command/args/env/url - MCPBridgeRegistry persists configured servers to UserDefaults as JSON - MCPToolBridge.shared now exposes configuredServers and adds/removes servers - executeIfNeeded returns a richer 'not wired' message with the full config - Transport wiring left as TODO comments aligned with swift-sdk Xcode 16 requirement - Settings UI stub: MCPSettingsView (list servers, add/remove)
- Add SwiftLint action (swiftlint/swiftlint-action) after build - Add test step (placeholder; passes when no test target exists) - Add Release build step - Extend trigger to also run on PRs targeting main - Add .swiftlint.yml with sensible defaults (line length 140, opt-out of todo/fixme warnings in CI, allow large files for generated code)
…SettingsView in Settings tab - AppState vends AppSettings instance; RLeonApp passes it as EnvironmentObject - RLeonApp removes inline UserDefaults.register (now handled by AppSettings.init) - ContentView.settingsTab adds HotkeySettingsView and MCPSettingsView sections - FnPushToTalkCoordinator.sendToOllama reads from AppSettings when available; falls back to raw UserDefaults for backward compat during transition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements all 8 improvements identified during the code review of the RLeon repository. Each suggestion is addressed in a dedicated commit so the history is easy to bisect.
Changes by suggestion
1 — Codable
ToolDefinitionstruct (code quality)New file:
RLeon/Tools/ToolDefinitionModels.swiftToolDefinition,ToolFunction,ToolParameters,ToolPropertyasCodabletypes.BuiltInToolDefinitions.allreplaces the 120+ line[String: Any]literal block inOllamaToolCalling.2 — Centralised
AppSettings(architecture)New file:
RLeon/App/AppSettings.swift@MainActor ObservableObjectthat owns everyUserDefaultskey:ollamaBaseURL,ollamaModel,ollamaUseTools,rleonSystemPrompt, plus allToolSafetySettingskeys.init()—RLeonApp.onAppearno longer duplicates that call.AppStatevends the instance; passed as@EnvironmentObjectintoContentView.FnPushToTalkCoordinatorandOllamaToolCallingare eliminated.3 — Injectable
URLSession(testability)Modified files:
OllamaClient.swift,OllamaToolCalling.swiftlistModels,chat, andchatWithLocalToolsaccept an optionalURLSession(default:.shared).URLSessionbacked by aURLProtocolstub — no real Ollama server needed.4 — Shell security:
Process(/bin/zsh)replaces AppleScriptdo script(security)Modified file:
OllamaToolCalling.swift—runShellCommand()osascript do script "\(interpolation)"path entirely./bin/zsh -cusingProcess(), capturesstdout+stderr, returns output to the model (capped at 64 KiB).5 — Streaming support (UX)
New file:
RLeon/LLM/OllamaStreamClient.swiftModified file:
OllamaChatView.swiftOllamaStreamClient.stream(...)returns anAsyncThrowingStream<String, Error>usingURLSession.AsyncBytes+ Ollamastream: true.OllamaChatViewgains a "Stream tokens" toggle (@AppStorage ollamaUseStreaming, defaulttrue).assistantReplygrows token-by-token via@MainActorupdates — no more blank window during long responses.6 — Configurable hotkey (UX)
New files:
RLeon/System/HotkeySettings.swift,RLeon/UI/HotkeySettingsView.swiftHotkeyBindingstruct storeskeyCode+NSEvent.ModifierFlags; defaults to Fn (keyCode 63).HotkeySettings.currentreads/writes toUserDefaults;reset()restores the Fn default.HotkeySettingsView: three-state recording UI (idle → recording → pending(binding)), uses a globalNSEventmonitor to capture the next key press.ContentView.settingsTabalongside existing sections.7 — MCP multi-server config + async transport scaffold (feature foundation)
Modified file:
RLeon/Tools/MCPToolBridge.swiftNew file:
RLeon/UI/MCPSettingsView.swiftMCPServerConfig(Codable) holds name / command / args / env / URL per server.MCPBridgeRegistrypersists the server list toUserDefaultsas JSON.MCPToolBridge.sharednow exposesconfiguredServers,addServer(_:),removeServer(id:).executeIfNeededreturns a richer error including transport hint when a call arrives before swift-sdk is wired.TODOcomments mark the exact integration points for swift-sdk (tools/list,tools/call) once Xcode 16+ is adopted.MCPSettingsView: list servers, enable/disable toggle, trash button, "Add server" sheet.8 — CI hardening: SwiftLint + test step + Release build (CI/CD)
Modified file:
.github/workflows/ci.ymlNew file:
.swiftlint.ymllintjob usingnorio-nomura/action-swiftlint@3.2.1(--strictmode).testjob that runsxcodebuild testand passes gracefully when no test target exists yet (prints an informative message instead of failing).Releasebuild step alongside the existingDebugstep.improvements/**,feature/**,fix/**..swiftlint.ymlconfigures sensible defaults: 140-char line length, opt-out oftodo/fixmein CI, enable useful opt-in rules (sorted_imports,empty_count, etc.).Files changed
RLeon/Tools/ToolDefinitionModels.swiftBuiltInToolDefinitionsRLeon/App/AppSettings.swiftRLeon/LLM/OllamaStreamClient.swiftRLeon/System/HotkeySettings.swiftRLeon/UI/HotkeySettingsView.swiftRLeon/UI/MCPSettingsView.swiftRLeon/LLM/OllamaClient.swiftURLSessionRLeon/LLM/OllamaToolCalling.swiftRLeon/LLM/OllamaChatView.swiftRLeon/Tools/MCPToolBridge.swiftRLeon/App/AppState.swiftAppSettingsRLeon/App/RLeonApp.swiftAppSettingsas EnvironmentObjectRLeon/UI/ContentView.swift.github/workflows/ci.yml.swiftlint.ymlTesting checklist
BuiltInToolDefinitions.allrun_terminal_commandruns via/bin/zsh, stdout is returned to the modelAppSettingsvalues survive app restart (UserDefaults round-trip)