πŸ“„ File detail

utils/teammateContext.ts

🧩 .tsπŸ“ 97 linesπŸ’Ύ 3,161 bytesπŸ“ text
← Back to All Files

🎯 Use case

This file lives under β€œutils/”, which covers cross-cutting helpers (shell, tempfiles, settings, messages, process input, …). On the API surface it exposes TeammateContext, getTeammateContext, runWithTeammateContext, isInProcessTeammate, and createTeammateContext β€” mainly functions, hooks, or classes. Dependencies touch async_hooks. What the file header says: TeammateContext - Runtime context for in-process teammates This module provides AsyncLocalStorage-based context for in-process teammates, enabling concurrent teammate execution without global state conflicts. Relationship with other teammate identity mechanisms: - Env vars (CLAUD.

Generated from folder role, exports, dependency roots, and inline comments β€” not hand-reviewed for every path.

🧠 Inline summary

TeammateContext - Runtime context for in-process teammates This module provides AsyncLocalStorage-based context for in-process teammates, enabling concurrent teammate execution without global state conflicts. Relationship with other teammate identity mechanisms: - Env vars (CLAUDE_CODE_AGENT_ID): Process-based teammates spawned via tmux - dynamicTeamContext (teammate.ts): Process-based teammates joining at runtime - TeammateContext (this file): In-process teammates via AsyncLocalStorage The helper functions in teammate.ts check AsyncLocalStorage first, then dynamicTeamContext, then env vars.

πŸ“€ Exports (heuristic)

  • TeammateContext
  • getTeammateContext
  • runWithTeammateContext
  • isInProcessTeammate
  • createTeammateContext

πŸ“š External import roots

Package roots from from "…" (relative paths omitted).

  • async_hooks

πŸ–₯️ Source preview

/**
 * TeammateContext - Runtime context for in-process teammates
 *
 * This module provides AsyncLocalStorage-based context for in-process teammates,
 * enabling concurrent teammate execution without global state conflicts.
 *
 * Relationship with other teammate identity mechanisms:
 * - Env vars (CLAUDE_CODE_AGENT_ID): Process-based teammates spawned via tmux
 * - dynamicTeamContext (teammate.ts): Process-based teammates joining at runtime
 * - TeammateContext (this file): In-process teammates via AsyncLocalStorage
 *
 * The helper functions in teammate.ts check AsyncLocalStorage first, then
 * dynamicTeamContext, then env vars.
 */

import { AsyncLocalStorage } from 'async_hooks'

/**
 * Runtime context for in-process teammates.
 * Stored in AsyncLocalStorage for concurrent access.
 */
export type TeammateContext = {
  /** Full agent ID, e.g., "researcher@my-team" */
  agentId: string
  /** Display name, e.g., "researcher" */
  agentName: string
  /** Team name this teammate belongs to */
  teamName: string
  /** UI color assigned to this teammate */
  color?: string
  /** Whether teammate must enter plan mode before implementing */
  planModeRequired: boolean
  /** Leader's session ID (for transcript correlation) */
  parentSessionId: string
  /** Discriminator - always true for in-process teammates */
  isInProcess: true
  /** Abort controller for lifecycle management (linked to parent) */
  abortController: AbortController
}

const teammateContextStorage = new AsyncLocalStorage<TeammateContext>()

/**
 * Get the current in-process teammate context, if running as one.
 * Returns undefined if not running within an in-process teammate context.
 */
export function getTeammateContext(): TeammateContext | undefined {
  return teammateContextStorage.getStore()
}

/**
 * Run a function with teammate context set.
 * Used when spawning an in-process teammate to establish its execution context.
 *
 * @param context - The teammate context to set
 * @param fn - The function to run with the context
 * @returns The return value of fn
 */
export function runWithTeammateContext<T>(
  context: TeammateContext,
  fn: () => T,
): T {
  return teammateContextStorage.run(context, fn)
}

/**
 * Check if current execution is within an in-process teammate.
 * This is faster than getTeammateContext() !== undefined for simple checks.
 */
export function isInProcessTeammate(): boolean {
  return teammateContextStorage.getStore() !== undefined
}

/**
 * Create a TeammateContext from spawn configuration.
 * The abortController is passed in by the caller. For in-process teammates,
 * this is typically an independent controller (not linked to parent) so teammates
 * continue running when the leader's query is interrupted.
 *
 * @param config - Configuration for the teammate context
 * @returns A complete TeammateContext with isInProcess: true
 */
export function createTeammateContext(config: {
  agentId: string
  agentName: string
  teamName: string
  color?: string
  planModeRequired: boolean
  parentSessionId: string
  abortController: AbortController
}): TeammateContext {
  return {
    ...config,
    isInProcess: true,
  }
}