Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

agent-codespaces

GitHub Codespaces lifecycle management, SSH transport, and credential relay for Copilot CLI.

Overview

A copilot-extensions plugin that provides:

  • SSH transport -- multiplexed SSH connections to CodeSpaces via ssh-manager, wrapping gh codespace ssh --config
  • Lifecycle management -- create, delete, list, and status for CodeSpaces
  • Credential relay -- forward git credentials, GitHub tokens, and Azure tokens to CodeSpaces over SSH tunnels (pluggable sources: git-credential, gh-auth, az-login)
  • Agent-bridge provider -- register CodeSpaces as dynamic agents in agent-bridge for inter-agent communication

Configuration

All configuration lives in the adopting repo in a codespaces.yaml file. The service reads config live from adopted repos -- no generated intermediate config.

# codespaces.yaml
defaults:
  machine_type: largePremiumLinux
  location: EastUs

credentials:
  sources:
    git-credential:
      enabled: true
      allowed_hosts:
        - "*.visualstudio.com"
        - "dev.azure.com"
    gh-auth:
      enabled: true
      allowed_hosts:
        - "github.com"
    # az-login:                        # Azure token relay (disabled by default)
    #   enabled: false
    #   allowed_resources:
    #     - "https://management.azure.com/"

repos:
  org/my-repo:
    machine_type: largePremiumLinux256gb
    location: EastUs

CLI

agent-codespaces ssh <name>           # SSH into a CodeSpace
agent-codespaces ssh --stdio <name>   # Structured SSH for agent-bridge
agent-codespaces list                 # List active CodeSpaces
agent-codespaces create <owner/repo>  # Create a CodeSpace + run provisioning
agent-codespaces delete <name>        # Delete a CodeSpace (--force to skip prompt)
agent-codespaces config adopt         # Register repo for config
agent-codespaces config init          # Scaffold codespaces.yaml from your CodeSpaces
agent-codespaces config show          # Show resolved config
agent-codespaces bridge register      # Register CodeSpaces as bridge agents
agent-codespaces cleanup              # Remove stale local state (SSH configs, sockets)
agent-codespaces status               # Service + relay + tunnel state
agent-codespaces version              # Show version

create options

agent-codespaces create <owner/repo> \
  --branch <branch> \           # branch to create on (default: repo default)
  --display-name <name> \       # CodeSpace display name
  --timeout 300 \               # seconds to wait for Available (default 300)
  --no-wait                     # don't wait / skip provisioning

Machine type and location come from codespaces.yaml (per-repo overrides apply). After the CodeSpace is Available, on_create provisioning hooks from codespaces.yaml run automatically.

bridge options

Usually unnecessary. Once agent-codespaces is installed, agent-bridge auto-registers the live codespace: namespace resolver, so CodeSpaces are addressable as codespace:<name> (raw or friendly) with no registration. bridge register only POSTs a static cs-<name> snapshot (with a TTL) for HTTP consumers that prefer a pre-registered provider list; it is optional and superseded by the resolver.

agent-codespaces bridge register   [--ttl 300] [--bridge-url <url>]
agent-codespaces bridge refresh    [--ttl 300] [--bridge-url <url>]
agent-codespaces bridge status     [--bridge-url <url>]
agent-codespaces bridge unregister [--bridge-url <url>]

Linux/WSL: the bridge defaults to port 9281, but these commands default --bridge-url to http://127.0.0.1:9280. On Linux/WSL pass --bridge-url http://127.0.0.1:9281 explicitly.

Credential relay: fail-fast & auth verification

The relay forwards git-credential requests from a CodeSpace back to the host over the SSH tunnel, resolving them through the host's Git Credential Manager (GCM) — which serves both GitHub (github.com) and Azure DevOps (*.visualstudio.com, dev.azure.com) credentials.

To avoid the failure mode where a missing/expired credential causes a CodeSpace git fetch to hang indefinitely on git credential fill:

  • Host GCM runs non-interactively (GIT_TERMINAL_PROMPT=0, GCM_INTERACTIVE=never), so it errors fast instead of blocking on a prompt.
  • The relay replies quit=1 when a git get/fill request can't be resolved, which makes git in the CodeSpace abort immediately (fatal: credential helper ... told us to quit) rather than dropping to an interactive prompt. CodeSpace SSH sessions also export GIT_TERMINAL_PROMPT=0.
  • On connect, remote-domain auth is verified up front: the workspace's git remote -v domains are probed against the host credential store, and any domain lacking local auth is reported as a [WARN] so it can be fixed (az login / GCM sign-in) before work begins, rather than discovered mid-fetch.

Local identifier guard

This is a public repo, so internal org/account/repo names and personal aliases must never land in it. The generated codespaces.yaml scaffold is checked for such leaks by tests/test_config_init.py, and the whole working tree by tools/check-no-internal-identifiers.py (wire it up as a git pre-push hook).

A denylist that named those identifiers would itself leak them, so it is never stored in the repo. Both guards read it privately from:

  1. env COPILOT_EXTENSIONS_FORBIDDEN_IDS (comma-separated), and
  2. ~/.agent-codespaces/forbidden-identifiers.txt (one per line; blank lines and # comments ignored).

With neither configured (a fresh clone / CI) the identifier check is a no-op, so the guards are safe to ship. Populate one of the sources on your own machine — e.g.:

# ~/.agent-codespaces/forbidden-identifiers.txt
my-internal-org
my-internal-repo
my-alias

Matching is case-insensitive (substring). The host file lives in $HOME, outside any repo, so it is never committed.

Development

cd plugins/agent-codespaces
pip install -e ".[dev]" -e "../../libs/ssh-manager[dev]"
pytest tests/