Skip to content

Support agent plugins (Agent Plugins spec v1.0.0) - #1372

Open
hsm207 wants to merge 2 commits into
CodebuffAI:mainfrom
hsm207:fix/agent-plugin-support
Open

hsm207 wants to merge 2 commits into
CodebuffAI:mainfrom
hsm207:fix/agent-plugin-support

Conversation

@hsm207

@hsm207 hsm207 commented Sep 17, 2026

Copy link
Copy Markdown

This implements the Agent Plugins spec v1.0.0 and closes #1349. An agent plugin bundles a manifest (plugin.json), skills, and MCP server config, and this PR adds a one-command install for such bundles. After a restart the plugin's skills and MCP servers join the session.

fb plugin install https://github.com/google/skills/plugins/cloud/google-cloud-developer

I verified the feature end to end against that plugin: its five skills are served, its MCP server is discovered and routed through the project's existing MCP client, and nothing collides with the user's own skills or servers.

How it works

  • Domain model (common/src/plugins/): a Plugin value object, whose manifest is validated per §5, and an InstalledPlugin entity rooted at a client-managed plugins root. The entity shape leaves room for a plugin update flow later.
  • Validation: the specification text is authoritative if it conflicts with the official JSON schema (§5.2), so section 5's rules are implemented as a direct rule engine rather than zod transforms. MCP entries reuse the existing MCP config types, and streamable-http maps onto the CLI's http transport.
  • Install: fetch the GitHub archive (no git clone), extract to a staging dir, validate before installing, abort on any name conflict with the user's existing skills or servers, then move into the plugins root atomically. Only https://github.com URLs are accepted; anything else is refused before any network or filesystem work.
  • Session wiring: plugin skills and MCP servers load after the user's own. Install aborts on conflicts, so nothing is shadowed.

The four spec gaps

  • §5.2 never defines "object". I validate the three checks that match the spec's examples (non-null, non-array, plain) and note the assumption at the enforcement site.
  • Skill files are read by the existing SDK loader without re-validation. A present-but-invalid skill can currently load as absent, which §7.1 wants reported; flagged inline.
  • Env provisioning and ${PLUGIN_ROOT}/${PLUGIN_DATA} expansion (§9.1, §9.2) are not implemented; flagged inline where the spec expects them.
  • Remote MCP servers wanting user credentials (OAuth, ADC) cannot connect, exactly as on main today: the existing MCP client has no credential path for remote servers. §7.2.2 rule 5 maps this to a connection failure, never invalid config.

Testing

62 unit tests cover the manifest, skills and MCP policy in common; command, registry and child-process suites cover the cli side. The live verification above also confirmed gitlab URLs are refused cleanly. Automated end-to-end tests through the real binary are a small follow-up: the e2e scaffolding is unusable from a public checkout.

hsm207 and others added 2 commits September 17, 2026 09:41
Implements github issue CodebuffAI#1349: consume Agent Plugins-spec bundles
(plugin.json manifest + skills + mcp.json) as a unit, installable with
one command.

    fb plugin install https://github.com/google/skills/plugins/cloud/google-cloud-developer

Domain model (common/src/plugins/):
- Plugin value object: a validated manifest per spec section 5, plus
  skills and MCP servers parsed from the plugin root
- InstalledPlugin entity rooted at a client-managed plugins root
  (~/.agents/plugins/<name>/), enabling future update flows
- install URL handling restricted to https://github.com sources;
  anything else is refused before any network or filesystem work

Validation (manifest-policy): the spec's own rule engine - the
specification text is authoritative where it conflicts with the
published JSON schema (its own words), so section 5's field/type/
closed-set rules are implemented and tested directly rather than
bent into zod. MCP server entries reuse the existing MCP config
types; streamable-http maps onto the CLI's http transport.

Install pipeline (cli/): fetch the GitHub archive tarball (no git
clone), extract to a staging dir, validate before installing, abort
on any name conflict with the user's existing skills or MCP servers,
then atomically move into the plugins root. Names, conflicts and
the manifest itself are validated in common so the SDK can reuse
the same policy.

