{"version":3,"file":"composed-pi.mjs","names":[],"sources":["../../src/extensions/composedPi.ts"],"sourcesContent":["import { disposeHarnessState } from '@agimon-ai/doompi-config/harnessStore';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\n// Imported from the module rather than the barrel: Pi loads this file directly\n// and it is the first thing a synced session runs, so it pulls in nothing it\n// does not use.\nimport {\n  type ComposeOutcome,\n  cleanupRunDirectory,\n  composeDoomSession,\n  findSyncedRoot,\n  registerDoomFlags,\n} from '../builders/cli/composition';\nimport { acquireCompositionClaim } from '../builders/cli/compositionState';\nconst WARNING = 'warning';\nconst STALE_MESSAGE = 'doompi config changed since the last sync. Run doompi sync.';\n\n/**\n * The one entry `doom-pi sync` puts in Pi's own config.\n *\n * Everything doom-pi contributes to a plain `pi` session is loaded from here,\n * which is what keeps `.pi/settings.json` to a single stable line and lets the\n * whole matrix be recomposed on `/reload` rather than frozen at startup.\n */\nexport async function doomExtension(pi: ExtensionAPI): Promise<void> {\n  const releaseClaim = acquireCompositionClaim();\n  if (!releaseClaim) return;\n\n  try {\n    registerDoomFlags(pi);\n    const outcome: ComposeOutcome = await composeDoomSession(pi);\n\n    // Reported on session_start rather than thrown: composition problems have to\n    // reach the user through the UI, and the UI does not exist yet at load time.\n    pi.on('session_start', (_event, ctx) => {\n      // Every configured factory has loaded. A later /reload gets a new claim,\n      // while a duplicate registration in this runner has already stood down.\n      releaseClaim();\n      for (const problem of outcome.problems) ctx.ui.notify(problem, WARNING);\n      if (outcome.stale) ctx.ui.notify(STALE_MESSAGE, WARNING);\n    });\n\n    pi.on('session_shutdown', async (event, ctx) => {\n      // Reload keeps the process and its deterministic run directory alive. The\n      // replacement session reuses both, so only terminal shutdown owns cleanup.\n      if (event.reason === 'reload') return;\n      const repoRoot = findSyncedRoot(ctx.cwd);\n      if (!repoRoot) return;\n      // The state file first, so nothing is left pointing at a path that is\n      // about to disappear, then the directory it lived in.\n      disposeHarnessState();\n      await cleanupRunDirectory(repoRoot);\n    });\n  } catch (error) {\n    // Pi discards a failed factory, including the session_start handler that\n    // would normally release ownership. Leave a retry or reload possible.\n    releaseClaim();\n    throw error;\n  }\n}\n\nexport default doomExtension;\n"],"mappings":";;;;;AAcA,MAAM,UAAU;AAChB,MAAM,gBAAgB;;;;;;;;AAStB,eAAsB,cAAc,IAAiC;CACnE,MAAM,eAAe,wBAAwB;CAC7C,IAAI,CAAC,cAAc;CAEnB,IAAI;EACF,kBAAkB,EAAE;EACpB,MAAM,UAA0B,MAAM,mBAAmB,EAAE;EAI3D,GAAG,GAAG,kBAAkB,QAAQ,QAAQ;GAGtC,aAAa;GACb,KAAK,MAAM,WAAW,QAAQ,UAAU,IAAI,GAAG,OAAO,SAAS,OAAO;GACtE,IAAI,QAAQ,OAAO,IAAI,GAAG,OAAO,eAAe,OAAO;EACzD,CAAC;EAED,GAAG,GAAG,oBAAoB,OAAO,OAAO,QAAQ;GAG9C,IAAI,MAAM,WAAW,UAAU;GAC/B,MAAM,WAAW,eAAe,IAAI,GAAG;GACvC,IAAI,CAAC,UAAU;GAGf,oBAAoB;GACpB,MAAM,oBAAoB,QAAQ;EACpC,CAAC;CACH,SAAS,OAAO;EAGd,aAAa;EACb,MAAM;CACR;AACF"}