{"version":3,"file":"init-DUwZV5Ob.mjs","names":[],"sources":["../src/services/init/index.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from '../config';\n\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst PRIVATE_FILE_MODE = 0o600;\nconst REPOSITORY_DIRECTORY_MODE = 0o755;\nconst REPOSITORY_FILE_MODE = 0o644;\nconst DOOM_DIRECTORY = '.doom';\nconst UTF8_ENCODING = 'utf8';\nconst FILE_ALREADY_EXISTS = 'EEXIST';\nconst FILE_NOT_FOUND = 'ENOENT';\n\n/** The global seed files are processed in this fixed order. */\nexport const GLOBAL_DOOM_SEED_FILES = ['config.yaml', 'modes.yaml', 'domains.yaml', 'profiles.yaml'] as const;\n\ntype DoomSeedFile = (typeof GLOBAL_DOOM_SEED_FILES)[number];\n\n/** Portable defaults for a new global Doom configuration directory. */\nexport const DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>> = {\n  'config.yaml': `projectTrust: ask\n\n# Autonomous voice is opt-in and uses an explicitly configured Pi model.\n# voice:\n#   autoCapture:\n#     model: provider/model-id\n#     startPhrases:\n#       - hey doom\n#     stopPhrases:\n#       - stop speaking\n#     utteranceIdleMs: 3000\n#     # Long prompts only: open a draft, keep talking, then send it in one piece.\n#     # Short utterances are delivered as you finish them and need no phrase.\n#     composeOpenPhrases:\n#       - hey doom\n#     composeSendPhrases:\n#       - that's it\n#     composeCancelPhrases:\n#       - scratch that\n#     # Endpoint window while a draft collects, so a short command lands on its own.\n#     composeUtteranceIdleMs: 1200\n#     # Silence before Voice reminds you a draft is open. 0 turns the reminder off.\n#     composeNudgeMs: 10000\n#     tts:\n#       engine: macos-say\n#       voice: Samantha\n#       rate: 190\n`,\n  'modes.yaml': `# A layer is a reusable named bundle of packages, built-in or local extensions,\n# and hook groups. Major modes below choose which layers load together for a session.\n#\n# Layers and modes defined here apply to every repository. A repository's own\n# .doom/modes.yaml is read after this file and replaces any layer or mode of the\n# same name, so a repository can override one entry without restating the rest.\n#\n# Add a layer by giving it a unique name under layers. Local Pi scripts belong\n# under extensions, while installed Pi packages belong under packages:\n#   review-tools:\n#     extensions:\n#       - './extensions/local-review.ts'\n#     packages:\n#       - '@scope/review-extension'\n# A bare extension name selects a DoomPi built-in. A path beginning with ./ or\n# ../ loads a custom script or extension directory. A bare package loads its\n# ordered package.json pi.extensions entries, while an exported subpath selects\n# one adapter. Relative paths resolve beside this file here (~/.pi/.doom), or\n# from the repository root in .doom/modes.yaml.\n#\n# Use a package mapping when that package accepts configuration. Configuration\n# belongs under the package entry that consumes it, not beside packages.\n# The top-level default bundle loads before every major mode. Replace this whole\n# packages list to customize the distribution defaults. DoomPi core packages\n# remain active independently of this list.\ndefault:\n  packages:\n    - '@agimon-ai/doompi-help'\n    - '@agimon-ai/doompi-hook'\n    - '@agimon-ai/doompi-goal'\n    - '@agimon-ai/doompi-voice'\n    - '@agimon-ai/doompi-runner'\n    - '@agimon-ai/doompi-read'\n    - '@agimon-ai/doompi-grep'\n    - '@agimon-ai/doompi-edit'\n    - '@agimon-ai/doompi-file-edit'\n    - '@agimon-ai/doompi-autocompact'\n    - '@agimon-ai/doompi-loop'\n    - '@agimon-ai/doompi-plan'\n    - '@agimon-ai/doompi-workflow'\n    - '@agimon-ai/doompi-log'\n    - '@agimon-ai/doompi-mcp'\n    - '@agimon-ai/doompi-template-elegant'\nlayers:\n  team:\n    packages:\n      - name: '@agimon-ai/doompi-team'\n        # Optional Team configuration. Uncomment and choose models available to Pi.\n        # config:\n        #   models:\n        #     - model: openai-codex/gpt-5.6-luna\n        #       thinking: xhigh\n        #   # Tool names excluded from subagents launched by this package. These\n        #   # remove model-visible tools while preserving hidden team transport.\n        #   excludeTools: [ask_user_question, intercom, subagent]\n  ask-user:\n    packages:\n      - '@agimon-ai/doompi-user-feedback'\n  task:\n    packages:\n      - '@agimon-ai/doompi-task'\n# A major mode explains when it should be used and names its ordered layers.\n# Add another entry under majorMode, then select it with\n# doompi --major-mode <name>. Change defaultMajorMode to make it the default.\ndefaultMajorMode: copilot\nmajorMode:\n  minimal:\n    description: Lean mode with Team delegation and persistent tasks.\n    layers: [team, task]\n  copilot:\n    description: General-purpose coding mode with Team delegation, persistent tasks, supervised commands, and structured user feedback.\n    layers: [team, ask-user, task]\n  # review:\n  #   description: Focused review mode for inspecting changes and reporting risks.\n  #   layers: [team, task, ask-user]\n`,\n  'domains.yaml': `# Plugins are named once in this catalog, then selected by one or more domains.\n# DoomPi automatically inspects personal and repository Codex marketplaces.\n# Each configured root may also be a folder whose direct children are plugins;\n# use roots: [plugins] to discover a repository plugin folder without one entry\n# per plugin. Discovery never scans recursively.\ndefaultDomains: [default]\nplugins:\n  roots: []\n  entries: {}\n  # Local paths resolve beside this file in ~/.pi/.doom. Repository paths in a\n  # repository .doom/domains.yaml resolve from that repository root.\n  # entries:\n  #   development:\n  #     source: local\n  #     path: plugins/development\n  #   remote-review:\n  #     source: url\n  #     url: https://github.com/acme/review-plugin.git\n  #     ref: v1.2.0\n  #   published-review:\n  #     source: npm\n  #     package: '@acme/review-plugin'\n  #     version: 1.2.0\n# Domains carry descriptions and refer to catalog names, not filesystem paths.\ndomains:\n  default:\n    description: Shared skills and repository MCP only.\n    plugins: []\n  # development:\n  #   description: TypeScript implementation and review tools.\n  #   plugins:\n  #     - development\n  #     # Mapping form can load only selected resources from a shared plugin.\n  #     - name: remote-review\n  #       skills: [typescript]\n  #       agents: [reviewer]\n  #       hooks: false\n  #       mcp: true\n  #   # Set false only when this domain should omit shared .claude/skills.\n  #   sharedSkills: false\n  #   # Domain mcp is an allowlist over servers configured elsewhere, not a\n  #   # request to start new ones. Listing servers here drops the tool schemas\n  #   # of the ones left out, usually the largest context saving a domain can\n  #   # make. Run doompi --explain to see the token cost before and after.\n  #   # Filtering applies only when every selected domain declares mcp, so a\n  #   # selection mixing this with a domain that omits it stays unfiltered.\n  #   mcp:\n  #     servers: [code-intel]\n  #     proxy: [repository-search]\n# Select it with doompi --domains development, or add it to defaultDomains.\n#\n# Aliases let one selection enable multiple domains. Replace the empty mapping\n# below with entries like the commented example.\naliases: {}\n# aliases:\n#   work: [default, development]\n`,\n  'profiles.yaml': `# Profiles select a persona and optional environment defaults for a session.\n# Each configured root may itself be a profile or contain direct-child profile\n# folders. A folder is discovered when it contains profile.md, SOUL.md, or\n# AGENTS.md; discovery never scans recursively.\nprofiles:\n  roots: []\n  entries: {}\n  # Roots resolve beside this file in ~/.pi/.doom. Repository roots in a\n  # repository .doom/profiles.yaml resolve from that repository root.\n  # roots: [agents/acme]\n  # Explicit entries override an automatically discovered folder of the same\n  # name. Environment values must be strings; already exported values win.\n  # entries:\n  #   writer:\n  #     persona: agents/special/writer\n  #     env:\n  #       BRAND: acme\n  #       TONE: concise\n# Doom Pi concatenates profile.md, SOUL.md, then AGENTS.md for the persona.\n# Select one with: doompi --profile writer\n`,\n};\n\n/** Standalone defaults for a repository that is trying DoomPi through DPI. */\nexport const REPOSITORY_DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>> = {\n  'config.yaml': DOOM_CONFIG_TEMPLATES['config.yaml'],\n  'modes.yaml': `# Repository-local layers and major modes. These entries override personal\n# entries with the same name from ~/.pi/.doom/modes.yaml.\n# This repository-local default replaces the personal top-level default as one\n# whole package list. Edit it to customize the standalone package baseline.\ndefault:\n  packages:\n    - '@agimon-ai/doompi-help'\n    - '@agimon-ai/doompi-hook'\n    - '@agimon-ai/doompi-goal'\n    - '@agimon-ai/doompi-voice'\n    - '@agimon-ai/doompi-runner'\n    - '@agimon-ai/doompi-read'\n    - '@agimon-ai/doompi-grep'\n    - '@agimon-ai/doompi-edit'\n    - '@agimon-ai/doompi-file-edit'\n    - '@agimon-ai/doompi-autocompact'\n    - '@agimon-ai/doompi-loop'\n    - '@agimon-ai/doompi-plan'\n    - '@agimon-ai/doompi-workflow'\n    - '@agimon-ai/doompi-log'\n    - '@agimon-ai/doompi-mcp'\n    - '@agimon-ai/doompi-template-elegant'\nlayers:\n  team:\n    packages:\n      - name: '@agimon-ai/doompi-team'\n  ask-user:\n    packages:\n      - '@agimon-ai/doompi-user-feedback'\n  task:\n    packages:\n      - '@agimon-ai/doompi-task'\ndefaultMajorMode: copilot\nmajorMode:\n  minimal:\n    description: Lean mode with Team delegation and persistent tasks.\n    layers: [team, task]\n  copilot:\n    description: General-purpose coding mode with delegation, persistent tasks, supervised commands, and structured user feedback.\n    layers: [team, ask-user, task]\n`,\n  'domains.yaml': `# Repository-local plugin catalog and domain selection.\ndefaultDomains: [default]\nplugins:\n  roots: []\n  entries: {}\ndomains:\n  default:\n    description: Shared skills and repository MCP only.\n    plugins: []\naliases: {}\n`,\n  'profiles.yaml': `# Repository-local persona roots and environment defaults.\nprofiles:\n  roots: []\n  entries: {}\n`,\n};\n\n/** Result of filling a Doom seed directory. File arrays contain names in seed order. */\nexport interface GlobalDoomInitResult {\n  directory: string;\n  created: string[];\n  preserved: string[];\n  /** Existing files overwritten from the template. Only ever non-empty under `force`. */\n  replaced: string[];\n}\n\nexport interface GlobalDoomInitOptions {\n  /**\n   * Overwrite existing seed files instead of preserving them.\n   *\n   * Off by default: init is safe to re-run, and hand-edited config is the\n   * normal case rather than the exception.\n   */\n  force?: boolean;\n}\n\nexport type RepositoryDoomInitOptions = GlobalDoomInitOptions;\nexport type RepositoryDoomInitResult = GlobalDoomInitResult;\n\nfunction errorCode(error: unknown): string | undefined {\n  if (!(error instanceof Error)) return undefined;\n  const code = (error as NodeJS.ErrnoException).code;\n  return typeof code === 'string' ? code : undefined;\n}\n\nfunction ensureDirectory(directory: string, mode: number): void {\n  let stats: fs.Stats;\n  try {\n    stats = fs.lstatSync(directory);\n  } catch (error) {\n    if (errorCode(error) !== FILE_NOT_FOUND) throw error;\n    try {\n      fs.mkdirSync(directory, { mode });\n      stats = fs.lstatSync(directory);\n    } catch (mkdirError) {\n      if (errorCode(mkdirError) !== FILE_ALREADY_EXISTS) throw mkdirError;\n      stats = fs.lstatSync(directory);\n    }\n  }\n\n  if (stats.isSymbolicLink()) {\n    throw new Error(`Refusing to initialize through symlinked directory: ${directory}`);\n  }\n  if (!stats.isDirectory()) {\n    throw new Error(`Doom config path is not a directory: ${directory}`);\n  }\n}\n\nfunction ensureDoomDirectory(directory: string, mode: number): void {\n  ensureDirectory(path.dirname(directory), mode);\n  ensureDirectory(directory, mode);\n}\n\nfunction classifyTarget(targetPath: string): 'missing' | 'file' {\n  let stats: fs.Stats;\n  try {\n    stats = fs.lstatSync(targetPath);\n  } catch (error) {\n    if (errorCode(error) === FILE_NOT_FOUND) return 'missing';\n    throw error;\n  }\n\n  if (stats.isFile()) return 'file';\n  if (stats.isSymbolicLink()) {\n    try {\n      if (fs.statSync(targetPath).isFile()) return 'file';\n    } catch (error) {\n      throw new Error(`Doom config seed symlink is not file-like: ${targetPath}`, { cause: error });\n    }\n  }\n  throw new Error(`Doom config seed path is not file-like: ${targetPath}`);\n}\n\nfunction cleanupTemporaryFile(temporaryPath: string): void {\n  try {\n    fs.unlinkSync(temporaryPath);\n  } catch (error) {\n    if (errorCode(error) !== FILE_NOT_FOUND) throw error;\n  }\n}\n\nfunction publishExclusively(targetPath: string, content: string, mode: number): boolean {\n  const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n  let fileDescriptor: number | undefined;\n  try {\n    fileDescriptor = fs.openSync(temporaryPath, 'wx', mode);\n    fs.writeFileSync(fileDescriptor, content, UTF8_ENCODING);\n    fs.fchmodSync(fileDescriptor, mode);\n    fs.fsyncSync(fileDescriptor);\n    const descriptorToClose = fileDescriptor;\n    fileDescriptor = undefined;\n    fs.closeSync(descriptorToClose);\n\n    try {\n      fs.linkSync(temporaryPath, targetPath);\n      return true;\n    } catch (error) {\n      if (errorCode(error) === FILE_ALREADY_EXISTS && classifyTarget(targetPath) === 'file') return false;\n      throw error;\n    }\n  } finally {\n    if (fileDescriptor !== undefined) {\n      const descriptorToClose = fileDescriptor;\n      fileDescriptor = undefined;\n      fs.closeSync(descriptorToClose);\n    }\n    cleanupTemporaryFile(temporaryPath);\n  }\n}\n\n/**\n * Replaces a seed file with the template, atomically.\n *\n * The rename swaps the directory entry in one step, so a reader either sees the\n * whole old file or the whole new one. Renaming onto a symlinked seed replaces\n * the link rather than writing through it.\n */\nfunction publishForcefully(targetPath: string, content: string, mode: number): void {\n  const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n  let fileDescriptor: number | undefined;\n  try {\n    fileDescriptor = fs.openSync(temporaryPath, 'wx', mode);\n    fs.writeFileSync(fileDescriptor, content, UTF8_ENCODING);\n    fs.fchmodSync(fileDescriptor, mode);\n    fs.fsyncSync(fileDescriptor);\n    const descriptorToClose = fileDescriptor;\n    fileDescriptor = undefined;\n    fs.closeSync(descriptorToClose);\n\n    fs.renameSync(temporaryPath, targetPath);\n  } finally {\n    if (fileDescriptor !== undefined) {\n      const descriptorToClose = fileDescriptor;\n      fileDescriptor = undefined;\n      fs.closeSync(descriptorToClose);\n    }\n    cleanupTemporaryFile(temporaryPath);\n  }\n}\n\nfunction initializeDoomConfig(\n  directory: string,\n  templates: Readonly<Record<DoomSeedFile, string>>,\n  options: GlobalDoomInitOptions,\n  directoryMode: number,\n  fileMode: number,\n): GlobalDoomInitResult {\n  ensureDoomDirectory(directory, directoryMode);\n\n  const created: string[] = [];\n  const preserved: string[] = [];\n  const replaced: string[] = [];\n  for (const fileName of GLOBAL_DOOM_SEED_FILES) {\n    const targetPath = path.join(directory, fileName);\n    const existed = classifyTarget(targetPath) === 'file';\n\n    if (options.force) {\n      publishForcefully(targetPath, templates[fileName], fileMode);\n      (existed ? replaced : created).push(fileName);\n      continue;\n    }\n    if (existed) {\n      preserved.push(fileName);\n      continue;\n    }\n    if (publishExclusively(targetPath, templates[fileName], fileMode)) created.push(fileName);\n    else preserved.push(fileName);\n  }\n\n  return { directory, created, preserved, replaced };\n}\n\n/**\n * Fills missing global seed files.\n *\n * Existing files are left alone so that re-running init never discards\n * hand-edited config; pass `force` to overwrite them from the template.\n */\nexport function initializeGlobalDoomConfig(\n  homeDirectory = os.homedir(),\n  options: GlobalDoomInitOptions = {},\n): GlobalDoomInitResult {\n  return initializeDoomConfig(\n    globalDoomConfigDirectory(homeDirectory),\n    DOOM_CONFIG_TEMPLATES,\n    options,\n    PRIVATE_DIRECTORY_MODE,\n    PRIVATE_FILE_MODE,\n  );\n}\n\n/** Seeds repository-local configuration without creating or changing Pi settings. */\nexport function initializeRepositoryDoomConfig(\n  repositoryRoot = process.cwd(),\n  options: RepositoryDoomInitOptions = {},\n): RepositoryDoomInitResult {\n  return initializeDoomConfig(\n    path.join(path.resolve(repositoryRoot), DOOM_DIRECTORY),\n    REPOSITORY_DOOM_CONFIG_TEMPLATES,\n    options,\n    REPOSITORY_DIRECTORY_MODE,\n    REPOSITORY_FILE_MODE,\n  );\n}\n"],"mappings":"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"}