/ utils / swarm / backends / teammateModeSnapshot.ts
teammateModeSnapshot.ts
 1  /**
 2   * Teammate mode snapshot module.
 3   *
 4   * Captures the teammate mode at session startup, following the same pattern
 5   * as hooksConfigSnapshot.ts. This ensures that runtime config changes don't
 6   * affect the teammate mode for the current session.
 7   */
 8  
 9  import { getGlobalConfig } from '../../../utils/config.js'
10  import { logForDebugging } from '../../../utils/debug.js'
11  import { logError } from '../../../utils/log.js'
12  
13  export type TeammateMode = 'auto' | 'tmux' | 'in-process'
14  
15  // Module-level variable to hold the captured mode at startup
16  let initialTeammateMode: TeammateMode | null = null
17  
18  // CLI override (set before capture if --teammate-mode is provided)
19  let cliTeammateModeOverride: TeammateMode | null = null
20  
21  /**
22   * Set the CLI override for teammate mode.
23   * Must be called before captureTeammateModeSnapshot().
24   */
25  export function setCliTeammateModeOverride(mode: TeammateMode): void {
26    cliTeammateModeOverride = mode
27  }
28  
29  /**
30   * Get the current CLI override, if any.
31   * Returns null if no CLI override was set.
32   */
33  export function getCliTeammateModeOverride(): TeammateMode | null {
34    return cliTeammateModeOverride
35  }
36  
37  /**
38   * Clear the CLI override and update the snapshot to the new mode.
39   * Called when user changes the setting in the UI, allowing their change to take effect.
40   *
41   * @param newMode - The new mode the user selected (passed directly to avoid race condition)
42   */
43  export function clearCliTeammateModeOverride(newMode: TeammateMode): void {
44    cliTeammateModeOverride = null
45    initialTeammateMode = newMode
46    logForDebugging(
47      `[TeammateModeSnapshot] CLI override cleared, new mode: ${newMode}`,
48    )
49  }
50  
51  /**
52   * Capture the teammate mode at session startup.
53   * Called early in main.tsx, after CLI args are parsed.
54   * CLI override takes precedence over config.
55   */
56  export function captureTeammateModeSnapshot(): void {
57    if (cliTeammateModeOverride) {
58      initialTeammateMode = cliTeammateModeOverride
59      logForDebugging(
60        `[TeammateModeSnapshot] Captured from CLI override: ${initialTeammateMode}`,
61      )
62    } else {
63      const config = getGlobalConfig()
64      initialTeammateMode = config.teammateMode ?? 'auto'
65      logForDebugging(
66        `[TeammateModeSnapshot] Captured from config: ${initialTeammateMode}`,
67      )
68    }
69  }
70  
71  /**
72   * Get the teammate mode for this session.
73   * Returns the snapshot captured at startup, ignoring any runtime config changes.
74   */
75  export function getTeammateModeFromSnapshot(): TeammateMode {
76    if (initialTeammateMode === null) {
77      // This indicates an initialization bug - capture should happen in setup()
78      logError(
79        new Error(
80          'getTeammateModeFromSnapshot called before capture - this indicates an initialization bug',
81        ),
82      )
83      captureTeammateModeSnapshot()
84    }
85    // Fallback to 'auto' if somehow still null (shouldn't happen, but safe)
86    return initialTeammateMode ?? 'auto'
87  }