SDK Reference

Complete reference for @bradygaster/squad-sdk — the programmatic API for Squad.

npm install @bradygaster/squad-sdk

All imports work from the barrel export:

import { resolveSquad, loadConfig, SquadCoordinator, defineTool } from '@bradygaster/squad-sdk';

Resolution

Find .squad/ directories on disk.

Function Description
resolveSquad(startPath?) Find .squad/ walking up from startPath (throws if not found)
resolveGlobalSquadPath() Get ~/.squad/ path (%USERPROFILE%\.squad\ on Windows)
ensureSquadPath(startPath?) Like resolveSquad, but creates .squad/ if missing
const squadPath = resolveSquad();                // '/home/user/project/.squad'
const globalPath = resolveGlobalSquadPath();      // '/home/user/.squad'
const safePath = ensureSquadPath();               // Creates if needed

Configuration

loadConfig(squadPath): Promise<ConfigLoadResult>

Load and validate Squad configuration asynchronously.

const config = await loadConfig('./.squad');
config.team.name;           // Team name
Object.keys(config.agents); // Agent names
config.routing.workTypes;   // Routing rules

loadConfigSync(squadPath): ConfigLoadResult

Synchronous version for scripts and CLI tools.

defineConfig(partial): SquadConfig

Create a typed config with defaults and editor autocomplete:

// squad.config.ts
import { defineConfig } from '@bradygaster/squad-sdk';

export default defineConfig({
  team: { name: 'my-squad', root: '.squad' },
  agents: {
    backend: { model: 'claude-sonnet-4', tools: ['route', 'memory', 'decision'] },
  },
  routing: {
    workTypes: [
      { pattern: /\bAPI|backend\b/i, targets: ['backend'], tier: 'standard' },
    ],
  },
  models: {
    default: 'claude-sonnet-4',
    fallbackChains: {
      premium: ['claude-opus-4', 'gpt-4.1'],
      standard: ['claude-sonnet-4', 'gpt-4.1'],
      fast: ['claude-haiku-3.5', 'gpt-4.1-mini'],
    },
  },
});

Key Types

interface ConfigLoadResult {
  team: { name: string; root: string; description?: string };
  agents?: Record<string, AgentConfig>;
  routing?: RoutingConfig;
  models?: ModelConfig;
}

interface AgentConfig {
  role: string;
  model?: string;
  tools?: string[];
  status?: 'active' | 'inactive';
}

SquadClient

Wraps @github/copilot-sdk with lifecycle management and auto-reconnection.

import { SquadClient } from '@bradygaster/squad-sdk';

const client = new SquadClient({
  port: 3000,
  auth: { token: process.env.COPILOT_TOKEN },
  reconnection: { maxRetries: 5, backoffMs: 1000 },
});

await client.connect();

Connection states: disconnected → connecting → connected → reconnecting → error

SquadClientWithPool

Production-ready client composing SquadClient, SessionPool, and EventBus:

import { SquadClientWithPool } from '@bradygaster/squad-sdk';

const squad = new SquadClientWithPool({
  client: clientOptions,
  pool: { maxConcurrent: 10, idleTimeout: 60_000 },
});

const session = await squad.createSession({ agent: 'backend' });
const response = await session.sendMessage('Implement the /users endpoint');
await session.destroy();

Session states: creating → active → idle → error → destroyed


Coordinator

Central routing and orchestration engine.

SquadCoordinator

import { SquadCoordinator } from '@bradygaster/squad-sdk';

const coordinator = new SquadCoordinator({ teamRoot: './.squad', enableParallel: true });
await coordinator.initialize();

const decision = await coordinator.route('refactor the API');
// decision.tier:      'direct' | 'lightweight' | 'standard' | 'full'
// decision.agents:    ['backend', 'tester']
// decision.parallel:  true
// decision.rationale: 'Backend refactor with test coverage'

await coordinator.execute(decision, 'refactor the API');
await coordinator.shutdown();

selectResponseTier(context): TierName

const tier = selectResponseTier({ complexity: 'high', budget: 10, userTeam: true });
// → 'standard' or 'full'

getTier(name): TierDefinition

const tier = getTier('standard');
tier.maxAgents;     // Max parallel agents
tier.defaultModel;  // Default model
tier.toolset;       // Available tools

Event Handling

Typed pub/sub for session lifecycle events:

squad.events.on('session.created', (event) => {
  console.log(`Session ${event.sessionId} started`);
});

squad.events.on('session.status_changed', (event) => {
  if (event.payload.status === 'error') { /* handle */ }
});

Events: session.created, session.destroyed, session.status_changed, tool execution events.


Tools & Hooks

defineTool<TArgs>(config): SquadTool<TArgs>

import { defineTool } from '@bradygaster/squad-sdk';

