Skip to content

Bug: watch --execute fails — gh copilot --message is not a valid command #980

Closed

Description

@andikrueger

Summary

squad watch --execute has several bugs that prevent it from working. All are fixable. This issue documents root causes and tested fixes.

1. Wrong Copilot CLI invocation

execute.js buildAgentCommand uses gh copilot --message — neither --message nor gh copilot as a subcommand exist. The Copilot CLI binary is copilot (or gh copilot -- to pass through), and the non-interactive flag is -p.

Additionally, without permission flags, copilot answers in text but cannot do work (no file I/O, no shell, no git).

// Broken:
const args = ['copilot', '--message', prompt];
return { cmd: 'gh', args };

// Working:
const args = ['-p', prompt, '--yolo', '--no-ask-user', '--silent'];
return { cmd: 'copilot', args };

Use copilot directly, not gh copilot — on Windows gh is a .cmd batch file that opens a visible console window even with windowsHide: true.

2. Config file execute: true doesn't enable the capability

The CLI flag path (--execute) explicitly sets capabilities['execute'] = true. The config file path reads execute: true into config.execute but never maps it to config.capabilities. The preflight system only checks config.capabilities[cap.name] — so the capability silently doesn't load.

// Fix in loadWatchConfig (config.js), after the merge block:
if (merged.execute && !merged.capabilities['execute']) {
    merged.capabilities['execute'] = true;
}

3. Single prompt for all issues blocks Ralph

executeAll sends every eligible issue in one copilot prompt and waits synchronously (up to 30min timeout). Ralph can't poll or triage during this time.

Fix: Spawn one detached copilot process per issue (max N per round). Use spawn() with detached: true, stdio: 'ignore' so Ralph returns immediately. Track dispatched issue numbers in a state file to avoid re-dispatching on the next poll.

4. Console windows on Windows (MCP servers via npx)

Copilot spawns MCP servers (Context7, WorkIQ, Playwright) via npx, which is a .cmd batch file on Windows. Every .cmd invocation opens a visible console window — 10-15 of them per copilot session, coming and going.

windowsHide: true on the parent spawn does not propagate to grandchild processes.

Workaround: Use --config-dir pointing to a headless MCP config where stdio servers use node directly instead of npx:

{
  "mcpServers": {
    "Context7": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/node_modules/@upstash/context7-mcp/dist/index.js"]
    }
  }
}

node.exe is a real executable — no console window. HTTP-based MCP servers (Microsoft Docs, FluentUI) don't spawn subprocesses and work as-is.

Proper fix (in copilot CLI): When running in non-interactive mode (-p), copilot should spawn MCP stdio subprocesses with windowsHide: true or the Windows CREATE_NO_WINDOW flag. Alternatively, provide a --no-mcp or --headless flag.

5. No worktree isolation

Multiple copilot sessions in the same working directory cause git conflicts. Each issue should get its own worktree:

execFileSync('git', ['worktree', 'add', `../repo-${issue.number}`, '-b', `squad/${issue.number}-${slug}`, 'main']);
spawn('copilot', args, { cwd: worktreePath, detached: true, ... });

Recommended executeAll architecture

Per round (non-blocking):
  1. Load state file → skip already-dispatched issues
  2. Pick up to 3 eligible issues
  3. For each:
     a. git worktree add ../repo-{N} -b squad/{N}-{slug} main
     b. spawn('copilot', ['-p', prompt, '--yolo', '--no-ask-user', '--silent',
              '--config-dir', '.squad/.copilot-headless'],
              { cwd: worktreePath, detached: true, stdio: 'ignore', windowsHide: true })
  4. Save dispatched issue numbers to state file
  5. Return immediately → Ralph keeps polling

Environment

  • Squad CLI: v0.9.4-insider.1
  • OS: Windows 11
  • Copilot CLI: latest (WinGet)

All fixes tested and working locally via monkey-patches to the installed squad CLI.

Activity

  1. added 4 commits that reference this issue on Apr 16, 2026
    e9dec56
    5e53a54
    b7a38ac
    723f6e2
  2. added a commit that references this issue on Apr 17, 2026
    21587fb
  3. added a commit that references this issue on Apr 21, 2026
    fdc41a9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions