Repository navigation
Add native PowerShell support for Copilot CLI - #206
Ken Kuang (sykuang) wants to merge 3 commits into
Conversation
Reuse the Python bootstrap for native Windows hooks and CLI launchers, and select PowerShell in Copilot slash commands. Repair stable launchers on prompt submission as well as session start so already-open sessions do not fail with a missing te.ps1. Cover native shells, argument forwarding, interpreter discovery, and the missing-launcher regression. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e7520c60-7772-47ec-8bcf-90f5ec0785dc
Set the console input encoding before reading redirected hook JSON. Assert that the session preserves the exact non-ASCII working directory, and expose errors.log when fail-open hook behavior hides a startup error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e7520c60-7772-47ec-8bcf-90f5ec0785dc
Muhammad Abdullah Butt (1AbdullahButt)
left a comment
There was a problem hiding this comment.
I compared te.ps1 with the te and te-hook shell launchers at the PR head. They pick an interpreter in the same order: TE_PYTHON, python3, python, py, preferring one outside WindowsApps and probing the alias last. Both use py -3 and PYTHONUTF8=1, and both fail open with {} and an errors.log line when there is no Python. $OutputEncoding is a BOM-less UTF8Encoding, so the payload piped to Python doesn't start with a BOM. In ensure_launcher, the .ps1 body escapes ' by doubling it. The read-back comparison is stable on Windows because both the write and the read are in text mode.
Two points:
- The two Copilot hook forms use different variables.
commanduses${PLUGIN_ROOT}, and the newwindowsform uses$env:CLAUDE_PLUGIN_ROOT.hosts.detect(hosts.py:1243) already treatsCOPILOT_PLUGIN_ROOTas the variable Copilot sets for its hook processes.$env:COPILOT_PLUGIN_ROOTwould avoid depending on Copilot also exporting the Claude-compatible name. If Copilot does export all three, a line saying so in the README would help the next reader. - #194 (open) adds a minimum-version check to the shell launchers. It skips a
python3that is older than the bootstrap needs.te.ps1has no such check, so if #194 lands, the two launchers will choose interpreters differently.te_bootstrap.pystill refuses an old Python by itself (MIN_VERSION), so the result is a refusal, not a crash. Whichever PR lands second should probably copy the check.
I didn't run the PowerShell tests.
Reviewed with help from Claude Code.
Remove the dependency on CLAUDE_PLUGIN_ROOT in all six Windows hook commands. Exercise hook and slash-command execution with only COPILOT_PLUGIN_ROOT defined so the native root contract is covered. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: e7520c60-7772-47ec-8bcf-90f5ec0785dc
|
Thanks Muhammad Abdullah Butt (@1AbdullahButt). Addressed the root-variable point in 8466f75: all six Windows hooks now use For #194, I checked its current scope: it is still open and explicitly changes the POSIX branches only, leaving Windows untouched. I am keeping Windows version-aware interpreter selection out of this PR rather than pulling that separate change into it. The existing bootstrap minimum-version check still refuses an unsupported interpreter safely; Windows candidate-skipping can be handled in a separate follow-up. |
Summary
TE_PYTHON, preserve UTF-8 input, and prefer interpreters outside WindowsApps.bin/teandbin/te.ps1launchers on Windows.Bootstrap fix
Creating the stable launcher only at
SessionStartleft an already-open session withoutte.ps1. Slash commands then failed withCommandNotFoundException. Prompt hooks now create or repair the launchers before the command runs, and launcher-write errors are recorded inerrors.log.The regression executes the actual PowerShell blocks from the slash-command files after a prompt hook without a preceding session-start event. It failed with the reported missing-launcher error in both Windows PowerShell 5.1 and PowerShell 7 before the fix, and passes afterward.
Validation
python -m pytest tests\test_plugin_package.py tests\test_live_core.py tests\test_live_safety.py tests\test_hook_queue.py -q --tb=shorttoolprune refresh-catalogcommand.