Skip to content

refactor(registry/coder/modules/goose)!: remove agentapi, tasks and start logic - #1179

Open
35C4n0r wants to merge 4 commits into
mainfrom
35C4n0r/migrate-goose
Open

35C4n0r wants to merge 4 commits into
mainfrom
35C4n0r/migrate-goose

Conversation

@35C4n0r

@35C4n0r 35C4n0r commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Closes REG-81

Refactor coder/goose to install and configure Goose only, matching the claude-code, codex, copilot, cursor-cli, opencode, and kiro-cli (#1161) migrations. The install and config logic is v3's install.sh with only the AgentAPI and Tasks parts removed. Bump to 4.0.0.

  • Replace the agentapi module with coder-utils; drop Tasks/web-app inputs (order, group, subdomain, install_agentapi, agentapi_version), the task_app_id output, the start script (GOOSE_TASK_PROMPT), and the task-reporting coder extension.
  • Rename folder to optional workdir (created if missing, as the agentapi module did for folder).
  • Install with the same download_cli.sh (GOOSE_VERSION, CONFIGURE=false; stable maps to the installer default). The URL now points at aaif-goose/goose, where the repo moved, and the installer runs from a temp dir because it downloads into the working directory.
  • config.yaml is still overwritten with GOOSE_PROVIDER, GOOSE_MODEL, the developer extension, and additional_extensions. GOOSE_SYSTEM_PROMPT is still written to .goosehints.
  • Link goose into CODER_SCRIPT_BIN_DIR: the module no longer launches Goose, and ~/.local/bin is not on the agent PATH, so launchers and downstream scripts would not find it otherwise.
  • Add scripts output; README reduced to examples and doc links; rewrite tests.

Testing

  • terraform test (6 passed), bun test main.test.ts (11 passed, container-based, includes a real Goose v1.54.0 install checked with goose info -v), terraform fmt, terraform validate, prettier, shellcheck on the rendered script
  • Dogfood workspace from a test template: Goose 1.55.0 installed, script order pre_install, install, post_install, then a downstream coder exp sync script that finds goose; config.yaml and .goosehints written, workdir created; goose run with only CODER_SCRIPT_BIN_DIR on PATH called the everything extension through Coder AI Gateway; restart and pinned v1.54.0 work, agent ready

Generated with Coder Agents.

@linear-code

linear-code Bot commented Oct 13, 2026

Copy link
Copy Markdown

REG-81

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Module Scorecard Check

coder/goose: 50 → 64

✅ Score improvement: 50 → 64 (+14).

Theme Before After
Presentation & Onboarding 6 / 17 12 / 17
Integration 10 / 25 10 / 25
Credential Hygiene 16 / 20 18 / 20
Restricted-Environment 7 / 20 12 / 20
Engineering Quality 7 / 10 7 / 10
Overall 50 / 100 64 / 100
Full scorecard for this PR
Presentation & Onboarding Agent Integration Credential Hygiene Restricted-Environment Readiness Engineering Quality Overall
12 / 17 10 / 25 18 / 20 12 / 20 7 / 10 64 / 100
Drilldown

Presentation & Onboarding — 12 / 17

Criterion Max Score Notes
Configuration-mode examples 12 12 README shows multiple configured modes: standalone with launcher coder_app, extensions/MCP config (additional_extensions), pinned version (goose_version), and downstream coder_script serialization via the scripts output. Defaults (goose_version = "stable", install_goose = true) are sensible.
Visual preview 5 0 No image, GIF, or video embedded in README.

Agent Integration — 10 / 25

Criterion Max Score Notes
AI governance 10 0 No mention of Coder AI Gateway or Agent Firewall anywhere in README; v4 explicitly drops AgentAPI/Tasks support, not governance features.
Dashboard entry point 5 5 README's "Standalone mode with a launcher app" example documents a full coder_app resource (slug, display_name, icon, open_in, command) launching goose session.
Session continuity 5 0 No documentation of resuming an existing Goose session or wrapping in tmux/screen; goose session is invoked fresh each launch.
Managed configuration 5 5 additional_extensions variable documents managed MCP/extensions config; GOOSE_SYSTEM_PROMPT env var writes .goosehints; module fully owns config.yaml.

Credential Hygiene — 18 / 20

Criterion Max Score Notes
Secrets marked sensitive 16 16 Module itself defines no secret input variables (provider/model are non-sensitive). README example injects ANTHROPIC_API_KEY via coder_env referencing var.anthropic_api_key rather than a literal key — no inline secrets shown.
Non-hardcoded auth path 4 2 README documents injecting provider credentials via coder_env/environment variable, avoiding template-pasted keys, but this is plain env-var injection rather than a ServiceAccount/IAM/OAuth/API-key-helper/AI-Gateway path — only partial credit.

Restricted-Environment Readiness — 12 / 20

Criterion Max Score Notes
Mirrorable artifact source 5 0 Install script hardcodes https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh; no module variable overrides this download URL (goose_version only changes a pinned tag parameter passed to the fixed installer).
Bring-your-own binary 10 10 install_goose = false is documented ("goose must already be on PATH") and tested (preinstalled-binary-required-when-install-disabled), providing a clear way to skip install when goose is baked into the image.
Egress transparency 3 0 No dedicated README section enumerating install/runtime endpoints; the GitHub release URL is only visible in source, not documented.
Runs without sudo 2 2 install.sh.tftpl never invokes sudo; all operations (curl, mkdir, symlink) occur under $HOME/user-writable paths — verified unprivileged in script and tests.

Engineering Quality — 7 / 10

Criterion Max Score Notes
Input quality 6 3 All variables have clear description fields and sensible defaults (e.g. install_goose = true, goose_version = "stable"), but no validation blocks exist anywhere (e.g. for goose_provider, goose_version format).
Test coverage 4 4 main.tftest.hcl covers business logic (defaults, workdir trimming, extension merging, scripts output ordering) and main.test.ts runs extensive end-to-end container tests (install paths, config writing, symlinking, real-binary smoke test).

Overall — 64 / 100

Raw 59 / 92 → round(59 / 92 × 100) = 64

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.

@coder

coder Bot commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Automated review requested by @matifali. Please sanity-check before acting on it.

Summary

This PR replaces agentapi with coder-utils. It drops order/group/subdomain/install_agentapi/agentapi_version, the task_app_id output, start.sh (GOOSE_TASK_PROMPT), the GOOSE_SYSTEM_PROMPT → .goosehints write, and the hard-coded coder (task reporting) and developer extensions. It renames folder → workdir, exports GOOSE_PROVIDER/GOOSE_MODEL via coder_env, and switches to the new aaif-goose installer URL run in a temp dir. additional_extensions is now merged into config.yaml (existing names win) instead of overwriting the file. It also adds the first main.tftest.hcl for this module and the scripts output.

Checks

Area Result
Correctness main.tf is valid. Template vars match the .tftpl. stable → empty GOOSE_VERSION matches upstream download_cli.sh (verified: it honors GOOSE_VERSION, CONFIGURE, and GOOSE_BIN_DIR, and validates semver). Running the installer in a temp dir with < /dev/null is correct. The YAML is parsed at plan time (yamldecode), the awk merge is idempotent and writes through symlinks, and the config path resolution (GOOSE_PATH_ROOT / XDG_CONFIG_HOME) matches goose.
Leftovers None in module code. No CODER_MCP_APP_STATUS_SLUG, CODER_MCP_AI_AGENTAPI_URL, 3284, exp mcp, app_slug, or task_app_id. But upgraded workspaces keep the old module-written coder extension in config.yaml (finding 1). Outside the module, registry/coder/modules/agentapi/README.md:134 still points to the Goose module as "a complete example" of using agentapi, and its example at lines 23-47 mirrors the old goose code (finding 7).
Breaking change Major bump to 4.0.0. All README examples use 4.0.0. README.md:23-24 warning covers the removed inputs/output/env vars, the folder → workdir rename, and the config behavior change.
Tests New main.tftest.hcl (7 runs: defaults, env vars, workdir trim, extension JSON encoding, pinned version, scripts output). main.test.ts was rewritten (17 container tests incl. merge/idempotency/inline/symlink/GOOSE_PATH_ROOT and a real goose v1.54.0 install). Coverage is strong.
CI All green: CI (TS 17/17 pass, Terraform 7/7, validate, shellcheck), fmt/typos, README validation, golangci-lint, scorecard (50 → 50; credential hygiene 16 → 10 because the module no longer has secret inputs, input quality 3/6 for no validations).
Reviews No reviews or review comments yet. Only bot comments.
Series consistency Matches codex/claude-code structure. folder → workdir aligns with the series.

Findings

should-fix

  1. Upgraded workspaces keep the Tasks-reporting coder extension. v3 rewrote ~/.config/goose/config.yaml on every start with extensions.coder (cmd: coder, args: [exp, mcp, server], envs: CODER_MCP_APP_STATUS_SLUG: goose, CODER_MCP_AI_AGENTAPI_URL: http://localhost:3284; see old main.tf:105-126). v4 never touches existing entries (scripts/install.sh.tftpl:170-241), so on persistent homes goose will keep spawning coder exp mcp server with status env vars pointing at a port nothing listens on. That's exactly the integration this series removes, and it's invisible to users. Suggested fix, either:
    • a one-time cleanup in setup_extensions (or a separate cleanup_legacy_config step that always runs): drop the extensions.coder block when it contains CODER_MCP_AI_AGENTAPI_URL (the module wrote it, so removing it is safe), plus the legacy developer: {type: builtin} block if desired; or
    • at minimum, a README migration line: "Remove extensions.coder (and the flat GOOSE_PROVIDER/GOOSE_MODEL keys) from ~/.config/goose/config.yaml written by v3."
  2. Changes to additional_extensions no longer reach existing workspaces. Because "existing wins" (install.sh.tftpl:195-205), any extension v3 already wrote, or that v4 wrote on first start, won't be updated when a template admin later changes its args/env/timeout. The only sign is a warning in install.log. That's a behavior change for template admins on top of the upgrade notes. Document it in README.md:89 and the warning at README.md:24, e.g. "to change an extension the module already added, rename it or remove it from config.yaml". Optionally offer an opt-in overwrite toggle for module-provided names.
  3. New runtime dependency on jq. install.sh.tftpl:29-34,176 hard-fails when additional_extensions is set and jq is missing. v3 had no such requirement, and minimal images often lack jq. Terraform already decodes the YAML, so the script can avoid jq entirely: pass the names (base64encode(join("\n", keys(local.ext)))) and pre-rendered flow lines (join("\n", [for k, v in local.ext : "${jsonencode(k)}: ${jsonencode(v)}"])) from main.tf:88, then filter with grep -Fxv / awk. If jq stays, add it to the README (prerequisites + migration note).
  4. Not merge-ready per the PR's own note. The PR is a draft and the dogfood template test is pending (provisioner disk full). Run it before marking ready.

nit
5. main.tf:35-39: add validation for goose_version (var.goose_version == "stable" || can(regex("^v?[0-9]+\\.[0-9]+\\.[0-9]+(-.*)?$", var.goose_version))). Upstream download_cli.sh:76 rejects anything else, so today goose_version = "latest" fails at workspace start instead of at plan time. Also add a validation on additional_extensions (var.additional_extensions == null || can(keys(yamldecode(var.additional_extensions)))) so a YAML list fails at plan rather than at runtime (install.sh.tftpl:178-181). Both would also recover scorecard input-quality points.
6. install.sh.tftpl:186-190,230: extensions: # comment passes the guard but print_entries replaces the line with a bare extensions:, which drops the comment. extensions: null / extensions: ~ is treated as an "inline format" and skipped with a misleading warning. Both are rare. Handle null/~ like {}, and keep any trailing comment.
7. registry/coder/modules/agentapi/README.md:134 (not in this PR's diff) still says "For a complete example of how to use this module, see the Goose module". After this PR that's false. Update the pointer here or in the agentapi-removal PR.
8. README.md:24: also mention that the developer builtin is no longer written (goose enables it by default now), and that leftover ~/.goose-module/ from v3 is unused.
9. main.test.ts:486-513 (real-goose-loads-merged-config) downloads the real installer and binary from GitHub in CI. It's valuable, but a flake source. Consider gating it behind an env flag or accepting the risk knowingly.
10. main.tf:2: required_version = ">= 1.0" vs >= 1.9 in the merged series modules. Same footer nit as #1178 (include the model name).

Verdict: request changes (minor)

The module itself works and is well tested. The blocker-ish gap is #1: upgraded workspaces silently keep the coder exp mcp server task-reporting extension with CODER_MCP_APP_STATUS_SLUG / CODER_MCP_AI_AGENTAPI_URL=http://localhost:3284. Fix that with a cleanup or at least a migration note, document #2, resolve #3, and it's an approve.

…config logic

Keep v3's install.sh behavior minus AgentAPI: run download_cli.sh,
overwrite config.yaml with provider, model, the developer extension and
additional_extensions, and write GOOSE_SYSTEM_PROMPT to .goosehints.
Drop the extension merge and the GOOSE_PROVIDER/GOOSE_MODEL coder_env
exports. Run the installer from a temp dir and link goose into
CODER_SCRIPT_BIN_DIR so launchers and downstream scripts find it.
@35C4n0r
35C4n0r marked this pull request as ready for review October 16, 2026 18:24
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