Skip to content

Latest commit

 

History

History
142 lines (113 loc) · 6.95 KB

File metadata and controls

142 lines (113 loc) · 6.95 KB

Server

Running the Service Manually

cd server/

# Development — OS assigns a free port; actual address printed to stderr
go run .

# Pin to a specific port (useful for curl testing)
go run . \
  -addr 127.0.0.1:8088 \
  -cwd /path/to/workspace \
  -cli-path /path/to/@github/copilot/index.js \
  -lsp=true      # default: true — LSP server on stdio

# LSP-only helper that connects to an existing HTTP service
go run . \
  -lsp-only \
  -service-url http://127.0.0.1:8088

# Build a binary
go build -o copilot-agent .
./copilot-agent          # dynamic port
./copilot-agent -addr 127.0.0.1:8088   # fixed port

Flags:

Flag Default Description
-addr (free port) HTTP listen address; empty or :0 → OS picks
-port-range Try ports lo–hi (e.g. 18000-19000); first free wins
-cwd current dir Default working directory for sessions
-model (sdk default) Default model for new sessions
-cli-path auto-detected Path to Copilot CLI binary/JS entrypoint
-cli-url URL of an already-running Copilot CLI server
-log-level Copilot CLI log level
-log-file stderr only Mirror service logs to a file with INFO/WARN/ERROR prefixes
-lsp true Start LSP server on stdio
-lsp-only false Start only the LSP server and reuse an existing HTTP service
-service-url HTTP base URL used by -lsp-only

The service always prints COPILOT_AGENT_ADDR=127.0.0.1:<PORT> to stderr once the listener is bound. When auto_start = true, the plugin reads this line and configures its HTTP client automatically — no manual base_url needed.

Service log lines are prefixed with [INFO], [WARN], or [ERROR] when -log-file is set.

When -client-lease-dir is configured, detached-service shutdown is delayed by the lease watcher grace window. Current defaults (from server/main.go) are: clientLeasePollInterval = 500ms and clientLeaseEmptyGrace = 5m (i.e. the lease directory must stay empty for five minutes before shutdown).


HTTP API Reference

Method Path Description
GET /healthz Health check
GET /sessions List all sessions (live + persisted)
POST /sessions Create or resume a session
GET /sessions/{id} Get live session metadata
DELETE /sessions/{id} Disconnect; ?delete=true removes persisted state
GET /sessions/{id}/messages Fetch stored session events
POST /sessions/{id}/messages Send a prompt with optional attachments
GET /sessions/{id}/events SSE stream of session + host events
POST /sessions/{id}/user-input/{reqID} Answer a pending ask_user request
POST /sessions/{id}/permission/{reqID} Answer a pending permission request (interactive mode)
POST /sessions/{id}/permission-mode Update permission mode on a live session
POST /sessions/{id}/model Switch model for a live session
POST /sessions/{id}/tools Update excluded tools list
GET /models List available models

Permission modes for POST /sessions

{ "permissionMode": "interactive" }   // prompt Neovim UI per tool use
{ "permissionMode": "approve-all" }   // auto-approve everything
{ "permissionMode": "autopilot" }     // approve-all + auto-answer user inputs
{ "permissionMode": "reject-all" }    // reject all tool uses

SSE Event Types

Event Description
session.event Raw SDK events (assistant.message_delta, assistant.turn_end, etc.)
host.user_input_requested Agent needs user input — reply via POST .../user-input/{id}
host.permission_requested Tool use needs approval (interactive mode) — reply via POST .../permission/{id}
host.permission_decision Logged approval/rejection outcome
host.permission_mode_changed Permission mode updated on live session
host.model_changed Model switched on live session
host.session_disconnected Session was closed
: keepalive SSE keepalive comment (ignore)

Quick Start (HTTP API)

# Terminal 1: start the service using the pre-built binary (no Go needed)
# Download it first with :CopilotAgentInstall inside Neovim, then:
~/.local/share/nvim/lazy/copilot-agent.nvim/bin/copilot-agent

# Or build from source (requires Go 1.24+)
cd server/ && go run . -cli-path ~/.local/share/github-copilot/index.js
# prints: COPILOT_AGENT_ADDR=127.0.0.1:XXXXX

# Terminal 2: create a session (replace port)
curl -s -X POST http://127.0.0.1:XXXXX/sessions \
  -H 'Content-Type: application/json' \
  -d '{"workingDirectory":".","permissionMode":"approve-all","clientName":"test"}'

# Stream events (replace SESSION_ID)
curl -N http://127.0.0.1:XXXXX/sessions/SESSION_ID/events

# Send a message
curl -X POST http://127.0.0.1:XXXXX/sessions/SESSION_ID/messages \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"Explain what this project does."}'

Testing

# Go tests (vet, fmt, unit tests, build)
cd server/
go vet ./...
go test -race ./...
go build ./...

# Lua unit tests (no Neovim required)
busted --lpath='lua/?.lua;lua/?/init.lua' tests/unit/

# Neovim integration tests (requires nvim on PATH)
nvim --headless -u tests/minimal_init.lua \
  -c "PlenaryBustedFile tests/integration/setup_spec.lua"

CI runs all of the above automatically on push and PR via GitHub Actions.