@swarmboard/shared

v1.6.0

Published

Shared TypeScript types and Zod schemas powering the swarmboard kanban platform — task models, organization/board entities, agent API payloads, and Socket.IO event contracts used by the swarmboard server, web client, and MCP server.

Downloads

706

Readme

@swarmboard/shared

Shared TypeScript types and Zod validation schemas for the swarmboard kanban platform.

This package is the single source of truth for the data contracts used across every swarmboard component — the Express API, the React web client, and the MCP server. By centralising the type definitions and runtime schemas in one place, the server, browser, and any AI agent stay in sync at both compile-time and runtime.

You typically don't install this package directly — it ships as a transitive dependency of @swarmboard/mcp-server. Install it explicitly only if you're building a custom client, alternative web frontend, or another service that talks to the swarmboard API.


What's inside

Core entities (TypeScript types + Zod schemas)

| Export | Description | |---|---| | Organization / OrganizationSchema | A workspace — top-level tenant boundary | | User / UserSchema | A swarmboard user (synced from Better Auth) | | Member / MemberSchema | A user's role inside an organization | | Board / BoardSchema | A kanban board, optionally linked to a git repository | | Task / TaskSchema | A kanban card with status, owner, agent type, conflict flags, CI status, PR link, board position, and optional parentId for subtasks | | ActivityLog / ActivityLogSchema | A log entry on a task (agent / git / ci / system / user source), with the originating user | | AgentToken / AgentTokenSchema | A per-developer API key used by AI agents to authenticate |

Enums (Zod enums + types)

  • TaskStatus"backlog" | "in_progress" | "in_review" | "verified" | "deployed"
  • MemberRole"owner" | "admin" | "member" | "viewer"
  • AgentType"cursor" | "claude_code" | "copilot" | "windsurf" | "other"
  • ActivitySource"agent" | "git" | "ci" | "system" | "user"

Agent API request payloads (used by the MCP server and POST /api/v1/tasks/* and /api/v1/boards/*)

  • ClaimTaskPayload — body for POST /tasks/:id/claim
  • UpdateTaskPayload — body for POST /tasks/:id/update
  • SubtaskPayload — body for POST /tasks/:id/subtask
  • BlockTaskPayload — body for POST /tasks/:id/block
  • CompleteTaskPayload — body for POST /tasks/:id/complete
  • CreateAgentTaskPayload — body for POST /boards/:boardId/tasks (create one task, optional parentId)
  • CreatePlanPayload / PlanTaskItem — body for POST /boards/:boardId/plan (create an agreed plan: tasks with nested subtasks)

Socket.IO event contracts

  • ServerToClientEventstask:created, task:updated, task:deleted, activity:created, conflict:detected, task:stale
  • ClientToServerEventsboard:join, board:leave

These interfaces give you fully typed Socket<ServerToClientEvents, ClientToServerEvents> instances on both ends of the wire.


Installation

npm install @swarmboard/shared
# or
pnpm add @swarmboard/shared
# or
yarn add @swarmboard/shared

This package targets ESM only ("type": "module"). It requires Node.js 18+ or a modern bundler. Zod is a peer-friendly direct dependency — installing this package will pull in zod@^3.25.76.


Usage

TypeScript types

import type { Task, TaskStatus, ActivityLog, Board } from "@swarmboard/shared";

function isActive(task: Task): boolean {
  return task.status === "in_progress" || task.status === "in_review";
}

Runtime validation with Zod

import { TaskSchema, ClaimTaskPayload } from "@swarmboard/shared";

// Validate an unknown payload before processing it
const result = TaskSchema.safeParse(unknownData);
if (!result.success) {
  console.error(result.error.flatten());
  return;
}
const task = result.data;

// Build a typed Agent API request body
const body: ClaimTaskPayload = ClaimTaskPayload.parse({
  agentType: "cursor",
  agentModel: "claude-opus-4.8",
  files: ["apps/api/src/index.ts"],
});

Strongly-typed Socket.IO

import { io, Socket } from "socket.io-client";
import type { ServerToClientEvents, ClientToServerEvents } from "@swarmboard/shared";

const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io("/");

socket.on("task:updated", (task) => {
  // `task` is fully typed as Task — no `any`, no manual casting
});

socket.emit("board:join", boardId);

Related packages


License

MIT