Repository navigation
fix(watch): Windows shell:true, shared agent-spawn, round-level fetch - #927
Merged
tamirdresher merged 5 commits intoApr 12, 2026
Merged
Conversation
…ithub#920, github#923) Three fixes for watch capabilities: 1. Shared issue fetch (github#923): Fetch issues + PRs ONCE at round start via new RoundData on WatchContext. All 4 capabilities that called adapter.listWorkItems() independently now read from context.roundData. Core triage (runCheck + checkPRs) also uses shared data. Reduces API calls from ~6 to 2 per round. 2. Windows execFile + shell:true (github#920): Added shell: IS_WINDOWS to every execFile/execFileSync call across the watch system, gh-cli.ts, and health.ts. Fixes 'spawn EINVAL' on Windows where bare commands like 'gh' resolve to .cmd wrappers that require a shell. 3. agentCmd default change: Default agent command changed from 'gh copilot' (deprecated) to standalone 'copilot'. Extracted duplicated buildAgentCommand() and spawnWithTimeout() from 7 files into shared agent-spawn.ts module. Files: - NEW: watch/agent-spawn.ts — shared buildAgentCommand, spawnWithTimeout, spawnAgent, IS_WINDOWS - watch/types.ts — added RoundData interface + roundData field on WatchContext - watch/index.ts — fetch once in executeRound(), pass roundData through - watch/capabilities/{decision-hygiene,monitor-teams,monitor-email,retro}.ts — use agent-spawn.ts - watch/capabilities/{execute,wave-dispatch}.ts — use agent-spawn.ts + roundData - watch/capabilities/{fleet-dispatch,two-pass}.ts — use roundData + shell:IS_WINDOWS - watch/capabilities/{board,self-pull}.ts — shell:IS_WINDOWS on all execFile calls - watch/health.ts — shell:IS_WINDOWS on gh auth check - core/gh-cli.ts — shell:IS_WINDOWS on all 6 execFileAsync calls
The default agent command changed from 'gh copilot' to standalone 'copilot' CLI. Updated test expectations accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add resolveCopilotCmd() that tries standalone 'copilot' first, falls back to 'gh copilot' if not found. Result is cached per process. Addresses Q's review of PR github#927: hardcoded 'copilot' default could break users without the standalone CLI installed. Both buildAgentCommand (shared) and buildAgentCommand (legacy compat) now use the same detection logic. Tests updated to accept either resolved command.
…t-dispatch - Remove unnecessary ChildProcess assignment in spawnAgent - Fleet-dispatch now uses runtime copilot detection instead of hardcoding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tamirdresher
added a commit
that referenced
this pull request
Apr 21, 2026
… fetch (#920, #923) * fix(watch): shared issue fetch, Windows shell:true, agentCmd default (#920, #923) Three fixes for watch capabilities: 1. Shared issue fetch (#923): Fetch issues + PRs ONCE at round start via new RoundData on WatchContext. All 4 capabilities that called adapter.listWorkItems() independently now read from context.roundData. Core triage (runCheck + checkPRs) also uses shared data. Reduces API calls from ~6 to 2 per round. 2. Windows execFile + shell:true (#920): Added shell: IS_WINDOWS to every execFile/execFileSync call across the watch system, gh-cli.ts, and health.ts. Fixes 'spawn EINVAL' on Windows where bare commands like 'gh' resolve to .cmd wrappers that require a shell. 3. agentCmd default change: Default agent command changed from 'gh copilot' (deprecated) to standalone 'copilot'. Extracted duplicated buildAgentCommand() and spawnWithTimeout() from 7 files into shared agent-spawn.ts module. Files: - NEW: watch/agent-spawn.ts — shared buildAgentCommand, spawnWithTimeout, spawnAgent, IS_WINDOWS - watch/types.ts — added RoundData interface + roundData field on WatchContext - watch/index.ts — fetch once in executeRound(), pass roundData through - watch/capabilities/{decision-hygiene,monitor-teams,monitor-email,retro}.ts — use agent-spawn.ts - watch/capabilities/{execute,wave-dispatch}.ts — use agent-spawn.ts + roundData - watch/capabilities/{fleet-dispatch,two-pass}.ts — use roundData + shell:IS_WINDOWS - watch/capabilities/{board,self-pull}.ts — shell:IS_WINDOWS on all execFile calls - watch/health.ts — shell:IS_WINDOWS on gh auth check - core/gh-cli.ts — shell:IS_WINDOWS on all 6 execFileAsync calls * test: update buildAgentCommand tests for copilot default The default agent command changed from 'gh copilot' to standalone 'copilot' CLI. Updated test expectations accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: add changeset for watch Windows fixes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(watch): runtime copilot CLI detection with gh fallback Add resolveCopilotCmd() that tries standalone 'copilot' first, falls back to 'gh copilot' if not found. Result is cached per process. Addresses Q's review of PR #927: hardcoded 'copilot' default could break users without the standalone CLI installed. Both buildAgentCommand (shared) and buildAgentCommand (legacy compat) now use the same detection logic. Tests updated to accept either resolved command. * fix(watch): remove unused _cp variable, use resolveCopilotCmd in fleet-dispatch - Remove unnecessary ChildProcess assignment in spawnAgent - Fleet-dispatch now uses runtime copilot detection instead of hardcoding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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
Three fixes for the
watch --executesubsystem, addressing Windows compatibility, API rate limiting, and code duplication.Closes #920, #923
What changed and why
Fix 1: Windows
shell: truefor allexecFilecalls (#920)Problem: On Windows, Node.js
execFile()cannot resolve bare command names through PATH or execute.cmd/.batfiles withoutshell: true. Every capability that spawnsgh,copilot,git, or other commands fails withspawn EINVAL.Fix: Added
shell: process.platform === 'win32'to all 37+execFilecallsites across:capabilities/board.ts(7 calls)capabilities/self-pull.ts(9 calls)capabilities/execute.tscapabilities/fleet-dispatch.tscapabilities/wave-dispatch.tscapabilities/two-pass.tscore/gh-cli.ts(6 calls)watch/health.tswatch/index.tsA shared
IS_WINDOWSconstant (process.platform === 'win32') is exported from the newagent-spawn.tsmodule.Fix 2: Shared agent spawn module (DRY)
Problem:
buildAgentCommand()was copy-pasted 7 times across capabilities (execute, fleet-dispatch, wave-dispatch, decision-hygiene, monitor-teams, monitor-email, retro). Each copy had slight variations and none included the Windows shell fix.Fix: Created
watch/agent-spawn.tswith:buildAgentCommand(prompt, context)— builds cmd + args fromagentCmdconfig or defaults to standalonecopilotCLIspawnWithTimeout(cmd, args, cwd, timeoutMs)— execFile with timeout + Windows shell supportspawnAgent(cmd, args, cwd, timeoutMs)— same but resolves with{success, error}instead of rejectingIS_WINDOWSconstantAll 7 capabilities now import from this single module. ~150 lines of duplication removed.
Default change: The default agent command changed from
gh copilot(deprecated) to standalonecopilotCLI. TheagentCmdconfig option overrides this.Fix 3: Shared round-level issue fetch (#923)
Problem: Each capability independently called
gh issue listandgh pr list, resulting in 6+ GitHub API calls per capability per round. With 7 capabilities enabled, that is 40+ API calls per round per repo. Running 4 repos simultaneously hits GitHub's 5000/hr rate limit within minutes.Fix: Added
RoundDatainterface totypes.ts:The main round runner in
index.tsfetches issues and PRs once per round and passes them viacontext.roundData. Capabilities that need issue/PR data read from the shared context instead of making their own API calls. This reduces API calls from ~40 to ~2 per round per repo.Files changed (16 files, +245 -222)
watch/agent-spawn.tswatch/types.tsRoundDatainterfacewatch/index.tsroundDatawatch/health.tsshell: IS_WINDOWScapabilities/board.tsshell: IS_WINDOWSon 7 execFile callscapabilities/self-pull.tsshell: IS_WINDOWSon 9 execFile callscapabilities/execute.tsspawnAgent()+roundDatacapabilities/fleet-dispatch.ts.cmdhack, shared spawn +roundDatacapabilities/wave-dispatch.tsspawnAgent()+roundDatacapabilities/two-pass.tsshell: IS_WINDOWS+roundDatacapabilities/decision-hygiene.tscapabilities/monitor-teams.tscapabilities/monitor-email.tscapabilities/retro.tscore/gh-cli.tsshell: IS_WINDOWSon all 6 execFile callstest/cli/watch-execute.test.tscopilotdefaultTesting
copilotdefault)spawn EINVALerrorsstorage-provider.test.ts(unicode paths),template-sync.test.ts(template content),team-root-resolution.test.ts(path resolution) — all unrelated to this PR