Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions deploy/workspace/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ RUN mkdir -p /home/workspace/.codex && \
> /home/workspace/.codex/config.toml && \
chown -R workspace:workspace /home/workspace/.codex

# Configure GitHub Copilot MCP settings
RUN mkdir -p /home/workspace/.config/github-copilot && \
echo '{"mcpServers":{"agent-relay":{"command":"node","args":["/app/dist/src/cli/index.js","mcp","serve"]}}}' \
> /home/workspace/.config/github-copilot/mcp.json && \
chown -R workspace:workspace /home/workspace/.config/github-copilot

# Run entrypoint as root so it can start sshd; entrypoint drops to workspace via gosu
USER root

Expand Down
3 changes: 2 additions & 1 deletion deploy/workspace/Dockerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ RUN npm install -g \
@anthropic-ai/claude-code@2.1.17 \
@openai/codex@0.88.0 \
@google/gemini-cli@0.25.1 \
opencode-ai@1.1.34
opencode-ai@1.1.34 \
@github/copilot@0.0.395

# Create workspace directory structure
RUN mkdir -p /workspace /data
Expand Down
1 change: 1 addition & 0 deletions deploy/workspace/Dockerfile.browser
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ RUN npm install -g @anthropic-ai/claude-code@2.0.67
RUN npm install -g @openai/codex@0.78.0
RUN npm install -g @google/gemini-cli@0.22.5
RUN npm install -g opencode-ai@1.1.3
RUN npm install -g @github/copilot@0.0.395
# Install Playwright with browsers
RUN npm install -g playwright
RUN npx playwright install chromium firefox
Expand Down
1 change: 1 addition & 0 deletions deploy/workspace/Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ RUN npm install -g @anthropic-ai/claude-code@2.0.67
RUN npm install -g @openai/codex@0.78.0
RUN npm install -g @google/gemini-cli@0.22.5
RUN npm install -g opencode-ai@1.1.3
RUN npm install -g @github/copilot@0.0.395

# Create workspace directory structure
RUN mkdir -p /workspace /data
Expand Down
62 changes: 62 additions & 0 deletions packages/config/src/cli-auth-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,68 @@ export const CLI_AUTH_CONFIG: Record<string, CLIAuthConfig> = {
},
],
},
copilot: {
command: 'copilot',
args: ['auth', 'login'], // copilot auth login - triggers GitHub OAuth flow
deviceFlowArgs: ['auth', 'login', '--device'], // Device flow for headless environments
supportsDeviceFlow: true,
urlPattern: /(https:\/\/[^\s]+)/,
// Copilot uses gh CLI's auth - credentials stored via GitHub CLI config
credentialPath: '~/.config/gh/hosts.yml',
displayName: 'GitHub Copilot',
waitTimeout: 30000,
prompts: [
{
// Browser or device code selection
pattern: /login\s*with\s*a\s*code|one-time\s*code|device\s*code|browser|authenticate/i,
response: '\r', // Select first option (browser-based auth)
delay: 200,
description: 'Auth method selection',
},
{
// Press Enter to open browser
pattern: /press\s*enter\s*to\s*open|open.*browser|opening\s*browser/i,
response: '\r',
delay: 200,
description: 'Open browser prompt',
},
{
// Login success - press enter to continue
pattern: /login\s*successful|logged\s*in.*press\s*enter|press\s*enter\s*to\s*continue|authentication\s*complete/i,
response: '\r',
delay: 200,
description: 'Login success prompt',
},
{
// Generic enter prompt (fallback)
pattern: /press\s*enter|enter\s*to\s*(confirm|continue|proceed)/i,
response: '\r',
delay: 300,
description: 'Generic enter prompt',
},
],
successPatterns: [/success/i, /authenticated/i, /logged\s*in/i, /you.*(?:are|now).*logged/i, /authentication\s*complete/i],
errorPatterns: [
{
pattern: /oauth\s*error|auth.*failed|authentication\s*error/i,
message: 'GitHub authentication failed',
recoverable: true,
hint: 'Please try logging in again. Make sure you have GitHub Copilot access.',
},
{
pattern: /network\s*error|ENOTFOUND|ECONNREFUSED|timeout/i,
message: 'Network error during authentication',
recoverable: true,
hint: 'Please check your internet connection and try again.',
},
{
pattern: /no\s*copilot\s*access|copilot\s*not\s*enabled|subscription\s*required/i,
message: 'GitHub Copilot access not available',
recoverable: false,
hint: 'Your GitHub account needs an active Copilot subscription or organization access.',
},
],
},
};

/**
Expand Down
6 changes: 4 additions & 2 deletions packages/wrapper/src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export interface InjectionMetrics {
/**
* CLI types for special handling
*/
export type CliType = 'claude' | 'codex' | 'gemini' | 'droid' | 'opencode' | 'cursor' | 'spawned' | 'other';
export type CliType = 'claude' | 'codex' | 'gemini' | 'droid' | 'opencode' | 'cursor' | 'copilot' | 'spawned' | 'other';

/**
* Injection timing constants
Expand Down Expand Up @@ -293,6 +293,7 @@ export function detectCliType(command: string): CliType {
if (cmdLower.includes('droid')) return 'droid';
if (cmdLower.includes('opencode')) return 'opencode';
if (cmdLower.includes('cursor')) return 'cursor';
if (cmdLower.includes('copilot')) return 'copilot';
return 'other';
}

Expand All @@ -312,7 +313,7 @@ export const CLI_QUIRKS = {
* Others may interpret the escape sequences literally.
*/
supportsBracketedPaste: (cli: CliType): boolean => {
return cli === 'claude' || cli === 'codex' || cli === 'gemini' || cli === 'opencode' || cli === 'cursor';
return cli === 'claude' || cli === 'codex' || cli === 'gemini' || cli === 'opencode' || cli === 'cursor' || cli === 'copilot';
},

/**
Expand All @@ -335,6 +336,7 @@ export const CLI_QUIRKS = {
droid: /^[>›»]\s*$/,
opencode: /^[>›»]\s*$/,
cursor: /^[>›»]\s*$/,
copilot: /^[>›»]\s*$/,
spawned: /^[>›»]\s*$/,
other: /^[>$%#➜›»]\s*$/,
};
Expand Down
Loading