fix: Copilot runtime — model aliases, hooks support, auto-detect & folder trust#77
Merged
jayminwest merged 17 commits intomainfrom Mar 23, 2026
Merged
fix: Copilot runtime — model aliases, hooks support, auto-detect & folder trust#77jayminwest merged 17 commits intomainfrom
jayminwest merged 17 commits intomainfrom
Conversation
lucabarak
approved these changes
Mar 5, 2026
Collaborator
lucabarak
left a comment
There was a problem hiding this comment.
Code looks clean — nice separation with the hooks deployer as its own module, and the ensureCopilotTrustedFolders tests are thorough (the invalid JSON recovery + dedup edge cases are great).
A couple small things:
- The PR body doesn't include
Fixes #72,Fixes #74,Fixes #76— adding those would auto-close the issues on merge.
I don't have Copilot CLI installed to test the integration, so I can't validate the hook schema or config path against the real CLI. @karlis-balcers would be the one to confirm those.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add MODEL_MAP to copilot.ts mapping sonnet/opus/haiku to fully-qualified names (claude-sonnet-4-6, claude-opus-4-6, claude-haiku-4-5) - Add expandModel() method applied in buildSpawnCommand() and buildPrintCommand() - Check waitForTuiReady() return value in sling.ts; throw AgentError on timeout/dead pane instead of sending keys to a dead tmux session Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-detects installed coding agent runtimes (claude, copilot, gemini, opencode, sapling, pi) and sets runtime.default in generated config.yaml. Falls back to 'claude' when nothing is detected. Uses existing Spawner abstraction for testability. Adds 10 tests covering priority order, fallback, and integration with initCommand. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add optional prepareWorktree?(worktreePath) to AgentRuntime interface - Implement ensureCopilotTrustedFolders() in copilot.ts that writes worktree path to ~/.config/github-copilot/config.json trustedFolders - Add CopilotRuntime.prepareWorktree() calling the above (non-fatal errors) - Call runtime.prepareWorktree() in sling.ts after worktree creation - Add 9 tests for ensureCopilotTrustedFolders and prepareWorktree Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-resolve merge dropped the MODEL_MAP constant, causing expandModel() to reference an undefined variable. Restores the mapping and fixes two pre-existing Biome formatting issues. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add templates/copilot-hooks.json.tmpl with onSessionStart hooks
(ov prime + ov mail check --inject) using ENV_GUARD pattern
- Add src/agents/copilot-hooks-deployer.ts with deployCopilotHooks()
that reads template, substitutes {{AGENT_NAME}}, prepends PATH_PREFIX,
and writes to .github/hooks/hooks.json
- Wire CopilotRuntime.deployConfig() to call deployCopilotHooks()
- Add tests for deployer (template health, substitution, PATH_PREFIX,
schema structure, directory creation)
- Add tests for deployConfig hooks.json output in copilot.test.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ment) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83873f9 to
c539686
Compare
detectDefaultRuntime calls spawner(["which", ...]) which throws when the spawner is broken (e.g. ENOENT). This broke the existing spawner error resilience tests. Wrapping in try/catch with a "claude" fallback matches the graceful degradation pattern used by ecosystem tool onboarding. Co-Authored-By: Claude Opus 4.6 (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.
Summary
Addresses three Copilot runtime issues reported by @karlis-balcers:
copilotCLI, causing agent spawn failure #72 — Model alias expansion (sonnet→claude-sonnet-4-6, etc.) + abort sling on TUI ready failureov prime+ov mail check)ov initand pre-trust worktree folders inov sling#76 —detectDefaultRuntime()inov init+prepareWorktree()for Copilot folder trustChanges
src/runtimes/copilot.tsMODEL_MAP,expandModel(),prepareWorktree(),ensureCopilotTrustedFolders(), wireddeployCopilotHooks()indeployConfig()src/runtimes/types.tsprepareWorktree()onAgentRuntimeinterfacesrc/commands/sling.tsprepareWorktree()before spawn, abort onwaitForTuiReadyfailuresrc/commands/init.tsdetectDefaultRuntime()viawhichcheckssrc/agents/copilot-hooks-deployer.ts.github/hooks/hooks.jsonfor Copilottemplates/copilot-hooks.json.tmplI don't have a Copilot CLI subscription, so none of this has been tested against a real Copilot session. The implementation is based on your excellent reverse-engineering analysis in #74. Key things to verify:
copilot --model claude-sonnet-4-6actually work?.github/hooks/hooks.jsonwith theversion: 1schema?~/.config/github-copilot/config.jsonthe right path, and doestrustedFoldersprevent the trust dialog?Note on commit history
This was built by an agent swarm, so the history includes merge commits and sync noise. Happy to squash if preferred.
Test plan
bun testpasses🤖 Generated with Claude Code