feat(ai): add local CLI enhancement provider#600
Closed
mitsuhiko wants to merge 1 commit intoBeingpax:mainfrom
Closed
feat(ai): add local CLI enhancement provider#600mitsuhiko wants to merge 1 commit intoBeingpax:mainfrom
mitsuhiko wants to merge 1 commit intoBeingpax:mainfrom
Conversation
Add a Local CLI provider for AI enhancement with command templates for Pi, Claude, and Codex. Include Local CLI settings in the provider UI with template loading, command editing, and timeout selection. Wire enhancement execution through LocalCLIService with env-based prompt injection, stdin fallback, shell PATH discovery, and improved Local CLI error reporting in the transcription pipeline.
moona3k
added a commit
to moona3k/macparakeet
that referenced
this pull request
Apr 3, 2026
## What Changed - Sources/MacParakeetCore/Models/LLMProvider.swift: Added `.localCLI` case to `LLMProviderID` with `displayName`, `isLocal: false`, and `requiresAPIKey` property. Added `.localCLI()` factory method with placeholder config. - Sources/MacParakeetCore/Services/LocalCLIExecutor.swift: New file containing `LocalCLIConfig`, `LocalCLITemplate` (Claude Code, Codex), `LocalCLIError`, `LocalCLIConfigStore`, and `LocalCLIExecutor` with PATH discovery, Process execution, env var injection, stdin piping, and timeout handling. - Sources/MacParakeetCore/Services/LocalCLILLMClient.swift: New file implementing `LLMClientProtocol` for CLI tools. Formats messages into system/user prompts, delegates to `LocalCLIExecutor`, maps errors to `LLMError.cliError`. - Sources/MacParakeetCore/Services/RoutingLLMClient.swift: New thin router (~40 lines) that delegates `.localCLI` to `LocalCLILLMClient` and everything else to `LLMClient` (HTTP). Clean separation of concerns. - Sources/MacParakeetCore/Services/LLMError.swift: Added `.cliError(String)` case. - Sources/MacParakeetCore/Services/LLMConfigStore.swift: Skip Keychain operations for `.localCLI` provider (no API key needed). - Sources/MacParakeet/App/AppEnvironment.swift: Changed `LLMClient()` to `RoutingLLMClient()` — single line change that enables CLI routing. - Sources/MacParakeetViewModels/LLMSettingsDraft.swift: Added CLI fields (commandTemplate, selectedCLITemplate, cliTimeoutSeconds), validation for missing command, updated `requiresAPIKey` to use provider property. - Sources/MacParakeetViewModels/LLMSettingsViewModel.swift: Added CLI config management (template selection, command editing, timeout), save/load via `LocalCLIConfigStore`, updated provider switching logic. - Sources/MacParakeet/Views/Settings/LLMSettingsView.swift: CLI-specific settings UI with template picker, monospace command editor, timeout field, and custom privacy message. Hides model picker and base URL for CLI provider. - Sources/CLI/Commands/LLMInlineConfig.swift: Added `--command` option and `.localCLI` case in `buildConfig()`. - Tests: 44 new tests across LocalCLIExecutorTests, LocalCLILLMClientTests, and LLMSettingsViewModelTests (1064 total, all passing). ## Root Intent Users with Claude Code or Codex subscriptions should be able to use their CLI tools (`claude -p`, `codex exec`) for AI text enhancement — summaries, chat, and transforms — instead of paying for separate API keys. This is a natural extension of the existing LLM provider system. Inspired by Beingpax/VoiceInk#591 (filed by @mitsuhiko) and Beingpax/VoiceInk#600. Tracks #45. ## Prompt That Would Produce This Diff Add a "Local CLI" LLM provider to MacParakeet that lets users run CLI tools like `claude -p` or `codex exec` for AI features (summary, chat, transform). Architecture: Create a separate `LocalCLILLMClient` conforming to `LLMClientProtocol` (don't modify `LLMClient` which stays pure HTTP). Add a thin `RoutingLLMClient` router that delegates `.localCLI` to the CLI client and everything else to the HTTP client. Wire it via `AppEnvironment`. The executor should: discover user's shell PATH via `zsh -ilc` (apps from Finder don't get Homebrew paths), run commands via `/bin/zsh -lc`, set MACPARAKEET_SYSTEM_PROMPT/USER_PROMPT/FULL_PROMPT env vars, pipe full prompt to stdin, handle timeout with semaphore, and map exit codes to clear errors. Add built-in templates for Claude Code and Codex. Store CLI config (command + timeout) separately in UserDefaults since it doesn't fit `LLMProviderConfig`. Add settings UI with template picker, monospace command editor, and timeout field. Update CLI inline options with --command flag. Set `isLocal: false` (CLI tools send data to cloud APIs) but `requiresAPIKey: false`. Add tests for executor, client, and ViewModel. ## Files Changed - Sources/MacParakeetCore/Services/LocalCLIExecutor.swift (+247) - Sources/MacParakeetCore/Services/LocalCLILLMClient.swift (+76) - Sources/MacParakeetCore/Services/RoutingLLMClient.swift (+43) - Sources/MacParakeetCore/Models/LLMProvider.swift (+24, ~4) - Sources/MacParakeetCore/Services/LLMError.swift (+3) - Sources/MacParakeetCore/Services/LLMConfigStore.swift (+3) - Sources/MacParakeetViewModels/LLMSettingsDraft.swift (+35, ~12) - Sources/MacParakeetViewModels/LLMSettingsViewModel.swift (+50, ~11) - Sources/MacParakeet/App/AppEnvironment.swift (~2) - Sources/MacParakeet/Views/Settings/LLMSettingsView.swift (+90, ~65) - Sources/CLI/Commands/LLMInlineConfig.swift (+10, ~4) - Tests/MacParakeetTests/Services/LocalCLIExecutorTests.swift (+143) - Tests/MacParakeetTests/Services/LocalCLILLMClientTests.swift (+117) - Tests/MacParakeetTests/ViewModels/LLMSettingsViewModelTests.swift (+46) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 tasks
Owner
|
Thanks for the initial work @mitsuhiko! Built on top of your work with some fixes for codex since the main branch had diverged. |
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.
Feel free to close this as this might be too sloppy for inclusion.
This is my attempt to implement post processing via local coding agents #591. It works quite well for me but it might not be generalizable.
This has the benefit that you can use your Codex or Claude subscriptions for it.
These environment variables are available to the script:
VOICEINK_SYSTEM_PROMPT: the system promptVOICEINK_USER_PROMPT: the user prompt (transcribed text)VOICEINK_FULL_PROMPT: combined system + user promptVOICEINK_ACTIVE_APP_NAME: name of the frontmost applicationVOICEINK_ACTIVE_APP_BUNDLE_ID: bundle identifier of the frontmost appVOICEINK_ACTIVE_APP_PID: process ID of the frontmost appVOICEINK_BROWSER_URL: current browser URL (if applicable)VOICEINK_PROMPT_NAME: name of the active prompt profileVOICEINK_SCREENSHOT: path to a screenshot of the active window (if captured)VOICEINK_CLIPBOARD_TEXT: current clipboard contentsVOICEINK_SELECTED_TEXT: currently selected text in the frontmost appVOICEINK_LOCALE: system locale (e.g. en_US)VOICEINK_POWER_MODE: name of the active Power Mode (if any)VOICEINK_RAW_SYSTEM_PROMPT: the prompt text without added context sectionSummary by cubic
Adds a Local CLI enhancement provider that runs your own command-line tools to post‑process transcriptions. Includes templates for
pi,claude, andcodex, a settings UI, and clearer error messages.New Features
.localCLI(no API key). Considered connected when a command is set.pi,claude,codexwith an editor and timeout picker in settings.Migration
pi,claude,codex, etc.) is installed and available on your PATH.Written for commit 1dc5c8f. Summary will update on new commits.