All files / src/components/panels CredentialProvidersPanel.tsx

90.9% Statements 10/11
50% Branches 1/2
100% Functions 5/5
90.9% Lines 10/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                          3x                                                                                                                           6x 1x 1x     1x   1x     6x                   30x           1x     66x                      
import type { JSX } from "react";
import type { CredentialProviderConfig } from "../../hooks/types.js";
import styles from "./SettingsPanel.module.scss";
 
/** Provider descriptor for rendering toggle rows. */
interface ProviderDef {
  key: keyof CredentialProviderConfig;
  label: string;
  description: string;
  options: Array<{ value: string; label: string }>;
}
 
/** Definitions for each credential provider. */
const PROVIDERS: ProviderDef[] = [
  {
    key: "claude",
    label: "Claude",
    description: "Forward Claude credentials for AI agent access.",
    options: [
      { value: "off", label: "Off" },
      { value: "subscription", label: "Subscription" },
      { value: "api_key", label: "API Key" },
    ],
  },
  {
    key: "github",
    label: "GitHub",
    description: "Forward GITHUB_TOKEN and GH_TOKEN for git operations.",
    options: [
      { value: "off", label: "Off" },
      { value: "on", label: "On" },
    ],
  },
  {
    key: "copilot",
    label: "Copilot",
    description: "Forward Copilot tokens (COPILOT_GITHUB_TOKEN, CLI config).",
    options: [
      { value: "off", label: "Off" },
      { value: "on", label: "On" },
    ],
  },
  {
    key: "codex",
    label: "Codex",
    description: "Forward OPENAI_API_KEY for Codex/OpenAI access.",
    options: [
      { value: "off", label: "Off" },
      { value: "on", label: "On" },
    ],
  },
  {
    key: "goose",
    label: "Goose",
    description: "Forward Goose config and API keys for Goose agent access.",
    options: [
      { value: "off", label: "Off" },
      { value: "on", label: "On" },
    ],
  },
];
 
/** Props for the CredentialProvidersPanel component. */
interface CredentialProvidersPanelProps {
  /** Current credential provider configuration. */
  credentialProviders: CredentialProviderConfig;
  /** Callback to update the credential provider configuration. */
  onUpdateCredentialProviders: (config: CredentialProviderConfig) => void;
}
 
/** Panel for configuring which credential providers are auto-forwarded to environments. */
export function CredentialProvidersPanel({
  credentialProviders,
  onUpdateCredentialProviders,
}: CredentialProvidersPanelProps): JSX.Element {
  const handleChange = (key: keyof CredentialProviderConfig, value: string): void => {
    const updated: CredentialProviderConfig = { ...credentialProviders };
    Iif (key === "claude") {
      updated.claude = value as CredentialProviderConfig["claude"];
    } else {
      updated[key] = value as "off" | "on";
    }
    onUpdateCredentialProviders(updated);
  };
 
  return (
    <section className={styles.section}>
      <h3 className={styles.sectionTitle}>Credential Providers</h3>
      <p className={styles.sectionDescription}>
        Enable providers to automatically forward credentials to environments at task start.
        Credentials are read fresh from the host each time.
      </p>
 
      <div className={styles.tokenList}>
        {PROVIDERS.map((provider) => (
          <div key={provider.key} className={styles.tokenRow}>
            <span className={styles.tokenName}>{provider.label}</span>
            <span className={styles.tokenTarget}>{provider.description}</span>
            <select
              className={styles.select}
              value={credentialProviders[provider.key]}
              onChange={(e) => handleChange(provider.key, e.target.value)}
            >
              {provider.options.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </div>
        ))}
      </div>
    </section>
  );
}