You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
_copilot_executable() in src/specify_cli/integrations/copilot/__init__.py
hardcoded copilot.cmd as the Windows executable name, assuming the GitHub
Copilot CLI was always installed via an npm global install (which wraps the
binary in a .cmd shim on Windows). Any other install channel — a standalone
installer, winget, scoop, or a signed native binary — puts copilot.exe
on PATH instead. Because Spec Kit never probed PATH, workflow/command-step
dispatch to the copilot integration failed outright for those installs on
Windows (copilot.cmd not found), even though a working Copilot CLI was
present.
Fix
_copilot_executable() now probes PATH on Windows with shutil.which,
preferring copilot.exe, then copilot.cmd, then falls back to the
historical copilot.cmd default if nothing is found (so the resulting
"command not found" error still references the previously expected name).
Non-Windows behavior ("copilot") is unchanged. The env-var override
(SPECKIT_INTEGRATION_COPILOT_EXECUTABLE) still takes precedence, unchanged.
This mirrors the fix suggested in the issue report.
Test evidence
Added three regression tests in tests/integrations/test_extra_args.py
that monkeypatch os.name and shutil.which to simulate the three Windows
scenarios: only copilot.exe present, only copilot.cmd present, and
neither present.
Confirmed the key regression test fails without the fix
(git checkout HEAD~1 -- src/specify_cli/integrations/copilot/__init__.py,
then restored):
Full suite (.venv/bin/python -m pytest): 10 failed, 8582 passed, 13 skipped.
The 10 failures are pre-existing *_python_parity tests (bash/PowerShell vs.
Python template-composition parity) unrelated to this change — confirmed by
running the same test files against the unmodified main branch, which
produces the identical 10 failures.
AI disclosure
Implemented autonomously by an OSS-contribution agent running Claude Code
(Claude Sonnet 5, claude-sonnet-5), operating without human line-by-line
review before this push. Extent: full code change and test authored by the
agent, based on the fix already suggested in the issue body; issue
investigation, prior-PR/claim search, and test verification (including the
before/after regression check) were also performed by the agent.
…ot.cmd
_copilot_executable() hardcoded the npm-shim name copilot.cmd on
Windows, so workflow command-step dispatch failed for any Copilot CLI
install that puts copilot.exe on PATH instead (standalone installer,
winget, scoop). Probe PATH for copilot.exe, then copilot.cmd, before
falling back to the historical default.
Fixesgithub#4755
Assisted-by: Claude Code (model: Claude Sonnet 5, autonomous)
Updated the _resolve_executable() docstring (lines 304-309) to describe the PATH-probing behavior instead of the stale copilot.cmd-always-on-Windows description. No behavior change; existing tests still pass (8 passed, 30 deselected).
shutil.which("copilot") can succeed for a copilot.bat or .com through PATHEXT, but this returns the bare name. Unlike IntegrationBase.dispatch_command, the Copilot override passes that name directly to subprocess.run, and CreateProcess does not consult PATHEXT (src/specify_cli/integrations/base.py:449-454), so this branch detects an executable it cannot launch. Limit the probe to the two documented launchable names, or return the resolved path.
tests/test_workflows.py::test_copilot_exec_args still hardcodes copilot.cmd whenever os.name == "nt" (line 1030). With this new PATH-dependent result, that existing test fails on a Windows runner where copilot.exe is installed. Update it to mock shutil.which or derive the expectation from _copilot_executable() so the Windows test matrix remains deterministic.
Test executable preference when both Copilot variants are available
tests/integrations/test_extra_args.py:652
Despite the test name, this mock makes only copilot.exe available, so reversing the candidate order to prefer copilot.cmd would still pass all three new tests. Make both .exe and .cmd discoverable here while retaining the cmd-only test below to lock in the promised preference behavior.
…rministic
Copilot bot review flagged three issues: the bare "copilot" candidate in
_copilot_executable() can match a .bat/.com via PATHEXT that
CreateProcess can't actually launch; test_copilot_exec_args hardcoded
copilot.cmd for os.name == "nt" instead of deriving it from
_copilot_executable(), making it non-deterministic on a real Windows
runner; and the "prefers .exe" test only mocked .exe being present, so
it didn't actually lock in preference over .cmd.
Addressed the three Copilot review findings from the latest pass:
Dropped the bare "copilot" PATH candidate — CreateProcess doesn't consult PATHEXT, so a match there (e.g. a .bat/.com) could never actually launch. Added a regression test (test_copilot_executable_windows_ignores_unlaunchable_bare_name) proving it now falls back to copilot.cmd instead.
tests/test_workflows.py::test_copilot_exec_args now derives its expectation from _copilot_executable() instead of hardcoding copilot.cmd for os.name == "nt", so it stays deterministic on a Windows runner regardless of what's actually on PATH.
test_copilot_executable_windows_prefers_exe_on_path now mocks both copilot.exe and copilot.cmd as present, so it actually locks in the .exe-over-.cmd preference rather than passing vacuously.
Full suite (.venv/bin/python -m pytest): 8593 passed, 13 skipped. uvx ruff@0.15.0 check src tests: all checks passed.
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
triage-nice-to-haveVerdict: evidence-backed fix or greenlit feature — land after review
3 participants
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 #4755
Problem
_copilot_executable()insrc/specify_cli/integrations/copilot/__init__.pyhardcoded
copilot.cmdas the Windows executable name, assuming the GitHubCopilot CLI was always installed via an npm global install (which wraps the
binary in a
.cmdshim on Windows). Any other install channel — a standaloneinstaller,
winget,scoop, or a signed native binary — putscopilot.exeon
PATHinstead. Because Spec Kit never probedPATH, workflow/command-stepdispatch to the
copilotintegration failed outright for those installs onWindows (
copilot.cmdnot found), even though a working Copilot CLI waspresent.
Fix
_copilot_executable()now probesPATHon Windows withshutil.which,preferring
copilot.exe, thencopilot.cmd, then falls back to thehistorical
copilot.cmddefault if nothing is found (so the resulting"command not found" error still references the previously expected name).
Non-Windows behavior (
"copilot") is unchanged. The env-var override(
SPECKIT_INTEGRATION_COPILOT_EXECUTABLE) still takes precedence, unchanged.This mirrors the fix suggested in the issue report.
Test evidence
Added three regression tests in
tests/integrations/test_extra_args.pythat monkeypatch
os.nameandshutil.whichto simulate the three Windowsscenarios: only
copilot.exepresent, onlycopilot.cmdpresent, andneither present.
Confirmed the key regression test fails without the fix
(
git checkout HEAD~1 -- src/specify_cli/integrations/copilot/__init__.py,then restored):
With the fix, all three new tests plus the existing Copilot executable/extra-args
tests pass:
Full suite (
.venv/bin/python -m pytest):10 failed, 8582 passed, 13 skipped.The 10 failures are pre-existing
*_python_paritytests (bash/PowerShell vs.Python template-composition parity) unrelated to this change — confirmed by
running the same test files against the unmodified
mainbranch, whichproduces the identical 10 failures.
AI disclosure
Implemented autonomously by an OSS-contribution agent running Claude Code
(Claude Sonnet 5,
claude-sonnet-5), operating without human line-by-linereview before this push. Extent: full code change and test authored by the
agent, based on the fix already suggested in the issue body; issue
investigation, prior-PR/claim search, and test verification (including the
before/after regression check) were also performed by the agent.
🤖 Generated with Claude Code