feat(doctor): add a console ctrl+c check - #250
Merged
Merged
Conversation
Quitting CoDev Code hangs for some Windows users and not others, and the
variable we could not observe is how ctrl+c is delivered. CoDev Code
clears ENABLE_PROCESSED_INPUT on the shared console while it runs so
ctrl+c arrives as a keypress; when that guard does not take, ctrl+c
stays a console break delivered to every process attached to the
console, including the cmd.exe shims in our launch chain, which stop at
"Terminate batch job (Y/N)?" instead of exiting.
The agent reports its own verdict (`codev debug console --json`): it
runs under Bun and owns the FFI that reads the console mode, and it
installs the real guard to check that clearing the bit sticks. This
check relays that and names which precondition failed.
Two supporting changes:
- run.ts splits resolveAgentPath out of agentOnPath. The check probes
the resolved path, never the bare name — the bare name would re-enter
our own PATH shim and relaunch the agent through the hub, with the
upload daemon and gateway key refresh in tow.
- npm.ts gains execAsync({ inheritStdin }). The probe reads the console
input mode through its stdin handle, and a piped stdin is not a
console. execFile has no stdio option, so that path uses spawn and
collects the streams itself. Its shell branch now also quotes a file
carrying spaces, since callers can pass a resolved absolute path.
Skips rather than fails on a build predating `codev debug console`, so
the two repos can land in either order.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Why
Quitting CoDev Code hangs for some Windows users and not others (#249). The variable we could not observe is how
ctrl+cis delivered.CoDev Code clears
ENABLE_PROCESSED_INPUTon the shared console while it runs, soctrl+carrives as a keypress its own double-ctrl+cexit can handle. When that guard doesn't take,ctrl+cstays a console break — delivered to every process attached to the console, including the fourcmd.exebatch shims in a hub launch chain, which stop atTerminate batch job (Y/N)?instead of exiting.Until now the only way to tell an affected machine from a working one was to ask the user for a screenshot and guess.
What
A
console-ctrl-cenvironment check:The agent reports its own verdict via
codev debug console --json(codev-code PR #163) rather than the hub reading the console itself, for two reasons: the agent runs under Bun and owns the FFI that reads the mode, and it can install the real guard and re-read to prove the bit actually clears. A mode read from the hub would only describe the shell's console at rest, which is not the question.The three failure modes are graded apart — FFI unavailable, guard didn't install, guard installed but the bit stayed set — so the output names its own cause.
Skips (not fails) when: not Windows, stdin isn't a console, CoDev Code isn't installed, or the installed build predates
codev debug console. That last one means the two PRs can land in either order.Supporting changes
run.ts—resolveAgentPathsplit out ofagentOnPath, which becomes a one-line wrapper. The check probes the resolved path, never the bare name: the bare name would re-enter our own PATH shim and relaunch the agent through the hub, dragging in the upload daemon and gateway-key refresh — side effects a diagnostic has no business causing.npm.ts—execAsyncgains{ inheritStdin }. The probe reads the console input mode through its stdin handle, and a piped stdin is not a console.execFilehas nostdiooption (neither its typings nor its docs), so that one path goes throughspawnand collects the streams itself. Kept insideexecAsyncrather than spawned fromdoctor.tsso the child stays covered by the diagnostic log andcommandLog.Its shell branch now also quotes a file containing spaces — callers can pass a resolved absolute path like
C:\Program Files\...\codev.cmd, which cmd.exe would otherwise split. Args stay unquoted, as before.Tests
Six new tests in
tests/lib/doctor.test.ts, using the existingstdinApi/ platform-swap seams:codevhub updateinheritStdin, never the bare nameFull suite green via the pre-commit hook:
biome check,tsc --noEmit, 1390 passed / 2 skipped,pnpm build.Relationship to #249
Independent, and branched off
mainso they can merge in any order. #249 makes a wedged launch survivable; this one tells you whether a given machine is at risk in the first place.Neither is verified on Windows — that is what this check exists to change.
🤖 Generated with Claude Code