Motivation
Enterprise teams standardize how agents behave across repositories — a "React Frontend" role should mean the same thing in every repo, enforced at the tooling level rather than by convention. Today, the only way to achieve this is duplicating defineAgent() definitions in every repo's squad.config.ts or forking the SDK. Neither scales. A centrally maintained role catalog distributed through the existing marketplace infrastructure would let platform teams define once, install everywhere, and update without touching individual repos.
Problem Statement
useRole() resolves against BASE_ROLES — a compiled array in packages/squad-sdk/src/roles/catalog.ts. There is no mechanism for marketplace plugins to register new role IDs that useRole() can discover.
This means organizations that need constrained role definitions (e.g., a React-only frontend role that excludes Vue/Angular from expertise and boundaries) have three options, all with drawbacks:
- Per-repo
squad.config.ts with defineAgent() inline — works but doesn't scale across dozens of repos. Each repo duplicates the same constrained definitions.
- Skills layering — plugins can install
SKILL.md files, but skills are advisory. They don't change expertise, boundaries, ownership, or routingPatterns at the catalog level.
- Fork the SDK — full control, but maintenance burden on every upstream release.
The gap: plugins can deliver skills and charter overlays, but cannot deliver first-class roles that participate in useRole(), searchRoles(), and squad init scaffolding.
Proposed Solution
Allow a marketplace plugin to include a roles/ directory containing role definition files. When installed, these entries are registered in a runtime-extensible catalog layer that useRole() resolves after checking BASE_ROLES.
Detailed API design and resolution semantics should go in a proposal (docs/proposals/). The key constraints:
- Plugin roles must not override built-in
BASE_ROLES entries (additive only)
useRole('react-frontend') should resolve a plugin-provided role the same way it resolves a built-in one
squad init scaffolding should discover plugin roles alongside built-in roles
- Role IDs must be namespaced to avoid cross-plugin collisions
Acceptance Criteria
Alternatives Considered
- Starter repo / bootstrap package — an org creates a template repo with pre-configured
squad.config.ts. Reduces duplication but doesn't solve drift when the base definition changes.
squad upstream for shared config — upstream syncs context (skills, decisions, manifests), not role definitions. Would require extending upstream semantics beyond its current scope.
- App-generator approach — a CLI command generates
squad.config.ts from a central template. Produces per-repo snapshots that go stale.
Files Likely Affected
packages/squad-sdk/src/roles/catalog.ts — resolution layer
packages/squad-sdk/src/roles/index.ts — useRole(), searchRoles()
packages/squad-sdk/src/roles/types.ts — namespace type additions
packages/squad-cli/src/cli/commands/plugin.ts — install flow for role definitions
packages/squad-sdk/src/config/init.ts — scaffolding role discovery
Motivation
Enterprise teams standardize how agents behave across repositories — a "React Frontend" role should mean the same thing in every repo, enforced at the tooling level rather than by convention. Today, the only way to achieve this is duplicating
defineAgent()definitions in every repo'ssquad.config.tsor forking the SDK. Neither scales. A centrally maintained role catalog distributed through the existing marketplace infrastructure would let platform teams define once, install everywhere, and update without touching individual repos.Problem Statement
useRole()resolves againstBASE_ROLES— a compiled array inpackages/squad-sdk/src/roles/catalog.ts. There is no mechanism for marketplace plugins to register new role IDs thatuseRole()can discover.This means organizations that need constrained role definitions (e.g., a React-only frontend role that excludes Vue/Angular from expertise and boundaries) have three options, all with drawbacks:
squad.config.tswithdefineAgent()inline — works but doesn't scale across dozens of repos. Each repo duplicates the same constrained definitions.SKILL.mdfiles, but skills are advisory. They don't changeexpertise,boundaries,ownership, orroutingPatternsat the catalog level.The gap: plugins can deliver skills and charter overlays, but cannot deliver first-class roles that participate in
useRole(),searchRoles(), andsquad initscaffolding.Proposed Solution
Allow a marketplace plugin to include a
roles/directory containing role definition files. When installed, these entries are registered in a runtime-extensible catalog layer thatuseRole()resolves after checkingBASE_ROLES.Detailed API design and resolution semantics should go in a proposal (
docs/proposals/). The key constraints:BASE_ROLESentries (additive only)useRole('react-frontend')should resolve a plugin-provided role the same way it resolves a built-in onesquad initscaffolding should discover plugin roles alongside built-in rolesAcceptance Criteria
useRole()discoversBASE_ROLES@marketplace/react-frontend)searchRoles()andgetRoleCategories()include plugin-provided rolessquad initoffers plugin roles during scaffolding when a matching plugin is installedAlternatives Considered
squad.config.ts. Reduces duplication but doesn't solve drift when the base definition changes.squad upstreamfor shared config — upstream syncs context (skills, decisions, manifests), not role definitions. Would require extending upstream semantics beyond its current scope.squad.config.tsfrom a central template. Produces per-repo snapshots that go stale.Files Likely Affected
packages/squad-sdk/src/roles/catalog.ts— resolution layerpackages/squad-sdk/src/roles/index.ts—useRole(),searchRoles()packages/squad-sdk/src/roles/types.ts— namespace type additionspackages/squad-cli/src/cli/commands/plugin.ts— install flow for role definitionspackages/squad-sdk/src/config/init.ts— scaffolding role discovery