Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/bradygaster/squad/llms.txt

Use this file to discover all available pages before exploring further.

When Squad initializes a team, it does not give agents generic names like “Agent1” or “Backend”. Instead, the casting engine assigns each agent a character name drawn from a fictional universe — The Usual Suspects, Ocean’s Eleven, and others. Names are deterministic: the same team configuration always produces the same cast, so your team identity persists across sessions, machines, and contributors. Keyser will always be Keyser on this project. This matters for more than aesthetics. Persistent names let agents build identity over time — their history.md is indexed by name, their decisions are attributed by name, and the coordinator refers to them by name. When you say “McManus, look at this performance issue”, the routing engine knows exactly who you mean.

How Casting Works

The CastingEngine maps each AgentRole to a character from the chosen universe. Role-to-character assignment prefers characters whose preferredRoles match the requested role, then falls back to unassigned characters in order. The casting results are stored in .squad/casting/:
.squad/casting/
├── policy.json     # Casting configuration (universe, overflow strategy)
├── registry.json   # Persistent name registry (role → character mapping)
└── history.json    # Universe usage history across casts
Do not manually edit registry.json. The casting engine manages it. Manual edits can cause name conflicts — if the same character appears twice or a role maps to the wrong name, the coordinator’s routing becomes inconsistent. Use squad init or the SDK to re-cast.

Supported Universes

The SDK ships with two built-in universes:

The Usual Suspects (usual-suspects)

CharacterPreferred RolesPersonality
KeyserleadQuietly commanding; sees the whole board before anyone else
McManusdeveloperBold and direct; ships fast, asks questions later
FenstertesterEccentric communicator; finds bugs nobody else can see
Verbalprompt-engineer, scribeSilver-tongued storyteller; turns complexity into clarity
Hockneysecurity, reviewerStreet-smart and suspicious; trusts no input
RedfootdevopsResourceful fixer; keeps the machinery running
Ediereviewer, testerMethodical and detail-oriented; nothing escapes review
Kobayashidesigner, prompt-engineerPrecise and formal; an interface between worlds

Ocean’s Eleven (oceans-eleven)

Characters drawn from the heist ensemble — Danny, Rusty, Linus, Saul, Livingston, and others — each mapped to corresponding roles.

Custom universes

Set universe: 'custom' and provide a customNames map to use your own character names:
const team = engine.castTeam({
  universe: 'custom',
  teamSize: 3,
  requiredRoles: ['lead', 'developer', 'tester'],
  customNames: {
    lead: 'Picard',
    developer: 'LaForge',
    tester: 'Data',
  },
});

Overflow strategy

When a team is larger than the available characters in a universe, the overflowStrategy setting controls what happens:
StrategyBehavior
genericExtra agents get generic names (Agent1, Agent2, …)
rotateCharacters are reused from the beginning of the universe list
rejectAn error is thrown if the team exceeds universe capacity

Configuring Casting

In squad.config.ts (SDK-first mode):
import { defineSquad, defineTeam, defineAgent, defineCasting } from '@bradygaster/squad-sdk';

export default defineSquad({
  team: defineTeam({ name: 'Platform Squad', members: [] }),
  agents: [
    defineAgent({ name: 'lead', role: 'lead', model: 'claude-sonnet-4' }),
    defineAgent({ name: 'dev', role: 'developer', model: 'claude-haiku-4.5' }),
  ],
  casting: defineCasting({
    allowlistUniverses: ['The Usual Suspects', "Ocean's Eleven"],
    overflowStrategy: 'generic',
  }),
});
In markdown-first mode: Edit .squad/casting/policy.json directly:
{
  "allowlistUniverses": ["The Usual Suspects"],
  "overflowStrategy": "generic",
  "universeCapacity": {}
}
The default configuration (created by squad init) allows the two built-in universes with generic overflow.

Casting History

CastingHistory ensures names persist across sessions. Once an agent is cast with a name, that name is recorded in history.json. On subsequent casts with the same configuration, the history is consulted first and the same names are returned.
import { CastingHistory } from '@bradygaster/squad-sdk';

const history = new CastingHistory();

// Record a cast
history.recordCast(team, config);

// Serialize to disk
const serialized = history.serializeHistory();

// Query history for a specific agent
const agentHistory = history.getAgentHistory('Keyser');
console.log(`Keyser appeared in ${agentHistory.length} cast(s)`);
The serialized history includes a version field and an array of CastingRecord objects, each containing the full team lineup, the universe used, and a timestamp. This makes it straightforward to audit when and how the team was cast, and to restore a previous cast if needed.

SDK Usage

Here is a complete example from the hello-squad sample showing how to cast a team, onboard agents, and persist the casting history:
import { resolveSquad, CastingEngine, CastingHistory, onboardAgent } from '@bradygaster/squad-sdk';
import type { CastMember, AgentRole } from '@bradygaster/squad-sdk';

// Step 1: Cast a team of 4 agents from The Usual Suspects
const engine = new CastingEngine();
const roles: AgentRole[] = ['lead', 'developer', 'tester', 'scribe'];

const team: CastMember[] = engine.castTeam({
  universe: 'usual-suspects',
  teamSize: roles.length,
  requiredRoles: roles,
});

// Each CastMember has: name, role, personality, backstory, displayName
for (const member of team) {
  console.log(`🎭 ${member.displayName}`);
  // e.g. "Keyser — Lead"
}

// Step 2: Onboard each agent (creates charter.md and history.md)
for (const member of team) {
  await onboardAgent({
    teamRoot: '/path/to/project',
    agentName: member.name.toLowerCase(),
    role: member.role,
    displayName: member.displayName,
    projectContext: 'Description of your project',
    userName: 'YourName',
  });
}

// Step 3: Persist casting history so names survive across sessions
const history = new CastingHistory();
const config = { universe: 'usual-suspects' as const, teamSize: 4, requiredRoles: roles };
history.recordCast(team, config);

// Casting is deterministic — same config always produces same names
const team2 = engine.castTeam(config);
const match = team.every((m, i) => m.name === team2[i].name);
console.log(`Names match: ${match}`); // true
See the full sample at /samples/hello-squad/index.ts in the repository.

Build docs developers (and LLMs) love