Repository navigation
Replies: 1 comment
|
Validating this on native Windows 11 — thank you. @arlinamid, I independently validated your branch (
This is the real thing — a complete, tested port, not another partial patch. Thank you for doing the work properly — the write-up (traced timings, ConPTY keystroke tests, per-commit test evidence) made independent validation straightforward. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
CONTRIBUTING.mdsays external PRs aren't being accepted, so I'm sharing this here instead of opening one. The fix lives in a branch on my fork, in case it is useful to anyone hitting the same problems or to the maintainers:c19ce50,ef19bd1,f3ef7c8,a0ea62e,98ad068,5beff34,29f8bfband0f3ad51, on top ofmainincl. fix: Windows termios crash and portable Drive auth prompt #135)Updates (2026-10-07):
ef19bd1fixescolab editon Windows.f3ef7c8escapes%in the ssh ProxyCommand (a bug on all platforms) and makes the whole test suite pass on Windows.a0ea62estops a pipedcolab consolefrom leaking terminal replies into the next command (all platforms), and makescolab edithonor a Windows$EDITORpath.98ad068stops a pipedcolab consolefrom cutting off its own output on a freshly started runtime (all platforms).5beff34explains a dropped kernel connection in one line instead of a traceback, and stops a finished command from writing a stopped session back intosessions.json(all platforms).29f8bfband0f3ad51add notebook control tocolab exec:--cells,--stop-on-error, a local pre-flight--check/--check-only, and a non-zero exit code when a cell fails (all platforms; this is a new feature, not a fix).Details are below.
Symptom
On 0.7.4 (WSL Ubuntu, T4 runtime),
colab drivemountfailed with:This is the same failure as #113: the consent step completes in the browser, but the command never recovers.
Root cause (two separate problems)
drive.mount()defaults totimeout_ms=120000, and that budget includes the time the user spends on the consent screen. A normal click-through can exceed it, so the kernel gives up and the mount fails.dfs_ephemeralcolab_requesthook ran the whole credential-propagation handshake, including waiting for the user to press Enter, inside the websocket message callback. While it waits, the receive loop is blocked, so a long consent step ends in "Connection was lost" or a missed execute reply.What the branch changes
drivemountcallsdrive.mount(path, timeout_ms=600000), which matches the CLI's existing 10-minute interactive timeout.colab_replywith anerrorto the kernel, sodrive.mountfails at once instead of waiting out the timeout.login_hintaccount, instead of printing Google's raw HTML error page. An optional--authuserflag is only appended to the consent URL when given explicitly.msvcrt, virtual-terminal processing enabled for cmd.exe and PowerShell, and fixes forssh --proxy-modestdin and quoting.colab editon Windows (ef19bd1): the local copy was kept in an openNamedTemporaryFile, which Windows does not allow to be opened a second time. The download, the hash and the editor all failed withPermissionError. The download error was also swallowed, so without the hash crash the editor would have received an empty file and saving would have overwritten the remote file. The file now lives in aTemporaryDirectory, named after the remote file.%in the ssh ProxyCommand (f3ef7c8, all platforms): OpenSSH expands%-tokens (%h,%p, ...) in ProxyCommand before running it. A session name or identity path containing%therefore either failed (unknown key %x) or was silently rewritten, for examplea%hbecamea<host>.%is now written as%%. Checked against OpenSSH 10.5p1 and OpenSSH_for_Windows_9.5p2.a&echo INJECTEDarrived as one literal argument. The command is passed to CreateProcess and split with the MSVCRT rules, which is exactly whatsubprocess.list2cmdlineproduces, so the quoting code was right and only the comments were wrong.f3ef7c8), all test-side:CommandLineToArgvWon Windows,DummyOutput,SIGHUPtests expect only the signals the platform has,--helpordering parser skips wrapped description lines,colab console(a0ea62e, all platforms):ESC[c, DA2ESC[>c, XTVERSIONESC[>qand the OSC 10/11 colour queries. The local terminal answers by typing the reply into its own input.ESC[?61;...c ESC[>0;10;1c.colab editwith a Windows$EDITOR(a0ea62e):click.editsplits$VISUAL/$EDITORwith POSIXshlexon every platform (click.editon Windows throws WinError 14001 or 87 pallets/click#3840), sopython D:\x\editor.pybecameD:xeditor.py.colab editsplits it withCommandLineToArgvW, resolves the program withshutil.which(so.cmdlaunchers such as VS Code'scodework), and starts the editor itself. POSIX, and click's own default editor, still go throughclick.edit.colab consoleon a fresh runtime (98ad068, all platforms):exit\nand closed the websocket itself a fixed 0.5s later (PIPED_EOF_GRACE_SECONDS). On a freshly started runtime the first attach often needs 0.5-1s before the shell answers, so the client closed first and nothing came back.exit(tmux[exited], thenon_close).echo cmd | ssh host, a piped command running longer than that is cut off.5beff34, all platforms):colab stopfrom another terminal, whilecolab exec(orrepl,run,drivemount) was running against the same session, ended that command with a jupyter_kernel_client traceback (RuntimeError: Connection was lost.).ColabRuntimenow raisesSessionConnectionLostinstead, and thecolabentry point prints one line with exit code 1: "Session 'X' was stopped, so the running command ended.", or, if the session is still known locally, "Lost the connection … check it withcolab status -s X".sessions.jsonin theirfinallyblocks, aftercolab stophad removed it, which left a stopped session behind locally. They now useStateStore.update_if_present, which only writes if the session is still recorded (under the same lock).ColabRuntimeconstructions did not passsession_name; they now do, so the message names the session.colab execnotebook control (29f8bfb,0f3ad51):colab exec -f nb.ipynbalways ran every code cell top to bottom and kept going after a failing cell. It exited 0 either way, so a script could not tell that a notebook had failed. A missing file or an unreadable notebook ended in a traceback.--cells SPEC: runs only the selected code cells, in the given order. SPEC accepts code-cell numbers (from 1, markdown cells not counted), ranges (2-5),#@titlevalues and cell ids. An entry that looks like a number or a range is always read as one; nbformat's random ids are occasionally all digits, so such cells are selected by number. An unknown or ambiguous entry is an error (exit 2) before anything runs.--stop-on-error: stops at the first cell with an error output; the partial outputs are still saved.execexits 1 when the code, or any notebook cell, raised, and lists the failed cells. This is a behaviour change, and it also applies to.pyfiles and stdin.--check/--check-only: a local pre-flight that runs before anything is sent. It validates the notebook, resolves--cells, and syntax-checks each selected cell; IPython!cmd,%magic,x = !cmdand top-levelawaitare accepted,%%cell magics are skipped, and line numbers are kept. If a check fails, nothing runs (exit 2).--check-onlyprints the plan without needing a session.How it was tested
test_state.py(test_write_lock_blocks_across_processes,test_readers_are_concurrent_across_processes) failed in one run on a busy machine and passed on rerun; they look timing-sensitive, and these commits do not touch the locking code.termios).colab execnotebook options, Linux (WSL), live, CPU runtime: I used a 3-cell notebook whose cell 2 raises.--checkon a notebook with a syntax error reportedcell 2 (Broken), line 2: expected ':'and ran nothing (exit 2).1 cell(s) raised an error: cell 2 (Two).--stop-on-errorstopped after cell 2 (1 cell(s) not run).--cells "Three,1"ran cell 3, then cell 1.File not found(exit 1).5beff34: I started a 2-minutecolab execand stopped its session from another process after 15s. It printed "[colab] Session 'losttest' was stopped, so the running command ended." with exit code 1, andsessions.jsonstayed empty.98ad068: 3 of 3 runs got their output. In one run the output arrived 1.08s afterexit, which the old 0.5s grace would have cut off. The backend closed the socket every time, so the 30s fallback was never used. Beforef3ef7c8, 30 tests failed and 1 hung. The new%test cases fail without the fix.colab console, I counted the events waiting in the console input buffer (CONIN$, viaPeekConsoleInputW). Beforea0ea62ethere were 41, containing the DA1 and DA2 replies; after it, none.colab editwithEDITOR=python D:\tool\...\fake_editor.py(unquoted backslashes), Windows, live: an existing and a new remote file both round-trip. Beforea0ea62ethe same setting failed with "can't open file 'D:\toolqwen21...'".colab new→colab drivemount→Credentials propagated. Resuming mount...→Mounted at /content/drive, exit code 0, confirmed withos.path.ismount('/content/drive') == True→colab stop. This is the same machine and account where 0.7.4 failed with "Connection was lost". With no browser available in WSL, the CLI printed "Could not launch a browser here. Open the link above." and the copy-the-link flow worked.oauth2login →colab new→colab exec(stdin) →colab console(piped) →colab drivemount→Credentials propagated. Resuming mount...→Mounted at /content/drive, confirmed withos.path.ismount('/content/drive') == True→colab stop. This was a single run with one Google account.colab edit, Windows: the two new regression tests (and the two existingedittests) fail withoutef19bd1and pass with it. Live on a CPU runtime with a scripted editor: editing an existing remote file and creating a new one both round-trip correctly, and no temporary directories are left behind.Correction
An earlier version of this post listed an issue where the update-check banner ran into the next line ("…settings.json[colab] Mounting…"). That was wrong. The CLI's raw output contains the line breaks (
settings.json\r\n\r\n[colab] …on Windows,\n\non Linux); they were only lost in the terminal view I was reading the output from.The changes were drafted with AI coding agents: Cursor wrote
c19ce50, and Claude Code wroteef19bd1,f3ef7c8,a0ea62e,98ad068,5beff34,29f8bfband0f3ad51. All the tests above were run on my own machines.All reactions