SDKs and Client Libraries

Official SDKs and client libraries for integrating with the TeamDay platform.

Overview

TeamDay provides client libraries for building applications on top of the platform. All SDKs use Firebase as the underlying transport layer with Firestore for real-time data and Firebase Auth for authentication.

SDKStatusLanguageUse Case
JavaScript/TypeScript SDK✅ ProductionTypeScriptWeb apps (Nuxt/Vue)
REST API🚧 PlannedN/AServer-side integrations
Python SDK📋 RoadmapPythonScripts, automation
CLI Tool✅ ProductionTypeScriptDevelopment workflow

JavaScript/TypeScript SDK

The primary SDK is built with Vue 3 composables and works seamlessly with Nuxt 3 applications.

Installation

# Using bun (recommended)
bun add firebase firebase/firestore

# Using npm
npm install firebase

Configuration

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      firebase: {
        apiKey: process.env.NUXT_PUBLIC_FIREBASE_API_KEY,
        authDomain: process.env.NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
        projectId: process.env.NUXT_PUBLIC_FIREBASE_PROJECT_ID,
        storageBucket: process.env.NUXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
        messagingSenderId: process.env.NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
        appId: process.env.NUXT_PUBLIC_FIREBASE_APP_ID,
      }
    }
  }
})

Core Composables

Authentication - useAuth()

Manages user authentication and session state.

const {
  user,           // Current user (reactive)
  loading,        // Auth state loading
  signInWithGoogle,
  signInWithGitHub,
  signOut
} = useAuth()

// Check if user is authenticated
if (user.value) {
  console.log('User ID:', user.value.uid)
  console.log('Email:', user.value.email)
}

// Sign in with Google
await signInWithGoogle()

// Sign out
await signOut()

Available Methods:

  • signInWithGoogle() - OAuth with Google
  • signInWithGitHub() - OAuth with GitHub
  • signInWithEmail(email, password) - Email/password auth
  • signOut() - Sign out current user

Organizations - useOrganizations()

Manage organizations and team memberships.

const {
  organizations,           // Array of user's organizations
  loading,
  error,
  fetchUserOrganizations,
  getOrganization,
  createOrganization,
  updateOrganization
} = useOrganizations()

// Fetch user's organizations
await fetchUserOrganizations()

// Get specific organization
const org = await getOrganization('org_id')

// Create new organization
const newOrg = await createOrganization('Acme Corp')

// Update organization
await updateOrganization('org_id', {
  name: 'Acme Corporation',
  logoUrl: 'https://...'
})

Organization Type:

interface Organization {
  id: string
  name: string
  logoUrl?: string
  ownerId: string
  members: string[]
  subscription?: {
    tier: 'free' | 'pro' | 'enterprise'
    status: 'active' | 'cancelled' | 'expired'
  }
  createdAt: Date
  updatedAt: Date
}

Spaces - useSpaces()

Manage workspaces where agents operate.

const {
  spaces,              // Array of spaces (reactive, real-time)
  chats,               // Chats in current space
  loading,
  error,
  fetchSpaces,
  createSpace,
  updateSpace,
  deleteSpace,
  initializeSpace
} = useSpaces()

// Subscribe to real-time updates
fetchSpaces('org_id')

// Create a new space
const space = await createSpace(
  'org_id',
  'Marketing Workspace',
  'Space for marketing team',
  'organization',  // visibility
  'https://cover-image.jpg'
)

// Update space
await updateSpace('space_id', {
  name: 'Updated Name',
  description: 'Updated description'
})

// Initialize workspace (creates file system)
await initializeSpace('space_id', {
  type: 'empty'  // or 'git', 'readme', 'starterKit'
})

// Soft delete (can be restored)
await softDeleteSpace('space_id')

// Restore deleted space
await restoreSpace('space_id')

// Permanent delete
await deleteSpace('space_id')

Space Type:

interface Space {
  id: string
  organizationId: string
  name: string
  description: string
  visibility: 'private' | 'organization' | 'public'
  ownerId: string
  assignedAgents?: string[]       // Character IDs
  skillIds?: string[]             // Skill IDs
  pluginIds?: string[]            // Plugin IDs
  chatCount?: number
  fileCount?: number
  createdAt: Date
  updatedAt: Date
}

