Fix: Agent Launchers Ignore Settings On Welcome Screen

by Alex Johnson 55 views

Have you ever configured custom settings for your agents, only to find them ignored when launching from the welcome screen? This article dives into a bug where agent launchers on the welcome screen bypass your carefully configured settings. We'll explore the issue, its root cause, and the fix implemented to ensure your agents launch with the settings you expect. Plus, we'll touch on how this enhances your overall experience by making the application more consistent and reliable.

Summary

Agent launchers on the welcome screen, also known as the empty state, were found to bypass configured settings. Instead of respecting user-configured models, flags, and system prompts, they spawned terminals with default arguments. This meant that any custom configurations you set for your agents were not being applied when launching from the welcome screen. This inconsistency could be confusing and frustrating, especially for users who rely on specific settings for their workflows.

Current Behavior

When launching agents like Claude, Gemini, or Codex from the welcome screen launcher cards, several issues were observed:

  • Custom agent settings were completely ignored. Any specific configurations you had set for these agents were not being applied.
  • Configured models were not applied. If you had chosen a specific model for an agent (e.g., opus or haiku for Claude), the agent would launch with the default model instead.
  • Custom command-line flags were not passed. Any flags you had added to customize the agent's behavior were not being used.
  • System prompts from settings were bypassed. Custom system prompts designed to guide the agent's responses were being ignored.
  • Agents launched with bare-minimum default configuration. This meant that the agents were running with the most basic settings, disregarding any user-defined preferences.

The affected component was identified as EmptyState in TerminalGrid.tsx. This component is responsible for rendering the welcome screen and handling agent launches from that screen.

Root Cause

The root cause of this issue was traced to the handleLaunchAgent function within TerminalGrid.tsx. Specifically, lines 219-230 of the code directly call addTerminal with basic options. This call bypasses the settings-aware logic that is used when launching agents from other parts of the application, such as the toolbar. The useAgentLauncher hook, which contains the logic for applying custom settings, was not being utilized in this particular launch path. This meant that the welcome screen launchers were essentially taking a shortcut, resulting in the agents being launched with default configurations.

Expected Behavior

The expected behavior for agent launchers on the welcome screen is that they should respect all configured settings. This means:

  • Applying all configured settings (models, flags, system prompts). When you launch an agent from the welcome screen, it should use the specific settings you have defined.
  • Behaving identically to agents launched from toolbar buttons. The launch behavior should be consistent regardless of where you initiate the launch from.
  • Respecting user preferences stored in agent settings. Your preferences, such as the choice of model or custom flags, should be honored.
  • Using the same launch code path regardless of UI entry point. Whether you launch from the welcome screen or the toolbar, the same underlying logic should be used to ensure consistency.

In essence, the agents should launch with the same configuration whether you click a launcher card on the welcome screen or use a toolbar button. This ensures a seamless and predictable user experience.

Steps to Reproduce

To reproduce this issue, you can follow these steps:

  1. Open the application's settings and configure custom agent settings. This includes:
    • Setting a custom model for Claude (e.g., opus, haiku).
    • Adding custom flags or system prompts to further customize the agent's behavior.
    • Saving the settings to ensure they are applied.
  2. Close all terminals in the application. This will bring you to the welcome screen, where the agent launcher cards are displayed.
  3. Click a launcher card, such as the "Claude Code" card, to initiate an agent launch.
  4. Observe the spawned terminal. You will notice that it uses the default configuration instead of the custom settings you configured earlier.

This issue is consistently reproducible, occurring 100% of the time when launching agents from the welcome screen with custom settings defined.

Environment

This issue was observed in the following environment:

  • OS: macOS 14.2+ / Windows / Linux. The issue is not specific to a particular operating system.
  • Version: Current main branch (commit a9eda1e). This indicates the specific version of the codebase where the issue was identified.
  • Affected Agents: Claude, Gemini, Codex. These are the specific agents that were affected by the bug.
  • Component: TerminalGrid empty state. This pinpoints the specific part of the application where the issue occurs.

Evidence

To further illustrate the issue, let's examine the relevant code snippets.

Current Implementation

The following code from src/components/Terminal/TerminalGrid.tsx (lines 219-230) shows the broken handler:

const handleLaunchAgent = useCallback(
  async (type: "claude" | "gemini" | "codex" | "shell") => {
    try {
      const cwd = defaultCwd || "";
      const command = type !== "shell" ? type : undefined;
      await addTerminal({ type, cwd, command });
    } catch (error) {
      console.error(`Failed to launch ${type}:`, error);
    }
  },
  [addTerminal, defaultCwd]
);

This code directly calls addTerminal with minimal options, bypassing the settings-aware logic.

Settings-Aware Logic (NOT used by welcome screen)

In contrast, the following code from src/hooks/useAgentLauncher.ts (lines 140-191) demonstrates the settings-aware logic that should be used:

