[PR #4039] feat(clients): register ggcode during setup #6010

Open
opened 2026-10-31 01:11:09 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4039
Author: @topcheer
Created: 10/15/2026
Status: 🔄 Open

Base: main ← Head: feat/ggcode-client-upstream


📝 Commits (10+)

  • 4b696ac feat(clients): register ggcode during setup
  • 63383f1 fix(clients): harden ggcode legacy fallback, migration and validation
  • 1ae062e Merge branch 'morluto:main' into feat/ggcode-client-upstream
  • b13e8ea Merge branch 'morluto:main' into feat/ggcode-client-upstream
  • 70bb97e Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream
  • 814ebcd fix(clients): resolve aliased ggcode names and report the legacy path
  • a164fa9 Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream
  • ea5e5a9 Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream
  • 28fe064 Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream
  • 574ba9c chore(clients): drop unrelated import shuffles from the ggcode PR

📊 Changes

13 files changed (+1288 additions, -12 deletions)

View changed files

📝 .agents/skills/reverse-engineer-anything/references/connection-and-recovery.md (+1 -1)
📝 docs/client-configuration.md (+13 -0)
📝 docs/installation.md (+1 -0)
📝 src/application/ClientConfigurationDocument.ts (+74 -0)
📝 src/application/ClientConfigurationFiles.ts (+44 -1)
📝 src/application/ClientRegistration.ts (+8 -2)
📝 src/application/ClientRegistrationStatus.ts (+3 -1)
➕ src/application/GgcodeConfigurationYaml.ts (+316 -0)
📝 src/application/SetupClientConfiguration.ts (+94 -3)
📝 src/application/SupportedClients.ts (+60 -1)
📝 src/application/Uninstall.ts (+21 -3)
📝 tests/boundary/filesystem/clientLifecycle.test.ts (+1 -0)
➕ tests/boundary/filesystem/ggcodeClientConfiguration.test.ts (+652 -0)

📄 Description

Summary

Setup now registers REA with ggcode, so
npx rea-agents setup (or rea setup --client ggcode) writes the REA MCP
registration and installs the bundled reverse-engineering skill for ggcode
users, with the same plan-approve-apply flow and backups as every other
supported client.

Problem and expected behavior

ggcode users had to hand-register REA. After this change, setup detects
ggcode from ~/.ggcode and registers the rea stdio server in ggcode's
standalone MCP configuration, reporting aligned/stale/missing in doctor like
other clients.

Change and scope

ggcode reads MCP servers from ~/.ggcode/mcp_servers.yaml, a top-level YAML
sequence of named entries (- name: rea with type/command/args/env;
an empty type connects as stdio). It auto-migrates a legacy mcp_servers
section of the main ~/.ggcode/ggcode.yaml into that standalone file and
honors the section only while the file is absent.

  • SupportedClients: ggcode definition with a new ggcode YAML-sequence
    format. ~/.ggcode/ggcode.yaml is a lower-precedence read layer (so a
    legacy in-main registration reports correctly) and, via the new
    supersededConfigPath, the seed source for a freshly created standalone
    file — mirroring ggcode's own migration instead of suppressing
    hand-configured servers. ggcode has no home-directory override.
  • GgcodeConfigurationYaml (new): parses both layouts into the synthetic
    mcp_servers server table; upserts/deletes one named sequence entry while
    retaining formatting, order, and comments; malformed items fail closed.
  • ClientConfigurationDocument: parse/serialize wiring and a stdio
    registration entry. ClientRegistrationStatus treats a non-stdio type
    as stale/invalid, like the other type-carrying dialects.
  • SetupClientConfiguration: seeds a freshly created standalone file with
    the superseded in-main servers. An existing target is never reseeded, so a
    deleted entry cannot resurrect from the inert legacy section.
  • Skill installs to ~/.ggcode/skills, which ggcode discovers (it also reads
    the shared ~/.agents/skills destination).
  • Docs: installation client table, client-configuration ggcode section,
    bundled skill's supported client list.

Intentionally not included: writing to ~/.ggcode/ggcode.yaml (REA only ever
writes the standalone file), and real-client verification beyond the local
run described below.

Contract and boundary impact

  • Semantic owner and earliest changed stage: setup/doctor client
    registration (src/application), same boundary as all client dialects.
  • Contribution scope fit and linked maintainer decision: not applicable —
    ordinary client registration within existing setup boundaries, following
    the droid/qoder precedent.
  • CLI and MCP/tool-catalog contract: new --client ggcode selection and
    doctor client entry; no tool-catalog change.
  • Provider, bridge, target-format, or platform compatibility: none; POSIX and
    Windows paths resolve through the existing ClientPathContext.
  • Evidence, artifact, provenance, or reconstruction contract: unchanged.
  • Target selection, authority, upstream behavior, and cleanup details (if
    applicable): setup writes only ~/.ggcode/mcp_servers.yaml with a
    .rea.backup recovery backup; uninstall removes only the rea entry.
  • Generated metadata: no authored-contract change; .agents/skills source
    updated, generated outputs untouched.

Expected effects:

  • Read existing files or captured data. (reads ~/.ggcode/*.yaml during doctor/setup)
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

(The registered server launches REA itself when ggcode connects, same as
every other stdio client registration.)

Evidence and regression coverage

  • Tests added or updated: tests/boundary/filesystem/ggcodeClientConfiguration.test.ts
    (10 tests: path resolution, skills directory, create/upsert/empty-file
    registration, comment+order preservation, legacy seeding, no-resurrect
    beside an existing file, legacy-layer aligned status, malformed YAML
    rejected untouched, uninstall); clientLifecycle.test.ts client list.
  • Base reproduction or other evidence: real run on macOS against a live
    ~/.ggcode (ggcode installed at /opt/homebrew/bin/ggcode): setup appended
    rea to an existing mcp_servers.yaml with four unrelated servers
    preserved, ggcode mcp list loads the entry, rea doctor --json reports
    {"client": "ggcode", "state": "aligned"}, and a raw stdio initialize
    handshake against the registered command returns REA's capabilities.
  • User-visible CLI/MCP output (if applicable): dry-run plan shows
    configure_client:ggcode → /Users/zhanju/.ggcode/mcp_servers.yaml
    (operation update, backup .../mcp_servers.yaml.rea.backup) and
    install_skill:ggcode → ~/.ggcode/skills/reverse-engineer-anything.
  • Remaining proof gaps: no Windows host verification (path cases covered in
    unit tests); no ggcode version matrix (verified against the locally
    installed ggcode build only). The observed skill stale state after a
    from-source setup run is shared with other clients and unrelated to this
    change (skill fingerprint is produced by the packaged build).

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

On the PR branch (single commit on top of upstream main @ e45eb33f0):

  • npx tsc --noEmit — clean.
  • npm run check — pass (typecheck, lint, format, knip, metadata freshness,
    architecture guards across 1425 source files).
  • npm run check:fast — pass.
  • npm run docs:check — pass (5/5).
  • npx vitest run tests/boundary/filesystem/ggcodeClientConfiguration.test.ts tests/boundary/filesystem/clientLifecycle.test.ts — 66/66 pass.
  • npx vitest run tests/boundary/filesystem/{hermes,kimi,droid,qoder}ClientConfiguration.test.ts tests/boundary/filesystem/clientConfigurationEnvironment.test.ts — 97/97 pass.
  • npx vitest run src/application/Setup.planning.test.ts src/application/Doctor.test.ts src/application/HermesConfigurationYaml.test.ts — 63/63 pass.
  • npm run verify:package — pass (setup planned-then-idempotent with backup
    readback, repository skill bundle verified, 207 MCP tools listed).
  • npm pack --dry-run — 1687 files, no unexpected additions.
  • node scripts/rea.mjs setup --client ggcode --dry-run --json — planned
    update of ~/.ggcode/mcp_servers.yaml with backup, plus skill install.
  • node scripts/rea.mjs setup --client ggcode --yes --json — status: ready;
    existing servers preserved, backup written.
  • ggcode mcp list — lists rea [stdio] alongside the four pre-existing servers.
  • node scripts/rea.mjs doctor --json — ggcode registration state: aligned.
  • stdio initialize against the registered command — REA capabilities returned.
  • Pre-existing, environment-dependent failures on this machine
    (tests/acceptance/setup/*, several JavaScript/Apple artifact boundary
    suites, qwenClientConfiguration, setupSkill) reproduce identically on
    unmodified main; they are unrelated to this change.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Existing ggcode users keep their
    configuration; setup only appends/updates the rea entry with a backup.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable; no analysis
    provider behavior changed.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: writes are confined to
    ggcode's user configuration with atomic writes and .rea.backup recovery;
    the registered entry carries no environment beyond explicitly configured
    values; the seeding path never deletes or rewrites the legacy
    ggcode.yaml.

Author readiness

Human owner: @topcheer

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above. (No issue filed; direct enhancement following the droid/qoder client-addition precedent.)
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4039 **Author:** [@topcheer](https://github.com/topcheer) **Created:** 10/15/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/ggcode-client-upstream` --- ### 📝 Commits (10+) - [`4b696ac`](https://github.com/morluto/rea/commit/4b696ac4057fb0d65ed61ef404d6f007eb7f55f5) feat(clients): register ggcode during setup - [`63383f1`](https://github.com/morluto/rea/commit/63383f11cacdd3aa5e855e94a9f31583e2e88e62) fix(clients): harden ggcode legacy fallback, migration and validation - [`1ae062e`](https://github.com/morluto/rea/commit/1ae062e6fb33af35ea8c8b56de7f8861736079e5) Merge branch 'morluto:main' into feat/ggcode-client-upstream - [`b13e8ea`](https://github.com/morluto/rea/commit/b13e8ea18f8dcaf012596848d6fc6b0b8cbbdfbd) Merge branch 'morluto:main' into feat/ggcode-client-upstream - [`70bb97e`](https://github.com/morluto/rea/commit/70bb97e4287b008bc450100af81d94ff6dccdceb) Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream - [`814ebcd`](https://github.com/morluto/rea/commit/814ebcd682068f0a0d00614c7c8fb8b90ed3e10d) fix(clients): resolve aliased ggcode names and report the legacy path - [`a164fa9`](https://github.com/morluto/rea/commit/a164fa946f1e54820ea985fb19c57d41edb06d51) Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream - [`ea5e5a9`](https://github.com/morluto/rea/commit/ea5e5a93feb67cc581798d3f013e8951195dad01) Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream - [`28fe064`](https://github.com/morluto/rea/commit/28fe06497a080d6f8ec9ab409f3e7260e2d48bde) Merge remote-tracking branch 'upstream/main' into feat/ggcode-client-upstream - [`574ba9c`](https://github.com/morluto/rea/commit/574ba9cc5f048b2cbf649cc196efa42897a08a93) chore(clients): drop unrelated import shuffles from the ggcode PR ### 📊 Changes **13 files changed** (+1288 additions, -12 deletions) <details> <summary>View changed files</summary> 📝 `.agents/skills/reverse-engineer-anything/references/connection-and-recovery.md` (+1 -1) 📝 `docs/client-configuration.md` (+13 -0) 📝 `docs/installation.md` (+1 -0) 📝 `src/application/ClientConfigurationDocument.ts` (+74 -0) 📝 `src/application/ClientConfigurationFiles.ts` (+44 -1) 📝 `src/application/ClientRegistration.ts` (+8 -2) 📝 `src/application/ClientRegistrationStatus.ts` (+3 -1) ➕ `src/application/GgcodeConfigurationYaml.ts` (+316 -0) 📝 `src/application/SetupClientConfiguration.ts` (+94 -3) 📝 `src/application/SupportedClients.ts` (+60 -1) 📝 `src/application/Uninstall.ts` (+21 -3) 📝 `tests/boundary/filesystem/clientLifecycle.test.ts` (+1 -0) ➕ `tests/boundary/filesystem/ggcodeClientConfiguration.test.ts` (+652 -0) </details> ### 📄 Description ## Summary Setup now registers REA with [ggcode](https://github.com/topcheer/ggcode), so `npx rea-agents setup` (or `rea setup --client ggcode`) writes the REA MCP registration and installs the bundled reverse-engineering skill for ggcode users, with the same plan-approve-apply flow and backups as every other supported client. ## Problem and expected behavior ggcode users had to hand-register REA. After this change, setup detects ggcode from `~/.ggcode` and registers the `rea` stdio server in ggcode's standalone MCP configuration, reporting aligned/stale/missing in doctor like other clients. ## Change and scope ggcode reads MCP servers from `~/.ggcode/mcp_servers.yaml`, a top-level YAML sequence of named entries (`- name: rea` with `type`/`command`/`args`/`env`; an empty `type` connects as stdio). It auto-migrates a legacy `mcp_servers` section of the main `~/.ggcode/ggcode.yaml` into that standalone file and honors the section only while the file is absent. - `SupportedClients`: ggcode definition with a new `ggcode` YAML-sequence format. `~/.ggcode/ggcode.yaml` is a lower-precedence read layer (so a legacy in-main registration reports correctly) and, via the new `supersededConfigPath`, the seed source for a freshly created standalone file — mirroring ggcode's own migration instead of suppressing hand-configured servers. ggcode has no home-directory override. - `GgcodeConfigurationYaml` (new): parses both layouts into the synthetic `mcp_servers` server table; upserts/deletes one named sequence entry while retaining formatting, order, and comments; malformed items fail closed. - `ClientConfigurationDocument`: parse/serialize wiring and a stdio registration entry. `ClientRegistrationStatus` treats a non-stdio `type` as stale/invalid, like the other type-carrying dialects. - `SetupClientConfiguration`: seeds a freshly created standalone file with the superseded in-main servers. An existing target is never reseeded, so a deleted entry cannot resurrect from the inert legacy section. - Skill installs to `~/.ggcode/skills`, which ggcode discovers (it also reads the shared `~/.agents/skills` destination). - Docs: installation client table, client-configuration ggcode section, bundled skill's supported client list. Intentionally not included: writing to `~/.ggcode/ggcode.yaml` (REA only ever writes the standalone file), and real-client verification beyond the local run described below. ## Contract and boundary impact - Semantic owner and earliest changed stage: setup/doctor client registration (`src/application`), same boundary as all client dialects. - Contribution scope fit and linked maintainer decision: not applicable — ordinary client registration within existing setup boundaries, following the droid/qoder precedent. - CLI and MCP/tool-catalog contract: new `--client ggcode` selection and doctor client entry; no tool-catalog change. - Provider, bridge, target-format, or platform compatibility: none; POSIX and Windows paths resolve through the existing `ClientPathContext`. - Evidence, artifact, provenance, or reconstruction contract: unchanged. - Target selection, authority, upstream behavior, and cleanup details (if applicable): setup writes only `~/.ggcode/mcp_servers.yaml` with a `.rea.backup` recovery backup; uninstall removes only the `rea` entry. - Generated metadata: no authored-contract change; `.agents/skills` source updated, generated outputs untouched. Expected effects: - [x] Read existing files or captured data. (reads `~/.ggcode/*.yaml` during doctor/setup) - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. (The registered server launches REA itself when ggcode connects, same as every other stdio client registration.) ## Evidence and regression coverage - Tests added or updated: `tests/boundary/filesystem/ggcodeClientConfiguration.test.ts` (10 tests: path resolution, skills directory, create/upsert/empty-file registration, comment+order preservation, legacy seeding, no-resurrect beside an existing file, legacy-layer aligned status, malformed YAML rejected untouched, uninstall); `clientLifecycle.test.ts` client list. - Base reproduction or other evidence: real run on macOS against a live `~/.ggcode` (ggcode installed at /opt/homebrew/bin/ggcode): setup appended `rea` to an existing `mcp_servers.yaml` with four unrelated servers preserved, `ggcode mcp list` loads the entry, `rea doctor --json` reports `{"client": "ggcode", "state": "aligned"}`, and a raw stdio `initialize` handshake against the registered command returns REA's capabilities. - User-visible CLI/MCP output (if applicable): dry-run plan shows `configure_client:ggcode` → `/Users/zhanju/.ggcode/mcp_servers.yaml` (operation update, backup `.../mcp_servers.yaml.rea.backup`) and `install_skill:ggcode` → `~/.ggcode/skills/reverse-engineer-anything`. - Remaining proof gaps: no Windows host verification (path cases covered in unit tests); no ggcode version matrix (verified against the locally installed ggcode build only). The observed skill `stale` state after a from-source setup run is shared with other clients and unrelated to this change (skill fingerprint is produced by the packaged build). For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed On the PR branch (single commit on top of upstream `main` @ e45eb33f0): - `npx tsc --noEmit` — clean. - `npm run check` — pass (typecheck, lint, format, knip, metadata freshness, architecture guards across 1425 source files). - `npm run check:fast` — pass. - `npm run docs:check` — pass (5/5). - `npx vitest run tests/boundary/filesystem/ggcodeClientConfiguration.test.ts tests/boundary/filesystem/clientLifecycle.test.ts` — 66/66 pass. - `npx vitest run tests/boundary/filesystem/{hermes,kimi,droid,qoder}ClientConfiguration.test.ts tests/boundary/filesystem/clientConfigurationEnvironment.test.ts` — 97/97 pass. - `npx vitest run src/application/Setup.planning.test.ts src/application/Doctor.test.ts src/application/HermesConfigurationYaml.test.ts` — 63/63 pass. - `npm run verify:package` — pass (setup planned-then-idempotent with backup readback, repository skill bundle verified, 207 MCP tools listed). - `npm pack --dry-run` — 1687 files, no unexpected additions. - `node scripts/rea.mjs setup --client ggcode --dry-run --json` — planned update of `~/.ggcode/mcp_servers.yaml` with backup, plus skill install. - `node scripts/rea.mjs setup --client ggcode --yes --json` — `status: ready`; existing servers preserved, backup written. - `ggcode mcp list` — lists `rea [stdio]` alongside the four pre-existing servers. - `node scripts/rea.mjs doctor --json` — ggcode registration `state: aligned`. - stdio `initialize` against the registered command — REA capabilities returned. - Pre-existing, environment-dependent failures on this machine (`tests/acceptance/setup/*`, several JavaScript/Apple artifact boundary suites, `qwenClientConfiguration`, `setupSkill`) reproduce identically on unmodified `main`; they are unrelated to this change. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Existing ggcode users keep their configuration; setup only appends/updates the `rea` entry with a backup. - Real Hopper/Ghidra, browser, or OS coverage: not applicable; no analysis provider behavior changed. - Package or release metadata impact: none. - Security, privacy, process, or containment review: writes are confined to ggcode's user configuration with atomic writes and `.rea.backup` recovery; the registered entry carries no environment beyond explicitly configured values; the seeding path never deletes or rewrites the legacy `ggcode.yaml`. ## Author readiness Human owner: @topcheer - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. (No issue filed; direct enhancement following the droid/qoder client-addition precedent.) - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6010
No description provided.