Characters (Agents) - useCharacters()

Manage AI agents/assistants.

const {
  characters,          // Array of characters (reactive, real-time)
  loading,
  error,
  fetchCharacters,
  createCharacter,
  getCharacter,
  updateCharacter,
  deleteCharacter
} = useCharacters()

// Subscribe to real-time updates
fetchCharacters('org_id')

// Create a new agent
const agent = await createCharacter(
  'org_id',
  'Marketing Maven',
  'Marketing Assistant',
  'You are an expert marketing assistant...',
  'organization'  // visibility
)

// Get specific character
const character = await getCharacter('char_id')

// Update character
await updateCharacter('char_id', {
  name: 'Updated Name',
  systemPrompt: 'Updated prompt...',
  skillIds: ['research-assistant', 'technical-writer'],
  advanced_tools: ['mcp_google_analytics']
})

// Soft delete
await softDeleteCharacter('char_id')

// Restore
await restoreCharacter('char_id')

// Archive (soft delete alternative)
await deleteCharacter('char_id')

Character Type:

interface Character {
  id: string
  name: string
  role: string
  initialGreeting: string
  system_message: string
  image: string
  color: string
  model?: string
  visibility: 'private' | 'organization' | 'public' | 'unlisted'
  ownerId: string
  organizationId?: string
  skillIds?: string[]
  advanced_tools?: string[]
  tags?: string[]
  archived?: boolean
  createdAt: Date
}

Chats - useChatCrud()

Manage conversations with agents.

const {
  chats,               // Array of chats (reactive, real-time)
  loading,
  error,
  fetchChats,
  createChat,
  getChat,
  updateChat,
  deleteChat,
  toggleChatClosed
} = useChatCrud()

// Fetch chats for a space
await fetchChats('org_id', 'space_id')

// Create new chat
const chat = await createChat('org_id', 'space_id', 'New Conversation')

// Get specific chat
const chat = await getChat('chat_id')

// Update chat
await updateChat('chat_id', {
  title: 'Updated Title',
  status: 'done'
})

// Toggle closed state
await toggleChatClosed('chat_id')

// Delete chat
await deleteChat('chat_id')

Chat Type:

interface Chat {
  id: string
  organizationId: string
  spaceId: string
  title: string
  subtitle?: string
  status: 'standby' | 'working' | 'done' | 'needs_attention' | 'error'
  ownerId: string
  lastMessage?: string
  sessionId?: string
  closed: boolean
  closedAt?: Date | null
  createdAt: Date
  updatedAt: Date
}

Skills - useSkills()

Manage reusable prompt packages.

const {
  skills,              // Array of skills
  loading,
  error,
  fetchSkills,
  createSkill,
  updateSkill,
  deleteSkill
} = useSkills()

// Fetch skills for organization
await fetchSkills('org_id')

// Create a skill
const skill = await createSkill({
  name: 'custom-researcher',
  displayName: 'Custom Researcher',
  description: 'Custom research skill',
  prompt: '# Research Skill\n\nInstructions...',
  category: 'research',
  builtInTools: ['WebSearch', 'Read'],
  visibility: 'organization',
  organizationId: 'org_id',
  ownerId: 'user_id'
})

// Update skill
await updateSkill('skill_id', {
  displayName: 'Updated Name',
  prompt: 'Updated instructions...'
})

// Delete skill
await deleteSkill('skill_id')

Skill Type:

interface Skill {
  id: string
  name: string                    // kebab-case
  displayName: string
  description: string
  prompt: string                  // Markdown instructions
  category: 'research' | 'writing' | 'data' | 'code' | 'marketing' | 'productivity' | 'file-handling' | 'other'
  builtInTools?: string[]
  requiredMCPs?: string[]
  visibility: 'private' | 'organization' | 'public'
  organizationId: string
  ownerId: string
  version: number
  createdAt: Date
}

Missions - useMissions()

Manage long-running autonomous tasks.

const {
  missions,            // Array of missions
  loading,
  error,
  fetchMissions,
  createMission,
  updateMission,
  pauseMission,
  resumeMission
} = useMissions()

// Fetch missions
await fetchMissions('org_id')

