Skip to content

feat(copilot): prompt flag fix + ACP provider support#31

Open
EmmittJ wants to merge 5 commits intogastownhall:mainfrom
EmmittJ:fix/copilot-prompt-flag
Open

feat(copilot): prompt flag fix + ACP provider support#31
EmmittJ wants to merge 5 commits intogastownhall:mainfrom
EmmittJ:fix/copilot-prompt-flag

Conversation

@EmmittJ
Copy link

@EmmittJ EmmittJ commented Mar 20, 2026

Summary

Brings the built-in Copilot provider to parity with Claude as a first-class ACP provider in Gas City.

Changes

Fix: --prompt flag delivery

The Copilot provider was configured with prompt_mode = "arg", passing prompts as bare positional arguments. Copilot CLI expects --prompt <text> instead.

  • provider.go: Switch copilot from PromptMode: "arg"PromptMode: "flag", PromptFlag: "--prompt"
  • runtime.go: Add PromptMode/PromptFlag fields to runtime.Config
  • tmux/adapter.go: Insert the flag before the prompt payload in all three command-build paths (temp-file, inline fallback, short inline)
  • template_resolve.go: Wire PromptMode/PromptFlag from ResolvedProvider into runtime.Config (nil-guarded)

Feat: ACP support for Copilot

  • provider.go: Add SupportsACP: true, ACPArgs: ["--acp", "--stdio"], ResumeFlag, ResumeStyle, PermissionModes, OptionsSchema to copilot builtin; add ACPArgs []string field to ProviderSpec and ResolvedProvider
  • compose.go: Handle acp_args slice merging in deepMergeProvider
  • resolve.go: Copy ACPArgs in specToResolved
  • template_resolve.go: Append ACPArgs to command when session = "acp"

Fix: ACP protocol correctness for Copilot

Copilot's ACP server uses strict schema validation. Several protocol issues required fixing:

  • --stdio flag: copilot --acp alone starts a TCP server; --stdio switches it to JSON-RPC over stdin/stdout (required for Gas City's pipe-based adapter). This flag is not shown in copilot --help but is accepted.
  • protocolVersion: Added integer field (1) to InitializeParams — omitting it causes -32603 Internal error: expected number, received undefined
  • session/new params: Copilot requires both cwd (string) and mcpServers (array) — sending null or {} returns a validation error; added SessionNewParams + MCPServer structs and wired workDir through to the handshake
  • Removed initialized notification: Gas City was sending an MCP lifecycle notification between initialize and session/new; this is not part of the ACP spec and Copilot hangs on it
  • Handshake timeout: Bumped default from 30s → 60s; Copilot fetches available models from the GitHub API during session/new which takes ~5s

Testing

go test ./internal/config/ ./internal/runtime/... ./cmd/gc/

Verified end-to-end: gc session new mayor with session = "acp" successfully starts a Copilot ACP process (copilot --yolo --acp --stdio --prompt ...) and transitions the session to awake.

@EmmittJ EmmittJ requested a review from julianknutsen as a code owner March 20, 2026 03:18
@EmmittJ EmmittJ changed the title fix(copilot): use --prompt flag for prompt delivery feat(copilot): prompt flag fix + ACP provider parity Mar 20, 2026
@EmmittJ EmmittJ force-pushed the fix/copilot-prompt-flag branch from c9f80ce to f8cdc05 Compare March 20, 2026 03:49
@EmmittJ EmmittJ marked this pull request as draft March 20, 2026 04:40
EmmittJ and others added 5 commits March 20, 2026 07:21
Copilot CLI expects prompts via `-p`/`--prompt <text>`, not as a bare
positional argument.  Switch the built-in copilot provider from
PromptMode "arg" to "flag" with PromptFlag "--prompt".

Wire PromptMode and PromptFlag through runtime.Config so the tmux
adapter inserts the flag before the prompt payload in all code paths
(temp-file, inline, and fallback).

Guard the ResolvedProvider dereference in templateParamsToConfig with
a nil check to prevent a panic when no provider is resolved.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enable Copilot as a first-class ACP provider, bringing it to parity
with Claude for Gas City orchestration:

- SupportsACP: true — Copilot speaks ACP (JSON-RPC 2.0 over stdio)
- ACPArgs: ["--acp"] — new ProviderSpec field for ACP-specific CLI
  flags, appended to the command when session = "acp". Unlike Claude
  (which auto-detects pipe mode), Copilot requires an explicit --acp
  flag.
- ResumeFlag: "--resume" with ResumeStyle: "flag" for session resume
- PermissionModes: map unrestricted → --yolo
- OptionsSchema: permission_mode and model selectors for Mission Control

Wire ACPArgs through the full config pipeline:
  ProviderSpec → compose (deepMergeProvider) → resolve (specToResolved)
  → ResolvedProvider → template_resolve (command construction)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
copilot --acp starts a TCP server waiting for connections, not a
stdio-based JSON-RPC process. The --stdio flag switches it to use
stdin/stdout for ACP communication, which is what Gas City's ACP
adapter expects when piping JSON-RPC messages.

Without --stdio, Gas City's ACP handshake hangs indefinitely until
the handshake_timeout fires, causing sessions to appear stuck in
'creating' state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…quest

Copilot's ACP implementation requires protocolVersion (integer) in the
initialize params — omitting it returns a -32603 Internal error:
'expected number, received undefined'. This caused every ACP handshake
to silently fail and sessions to hit the 30s handshake timeout.

Also add clientCapabilities (terminal + fs) to match what the go-acp
library and Legion's vessel-driver send.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…notification

Copilot requires both 'cwd' and 'mcpServers' fields in session/new params
(null or empty object returns -32603). Add SessionNewParams struct with
required fields; mcpServers sent as empty array when none configured.

Remove the 'initialized' notification between initialize and session/new —
ACP does not define this step (it's an MCP concept) and Copilot ignores it.

Bump default handshake_timeout from 30s to 60s since session/new triggers
a model list fetch from GitHub API (~5s on good networks).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@EmmittJ EmmittJ changed the title feat(copilot): prompt flag fix + ACP provider parity feat(copilot): prompt flag fix + ACP provider support Mar 20, 2026
@EmmittJ EmmittJ force-pushed the fix/copilot-prompt-flag branch from d69a6db to 4a7b1ae Compare March 20, 2026 14:56
@EmmittJ EmmittJ marked this pull request as ready for review March 20, 2026 14:59
@EmmittJ
Copy link
Author

EmmittJ commented Mar 20, 2026

@julianknutsen this should be good for review. If you would like me to split anything out, let me know.

EmmittJ added a commit to EmmittJ/gascity that referenced this pull request Mar 20, 2026
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.

1 participant