{"version":3,"sources":["../src/cli/utils/responseFormat.ts","../src/cli/utils/promptConverter.ts","../src/cli/utils/fileManager.ts","../src/cli/utils/errors/prompt-not-found.error.ts"],"sourcesContent":["/**\n * Bidirectional mapping between the platform's `outputs` array and the\n * local YAML `response_format` block.\n *\n * The platform is the single source of truth and stores structured output as\n * an `outputs` array. The local `.prompt.yaml` follows the GitHub Prompts\n * convention and carries a `response_format` block. Push and pull must be\n * exact inverses, so both directions live here and share one definition of\n * what \"flat structured fields\" vs. \"an opaque JSON schema\" means.\n *\n * Two shapes round-trip losslessly:\n *\n *  - Flat platform fields (e.g. l1, l2, l3, reasoning) ⇆ a single-level\n *    JSON-schema object whose properties are those fields. The platform keeps\n *    showing them as individual fields after a pull → edit → push cycle.\n *\n *  - A rich JSON schema (enums, nested objects, arrays, descriptions, …) ⇆ a\n *    single `json_schema` output that preserves the schema verbatim.\n */\n\nexport type CliOutputType = \"str\" | \"float\" | \"bool\" | \"json_schema\";\n\nexport interface CliOutput {\n  identifier: string;\n  type: CliOutputType;\n  json_schema?: Record<string, unknown>;\n}\n\nexport interface LocalResponseFormat {\n  name?: string;\n  schema: Record<string, unknown>;\n}\n\n/**\n * The CLI default output for an unstructured (plain text) prompt. A prompt\n * with exactly this single output has no structured response and therefore no\n * `response_format` block.\n */\nexport const DEFAULT_TEXT_OUTPUT: CliOutput = {\n  identifier: \"output\",\n  type: \"str\",\n};\n\nconst SCALAR_OUTPUT_TO_JSON_TYPE: Record<\n  Exclude<CliOutputType, \"json_schema\">,\n  string\n> = {\n  str: \"string\",\n  float: \"number\",\n  bool: \"boolean\",\n};\n\nconst JSON_TYPE_TO_SCALAR_OUTPUT: Record<\n  string,\n  Exclude<CliOutputType, \"json_schema\">\n> = {\n  string: \"str\",\n  number: \"float\",\n  integer: \"float\",\n  boolean: \"bool\",\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n  typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/**\n * Accepts either the canonical local form `{ name?, schema }` or the\n * OpenAI-standard wrapper `{ type: \"json_schema\", json_schema: { name, schema } }`\n * and normalizes to `{ name?, schema }`. Returns undefined when there is no\n * usable schema.\n */\nexport const normalizeResponseFormat = (\n  raw: unknown,\n): LocalResponseFormat | undefined => {\n  if (!isPlainObject(raw)) return undefined;\n\n  // OpenAI-standard wrapper\n  if (raw.type === \"json_schema\" && isPlainObject(raw.json_schema)) {\n    const inner = raw.json_schema;\n    if (isPlainObject(inner.schema)) {\n      return {\n        name: typeof inner.name === \"string\" ? inner.name : undefined,\n        schema: inner.schema,\n      };\n    }\n    return undefined;\n  }\n\n  // Canonical local form\n  if (isPlainObject(raw.schema)) {\n    return {\n      name: typeof raw.name === \"string\" ? raw.name : undefined,\n      schema: raw.schema,\n    };\n  }\n\n  return undefined;\n};\n\n/**\n * A \"simple flat object schema\" has only scalar properties (string / number /\n * integer / boolean), no extra JSON-schema keywords on the schema or on any\n * property, and (when present) `required` listing exactly the properties.\n * These map losslessly to flat platform fields. Anything richer (enums,\n * arrays, nested objects, descriptions, …) is opaque and must be preserved\n * verbatim as a json_schema output.\n */\nexport const asFlatFields = (\n  schema: Record<string, unknown>,\n): { identifier: string; type: Exclude<CliOutputType, \"json_schema\"> }[] | null => {\n  if (schema.type !== \"object\") return null;\n  if (!isPlainObject(schema.properties)) return null;\n\n  const allowedSchemaKeys = new Set([\n    \"type\",\n    \"properties\",\n    \"required\",\n    \"additionalProperties\",\n  ]);\n  if (Object.keys(schema).some((k) => !allowedSchemaKeys.has(k))) return null;\n\n  if (\n    schema.additionalProperties !== undefined &&\n    schema.additionalProperties !== false\n  ) {\n    return null;\n  }\n\n  const properties = schema.properties;\n  const propertyNames = Object.keys(properties);\n  if (propertyNames.length === 0) return null;\n\n  const fields: {\n    identifier: string;\n    type: Exclude<CliOutputType, \"json_schema\">;\n  }[] = [];\n\n  for (const name of propertyNames) {\n    const prop = properties[name];\n    if (!isPlainObject(prop)) return null;\n    if (Object.keys(prop).some((k) => k !== \"type\")) return null;\n    const jsonType = prop.type;\n    if (typeof jsonType !== \"string\") return null;\n    const scalar = JSON_TYPE_TO_SCALAR_OUTPUT[jsonType];\n    if (!scalar) return null;\n    fields.push({ identifier: name, type: scalar });\n  }\n\n  if (schema.required !== undefined) {\n    if (!Array.isArray(schema.required)) return null;\n    const required = [...(schema.required as unknown[])].sort();\n    const names = [...propertyNames].sort();\n    if (\n      required.length !== names.length ||\n      required.some((r, i) => r !== names[i])\n    ) {\n      return null;\n    }\n  }\n\n  return fields;\n};\n\n/**\n * Pull direction: reconstruct the local `response_format` block from the\n * platform `outputs` array. Returns undefined for a plain-text prompt so we\n * never invent a schema that wasn't there.\n */\nexport const outputsToResponseFormat = (\n  outputs: CliOutput[] | undefined | null,\n  fallbackName?: string,\n): LocalResponseFormat | undefined => {\n  if (!outputs || outputs.length === 0) return undefined;\n\n  const jsonSchemaOutput = outputs.find(\n    (o) => o.type === \"json_schema\" && o.json_schema,\n  );\n  if (jsonSchemaOutput?.json_schema) {\n    return {\n      name: jsonSchemaOutput.identifier,\n      schema: jsonSchemaOutput.json_schema,\n    };\n  }\n\n  // Exactly the CLI default single text output → unstructured, no schema.\n  if (\n    outputs.length === 1 &&\n    outputs[0]!.identifier === DEFAULT_TEXT_OUTPUT.identifier &&\n    outputs[0]!.type === DEFAULT_TEXT_OUTPUT.type\n  ) {\n    return undefined;\n  }\n\n  // Flat structured fields → a single-level JSON schema object.\n  const properties: Record<string, { type: string }> = {};\n  for (const output of outputs) {\n    if (output.type === \"json_schema\") continue;\n    properties[output.identifier] = {\n      type: SCALAR_OUTPUT_TO_JSON_TYPE[output.type],\n    };\n  }\n  if (Object.keys(properties).length === 0) return undefined;\n\n  return {\n    name: fallbackName ?? \"output\",\n    schema: {\n      type: \"object\",\n      properties,\n      required: Object.keys(properties),\n      additionalProperties: false,\n    },\n  };\n};\n\n/**\n * Push direction: turn the local `response_format` block back into the\n * platform `outputs` array. The exact inverse of {@link outputsToResponseFormat}:\n * a flat object schema expands to flat fields (so the platform keeps showing\n * them individually), anything richer becomes one json_schema output.\n */\nexport const responseFormatToOutputs = (\n  raw: unknown,\n): CliOutput[] | undefined => {\n  const rf = normalizeResponseFormat(raw);\n  if (!rf) return undefined;\n\n  const flat = asFlatFields(rf.schema);\n  if (flat) {\n    return flat.map((f) => ({ identifier: f.identifier, type: f.type }));\n  }\n\n  return [\n    {\n      identifier: rf.name ?? \"output\",\n      type: \"json_schema\",\n      json_schema: rf.schema,\n    },\n  ];\n};\n","import type {\n  LocalPromptConfig,\n  MaterializedPrompt,\n  RuntimeParameters,\n} from \"../types\";\nimport { type PromptResponse, type UpdatePromptBody } from \"@/client-sdk/services/prompts/types\";\nimport {\n  type CliOutput,\n  type LocalResponseFormat,\n  outputsToResponseFormat,\n} from \"./responseFormat\";\n\n/**\n * Converter utility for transforming between YAML prompt format and API service format.\n *\n * The YAML format follows the GitHub .prompt.yaml file format standard,\n * while the API format is our internal prompt service schema tied to the database.\n *\n * This separation allows us to maintain and evolve both formats independently\n * while keeping the conversion logic centralized and well-tested.\n */\nexport class PromptConverter {\n  /**\n   * Converts a Prompt instance from the API service to the MaterializedPrompt format\n   * used for saving to the .materialized directory.\n   */\n  static fromApiToMaterialized(prompt: PromptResponse): MaterializedPrompt {\n    return {\n      id: prompt.id,\n      name: prompt.name,\n      version: prompt.version,\n      versionId: prompt.versionId,\n      model: prompt.model,\n      messages: prompt.messages,\n      prompt: prompt.prompt,\n      temperature: prompt.temperature,\n      maxTokens: prompt.maxTokens,\n      inputs: prompt.inputs,\n      outputs: prompt.outputs,\n      parameters: prompt.parameters ?? {},\n      updatedAt: prompt.updatedAt,\n    };\n  }\n\n  /**\n   * Converts a MaterializedPrompt to the YAML content structure\n   * for saving to .prompt.yaml files.\n   */\n  static fromMaterializedToYaml(prompt: MaterializedPrompt): {\n    model: string;\n    modelParameters?: {\n      temperature?: number;\n      maxTokens?: number;\n    };\n    messages: Array<{\n      role: \"system\" | \"user\" | \"assistant\";\n      content: string;\n    }>;\n    response_format?: LocalResponseFormat;\n    parameters?: RuntimeParameters;\n  } {\n    const result: any = {\n      model: prompt.model,\n      messages: prompt.messages,\n    };\n\n    if (Object.keys(prompt.parameters ?? {}).length > 0) {\n      result.parameters = prompt.parameters;\n    }\n\n    // Add modelParameters if temperature or maxTokens exist. The server is the\n    // source of truth for which sampling parameters a model accepts and omits\n    // the ones it would reject (e.g. temperature on the gpt-5 family), so we\n    // simply mirror what the API returned — never inject a default here.\n    if (prompt.temperature !== undefined || prompt.maxTokens !== undefined) {\n      result.modelParameters = {};\n      if (prompt.temperature !== undefined) {\n        result.modelParameters.temperature = prompt.temperature;\n      }\n      if (prompt.maxTokens !== undefined) {\n        result.modelParameters.maxTokens = prompt.maxTokens;\n      }\n    }\n\n    // Reconstruct the structured-output block from the platform outputs so a\n    // pull never drops a response_format the user configured. Inverse of the\n    // push direction in pushPrompts.\n    const responseFormat = outputsToResponseFormat(\n      prompt.outputs as CliOutput[] | undefined,\n      prompt.name,\n    );\n    if (responseFormat) {\n      result.response_format = responseFormat;\n    }\n\n    return result;\n  }\n\n  /**\n   * Converts a LocalPromptConfig (loaded from YAML) to the format\n   * expected by the API service for upserting.\n   */\n  static fromLocalToApiFormat(\n    config: LocalPromptConfig,\n  ): Omit<UpdatePromptBody, \"commitMessage\"> & { parameters?: RuntimeParameters }\n  {\n    return {\n      model: config.model,\n      temperature: config.modelParameters?.temperature,\n      maxTokens: config.modelParameters?.max_tokens,\n      messages: config.messages,\n      parameters: config.parameters ?? {},\n    };\n  }\n\n  /**\n   * Extracts the system prompt from messages array.\n   * Used when converting to API format that separates system prompt from messages.\n   */\n  static extractSystemPrompt(\n    messages: Array<{ role: string; content: string }>,\n  ): string {\n    return messages.find((m) => m.role === \"system\")?.content ?? \"\";\n  }\n\n  /**\n   * Filters out system messages from the messages array.\n   * Used when converting to API format that handles system prompt separately.\n   */\n  static filterNonSystemMessages(\n    messages: Array<{\n      role: \"system\" | \"user\" | \"assistant\";\n      content: string;\n    }>,\n  ): Array<{ role: \"user\" | \"assistant\"; content: string }> {\n    return messages.filter((m) => m.role !== \"system\") as Array<{\n      role: \"user\" | \"assistant\";\n      content: string;\n    }>;\n  }\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as yaml from \"js-yaml\";\nimport chalk from \"chalk\";\nimport type { PromptsConfig, LocalPromptConfig, MaterializedPrompt, PromptsLock } from \"../types\";\nimport { localPromptConfigSchema } from \"../types\";\nimport { PromptConverter } from \"@/cli/utils/promptConverter\";\nimport { PromptFileNotFoundError } from \"./errors/prompt-not-found.error\";\nimport { formatApiErrorMessage } from \"@/client-sdk/services/_shared/format-api-error\";\n\nexport class FileManager {\n  private static readonly PROMPTS_CONFIG_FILE = \"prompts.json\";\n  private static readonly PROMPTS_LOCK_FILE = \"prompts-lock.json\";\n  private static readonly PROMPTS_DIR = \"prompts\";\n  private static readonly MATERIALIZED_DIR = \".materialized\";\n\n  private static _projectRoot: string | undefined;\n\n  /** Reset the cached project root. Tests use this to exercise different cwds. */\n  static _resetProjectRootCache(): void {\n    this._projectRoot = undefined;\n  }\n\n  private static readonly PROJECT_MARKERS = [\n    \".git\",\n    \"package.json\",\n    \"pyproject.toml\",\n  ];\n\n  private static hasProjectMarker(dir: string): boolean {\n    return this.PROJECT_MARKERS.some((m) => fs.existsSync(path.join(dir, m)));\n  }\n\n  private static findProjectRoot(): string {\n    if (this._projectRoot) {\n      return this._projectRoot;\n    }\n\n    const cwd = process.cwd();\n    const fsRoot = path.parse(cwd).root;\n\n    // Find the highest ancestor that still looks like part of \"this project\"\n    // (has package.json / pyproject.toml / .git). If cwd itself has no marker,\n    // we don't walk up at all — prevents grabbing a stray prompts.json from\n    // /tmp or other shared scratch dirs.\n    let topProjectDir: string | null = null;\n    let scan = cwd;\n    while (scan !== fsRoot) {\n      if (this.hasProjectMarker(scan)) {\n        topProjectDir = scan;\n      }\n      scan = path.dirname(scan);\n    }\n\n    if (!topProjectDir) {\n      this._projectRoot = cwd;\n      return cwd;\n    }\n\n    // Walk up from cwd looking for prompts.json, capped at the project boundary.\n    let currentDir = cwd;\n    while (true) {\n      const configPath = path.join(currentDir, this.PROMPTS_CONFIG_FILE);\n      if (fs.existsSync(configPath)) {\n        this._projectRoot = currentDir;\n        return currentDir;\n      }\n      if (currentDir === topProjectDir) break;\n      currentDir = path.dirname(currentDir);\n    }\n\n    // No prompts.json anywhere within the project — default to cwd so `init`\n    // creates it where the user actually ran the command. This also keeps\n    // concurrent test workdirs isolated: each tempdir gets its own prompts.json\n    // instead of all pointing at a shared repo-root file.\n    this._projectRoot = cwd;\n    return cwd;\n  }\n\n  static getPromptsConfigPath(): string {\n    return path.join(this.findProjectRoot(), this.PROMPTS_CONFIG_FILE);\n  }\n\n  static getPromptsLockPath(): string {\n    return path.join(this.findProjectRoot(), this.PROMPTS_LOCK_FILE);\n  }\n\n  static getPromptsDir(): string {\n    return path.join(this.findProjectRoot(), this.PROMPTS_DIR);\n  }\n\n  static getMaterializedDir(): string {\n    return path.join(this.getPromptsDir(), this.MATERIALIZED_DIR);\n  }\n\n  static ensureDirectories(): void {\n    const promptsDir = this.getPromptsDir();\n    const materializedDir = this.getMaterializedDir();\n\n    if (!fs.existsSync(promptsDir)) {\n      fs.mkdirSync(promptsDir, { recursive: true });\n    }\n\n    if (!fs.existsSync(materializedDir)) {\n      fs.mkdirSync(materializedDir, { recursive: true });\n    }\n  }\n\n  static loadPromptsConfig(): PromptsConfig {\n    const configPath = this.getPromptsConfigPath();\n\n    if (!fs.existsSync(configPath)) {\n      return { prompts: {} };\n    }\n\n    try {\n      const content = fs.readFileSync(configPath, \"utf-8\");\n      return JSON.parse(content) as PromptsConfig;\n    } catch (error) {\n      throw new Error(`Failed to parse prompts.json: ${formatApiErrorMessage({ error })}`);\n    }\n  }\n\n  static savePromptsConfig(config: PromptsConfig): void {\n    const configPath = this.getPromptsConfigPath();\n    fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\");\n  }\n\n  static initializePromptsConfig(): { created: boolean; path: string } {\n    const configPath = this.getPromptsConfigPath();\n    const existed = fs.existsSync(configPath);\n\n    if (!existed) {\n      const emptyConfig: PromptsConfig = { prompts: {} };\n      this.savePromptsConfig(emptyConfig);\n      return { created: true, path: configPath };\n    }\n\n    return { created: false, path: configPath };\n  }\n\n  static loadPromptsLock = (): PromptsLock => {\n    const lockPath = this.getPromptsLockPath();\n\n    if (!fs.existsSync(lockPath)) {\n      return {\n        lockfileVersion: 1,\n        prompts: {}\n      };\n    }\n\n    try {\n      const content = fs.readFileSync(lockPath, \"utf-8\");\n      return JSON.parse(content) as PromptsLock;\n    } catch (error) {\n      throw new Error(`Failed to parse prompts-lock.json: ${formatApiErrorMessage({ error })}`);\n    }\n  }\n\n  static savePromptsLock(lock: PromptsLock): void {\n    const lockPath = this.getPromptsLockPath();\n    fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + \"\\n\");\n  }\n\n  static initializePromptsLock(): { created: boolean; path: string } {\n    const lockPath = this.getPromptsLockPath();\n    const existed = fs.existsSync(lockPath);\n\n    if (!existed) {\n      const emptyLock: PromptsLock = {\n        lockfileVersion: 1,\n        prompts: {}\n      };\n      this.savePromptsLock(emptyLock);\n      return { created: true, path: lockPath };\n    }\n\n    return { created: false, path: lockPath };\n  }\n\n  static loadLocalPrompt = (filePath: string): LocalPromptConfig => {\n    const fullPath = path.resolve(filePath);\n\n    if (!fs.existsSync(fullPath)) {\n      throw new PromptFileNotFoundError(filePath);\n    }\n\n    try {\n      const content = fs.readFileSync(fullPath, \"utf-8\");\n      const rawData = yaml.load(content);\n\n      // Validate with zod and provide nice error messages\n      const result = localPromptConfigSchema.safeParse(rawData);\n\n            if (!result.success) {\n        // Format zod errors nicely (manually since z.prettifyError might not be available)\n        const prettyError = result.error.issues\n          .map(issue => `✖ ${issue.message}${issue.path.length > 0 ? `\\n  → at ${issue.path.join('.')}` : ''}`)\n          .join('\\n');\n\n        throw new Error(\n          `Invalid prompt configuration in ${chalk.yellow(filePath)}:\\n${prettyError}`\n        );\n      }\n\n      return result.data;\n    } catch (error) {\n      if (error instanceof Error && error.message.includes(\"Invalid prompt configuration\")) {\n        throw error; // Re-throw zod validation errors as-is\n      }\n      throw new Error(`Failed to parse local prompt file ${filePath}: ${formatApiErrorMessage({ error })}`);\n    }\n  }\n\n    static saveMaterializedPrompt(name: string, prompt: MaterializedPrompt): string {\n    const materializedDir = this.getMaterializedDir();\n    const parts = name.split(\"/\");\n    const fileName = `${parts[parts.length - 1]}.prompt.yaml`;\n\n    // Create nested directories if needed\n    if (parts.length > 1) {\n      const subDir = path.join(materializedDir, ...parts.slice(0, -1));\n      if (!fs.existsSync(subDir)) {\n        fs.mkdirSync(subDir, { recursive: true });\n      }\n    }\n\n    const filePath = path.join(materializedDir, ...parts.slice(0, -1), fileName);\n\n    // Convert to YAML format using the converter\n    const yamlContent = PromptConverter.fromMaterializedToYaml(prompt);\n\n    const yamlString = yaml.dump(yamlContent, {\n      lineWidth: -1,\n      noRefs: true,\n      sortKeys: false\n    });\n\n    fs.writeFileSync(filePath, yamlString);\n    return filePath;\n  }\n\n  static getLocalPromptFiles = (): string[] => {\n    const promptsDir = this.getPromptsDir();\n    const materializedDir = this.getMaterializedDir();\n\n    if (!fs.existsSync(promptsDir)) {\n      return [];\n    }\n\n    const files: string[] = [];\n\n    const walkDir = (dir: string, relativePath = \"\"): void => {\n      const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n      for (const entry of entries) {\n        const fullPath = path.join(dir, entry.name);\n        const relativeFilePath = path.join(relativePath, entry.name);\n\n        if (entry.isDirectory()) {\n          // Skip the .materialized directory\n          if (fullPath === materializedDir) {\n            continue;\n          }\n          walkDir(fullPath, relativeFilePath);\n        } else if (entry.isFile() && entry.name.endsWith(\".prompt.yaml\")) {\n          files.push(path.join(promptsDir, relativeFilePath));\n        }\n      }\n    };\n\n    walkDir(promptsDir);\n    return files;\n  }\n\n  static promptNameFromPath(filePath: string): string {\n    const promptsDir = this.getPromptsDir();\n    const relativePath = path.relative(promptsDir, filePath);\n    return relativePath.replace(/\\.prompt\\.yaml$/, \"\");\n  }\n\n  static cleanupOrphanedMaterializedFiles(currentDependencies: Set<string>): string[] {\n    const materializedDir = this.getMaterializedDir();\n\n    if (!fs.existsSync(materializedDir)) {\n      return [];\n    }\n\n    const cleaned: string[] = [];\n\n    const cleanupDir = (dir: string, relativePath = \"\"): void => {\n      const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n      for (const entry of entries) {\n        const fullPath = path.join(dir, entry.name);\n        const relativeFilePath = path.join(relativePath, entry.name);\n\n        if (entry.isDirectory()) {\n          cleanupDir(fullPath, relativeFilePath);\n\n          // Remove empty directories\n          try {\n            const dirEntries = fs.readdirSync(fullPath);\n            if (dirEntries.length === 0) {\n              fs.rmdirSync(fullPath);\n            }\n          } catch {\n            // Directory not empty or other error, ignore\n          }\n        } else if (entry.isFile() && entry.name.endsWith(\".prompt.yaml\")) {\n          // Extract prompt name from materialized file path\n          const promptName = relativeFilePath.replace(/\\.prompt\\.yaml$/, \"\");\n\n          if (!currentDependencies.has(promptName)) {\n            fs.unlinkSync(fullPath);\n            cleaned.push(promptName);\n          }\n        }\n      }\n    };\n\n    cleanupDir(materializedDir);\n    return cleaned;\n  }\n\n  static updateLockEntry(lock: PromptsLock, name: string, prompt: MaterializedPrompt, materializedPath: string): void {\n    const relativePath = path.relative(this.findProjectRoot(), materializedPath);\n\n    lock.prompts[name] = {\n      version: prompt.version,\n      versionId: prompt.versionId,\n      materialized: relativePath,\n    };\n  }\n\n  static removeFromLock(lock: PromptsLock, names: string[]): void {\n    for (const name of names) {\n      delete lock.prompts[name];\n    }\n  }\n\n  static addToGitignore(entry: string): { added: boolean; existed: boolean } {\n    const gitignorePath = path.join(this.findProjectRoot(), \".gitignore\");\n\n    // Check if .gitignore exists\n    if (!fs.existsSync(gitignorePath)) {\n      // Create new .gitignore with the entry\n      fs.writeFileSync(gitignorePath, `${entry}\\n`);\n      return { added: true, existed: false };\n    }\n\n    // Read existing .gitignore\n    const content = fs.readFileSync(gitignorePath, \"utf-8\");\n    const lines = content.split(\"\\n\").map(line => line.trim());\n\n    // Check if entry already exists\n    if (lines.includes(entry)) {\n      return { added: false, existed: true };\n    }\n\n    // Add entry to .gitignore\n    const newContent = content.endsWith(\"\\n\") ? `${content}${entry}\\n` : `${content}\\n${entry}\\n`;\n    fs.writeFileSync(gitignorePath, newContent);\n\n    return { added: true, existed: false };\n  }\n}\n","export class PromptFileNotFoundError extends Error {\n  constructor(filePath: string) {\n    super(`Local prompt file not found: ${filePath}`);\n    this.name = 'PromptFileNotFoundError';\n  }\n}\n"],"mappings":"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","names":[]}