Session wiring: installed plugins' skills join the registry after
the user's own (install aborts on conflicts, so nothing is
shadowed); plugin MCP servers join mcp.json the same way. A
restart picks up newly installed plugins; in-session reload is
intentionally out of scope.

Tests: 62 unit tests over the manifest/skills/MCP policy in common,
plus command, registry and child-process tests in cli. Scope
limits, honestly stated: skill-file deep validation is delegated
to the existing SDK reader; env provisioning and
PLUGIN_ROOT/PLUGIN_DATA expansion (spec sections 9.1/9.2) are not
implemented in the runtime and are flagged inline where the spec
expects them. Remote MCP servers wanting user credentials (OAuth,
ADC) cannot connect, exactly as on main today: the existing MCP
client has no credential path for remote servers (section 7.2.2
maps this to a connection failure, not invalid config). Connection
behavior is the project's existing client, reused unchanged.

Live-verified against google/skills' google-cloud-developer
plugin: 5 skills served, the MCP server discovered and routed
through the project's existing MCP client, zero collisions with
user roots.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Plugins-only construction: the verified plugin tree, with the MCP
fix's modules and tests excluded so this PR carries exactly one
concern.

Implements github issue CodebuffAI#1349: consume Agent Plugins-spec bundles
(plugin.json manifest + skills + mcp.json) as a unit, installable with
one command.

    fb plugin install https://github.com/google/skills/plugins/cloud/google-cloud-developer

Domain model (common/src/plugins/): a Plugin value object whose
manifest is validated per spec section 5, and an InstalledPlugin
entity rooted at a client-managed plugins root, enabling future
update flows. Install URLs are restricted to https://github.com
sources; anything else is refused before any network or filesystem
work.

Validation (manifest-policy): the specification text is authoritative
where it conflicts with the published JSON schema (its own words), so
section 5's field/type/closed-set rules are implemented as a direct
rule engine rather than bent into zod. MCP server entries reuse the
existing MCP config types; streamable-http maps onto the CLI's http
transport.

Install pipeline (cli/): fetch the GitHub archive tarball (no git
clone), extract to a staging dir, validate before installing, abort
on any name conflict with the user's existing skills or MCP servers,
then atomically move into the plugins root. Names, conflicts and the
manifest itself are validated in common so the SDK can reuse the same
policy.

Session wiring: installed plugins' skills join the registry after the
user's own (install aborts on conflicts, so nothing is shadowed);
plugin MCP servers join mcp.json the same way. A restart picks up
newly installed plugins; in-session reload is intentionally out of
scope.

Tests: 62 unit tests over the manifest/skills/MCP policy in common,
plus command, registry and child-process tests in cli. Scope limits,
honestly stated: skill-file deep validation is delegated to the
existing SDK reader; env provisioning and PLUGIN_ROOT/PLUGIN_DATA
expansion (spec sections 9.1/9.2) are not implemented in the runtime
and are flagged inline where the spec expects them. Remote MCP
servers wanting user credentials (OAuth, ADC) cannot connect, exactly
as on main today: the existing MCP client has no credential path for
remote servers (section 7.2.2 maps this to a connection failure, not
invalid config). Connection behavior is the project's existing
client, reused unchanged.

Live-verified against google/skills' google-cloud-developer plugin:
5 skills served, the MCP server discovered and routed through the
project's existing MCP client, zero collisions with user roots.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
hsm207 added a commit to hsm207/codebuff that referenced this pull request Sep 17, 2026
…e tip

Block 7 closed: the PR is open against upstream, the description
draft is superseded by the public body, the tsc-parity finding and
sweep findings are archived as field notes.

local/debug-infra now points at the feature tip per the V2-rebuild
shape: the driver is the feature branch plus internal commits, the
toolbox re-arms from here when needed. The pre-plugins driver is
preserved as backup/driver-pre-plugins-rebuild; the pre-rebase
feature as backup/feat-agent-plugins-pre-rebase-2026-09-17 (delete
after merge).

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
hsm207 added a commit to hsm207/codebuff that referenced this pull request Sep 17, 2026
…or ruling