const launchAgent = useCallback(
  async (type: AgentType): Promise<string | null> => {
    // ... configuration logic ...
    let command = config.command;
    if (command && agentSettings) {
      let flags: string[] = [];

      switch (type) {
        case "claude":
          flags = generateClaudeFlags(agentSettings.claude);
          break;
        case "gemini":
          flags = generateGeminiFlags(agentSettings.gemini);
          break;
        case "codex":
          flags = generateCodexFlags(agentSettings.codex);
          break;
      }

      if (flags.length > 0) {
        command = `${config.command} ${flags.join(" ")}`;
      }
    }
    // ... rest of implementation
  },
  [activeId, worktreeMap, addTerminal, currentProject, agentSettings]
);

This code snippet shows how the useAgentLauncher hook incorporates user-defined settings, such as flags and system prompts, when launching agents. However, this logic was not being used by the welcome screen launchers.

Affected Files

The following files were identified as being affected by this issue:

Deliverables

The fix for this issue involved several code changes and testing procedures to ensure the correct behavior and prevent regressions.

Code Changes

The primary code changes were made in the TerminalGrid and App components.

1. Update TerminalGrid Component

File: src/components/Terminal/TerminalGrid.tsx

Changes:

  • Added an onLaunchAgent optional prop to the TerminalGridProps interface (line 25). This prop allows the parent component to pass down a custom agent launch handler.
  • Updated the handleLaunchAgent function to delegate to the onLaunchAgent prop if provided (lines 219-230). This ensures that the custom handler is used when available.
  • Kept the fallback logic for standalone usage. If the onLaunchAgent prop is not provided, the component falls back to the basic launch behavior.

2. Update App Component

File: src/App.tsx

Changes:

  • Passed the handleLaunchAgent prop to the TerminalGrid component (line 571). This connects the settings-aware launcher from useAgentLauncher to the welcome screen.

Tests

To ensure the fix was effective and did not introduce any regressions, the following tests were performed:

  • Manual verification: Custom settings were configured, terminals were closed, and agents were launched from the welcome screen. The launched agents were then verified to use the configured settings.
  • Integration test: Agents were launched from both the toolbar and the welcome screen, and the resulting terminal configurations were asserted to be identical. This ensures consistency across different launch points.
  • Settings edge case: The fallback behavior was verified when settings were invalid or missing. This ensures that the application handles edge cases gracefully.

Documentation

No documentation changes were needed for this fix. It was an internal bug fix that did not affect the application's API or external interfaces.

Technical Specifications

Footprint

  • UI Components: TerminalGrid, App
  • Hook dependency: useAgentLauncher
  • No IPC or service layer changes

Architecture

  • Followed the React props pattern for passing handlers down the component tree. This is a standard React pattern that ensures data and behavior are passed down in a predictable way.
  • Maintained a single source of truth for agent launching logic (useAgentLauncher). This ensures that the launch logic is consistent across the application.
  • Preserved fallback behavior for component reusability. This allows the TerminalGrid component to be used in other contexts without requiring the onLaunchAgent prop.

Dependencies

None - This was a standalone bug fix that did not introduce any new dependencies.

Tasks

The following tasks were completed as part of the fix:

Acceptance Criteria

The following acceptance criteria were used to ensure the fix was successful:

  • [x] Agents launched from the welcome screen respect all configured settings (models, flags, prompts)
  • [x] Settings-configured Claude/Gemini/Codex spawn with correct command-line arguments
  • [x] Toolbar and welcome screen launchers produce identical terminal configurations
  • [x] No regression in existing toolbar agent launch functionality
  • [x] Fallback behavior still works if onLaunchAgent prop is not provided

Edge Cases & Risks

Edge Cases

The following edge cases were considered during the fix:

  • Settings partially configured (some agents have custom config, others do not). The fix handles this by applying the custom settings where available and falling back to defaults for others.
  • Settings invalid or corrupted (should fallback gracefully). The application gracefully falls back to default settings if the configured settings are invalid or corrupted.
  • TerminalGrid used without onLaunchAgent prop (preserve fallback). The fallback logic ensures that the component can still be used in other contexts without requiring the prop.

Risks

  • Low risk: The fix involves a simple prop passing pattern and is a well-isolated change.
  • Potential confusion if TerminalGrid is reused elsewhere without prop (mitigated by fallback logic).

Regression Risk

  • Minimal - The change only affects the empty state launch path.
  • Toolbar launches unchanged (already using the correct logic).

Conclusion

By addressing this bug, we've ensured that agent launchers on the welcome screen now respect your configured settings, providing a consistent and reliable experience across the application. This fix enhances usability by ensuring your custom settings are applied regardless of how you launch your agents. Remember to always test your configurations and report any unexpected behavior to help improve the application further.

For more information on related topics, you can check out this React documentation on component props and data flow.