{"version":3,"sources":["../src/sources/registry.ts","../src/encryption/age.ts","../src/config/paths.ts","../src/utils/prompts.ts","../src/config/types.ts","../src/config/loader.ts","../src/core/validation.ts","../src/sources/local/index.ts","../src/core/service.ts","../src/wizard/validation.ts","../src/wizard/ui.ts","../src/cli.ts","../src/utils/banner.ts","../src/commands/init.ts","../src/utils/output.ts","../src/commands/add.ts","../src/commands/list.ts","../src/commands/get.ts","../src/commands/grant.ts","../src/commands/revoke.ts","../src/commands/config.ts","../src/commands/remove.ts","../src/commands/rotate.ts","../src/commands/export.ts","../src/commands/import.ts","../src/commands/status.ts","../src/commands/audit.ts","../src/commands/wizard.ts","../src/wizard/terminal.ts","../src/commands/deploy.ts","../src/commands/backup-codes.ts"],"sourcesContent":["/**\n * Credential Source Registry\n *\n * Manages multiple credential sources with priority-based resolution.\n * Enables plugin architecture for future sources (1Password, Bitwarden, etc.)\n */\n\nimport type { ICredentialSource } from './types';\nimport type { Credential, CredentialMetadata } from '../core/types';\n\n/**\n * Registry for credential sources\n *\n * Sources are resolved in priority order (lowest number = highest priority).\n * This allows fallback behavior when a credential isn't found in the\n * primary source.\n */\nexport class CredentialSourceRegistry {\n  private sources: Map<string, ICredentialSource> = new Map();\n\n  /**\n   * Register a credential source\n   *\n   * @param source - Credential source to register\n   */\n  register(source: ICredentialSource): void {\n    this.sources.set(source.id, source);\n  }\n\n  /**\n   * Unregister a credential source\n   *\n   * @param sourceId - ID of source to remove\n   */\n  unregister(sourceId: string): void {\n    this.sources.delete(sourceId);\n  }\n\n  /**\n   * Get a specific source by ID\n   *\n   * @param sourceId - Source ID\n   * @returns Source if found, undefined otherwise\n   */\n  getSource(sourceId: string): ICredentialSource | undefined {\n    return this.sources.get(sourceId);\n  }\n\n  /**\n   * Get all registered sources\n   */\n  getAllSources(): ICredentialSource[] {\n    return Array.from(this.sources.values());\n  }\n\n  /**\n   * Get available sources in priority order\n   *\n   * @returns Sources that are available and configured\n   */\n  async getAvailableSources(): Promise<ICredentialSource[]> {\n    const available: ICredentialSource[] = [];\n\n    for (const source of this.sources.values()) {\n      if (await source.isAvailable()) {\n        available.push(source);\n      }\n    }\n\n    // Sort by priority (lower number = higher priority)\n    return available.sort((a, b) => a.priority - b.priority);\n  }\n\n  /**\n   * Get a credential from the first available source that has it\n   *\n   * @param name - Credential name\n   * @returns Credential if found, null otherwise\n   */\n  async get(name: string): Promise<Credential | null> {\n    for (const source of await this.getAvailableSources()) {\n      const credential = await source.get(name);\n      if (credential) {\n        return credential;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * List all credentials from all available sources\n   *\n   * @returns Combined list of credential metadata (deduplicated by name)\n   */\n  async list(): Promise<CredentialMetadata[]> {\n    const seen = new Set<string>();\n    const result: CredentialMetadata[] = [];\n\n    for (const source of await this.getAvailableSources()) {\n      const credentials = await source.list();\n      for (const cred of credentials) {\n        if (!seen.has(cred.name)) {\n          seen.add(cred.name);\n          result.push(cred);\n        }\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Set a credential in the specified source (or first writable source)\n   *\n   * @param name - Credential name\n   * @param value - Credential value\n   * @param metadata - Optional metadata to store with credential\n   * @param sourceId - Optional specific source to use\n   */\n  async set(\n    name: string,\n    value: string,\n    metadata?: Partial<CredentialMetadata>,\n    sourceId?: string\n  ): Promise<void> {\n    if (sourceId) {\n      const source = this.sources.get(sourceId);\n      if (!source) {\n        throw new Error(`Source '${sourceId}' not found`);\n      }\n      if (!source.set) {\n        throw new Error(`Source '${sourceId}' is read-only`);\n      }\n      await source.set(name, value, metadata);\n      return;\n    }\n\n    // Use first available writable source\n    for (const source of await this.getAvailableSources()) {\n      if (source.set) {\n        await source.set(name, value, metadata);\n        return;\n      }\n    }\n\n    throw new Error('No writable credential source available');\n  }\n\n  /**\n   * Delete a credential from the specified source (or all sources)\n   *\n   * @param name - Credential name\n   * @param sourceId - Optional specific source\n   * @returns true if deleted from any source\n   */\n  async delete(name: string, sourceId?: string): Promise<boolean> {\n    if (sourceId) {\n      const source = this.sources.get(sourceId);\n      if (!source) {\n        throw new Error(`Source '${sourceId}' not found`);\n      }\n      if (!source.delete) {\n        throw new Error(`Source '${sourceId}' doesn't support deletion`);\n      }\n      return source.delete(name);\n    }\n\n    // Delete from all sources\n    let deleted = false;\n    for (const source of await this.getAvailableSources()) {\n      if (source.delete) {\n        const result = await source.delete(name);\n        deleted = deleted || result;\n      }\n    }\n    return deleted;\n  }\n}\n","/**\n * Age Encryption Provider\n *\n * Implementation of IEncryptionProvider using the age-encryption npm package.\n * Age is a modern, simple encryption tool: https://age-encryption.org\n *\n * Based on typage: https://github.com/FiloSottile/typage\n */\n\nimport * as age from 'age-encryption';\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport type { IEncryptionProvider, KeyPair } from './types';\n\n/**\n * Age encryption provider\n *\n * Uses age-encryption npm package for X25519 + ChaCha20-Poly1305.\n * Keys are age-native format (age1... for public, AGE-SECRET-KEY-... for private).\n */\nexport class AgeProvider implements IEncryptionProvider {\n  readonly id = 'age';\n  readonly name = 'age encryption';\n\n  /**\n   * Check if age encryption is available\n   * (always true since we use the npm package, not CLI)\n   */\n  async isAvailable(): Promise<boolean> {\n    return true;\n  }\n\n  /**\n   * Generate a new age key pair\n   *\n   * @returns KeyPair with age-format public and private keys\n   */\n  async generateKeyPair(): Promise<KeyPair> {\n    const identity = await age.generateIdentity();\n    const recipient = await age.identityToRecipient(identity);\n\n    return {\n      publicKey: recipient,   // age1...\n      privateKey: identity,   // AGE-SECRET-KEY-...\n    };\n  }\n\n  /**\n   * Encrypt plaintext with recipient's public key\n   *\n   * @param plaintext - Text to encrypt\n   * @param recipient - Public key (age1...)\n   * @returns Base64-encoded ciphertext\n   */\n  async encrypt(plaintext: string, recipient: string): Promise<string> {\n    const encrypter = new age.Encrypter();\n    encrypter.addRecipient(recipient);\n\n    const plaintextBytes = new TextEncoder().encode(plaintext);\n    const ciphertext = await encrypter.encrypt(plaintextBytes);\n\n    // Convert Uint8Array to base64 for storage\n    return this.uint8ArrayToBase64(ciphertext);\n  }\n\n  /**\n   * Decrypt ciphertext with private key\n   *\n   * @param ciphertext - Base64-encoded ciphertext\n   * @param privateKey - Private key (AGE-SECRET-KEY-...)\n   * @returns Decrypted plaintext\n   */\n  async decrypt(ciphertext: string, privateKey: string): Promise<string> {\n    const decrypter = new age.Decrypter();\n    decrypter.addIdentity(privateKey);\n\n    // Convert base64 back to Uint8Array\n    const ciphertextBytes = this.base64ToUint8Array(ciphertext);\n    const plaintext = await decrypter.decrypt(ciphertextBytes, 'text');\n\n    return plaintext as string;\n  }\n\n  /**\n   * Load private key from identity file\n   *\n   * @param identityPath - Path to identity file\n   * @returns Private key string\n   */\n  async loadIdentity(identityPath: string): Promise<string> {\n    const content = await fs.readFile(identityPath, 'utf8');\n\n    // Identity file may have comments, extract the key line\n    const lines = content.split('\\n');\n    for (const line of lines) {\n      const trimmed = line.trim();\n      if (trimmed.startsWith('AGE-SECRET-KEY-')) {\n        return trimmed;\n      }\n    }\n\n    throw new Error(`No valid age identity found in ${identityPath}`);\n  }\n\n  /**\n   * Save private key to identity file\n   *\n   * @param privateKey - Private key to save\n   * @param identityPath - Path to identity file\n   */\n  async saveIdentity(privateKey: string, identityPath: string): Promise<void> {\n    // Ensure directory exists\n    await fs.ensureDir(path.dirname(identityPath));\n\n    // Create identity file with comment header\n    const content = `# created: ${new Date().toISOString()}\n# SecretSage identity file\n# public key: (run 'secretsage config --show' to see)\n${privateKey}\n`;\n\n    // Write with restrictive permissions (owner read/write only)\n    await fs.writeFile(identityPath, content, { mode: 0o600 });\n  }\n\n  /**\n   * Save public key to recipient file\n   *\n   * @param publicKey - Public key to save\n   * @param recipientPath - Path to recipient file\n   */\n  async saveRecipient(publicKey: string, recipientPath: string): Promise<void> {\n    await fs.ensureDir(path.dirname(recipientPath));\n\n    const content = `# SecretSage recipient (public key)\n# Share this key to allow others to encrypt credentials for you\n${publicKey}\n`;\n\n    await fs.writeFile(recipientPath, content, { mode: 0o644 });\n  }\n\n  /**\n   * Load public key from recipient file\n   *\n   * @param recipientPath - Path to recipient file\n   * @returns Public key string\n   */\n  async loadRecipient(recipientPath: string): Promise<string> {\n    const content = await fs.readFile(recipientPath, 'utf8');\n\n    const lines = content.split('\\n');\n    for (const line of lines) {\n      const trimmed = line.trim();\n      if (trimmed.startsWith('age1')) {\n        return trimmed;\n      }\n    }\n\n    throw new Error(`No valid age recipient found in ${recipientPath}`);\n  }\n\n  /**\n   * Convert Uint8Array to base64 string\n   */\n  private uint8ArrayToBase64(bytes: Uint8Array): string {\n    // Use Buffer in Node.js for efficiency\n    return Buffer.from(bytes).toString('base64');\n  }\n\n  /**\n   * Convert base64 string to Uint8Array\n   */\n  private base64ToUint8Array(base64: string): Uint8Array {\n    return new Uint8Array(Buffer.from(base64, 'base64'));\n  }\n}\n\n/**\n * Encrypt the identity (private key) with a passphrase using scrypt\n *\n * @param privateKey - The age identity to protect\n * @param passphrase - User passphrase\n * @returns Base64-encoded encrypted identity\n */\nexport async function encryptIdentityWithPassphrase(\n  privateKey: string,\n  passphrase: string\n): Promise<string> {\n  const encrypter = new age.Encrypter();\n  encrypter.setPassphrase(passphrase);\n  // Use work factor 18 (default) for good security\n  encrypter.setScryptWorkFactor(18);\n\n  const plaintextBytes = new TextEncoder().encode(privateKey);\n  const ciphertext = await encrypter.encrypt(plaintextBytes);\n\n  return Buffer.from(ciphertext).toString('base64');\n}\n\n/**\n * Decrypt the identity (private key) with a passphrase\n *\n * @param encryptedIdentity - Base64-encoded encrypted identity\n * @param passphrase - User passphrase\n * @returns Decrypted age identity\n */\nexport async function decryptIdentityWithPassphrase(\n  encryptedIdentity: string,\n  passphrase: string\n): Promise<string> {\n  const decrypter = new age.Decrypter();\n  decrypter.addPassphrase(passphrase);\n\n  const ciphertextBytes = new Uint8Array(Buffer.from(encryptedIdentity, 'base64'));\n  const plaintext = await decrypter.decrypt(ciphertextBytes, 'text');\n\n  return plaintext as string;\n}\n\n/**\n * Check if an identity file contains a passphrase-protected identity\n *\n * @param content - Content of identity file\n * @returns true if passphrase-protected\n */\nexport function isPassphraseProtectedIdentity(content: string): boolean {\n  // Passphrase-protected identities are stored as base64 of age ciphertext\n  // They will NOT start with AGE-SECRET-KEY-\n  const trimmed = content.trim();\n  // If it doesn't have a raw AGE-SECRET-KEY line, it's probably encrypted\n  const hasRawKey = trimmed.split('\\n').some(line =>\n    line.trim().startsWith('AGE-SECRET-KEY-')\n  );\n  return !hasRawKey && trimmed.length > 0;\n}\n\n/**\n * Default singleton instance\n */\nexport const ageProvider = new AgeProvider();\n","/**\n * Platform-specific path utilities for SecretSage\n *\n * Handles cross-platform paths for:\n * - Global config: ~/.secretsage/\n * - Local config: .secretsage/\n * - Vault files\n * - Identity files\n */\n\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs-extra';\n\n/**\n * Get the user's home directory\n */\nexport function getHomeDir(): string {\n  return os.homedir();\n}\n\n/**\n * Get the global SecretSage directory\n * ~/.secretsage on Unix, %USERPROFILE%\\.secretsage on Windows\n */\nexport function getGlobalDir(): string {\n  return path.join(getHomeDir(), '.secretsage');\n}\n\n/**\n * Get the local SecretSage directory (in current project)\n */\nexport function getLocalDir(): string {\n  return path.join(process.cwd(), '.secretsage');\n}\n\n/**\n * Get a custom vault directory (user-specified path)\n */\nexport function getCustomDir(customPath: string): string {\n  return expandPath(customPath);\n}\n\n/**\n * Check if a local vault exists in the current directory\n */\nexport async function hasLocalVault(): Promise<boolean> {\n  return fs.pathExists(path.join(getLocalDir(), 'identity.txt'));\n}\n\n/**\n * Check if a global vault exists\n */\nexport async function hasGlobalVault(): Promise<boolean> {\n  return fs.pathExists(path.join(getGlobalDir(), 'identity.txt'));\n}\n\n/**\n * Check if a vault exists at a custom path\n */\nexport async function hasCustomVault(customPath: string): Promise<boolean> {\n  return fs.pathExists(path.join(getCustomDir(customPath), 'identity.txt'));\n}\n\n/**\n * Get the active vault directory (local if exists, otherwise global)\n */\nexport async function getActiveDir(): Promise<string> {\n  if (await hasLocalVault()) {\n    return getLocalDir();\n  }\n  return getGlobalDir();\n}\n\n/**\n * Get the vault file path\n */\nexport function getVaultPath(local?: boolean): string {\n  const dir = local ? getLocalDir() : getGlobalDir();\n  return path.join(dir, 'vault.json');\n}\n\n/**\n * Get the identity (private key) file path\n */\nexport function getIdentityPath(local?: boolean): string {\n  const dir = local ? getLocalDir() : getGlobalDir();\n  return path.join(dir, 'identity.txt');\n}\n\n/**\n * Get the recipient (public key) file path\n */\nexport function getRecipientPath(local?: boolean): string {\n  const dir = local ? getLocalDir() : getGlobalDir();\n  return path.join(dir, 'recipient.txt');\n}\n\n/**\n * Get the config file path\n */\nexport function getConfigPath(local?: boolean): string {\n  const dir = local ? getLocalDir() : getGlobalDir();\n  return path.join(dir, 'config.yaml');\n}\n\n/**\n * Get the .env file path in the current directory\n */\nexport function getEnvPath(): string {\n  return path.join(process.cwd(), '.env');\n}\n\n/**\n * Get the .env backup file path\n */\nexport function getEnvBackupPath(): string {\n  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n  return path.join(process.cwd(), `.env.backup.${timestamp}`);\n}\n\n/**\n * Get the .gitignore path in the current directory\n */\nexport function getGitignorePath(): string {\n  return path.join(process.cwd(), '.gitignore');\n}\n\n/**\n * Resolve a path with ~ expansion\n */\nexport function expandPath(p: string): string {\n  if (p.startsWith('~')) {\n    return path.join(getHomeDir(), p.slice(1));\n  }\n  return path.resolve(p);\n}\n","import inquirer from 'inquirer';\nimport chalk from 'chalk';\n\n/**\n * Inquirer prompt wrappers for consistent UX\n */\n\n/**\n * Prompt for a credential value with masked input\n */\nexport async function promptCredentialValue(name: string): Promise<string> {\n  const { value } = await inquirer.prompt([\n    {\n      type: 'password',\n      name: 'value',\n      message: `Enter value for ${chalk.cyan(name)}:`,\n      mask: '*',\n      validate: (input: string) => {\n        if (!input || input.trim().length === 0) {\n          return 'Value cannot be empty';\n        }\n        return true;\n      },\n    },\n  ]);\n  return value;\n}\n\n/**\n * Prompt for confirmation\n */\nexport async function confirm(message: string, defaultValue = false): Promise<boolean> {\n  const { confirmed } = await inquirer.prompt([\n    {\n      type: 'confirm',\n      name: 'confirmed',\n      message,\n      default: defaultValue,\n    },\n  ]);\n  return confirmed;\n}\n\n/**\n * Prompt for credential selection with checkboxes\n */\nexport async function selectCredentials(\n  credentials: string[],\n  message = 'Select credentials to grant:'\n): Promise<string[]> {\n  if (credentials.length === 0) {\n    return [];\n  }\n\n  const { selected } = await inquirer.prompt([\n    {\n      type: 'checkbox',\n      name: 'selected',\n      message,\n      choices: credentials.map((name) => ({\n        name,\n        value: name,\n        checked: false,\n      })),\n      validate: (answer: string[]) => {\n        if (answer.length === 0) {\n          return 'You must select at least one credential';\n        }\n        return true;\n      },\n    },\n  ]);\n  return selected;\n}\n\n/**\n * Prompt for vault location choice\n */\nexport async function promptVaultLocation(): Promise<'global' | 'local' | 'custom'> {\n  const { location } = await inquirer.prompt([\n    {\n      type: 'list',\n      name: 'location',\n      message: 'Where should the vault be created?',\n      choices: [\n        {\n          name: 'Global (~/.secretsage) - Shared across projects',\n          value: 'global',\n        },\n        {\n          name: 'Local (.secretsage) - Project-specific',\n          value: 'local',\n        },\n        {\n          name: 'Custom path - Specify a directory',\n          value: 'custom',\n        },\n      ],\n      default: 'global',\n    },\n  ]);\n  return location;\n}\n\n/**\n * Prompt for custom vault path\n */\nexport async function promptCustomPath(): Promise<string> {\n  const { customPath } = await inquirer.prompt([\n    {\n      type: 'input',\n      name: 'customPath',\n      message: 'Enter vault directory path:',\n      validate: (input: string) => {\n        if (!input || input.trim().length === 0) {\n          return 'Path cannot be empty';\n        }\n        return true;\n      },\n    },\n  ]);\n  return customPath.trim();\n}\n\n/**\n * Prompt for text input\n */\nexport async function promptText(\n  message: string,\n  defaultValue?: string\n): Promise<string> {\n  const { value } = await inquirer.prompt([\n    {\n      type: 'input',\n      name: 'value',\n      message,\n      default: defaultValue,\n    },\n  ]);\n  return value;\n}\n\n/**\n * Prompt for passphrase with confirmation\n */\nexport async function promptPassphrase(requireConfirm = true): Promise<string> {\n  const { passphrase } = await inquirer.prompt([\n    {\n      type: 'password',\n      name: 'passphrase',\n      message: 'Enter passphrase for identity file:',\n      mask: '*',\n      validate: (input: string) => {\n        if (!input || input.length < 8) {\n          return 'Passphrase must be at least 8 characters';\n        }\n        return true;\n      },\n    },\n  ]);\n\n  if (requireConfirm) {\n    const { confirm } = await inquirer.prompt([\n      {\n        type: 'password',\n        name: 'confirm',\n        message: 'Confirm passphrase:',\n        mask: '*',\n        validate: (input: string) => {\n          if (input !== passphrase) {\n            return 'Passphrases do not match';\n          }\n          return true;\n        },\n      },\n    ]);\n  }\n\n  return passphrase;\n}\n\n/**\n * Prompt for passphrase (no confirmation, for decryption)\n */\nexport async function promptPassphraseDecrypt(): Promise<string> {\n  const { passphrase } = await inquirer.prompt([\n    {\n      type: 'password',\n      name: 'passphrase',\n      message: 'Enter identity passphrase:',\n      mask: '*',\n    },\n  ]);\n  return passphrase;\n}\n","/**\n * Configuration types for SecretSage\n */\n\n/**\n * Main configuration schema\n */\nexport interface SecretSageConfig {\n  /** Config file version */\n  version: string;\n\n  /** Vault settings */\n  vault: VaultConfig;\n\n  /** Encryption settings */\n  encryption: EncryptionConfig;\n\n  /** Credential source settings */\n  sources: SourceConfig[];\n\n  /** Agent/automation settings */\n  agent: AgentConfig;\n}\n\n/**\n * Vault configuration\n */\nexport interface VaultConfig {\n  /** Default vault location: 'global', 'local', or 'custom' */\n  defaultLocation: 'global' | 'local' | 'custom';\n\n  /** Custom global vault path (default: ~/.secretsage) */\n  globalPath?: string;\n\n  /** Custom local vault path (default: .secretsage) */\n  localPath?: string;\n\n  /** Custom vault path (user-specified arbitrary directory) */\n  customPath?: string;\n}\n\n/**\n * Encryption configuration\n */\nexport interface EncryptionConfig {\n  /** Encryption provider: 'age' (default) */\n  provider: 'age';\n\n  /** Path to identity file (overrides default) */\n  identityPath?: string;\n\n  /** Path to recipient file (overrides default) */\n  recipientPath?: string;\n\n  /** Enable passphrase protection on identity file (scrypt) */\n  passphrase?: boolean;\n\n  /** Passphrase cache TTL in seconds (default: 300, 0 to disable) */\n  passphraseCacheTTL?: number;\n}\n\n/**\n * Credential source configuration\n */\nexport interface SourceConfig {\n  /** Source type: 'local', '1password', 'bitwarden', etc. */\n  type: string;\n\n  /** Whether this source is enabled */\n  enabled: boolean;\n\n  /** Priority for resolution (lower = higher priority) */\n  priority: number;\n\n  /** Source-specific options */\n  options?: Record<string, unknown>;\n}\n\n/**\n * Agent/automation configuration\n */\nexport interface AgentConfig {\n  /** Automatically add .secretsage and .env to .gitignore */\n  autoGitignore: boolean;\n\n  /** Backup .env before granting credentials */\n  backupEnvOnGrant: boolean;\n\n  /** Require confirmation for grant operations */\n  requireConfirmation: boolean;\n}\n\n/**\n * Default configuration\n */\nexport function getDefaultConfig(): SecretSageConfig {\n  return {\n    version: '1',\n    vault: {\n      defaultLocation: 'global',\n    },\n    encryption: {\n      provider: 'age',\n    },\n    sources: [\n      {\n        type: 'local',\n        enabled: true,\n        priority: 1,\n      },\n    ],\n    agent: {\n      autoGitignore: true,\n      backupEnvOnGrant: true,\n      requireConfirmation: true,\n    },\n  };\n}\n","/**\n * Configuration loader for SecretSage\n *\n * Handles loading and merging global and local configs.\n */\n\nimport * as fs from 'fs-extra';\nimport * as yaml from 'yaml';\nimport { getConfigPath, getGlobalDir, getLocalDir, hasLocalVault } from './paths';\nimport type { SecretSageConfig } from './types';\nimport { getDefaultConfig } from './types';\n\n/**\n * Load configuration from file\n *\n * Priority:\n * 1. Local config (.secretsage/config.yaml)\n * 2. Global config (~/.secretsage/config.yaml)\n * 3. Default config\n */\nexport async function loadConfig(): Promise<SecretSageConfig> {\n  const defaultConfig = getDefaultConfig();\n\n  // Try to load global config first\n  let globalConfig: Partial<SecretSageConfig> = {};\n  const globalConfigPath = getConfigPath(false);\n\n  if (await fs.pathExists(globalConfigPath)) {\n    try {\n      const content = await fs.readFile(globalConfigPath, 'utf8');\n      globalConfig = yaml.parse(content) || {};\n    } catch {\n      // Ignore parse errors, use defaults\n    }\n  }\n\n  // Try to load local config\n  let localConfig: Partial<SecretSageConfig> = {};\n  const localConfigPath = getConfigPath(true);\n\n  if (await fs.pathExists(localConfigPath)) {\n    try {\n      const content = await fs.readFile(localConfigPath, 'utf8');\n      localConfig = yaml.parse(content) || {};\n    } catch {\n      // Ignore parse errors, use defaults\n    }\n  }\n\n  // Merge configs: default < global < local\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  return deepMerge(defaultConfig as any, globalConfig as any, localConfig as any) as unknown as SecretSageConfig;\n}\n\n/**\n * Save configuration to file\n */\nexport async function saveConfig(\n  config: Partial<SecretSageConfig>,\n  local = false\n): Promise<void> {\n  const configPath = getConfigPath(local);\n  const dir = local ? getLocalDir() : getGlobalDir();\n\n  await fs.ensureDir(dir);\n\n  const content = yaml.stringify(config, {\n    indent: 2,\n    lineWidth: 80,\n  });\n\n  // Add header comment\n  const header = `# SecretSage Configuration\n# https://cyclecore.ai\n#\n# Run 'secretsage config --show' to see all options\n`;\n\n  await fs.writeFile(configPath, header + content, { mode: 0o600 });\n}\n\n/**\n * Get the active config path (local if exists, otherwise global)\n */\nexport async function getActiveConfigPath(): Promise<string> {\n  if (await hasLocalVault()) {\n    return getConfigPath(true);\n  }\n  return getConfigPath(false);\n}\n\n/**\n * Check if local config exists\n */\nexport async function hasLocalConfig(): Promise<boolean> {\n  return fs.pathExists(getConfigPath(true));\n}\n\n/**\n * Check if global config exists\n */\nexport async function hasGlobalConfig(): Promise<boolean> {\n  return fs.pathExists(getConfigPath(false));\n}\n\n/**\n * Deep merge objects\n */\nfunction deepMerge(\n  target: Record<string, unknown>,\n  ...sources: Record<string, unknown>[]\n): Record<string, unknown> {\n  const result = { ...target };\n\n  for (const source of sources) {\n    if (!source) continue;\n\n    for (const key in source) {\n      const sourceValue = source[key];\n      const targetValue = result[key];\n\n      if (\n        sourceValue !== null &&\n        typeof sourceValue === 'object' &&\n        !Array.isArray(sourceValue) &&\n        targetValue !== null &&\n        typeof targetValue === 'object' &&\n        !Array.isArray(targetValue)\n      ) {\n        // Recursively merge objects\n        result[key] = deepMerge(\n          targetValue as Record<string, unknown>,\n          sourceValue as Record<string, unknown>\n        );\n      } else if (sourceValue !== undefined) {\n        // Override with source value\n        result[key] = sourceValue;\n      }\n    }\n  }\n\n  return result;\n}\n","/**\n * Credential Validation Primitives\n *\n * v0.5.0 ships the storage-layer prompt-leak guard only. Full key-shape\n * validation (GitHub PAT family, Slack, GitLab, NPM, etc.) and the\n * --force-shape escape hatch are scoped for v0.5.1.\n *\n * The existing wizard-side regex table at src/wizard/validation.ts is\n * unchanged for v0.5.0. v0.5.1 will move it here and wire it through\n * all capture paths.\n */\n\n/**\n * Escape a string for use as a literal inside a RegExp.\n */\nfunction escapeRegExp(s: string): string {\n  return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Detect whether a value has the shape of the pre-v0.5.0 keyValue()\n * formatter output for the given key name: leading whitespace (0-4 spaces),\n * the key name, a colon, optional whitespace, then the actual value.\n *\n * Returns the stripped value alongside the leak flag so callers can choose\n * to reject (recommended; storage layer does this) or repair.\n *\n * Example match:\n *   \"  GH_PAT_TEST: ghp_AAAA...\" -> { leak: true, stripped: \"ghp_AAAA...\" }\n */\nexport function detectPromptLeak(\n  name: string,\n  value: string\n): { leak: boolean; stripped: string } {\n  const re = new RegExp(`^\\\\s{0,4}${escapeRegExp(name)}\\\\s*:\\\\s+`);\n  if (re.test(value)) {\n    return { leak: true, stripped: value.replace(re, '') };\n  }\n  return { leak: false, stripped: value };\n}\n","/**\n * Local Credential Source\n *\n * Stores credentials in a local encrypted vault file.\n * Uses age encryption for secure storage.\n */\n\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport type { ICredentialSource } from '../types';\nimport type { Credential, CredentialMetadata, VaultEntry, RotationEvent, AccessLogEntry } from '../../core/types';\nimport {\n  AgeProvider,\n  encryptIdentityWithPassphrase,\n  decryptIdentityWithPassphrase,\n  isPassphraseProtectedIdentity,\n} from '../../encryption/age';\nimport { getVaultPath, getIdentityPath, getRecipientPath } from '../../config/paths';\nimport { promptPassphraseDecrypt } from '../../utils/prompts';\nimport { loadConfig } from '../../config/loader';\nimport { detectPromptLeak } from '../../core/validation';\n\n/**\n * Module-level cache for decrypted identity\n * Persists across LocalSource instances within same process\n */\ninterface IdentityCache {\n  key: string;\n  expiresAt: number;\n  identityPath: string;  // Track which identity file this was for\n}\n\nlet identityCache: IdentityCache | null = null;\n\n/**\n * Local credential source using age-encrypted vault\n */\nexport class LocalSource implements ICredentialSource {\n  readonly id = 'local';\n  readonly name = 'Local Vault';\n  readonly priority = 1;\n\n  private encryptionProvider: AgeProvider;\n  private vaultPath: string;\n  private identityPath: string;\n  private recipientPath: string;\n\n  constructor(options?: {\n    vaultPath?: string;\n    identityPath?: string;\n    recipientPath?: string;\n  }) {\n    this.encryptionProvider = new AgeProvider();\n    this.vaultPath = options?.vaultPath ?? getVaultPath();\n    this.identityPath = options?.identityPath ?? getIdentityPath();\n    this.recipientPath = options?.recipientPath ?? getRecipientPath();\n  }\n\n  /**\n   * Check if the local vault is available\n   */\n  async isAvailable(): Promise<boolean> {\n    try {\n      // Check if identity file exists\n      const identityExists = await fs.pathExists(this.identityPath);\n      return identityExists;\n    } catch {\n      return false;\n    }\n  }\n\n  /**\n   * Initialize the local vault\n   * Creates identity file and vault directory\n   */\n  async initialize(options?: { passphrase?: string }): Promise<void> {\n    // Generate new keypair\n    const keyPair = await this.encryptionProvider.generateKeyPair();\n\n    // Save identity (private key) - optionally encrypted with passphrase\n    if (options?.passphrase) {\n      const encryptedIdentity = await encryptIdentityWithPassphrase(\n        keyPair.privateKey,\n        options.passphrase\n      );\n      // Write as passphrase-protected format (marker + base64)\n      const content = `# SecretSage passphrase-protected identity\\n# Encrypted with scrypt\\n${encryptedIdentity}\\n`;\n      await fs.ensureDir(path.dirname(this.identityPath));\n      await fs.writeFile(this.identityPath, content, { mode: 0o600 });\n    } else {\n      await this.encryptionProvider.saveIdentity(keyPair.privateKey, this.identityPath);\n    }\n\n    // Save recipient (public key)\n    await this.encryptionProvider.saveRecipient(keyPair.publicKey, this.recipientPath);\n\n    // Create empty vault file\n    await this.writeVault([]);\n  }\n\n  /**\n   * Load identity, prompting for passphrase if protected\n   * Uses caching to avoid repeated passphrase prompts\n   */\n  private async loadIdentity(): Promise<string> {\n    // Check cache first\n    if (identityCache && identityCache.identityPath === this.identityPath) {\n      if (Date.now() < identityCache.expiresAt) {\n        return identityCache.key;\n      }\n      // Cache expired, clear it\n      identityCache = null;\n    }\n\n    const content = await fs.readFile(this.identityPath, 'utf8');\n\n    if (isPassphraseProtectedIdentity(content)) {\n      // Extract the base64 encrypted data (skip comment lines)\n      const lines = content.split('\\n').filter(l => !l.startsWith('#') && l.trim());\n      const encryptedData = lines.join('');\n\n      // Prompt for passphrase\n      const passphrase = await promptPassphraseDecrypt();\n\n      try {\n        const decryptedKey = await decryptIdentityWithPassphrase(encryptedData, passphrase);\n\n        // Cache the decrypted identity\n        const config = await loadConfig();\n        const ttlSeconds = config.encryption?.passphraseCacheTTL ?? 300;  // Default 5 minutes\n        if (ttlSeconds > 0) {\n          identityCache = {\n            key: decryptedKey,\n            expiresAt: Date.now() + (ttlSeconds * 1000),\n            identityPath: this.identityPath,\n          };\n        }\n\n        return decryptedKey;\n      } catch {\n        throw new Error('Invalid passphrase or corrupted identity file');\n      }\n    }\n\n    // Not passphrase protected, load normally\n    return this.encryptionProvider.loadIdentity(this.identityPath);\n  }\n\n  /**\n   * Get a credential by name\n   */\n  async get(name: string, options?: { action?: 'read' | 'grant' }): Promise<Credential | null> {\n    const entries = await this.readVault();\n    const entryIndex = entries.findIndex((e) => e.name === name);\n\n    if (entryIndex < 0) {\n      return null;\n    }\n\n    const entry = entries[entryIndex];\n\n    // Decrypt the value (will prompt for passphrase if needed)\n    const privateKey = await this.loadIdentity();\n    const value = await this.encryptionProvider.decrypt(entry.encryptedValue, privateKey);\n\n    // Log the access\n    await this.logAccess(entries, entryIndex, options?.action || 'read');\n\n    return {\n      name: entry.name,\n      value,\n      source: this.id,\n      metadata: entry.metadata,\n    };\n  }\n\n  /**\n   * Log an access event to the credential's access log\n   */\n  private async logAccess(\n    entries: VaultEntry[],\n    index: number,\n    action: 'read' | 'grant'\n  ): Promise<void> {\n    const entry = entries[index];\n    const accessLog = entry.accessLog || [];\n\n    // Add new entry\n    accessLog.push({\n      timestamp: new Date(),\n      action,\n    });\n\n    // Keep only last 100 entries\n    if (accessLog.length > 100) {\n      accessLog.shift();\n    }\n\n    entries[index].accessLog = accessLog;\n    await this.writeVault(entries);\n  }\n\n  /**\n   * List all credential metadata\n   */\n  async list(): Promise<CredentialMetadata[]> {\n    const entries = await this.readVault();\n    return entries.map((entry) => ({\n      name: entry.name,\n      ...entry.metadata,\n    }));\n  }\n\n  /**\n   * Store a credential\n   */\n  async set(\n    name: string,\n    value: string,\n    metadata?: Partial<CredentialMetadata>\n  ): Promise<void> {\n    // Defense-in-depth: refuse to encrypt a value that has the shape of the\n    // pre-v0.5.0 \"  KEY: value\" display-layer formatter output. Guards\n    // against any future code path that could re-introduce that symptom.\n    const leak = detectPromptLeak(name, value);\n    if (leak.leak) {\n      throw new Error(\n        `Refusing to store value: appears to be a \"  ${name}: ...\" formatted line, ` +\n        `not a raw credential. If this is intentional, strip the prefix at the call site.`\n      );\n    }\n\n    // Read current vault\n    const entries = await this.readVault();\n\n    // Get public key for encryption\n    const publicKey = await this.encryptionProvider.loadRecipient(this.recipientPath);\n\n    // Encrypt the value\n    const encryptedValue = await this.encryptionProvider.encrypt(value, publicKey);\n\n    // Find existing entry or create new\n    const existingIndex = entries.findIndex((e) => e.name === name);\n    const now = new Date();\n    const isRotation = existingIndex >= 0;\n\n    // Build rotation history\n    let rotationHistory: RotationEvent[] = [];\n    if (isRotation) {\n      // Preserve existing history\n      rotationHistory = entries[existingIndex].metadata?.rotationHistory || [];\n      // Add new rotation event\n      rotationHistory.push({\n        timestamp: now,\n        reason: metadata?.rotationHistory?.[0]?.reason,\n      });\n    }\n\n    const newEntry: VaultEntry = {\n      name,\n      encryptedValue,\n      metadata: {\n        name,\n        createdAt: isRotation ? entries[existingIndex].metadata?.createdAt : now,\n        updatedAt: now,\n        ...metadata,\n        rotationHistory: isRotation ? rotationHistory : undefined,\n      },\n    };\n\n    if (existingIndex >= 0) {\n      entries[existingIndex] = newEntry;\n    } else {\n      entries.push(newEntry);\n    }\n\n    // Write updated vault\n    await this.writeVault(entries);\n  }\n\n  /**\n   * Delete a credential\n   */\n  async delete(name: string): Promise<boolean> {\n    const entries = await this.readVault();\n    const index = entries.findIndex((e) => e.name === name);\n\n    if (index < 0) {\n      return false;\n    }\n\n    entries.splice(index, 1);\n    await this.writeVault(entries);\n    return true;\n  }\n\n  /**\n   * Search credentials by pattern\n   */\n  async search(pattern: string): Promise<CredentialMetadata[]> {\n    const entries = await this.readVault();\n    const regex = new RegExp(pattern, 'i');\n\n    return entries\n      .filter((e) => regex.test(e.name))\n      .map((e) => ({\n        name: e.name,\n        ...e.metadata,\n      }));\n  }\n\n  /**\n   * Get all credentials (decrypted)\n   */\n  async getAll(): Promise<Credential[]> {\n    const entries = await this.readVault();\n    const privateKey = await this.loadIdentity();\n\n    const credentials: Credential[] = [];\n\n    for (const entry of entries) {\n      const value = await this.encryptionProvider.decrypt(entry.encryptedValue, privateKey);\n      credentials.push({\n        name: entry.name,\n        value,\n        source: this.id,\n        metadata: entry.metadata,\n      });\n    }\n\n    return credentials;\n  }\n\n  /**\n   * Get the public key (recipient)\n   */\n  async getPublicKey(): Promise<string> {\n    return this.encryptionProvider.loadRecipient(this.recipientPath);\n  }\n\n  /**\n   * Get the access log for a credential\n   */\n  async getAccessLog(name: string): Promise<AccessLogEntry[]> {\n    const entries = await this.readVault();\n    const entry = entries.find((e) => e.name === name);\n    return entry?.accessLog || [];\n  }\n\n  /**\n   * Read vault entries from file\n   */\n  private async readVault(): Promise<VaultEntry[]> {\n    try {\n      const exists = await fs.pathExists(this.vaultPath);\n      if (!exists) {\n        return [];\n      }\n\n      const content = await fs.readFile(this.vaultPath, 'utf8');\n      if (!content.trim()) {\n        return [];\n      }\n\n      return JSON.parse(content) as VaultEntry[];\n    } catch (error) {\n      // If file doesn't exist or is invalid, return empty\n      return [];\n    }\n  }\n\n  /**\n   * Write vault entries to file\n   */\n  private async writeVault(entries: VaultEntry[]): Promise<void> {\n    await fs.ensureDir(path.dirname(this.vaultPath));\n\n    // Write with restrictive permissions\n    const content = JSON.stringify(entries, null, 2);\n    await fs.writeFile(this.vaultPath, content, { mode: 0o600 });\n  }\n}\n","/**\n * Credential Service\n *\n * Main service layer for SecretSage operations.\n * Orchestrates sources, encryption, and config.\n */\n\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport { parse as parseEnv } from 'dotenv';\nimport type { Credential, CredentialMetadata } from './types';\nimport { CredentialSourceRegistry } from '../sources/registry';\nimport { LocalSource } from '../sources/local';\nimport { loadConfig } from '../config/loader';\nimport {\n  getEnvPath,\n  getEnvBackupPath,\n  getGitignorePath,\n  getLocalDir,\n  getGlobalDir,\n  hasLocalVault,\n  hasGlobalVault,\n} from '../config/paths';\n\n/**\n * Main credential service\n */\nexport class CredentialService {\n  private registry: CredentialSourceRegistry;\n  private localSource: LocalSource | null = null;\n  private initialized = false;\n\n  constructor() {\n    this.registry = new CredentialSourceRegistry();\n  }\n\n  /**\n   * Initialize the service with configured sources\n   */\n  async init(options?: { local?: boolean }): Promise<void> {\n    if (this.initialized) return;\n\n    const config = await loadConfig();\n\n    // Create local source based on options or config\n    const useLocal = options?.local ?? config.vault.defaultLocation === 'local';\n\n    this.localSource = new LocalSource({\n      vaultPath: useLocal\n        ? path.join(getLocalDir(), 'vault.json')\n        : path.join(getGlobalDir(), 'vault.json'),\n      identityPath: useLocal\n        ? path.join(getLocalDir(), 'identity.txt')\n        : path.join(getGlobalDir(), 'identity.txt'),\n      recipientPath: useLocal\n        ? path.join(getLocalDir(), 'recipient.txt')\n        : path.join(getGlobalDir(), 'recipient.txt'),\n    });\n\n    this.registry.register(this.localSource);\n    this.initialized = true;\n  }\n\n  /**\n   * Initialize a new vault\n   */\n  async initializeVault(options?: {\n    local?: boolean;\n    customPath?: string;\n    passphrase?: string;\n  }): Promise<{ publicKey: string; vaultDir: string }> {\n    let vaultDir: string;\n\n    if (options?.customPath) {\n      // Use custom path (expand ~ if present)\n      vaultDir = path.resolve(\n        options.customPath.startsWith('~')\n          ? path.join(require('os').homedir(), options.customPath.slice(1))\n          : options.customPath\n      );\n    } else {\n      vaultDir = options?.local ? getLocalDir() : getGlobalDir();\n    }\n\n    this.localSource = new LocalSource({\n      vaultPath: path.join(vaultDir, 'vault.json'),\n      identityPath: path.join(vaultDir, 'identity.txt'),\n      recipientPath: path.join(vaultDir, 'recipient.txt'),\n    });\n\n    await this.localSource.initialize({ passphrase: options?.passphrase });\n    const publicKey = await this.localSource.getPublicKey();\n\n    return { publicKey, vaultDir };\n  }\n\n  /**\n   * Check if a vault exists\n   */\n  async hasVault(): Promise<{ local: boolean; global: boolean }> {\n    return {\n      local: await hasLocalVault(),\n      global: await hasGlobalVault(),\n    };\n  }\n\n  /**\n   * Get the active vault directory path\n   */\n  async getVaultPath(): Promise<string> {\n    // Priority: local vault > custom path > global vault\n    if (await hasLocalVault()) {\n      return getLocalDir();\n    }\n    const config = await loadConfig();\n    if (config.vault.defaultLocation === 'custom' && config.vault.customPath) {\n      return config.vault.customPath;\n    }\n    return getGlobalDir();\n  }\n\n  /**\n   * Add a credential to the vault\n   */\n  async add(name: string, value: string, metadata?: Partial<CredentialMetadata>): Promise<void> {\n    await this.ensureInitialized();\n    await this.registry.set(name, value, metadata);\n  }\n\n  /**\n   * Get a credential\n   */\n  async get(name: string): Promise<Credential | null> {\n    await this.ensureInitialized();\n    return this.registry.get(name);\n  }\n\n  /**\n   * List all credentials\n   */\n  async list(): Promise<CredentialMetadata[]> {\n    await this.ensureInitialized();\n    return this.registry.list();\n  }\n\n  /**\n   * Delete a credential\n   */\n  async delete(name: string): Promise<boolean> {\n    await this.ensureInitialized();\n    return this.registry.delete(name);\n  }\n\n  /**\n   * Grant credentials to .env file\n   */\n  async grant(\n    names: string[],\n    options?: { backup?: boolean; envPath?: string }\n  ): Promise<{ granted: string[]; envPath: string }> {\n    await this.ensureInitialized();\n\n    const envPath = options?.envPath || getEnvPath();\n\n    // Read existing .env\n    let existingEnv: Record<string, string> = {};\n    if (await fs.pathExists(envPath)) {\n      const content = await fs.readFile(envPath, 'utf8');\n      existingEnv = parseEnv(content);\n\n      // Backup if requested (with secure permissions)\n      if (options?.backup !== false) {\n        const backupPath = getEnvBackupPath();\n        const backupContent = await fs.readFile(envPath, 'utf8');\n        await fs.writeFile(backupPath, backupContent, { mode: 0o600 });\n      }\n    }\n\n    // Get requested credentials\n    const granted: string[] = [];\n    for (const name of names) {\n      const cred = await this.registry.get(name);\n      if (cred) {\n        existingEnv[name] = cred.value;\n        granted.push(name);\n      }\n    }\n\n    // Write .env with secure permissions\n    const envContent = this.stringifyEnv(existingEnv);\n    await fs.writeFile(envPath, envContent, { mode: 0o600 });\n\n    return { granted, envPath };\n  }\n\n  /**\n   * Revoke credentials from .env file\n   */\n  async revoke(names: string[]): Promise<{ revoked: string[]; envPath: string }> {\n    const envPath = getEnvPath();\n\n    if (!(await fs.pathExists(envPath))) {\n      return { revoked: [], envPath };\n    }\n\n    const content = await fs.readFile(envPath, 'utf8');\n    const existingEnv = parseEnv(content);\n\n    const revoked: string[] = [];\n    for (const name of names) {\n      if (name in existingEnv) {\n        delete existingEnv[name];\n        revoked.push(name);\n      }\n    }\n\n    // Write updated .env\n    const envContent = this.stringifyEnv(existingEnv);\n    await fs.writeFile(envPath, envContent);\n\n    return { revoked, envPath };\n  }\n\n  /**\n   * Get all credentials (decrypted)\n   */\n  async getAll(): Promise<Credential[]> {\n    await this.ensureInitialized();\n    if (this.localSource) {\n      return this.localSource.getAll();\n    }\n    return [];\n  }\n\n  /**\n   * Get access log for a credential\n   */\n  async getAccessLog(name: string): Promise<{ timestamp: Date; action: 'read' | 'grant' }[]> {\n    await this.ensureInitialized();\n    if (this.localSource) {\n      return this.localSource.getAccessLog(name);\n    }\n    return [];\n  }\n\n  /**\n   * Add .secretsage and .env to .gitignore\n   */\n  async updateGitignore(): Promise<boolean> {\n    const gitignorePath = getGitignorePath();\n    const entriesToAdd = ['.env', '.env.*', '.secretsage/'];\n\n    let content = '';\n    if (await fs.pathExists(gitignorePath)) {\n      content = await fs.readFile(gitignorePath, 'utf8');\n    }\n\n    const lines = content.split('\\n').map((l) => l.trim());\n    const additions: string[] = [];\n\n    for (const entry of entriesToAdd) {\n      if (!lines.includes(entry)) {\n        additions.push(entry);\n      }\n    }\n\n    if (additions.length === 0) {\n      return false; // Nothing to add\n    }\n\n    const newContent =\n      content.trimEnd() + '\\n\\n# SecretSage\\n' + additions.join('\\n') + '\\n';\n    await fs.writeFile(gitignorePath, newContent);\n\n    return true;\n  }\n\n  /**\n   * Ensure service is initialized\n   */\n  private async ensureInitialized(): Promise<void> {\n    if (!this.initialized) {\n      await this.init();\n    }\n  }\n\n  /**\n   * Convert env object to string format\n   */\n  private stringifyEnv(env: Record<string, string>): string {\n    const lines: string[] = [];\n\n    for (const [key, value] of Object.entries(env)) {\n      // Quote values that contain special characters\n      const needsQuotes = /[\\s#\"'\\\\]/.test(value) || value.includes('=');\n      const quotedValue = needsQuotes ? `\"${value.replace(/\"/g, '\\\\\"')}\"` : value;\n      lines.push(`${key}=${quotedValue}`);\n    }\n\n    return lines.join('\\n') + '\\n';\n  }\n}\n\n/**\n * Default singleton instance\n */\nexport const credentialService = new CredentialService();\n","/**\n * Key Validation Patterns\n *\n * Validation patterns for common API key formats.\n */\n\n/**\n * Known key patterns for validation\n */\nexport const KEY_PATTERNS: Record<string, RegExp> = {\n  // Stripe\n  STRIPE_SECRET_KEY: /^sk_(test|live)_[A-Za-z0-9]+$/,\n  STRIPE_WEBHOOK_SECRET: /^whsec_[A-Za-z0-9]+$/,\n  STRIPE_PUBLISHABLE_KEY: /^pk_(test|live)_[A-Za-z0-9]+$/,\n\n  // Generic patterns for generated keys\n  HEX_64: /^[a-f0-9]{64}$/i,  // 32 bytes\n  HEX_32: /^[a-f0-9]{32}$/i,  // 16 bytes\n\n  // OpenAI\n  OPENAI_API_KEY: /^sk-[A-Za-z0-9]{48,}$/,\n\n  // Anthropic\n  ANTHROPIC_API_KEY: /^sk-ant-[A-Za-z0-9-]+$/,\n\n  // AWS\n  AWS_ACCESS_KEY_ID: /^AKIA[A-Z0-9]{16}$/,\n  AWS_SECRET_ACCESS_KEY: /^[A-Za-z0-9/+=]{40}$/,\n\n  // Generic patterns\n  API_KEY: /^.{10,}$/,  // At least 10 chars\n  SECRET_KEY: /^.{10,}$/,\n};\n\n/**\n * Key-specific instructions for wizard\n */\nexport const KEY_INSTRUCTIONS: Record<string, string> = {\n  STRIPE_SECRET_KEY: 'Go to https://dashboard.stripe.com/apikeys and click \"Roll key\" on your secret key',\n  STRIPE_WEBHOOK_SECRET: 'Go to https://dashboard.stripe.com/webhooks, select your endpoint, and click \"Roll secret\"',\n  STRIPE_PUBLISHABLE_KEY: 'Go to https://dashboard.stripe.com/apikeys and copy your publishable key',\n  OPENAI_API_KEY: 'Go to https://platform.openai.com/api-keys and create a new key',\n  ANTHROPIC_API_KEY: 'Go to https://console.anthropic.com/settings/keys and create a new key',\n};\n\n/**\n * Get validation pattern for a key name\n */\nexport function getPatternForKey(keyName: string): RegExp | null {\n  // Check exact match first\n  if (KEY_PATTERNS[keyName]) {\n    return KEY_PATTERNS[keyName];\n  }\n\n  // Check if key name contains known prefixes\n  // WEBHOOK check must come before generic SECRET check\n  if (keyName.includes('STRIPE') && keyName.includes('WEBHOOK')) {\n    return KEY_PATTERNS.STRIPE_WEBHOOK_SECRET;\n  }\n  if (keyName.includes('STRIPE') && keyName.includes('SECRET')) {\n    return KEY_PATTERNS.STRIPE_SECRET_KEY;\n  }\n  if (keyName.includes('STRIPE') && keyName.includes('PUBLISH')) {\n    return KEY_PATTERNS.STRIPE_PUBLISHABLE_KEY;\n  }\n  if (keyName.includes('OPENAI')) {\n    return KEY_PATTERNS.OPENAI_API_KEY;\n  }\n  if (keyName.includes('ANTHROPIC')) {\n    return KEY_PATTERNS.ANTHROPIC_API_KEY;\n  }\n\n  // Check for encryption key patterns (usually hex)\n  if (keyName.includes('ENCRYPTION') || keyName.includes('OAUTH')) {\n    return KEY_PATTERNS.HEX_64;\n  }\n\n  // Fallback to generic pattern\n  return KEY_PATTERNS.API_KEY;\n}\n\n/**\n * Get instructions for a key name\n */\nexport function getInstructionsForKey(keyName: string): string | null {\n  return KEY_INSTRUCTIONS[keyName] || null;\n}\n\n/**\n * Validate a key value against its expected pattern\n */\nexport function validateKey(keyName: string, value: string): { valid: boolean; message?: string } {\n  const pattern = getPatternForKey(keyName);\n\n  if (!pattern) {\n    return { valid: true }; // No validation available\n  }\n\n  if (pattern.test(value)) {\n    return { valid: true };\n  }\n\n  // Provide helpful error messages\n  if (keyName.includes('STRIPE') && keyName.includes('SECRET')) {\n    return { valid: false, message: 'Stripe secret keys should start with sk_test_ or sk_live_' };\n  }\n  if (keyName.includes('STRIPE') && keyName.includes('WEBHOOK')) {\n    return { valid: false, message: 'Stripe webhook secrets should start with whsec_' };\n  }\n  if (keyName.includes('ENCRYPTION') || keyName.includes('OAUTH')) {\n    return { valid: false, message: 'Expected a 64-character hex string (32 bytes)' };\n  }\n\n  return { valid: false, message: 'Value does not match expected format' };\n}\n","/**\n * Wizard UI\n *\n * Terminal UI for interactive key entry.\n * This runs in a spawned terminal window.\n */\n\nimport * as fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { CredentialService } from '../core/service';\nimport { validateKey, getInstructionsForKey } from './validation';\n\nexport interface WizardConfig {\n  keys: string[];\n  reason?: string;\n  signalPath?: string; // Optional for inline mode\n}\n\n/**\n * Display wizard banner\n */\nfunction showBanner(reason?: string): void {\n  console.clear();\n  console.log('');\n  console.log(chalk.magenta('┌─────────────────────────────────────────────────────┐'));\n  console.log(chalk.magenta('│') + chalk.bold.white('  SecretSage Key Rotation Wizard                    ') + chalk.magenta('│'));\n  console.log(chalk.magenta('└─────────────────────────────────────────────────────┘'));\n  console.log('');\n\n  if (reason) {\n    console.log(chalk.yellow('  Reason:'), reason);\n    console.log('');\n  }\n}\n\n/**\n * Prompt for a single key value\n */\nasync function promptForKey(keyName: string): Promise<string | null> {\n  const instructions = getInstructionsForKey(keyName);\n\n  console.log(chalk.cyan(`\\n  ${keyName}`));\n  console.log(chalk.gray('  ─'.repeat(25)));\n\n  if (instructions) {\n    console.log(chalk.gray(`  ${instructions}`));\n    console.log('');\n  }\n\n  const { value } = await inquirer.prompt([\n    {\n      type: 'password',\n      name: 'value',\n      message: `Paste value for ${chalk.cyan(keyName)}:`,\n      mask: '*',\n      validate: (input: string) => {\n        if (!input || input.trim().length === 0) {\n          return 'Value cannot be empty. Press Ctrl+C to cancel.';\n        }\n\n        const validation = validateKey(keyName, input.trim());\n        if (!validation.valid) {\n          return validation.message || 'Invalid format';\n        }\n\n        return true;\n      },\n    },\n  ]);\n\n  return value.trim();\n}\n\n/**\n * Run the wizard UI\n */\nexport async function runWizardUI(config: WizardConfig): Promise<void> {\n  const service = new CredentialService();\n\n  try {\n    // Check vault exists\n    const vaults = await service.hasVault();\n    if (!vaults.local && !vaults.global) {\n      console.log(chalk.red('\\n  Error: No vault found. Run `secretsage init` first.\\n'));\n      if (config.signalPath) {\n        await writeSignal(config.signalPath, { success: false, error: 'No vault found' });\n      }\n      process.exit(1);\n    }\n\n    await service.init();\n\n    showBanner(config.reason);\n\n    console.log(chalk.white('  The following keys need to be entered:'));\n    config.keys.forEach((key, i) => {\n      console.log(chalk.gray(`    ${i + 1}. `) + chalk.cyan(key));\n    });\n\n    console.log('');\n    console.log(chalk.gray('  Press Ctrl+C at any time to cancel.'));\n\n    // Collect all key values\n    const values: Record<string, string> = {};\n\n    for (const keyName of config.keys) {\n      const value = await promptForKey(keyName);\n      if (value === null) {\n        throw new Error('User cancelled');\n      }\n      values[keyName] = value;\n    }\n\n    // Confirm before saving (show minimal info to prevent leakage)\n    console.log('');\n    console.log(chalk.yellow('  Ready to save the following keys:'));\n    config.keys.forEach((key) => {\n      // Only show length, not actual characters (security)\n      const len = values[key].length;\n      console.log(chalk.gray(`    • `) + chalk.cyan(key) + chalk.gray(` (${len} characters)`));\n    });\n    console.log('');\n\n    const { confirm } = await inquirer.prompt([\n      {\n        type: 'confirm',\n        name: 'confirm',\n        message: 'Save these keys to the vault?',\n        default: true,\n      },\n    ]);\n\n    if (!confirm) {\n      console.log(chalk.yellow('\\n  Cancelled. No changes made.\\n'));\n      if (config.signalPath) {\n        await writeSignal(config.signalPath, { success: false, error: 'User cancelled' });\n      }\n      process.exit(0);\n    }\n\n    // Save all keys\n    console.log('');\n    for (const keyName of config.keys) {\n      console.log(chalk.gray(`  Encrypting ${keyName}...`));\n      const metadata = config.reason\n        ? { rotationHistory: [{ timestamp: new Date(), reason: config.reason }] }\n        : undefined;\n      await service.add(keyName, values[keyName], metadata);\n    }\n\n    console.log('');\n    console.log(chalk.green('  ✓ All keys saved successfully!'));\n    console.log('');\n    console.log(chalk.gray('  Run `secretsage grant --all` to update your .env file.'));\n    console.log('');\n\n    // Write success signal (if running in spawned terminal mode)\n    if (config.signalPath) {\n      await writeSignal(config.signalPath, {\n        success: true,\n        keys: config.keys,\n        timestamp: new Date().toISOString(),\n      });\n      // Give user time to read the message in spawned terminal\n      await new Promise((resolve) => setTimeout(resolve, 2000));\n    }\n\n  } catch (error) {\n    const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n    console.log(chalk.red(`\\n  Error: ${errorMessage}\\n`));\n    if (config.signalPath) {\n      await writeSignal(config.signalPath, { success: false, error: errorMessage });\n    }\n    process.exit(1);\n  }\n}\n\n/**\n * Write signal file for main process\n */\nasync function writeSignal(signalPath: string, data: Record<string, unknown>): Promise<void> {\n  await fs.writeFile(signalPath, JSON.stringify(data, null, 2));\n}\n","#!/usr/bin/env node\n\n/**\n * SecretSage CLI\n *\n * Terminal-based credential wizard for agent-driven development.\n * The missing OAuth for LLM agents.\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { BANNER } from './utils/banner';\nimport { initCommand } from './commands/init';\nimport { addCommand } from './commands/add';\nimport { listCommand } from './commands/list';\nimport { getCommand } from './commands/get';\nimport { grantCommand } from './commands/grant';\nimport { revokeCommand } from './commands/revoke';\nimport { configCommand } from './commands/config';\nimport { removeCommand } from './commands/remove';\nimport { rotateCommand } from './commands/rotate';\nimport { exportCommand } from './commands/export';\nimport { importCommand } from './commands/import';\nimport { statusCommand } from './commands/status';\nimport { auditCommand } from './commands/audit';\nimport { wizardCommand, wizardUICommand } from './commands/wizard';\nimport { deployCommand } from './commands/deploy';\nimport {\n  backupCodesAddCommand,\n  backupCodesListCommand,\n  backupCodesShowCommand,\n  backupCodesUseCommand,\n} from './commands/backup-codes';\n\nconst program = new Command();\n\nprogram\n  .name('secretsage')\n  .description('Terminal-based credential wizard for agent-driven development')\n  .version('0.5.0')\n  .addHelpText('beforeAll', BANNER)\n  .addHelpText('after', `\n${chalk.magenta('Quick Start:')}\n  ${chalk.white('secretsage init')}              Initialize vault and generate keypair\n  ${chalk.white('secretsage add OPENAI_API_KEY')}  Add a credential\n  ${chalk.white('secretsage grant --all')}        Grant all credentials to .env\n\n${chalk.magenta('Agent Usage:')}\n  ${chalk.white('secretsage list --json')}        Machine-readable credential list\n  ${chalk.white('secretsage grant KEY --yes')}    Non-interactive grant for agents\n`);\n\n// Initialize vault\nprogram\n  .command('init')\n  .description('Initialize SecretSage vault and generate encryption keypair')\n  .option('-l, --local', 'Create vault in current directory instead of ~/.secretsage')\n  .option('-p, --path <path>', 'Create vault at a custom directory path')\n  .option('-y, --yes', 'Skip confirmation prompts')\n  .option('--force', 'Overwrite existing configuration')\n  .option('--passphrase', 'Protect identity file with a passphrase (scrypt)')\n  .action(initCommand);\n\n// Add credential\nprogram\n  .command('add <name>')\n  .description('Add a credential to the encrypted vault')\n  .option('-v, --value <value>', 'Credential value (use \"-\" for stdin, prompts if not provided)')\n  .option('--from-env', 'Import value from existing .env file')\n  .option('-q, --quiet', 'Minimal output')\n  .action(addCommand);\n\n// List credentials\nprogram\n  .command('list')\n  .alias('ls')\n  .description('List credential names in the vault')\n  .option('--json', 'Output as JSON (agent-friendly)')\n  .option('-a, --all', 'Include metadata')\n  .action(listCommand);\n\n// Get single credential\nprogram\n  .command('get <name>')\n  .description('Retrieve a single credential value (for scripting)')\n  .option('-r, --raw', 'Output only the value (no newline, for piping)')\n  .option('--json', 'Output as JSON')\n  .option('-q, --quiet', 'Suppress error messages')\n  .action(getCommand);\n\n// Grant credentials\nprogram\n  .command('grant [names...]')\n  .description('Decrypt and write credentials to .env for agent use')\n  .option('-a, --all', 'Grant all credentials')\n  .option('-y, --yes', 'Skip confirmation (for agents)')\n  .option('-e, --env <path>', 'Target .env file path (default: .env in current directory)')\n  .option('--no-backup', 'Skip .env backup')\n  .action(grantCommand);\n\n// Revoke credentials\nprogram\n  .command('revoke [names...]')\n  .description('Remove credentials from .env (vault remains intact)')\n  .option('-a, --all', 'Revoke all credentials')\n  .option('-y, --yes', 'Skip confirmation')\n  .action(revokeCommand);\n\n// Config\nprogram\n  .command('config')\n  .description('View or update SecretSage configuration')\n  .option('-s, --show', 'Show current configuration')\n  .option('--set <key=value>', 'Set a configuration value')\n  .option('--path', 'Show configuration file path')\n  .action(configCommand);\n\n// Remove credential from vault\nprogram\n  .command('remove <name>')\n  .alias('rm')\n  .description('Permanently delete a credential from the vault')\n  .option('-y, --yes', 'Skip confirmation')\n  .option('-q, --quiet', 'Minimal output')\n  .action(removeCommand);\n\n// Rotate credential value\nprogram\n  .command('rotate <name>')\n  .description('Update the value of an existing credential')\n  .option('-v, --value <value>', 'New value (use \"-\" for stdin)')\n  .option('-g, --generate <bytes>', 'Generate random value (specify byte length)')\n  .option('-r, --reason <reason>', 'Reason for rotation (for audit trail)')\n  .option('-y, --yes', 'Skip confirmation')\n  .option('-q, --quiet', 'Minimal output')\n  .action(rotateCommand);\n\n// Export vault\nprogram\n  .command('export')\n  .description('Export vault credentials for backup or transfer')\n  .option('-o, --output <file>', 'Output file (default: stdout)')\n  .option('-f, --format <type>', 'Output format: json, env (default: json)', 'json')\n  .option('-k, --keys <names>', 'Comma-separated list of keys to export')\n  .option('--encrypted', 'Keep credentials encrypted (for backup)')\n  .option('-q, --quiet', 'Minimal output')\n  .option('-y, --yes', 'Skip confirmation (requires agent.trustedMode in config)')\n  .action(exportCommand);\n\n// Import credentials\nprogram\n  .command('import')\n  .description('Import credentials from backup or external source')\n  .option('-i, --input <file>', 'Input file (default: stdin)')\n  .option('-f, --format <type>', 'Input format: json, env (default: json)', 'json')\n  .option('--merge', 'Merge with existing vault (default: skip existing)')\n  .option('-y, --yes', 'Skip confirmation')\n  .option('-q, --quiet', 'Minimal output')\n  .action(importCommand);\n\n// Status check\nprogram\n  .command('status')\n  .description('Show vault status and health check')\n  .option('--json', 'Output as JSON (agent-friendly)')\n  .action(statusCommand);\n\n// Audit credential history\nprogram\n  .command('audit <name>')\n  .description('Show rotation history and audit trail for a credential')\n  .option('--json', 'Output as JSON (agent-friendly)')\n  .action(auditCommand);\n\n// Wizard - agent-human handoff for key entry\nprogram\n  .command('wizard')\n  .description('Open interactive key entry wizard in new terminal (agent-human handoff)')\n  .requiredOption('-k, --keys <keys>', 'Comma-separated list of key names to collect')\n  .option('-r, --reason <reason>', 'Reason for rotation (shown in wizard)')\n  .option('-t, --timeout <seconds>', 'Timeout in seconds (default: 300)')\n  .option('--no-wait', 'Return immediately without waiting for wizard completion')\n  .option('-i, --inline', 'Run wizard in current terminal (for headless/SSH environments)')\n  .action(wizardCommand);\n\n// Wizard UI - internal command run in spawned terminal\nprogram\n  .command('wizard-ui')\n  .description('(internal) Wizard UI for terminal')\n  .option('-c, --config <path>', 'Path to wizard config file')\n  .action(wizardUICommand);\n\n// Deploy secrets to remote\nprogram\n  .command('deploy <project>')\n  .description('Deploy secrets to a remote server via rsync/SSH')\n  .requiredOption('--remote <destination>', 'Remote destination (user@host:/path)')\n  .option('-f, --file <path>', 'Local .env file path (default: .env)')\n  .option('--restart <command>', 'Post-deploy command to run on remote (e.g., \"pm2 restart app\")')\n  .option('-y, --yes', 'Skip confirmation')\n  .action(deployCommand);\n\n// Backup codes - parent command\nconst backupCodes = program\n  .command('backup-codes')\n  .alias('bc')\n  .description('Manage 2FA backup/recovery codes');\n\nbackupCodes\n  .command('add <service>')\n  .description('Store backup codes for a service')\n  .option('-a, --account <email>', 'Account identifier (for multiple accounts)')\n  .option('-q, --quiet', 'Minimal output')\n  .action(backupCodesAddCommand);\n\nbackupCodes\n  .command('list')\n  .alias('ls')\n  .description('List services with stored backup codes')\n  .option('--json', 'Output as JSON')\n  .action(backupCodesListCommand);\n\nbackupCodes\n  .command('show <service>')\n  .description('Display backup codes for a service')\n  .option('-a, --account <email>', 'Account identifier')\n  .option('-y, --yes', 'Skip confirmation')\n  .action(backupCodesShowCommand);\n\nbackupCodes\n  .command('use <service>')\n  .description('Mark a backup code as used')\n  .option('-a, --account <email>', 'Account identifier')\n  .option('-i, --index <number>', 'Code number to mark as used')\n  .action(backupCodesUseCommand);\n\n// Parse and run\nprogram.parse(process.argv);\n\n// Show help if no command\nif (!process.argv.slice(2).length) {\n  program.outputHelp();\n}\n","import chalk from 'chalk';\n\n/**\n * ASCII art banner for SecretSage\n * Displayed when running `secretsage` or `secretsage --help`\n */\nexport const BANNER = `\n${chalk.magenta('   ___                      _    ___')}\n${chalk.magenta('  / __|  ___  __  _ _  ___ | |_ / __|  __ _   __ _   ___')}\n${chalk.magenta('  \\\\__ \\\\ / -_)/ _|| \\'_|/ -_)|  _|\\\\__ \\\\ / _` | / _` | / -_)')}\n${chalk.magenta('  |___/ \\\\___|\\\\___|_|  \\\\___| \\\\__||___/ \\\\__,_| \\\\__, | \\\\___|')}\n${chalk.magenta('                                             |___/')}\n\n${chalk.gray('  @cyclecore/secretsage')} ${chalk.dim('v0.5.0')}\n${chalk.gray('  The missing OAuth for LLM agents')}\n`;\n\n/**\n * Compact banner for use in command output\n */\nexport const COMPACT_BANNER = `${chalk.magenta('SecretSage')} ${chalk.dim('v0.5.0')}`;\n\n/**\n * Print the full banner to console\n */\nexport function printBanner(): void {\n  console.log(BANNER);\n}\n","/**\n * Init Command\n *\n * Initialize SecretSage vault and generate encryption keypair.\n */\n\nimport { CredentialService } from '../core/service';\nimport { loadConfig, saveConfig } from '../config/loader';\nimport { getGlobalDir, getLocalDir } from '../config/paths';\nimport * as output from '../utils/output';\nimport { confirm, promptVaultLocation, promptCustomPath, promptPassphrase } from '../utils/prompts';\nimport { printBanner } from '../utils/banner';\n\ninterface InitOptions {\n  local?: boolean;\n  path?: string;\n  yes?: boolean;\n  force?: boolean;\n  passphrase?: boolean;\n}\n\nexport async function initCommand(options: InitOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check existing vaults\n  const vaults = await service.hasVault();\n\n  if (vaults.local || vaults.global) {\n    if (!options.force) {\n      const existingLocation = vaults.local ? 'local (.secretsage/)' : 'global (~/.secretsage/)';\n      output.warning(`A vault already exists: ${existingLocation}`);\n\n      if (!options.yes) {\n        const proceed = await confirm('Overwrite existing vault? This will delete all stored credentials.', false);\n        if (!proceed) {\n          console.log('Aborted.');\n          return;\n        }\n      }\n    }\n  }\n\n  // Determine vault location\n  let local = options.local ?? false;\n  let customPath: string | undefined = options.path;\n  let locationType: 'global' | 'local' | 'custom' = 'global';\n\n  if (options.path) {\n    // Custom path provided via CLI flag\n    locationType = 'custom';\n    customPath = options.path;\n  } else if (!options.yes && !options.local) {\n    const choice = await promptVaultLocation();\n    if (choice === 'custom') {\n      locationType = 'custom';\n      customPath = await promptCustomPath();\n    } else if (choice === 'local') {\n      locationType = 'local';\n      local = true;\n    } else {\n      locationType = 'global';\n    }\n  } else if (options.local) {\n    locationType = 'local';\n    local = true;\n  }\n\n  // Get passphrase if requested\n  let passphrase: string | undefined;\n  if (options.passphrase) {\n    output.info('Passphrase protection adds scrypt encryption to your identity file.');\n    passphrase = await promptPassphrase(true);\n  }\n\n  // Show spinner\n  const spin = output.spinner('Initializing SecretSage vault...');\n  spin.start();\n\n  try {\n    // Initialize vault\n    const { publicKey, vaultDir } = await service.initializeVault({\n      local,\n      customPath,\n      passphrase,\n    });\n\n    // Save config\n    await saveConfig(\n      {\n        version: '1',\n        vault: {\n          defaultLocation: locationType,\n          ...(customPath ? { customPath: vaultDir } : {}),\n        },\n        encryption: {\n          provider: 'age',\n          ...(passphrase ? { passphrase: true } : {}),\n        },\n      },\n      locationType === 'local'\n    );\n\n    // Update .gitignore\n    const gitignoreUpdated = await service.updateGitignore();\n\n    spin.succeed('Vault initialized successfully!');\n\n    console.log('');\n    output.divider();\n    output.keyValue('Vault location', vaultDir);\n    output.keyValue('Public key', publicKey);\n\n    if (gitignoreUpdated) {\n      output.keyValue('.gitignore', 'Updated (added .env, .secretsage/)');\n    }\n\n    output.divider();\n    console.log('');\n\n    output.info('Your vault is ready! Add credentials with:');\n    console.log(`  ${output.colors.highlight('secretsage add OPENAI_API_KEY')}`);\n    console.log('');\n  } catch (error) {\n    spin.fail('Failed to initialize vault');\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","import chalk from 'chalk';\nimport ora, { Ora } from 'ora';\n\n/**\n * Output formatting utilities for consistent CLI experience\n */\n\nexport const colors = {\n  success: chalk.green,\n  error: chalk.red,\n  warning: chalk.yellow,\n  info: chalk.blue,\n  muted: chalk.gray,\n  dim: chalk.dim,\n  highlight: chalk.magenta,\n  key: chalk.cyan,\n  value: chalk.white,\n};\n\n/**\n * Print a success message\n */\nexport function success(message: string): void {\n  console.log(colors.success('✓'), message);\n}\n\n/**\n * Print an error message\n */\nexport function error(message: string): void {\n  console.log(colors.error('✗'), message);\n}\n\n/**\n * Print a warning message\n */\nexport function warning(message: string): void {\n  console.log(colors.warning('⚠'), message);\n}\n\n/**\n * Print an info message\n */\nexport function info(message: string): void {\n  console.log(colors.info('ℹ'), message);\n}\n\n/**\n * Print a credential name (without value)\n */\nexport function credentialName(name: string): string {\n  return colors.key(name);\n}\n\n/**\n * Create a spinner for async operations\n */\nexport function spinner(text: string): Ora {\n  return ora({\n    text,\n    color: 'magenta',\n  });\n}\n\n/**\n * Format JSON output for --json flag\n */\nexport function jsonOutput(data: unknown): void {\n  console.log(JSON.stringify(data, null, 2));\n}\n\n/**\n * Print a divider line\n */\nexport function divider(): void {\n  console.log(colors.muted('─'.repeat(50)));\n}\n\n/**\n * Format a key-value pair for display\n */\nexport function keyValue(key: string, value: string): void {\n  console.log(`  ${colors.muted(key + ':')} ${value}`);\n}\n\n/**\n * Print a header\n */\nexport function header(text: string): void {\n  console.log(chalk.bold.white(text));\n}\n\n/**\n * Display credential saved feedback with mini ASCII art\n */\nexport function credentialSaved(name: string, vaultPath: string): void {\n  console.log('');\n  console.log(colors.success('   .---.'));\n  console.log(colors.success('   | * |'), ' Credential saved!');\n  console.log(colors.success(\"   '---'\"));\n  divider();\n  keyValue('Name', colors.key(name));\n  keyValue('Vault', vaultPath);\n  divider();\n  console.log('');\n}\n","/**\n * Add Command\n *\n * Add a credential to the encrypted vault.\n */\n\nimport * as fs from 'fs-extra';\nimport { parse as parseEnv } from 'dotenv';\nimport { CredentialService } from '../core/service';\nimport { getEnvPath } from '../config/paths';\nimport * as output from '../utils/output';\nimport { promptCredentialValue } from '../utils/prompts';\n\n/**\n * Read value from stdin (for piped input)\n */\nasync function readStdin(): Promise<string> {\n  return new Promise((resolve, reject) => {\n    let data = '';\n    process.stdin.setEncoding('utf8');\n    process.stdin.on('data', (chunk) => { data += chunk; });\n    process.stdin.on('end', () => { resolve(data.trim()); });\n    process.stdin.on('error', reject);\n\n    // Handle case where stdin is a TTY (not piped)\n    if (process.stdin.isTTY) {\n      reject(new Error('No input provided via stdin. Use --value with a value or omit to use interactive prompt.'));\n    }\n  });\n}\n\ninterface AddOptions {\n  value?: string;\n  fromEnv?: boolean;\n  quiet?: boolean;\n}\n\n/**\n * Reserved/dangerous environment variable names that should be blocked\n */\nconst RESERVED_ENV_VARS = new Set([\n  'PATH', 'HOME', 'USER', 'SHELL', 'PWD', 'OLDPWD',\n  'LD_PRELOAD', 'LD_LIBRARY_PATH', 'LD_AUDIT',\n  'DYLD_INSERT_LIBRARIES', 'DYLD_LIBRARY_PATH',\n  'IFS', 'CDPATH', 'ENV', 'BASH_ENV',\n  'TERM', 'DISPLAY', 'XAUTHORITY',\n  'http_proxy', 'https_proxy', 'HTTP_PROXY', 'HTTPS_PROXY',\n  'NODE_OPTIONS', 'NODE_PATH',\n]);\n\nexport async function addCommand(name: string, options: AddOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  // Validate credential name\n  if (RESERVED_ENV_VARS.has(name) || RESERVED_ENV_VARS.has(name.toUpperCase())) {\n    output.error(`Cannot use reserved environment variable name: ${name}`);\n    process.exit(1);\n  }\n\n  if (!/^[A-Z][A-Z0-9_]*$/.test(name)) {\n    output.warning(`Credential name \"${name}\" doesn't follow ENV convention (UPPER_SNAKE_CASE).`);\n  }\n\n  let value: string;\n\n  if (options.fromEnv) {\n    // Import from existing .env\n    const envPath = getEnvPath();\n    if (!(await fs.pathExists(envPath))) {\n      output.error('No .env file found in current directory.');\n      process.exit(1);\n    }\n\n    const content = await fs.readFile(envPath, 'utf8');\n    const env = parseEnv(content);\n\n    if (!(name in env)) {\n      output.error(`Credential \"${name}\" not found in .env file.`);\n      process.exit(1);\n    }\n\n    value = env[name];\n    if (!options.quiet) {\n      output.info(`Importing ${name} from .env`);\n    }\n  } else if (options.value === '-') {\n    // Read from stdin\n    try {\n      value = await readStdin();\n      if (!value) {\n        output.error('Empty input received from stdin.');\n        process.exit(1);\n      }\n    } catch (error) {\n      output.error((error as Error).message);\n      process.exit(1);\n    }\n  } else if (options.value) {\n    // Use provided value\n    value = options.value;\n  } else {\n    // Prompt for value\n    value = await promptCredentialValue(name);\n  }\n\n  // Add to vault\n  const spin = options.quiet ? null : output.spinner(`Encrypting ${name}...`);\n  spin?.start();\n\n  try {\n    await service.add(name, value);\n    spin?.stop();\n\n    if (!options.quiet) {\n      const vaultPath = await service.getVaultPath();\n      output.credentialSaved(name, vaultPath);\n\n      output.info('Grant this credential to .env with:');\n      console.log(`  ${output.colors.highlight(`secretsage grant ${name}`)}`);\n      console.log('');\n    }\n  } catch (error) {\n    spin?.fail(`Failed to add ${name}`);\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","/**\n * List Command\n *\n * List credential names in the vault.\n */\n\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\n\ninterface ListOptions {\n  json?: boolean;\n  all?: boolean;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    if (options.json) {\n      output.jsonOutput({ credentials: [], error: 'No vault found' });\n    } else {\n      output.error('No vault found. Run `secretsage init` first.');\n    }\n    process.exit(1);\n  }\n\n  await service.init();\n\n  try {\n    const credentials = await service.list();\n\n    if (options.json) {\n      // Machine-readable output for agents\n      output.jsonOutput({\n        credentials: credentials.map((c) => ({\n          name: c.name,\n          createdAt: c.createdAt ? new Date(c.createdAt).toISOString() : undefined,\n          updatedAt: c.updatedAt ? new Date(c.updatedAt).toISOString() : undefined,\n          ...(options.all && c.description ? { description: c.description } : {}),\n          ...(options.all && c.tags?.length ? { tags: c.tags } : {}),\n        })),\n        count: credentials.length,\n      });\n      return;\n    }\n\n    if (credentials.length === 0) {\n      output.info('No credentials in vault.');\n      console.log('');\n      console.log(`Add credentials with: ${output.colors.highlight('secretsage add NAME')}`);\n      return;\n    }\n\n    console.log('');\n    console.log(output.colors.muted(`Credentials in vault (${credentials.length}):`));\n    console.log('');\n\n    for (const cred of credentials) {\n      const name = output.credentialName(cred.name);\n      const meta: string[] = [];\n\n      if (options.all) {\n        if (cred.updatedAt) {\n          meta.push(output.colors.muted(`updated ${formatDate(cred.updatedAt)}`));\n        } else if (cred.createdAt) {\n          meta.push(output.colors.muted(`created ${formatDate(cred.createdAt)}`));\n        }\n        if (cred.description) {\n          meta.push(output.colors.muted(cred.description));\n        }\n      }\n\n      const suffix = meta.length > 0 ? ` ${output.colors.muted('·')} ${meta.join(' · ')}` : '';\n      console.log(`  ${name}${suffix}`);\n    }\n\n    console.log('');\n  } catch (error) {\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n\nfunction formatDate(date: Date | string): string {\n  const d = typeof date === 'string' ? new Date(date) : date;\n  const now = new Date();\n  const diff = now.getTime() - d.getTime();\n  const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n\n  if (days === 0) return 'today';\n  if (days === 1) return 'yesterday';\n  if (days < 7) return `${days} days ago`;\n  if (days < 30) return `${Math.floor(days / 7)} weeks ago`;\n  if (days < 365) return `${Math.floor(days / 30)} months ago`;\n  return `${Math.floor(days / 365)} years ago`;\n}\n","/**\n * Get Command\n *\n * Retrieve a single credential value for programmatic use.\n */\n\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\n\ninterface GetOptions {\n  raw?: boolean;\n  json?: boolean;\n  quiet?: boolean;\n}\n\nexport async function getCommand(name: string, options: GetOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    if (!options.quiet && !options.raw) {\n      output.error('No vault found. Run `secretsage init` first.');\n    }\n    process.exit(1);\n  }\n\n  await service.init();\n\n  try {\n    const credential = await service.get(name);\n\n    if (!credential) {\n      if (!options.quiet && !options.raw) {\n        output.error(`Credential \"${name}\" not found.`);\n      }\n      process.exit(1);\n    }\n\n    if (options.raw) {\n      // Raw output: just the value, no newline (for scripting/piping)\n      process.stdout.write(credential.value);\n    } else if (options.json) {\n      // JSON output\n      console.log(JSON.stringify({ name, value: credential.value }));\n    } else {\n      // Default mode: human-readable \"  KEY: value\" form via keyValue formatter.\n      // Unsafe for piping — the rendered prefix bytes will be included in pipe output.\n      // When stdout is a pipe (non-TTY), warn on stderr and recommend --raw.\n      // Default behavior is unchanged in v0.5.0; will change to cat-equivalent in v1.0.\n      if (!process.stdout.isTTY && !options.quiet) {\n        process.stderr.write(\n          `secretsage: warning — default 'get' mode is unsafe to pipe (renders labeled form). ` +\n          `Use 'secretsage get ${name} --raw' for safe pipe output. ` +\n          `This default will change in v1.0.\\n`\n        );\n      }\n      output.keyValue(name, credential.value);\n    }\n  } catch (error) {\n    if (!options.quiet && !options.raw) {\n      output.error((error as Error).message);\n    }\n    process.exit(1);\n  }\n}\n","/**\n * Grant Command\n *\n * Decrypt and write credentials to .env for agent use.\n */\n\nimport { CredentialService } from '../core/service';\nimport { loadConfig } from '../config/loader';\nimport * as output from '../utils/output';\nimport { selectCredentials, confirm } from '../utils/prompts';\n\ninterface GrantOptions {\n  all?: boolean;\n  yes?: boolean;\n  backup?: boolean;\n  env?: string;\n}\n\nexport async function grantCommand(names: string[], options: GrantOptions): Promise<void> {\n  const service = new CredentialService();\n  const config = await loadConfig();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  try {\n    // Get list of available credentials\n    const allCredentials = await service.list();\n\n    if (allCredentials.length === 0) {\n      output.error('No credentials in vault.');\n      console.log(`Add credentials with: ${output.colors.highlight('secretsage add NAME')}`);\n      process.exit(1);\n    }\n\n    let selectedNames: string[];\n\n    if (options.all) {\n      // Grant all credentials\n      selectedNames = allCredentials.map((c) => c.name);\n    } else if (names.length > 0) {\n      // Use provided names\n      selectedNames = names;\n\n      // Validate names exist\n      const availableNames = new Set(allCredentials.map((c) => c.name));\n      const missingNames = selectedNames.filter((n) => !availableNames.has(n));\n\n      if (missingNames.length > 0) {\n        output.error(`Credentials not found: ${missingNames.join(', ')}`);\n        output.info('Available credentials:');\n        allCredentials.forEach((c) => console.log(`  ${output.credentialName(c.name)}`));\n        process.exit(1);\n      }\n    } else {\n      // Interactive selection\n      selectedNames = await selectCredentials(\n        allCredentials.map((c) => c.name),\n        'Select credentials to grant to .env:'\n      );\n    }\n\n    if (selectedNames.length === 0) {\n      output.info('No credentials selected.');\n      return;\n    }\n\n    // Confirmation (unless --yes)\n    if (!options.yes && config.agent.requireConfirmation) {\n      console.log('');\n      console.log('Credentials to grant:');\n      selectedNames.forEach((n) => console.log(`  ${output.credentialName(n)}`));\n      console.log('');\n\n      const proceed = await confirm('Write these credentials to .env?', true);\n      if (!proceed) {\n        console.log('Aborted.');\n        return;\n      }\n    }\n\n    // Grant credentials\n    const spin = output.spinner('Decrypting and writing to .env...');\n    spin.start();\n\n    const { granted, envPath } = await service.grant(selectedNames, {\n      backup: options.backup ?? config.agent.backupEnvOnGrant,\n      envPath: options.env,\n    });\n\n    spin.succeed(`Granted ${granted.length} credential${granted.length === 1 ? '' : 's'} to .env`);\n\n    console.log('');\n    output.divider();\n    granted.forEach((n) => console.log(`  ${output.colors.success('✓')} ${output.credentialName(n)}`));\n    output.divider();\n    output.keyValue('File', envPath);\n    console.log('');\n\n    // Remind about cleanup\n    output.info('Remember to revoke when done:');\n    console.log(`  ${output.colors.highlight('secretsage revoke --all')}`);\n  } catch (error) {\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","/**\n * Revoke Command\n *\n * Remove credentials from .env (vault remains intact).\n */\n\nimport * as fs from 'fs-extra';\nimport { parse as parseEnv } from 'dotenv';\nimport { CredentialService } from '../core/service';\nimport { getEnvPath } from '../config/paths';\nimport * as output from '../utils/output';\nimport { selectCredentials, confirm } from '../utils/prompts';\n\ninterface RevokeOptions {\n  all?: boolean;\n  yes?: boolean;\n}\n\nexport async function revokeCommand(names: string[], options: RevokeOptions): Promise<void> {\n  const service = new CredentialService();\n  const envPath = getEnvPath();\n\n  // Check if .env exists\n  if (!(await fs.pathExists(envPath))) {\n    output.info('No .env file found. Nothing to revoke.');\n    return;\n  }\n\n  // Read current .env\n  const content = await fs.readFile(envPath, 'utf8');\n  const env = parseEnv(content);\n  const envKeys = Object.keys(env);\n\n  if (envKeys.length === 0) {\n    output.info('.env file is empty. Nothing to revoke.');\n    return;\n  }\n\n  // Get vault credentials for reference\n  const vaults = await service.hasVault();\n  let vaultCredentials: string[] = [];\n\n  if (vaults.local || vaults.global) {\n    await service.init();\n    const creds = await service.list();\n    vaultCredentials = creds.map((c) => c.name);\n  }\n\n  // Find credentials in .env that are also in vault\n  const revokeableCreds = envKeys.filter((k) => vaultCredentials.includes(k));\n\n  if (revokeableCreds.length === 0 && !options.all) {\n    output.info('No SecretSage-managed credentials found in .env.');\n    output.info('Use --all to remove all credentials from .env.');\n    return;\n  }\n\n  let selectedNames: string[];\n\n  if (options.all) {\n    // Revoke all credentials in .env\n    selectedNames = envKeys;\n  } else if (names.length > 0) {\n    // Use provided names\n    selectedNames = names;\n\n    // Validate names exist in .env\n    const missingNames = selectedNames.filter((n) => !envKeys.includes(n));\n    if (missingNames.length > 0) {\n      output.warning(`Not found in .env: ${missingNames.join(', ')}`);\n      selectedNames = selectedNames.filter((n) => envKeys.includes(n));\n    }\n  } else {\n    // Interactive selection\n    selectedNames = await selectCredentials(\n      revokeableCreds,\n      'Select credentials to remove from .env:'\n    );\n  }\n\n  if (selectedNames.length === 0) {\n    output.info('No credentials selected.');\n    return;\n  }\n\n  // Confirmation (unless --yes)\n  if (!options.yes) {\n    console.log('');\n    console.log('Credentials to remove from .env:');\n    selectedNames.forEach((n) => console.log(`  ${output.credentialName(n)}`));\n    console.log('');\n    output.warning('Values will be removed from .env. Vault remains intact.');\n\n    const proceed = await confirm('Continue?', true);\n    if (!proceed) {\n      console.log('Aborted.');\n      return;\n    }\n  }\n\n  // Revoke credentials\n  const spin = output.spinner('Removing credentials from .env...');\n  spin.start();\n\n  try {\n    const { revoked } = await service.revoke(selectedNames);\n\n    if (revoked.length === 0) {\n      spin.info('No credentials to revoke.');\n      return;\n    }\n\n    spin.succeed(`Revoked ${revoked.length} credential${revoked.length === 1 ? '' : 's'} from .env`);\n\n    console.log('');\n    output.divider();\n    revoked.forEach((n) => console.log(`  ${output.colors.warning('✗')} ${output.credentialName(n)}`));\n    output.divider();\n    console.log('');\n\n    output.info('Credentials are still safe in the vault.');\n    console.log(`  Re-grant with: ${output.colors.highlight('secretsage grant')}`);\n  } catch (error) {\n    spin.fail('Failed to revoke credentials');\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","/**\n * Config Command\n *\n * View or update SecretSage configuration.\n */\n\nimport * as fs from 'fs-extra';\nimport { loadConfig, saveConfig, getActiveConfigPath } from '../config/loader';\nimport {\n  getGlobalDir,\n  getLocalDir,\n  getIdentityPath,\n  getRecipientPath,\n  hasLocalVault,\n  hasGlobalVault,\n} from '../config/paths';\nimport { AgeProvider } from '../encryption/age';\nimport * as output from '../utils/output';\n\ninterface ConfigOptions {\n  show?: boolean;\n  set?: string;\n  path?: boolean;\n}\n\nexport async function configCommand(options: ConfigOptions): Promise<void> {\n  if (options.path) {\n    // Show config file path\n    const configPath = await getActiveConfigPath();\n    console.log(configPath);\n    return;\n  }\n\n  if (options.set) {\n    // Set a config value\n    await setConfigValue(options.set);\n    return;\n  }\n\n  // Default: show config\n  await showConfig();\n}\n\nasync function showConfig(): Promise<void> {\n  const config = await loadConfig();\n\n  const hasLocal = await hasLocalVault();\n  const hasGlobal = await hasGlobalVault();\n\n  console.log('');\n  console.log(output.colors.highlight('SecretSage Configuration'));\n  console.log('');\n\n  output.divider();\n\n  // Vault status\n  console.log(output.colors.muted('Vault:'));\n  if (hasLocal) {\n    output.keyValue('  Location', 'Local (.secretsage/)');\n    output.keyValue('  Path', getLocalDir());\n  } else if (hasGlobal) {\n    output.keyValue('  Location', 'Global (~/.secretsage/)');\n    output.keyValue('  Path', getGlobalDir());\n  } else {\n    output.keyValue('  Status', output.colors.warning('Not initialized'));\n    console.log('');\n    output.info('Run `secretsage init` to create a vault.');\n    return;\n  }\n\n  // Public key\n  try {\n    const ageProvider = new AgeProvider();\n    const recipientPath = hasLocal ? getRecipientPath(true) : getRecipientPath(false);\n\n    if (await fs.pathExists(recipientPath)) {\n      const publicKey = await ageProvider.loadRecipient(recipientPath);\n      output.keyValue('  Public key', publicKey);\n    }\n  } catch {\n    // Ignore errors\n  }\n\n  console.log('');\n\n  // Encryption\n  console.log(output.colors.muted('Encryption:'));\n  output.keyValue('  Provider', config.encryption.provider);\n\n  console.log('');\n\n  // Agent settings\n  console.log(output.colors.muted('Agent:'));\n  output.keyValue('  Auto gitignore', config.agent.autoGitignore ? 'Yes' : 'No');\n  output.keyValue('  Backup .env', config.agent.backupEnvOnGrant ? 'Yes' : 'No');\n  output.keyValue('  Require confirm', config.agent.requireConfirmation ? 'Yes' : 'No');\n\n  output.divider();\n  console.log('');\n}\n\nasync function setConfigValue(keyValue: string): Promise<void> {\n  const [key, ...valueParts] = keyValue.split('=');\n  const value = valueParts.join('=');\n\n  if (!key || value === undefined) {\n    output.error('Invalid format. Use: secretsage config --set key=value');\n    process.exit(1);\n  }\n\n  const config = await loadConfig();\n\n  // Parse the key path (e.g., 'agent.autoGitignore')\n  const keys = key.split('.');\n\n  // Navigate to the right config level\n  let current: Record<string, unknown> = config as unknown as Record<string, unknown>;\n\n  for (let i = 0; i < keys.length - 1; i++) {\n    const k = keys[i];\n    if (!(k in current) || typeof current[k] !== 'object') {\n      output.error(`Unknown config key: ${key}`);\n      process.exit(1);\n    }\n    current = current[k] as Record<string, unknown>;\n  }\n\n  const finalKey = keys[keys.length - 1];\n\n  if (!(finalKey in current)) {\n    output.error(`Unknown config key: ${key}`);\n    process.exit(1);\n  }\n\n  // Parse value\n  let parsedValue: unknown = value;\n  if (value === 'true') parsedValue = true;\n  else if (value === 'false') parsedValue = false;\n  else if (!isNaN(Number(value))) parsedValue = Number(value);\n\n  current[finalKey] = parsedValue;\n\n  // Determine if local or global\n  const isLocal = await hasLocalVault();\n\n  // Save updated config\n  await saveConfig(config, isLocal);\n\n  output.success(`Set ${key} = ${String(parsedValue)}`);\n}\n","/**\n * Remove Command\n *\n * Delete a credential from the vault permanently.\n */\n\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\nimport { confirm } from '../utils/prompts';\n\ninterface RemoveOptions {\n  yes?: boolean;\n  quiet?: boolean;\n}\n\nexport async function removeCommand(name: string, options: RemoveOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  // Check credential exists\n  const credential = await service.get(name);\n  if (!credential) {\n    output.error(`Credential \"${name}\" not found in vault.`);\n    const list = await service.list();\n    if (list.length > 0) {\n      output.info('Available credentials:');\n      list.forEach((c) => console.log(`  ${c.name}`));\n    }\n    process.exit(1);\n  }\n\n  // Confirm deletion\n  if (!options.yes) {\n    const confirmed = await confirm(\n      `Are you sure you want to permanently delete \"${name}\"?`\n    );\n    if (!confirmed) {\n      output.info('Cancelled.');\n      return;\n    }\n  }\n\n  // Delete from vault\n  const spin = options.quiet ? null : output.spinner(`Removing ${name}...`);\n  spin?.start();\n\n  try {\n    const deleted = await service.delete(name);\n    spin?.stop();\n\n    if (deleted) {\n      if (!options.quiet) {\n        output.success(`Credential \"${name}\" removed from vault.`);\n      }\n    } else {\n      output.error(`Failed to remove \"${name}\".`);\n      process.exit(1);\n    }\n  } catch (error) {\n    spin?.fail(`Failed to remove ${name}`);\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","/**\n * Rotate Command\n *\n * Update the value of an existing credential.\n */\n\nimport * as crypto from 'crypto';\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\nimport { promptCredentialValue, confirm } from '../utils/prompts';\n\ninterface RotateOptions {\n  value?: string;\n  generate?: string;\n  reason?: string;\n  yes?: boolean;\n  quiet?: boolean;\n}\n\n/**\n * Read value from stdin (for piped input)\n */\nasync function readStdin(): Promise<string> {\n  return new Promise((resolve, reject) => {\n    let data = '';\n    process.stdin.setEncoding('utf8');\n    process.stdin.on('data', (chunk) => { data += chunk; });\n    process.stdin.on('end', () => { resolve(data.trim()); });\n    process.stdin.on('error', reject);\n\n    // Handle case where stdin is a TTY (not piped)\n    if (process.stdin.isTTY) {\n      reject(new Error('No input provided via stdin. Use --value with a value or omit to use interactive prompt.'));\n    }\n  });\n}\n\nexport async function rotateCommand(name: string, options: RotateOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  // Check credential exists\n  const credential = await service.get(name);\n  if (!credential) {\n    output.error(`Credential \"${name}\" not found in vault.`);\n    const list = await service.list();\n    if (list.length > 0) {\n      output.info('Available credentials:');\n      list.forEach((c) => console.log(`  ${c.name}`));\n    }\n    process.exit(1);\n  }\n\n  // Get new value\n  let newValue: string;\n\n  if (options.generate) {\n    // Generate random bytes\n    const bytes = parseInt(options.generate, 10);\n    if (isNaN(bytes) || bytes < 1 || bytes > 256) {\n      output.error('--generate must be a number between 1 and 256 (bytes)');\n      process.exit(1);\n    }\n    newValue = crypto.randomBytes(bytes).toString('hex');\n    if (!options.quiet) {\n      output.info(`Generated ${bytes}-byte (${bytes * 2} hex chars) random value`);\n    }\n  } else if (options.value === '-') {\n    // Read from stdin\n    try {\n      newValue = await readStdin();\n      if (!newValue) {\n        output.error('Empty input received from stdin.');\n        process.exit(1);\n      }\n    } catch (error) {\n      output.error((error as Error).message);\n      process.exit(1);\n    }\n  } else if (options.value) {\n    newValue = options.value;\n  } else {\n    // Prompt for new value\n    newValue = await promptCredentialValue(name);\n  }\n\n  // Confirm rotation\n  if (!options.yes) {\n    const confirmed = await confirm(\n      `Are you sure you want to rotate \"${name}\"?`\n    );\n    if (!confirmed) {\n      output.info('Cancelled.');\n      return;\n    }\n  }\n\n  // Update in vault\n  const spin = options.quiet ? null : output.spinner(`Rotating ${name}...`);\n  spin?.start();\n\n  try {\n    // Pass rotation reason in metadata\n    const metadata = options.reason\n      ? { rotationHistory: [{ timestamp: new Date(), reason: options.reason }] }\n      : undefined;\n    await service.add(name, newValue, metadata);\n    spin?.stop();\n\n    if (!options.quiet) {\n      const vaultPath = await service.getVaultPath();\n      output.credentialSaved(name, vaultPath);\n      if (options.reason) {\n        output.info(`Rotation reason: ${options.reason}`);\n      }\n      output.info('Credential rotated. Run `secretsage grant` to update .env');\n    }\n  } catch (error) {\n    spin?.fail(`Failed to rotate ${name}`);\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","/**\n * Export Command\n *\n * Export vault credentials for backup or transfer.\n */\n\nimport * as fs from 'fs-extra';\nimport { CredentialService } from '../core/service';\nimport { loadConfig } from '../config/loader';\nimport * as output from '../utils/output';\nimport { confirm } from '../utils/prompts';\n\ninterface ExportOptions {\n  output?: string;\n  format?: 'json' | 'env';\n  keys?: string;\n  encrypted?: boolean;\n  quiet?: boolean;\n  yes?: boolean;\n}\n\nexport async function exportCommand(options: ExportOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  const credentials = await service.list();\n  if (credentials.length === 0) {\n    output.warning('No credentials in vault to export.');\n    process.exit(0);\n  }\n\n  let exportContent: string;\n  const format = options.format || 'json';\n\n  if (options.encrypted) {\n    // Export encrypted vault\n    const vaultPath = await service.getVaultPath();\n    const vaultFile = `${vaultPath}/vault.json`;\n\n    if (await fs.pathExists(vaultFile)) {\n      const vaultContent = await fs.readFile(vaultFile, 'utf8');\n      let vaultData = JSON.parse(vaultContent);\n\n      // Filter by keys if specified\n      if (options.keys) {\n        const keysToExport = options.keys.split(',').map((k) => k.trim());\n        vaultData = vaultData.filter((entry: { name: string }) => keysToExport.includes(entry.name));\n\n        // Warn about missing keys\n        const foundNames = new Set(vaultData.map((e: { name: string }) => e.name));\n        const missingKeys = keysToExport.filter((k) => !foundNames.has(k));\n        if (missingKeys.length > 0 && !options.quiet) {\n          output.warning(`Keys not found: ${missingKeys.join(', ')}`);\n        }\n\n        if (vaultData.length === 0) {\n          output.error('No matching credentials found.');\n          process.exit(1);\n        }\n      }\n\n      exportContent = JSON.stringify(vaultData, null, 2) + '\\n';\n    } else {\n      output.error('Vault file not found.');\n      process.exit(1);\n    }\n\n    if (!options.quiet && !options.output) {\n      output.warning('Exporting encrypted vault (credentials remain encrypted)');\n    }\n  } else {\n    // Decrypt and export - requires confirmation for security\n    const config = await loadConfig();\n    const trustedMode = config.agent?.trustedMode === true;\n\n    // Security: require interactive confirmation unless trustedMode is enabled\n    if (!trustedMode) {\n      if (options.yes) {\n        output.error('--yes flag requires agent.trustedMode: true in config.');\n        output.info('This protects against agents exfiltrating credentials.');\n        output.info('Run: secretsage config --set agent.trustedMode=true');\n        process.exit(1);\n      }\n\n      // Force interactive confirmation\n      output.warning('⚠️  SECURITY WARNING: This will expose ALL decrypted credentials.');\n      const confirmed = await confirm('Export all credentials? This cannot be undone.');\n      if (!confirmed) {\n        output.info('Export cancelled.');\n        process.exit(0);\n      }\n    }\n\n    const allDecrypted = await service.getAll();\n\n    // Filter by keys if specified\n    let decrypted = allDecrypted;\n    if (options.keys) {\n      const keysToExport = options.keys.split(',').map((k) => k.trim());\n      decrypted = allDecrypted.filter((c) => keysToExport.includes(c.name));\n\n      // Warn about missing keys\n      const foundNames = new Set(decrypted.map((c) => c.name));\n      const missingKeys = keysToExport.filter((k) => !foundNames.has(k));\n      if (missingKeys.length > 0 && !options.quiet) {\n        output.warning(`Keys not found: ${missingKeys.join(', ')}`);\n      }\n\n      if (decrypted.length === 0) {\n        output.error('No matching credentials found.');\n        process.exit(1);\n      }\n    }\n\n    if (!options.quiet && !options.output) {\n      output.warning('Exporting DECRYPTED credentials. Handle with care!');\n    }\n\n    if (format === 'env') {\n      // Export as .env format\n      exportContent = decrypted\n        .map((c) => {\n          const needsQuotes = /[\\s#\"'\\\\]/.test(c.value) || c.value.includes('=');\n          const quotedValue = needsQuotes ? `\"${c.value.replace(/\"/g, '\\\\\"')}\"` : c.value;\n          return `${c.name}=${quotedValue}`;\n        })\n        .join('\\n') + '\\n';\n    } else {\n      // Export as JSON\n      exportContent = JSON.stringify(\n        decrypted.map((c) => ({\n          name: c.name,\n          value: c.value,\n          createdAt: c.metadata?.createdAt,\n          updatedAt: c.metadata?.updatedAt,\n        })),\n        null,\n        2\n      ) + '\\n';\n    }\n  }\n\n  // Output\n  if (options.output) {\n    await fs.writeFile(options.output, exportContent, { mode: 0o600 });\n    if (!options.quiet) {\n      output.success(`Exported ${credentials.length} credentials to ${options.output}`);\n    }\n  } else {\n    // Write to stdout\n    process.stdout.write(exportContent);\n  }\n}\n","/**\n * Import Command\n *\n * Import credentials from backup or external source.\n */\n\nimport * as fs from 'fs-extra';\nimport { parse as parseEnv } from 'dotenv';\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\nimport { confirm } from '../utils/prompts';\n\ninterface ImportOptions {\n  input?: string;\n  format?: 'json' | 'env';\n  merge?: boolean;\n  yes?: boolean;\n  quiet?: boolean;\n}\n\n/**\n * Read from stdin\n */\nasync function readStdin(): Promise<string> {\n  return new Promise((resolve, reject) => {\n    let data = '';\n    process.stdin.setEncoding('utf8');\n    process.stdin.on('data', (chunk) => { data += chunk; });\n    process.stdin.on('end', () => { resolve(data); });\n    process.stdin.on('error', reject);\n\n    if (process.stdin.isTTY) {\n      reject(new Error('No input provided via stdin. Use --input to specify a file.'));\n    }\n  });\n}\n\ninterface ImportedCredential {\n  name: string;\n  value: string;\n}\n\nexport async function importCommand(options: ImportOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  // Read input\n  let content: string;\n  if (options.input) {\n    if (!(await fs.pathExists(options.input))) {\n      output.error(`File not found: ${options.input}`);\n      process.exit(1);\n    }\n    content = await fs.readFile(options.input, 'utf8');\n  } else {\n    try {\n      content = await readStdin();\n    } catch (error) {\n      output.error((error as Error).message);\n      process.exit(1);\n    }\n  }\n\n  if (!content.trim()) {\n    output.error('Empty input.');\n    process.exit(1);\n  }\n\n  // Parse credentials\n  let credentials: ImportedCredential[] = [];\n  const format = options.format || 'json';\n\n  try {\n    if (format === 'env') {\n      const parsed = parseEnv(content);\n      credentials = Object.entries(parsed).map(([name, value]) => ({ name, value }));\n    } else {\n      const parsed = JSON.parse(content);\n      if (Array.isArray(parsed)) {\n        credentials = parsed.map((item) => ({\n          name: item.name,\n          value: item.value,\n        }));\n      } else {\n        output.error('Invalid JSON format. Expected array of {name, value} objects.');\n        process.exit(1);\n      }\n    }\n  } catch (error) {\n    output.error(`Failed to parse ${format} input: ${(error as Error).message}`);\n    process.exit(1);\n  }\n\n  if (credentials.length === 0) {\n    output.warning('No credentials found in input.');\n    process.exit(0);\n  }\n\n  // Check for existing credentials\n  const existing = await service.list();\n  const existingNames = new Set(existing.map((c) => c.name));\n  const newCreds = credentials.filter((c) => !existingNames.has(c.name));\n  const updateCreds = credentials.filter((c) => existingNames.has(c.name));\n\n  if (!options.quiet) {\n    output.info(`Found ${credentials.length} credentials to import:`);\n    output.info(`  New: ${newCreds.length}`);\n    output.info(`  Update: ${updateCreds.length}`);\n  }\n\n  // Confirm import\n  if (!options.yes) {\n    const action = options.merge ? 'merge into' : 'import into';\n    const confirmed = await confirm(\n      `${action} vault? ${updateCreds.length > 0 ? `(${updateCreds.length} existing will be overwritten)` : ''}`\n    );\n    if (!confirmed) {\n      output.info('Cancelled.');\n      return;\n    }\n  }\n\n  // Import credentials\n  const spin = options.quiet ? null : output.spinner('Importing credentials...');\n  spin?.start();\n\n  try {\n    let imported = 0;\n    for (const cred of credentials) {\n      if (!cred.name || typeof cred.value !== 'string') {\n        if (!options.quiet) {\n          output.warning(`Skipping invalid credential: ${JSON.stringify(cred)}`);\n        }\n        continue;\n      }\n\n      // Skip existing if not merging\n      if (!options.merge && existingNames.has(cred.name)) {\n        continue;\n      }\n\n      await service.add(cred.name, cred.value);\n      imported++;\n    }\n\n    spin?.stop();\n\n    if (!options.quiet) {\n      output.success(`Imported ${imported} credentials.`);\n    }\n  } catch (error) {\n    spin?.fail('Import failed');\n    output.error((error as Error).message);\n    process.exit(1);\n  }\n}\n","/**\n * Status Command\n *\n * Show vault status and health check.\n */\n\nimport * as fs from 'fs-extra';\nimport { parse as parseEnv } from 'dotenv';\nimport { CredentialService } from '../core/service';\nimport { getEnvPath, getLocalDir, getGlobalDir, hasLocalVault, hasGlobalVault } from '../config/paths';\nimport * as output from '../utils/output';\n\ninterface StatusOptions {\n  json?: boolean;\n}\n\ninterface StatusInfo {\n  vault: {\n    path: string;\n    type: 'local' | 'global' | 'custom' | 'none';\n    exists: boolean;\n  };\n  credentials: {\n    stored: number;\n    granted: number;\n    available: number;\n  };\n  env: {\n    path: string;\n    exists: boolean;\n  };\n}\n\nexport async function statusCommand(options: StatusOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Determine vault status\n  const hasLocal = await hasLocalVault();\n  const hasGlobal = await hasGlobalVault();\n\n  let vaultType: 'local' | 'global' | 'custom' | 'none' = 'none';\n  let vaultPath = '';\n  let vaultExists = false;\n\n  if (hasLocal) {\n    vaultType = 'local';\n    vaultPath = getLocalDir();\n    vaultExists = true;\n  } else if (hasGlobal) {\n    vaultType = 'global';\n    vaultPath = getGlobalDir();\n    vaultExists = true;\n  }\n\n  // Get credential counts\n  let storedCount = 0;\n  let grantedCount = 0;\n  const grantedNames: string[] = [];\n\n  if (vaultExists) {\n    await service.init();\n    const credentials = await service.list();\n    storedCount = credentials.length;\n\n    // Check .env for granted credentials\n    const envPath = getEnvPath();\n    if (await fs.pathExists(envPath)) {\n      const envContent = await fs.readFile(envPath, 'utf8');\n      const envVars = parseEnv(envContent);\n      const envNames = new Set(Object.keys(envVars));\n\n      for (const cred of credentials) {\n        if (envNames.has(cred.name)) {\n          grantedCount++;\n          grantedNames.push(cred.name);\n        }\n      }\n    }\n  }\n\n  const envPath = getEnvPath();\n  const envExists = await fs.pathExists(envPath);\n\n  const status: StatusInfo = {\n    vault: {\n      path: vaultPath,\n      type: vaultType,\n      exists: vaultExists,\n    },\n    credentials: {\n      stored: storedCount,\n      granted: grantedCount,\n      available: storedCount - grantedCount,\n    },\n    env: {\n      path: envPath,\n      exists: envExists,\n    },\n  };\n\n  if (options.json) {\n    console.log(JSON.stringify(status, null, 2));\n    return;\n  }\n\n  // Human-readable output\n  console.log('');\n  output.header('SecretSage Status');\n  output.divider();\n\n  if (!vaultExists) {\n    output.keyValue('Vault', output.colors.error('Not initialized'));\n    output.info('Run `secretsage init` to create a vault.');\n    console.log('');\n    return;\n  }\n\n  // Vault info\n  const vaultTypeLabel = vaultType === 'local' ? '(local)' : vaultType === 'global' ? '(global)' : '';\n  output.keyValue('Vault', `${vaultPath} ${output.colors.dim(vaultTypeLabel)}`);\n\n  // Credential counts\n  output.keyValue('Credentials', `${storedCount} stored`);\n\n  if (storedCount > 0) {\n    const grantedLabel = grantedCount > 0\n      ? output.colors.success(`${grantedCount} granted`)\n      : output.colors.dim('0 granted');\n    const availableLabel = (storedCount - grantedCount) > 0\n      ? output.colors.warning(`${storedCount - grantedCount} available`)\n      : output.colors.dim('0 available');\n    output.keyValue('.env', `${grantedLabel}, ${availableLabel}`);\n  }\n\n  output.divider();\n  console.log('');\n\n  // Hints\n  if (storedCount === 0) {\n    output.info('Add credentials with: secretsage add <NAME>');\n  } else if (grantedCount === 0) {\n    output.info('Grant credentials to .env with: secretsage grant --all');\n  } else if (grantedCount < storedCount) {\n    output.info(`${storedCount - grantedCount} credentials available to grant.`);\n  }\n}\n","/**\n * Audit Command\n *\n * Display rotation history and audit trail for a credential.\n */\n\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\n\ninterface AuditOptions {\n  json?: boolean;\n}\n\n/**\n * Format a date for display\n */\nfunction formatDate(date: Date | string | undefined): string {\n  if (!date) return 'Unknown';\n  const d = typeof date === 'string' ? new Date(date) : date;\n  return d.toLocaleString();\n}\n\nexport async function auditCommand(name: string, options: AuditOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  // Get credential metadata\n  const credential = await service.get(name);\n  if (!credential) {\n    output.error(`Credential \"${name}\" not found in vault.`);\n    const list = await service.list();\n    if (list.length > 0) {\n      output.info('Available credentials:');\n      list.forEach((c) => console.log(`  ${c.name}`));\n    }\n    process.exit(1);\n  }\n\n  const metadata = credential.metadata;\n\n  // Get access log\n  const accessLog = await service.getAccessLog(name);\n\n  if (options.json) {\n    // Machine-readable output\n    output.jsonOutput({\n      name,\n      createdAt: metadata?.createdAt,\n      updatedAt: metadata?.updatedAt,\n      rotationCount: metadata?.rotationHistory?.length || 0,\n      rotationHistory: metadata?.rotationHistory || [],\n      accessCount: accessLog.length,\n      accessLog,\n    });\n    return;\n  }\n\n  // Human-readable output\n  console.log('');\n  output.header(name);\n  output.divider();\n  output.keyValue('Created', formatDate(metadata?.createdAt));\n  output.keyValue('Last updated', formatDate(metadata?.updatedAt));\n\n  const rotations = metadata?.rotationHistory || [];\n  output.keyValue('Total rotations', String(rotations.length));\n\n  if (rotations.length > 0) {\n    console.log('');\n    output.header('Rotation History');\n    output.divider();\n\n    // Show rotations in reverse chronological order (most recent first)\n    const sortedRotations = [...rotations].reverse();\n    sortedRotations.forEach((event, index) => {\n      const num = rotations.length - index;\n      const timestamp = formatDate(event.timestamp);\n      const reason = event.reason || 'No reason provided';\n      console.log(`  ${output.colors.muted(`#${num}`)} ${timestamp}`);\n      console.log(`     ${output.colors.dim('Reason:')} ${reason}`);\n    });\n  } else {\n    console.log('');\n    output.info('No rotation history. This credential has not been rotated.');\n  }\n\n  // Show access log\n  if (accessLog.length > 0) {\n    console.log('');\n    output.header('Recent Access Log');\n    output.divider();\n    output.keyValue('Total accesses', String(accessLog.length));\n    console.log('');\n\n    // Show last 10 accesses in reverse chronological order\n    const recentAccesses = [...accessLog].reverse().slice(0, 10);\n    recentAccesses.forEach((entry) => {\n      const timestamp = formatDate(entry.timestamp);\n      const actionColor = entry.action === 'grant' ? output.colors.warning : output.colors.muted;\n      console.log(`  ${timestamp}  ${actionColor(entry.action)}`);\n    });\n\n    if (accessLog.length > 10) {\n      console.log(`  ${output.colors.dim(`... and ${accessLog.length - 10} more`)}`);\n    }\n  } else {\n    console.log('');\n    output.info('No access log. This credential has not been accessed yet.');\n  }\n\n  console.log('');\n}\n","/**\n * Wizard Command\n *\n * Spawn a new terminal for interactive key entry.\n * Enables agent-human handoff for credential rotation.\n */\n\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as crypto from 'crypto';\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\nimport { spawnTerminal, waitForSignalFile, findTerminal, isValidPath, isHeadless } from '../wizard/terminal';\n\ninterface WizardOptions {\n  keys: string;\n  reason?: string;\n  timeout?: string;\n  noWait?: boolean;\n  inline?: boolean;\n}\n\n/**\n * Generate secure paths for wizard communication\n * Uses cryptographically random suffix instead of predictable PID\n */\nasync function getWizardPaths(): Promise<{ tmpDir: string; configPath: string; signalPath: string }> {\n  // Use cryptographically secure random suffix\n  const randomSuffix = crypto.randomBytes(16).toString('hex');\n  const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'secretsage-wizard-'));\n\n  // Set restrictive permissions on temp directory\n  await fs.chmod(tmpDir, 0o700);\n\n  return {\n    tmpDir,\n    configPath: path.join(tmpDir, `config-${randomSuffix}.json`),\n    signalPath: path.join(tmpDir, `signal-${randomSuffix}.done`),\n  };\n}\n\nexport async function wizardCommand(options: WizardOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  // Parse keys\n  const keys = options.keys.split(',').map((k) => k.trim()).filter(Boolean);\n  if (keys.length === 0) {\n    output.error('No keys specified. Use --keys KEY1,KEY2,...');\n    process.exit(1);\n  }\n\n  // Determine if we should run inline\n  const headless = isHeadless();\n  const runInline = options.inline || headless;\n\n  if (runInline) {\n    // Run wizard UI directly in current terminal\n    if (headless && !options.inline) {\n      output.warning('Headless environment detected (no DISPLAY). Running inline.');\n    }\n    output.info(`Starting inline wizard for ${keys.length} key(s)...`);\n    if (options.reason) {\n      output.keyValue('Reason', options.reason);\n    }\n    output.divider();\n\n    // Import and run wizard UI directly\n    const { runWizardUI } = await import('../wizard/ui');\n    await runWizardUI({\n      keys,\n      reason: options.reason,\n      signalPath: undefined, // No signal file needed for inline mode\n    });\n    return;\n  }\n\n  // Check terminal availability for GUI mode\n  const terminal = await findTerminal();\n  if (!terminal) {\n    output.error('No terminal emulator found.');\n    output.info('');\n    output.info('Options:');\n    output.info('  1. Install: gnome-terminal, konsole, xterm, or xfce4-terminal');\n    output.info('  2. Use inline mode: secretsage wizard --keys KEY1,KEY2 --inline');\n    output.info('  3. Add keys manually: secretsage add KEY1 --value \"...\"');\n    process.exit(1);\n  }\n\n  // Generate secure paths\n  const { tmpDir, configPath, signalPath } = await getWizardPaths();\n\n  // Write config for wizard UI with secure permissions\n  const config = {\n    keys,\n    reason: options.reason,\n    signalPath,\n  };\n  await fs.writeFile(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });\n\n  output.info(`Starting wizard for ${keys.length} key(s)...`);\n  if (options.reason) {\n    output.keyValue('Reason', options.reason);\n  }\n  output.divider();\n\n  // Spawn wizard in new terminal\n  try {\n    // Get the path to the CLI and the running node binary\n    // Use process.argv[1] since __dirname is wrong in bundled code\n    const cliPath = process.argv[1]; // The CLI script that's currently running\n    const nodePath = process.execPath; // Use the same node that's running us\n\n    await spawnTerminal(nodePath, [cliPath, 'wizard-ui', '--config', configPath]);\n\n    output.info('Wizard opened in new terminal window.');\n\n    if (options.noWait) {\n      output.info('Running in no-wait mode. Check signal file when done:');\n      console.log(`  ${signalPath}`);\n      return;\n    }\n\n    // Wait for completion\n    output.info('Waiting for wizard to complete...');\n    output.info('(Press Ctrl+C to stop waiting)');\n\n    const timeoutMs = options.timeout ? parseInt(options.timeout, 10) * 1000 : 300000;\n    const result = await waitForSignalFile(signalPath, timeoutMs);\n\n    // Clean up entire temp directory\n    await fs.remove(tmpDir);\n\n    if (result.success) {\n      output.success('Wizard completed successfully!');\n      output.info('Keys have been saved to the vault.');\n      output.info('Run `secretsage grant --all` to update .env');\n    } else {\n      output.warning(`Wizard did not complete: ${result.error}`);\n      process.exit(1);\n    }\n\n  } catch (error) {\n    // Clean up entire temp directory on error\n    await fs.remove(tmpDir).catch(() => {});\n\n    const errorMsg = error instanceof Error ? error.message : 'Unknown error';\n    output.error(`Failed to start wizard: ${errorMsg}`);\n    output.info('');\n    output.info('Try running with --inline flag:');\n    output.info(`  secretsage wizard --keys \"${options.keys}\" --inline`);\n    process.exit(1);\n  }\n}\n\n/**\n * Wizard UI command - runs in the spawned terminal\n */\ninterface WizardUIOptions {\n  config: string;\n}\n\nexport async function wizardUICommand(options: WizardUIOptions): Promise<void> {\n  // Import dynamically to avoid loading UI deps in main process\n  const { runWizardUI } = await import('../wizard/ui');\n\n  if (!options.config) {\n    console.error('Error: --config is required');\n    process.exit(1);\n  }\n\n  // Validate config path is within system temp directory (security)\n  const resolvedPath = path.resolve(options.config);\n  if (!isValidPath(resolvedPath, [os.tmpdir()])) {\n    console.error('Error: Config file must be in system temp directory');\n    process.exit(1);\n  }\n\n  try {\n    const configContent = await fs.readFile(options.config, 'utf8');\n    const config = JSON.parse(configContent);\n\n    // Validate config structure\n    if (!config.keys || !Array.isArray(config.keys)) {\n      throw new Error('Invalid config: missing keys array');\n    }\n    if (!config.signalPath || typeof config.signalPath !== 'string') {\n      throw new Error('Invalid config: missing signalPath');\n    }\n\n    await runWizardUI(config);\n\n  } catch (error) {\n    console.error('Error: Failed to run wizard');\n    process.exit(1);\n  }\n}\n","/**\n * Terminal Spawning Utilities\n *\n * Detect and spawn new terminal windows for wizard UI.\n */\n\nimport { spawn } from 'child_process';\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport * as os from 'os';\n\n/**\n * Validate that a path is safe (no traversal, within expected dirs)\n */\nexport function isValidPath(filePath: string, allowedDirs: string[]): boolean {\n  const resolved = path.resolve(filePath);\n  const normalized = path.normalize(resolved);\n\n  // Check for path traversal attempts\n  if (normalized.includes('..')) {\n    return false;\n  }\n\n  // Check if path is within allowed directories\n  return allowedDirs.some(dir => normalized.startsWith(path.resolve(dir)));\n}\n\n/**\n * Sanitize argument for shell safety - reject dangerous characters\n */\nfunction sanitizeArg(arg: string): string {\n  // Allow safe characters: word chars, hyphens, dots, slashes, equals, and @ (for scoped npm packages)\n  if (!/^[\\w\\-\\.\\/=@]+$/.test(arg)) {\n    throw new Error(`Invalid argument contains unsafe characters: ${arg.substring(0, 20)}...`);\n  }\n  return arg;\n}\n\n/**\n * Terminal emulators to try, in order of preference\n * Each entry specifies how to run a command in that terminal\n */\nconst TERMINAL_COMMANDS = [\n  // Linux GUI terminals\n  { cmd: 'gnome-terminal', args: ['--wait', '--'], wrapInBash: false },\n  { cmd: 'konsole', args: ['--hold', '-e'], wrapInBash: false },\n  { cmd: 'xfce4-terminal', args: ['--hold', '-e'], wrapInBash: true },\n  { cmd: 'xterm', args: ['-hold', '-e'], wrapInBash: false },\n  { cmd: 'x-terminal-emulator', args: ['-e'], wrapInBash: true },\n  // macOS\n  { cmd: 'open', args: ['-a', 'Terminal'], wrapInBash: false },\n];\n\n/**\n * Check if a command exists in PATH\n */\nasync function commandExists(cmd: string): Promise<boolean> {\n  return new Promise((resolve) => {\n    const which = spawn('which', [cmd]);\n    which.on('close', (code) => resolve(code === 0));\n    which.on('error', () => resolve(false));\n  });\n}\n\n/**\n * Find available terminal emulator\n */\nexport async function findTerminal(): Promise<{ cmd: string; args: string[]; wrapInBash: boolean } | null> {\n  for (const terminal of TERMINAL_COMMANDS) {\n    if (await commandExists(terminal.cmd)) {\n      return terminal;\n    }\n  }\n  return null;\n}\n\n/**\n * Check if we're running in a headless environment\n */\nexport function isHeadless(): boolean {\n  // No display available\n  if (!process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) {\n    return true;\n  }\n  // SSH session without X forwarding\n  if (process.env.SSH_TTY && !process.env.DISPLAY) {\n    return true;\n  }\n  // Docker/container often has no GUI\n  if (fs.existsSync('/.dockerenv')) {\n    return true;\n  }\n  return false;\n}\n\n/**\n * Spawn a new terminal window running a command\n */\nexport async function spawnTerminal(\n  command: string,\n  args: string[]\n): Promise<{ pid: number; waitForExit: () => Promise<number> }> {\n  const terminal = await findTerminal();\n\n  if (!terminal) {\n    throw new Error(\n      'No terminal emulator found. Install gnome-terminal, konsole, xterm, or xfce4-terminal.'\n    );\n  }\n\n  // Validate and sanitize all arguments to prevent injection\n  const safeCommand = sanitizeArg(command);\n  const safeArgs = args.map(arg => {\n    // Config paths must be in temp directory\n    if (arg.startsWith('--config=') || arg.startsWith('--config')) {\n      const configPath = arg.includes('=') ? arg.split('=')[1] : args[args.indexOf(arg) + 1];\n      if (configPath && !isValidPath(configPath, [os.tmpdir()])) {\n        throw new Error('Config path must be in system temp directory');\n      }\n    }\n    return sanitizeArg(arg);\n  });\n\n  // Build the full command\n  let termArgs: string[];\n  let proc;\n\n  if (terminal.cmd === 'gnome-terminal') {\n    // gnome-terminal with --wait: blocks until command finishes\n    // Wrap in bash to ensure proper argument handling\n    const fullCmd = [safeCommand, ...safeArgs].join(' ');\n    termArgs = [...terminal.args, 'bash', '-c', fullCmd];\n    proc = spawn(terminal.cmd, termArgs, {\n      detached: true,\n      stdio: 'ignore',\n    });\n  } else if (terminal.cmd === 'open') {\n    // macOS - use osascript with proper escaping\n    const script = `tell application \"Terminal\" to do script \"${safeCommand} ${safeArgs.join(' ')}\"`;\n    proc = spawn('osascript', ['-e', script], {\n      detached: true,\n      stdio: 'ignore',\n    });\n  } else if (terminal.wrapInBash) {\n    // Some terminals need the command wrapped in bash\n    const fullCmd = [safeCommand, ...safeArgs].join(' ');\n    termArgs = [...terminal.args, 'bash', '-c', fullCmd];\n    proc = spawn(terminal.cmd, termArgs, {\n      detached: true,\n      stdio: 'ignore',\n    });\n  } else {\n    // Other terminals: pass command and args directly\n    termArgs = [...terminal.args, safeCommand, ...safeArgs];\n    proc = spawn(terminal.cmd, termArgs, {\n      detached: true,\n      stdio: 'ignore',\n    });\n  }\n\n  // Allow the terminal to run independently\n  proc.unref();\n\n  return {\n    pid: proc.pid || 0,\n    waitForExit: () =>\n      new Promise((resolve) => {\n        proc.on('close', (code) => resolve(code || 0));\n        proc.on('error', () => resolve(1));\n      }),\n  };\n}\n\n/**\n * Wait for a signal file to exist\n */\nexport async function waitForSignalFile(\n  signalPath: string,\n  timeoutMs: number = 300000 // 5 minutes default\n): Promise<{ success: boolean; error?: string }> {\n  const startTime = Date.now();\n  const pollInterval = 500; // Check every 500ms\n\n  while (Date.now() - startTime < timeoutMs) {\n    if (await fs.pathExists(signalPath)) {\n      // Read signal file content\n      try {\n        const content = await fs.readFile(signalPath, 'utf8');\n        const signal = JSON.parse(content);\n\n        // Clean up signal file\n        await fs.remove(signalPath);\n\n        if (signal.success) {\n          return { success: true };\n        } else {\n          return { success: false, error: signal.error || 'Wizard cancelled' };\n        }\n      } catch {\n        // File exists but invalid - assume success\n        await fs.remove(signalPath);\n        return { success: true };\n      }\n    }\n\n    // Wait before next poll\n    await new Promise((resolve) => setTimeout(resolve, pollInterval));\n  }\n\n  return { success: false, error: 'Timeout waiting for wizard completion' };\n}\n","/**\n * Deploy Command\n *\n * Deploy secrets to remote servers via rsync/SSH.\n */\n\nimport { spawn } from 'child_process';\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport { CredentialService } from '../core/service';\nimport { getEnvPath } from '../config/paths';\nimport * as output from '../utils/output';\nimport { confirm } from '../utils/prompts';\n\ninterface DeployOptions {\n  remote: string;\n  file?: string;\n  restart?: string;\n  yes?: boolean;\n}\n\n/**\n * Allowed restart command patterns (whitelist for security)\n * Only these patterns are allowed to prevent command injection\n */\nconst ALLOWED_RESTART_PATTERNS = [\n  /^pm2 restart [\\w\\-]+$/,                    // pm2 restart app-name\n  /^pm2 reload [\\w\\-]+$/,                     // pm2 reload app-name\n  /^systemctl restart [\\w\\-\\.]+$/,            // systemctl restart service\n  /^systemctl reload [\\w\\-\\.]+$/,             // systemctl reload service\n  /^docker restart [\\w\\-]+$/,                 // docker restart container\n  /^docker-compose restart$/,                 // docker-compose restart\n  /^docker-compose up -d$/,                   // docker-compose up -d\n  /^supervisorctl restart [\\w\\-:]+$/,         // supervisorctl restart process\n  /^service [\\w\\-]+ restart$/,                // service name restart\n];\n\n/**\n * Validate restart command against whitelist\n */\nfunction isValidRestartCommand(cmd: string): boolean {\n  return ALLOWED_RESTART_PATTERNS.some(pattern => pattern.test(cmd.trim()));\n}\n\n/**\n * Parse remote string into components\n * Format: user@host:path or host:path\n */\nfunction parseRemote(remote: string): { user?: string; host: string; path: string } | null {\n  // Match user@host:path or host:path\n  const match = remote.match(/^(?:([^@]+)@)?([^:]+):(.+)$/);\n  if (!match) {\n    return null;\n  }\n  return {\n    user: match[1],\n    host: match[2],\n    path: match[3],\n  };\n}\n\n/**\n * Run a command and return its output\n */\nfunction runCommand(\n  cmd: string,\n  args: string[],\n  options?: { cwd?: string }\n): Promise<{ code: number; stdout: string; stderr: string }> {\n  return new Promise((resolve) => {\n    const proc = spawn(cmd, args, {\n      cwd: options?.cwd,\n      stdio: ['pipe', 'pipe', 'pipe'],\n    });\n\n    let stdout = '';\n    let stderr = '';\n\n    proc.stdout?.on('data', (data) => { stdout += data; });\n    proc.stderr?.on('data', (data) => { stderr += data; });\n\n    proc.on('close', (code) => {\n      resolve({ code: code || 0, stdout, stderr });\n    });\n\n    proc.on('error', (err) => {\n      resolve({ code: 1, stdout: '', stderr: err.message });\n    });\n  });\n}\n\n/**\n * Check if rsync is available\n */\nasync function hasRsync(): Promise<boolean> {\n  const result = await runCommand('which', ['rsync']);\n  return result.code === 0;\n}\n\nexport async function deployCommand(project: string, options: DeployOptions): Promise<void> {\n  const service = new CredentialService();\n\n  // Check vault exists\n  const vaults = await service.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  // Validate remote format\n  if (!options.remote) {\n    output.error('--remote is required. Format: user@host:/path/to/destination');\n    process.exit(1);\n  }\n\n  const remote = parseRemote(options.remote);\n  if (!remote) {\n    output.error('Invalid remote format. Use: user@host:/path or host:/path');\n    process.exit(1);\n  }\n\n  // Check rsync availability\n  if (!await hasRsync()) {\n    output.error('rsync is required but not found in PATH.');\n    output.info('Install rsync: apt install rsync (Ubuntu) or brew install rsync (macOS)');\n    process.exit(1);\n  }\n\n  await service.init();\n\n  // Get local env file path\n  const localEnvPath = options.file || getEnvPath();\n\n  // Show deployment plan\n  output.header(`Deploy: ${project}`);\n  output.divider();\n  output.keyValue('Local file', localEnvPath);\n  output.keyValue('Remote', options.remote);\n  if (options.restart) {\n    output.keyValue('Post-deploy', options.restart);\n  }\n  output.divider();\n\n  // Check if env file exists, if not, grant all first\n  if (!await fs.pathExists(localEnvPath)) {\n    output.info('No .env file found. Granting all credentials...');\n    const list = await service.list();\n    if (list.length === 0) {\n      output.error('No credentials in vault to deploy.');\n      process.exit(1);\n    }\n    const names = list.map((c) => c.name);\n    await service.grant(names, { backup: true });\n    output.success(`Granted ${names.length} credentials to .env`);\n  }\n\n  // Show what will be deployed\n  const envContent = await fs.readFile(localEnvPath, 'utf8');\n  const envKeys = envContent\n    .split('\\n')\n    .filter((line) => line.includes('=') && !line.startsWith('#'))\n    .map((line) => line.split('=')[0]);\n\n  output.info(`Will deploy ${envKeys.length} environment variables:`);\n  envKeys.slice(0, 5).forEach((key) => {\n    console.log(`  ${output.colors.key(key)}`);\n  });\n  if (envKeys.length > 5) {\n    console.log(output.colors.muted(`  ... and ${envKeys.length - 5} more`));\n  }\n  console.log('');\n\n  // Confirm deployment\n  if (!options.yes) {\n    const confirmed = await confirm(`Deploy to ${remote.host}?`);\n    if (!confirmed) {\n      output.info('Deployment cancelled.');\n      return;\n    }\n  }\n\n  // Build rsync command\n  const remoteTarget = remote.user\n    ? `${remote.user}@${remote.host}:${remote.path}`\n    : `${remote.host}:${remote.path}`;\n\n  const spin = output.spinner('Deploying...');\n  spin.start();\n\n  // Run rsync\n  const rsyncResult = await runCommand('rsync', [\n    '-avz',\n    '--chmod=600',\n    localEnvPath,\n    remoteTarget,\n  ]);\n\n  if (rsyncResult.code !== 0) {\n    spin.fail('Deployment failed');\n    output.error(rsyncResult.stderr || 'rsync failed');\n    process.exit(1);\n  }\n\n  spin.succeed('Files synced');\n\n  // Run post-deploy command if specified\n  if (options.restart) {\n    // Validate restart command against whitelist to prevent command injection\n    if (!isValidRestartCommand(options.restart)) {\n      output.error('Invalid restart command. Allowed patterns:');\n      output.info('  pm2 restart <app>');\n      output.info('  pm2 reload <app>');\n      output.info('  systemctl restart <service>');\n      output.info('  docker restart <container>');\n      output.info('  docker-compose restart');\n      output.info('  supervisorctl restart <process>');\n      output.info('  service <name> restart');\n      process.exit(1);\n    }\n\n    const restartSpin = output.spinner(`Running: ${options.restart}`);\n    restartSpin.start();\n\n    const sshTarget = remote.user ? `${remote.user}@${remote.host}` : remote.host;\n    const sshResult = await runCommand('ssh', [sshTarget, options.restart]);\n\n    if (sshResult.code !== 0) {\n      restartSpin.fail('Post-deploy command failed');\n      output.warning(sshResult.stderr || 'Command failed');\n    } else {\n      restartSpin.succeed('Post-deploy command completed');\n      if (sshResult.stdout.trim()) {\n        console.log(output.colors.muted(sshResult.stdout.trim()));\n      }\n    }\n  }\n\n  console.log('');\n  output.success(`Deployed to ${remote.host}:${remote.path}`);\n}\n","/**\n * Backup Codes Command\n *\n * Securely store and manage 2FA recovery/backup codes.\n */\n\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { CredentialService } from '../core/service';\nimport * as output from '../utils/output';\nimport { confirm } from '../utils/prompts';\n\n/**\n * Generate credential name for backup codes\n */\nfunction getCredentialName(service: string, account?: string): string {\n  const normalized = service.toUpperCase().replace(/[^A-Z0-9]/g, '_');\n  if (account) {\n    const accountNorm = account.replace(/[^a-zA-Z0-9]/g, '_').toUpperCase();\n    return `BACKUP_CODES_${normalized}_${accountNorm}`;\n  }\n  return `BACKUP_CODES_${normalized}`;\n}\n\n/**\n * Parse stored backup codes\n */\nfunction parseCodes(value: string): { codes: string[]; usedIndices: number[] } {\n  try {\n    const data = JSON.parse(value);\n    return {\n      codes: data.codes || [],\n      usedIndices: data.usedIndices || [],\n    };\n  } catch {\n    // Legacy format: just newline-separated codes\n    return {\n      codes: value.split('\\n').filter(Boolean),\n      usedIndices: [],\n    };\n  }\n}\n\n/**\n * Serialize codes for storage\n */\nfunction serializeCodes(codes: string[], usedIndices: number[]): string {\n  return JSON.stringify({ codes, usedIndices });\n}\n\ninterface AddOptions {\n  account?: string;\n  quiet?: boolean;\n}\n\nexport async function backupCodesAddCommand(service: string, options: AddOptions): Promise<void> {\n  const svc = new CredentialService();\n\n  const vaults = await svc.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await svc.init();\n\n  const credName = getCredentialName(service, options.account);\n\n  // Check if already exists\n  const existing = await svc.get(credName);\n  if (existing) {\n    const overwrite = await confirm(`Backup codes for ${service} already exist. Overwrite?`);\n    if (!overwrite) {\n      output.info('Cancelled.');\n      return;\n    }\n  }\n\n  console.log('');\n  output.header(`Add Backup Codes: ${service}`);\n  if (options.account) {\n    output.keyValue('Account', options.account);\n  }\n  output.divider();\n  console.log(chalk.gray('  Enter your backup codes, one per line.'));\n  console.log(chalk.gray('  Press Enter twice when done.\\n'));\n\n  // Collect codes interactively\n  const codes: string[] = [];\n  let emptyCount = 0;\n\n  const readline = await import('readline');\n  const rl = readline.createInterface({\n    input: process.stdin,\n    output: process.stdout,\n  });\n\n  const askForCode = (): Promise<string> => {\n    return new Promise((resolve) => {\n      const num = codes.length + 1;\n      rl.question(chalk.cyan(`  Code ${num}: `), (answer) => {\n        resolve(answer.trim());\n      });\n    });\n  };\n\n  while (emptyCount < 1) {\n    const code = await askForCode();\n    if (code === '') {\n      emptyCount++;\n    } else {\n      emptyCount = 0;\n      codes.push(code);\n    }\n  }\n\n  rl.close();\n\n  if (codes.length === 0) {\n    output.error('No codes entered.');\n    process.exit(1);\n  }\n\n  // Store encrypted\n  const value = serializeCodes(codes, []);\n  const metadata = {\n    description: `Backup codes for ${service}${options.account ? ` (${options.account})` : ''}`,\n    tags: ['backup-codes', service.toLowerCase()],\n  };\n\n  const spin = output.spinner('Encrypting backup codes...');\n  spin.start();\n\n  await svc.add(credName, value, metadata);\n\n  spin.stop();\n\n  console.log('');\n  output.success(`Saved ${codes.length} backup codes for ${service}`);\n  output.info(`Retrieve with: secretsage backup-codes show ${service}`);\n  console.log('');\n}\n\ninterface ListOptions {\n  json?: boolean;\n}\n\nexport async function backupCodesListCommand(options: ListOptions): Promise<void> {\n  const svc = new CredentialService();\n\n  const vaults = await svc.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await svc.init();\n\n  const allCreds = await svc.list();\n  const backupCreds = allCreds.filter((c) => c.name.startsWith('BACKUP_CODES_'));\n\n  if (options.json) {\n    const services = backupCreds.map((c) => {\n      const parts = c.name.replace('BACKUP_CODES_', '').split('_');\n      // Try to detect if last part is account\n      return {\n        name: c.name,\n        service: parts[0].toLowerCase(),\n        account: parts.length > 1 ? parts.slice(1).join('_') : undefined,\n        addedAt: c.createdAt,\n      };\n    });\n    output.jsonOutput({ services, count: services.length });\n    return;\n  }\n\n  if (backupCreds.length === 0) {\n    output.info('No backup codes stored.');\n    output.info('Add with: secretsage backup-codes add <service>');\n    return;\n  }\n\n  console.log('');\n  output.header('Stored Backup Codes');\n  output.divider();\n\n  for (const cred of backupCreds) {\n    const servicePart = cred.name.replace('BACKUP_CODES_', '');\n    const parts = servicePart.split('_');\n    const service = parts[0].toLowerCase();\n    const account = parts.length > 1 ? parts.slice(1).join('_').toLowerCase() : null;\n\n    // Get the codes to show count\n    const full = await svc.get(cred.name);\n    if (full) {\n      const { codes, usedIndices } = parseCodes(full.value);\n      const remaining = codes.length - usedIndices.length;\n      const status = remaining === codes.length\n        ? chalk.green(`${codes.length} codes`)\n        : chalk.yellow(`${remaining}/${codes.length} remaining`);\n\n      console.log(`  ${chalk.cyan(service)}${account ? chalk.gray(` (${account})`) : ''}`);\n      console.log(`    ${status}`);\n    }\n  }\n\n  console.log('');\n}\n\ninterface ShowOptions {\n  account?: string;\n  yes?: boolean;\n}\n\nexport async function backupCodesShowCommand(service: string, options: ShowOptions): Promise<void> {\n  const svc = new CredentialService();\n\n  const vaults = await svc.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await svc.init();\n\n  const credName = getCredentialName(service, options.account);\n  const cred = await svc.get(credName);\n\n  if (!cred) {\n    output.error(`No backup codes found for ${service}`);\n    const allCreds = await svc.list();\n    const similar = allCreds.filter((c) =>\n      c.name.startsWith('BACKUP_CODES_') &&\n      c.name.toLowerCase().includes(service.toLowerCase())\n    );\n    if (similar.length > 0) {\n      output.info('Did you mean:');\n      similar.forEach((c) => console.log(`  ${c.name.replace('BACKUP_CODES_', '').toLowerCase()}`));\n    }\n    process.exit(1);\n  }\n\n  // Confirm before showing\n  if (!options.yes) {\n    console.log('');\n    output.warning('You are about to display sensitive backup codes.');\n    const confirmed = await confirm('Show backup codes on screen?');\n    if (!confirmed) {\n      output.info('Cancelled.');\n      return;\n    }\n  }\n\n  const { codes, usedIndices } = parseCodes(cred.value);\n\n  console.log('');\n  output.header(`Backup Codes: ${service}`);\n  if (options.account) {\n    output.keyValue('Account', options.account);\n  }\n  output.divider();\n\n  codes.forEach((code, i) => {\n    const num = String(i + 1).padStart(2, ' ');\n    if (usedIndices.includes(i)) {\n      console.log(chalk.gray(`  ${num}. ${chalk.strikethrough(code)} (used)`));\n    } else {\n      console.log(`  ${chalk.green(num)}. ${chalk.white(code)}`);\n    }\n  });\n\n  const remaining = codes.length - usedIndices.length;\n  console.log('');\n  output.info(`${remaining} of ${codes.length} codes remaining`);\n  console.log('');\n}\n\ninterface UseOptions {\n  account?: string;\n  index?: string;\n}\n\nexport async function backupCodesUseCommand(service: string, options: UseOptions): Promise<void> {\n  const svc = new CredentialService();\n\n  const vaults = await svc.hasVault();\n  if (!vaults.local && !vaults.global) {\n    output.error('No vault found. Run `secretsage init` first.');\n    process.exit(1);\n  }\n\n  await svc.init();\n\n  const credName = getCredentialName(service, options.account);\n  const cred = await svc.get(credName);\n\n  if (!cred) {\n    output.error(`No backup codes found for ${service}`);\n    process.exit(1);\n  }\n\n  const { codes, usedIndices } = parseCodes(cred.value);\n  const availableIndices = codes\n    .map((_, i) => i)\n    .filter((i) => !usedIndices.includes(i));\n\n  if (availableIndices.length === 0) {\n    output.error('All backup codes have been used!');\n    output.warning('You should generate new backup codes for this service.');\n    process.exit(1);\n  }\n\n  let indexToMark: number;\n\n  if (options.index) {\n    indexToMark = parseInt(options.index, 10) - 1; // Convert to 0-based\n    if (isNaN(indexToMark) || indexToMark < 0 || indexToMark >= codes.length) {\n      output.error(`Invalid index. Must be 1-${codes.length}`);\n      process.exit(1);\n    }\n    if (usedIndices.includes(indexToMark)) {\n      output.error(`Code #${indexToMark + 1} is already marked as used.`);\n      process.exit(1);\n    }\n  } else {\n    // Prompt to select which code was used\n    const choices = availableIndices.map((i) => ({\n      name: `${i + 1}. ${codes[i].substring(0, 4)}${'*'.repeat(codes[i].length - 4)}`,\n      value: i,\n    }));\n\n    const { selected } = await inquirer.prompt([\n      {\n        type: 'list',\n        name: 'selected',\n        message: 'Which code did you use?',\n        choices,\n      },\n    ]);\n\n    indexToMark = selected;\n  }\n\n  // Update used indices\n  const newUsedIndices = [...usedIndices, indexToMark];\n  const newValue = serializeCodes(codes, newUsedIndices);\n\n  await svc.add(credName, newValue, cred.metadata);\n\n  const remaining = codes.length - newUsedIndices.length;\n  output.success(`Marked code #${indexToMark + 1} as used.`);\n  output.info(`${remaining} codes remaining for ${service}`);\n\n  if (remaining <= 2) {\n    console.log('');\n    output.warning('Running low on backup codes! Consider generating new ones.');\n  }\n}\n"],"mappings":"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","names":["path","fs","chalk","confirm","fs","header","fs","path","error","fs","path","init_validation","fs","inquirer","chalk","confirm","resolve","error","init_validation","chalk","chalk","error","fs","parseEnv","resolve","parseEnv","error","error","error","error","fs","parseEnv","parseEnv","error","fs","ageProvider","keyValue","error","readStdin","resolve","error","fs","fs","parseEnv","readStdin","resolve","error","parseEnv","fs","parseEnv","envPath","parseEnv","formatDate","fs","path","os","crypto","fs","path","os","resolve","runWizardUI","error","spawn","fs","resolve","spawn","inquirer","chalk","chalk","resolve","inquirer","chalk"]}