The first squash carried the unmerged MCP-fix (CodebuffAI#1259) silently.
Rebuilt plugins-only, verified, force-pushed with lease. The lesson
is recorded in the focus list: unmix a stacked branch BEFORE the
squash.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
hsm207 added a commit to hsm207/codebuff that referenced this pull request Sep 17, 2026
…the wall

Per the two-exits protocol, one verdict per note:

- 2026-09-16-01 (PR description raw material): processed - compiled
  into PR CodebuffAI#1372's public body; the private draft dies when the public
  artifact exists.
- 2026-09-16-02 (fb plugin smoke walkthrough + letter): processed -
  results in the shape note's ledger and commit c26e9b8; the round-2
  letter archived verbatim in oss-labnotes 2026-09-17-01; the REST
  fallback recipe in oss-labnotes 2026-09-17-02; the docs follow-up
  dropped by the guardrail ruling. Nothing unresolved remains here.
- 2026-09-17-02 (PR-prep sweep findings): processed - every finding
  executed (docstring fixes, toolbox strip, chore-drop rebase,
  plugins-only rebuild); the record of what was done and why lives in
  the driver-state lab note (oss-labnotes 2026-09-17-03) and the
  commit history.
- 2026-09-17-03 (PR description draft): processed - superseded by the
  posted PR body; already marked SUPERSEDED before deletion.

Kept, each with a written death condition:
- 2026-09-13-01 (shape note): dies when PR CodebuffAI#1372 merges.
- 2026-09-17-01 (upstream tsc-red): dies when upstream main is
  tsc-green.

Focus list updated to record the wall state and both death conditions.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@codebuff-team

Copy link
Copy Markdown
Contributor

There's clearly a lot of care here — the domain model in common/src/plugins/, the containment/reparse-point tests, the conflict-checking on install, the child-process discovery tests. This is not sloppy work.

But this PR adopts a third-party specification (github.com/agentplugins/agent-plugins-spec) as a first-class Codebuff/Freebuff feature, adds a new CLI verb (fb plugin install), and — most importantly — teaches the CLI to download an arbitrary GitHub tarball and wire its declared MCP servers and skills into a live session. That's a new trust boundary and a new product surface ("we now support an external plugin ecosystem"), not a bug fix or a docs correction. Whether Codebuff should support this spec at all, whether MCP servers from a plugin should be trusted the way ~/.agents/mcp.json is, and how name-conflict/precedence semantics should work (you flag several of these as open questions yourself, e.g. plugin-vs-user precedence in plugin-discovery.ts) are calls for the maintainers to make before any implementation, not decisions a PR should make unilaterally.

Separately, at +4276/-5 across 49 files touching CLI argument parsing, session wiring, MCP config mapping, and a new domain layer, this is far larger than what could be reviewed or hand-ported in one pass even if the direction were agreed on.

If you want this considered, I'd suggest opening an issue/discussion first proposing agent-plugin support as a feature, and if there's interest, land it in much smaller, independently reviewable slices (e.g. manifest parsing and validation alone, with no install/execution path, would be a reasonable first PR).

@codebuff-team codebuff-team added bot:triaged Classified by the community triage bot pr:out-of-scope Touches paths the public mirror does not accept labels Sep 17, 2026
@hsm207

hsm207 commented Sep 17, 2026

Copy link
Copy Markdown
Author

Thanks for the review. The trust-boundary point is fair, and the open questions deserve real discussion.

On the process point: the proposal already exists. #1349 has been open since Sep 13, four days before this PR, and the description links it in the first line. I built this PR as a first MVP to make the discussion concrete. Working end to end is what surfaced the open questions: plugin-vs-user precedence, what install-time consent looks like, and the spec gaps listed in the description.

Happy to keep going when a human review picks this up. I can amend here, work through the open questions on #1349, or split manifest parsing into a standalone first PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:triaged Classified by the community triage bot pr:out-of-scope Touches paths the public mirror does not accept

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for the Agent Plugins specification (plugin.json / mcp.json / skills)

2 participants