Add CommandOptions with a working directory for the spawned process - #43
Merged
Conversation
This was referenced Aug 19, 2026
…rocess ProcessStartInfo.WorkingDirectory was never assigned, so every command inherited the host process's current directory. Callers wanting to drive a tool somewhere else were pushed onto a tool-specific flag where one exists, onto mutating the process-global Environment.CurrentDirectory, or onto shelling out through cmd /c cd, which reintroduces the quoting problems the argument-vector overloads exist to avoid. Introduce CommandOptions to carry process-shaping settings, and add three overloads on the argument-vector shape that take it. All fourteen existing overloads keep their signatures and delegate through it, so nothing existing changes behaviour. WorkingDirectory is an AbsoluteDirectoryPath rather than a string: a relative directory would have to be resolved against the caller's current directory, which is the process-global state the option exists to stop callers depending on. This adds ktsu.Semantics.Paths and ktsu.Semantics.Strings as package references, matching how AppDataStorage, SingleAppInstance and Schema consume them. Fixes #39
matt-edmondson
force-pushed
the
feat/39-working-directory
branch
from
August 19, 2026 10:43
b7b8478 to
c99e717
Compare
|
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.



Fixes #39.
Problem
ProcessStartInfo.WorkingDirectorywas never assigned, so every command inherited the host process's current directory. The workarounds available to callers were a tool-specific flag where one exists (git -C), mutating the process-globalEnvironment.CurrentDirectory(not thread-safe, races with concurrent calls), or shelling out throughcmd /c cd && ...(reintroduces the quoting problems the argument-vector overloads exist to avoid).Approach
Rather than add a parameter to every overload — and again for environment variables in #40 — this introduces a
CommandOptionsrecord to carry process-shaping settings:Three new overloads on the argument-vector shape accept it. All fourteen existing overloads keep their signatures and delegate through it, so no existing call changes behaviour and future options cost no new overloads.
WorkingDirectoryis anAbsoluteDirectoryPathrather than a string on purpose: a relative directory would have to be resolved against the caller's current directory, which is exactly the process-global state this option exists to stop callers depending on. Making it absolute renders that ambiguity unrepresentable rather than merely discouraged.Dependency note
This adds
ktsu.Semantics.Pathsandktsu.Semantics.Strings, matching how AppDataStorage, SingleAppInstance and Schema consume them (the SDK's KTSU0006 analyzer requires the Strings reference be explicit, sinceWeakStringis declared there).Worth being deliberate about the cost: on
net5.0–net7.0andnetstandard2.0/2.1this pullsSystem.Text.Json,System.IO.PipelinesandSystem.Text.Encodings.Webin transitively, and those packages emit "doesn't support net5.0/6.0/7.0" build warnings — 10 of them, against a previously warning-free build. They are MSBuild warnings from targets files, not compiler warnings, soTreatWarningsAsErrorsdoes not escalate them and the build stays green. The affected TFMs are all out of support, andnetstandard2.1already covers those consumers.Testing
ExecuteAsyncShouldStartTheProcessInTheGivenWorkingDirectory— runscmd /c cd/pwdin a per-test temp directory and compares the reported leaf (leaf rather than full path, so a symlinked temp directory as on macOS doesn't produce a spurious failure).ExecuteAsyncShouldInheritTheCurrentDirectoryWhenNoWorkingDirectoryIsGiven— pins that an unset working directory leaves the previous behaviour untouched.ExecuteAsyncShouldThrowArgumentNullExceptionWhenOptionsAreNull.Full suite: 27 passed, 2 skipped (elevated tests self-skip to avoid a UAC prompt). Builds clean across all eight target frameworks.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LwKTWcmxe5mh6DsLRj5NGQ