{"version":3,"file":"profiles-UGBJK65f.cjs","names":["isRecord","parseYaml","PARENT_DIRECTORY","path","fs","PROFILE_ICON_MAX_DATA_URL_LENGTH","path","fs","os","readDoomConfigSources"],"sources":["../src/services/personaFrontMatter/index.ts","../src/services/personaIcon/index.ts","../src/services/profiles/index.ts"],"sourcesContent":["import { parse as parseYaml } from 'yaml';\n\nimport type { PersonaDocument, PersonaFrontMatter, PersonaVoiceOverride } from '../../types/profiles';\n\n/**\n * Optional identity a persona declares at the top of its `profile.md`.\n *\n * A profile used to be prompt text only, so there was nowhere to say who the\n * persona is or how it should sound. Front-matter puts that beside the persona\n * text it describes, which is the only place that works for both explicit\n * `profiles.yaml` entries and folders found by root discovery.\n *\n * Recognition is deliberately narrow. Personas that exist today were written\n * without any of this, and one of them may legitimately open with a horizontal\n * rule, so a leading fence alone is not enough to claim the block. A block is\n * only treated as identity when it is fenced at the very first line, closed,\n * parses as a mapping, and declares at least one field this contract owns.\n * Anything else is passed through byte for byte.\n */\n\nconst FENCE = '---';\nconst OWNED_KEYS = ['name', 'icon', 'voice'] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readVoice(value: unknown): PersonaVoiceOverride | undefined {\n  if (!isRecord(value)) return undefined;\n  const voice = typeof value.voice === 'string' && value.voice.trim().length > 0 ? value.voice.trim() : undefined;\n  const rate = typeof value.rate === 'number' && Number.isFinite(value.rate) ? value.rate : undefined;\n  if (voice === undefined && rate === undefined) return undefined;\n  return { ...(voice === undefined ? {} : { voice }), ...(rate === undefined ? {} : { rate }) };\n}\n\nfunction readFrontMatter(parsed: Record<string, unknown>): PersonaFrontMatter | undefined {\n  const name = typeof parsed.name === 'string' && parsed.name.trim().length > 0 ? parsed.name.trim() : undefined;\n  const icon = typeof parsed.icon === 'string' && parsed.icon.trim().length > 0 ? parsed.icon.trim() : undefined;\n  const voice = readVoice(parsed.voice);\n  if (name === undefined && icon === undefined && voice === undefined) return undefined;\n  return {\n    ...(name === undefined ? {} : { name }),\n    ...(icon === undefined ? {} : { icon }),\n    ...(voice === undefined ? {} : { voice }),\n  };\n}\n\n/**\n * Splits a recognised identity block off a persona document.\n *\n * Never throws: a malformed avatar must not make a persona unloadable, so an\n * unparseable or unrecognised block leaves the document exactly as it arrived.\n */\nexport function parsePersonaFrontMatter(content: string): PersonaDocument {\n  const lines = content.split('\\n');\n  if (lines[0]?.trimEnd() !== FENCE) return { body: content };\n\n  const closingIndex = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FENCE);\n  if (closingIndex === -1) return { body: content };\n\n  let parsed: unknown;\n  try {\n    parsed = parseYaml(lines.slice(1, closingIndex).join('\\n'));\n  } catch {\n    return { body: content };\n  }\n  if (!isRecord(parsed)) return { body: content };\n  if (!OWNED_KEYS.some((key) => Object.hasOwn(parsed, key))) return { body: content };\n\n  const frontMatter = readFrontMatter(parsed);\n  if (!frontMatter) return { body: content };\n  return { frontMatter, body: lines.slice(closingIndex + 1).join('\\n') };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { PROFILE_ICON_MAX_DATA_URL_LENGTH, type ProfileIconMimeType } from '@agimon-ai/doompi-core/profileIdentity';\n\n/**\n * Reads a persona icon into a bounded `data:` URL.\n *\n * The icon travels inside the journalled identity entry rather than through an\n * HTTP route. A route would leave a request-time filesystem resolution reachable\n * from the browser for the life of a session, defended on every request forever;\n * this resolves the path once, server side, at the moment the profile loads.\n *\n * The path comes from user-authored front-matter, so it is confined the same way\n * `buildPersonaPrompt` confines persona files: a symlink must not read outside\n * the persona directory.\n *\n * Every failure is silent and returns undefined. An avatar is decoration, and a\n * broken one must never stop a persona from loading.\n */\nconst PARENT_DIRECTORY = '..';\n\n/**\n * Magic-byte signatures, checked instead of trusting the filename.\n *\n * `image/svg+xml` is absent on purpose: an SVG rendered same-origin executes\n * script, and the author of this path is whoever wrote the persona. Do not add\n * it to match the cockpit's broader media catalog.\n */\nconst SIGNATURES: readonly { readonly mime: ProfileIconMimeType; readonly test: (bytes: Buffer) => boolean }[] = [\n  {\n    mime: 'image/png',\n    test: (b) => b.length > 8 && b.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])),\n  },\n  { mime: 'image/jpeg', test: (b) => b.length > 3 && b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff },\n  { mime: 'image/gif', test: (b) => b.length > 6 && b.subarray(0, 6).toString('latin1').startsWith('GIF8') },\n  {\n    mime: 'image/webp',\n    test: (b) =>\n      b.length > 12 &&\n      b.subarray(0, 4).toString('latin1') === 'RIFF' &&\n      b.subarray(8, 12).toString('latin1') === 'WEBP',\n  },\n];\n\nfunction sniff(bytes: Buffer): ProfileIconMimeType | undefined {\n  return SIGNATURES.find((signature) => signature.test(bytes))?.mime;\n}\n\n/**\n * Resolves an icon declared in persona front-matter, or undefined when it is\n * missing, unreadable, not an allowed image, escapes the persona directory, or\n * exceeds the data-URL ceiling.\n */\nexport function readPersonaIcon(personaPath: string, iconRelative: string): string | undefined {\n  if (path.isAbsolute(iconRelative)) return undefined;\n\n  try {\n    const realPersonaPath = fs.realpathSync(personaPath);\n    const iconPath = path.resolve(realPersonaPath, iconRelative);\n    if (!fs.existsSync(iconPath)) return undefined;\n\n    const realIconPath = fs.realpathSync(iconPath);\n    const relative = path.relative(realPersonaPath, realIconPath);\n    if (\n      relative === PARENT_DIRECTORY ||\n      relative.startsWith(`${PARENT_DIRECTORY}${path.sep}`) ||\n      path.isAbsolute(relative)\n    ) {\n      return undefined;\n    }\n    if (!fs.statSync(realIconPath).isFile()) return undefined;\n\n    const bytes = fs.readFileSync(realIconPath);\n    const mime = sniff(bytes);\n    if (!mime) return undefined;\n\n    const dataUrl = `data:${mime};base64,${bytes.toString('base64')}`;\n    return dataUrl.length > PROFILE_ICON_MAX_DATA_URL_LENGTH ? undefined : dataUrl;\n  } catch {\n    return undefined;\n  }\n}\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { PersonaIdentity } from '../../types/profiles';\nimport { type PersonaFrontMatter, type PersonaVoiceOverride } from '../../types/profiles';\nimport { readDoomConfigSources } from '../layeredConfig';\nimport { parsePersonaFrontMatter } from '../personaFrontMatter';\nimport { readPersonaIcon } from '../personaIcon';\n\n/** Files that make up one repository persona, concatenated in this order. */\nexport const PERSONA_FILES = ['profile.md', 'SOUL.md', 'AGENTS.md'];\n\n/** The persona file that may carry an identity block; the others are prose only. */\nconst PERSONA_IDENTITY_FILE = 'profile.md';\n\n/** A persona's resolved presentation: display name, and an icon already read into a data URL. */\n\nexport interface AgentProfile {\n  name: string;\n  /** Directory relative to personaRoot, which remains the persona source. */\n  persona: string;\n  /**\n   * Root the persona path resolves against: the repository root for a\n   * repository profile, the global `.doom` directory for a global one.\n   */\n  personaRoot: string;\n  /** Environment defaults. Values already exported by the caller win. */\n  env: Record<string, string>;\n  /** Display name and avatar declared in the persona's own front-matter. */\n  identity?: PersonaIdentity;\n  /** Narrowly scoped TTS override declared alongside the identity. */\n  voice?: PersonaVoiceOverride;\n}\n\ninterface ProfileConfigLayer {\n  filePath: string;\n  baseDirectory: string;\n  roots: string[];\n  entries: Record<string, unknown>;\n  defaultProfile?: string;\n}\n\nconst PROFILE_KEYS = new Set(['persona', 'env']);\nconst PROFILE_CATALOG_KEYS = new Set(['roots', 'entries', 'defaultProfile']);\nconst PROFILES_FILE = 'profiles.yaml';\nconst PROFILES_ROOT_KEY = 'profiles';\nconst AGENTS_DIRECTORY = 'agents';\nconst PARENT_DIRECTORY = '..';\nconst TEXT_ENCODING = 'utf8';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isPathInside(root: string, candidate: string): boolean {\n  const relative = path.relative(root, candidate);\n  return (\n    relative === '' ||\n    (!path.isAbsolute(relative) &&\n      relative !== PARENT_DIRECTORY &&\n      !relative.startsWith(`${PARENT_DIRECTORY}${path.sep}`))\n  );\n}\n\nfunction parseEnvironment(name: string, value: unknown): Record<string, string> {\n  if (value === undefined) return {};\n  if (!isRecord(value)) throw new Error(`Profile \"${name}\" env must be a string mapping`);\n\n  const environment: Record<string, string> = {};\n  for (const [key, entry] of Object.entries(value)) {\n    if (typeof entry !== 'string') throw new Error(`Profile \"${name}\" env.${key} must be a string`);\n    environment[key] = entry;\n  }\n  return environment;\n}\n\nfunction parseProfileRoots(value: unknown, filePath: string, baseDirectory: string): string[] {\n  if (value === undefined) return [];\n  if (!Array.isArray(value)) throw new Error(`profiles.roots in ${filePath} must be an array`);\n  return value.map((entry, index) => {\n    if (typeof entry !== 'string' || entry.trim().length === 0) {\n      throw new Error(`profiles.roots[${index}] in ${filePath} must be a non-empty string`);\n    }\n    return path.resolve(baseDirectory, entry.trim());\n  });\n}\n\nfunction parseProfileLayer(source: { filePath: string; baseDirectory: string; document: unknown }): ProfileConfigLayer {\n  if (!isRecord(source.document) || !isRecord(source.document[PROFILES_ROOT_KEY])) {\n    throw new Error(`${source.filePath} must contain a profiles mapping`);\n  }\n  const unsupportedDocumentKeys = Object.keys(source.document).filter((key) => key !== PROFILES_ROOT_KEY);\n  if (unsupportedDocumentKeys.length > 0) {\n    throw new Error(`${source.filePath} may only contain profiles; unsupported: ${unsupportedDocumentKeys.join(', ')}`);\n  }\n\n  const profiles = source.document[PROFILES_ROOT_KEY];\n  const usesCatalogShape = Object.hasOwn(profiles, 'roots') || Object.hasOwn(profiles, 'entries');\n  if (!usesCatalogShape) {\n    return { filePath: source.filePath, baseDirectory: source.baseDirectory, roots: [], entries: profiles };\n  }\n\n  const unsupportedCatalogKeys = Object.keys(profiles).filter((key) => !PROFILE_CATALOG_KEYS.has(key));\n  if (unsupportedCatalogKeys.length > 0) {\n    throw new Error(\n      `profiles in ${source.filePath} may only contain roots, entries and defaultProfile; unsupported: ${unsupportedCatalogKeys.join(', ')}`,\n    );\n  }\n  if (\n    profiles.defaultProfile !== undefined &&\n    (typeof profiles.defaultProfile !== 'string' || profiles.defaultProfile.trim().length === 0)\n  ) {\n    throw new Error(`profiles.defaultProfile in ${source.filePath} must be a non-empty string`);\n  }\n  if (profiles.entries !== undefined && !isRecord(profiles.entries)) {\n    throw new Error(`profiles.entries in ${source.filePath} must be a mapping`);\n  }\n  return {\n    filePath: source.filePath,\n    baseDirectory: source.baseDirectory,\n    roots: parseProfileRoots(profiles.roots, source.filePath, source.baseDirectory),\n    entries: profiles.entries ?? {},\n    ...(profiles.defaultProfile === undefined ? {} : { defaultProfile: String(profiles.defaultProfile).trim() }),\n  };\n}\n\nfunction assertProfileInsideAllowedRoot(name: string, personaPath: string, lexicalRoots: readonly string[]): void {\n  const realPersonaPath = fs.realpathSync(personaPath);\n  if (!lexicalRoots.some((root) => isPathInside(fs.realpathSync(root), realPersonaPath))) {\n    throw new Error(`Profile \"${name}\" persona must stay inside agents/ or a configured profile root`);\n  }\n}\n\nfunction parseProfile(\n  personaRoot: string,\n  configuredRoots: readonly string[],\n  name: string,\n  value: unknown,\n): AgentProfile {\n  if (!isRecord(value)) throw new Error(`Profile \"${name}\" must be a mapping`);\n\n  const unsupported = Object.keys(value).filter((key) => !PROFILE_KEYS.has(key));\n  if (unsupported.length > 0) {\n    throw new Error(`Profile \"${name}\" may only set persona and env; unsupported: ${unsupported.join(', ')}`);\n  }\n  if (typeof value.persona !== 'string' || value.persona.trim().length === 0) {\n    throw new Error(`Profile \"${name}\" must set a persona`);\n  }\n  if (path.isAbsolute(value.persona)) {\n    throw new Error(`Profile \"${name}\" persona must be relative to the config that declares it`);\n  }\n\n  const persona = value.persona;\n  const personaPath = path.resolve(personaRoot, persona);\n  const lexicalRoots = [path.resolve(personaRoot, AGENTS_DIRECTORY), ...configuredRoots].filter((root) =>\n    isPathInside(root, personaPath),\n  );\n  if (lexicalRoots.length === 0) {\n    throw new Error(`Profile \"${name}\" persona must stay inside agents/ or a configured profile root`);\n  }\n  if (!fs.existsSync(personaPath) || !fs.statSync(personaPath).isDirectory()) {\n    throw new Error(`Profile \"${name}\" references a missing persona: ${persona}`);\n  }\n  assertProfileInsideAllowedRoot(name, personaPath, lexicalRoots);\n  if (!buildPersonaPrompt(personaRoot, persona)) {\n    // An identity block is not persona text, so a profile.md holding nothing else\n    // leaves the persona empty. Say that, rather than claiming the file is unreadable.\n    const declaresIdentity = readPersonaFrontMatter(personaRoot, persona) !== undefined;\n    throw new Error(\n      declaresIdentity\n        ? `Profile \"${name}\" persona declares identity front-matter but no persona text: ${persona}`\n        : `Profile \"${name}\" persona has no readable persona files: ${persona}`,\n    );\n  }\n\n  return {\n    name,\n    persona,\n    personaRoot,\n    env: parseEnvironment(name, value.env),\n    ...readPersonaPresentation(personaRoot, persona),\n  };\n}\n\nfunction containsPersonaFile(directory: string): boolean {\n  return PERSONA_FILES.some((file) => {\n    try {\n      return fs.lstatSync(path.join(directory, file)).isFile();\n    } catch {\n      return false;\n    }\n  });\n}\n\nfunction discoverProfile(directory: string, configuredRoot: string, personaRoot: string): AgentProfile | undefined {\n  if (!containsPersonaFile(directory)) return undefined;\n  try {\n    const realConfiguredRoot = fs.realpathSync(configuredRoot);\n    const realDirectory = fs.realpathSync(directory);\n    if (!isPathInside(realConfiguredRoot, realDirectory)) return undefined;\n    const persona = path.relative(personaRoot, directory) || '.';\n    if (!buildPersonaPrompt(personaRoot, persona)) return undefined;\n    return {\n      name: path.basename(directory),\n      persona,\n      personaRoot,\n      env: {},\n      ...readPersonaPresentation(personaRoot, persona),\n    };\n  } catch {\n    // Automatic discovery ignores unreadable or unsafe candidates; explicit entries remain fatal.\n    return undefined;\n  }\n}\n\nfunction discoverProfileRoot(root: string, personaRoot: string): AgentProfile[] {\n  if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n    throw new Error(`Configured profile root is not a directory: ${root}`);\n  }\n\n  const rootProfile = discoverProfile(root, root, personaRoot);\n  if (rootProfile) return [rootProfile];\n\n  return fs\n    .readdirSync(root, { withFileTypes: true })\n    .filter((entry) => entry.isDirectory())\n    .sort((left, right) => left.name.localeCompare(right.name))\n    .flatMap((entry) => {\n      const profile = discoverProfile(path.join(root, entry.name), root, personaRoot);\n      return profile ? [profile] : [];\n    });\n}\n\n/**\n * Loads profiles from the global and repository configs, repository last.\n *\n * Configured roots accumulate and inspect themselves or their direct-child\n * directories for persona files. Later discoveries replace earlier names, and\n * explicit entries replace discoveries. Legacy flat profile mappings remain\n * accepted as explicit entries.\n */\nexport function loadProfiles(repoRoot: string, homeDirectory: string = os.homedir()): AgentProfile[] {\n  const layers = readDoomConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);\n  const byName = new Map<string, AgentProfile>();\n\n  for (const layer of layers) {\n    for (const root of layer.roots) {\n      for (const profile of discoverProfileRoot(root, layer.baseDirectory)) byName.set(profile.name, profile);\n    }\n  }\n\n  for (const layer of layers) {\n    for (const [name, value] of Object.entries(layer.entries)) {\n      byName.set(name, parseProfile(layer.baseDirectory, layer.roots, name, value));\n    }\n  }\n\n  return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/**\n * The profile catalog: every resolved profile, plus the name a launch starts on\n * when the caller names none.\n *\n * `defaultProfile` mirrors `defaultMajorMode` in modes.yaml and `defaultDomains`\n * in domains.yaml, so each selection axis declares its default in its own\n * catalog. A repository declaration replaces a personal one. An unknown name is\n * an error rather than a silent fallback: a typo that quietly starts the session\n * with no persona is worse than a refused launch.\n */\nexport function loadProfileCatalog(\n  repoRoot: string,\n  homeDirectory: string = os.homedir(),\n): { profiles: AgentProfile[]; defaultProfile?: string } {\n  const layers = readDoomConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);\n  const profiles = loadProfiles(repoRoot, homeDirectory);\n  let defaultProfile: string | undefined;\n  for (const layer of layers) {\n    if (layer.defaultProfile !== undefined) defaultProfile = layer.defaultProfile;\n  }\n  if (defaultProfile !== undefined && !profiles.some((profile) => profile.name === defaultProfile)) {\n    throw new Error(`profiles.defaultProfile names an unknown profile: ${defaultProfile}`);\n  }\n  return { profiles, ...(defaultProfile === undefined ? {} : { defaultProfile }) };\n}\n\n/** Resolves one selected profile and fails clearly when its name is unknown. */\nexport function resolveProfile(repoRoot: string, name: string, homeDirectory?: string): AgentProfile {\n  const profile = loadProfiles(repoRoot, homeDirectory).find((candidate) => candidate.name === name);\n  if (!profile) throw new Error(`Unknown profile: ${name}`);\n  return profile;\n}\n\nexport function listProfileNames(repoRoot: string, homeDirectory?: string): string[] {\n  return loadProfiles(repoRoot, homeDirectory).map((profile) => profile.name);\n}\n\n/**\n * Reads the identity block from a persona's `profile.md`.\n *\n * Separate from `buildPersonaPrompt` because the prompt is assembled on several\n * paths that do not want the icon bytes, and because a persona that declares\n * nothing must stay exactly as cheap as it is today.\n */\nfunction readPersonaPresentation(\n  personaRoot: string,\n  personaDirectory: string,\n): { identity?: PersonaIdentity; voice?: PersonaVoiceOverride } {\n  const frontMatter = readPersonaFrontMatter(personaRoot, personaDirectory);\n  if (!frontMatter) return {};\n\n  const icon =\n    frontMatter.icon === undefined\n      ? undefined\n      : readPersonaIcon(path.join(personaRoot, personaDirectory), frontMatter.icon);\n  const identity: PersonaIdentity = {\n    ...(frontMatter.name === undefined ? {} : { name: frontMatter.name }),\n    ...(icon === undefined ? {} : { icon }),\n  };\n  return {\n    ...(identity.name === undefined && identity.icon === undefined ? {} : { identity }),\n    ...(frontMatter.voice === undefined ? {} : { voice: frontMatter.voice }),\n  };\n}\n\nfunction readPersonaFrontMatter(personaRoot: string, personaDirectory: string): PersonaFrontMatter | undefined {\n  try {\n    const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n    const filePath = path.join(personaPath, PERSONA_IDENTITY_FILE);\n    if (!fs.existsSync(filePath)) return undefined;\n    return parsePersonaFrontMatter(fs.readFileSync(fs.realpathSync(filePath), TEXT_ENCODING)).frontMatter;\n  } catch {\n    return undefined;\n  }\n}\n/** Builds the persona system-prompt block, or undefined when nothing is readable. */\nexport function buildPersonaPrompt(personaRoot: string, personaDirectory: string): string | undefined {\n  const sections: string[] = [];\n  const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n  for (const file of PERSONA_FILES) {\n    const filePath = path.join(personaPath, file);\n    if (!fs.existsSync(filePath)) continue;\n    const realFilePath = fs.realpathSync(filePath);\n    const relativeFilePath = path.relative(personaPath, realFilePath);\n    if (relativeFilePath === PARENT_DIRECTORY || relativeFilePath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)) {\n      throw new Error(`Persona file must stay inside ${personaDirectory}: ${file}`);\n    }\n    const raw = fs.readFileSync(realFilePath, TEXT_ENCODING);\n    // Only profile.md may declare identity, so only profile.md is stripped.\n    const content = (file === PERSONA_IDENTITY_FILE ? parsePersonaFrontMatter(raw).body : raw).trim();\n    if (content) sections.push(content);\n  }\n  if (sections.length === 0) return undefined;\n  return [`[PERSONA] You are operating as the person described below (source: ${personaDirectory}).`, ...sections].join(\n    '\\n\\n',\n  );\n}\n\n/** Applies profile environment defaults and returns only the values it contributed. */\nexport function applyProfileEnvironment(\n  environment: NodeJS.ProcessEnv,\n  defaults: Record<string, string>,\n): Record<string, string> {\n  const applied: Record<string, string> = {};\n  for (const [key, value] of Object.entries(defaults)) {\n    if (environment[key] !== undefined) continue;\n    environment[key] = value;\n    applied[key] = value;\n  }\n  return applied;\n}\n\n/** Replaces environment defaults previously contributed by another profile. */\nexport function replaceProfileEnvironment(\n  environment: NodeJS.ProcessEnv,\n  previous: Record<string, string>,\n  next: Record<string, string>,\n): Record<string, string> {\n  for (const [key, value] of Object.entries(previous)) {\n    if (environment[key] === value) delete environment[key];\n  }\n  return applyProfileEnvironment(environment, next);\n}\n"],"mappings":"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"}