Repository navigation
feat(registry/coder-labs/modules/copilot): migrate off AgentAPI and Tasks - #1117
Conversation
…oder Tasks Refactor the copilot module to install and configure Copilot only, matching the claude-code and codex v5 migrations: - Replace the agentapi module with coder-utils; drop Tasks/web-app/CLI-app and AgentAPI variables and the start script. - Install Copilot via the official install script (temp file + bash -n validation) instead of npm; no Node.js prerequisite. - Make workdir optional; write config.json and merge mcp_config into ~/.copilot; pass copilot_model through as given. - Add enable_ai_gateway using Copilot BYOK provider env vars; keep github_token (GITHUB_TOKEN + GH_TOKEN). - Output scripts; rewrite README and tests. Generated with Coder Agents.
Module Scorecard Check
|
| Presentation & Onboarding | Agent Integration | Credential Hygiene | Restricted-Environment Readiness | Engineering Quality | Overall |
|---|---|---|---|---|---|
| 12 / 17 | 15 / 25 | 20 / 20 | 6 / 20 | 10 / 10 | 68 / 100 |
Drilldown
Presentation & Onboarding — 12 / 17
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Configuration-mode examples | 12 | 12 | README documents each major mode: external auth, direct token, AI Gateway proxy, advanced config (managed_settings, base_copilot_config, mcp, pre_install_script), and downstream script serialization. Sensible defaults are shown in the basic example. |
| Visual preview | 5 | 0 | No image, GIF, or video embedded in the README. The frontmatter icon field and the coder_app icon reference are not visual previews of the module in action. |
Agent Integration — 15 / 25
| Criterion | Max | Score | Notes |
|---|---|---|---|
| AI governance | 10 | 5 | AI Gateway Proxy is documented with a full example (enable_ai_gateway, ai_gateway_proxy_auth_url, ai_gateway_proxy_cert_path). No mention of Agent Firewall anywhere in the README or code. Exactly one of two required → half. |
| Dashboard entry point | 5 | 5 | The "Launcher app with GitHub external auth" example includes a complete coder_app resource with slug, display_name, icon, open_in = "slim-window", and a launch command. |
| Session continuity | 5 | 0 | No documentation of session resumption, session IDs, or persistent session managers (tmux, screen, boo). The coder_app command launches copilot --allow-all-tools fresh each time with no resume mechanism. |
| Managed configuration | 5 | 5 | Three documented managed-config inputs: managed_settings (written to /etc/github-copilot/managed-settings.json), base_copilot_config (overwrites ~/.copilot/settings.json), and mcp (merged into ~/.copilot/mcp-config.json). The "Advanced configuration" example exercises all three. |
Credential Hygiene — 20 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Secrets marked sensitive | 16 | 16 | github_token and ai_gateway_proxy_auth_url both have sensitive = true in main.tf. README examples use var.github_token, data.coder_external_auth.github.access_token, and module.aibridge-proxy.proxy_auth_url—no inline literal or placeholder secrets. |
| Non-hardcoded auth path | 4 | 4 | Two documented non-hardcoded paths: (1) Coder external auth via data "coder_external_auth" "github", and (2) AI Gateway Proxy via the aibridge-proxy module. Both avoid pasting raw keys into templates. |
Restricted-Environment Readiness — 6 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Mirrorable artifact source | 5 | 0 | The install script hardcodes https://gh.io/copilot-install. No module input variable overrides this download URL. copilot_version pins the version but does not change the source URL. |
| Bring-your-own binary | 10 | 5 | install_copilot = false skips the download and validates an existing copilot on PATH (install.sh.tftpl lines 79–85). The variable is defined in main.tf with a description, but the README has no section or example documenting this "already baked into the image" path. Implemented but under-documented → half. |
| Egress transparency | 3 | 0 | No dedicated README section enumerating external endpoints (e.g., gh.io, AI Gateway proxy URL). Endpoints are only visible in the install script source and the AI Gateway example. |
| Runs without sudo | 2 | 1 | write_managed_settings() invokes sudo to write to /etc/github-copilot/ but includes a non-sudo fallback (else branch). Sudo is used only for the optional managed-settings feature with a working fallback → half. All other script functions (install, workdir, base config, trusted folders, MCP) run without sudo. |
Engineering Quality — 10 / 10
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Input quality | 6 | 6 | All 14 variables have type and description. Sensible defaults (install_copilot = true, copilot_version = "latest", workdir = null). enable_ai_gateway has two validation blocks enforcing required companion variables. github_token and ai_gateway_proxy_auth_url are marked sensitive. |
| Test coverage | 4 | 4 | main.tftest.hcl (12 test runs) covers defaults, env-var creation/absence, workdir trimming, script output ordering, AI Gateway proxy env vars, and validation failures. main.test.ts (9 tests) covers end-to-end behavior: install skip, workdir trust, trusted-folders union, base-config overwrite, managed-settings write/absence, MCP server write/merge, and token env var. Clear separation of plan-level and container-level tests. |
Overall — 68 / 100
Raw 63 / 92 → round(63 / 92 × 100) = 68
Tip
You can run this locally by telling your agent: "review this module against .github/scorecard/SCORECARD.md".
Scored against SCORECARD.md with solstice-1. Language-model scores are advisory.
Drop the enable_ai_gateway variable, its validation, and the COPILOT_PROVIDER_* env resources, along with the now-unused coder_workspace/coder_workspace_owner data sources. Update README, variable docs, and tests accordingly. Generated with Coder Agents.
…existing entries winning Always merge mcp_config into ~/.copilot/mcp-config.json via jq; on duplicate server names the existing on-disk entry takes precedence. Require jq (drop the verbatim-overwrite fallback) and add a test that seeds a conflicting server. Generated with Coder Agents.
…nfig and mcp merges Make module inputs authoritative for the keys/servers the module owns while preserving runtime state: - config.json: module keys win, trusted_folders is a union of existing and module lists, other on-disk keys (model, reasoning_effort, ...) are preserved. - mcp-config.json: module-provided servers win on duplicate names; unrelated on-disk servers are preserved. - Route mcpServers from copilot_config into mcp-config.json (mcp_config wins); never write mcpServers into config.json. - Update variable docs, README, and tests. Generated with Coder Agents.
…rvers routing from config config.json has no mcpServers key (Copilot reads MCP only from mcp-config.json), so a well-formed copilot_config never carries it. Remove the strip/route handling: copilot_config feeds config.json as-is, mcp_config feeds mcp-config.json. Generated with Coder Agents.
… ai_gateway Renames the pre-v1 enable_aibridge_proxy feature to ai_gateway. Sets HTTPS_PROXY and NODE_EXTRA_CA_CERTS via agent-level coder_env with variable validation, plus tests and README docs.
…gs.json/config.json schema
…e-tasks # Conflicts: # registry/coder-labs/modules/copilot/README.md # registry/coder-labs/modules/copilot/copilot.tftest.hcl # registry/coder-labs/modules/copilot/main.tf # registry/coder-labs/modules/copilot/scripts/install.sh # registry/coder-labs/modules/copilot/scripts/start.sh
…nd align with claude-code Replace copilot_settings/copilot_config with a managed_settings policy input written to /etc/github-copilot/managed-settings.json, keep workdir auto-trust, make MCP merge existing-wins, and rename mcp_config to mcp for claude-code parity.
…g model' call 'copilot config' is not a command; the model is set via the COPILOT_MODEL env var. Remove the dead configure_copilot_model function and the now-unused ARG_COPILOT_MODEL script argument.
…ta source in README
…ump example version
Use /icon/github-copilot.svg default and rename ai_gateway_auth_url to ai_gateway_proxy_auth_url and ai_gateway_cert_path to ai_gateway_proxy_cert_path.
Restore copilot_config as base_copilot_config. When set it overwrites ~/.copilot/settings.json, the current user settings file, on every start. MCP servers stay in mcp-config.json.
|
Automated review requested by @matifali. Please sanity-check before acting on it.
CI and existing reviews
CorrectnessThe Terraform is coherent: there are no dangling variable references, [BLOCKER] The install script wipes local existing='{}'
if [ -f "$${config_file}" ] && jq empty "$${config_file}" > /dev/null 2>&1; then
existing=$(cat "$${config_file}")
fi
echo "$${existing}" | jq ... '.trustedFolders = ...' > "$${config_file}"Since Copilot CLI 1.0.35,
Fix: strip the comment header before parsing, never fall back to local existing='{}'
if [ -f "$${config_file}" ]; then
if ! existing=$(sed -E '/^[[:space:]]*\/\//d' "$${config_file}" | jq -c .); then
echo "Warning: could not parse $${config_file}; skipping workdir trust" >&2; return
fi
fi
local tmp; tmp=$(mktemp "$${config_file}.XXXXXX"); chmod 600 "$${tmp}"
echo "$${existing}" | jq --argjson folders "$${ARG_TRUSTED_FOLDERS}" \
'.trustedFolders = (((.trustedFolders // []) + $folders) | unique)' > "$${tmp}" && mv "$${tmp}" "$${config_file}"Also add a test that seeds the [SHOULD-FIX] Fix: remove these Follow-up: [SHOULD-FIX] The stale task-reporting Fix: [SHOULD-FIX] GitHub external-auth regression Fix: export Leftovers
Breaking changes and migration
Tests
Other nits
|
…as configuring Copilot install_copilot can be false, in which case the module only configures Copilot.
…rusting workdir
Copilot writes config.json with a // comment header, which jq rejected, so
the script fell back to {} and overwrote auth and plugin state on every start.
Strip comments before parsing, skip when the workdir is already trusted or the
file cannot be parsed, and write atomically with mode 0600.
Closes REG-83
Refactor
coder-labs/copilotto install and configure GitHub Copilot CLI only, matching the claude-code and codex v5 migrations. Bump to1.0.0.task_app_idoutput, and the task-reportingcoderMCP server.https://gh.io/copilot-install, temp file +bash -n,VERSIONfromcopilot_version) instead of npm, so Node.js is no longer required. Skipped whencopilotis already onPATH; withinstall_copilot = false,copilotmust be onPATH.workdiris optional; when set it is created and added totrustedFoldersin~/.copilot/config.json(Copilot's//header is stripped before parsing; the file is left unchanged if it cannot be parsed).copilot_configtobase_copilot_config; when set it overwrites~/.copilot/settings.jsonon every start.mcp_configtomcp; merged into~/.copilot/mcp-config.jsonwith servers already on disk winning. A JSONC or invalid file is skipped with a warning.managed_settingsis written to/etc/github-copilot/managed-settings.json.github_tokenis exported asCOPILOT_GITHUB_TOKENandcopilot_modelasCOPILOT_MODELviacoder_env.enable_aibridge_proxy/aibridge_proxy_*toenable_ai_gateway/ai_gateway_proxy_auth_url/ai_gateway_proxy_cert_path; when enabled,HTTPS_PROXYandNODE_EXTRA_CA_CERTSare set viacoder_env.allow_all_tools,allow_tools,deny_tools,resume_session,ai_prompt,system_prompt) become flags in the user'scoder_app.scriptsoutput; README reduced to examples and doc links; rewrite tests.Testing
terraform test,bun test main.test.ts(container-based),terraform fmt,terraform validate, prettier, shellcheckbase_copilot_configoverwritessettings.json, JSONC is written as is, andmcpis merged intomcp-config.jsonin both casesGenerated with Coder Agents.