{"version":3,"file":"index.cjs","names":["execFileSync","os","path","SUBAGENT_CHILD_ENV","SUBAGENT_PARENT_SESSION_ENV","fs"],"sources":["../../../../src/services/paths/index.ts"],"sourcesContent":["import { execFile, execFileSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { SUBAGENT_CHILD_ENV, SUBAGENT_PARENT_SESSION_ENV } from '@agimon-ai/doompi-core/child-process';\n\nexport const STORE_PATH_ENV = 'DOOM_TASK_STORE';\n\nconst STORE_DIR_NAME = 'doom-task';\nconst STORE_FILE_NAME = 'tasks.json';\nconst DEFAULT_CONFIG_DIR_NAME = '.pi';\nconst AGENT_DIR_NAME = 'agent';\nconst PI_CODING_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR';\nconst HOME_ALIAS = '~';\nconst HOME_ALIAS_PREFIX = '~/';\nconst FILE_ENCODING = 'utf8';\nconst NOT_FOUND_ERROR_CODE = 'ENOENT';\n\nfunction git(args: string[], cwd: string): string | undefined {\n  try {\n    const output = execFileSync('git', args, {\n      cwd,\n      encoding: FILE_ENCODING,\n      stdio: ['ignore', 'pipe', 'ignore'],\n    });\n    const trimmed = output.trim();\n    return trimmed.length > 0 ? trimmed : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nasync function gitAsync(args: string[], cwd: string): Promise<string | undefined> {\n  return new Promise((resolve) => {\n    execFile('git', args, { cwd, encoding: FILE_ENCODING }, (error, stdout) => {\n      if (error) {\n        resolve(undefined);\n        return;\n      }\n      const trimmed = stdout.trim();\n      resolve(trimmed.length > 0 ? trimmed : undefined);\n    });\n  });\n}\n\nfunction resolveAgentDirectory(env: Readonly<Record<string, string | undefined>>): string {\n  const configured = env[PI_CODING_AGENT_DIR_ENV]?.trim();\n  if (configured === HOME_ALIAS) return os.homedir();\n  if (configured?.startsWith(HOME_ALIAS_PREFIX)) {\n    return path.join(os.homedir(), configured.slice(HOME_ALIAS_PREFIX.length));\n  }\n  return configured ? path.resolve(configured) : path.join(os.homedir(), DEFAULT_CONFIG_DIR_NAME, AGENT_DIR_NAME);\n}\n\nfunction isWithin(root: string, candidate: string): boolean {\n  const relative = path.relative(path.resolve(root), path.resolve(candidate));\n  return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\n/** Resolve the tree root without relying on extension startup order. */\nexport function resolveSessionKey(\n  rootSessionId: string,\n  env: Readonly<Record<string, string | undefined>> = process.env,\n): string {\n  if (!env[SUBAGENT_CHILD_ENV]) return rootSessionId;\n  const parentSessionId = env[SUBAGENT_PARENT_SESSION_ENV]?.trim();\n  if (!parentSessionId) throw new Error(`${SUBAGENT_PARENT_SESSION_ENV} is required in a subagent child`);\n  return parentSessionId;\n}\n\n/** Resolve one root session tree to a task document under the Pi agent directory. */\nexport function resolveStorePath(\n  _cwd: string = process.cwd(),\n  env: Readonly<Record<string, string | undefined>> = process.env,\n  sessionKey: string = 'standalone',\n): string {\n  const override = env[STORE_PATH_ENV]?.trim();\n  if (override) return path.resolve(override);\n\n  const trimmedSessionKey = sessionKey.trim();\n  if (!trimmedSessionKey) throw new Error('doom-task session id cannot be blank');\n  return path.join(resolveAgentDirectory(env), STORE_DIR_NAME, trimmedSessionKey, STORE_FILE_NAME);\n}\n\n/** Whether a deliberate unscoped task-store override is active. */\nexport function hasStorePathOverride(env: Readonly<Record<string, string | undefined>> = process.env): boolean {\n  return Boolean(env[STORE_PATH_ENV]?.trim());\n}\n\n/** Exact legacy Git-directory store, if the current working tree has one. */\nexport function resolveLegacyStoreDirectory(cwd: string = process.cwd()): string | undefined {\n  const commonDirectory = git(['rev-parse', '--path-format=absolute', '--git-common-dir'], cwd);\n  return commonDirectory ? path.join(commonDirectory, STORE_DIR_NAME) : undefined;\n}\n\nexport async function resolveLegacyStoreDirectoryAsync(cwd: string = process.cwd()): Promise<string | undefined> {\n  const commonDirectory = await gitAsync(['rev-parse', '--path-format=absolute', '--git-common-dir'], cwd);\n  return commonDirectory ? path.join(commonDirectory, STORE_DIR_NAME) : undefined;\n}\n\nexport interface StoreSweepResult {\n  removed: string[];\n  errors: string[];\n}\n\n/** Remove only the validated legacy Git store unless it contains the active override. */\nexport function removeLegacyStoreDirectory(currentStorePath: string, cwd: string = process.cwd()): StoreSweepResult {\n  const result: StoreSweepResult = { removed: [], errors: [] };\n  const target = resolveLegacyStoreDirectory(cwd);\n  if (!target || path.basename(target) !== STORE_DIR_NAME || isWithin(target, currentStorePath)) return result;\n\n  try {\n    if (!fs.existsSync(target)) return result;\n    fs.rmSync(target, { recursive: true, force: true });\n    result.removed.push(target);\n  } catch (error) {\n    result.errors.push(`Could not remove legacy task store ${target}: ${String(error)}`);\n  }\n  return result;\n}\n\nexport async function removeLegacyStoreDirectoryAsync(\n  currentStorePath: string,\n  cwd: string = process.cwd(),\n): Promise<StoreSweepResult> {\n  const result: StoreSweepResult = { removed: [], errors: [] };\n  const target = await resolveLegacyStoreDirectoryAsync(cwd);\n  if (!target || path.basename(target) !== STORE_DIR_NAME || isWithin(target, currentStorePath)) return result;\n\n  try {\n    await fs.promises.access(target);\n    await fs.promises.rm(target, { recursive: true, force: true });\n    result.removed.push(target);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) {\n      result.errors.push(`Could not remove legacy task store ${target}: ${String(error)}`);\n    }\n  }\n  return result;\n}\n\n/** Delete expired sibling session stores while preserving active or unreadable stores. */\nexport function sweepStoreFiles(currentStorePath: string, ttlMs: number, now: number = Date.now()): StoreSweepResult {\n  const result: StoreSweepResult = { removed: [], errors: [] };\n  const currentSessionDirectory = path.dirname(currentStorePath);\n  const storeDirectory = path.dirname(currentSessionDirectory);\n  let entries: string[];\n  try {\n    entries = fs.readdirSync(storeDirectory);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n    result.errors.push(`Could not read task store directory ${storeDirectory}: ${String(error)}`);\n    return result;\n  }\n\n  for (const entry of entries) {\n    const sessionDirectory = path.join(storeDirectory, entry);\n    const candidate = path.join(sessionDirectory, STORE_FILE_NAME);\n    if (sessionDirectory === currentSessionDirectory || !fs.existsSync(candidate)) continue;\n    try {\n      if (fs.existsSync(lockPathFor(candidate))) continue;\n      JSON.parse(fs.readFileSync(candidate, FILE_ENCODING));\n      if (now - fs.statSync(candidate).mtimeMs <= ttlMs) continue;\n      fs.rmSync(sessionDirectory, { recursive: true, force: true });\n      result.removed.push(sessionDirectory);\n    } catch (error) {\n      result.errors.push(`Could not sweep task store ${candidate}: ${String(error)}`);\n    }\n  }\n  return result;\n}\n\nexport async function sweepStoreFilesAsync(\n  currentStorePath: string,\n  ttlMs: number,\n  now: number = Date.now(),\n): Promise<StoreSweepResult> {\n  const result: StoreSweepResult = { removed: [], errors: [] };\n  const currentSessionDirectory = path.dirname(currentStorePath);\n  const storeDirectory = path.dirname(currentSessionDirectory);\n  let entries: string[];\n  try {\n    entries = await fs.promises.readdir(storeDirectory);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) return result;\n    result.errors.push(`Could not read task store directory ${storeDirectory}: ${String(error)}`);\n    return result;\n  }\n\n  for (const entry of entries) {\n    const sessionDirectory = path.join(storeDirectory, entry);\n    const candidate = path.join(sessionDirectory, STORE_FILE_NAME);\n    if (sessionDirectory === currentSessionDirectory) continue;\n    try {\n      await fs.promises.access(candidate);\n      try {\n        await fs.promises.access(lockPathFor(candidate));\n        continue;\n      } catch (error) {\n        if ((error as NodeJS.ErrnoException).code !== NOT_FOUND_ERROR_CODE) throw error;\n      }\n      JSON.parse(await fs.promises.readFile(candidate, FILE_ENCODING));\n      if (now - (await fs.promises.stat(candidate)).mtimeMs <= ttlMs) continue;\n      await fs.promises.rm(sessionDirectory, { recursive: true, force: true });\n      result.removed.push(sessionDirectory);\n    } catch (error) {\n      if ((error as NodeJS.ErrnoException).code === NOT_FOUND_ERROR_CODE) continue;\n      result.errors.push(`Could not sweep task store ${candidate}: ${String(error)}`);\n    }\n  }\n  return result;\n}\n\nexport function lockPathFor(storePath: string): string {\n  return `${storePath}.lock`;\n}\n\nexport function tempPathFor(storePath: string, pid: number = process.pid): string {\n  return `${storePath}.tmp.${pid}`;\n}\n"],"mappings":"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"}