// Create mission
const mission = await createMission({
  title: 'Daily Report',
  goal: 'Generate daily analytics report',
  agentType: 'claude',
  schedule: {
    type: 'cron',
    value: '0 9 * * *'  // Every day at 9 AM
  },
  organizationId: 'org_id',
  userId: 'user_id'
})

// Update mission
await updateMission('mission_id', {
  status: 'paused'
})

// Pause/Resume
await pauseMission('mission_id')
await resumeMission('mission_id')

Real-Time Subscriptions

All data composables provide real-time updates using Firestore's onSnapshot.

Subscription Lifecycle

const { fetchSpaces, unsubscribeSpaces } = useSpaces()

// Start subscription
fetchSpaces('org_id')

// Data updates automatically when Firestore changes
watch(spaces, (newSpaces) => {
  console.log('Spaces updated:', newSpaces.length)
})

// Cleanup on unmount
onUnmounted(() => {
  unsubscribeSpaces()
})

Auto-Cleanup

Composables handle cleanup automatically in most cases:

// This automatically cleans up on component unmount
const { spaces } = useSpaces()
fetchSpaces('org_id')

Error Handling

All composables follow a consistent error pattern:

const { error, loading } = useSpaces()

// Check loading state
if (loading.value) {
  console.log('Loading...')
}

// Check for errors
if (error.value) {
  console.error('Error:', error.value)
}

// Try-catch for explicit operations
try {
  await createSpace(...)
} catch (err) {
  console.error('Failed to create space:', err)
}

TypeScript Support

All types are fully typed with TypeScript:

import type { Space, Character, Skill, Chat } from '~/types'

const space: Space = await getSpace('space_id')
const character: Character = await getCharacter('char_id')

Type Exports:

// From ~/types/space
export type { Space, Chat, ChatMessage, SpaceVisibility }

// From ~/types/character
export type { Character, CharacterVisibility }

// From ~/types/skill
export type { Skill, SkillCategory, SkillVisibility }

// From ~/types/mission
export type { Mission, MissionStatus, AgentType }

// From ~/types/task
export type { Task, TaskStatus, TaskPriority }

// From ~/types/execution
export type { Execution, ExecutionStatus }

Server API Endpoints

TeamDay provides server-side API endpoints for operations requiring elevated permissions.

Base URL

Production: https://teamday.ai/api
Development: http://localhost:3000/api

Authentication

Use Firebase ID tokens for authentication:

const idToken = await user.value?.getIdToken()

const response = await fetch('/api/endpoint', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${idToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})

Available Endpoints

Space Initialization

POST /api/spaces/:spaceId/init
Content-Type: application/json

{
  "type": "empty",      // or "git", "readme", "starterKit"
  "orgId": "org_id",
  "spaceName": "Workspace Name"
}

Space Environment Variables

POST /api/spaces/:spaceId/environment
Content-Type: application/json

{
  "environmentVariables": {
    "API_KEY": "encrypted_value",
    "DATABASE_URL": "encrypted_value"
  }
}

Agent Execution

POST /api/agent/execute
Content-Type: application/json

{
  "characterId": "char_id",
  "spaceId": "space_id",
  "message": "User message",
  "sessionId": "session_id"
}

Usage Analytics

GET /api/usage/organization/:orgId?period=daily&start=2024-01-01&end=2024-01-31
Authorization: Bearer <id_token>

CLI Tool

The TeamDay CLI provides development workflow commands.

Installation

# Using bun
bun add -g @teamday/cli

# Using npm
npm install -g @teamday/cli

Authentication

# Login via browser OAuth
teamday login

# Verify authentication
teamday whoami

Commands

# Initialize a new space
teamday space init

# Deploy an agent
teamday agent deploy ./agent-config.json

# Run a mission locally
teamday mission run mission_id

# Tail agent logs
teamday logs --follow --space space_id

# Manage environment variables
teamday env set API_KEY=value
teamday env list

Configuration

Create .teamdayrc.json in your project:

{
  "organizationId": "org_abc123",
  "defaultSpace": "space_456",
  "region": "us-central1"
}

Best Practices

1. Always Clean Up Subscriptions

const unsubscribe = ref<Unsubscribe | null>(null)

const subscribe = () => {
  if (unsubscribe.value) {
    unsubscribe.value()
  }

  unsubscribe.value = onSnapshot(query, callback)
}

