Conversation
A vanished TempDir surfaces as a DirectoryNotFoundException wherever the victim next touches its tree, arbitrarily far from whatever removed it; dispose is the one place that can still name the owner. The orchestrator tests tripped it at once: cleanup of a standalone worktree deletes the path it is handed, and they handed it the whole fixture rather than a directory under it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Remembering a host probe only pays off if one router outlives a call, and the watcher re-detects every 60s for as long as it runs, so the router is a singleton that call sites take rather than construct. A static memo was shared across concurrent tests that each cleared it, so one test's write could answer another's probe and its budget assertion saw no round trip.
The two git children behind ResolveForRepo set no working directory of their own, so they inherited the process's and a test could steer them only by moving it; handing the value down without also handing it to them would have changed nothing. The ban covers the setter too, and one test still moves the process, because a path with no directory component resolves against nothing else.
Code Review by Qodo
1. Server ingest tests stop compiling
|
| var repoRoot = AppConfig.RepoRootOf(workdir); | ||
| var repoPath = global ? null : repoRoot; |
There was a problem hiding this comment.
2. Global profile changes can stall 🐞 Bug ➹ Performance
UseCommand.HandleAsync calls AppConfig.RepoRootOf(workdir) before selecting the --global path, although that value is unused for a global change without --save. RepoRootOf starts `git rev-parse, and GetGitRepoRoot blocks in ReadToEnd()` before reaching its timeout check, so a hung git process delays a global profile change that does not need repository information.
Agent Prompt
## Issue description
`kcap use <profile> --global` resolves a repository root even though it neither binds nor saves a repository-specific configuration. That starts an unnecessary git child process and can block the global-only operation if git does not complete.
## Fix Focus Areas
- src/Capacitor.Cli/Commands/UseCommand.cs[18-21]
## Recommended Fix
Only call `AppConfig.RepoRootOf(workdir)` when a repository path is required: for a non-global selection or when `--save` needs a repository config location. Preserve the existing `--global --save` behavior by resolving the root in that case, while passing `null` for a plain global selection.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| public PiImportSource( | ||
| ConfigRoot config, | ||
| string sessionsDir, | ||
| GitProviderRouter router, |
There was a problem hiding this comment.
1. Server ingest tests stop compiling 🔗 Cross-repo conflict ≡ Correctness
PiImportSource adds a required GitProviderRouter constructor argument before repoDetector, but kcap-server still constructs it with only ConfigRoot, sessionsDir, and the named detector. When kcap-server advances its CLI submodule, both Pi import integration-test call sites fail overload resolution in a project that directly references the CLI project.
Agent Prompt
## Issue description
Adding the required `GitProviderRouter` argument breaks existing `PiImportSource` constructions in kcap-server, whose ingest test project directly references the CLI project.
## Fix Focus Areas
- src/Capacitor.Cli/Harness/Pi/PiImportSource.cs[33-40]
## Recommended Fix
Add a backward-compatible constructor overload accepting the previous `ConfigRoot`, `sessionsDir`, and optional `repoDetector` parameters, and delegate it to the router-aware constructor. Alternatively, coordinate an update to both kcap-server call sites so they provide a `GitProviderRouter` before advancing the CLI submodule.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
PR Summary by QodoResolve process context once and inject repository state
AI Description
Diagram
High-Level Assessment
Files changed (161)
|
Refs #781 — AI-2528
What & why
A fixture deleted from outside its owner surfaces as a
DirectoryNotFoundExceptionwherever the victim next touches its tree, arbitrarily far from whatever removed it.
TempDirnow reports that at dispose, the one place that can still name the owner —which immediately caught orchestrator tests handing production cleanup their whole
fixture root instead of a directory under it.
Two ambient reads turned up the same way. The provider router's memo was a mutable
static that concurrent tests cleared under each other, so one test's write could
answer another's probe. The working directory was read from the process wherever it
was wanted. Both are resolved once now and injected; ambient cwd joins
BannedSymbols.txt, so a new read is a build error rather than a convention.Where to look
The two git children behind
ResolveForReposet no working directory of their own,so they inherited the process's. Handing the value down without also handing it to
them would have changed nothing.
One test still moves the process: a path with no directory component resolves against
nothing else.
Verification
dotnet test --solution Capacitor.slnx— 13012 tests, 12943 passed, 68 skipped, 1failed. That failure,
Installed_codex_schema_matches_the_vendored_pin, reproducesunchanged on
main(installed codex 0.154.0 against a pin taken from 0.147.0) and isSkip.When'd on CI, which has no codex.Rewritten assertions checked by mutation rather than by going green — pointing the
injected directory away from the repo fails 2/3
ResolveForRepoTests, 2/2 Uninstall--projecttests and 3/4 Setup acceptance tests; dropping the Cursor workspace-rootguard fails its test. The survivors are the rows whose docs already state they are
directory-independent.
dotnet publish -c Release: no IL2026/IL3050. Assembly-exclusive tests 517 → 499.