Add C# as a supported output language#102
Merged
Merged
Conversation
This is likely a transient issue. You can re-trigger a run from the dashboard. |
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Follows the exact same pattern as python/javascript/typescript:
- New prompt partial (prompts/partials/_language_csharp.md): uses
System.Net.Http.HttpClient and System.Text.Json - both part of the
.NET 5+ base class library, so no NuGet package is needed for HTTP
or JSON (unlike Java, .NET's stdlib does include JSON support).
Packaged as a minimal .csproj so `dotnet run` just works. Same
auth-hardcoding/refresh guidance as the other languages. No filename
vs. class-name naming workaround needed here (unlike Java) - C#
doesn't require a public class's name to match its file's name.
- base_engineer.py: added "csharp" to _OUTPUT_LANGUAGE_EXTENSIONS
(.cs), _get_language_name() ("C#"), _get_run_command() ("dotnet
run"), and _get_auto_output_files() (ApiClient.csproj, always
included - a project file is required to `dotnet run` regardless of
dependencies, matching typescript's "always" precedent rather than
javascript/go's conditional one).
- cli.py: added C# to the interactive `output_language` config picker.
- Updated the three docstrings/comments that listed the language set
(config.py, engineer.py, prompts/__init__.py) and README.md's output
language line.
- Tests: mirrored the existing per-language test pattern in
test_base_engineer.py (extension, run command, prompt content) and
test_prompts.py (partial loading) for C#.
Checked the partial for the literal-brace str.format_map() bug caught
in the Java PR before writing this one - no literal `{`/`}` anywhere
in the new file (confirmed via grep), since C# code snippets weren't
needed to convey the guidance here.
Full test suite passes (49/49, run 3x) except the same pre-existing
flaky test as the other language PRs
(test_existing_client_language_falls_back_to_newest_file - a
mtime-resolution race condition, unrelated to this change, present
on a clean main checkout too). ruff check is clean on every file this
touches (8 pre-existing lint errors elsewhere on main, none in the
touched lines).
Two real bugs caught by greptile-apps on the PR, both verified against the actual code before fixing: 1. Same class of bug as the Go and Java PRs: the agent's cwd for the whole session is scripts_dir.parent.parent (confirmed in engineer.py's analyze_and_generate -> ClaudeAgentOptions), not scripts_dir where ApiClient.csproj is saved. A bare `dotnet run` only looks for a project file in the current directory, so it wouldn't find it. _get_run_command() now points --project explicitly at this run's own .csproj path, the idiomatic dotnet-CLI way to do this (as opposed to Maven's -f flag used for the same fix in the Java PR). 2. The partial described HttpClient/System.Text.Json as available since .NET 5+, but then hardcoded the generated project's own <TargetFramework> to net8.0 unconditionally — a genuine internal contradiction: on a machine with only, say, .NET 6 installed, generation would succeed but the required dotnet run test step would fail with an unsupported-target-framework error, despite the partial's own text implying broader compatibility. Fixed by making the target framework adaptive: default to net8.0, but explicitly instructs lowering <TargetFramework> and retrying if the installed SDK doesn't support it - leaning on the same "test it, up to 5 attempts to fix issues" loop every partial already has, rather than assuming one hardcoded version always works. Updated test_get_run_command_csharp to match the new (scripts_dir- dependent) return value. A third bot finding (cli.py's `run <id> --file` subcommand only discovers *.py scripts and always launches them with the shared venv's python interpreter) is the same pre-existing, cross-cutting gap already noted on the Java PR - confirmed discover_scripts() in utils.py has been Python-only since before javascript/typescript were added, so this isn't specific to C# either. Left out of scope here for the same reason. Full test suite passes (49/49, run 2x). ruff check clean on the touched lines (2 pre-existing unused-import warnings elsewhere in test_base_engineer.py, unrelated).
Same class of bug caught by review bots on the PHP PR, applied here
proactively: _get_run_command()'s "--project \"{path}\"" only looked
safe - manual double-quoting doesn't stop $()/backtick command
substitution inside a double-quoted shell string. Replaced with
shlex.quote(). Added a test with a deliberately hostile path
(embedded $(rm -rf ~)) asserting the command round-trips through
shlex.split() back to the literal path.
Full test suite passes (50/50, run 2x) except the same pre-existing
flaky test noted on the other language PRs.
cubic flagged that a relative --output-dir breaks --project: scripts_dir stays relative to the original cwd, but once the agent's cwd moves to scripts_dir.parent.parent (see analyze_and_generate), embedding that same relative string re-interprets it from the new location and points at a doubly-nested, nonexistent path. Resolve scripts_dir before interpolating it so the command is genuinely cwd-independent, matching the intent already documented in the surrounding comment.
The partial told the agent to *lower* TargetFramework when dotnet run rejects it, but a machine with only a newer SDK (e.g. .NET 10, no .NET 8 runtime) needs the target *raised* — net8.0 builds fine under SDK 10 but fails at launch. Observed in live testing: the agent recovered anyway from dotnet's error message, but the guidance shouldn't point the wrong way.
kalil0321
force-pushed
the
add-csharp-output-language
branch
from
July 22, 2026 10:56
07c7d22 to
6306e39
Compare
Owner
|
@greptile review |
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.
Follows the exact same pattern as python/javascript/typescript:
dotnet runjust works. Same auth-hardcoding/refresh guidance as the other languages. No filename vs. class-name naming workaround needed here (unlike Java) - C# doesn't require a public class's name to match its file's name.dotnet runregardless of dependencies, matching typescript's "always" precedent rather than javascript/go's conditional one).output_languageconfig picker.Checked the partial for the literal-brace str.format_map() bug caught in the Java PR before writing this one - no literal
{/}anywhere in the new file (confirmed via grep), since C# code snippets weren't needed to convey the guidance here.Full test suite passes (49/49, run 3x) except the same pre-existing flaky test as the other language PRs
(test_existing_client_language_falls_back_to_newest_file - a mtime-resolution race condition, unrelated to this change, present on a clean main checkout too). ruff check is clean on every file this touches (8 pre-existing lint errors elsewhere on main, none in the touched lines).
Summary by cubic
Adds C# as a supported output language that generates a minimal .NET project and runs with a cwd‑independent
dotnet run --projectcommand. The run command resolves and shell‑quotes the project path so it works from any directory, including paths with shell metacharacters.New Features
base_engineer: mapscsharp->.cs, language "C#", run commanddotnet run --project {scripts_dir}/ApiClient.csprojusingshlex.quoteand an absolute path, and always includesApiClient.csproj.prompts/partials/_language_csharp.mdusingHttpClient/System.Text.Json(available since .NET Core 3.0), with auth hardcoding/refresh, save paths, and adaptive target framework guidance (defaultnet8.0; adjust up or down to match the installed SDK).csharp; README/config/engineer/prompt docs updated.Tests
tests/test_base_engineer.py: asserts.csextension; run command points to a resolved, safely quoted project path; handles metacharacters; resolves relative output dirs; C# prompt content included.tests/test_prompts.py: verifies the C# partial loads and rendersrun_commandand paths.Written for commit 6306e39. Summary will update on new commits.
Greptile Summary
This PR adds C# as a supported output language. The main changes are:
.csand.csprojoutput handling.dotnet run --projectcommand.Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (2): Last reviewed commit: "Make the C# target-framework guidance di..." | Re-trigger Greptile