{"version":3,"file":"bootstrapClaim.mjs","names":[],"sources":["../../../src/builders/cli/bootstrapClaim.ts"],"sourcesContent":["import path from 'node:path';\n\n/**\n * Process-wide ownership of one repository's DoomPi load cycle.\n *\n * Pi unions the extension lists of its user and project settings scopes and\n * dedupes only by the resolved file's real path, so registering DoomPi in both\n * scopes loads two separate installs of the same package. Each one would\n * otherwise read, recompile, and rewrite the same home-scoped worktree state\n * for the same repository, and two installs at different versions disagree about the state\n * contract. A process-global symbol survives the distinct module URLs those\n * installs have, so the first factory owns the cycle and the rest stand down.\n * Pi resolves project resources before user ones, which makes the owner the\n * repository-local install whenever both scopes register the package.\n */\n\nconst BOOTSTRAP_CLAIM_KEY = Symbol.for('@agimon-ai/doompi:bootstrap-claim');\n\nexport type ReleaseBootstrapClaim = () => void;\n\n/**\n * The registry shared by every DoomPi install in this process.\n *\n * The symbol description is part of the cross-install contract and must stay\n * exactly as written: two installs only meet here when they compute the same\n * key. A value of another shape belongs to an install that spelled the\n * registry differently, so this one starts its own rather than corrupting it.\n */\nfunction claimRegistry(): Map<string, symbol> {\n  const existing = Reflect.get(globalThis, BOOTSTRAP_CLAIM_KEY);\n  if (existing instanceof Map) return existing as Map<string, symbol>;\n  const created = new Map<string, symbol>();\n  Reflect.set(globalThis, BOOTSTRAP_CLAIM_KEY, created);\n  return created;\n}\n\n/**\n * Claims the load cycle for one repository, or reports that it is already owned.\n *\n * Callers must acquire before their first `await`, because releasing happens on\n * `session_start` and an interleaved second factory would otherwise slip in.\n */\nexport function acquireBootstrapClaim(repoRoot: string): ReleaseBootstrapClaim | undefined {\n  const registry = claimRegistry();\n  const key = path.resolve(repoRoot);\n  if (registry.has(key)) return undefined;\n\n  const claim = Symbol('doompi-bootstrap');\n  registry.set(key, claim);\n  return () => {\n    if (registry.get(key) === claim) registry.delete(key);\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAM,sBAAsB,OAAO,IAAI,mCAAmC;;;;;;;;;AAY1E,SAAS,gBAAqC;CAC5C,MAAM,WAAW,QAAQ,IAAI,YAAY,mBAAmB;CAC5D,IAAI,oBAAoB,KAAK,OAAO;CACpC,MAAM,0BAAU,IAAI,IAAoB;CACxC,QAAQ,IAAI,YAAY,qBAAqB,OAAO;CACpD,OAAO;AACT;;;;;;;AAQA,SAAgB,sBAAsB,UAAqD;CACzF,MAAM,WAAW,cAAc;CAC/B,MAAM,MAAM,KAAK,QAAQ,QAAQ;CACjC,IAAI,SAAS,IAAI,GAAG,GAAG,OAAO,KAAA;CAE9B,MAAM,QAAQ,OAAO,kBAAkB;CACvC,SAAS,IAAI,KAAK,KAAK;CACvB,aAAa;EACX,IAAI,SAAS,IAAI,GAAG,MAAM,OAAO,SAAS,OAAO,GAAG;CACtD;AACF"}