onUnmounted(() => {
  if (unsubscribe.value) {
    unsubscribe.value()
  }
})

2. Handle Undefined Values

Firestore doesn't allow undefined. Always use null or omit:

// ❌ Bad
await updateDoc(docRef, {
  optional: undefined
})

// ✅ Good
const cleanData = Object.fromEntries(
  Object.entries(data).filter(([_, v]) => v !== undefined)
)
await updateDoc(docRef, cleanData)

3. Use Server Timestamps

import { serverTimestamp } from 'firebase/firestore'

await updateDoc(docRef, {
  updatedAt: serverTimestamp()
})

4. Optimistic Updates

For better UX, show changes immediately:

// Add optimistically
optimisticSpaces.value.push(newSpace)

// Then persist
await addDoc(collection, spaceData)

// Snapshot updates with real data

5. Error Boundaries

Wrap operations in try-catch:

try {
  await createSpace(...)
} catch (error) {
  console.error('Operation failed:', error)
  // Show user-friendly error message
  toast.error('Failed to create space')
}

Migration from v1 to v2

Breaking Changes

Authentication:

  • Changed from custom JWT to Firebase Auth
  • Update: Replace useAuthToken() with useAuth()

Composables:

  • Renamed useAgents() to useCharacters()
  • Removed skills inline field, use skillIds instead

Types:

  • Agent renamed to Character
  • systemPrompt field renamed to system_message

Migration Guide

// v1
const { agents } = useAgents()

// v2
const { characters } = useCharacters()

// v1
const agent = {
  systemPrompt: 'You are...',
  skills: [{ name: 'research', instructions: '...' }]
}

// v2
const character = {
  system_message: 'You are...',
  skillIds: ['research-assistant']
}

Version Compatibility

TeamDay VersionSDK VersionFirebase SDKNuxt Version
1.0.x1.0.x^10.7.0^3.9.0
2.0.x2.0.x^10.12.0^3.13.0

Examples

Complete Workspace Setup

<script setup lang="ts">
const { user } = useAuth()
const { organizations, fetchUserOrganizations } = useOrganizations()
const { createSpace, fetchSpaces, spaces } = useSpaces()
const { createCharacter, fetchCharacters } = useCharacters()

// On mount, fetch user's organizations
onMounted(async () => {
  await fetchUserOrganizations()

  if (organizations.value.length > 0) {
    const orgId = organizations.value[0].id

    // Subscribe to spaces and characters
    fetchSpaces(orgId)
    fetchCharacters(orgId)
  }
})

// Create a complete workspace
const setupWorkspace = async () => {
  const orgId = organizations.value[0].id

  // 1. Create space
  const space = await createSpace(
    orgId,
    'My Workspace',
    'A workspace for my team',
    'organization'
  )

  // 2. Create agent
  const agent = await createCharacter(
    orgId,
    'Research Assistant',
    'Researcher',
    'You are an expert researcher...',
    'organization'
  )

  // 3. Assign agent to space
  if (space && agent) {
    await updateSpace(space.id, {
      assignedAgents: [agent.id]
    })
  }

  console.log('Workspace ready!')
}
</script>

Real-Time Chat

<script setup lang="ts">
const { chats, fetchChats } = useChatCrud()
const route = useRoute()

const spaceId = route.params.spaceId as string
const orgId = route.params.orgId as string

// Subscribe to chats in this space
fetchChats(orgId, spaceId)

// Watch for new messages
watch(chats, (newChats) => {
  const latestChat = newChats[0]
  if (latestChat?.status === 'done') {
    console.log('Agent finished:', latestChat.lastMessage)
  }
})
</script>

Support


Roadmap

Q1 2025

  • ✅ JavaScript/TypeScript SDK
  • ✅ CLI Tool
  • 🚧 REST API (beta)

Q2 2025

  • 📋 Python SDK
  • 📋 Webhook subscriptions
  • 📋 GraphQL API

Q3 2025

  • 📋 Go SDK
  • 📋 Mobile SDKs (React Native)
  • 📋 Streaming API for real-time agent output

Contributing

We welcome contributions! See our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/teamday/teamday.git
cd teamday

# Install dependencies
bun install

# Start development server
bun run dev

# Run tests
bun test

License

The TeamDay SDK is released under the MIT License. See LICENSE for details.