claude: feat(fc): add claude cli provider - #6
Draft
danwt wants to merge 2 commits into
Draft
Conversation
added 2 commits
August 14, 2026 14:41
Route prompts through the Claude Code CLI with `fastc --provider claude`, so a diff never reaches a third party and no API key is needed. The default stays on OpenRouter and behaves exactly as before. Splits the transport out of call_llm_raw into one function per provider, leaving the retry loop, timings and JSON repair shared.
Strip unified-diff context lines and the ---/+++ header pair from the copy sent to claude, cutting a typical diff by about a quarter, and use a shorter form of the scope rules that produced identical scopes. Phase 2 asks for a subject only when a group holds one file, reusing that group's phase 1 hint as the body so nothing is lost. Prompts move behind a per-provider table, so openrouter keeps the wording it had. Commit bodies are unchanged on both providers: a conditional-description prompt was tried and dropped, since it removed bodies from single-file commits without a measurable saving.
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.
fastc sends every diff to OpenRouter, which is a third party, and that is a problem for work code. There was no way to use a Claude subscription instead: the Claude Code OAuth token cannot be used in another tool, and an Anthropic API key means going through company procurement.
fastc --provider claudeshells out to the Claude Code CLI, which is the sanctioned route and spends the Agent SDK credit attached to the seat. The default provider is unchanged, so plainfastcbehaves exactly as it did. The transport is split out ofcall_llm_rawinto one function per provider, and the retry loop, timings, fence stripping and JSON repair stay shared.Keeping the prompt small
The claude path strips unified-diff context lines and the
---/+++header pair from the copy it sends, cutting a typical diff by about a quarter, and uses a shorter form of the scope rules that produced identical scopes. Phase 2 asks for a subject only when a group holds a single file, and reuses that group's phase 1 hint as the body. Commit messages come out the same shape on both providers.A conditional-description prompt was tried and dropped. It removed bodies from single-file commits, and repeated runs could not show it saving anything.
Trade-offs
Requests take tens of seconds against 2 to 3 on a fast OpenRouter model. The model thinks before answering, the CLI exposes no way to disable that, and thinking time varies by up to 9x between identical runs, which swamps any prompt-level tuning. Each request is a process holding about 450MB, so phase 2 runs 4 at a time instead of 32.
The CLI runs with
--safe-mode, so repoCLAUDE.mdfiles, skills, plugins, hooks and MCP servers are all ignored.--barewould strip more but forcesANTHROPIC_API_KEY, which would defeat the point.There is no JSON mode, so the claude path relies on the prompt asking for JSON, backed by the existing fence stripping and repair.
--json-schemawould enforce it properly but needs a different schema per call site, so it is left for later.Testing
157 tests pass, including new ones for the diff stripper and the phase 2 policy. Verified by hand in scratch repos: both providers on a 3 file diff produce equivalent commit plans with bodies; the claude provider on a 61 file diff exercises the two-phase path and groups it into 4 commits across 5 requests; a bad model name fails fast with the CLI's own message rather than retrying.
The claude envelope parsing has no unit test. The test file is pure functions with no mocking, and adding subprocess mocks for four short branches was not worth it.