Skip to content

fix(hooks): emit env and stop picking the Copilot command field by platform - #2621

Merged
dyoshikawa merged 2 commits into
mainfrom
resolve-issue-2401-copilot-hooks-env-shell
Aug 7, 2026
Merged

fix(hooks): emit env and stop picking the Copilot command field by platform#2621
dyoshikawa merged 2 commits into
mainfrom
resolve-issue-2401-copilot-hooks-env-shell

Conversation

@dyoshikawa

Copy link
Copy Markdown
Owner

Two bugs in src/features/hooks/copilot-hooks.ts, both from the 2026-08-06 comment.

env was never emitted. The unknown-key passthrough filters out every key in HookDefinitionSchema, and env is canonical, so an authored env was dropped on the floor - even though Copilot supports it natively on command hooks. It is now emitted explicitly, the way copilotcli-hooks.ts:239-248 already does.

The command field was chosen from process.platform. .github/hooks/copilot-hooks.json is committed to the repository, so the artifact differed depending on which machine ran generate. Worse, the docs are explicit that the cloud agent "runs hooks in a Linux sandbox. Only the bash field is honored; powershell entries are ignored" - so a file generated on Windows was simply inert. The field now follows the canonical shell selector, falling back to the portable command field (which upstream copies to both), exactly as the Copilot CLI adapter does.

Import made platform-independent too

Beyond the assigned scope, but the same bug class: resolveImportCommand broke a bash+powershell tie using process.platform, so importing one file produced different canonical configs on different machines. It now always takes bash - the only field the cloud agent runs - and warns. Import also records the shell selector and reads env, so both round-trip.

Note on the test changes

Nine existing tests asserted the platform-dependent behavior directly (should use powershell field on Windows and friends). Those encode the bug being fixed, so they are rewritten rather than kept: two became shell-selector tests, one asserts the generated file is byte-identical across win32 and linux, and the rest had incidental entry.bash assertions updated to entry.command. New coverage: env emission, and a round-trip of the shell selector plus env through import and re-export.

Verified against the hooks reference; checked locally with the hooks e2e spec.

Part of #2401

The issue's other items - edits/urls autoApprove permissions, MCP inputs/sandbox, and global hooks scope - are untouched and remain open.

🤖 Generated with Claude Code

…atform

canonicalToCopilotHooks filtered every canonical key out of its
passthrough, so an authored env never reached copilot-hooks.json even
though Copilot supports it natively on command hooks.

It also chose between the bash and powershell fields from
process.platform. That file is committed to the repository, so the
artifact differed by generating machine, and the cloud agent runs hooks
in a Linux sandbox where a powershell entry is ignored outright - a
Windows-generated file was unusable. The field now follows the canonical
shell selector, falling back to the portable command field, mirroring
copilotcli-hooks.ts.

Import is made platform-independent for the same reason: an entry
carrying both fields resolves to bash everywhere, and the shell selector
and env now round-trip.
…lector

Three spots still described the platform-based choice this branch
removed: the Copilot format note, the per-tool event summary, and the
canonical shell field, which now lists both Copilot targets among its
consumers.

The rationale is also restated: the load-bearing problem is that the
Linux-sandboxed cloud agent ignores a powershell entry outright, so a
Windows-generated hook never ran. Output stability is the secondary
benefit, and only for users who check the file in - rulesync gitignores
its own generated copy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants