{"version":3,"sources":["../src/cli/commands/add.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { FileManager } from \"../utils/fileManager\";\nimport { PromptsApiService, PromptsError } from \"@/client-sdk/services/prompts\";\nimport { PromptConverter } from \"../utils/promptConverter\";\nimport { ensureProjectInitialized } from \"../utils/init\";\nimport { checkApiKey } from \"../utils/apiKey\";\nimport { formatApiErrorMessage } from \"@/client-sdk/services/_shared/format-api-error\";\nimport { failSpinner } from \"../utils/spinnerError\";\n\ninterface AddOptions {\n  version?: string;\n  localFile?: string;\n}\n\nconst addLocalFile = async (\n  name: string,\n  localFilePath: string,\n): Promise<void> => {\n  // Validate that the file exists and has the right extension\n  if (!fs.existsSync(localFilePath)) {\n    console.error(chalk.red(`Error: Local file not found: ${localFilePath}`));\n    process.exit(1);\n  }\n\n  if (!localFilePath.endsWith(\".prompt.yaml\")) {\n    console.error(\n      chalk.red(`Error: Local file must have .prompt.yaml extension`),\n    );\n    process.exit(1);\n  }\n\n  // Load and validate the YAML file\n  try {\n    FileManager.loadLocalPrompt(localFilePath);\n\n    // Ensure project is initialized\n    await ensureProjectInitialized();\n\n    // Add to prompts.json as a file: dependency\n    const promptsConfig = FileManager.loadPromptsConfig();\n    promptsConfig.prompts[name] = `file:${localFilePath}`;\n    FileManager.savePromptsConfig(promptsConfig);\n\n    // Update lock file\n    const lock = FileManager.loadPromptsLock();\n    lock.prompts[name] = {\n      version: 0, // Local files start at version 0\n      versionId: \"local\",\n      materialized: localFilePath, // Store the original file path\n    };\n    FileManager.savePromptsLock(lock);\n\n    console.log(\n      chalk.green(\n        `✓ Added local prompt: ${chalk.cyan(name)} → ${chalk.gray(\n          localFilePath,\n        )}`,\n      ),\n    );\n  } catch (error) {\n    console.error(chalk.red(\"Error loading local prompt file:\"));\n    console.error(\n      chalk.red(error instanceof Error ? error.message : String(error)),\n    );\n    process.exit(1);\n  }\n};\n\nexport const addCommand = async (\n  name: string,\n  options: AddOptions,\n): Promise<void> => {\n  try {\n    // Validate prompt name\n    if (!name || name.trim() === \"\") {\n      console.error(chalk.red(\"Error: Prompt name cannot be empty\"));\n      process.exit(1);\n    }\n\n    // Handle local file addition\n    if (options.localFile) {\n      await addLocalFile(name, options.localFile);\n      return;\n    }\n\n    // Check API key before doing anything else\n    checkApiKey();\n\n    const promptsApiService = new PromptsApiService();\n    const version = options.version ?? \"latest\";\n\n    // Fetch and materialize the prompt (like sync does for individual prompts)\n    const spinner = ora(\n      `Adding ${chalk.cyan(`${name}@${version}`)}...`,\n    ).start();\n\n    try {\n      // Fetch the prompt from the API\n      const prompt = await promptsApiService.get(name, { version });\n\n      if (!prompt) {\n        spinner.fail(chalk.red(`Prompt \"${name}\" not found`));\n        process.exit(1);\n      }\n\n      // Stop spinner before any user input prompts\n      spinner.stop();\n\n      // Ensure project is initialized (prompts.json, lock file, directories)\n      await ensureProjectInitialized();\n\n      // Restart spinner for the actual work\n      spinner.start(`Adding ${chalk.cyan(`${name}@${version}`)}...`);\n\n      // Convert to MaterializedPrompt format and save\n      const materializedPrompt = PromptConverter.fromApiToMaterialized(prompt);\n      const savedPath = FileManager.saveMaterializedPrompt(\n        name,\n        materializedPrompt,\n      );\n      const relativePath = path.relative(process.cwd(), savedPath);\n\n      // Load existing config and lock, add the new dependency\n      const config = FileManager.loadPromptsConfig();\n      const lock = FileManager.loadPromptsLock();\n\n      config.prompts[name] = version;\n      FileManager.updateLockEntry(lock, name, materializedPrompt, savedPath);\n\n      // Save the updated config and lock\n      FileManager.savePromptsConfig(config);\n      FileManager.savePromptsLock(lock);\n\n      spinner.succeed();\n\n      // Show what was done (add ./ prefix for consistency)\n      const displayPath = relativePath.startsWith(\"./\")\n        ? relativePath\n        : `./${relativePath}`;\n      console.log(\n        chalk.green(\n          `✓ Pulled ${chalk.cyan(`${name}@${version}`)} ${chalk.gray(\n            `(version ${prompt.version})`,\n          )} → ${chalk.gray(displayPath)}`,\n        ),\n      );\n    } catch (error) {\n      failSpinner({ spinner, error, action: \"add prompt\" });\n      process.exit(1);\n    }\n  } catch (error) {\n    if (error instanceof PromptsError) {\n      console.error(chalk.red(`Error: ${error.message}`));\n    } else {\n      console.error(\n        chalk.red(\n          `Unexpected error: ${\n            formatApiErrorMessage({ error })\n          }`,\n        ),\n      );\n    }\n    process.exit(1);\n  }\n};\n"],"mappings":"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","names":[]}