const myTool = defineTool<{ query: string }>({
  name: 'search_docs',
  description: 'Search project documentation',
  parameters: {
    type: 'object',
    properties: { query: { type: 'string' } },
    required: ['query'],
  },
  handler: async (args) => ({
    textResultForLlm: `Found results for "${args.query}"`,
    resultType: 'success',
  }),
});

ToolRegistry

const registry = new ToolRegistry('./.squad');
registry.getTools();                                    // All tools
registry.getToolsForAgent(['squad_route', 'squad_decide']); // Agent-specific
registry.getTool('squad_route');                         // Single lookup

Built-in tools:

Tool Purpose
squad_route Route a task to another agent
squad_decide Write decisions to the inbox
squad_memory Append to agent history
squad_status Query session pool state
squad_skill Read/write agent skills

HookPipeline

Intercept tool calls before (PreToolUseHook) and after (PostToolUseHook) execution:

import { HookPipeline, type PreToolUseHook } from '@bradygaster/squad-sdk';

const auditHook: PreToolUseHook = async (toolName, params, context) => {
  console.log(`Agent ${context.agentId} calling ${toolName}`);
  return { action: 'allow' };
};

const pipeline = new HookPipeline();
pipeline.addPreHook(auditHook);

Hook actions: allow, block, modify

Built-in policies: ReviewerLockout, File Guards, Shell Restrictions, Rate Limits, PII Filters.


Agents & Casting

onboardAgent(options): Promise<OnboardResult>

const result = await onboardAgent({
  teamRoot: './.squad',
  agentName: 'data-analyst',
  role: 'backend',
  displayName: 'Dana — Data Analyst',
  projectContext: 'A recipe sharing app',
});
// result.agentDir, result.charterPath, result.historyPath

CastingEngine

import { CastingEngine } from '@bradygaster/squad-sdk';

const engine = new CastingEngine({ universes: ['The Wire'], activeUniverse: 'The Wire' });
const members = await engine.castTeam([
  { role: 'lead', title: 'Lead Developer' },
  { role: 'backend', title: 'Backend Engineer' },
]);
// members[0].name → 'Stringer', members[0].universe → 'The Wire'

Runtime Constants

import { MODELS, TIMEOUTS, AGENT_ROLES } from '@bradygaster/squad-sdk';

MODELS.premium;  // ['claude-opus-4.6', 'gpt-5.2', ...]
MODELS.standard; // ['claude-sonnet-4.5', 'gpt-5.1', ...]
MODELS.fast;     // ['claude-haiku-4.5', 'gpt-5-mini', ...]

TIMEOUTS.agentInitMs;        // 30000
TIMEOUTS.agentExecuteMs;     // 300000
TIMEOUTS.coordinatorRouteMs; // 5000

Upstream Inheritance

Share skills, decisions, and routing across teams.

import { readUpstreamConfig, resolveUpstreams, buildInheritedContextBlock } from '@bradygaster/squad-sdk';

const config = await readUpstreamConfig('./.squad');
const resolved = await resolveUpstreams(config, './.squad');
const contextBlock = buildInheritedContextBlock(resolved);

Upstream types: local, git, export


Observability (OpenTelemetry)

Quick Setup

import { initSquadTelemetry } from '@bradygaster/squad-sdk';

const telemetry = await initSquadTelemetry({
  endpoint: 'http://localhost:4318',
  serviceName: 'my-squad',
  eventBus: myEventBus,
});

// ... run agents ...
await telemetry.shutdown();

Low-Level Control

import { initializeOTel, shutdownOTel, getTracer, getMeter } from '@bradygaster/squad-sdk';

await initializeOTel({ endpoint: 'http://localhost:4318' });

const tracer = getTracer('my-component');
const span = tracer.startSpan('my-work');
// ... do work ...
span.end();

const meter = getMeter('my-component');
const counter = meter.createCounter('requests_total');
counter.add(1);

await shutdownOTel();

Error Classes

All errors extend SquadError with severity, category, and recoverability:

Error When
SDKConnectionError Connection failures (retryable)
AuthenticationError Bad credentials (fatal)
SessionLifecycleError Session state transitions
ToolExecutionError Tool call failures
ModelAPIError Model unavailable or rate limited
ConfigurationError Invalid config (includes field + reason)
RateLimitError Too many requests
ValidationError Schema validation failures

Exports at a Glance

Export Type Module
resolveSquad function resolution
resolveGlobalSquadPath function resolution
ensureSquadPath function resolution
MODELS constant runtime/constants
TIMEOUTS constant runtime/constants
AGENT_ROLES constant runtime/constants
loadConfig / loadConfigSync function config
onboardAgent function agents
CastingEngine / CastingHistory class casting
SquadCoordinator class coordinator
selectResponseTier / getTier function coordinator
defineTool / ToolRegistry function/class tools
initializeOTel / shutdownOTel function runtime/otel
getTracer / getMeter function runtime/otel
initSquadTelemetry function runtime/otel-init

See Also