{"version":3,"file":"upgrade-realign.mjs","names":[],"sources":["../../../src/services/scaffold/upgrade-realign.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { auditSessionPlane } from \"../resolution/plane-audit\";\nimport { type PlaneAuditLine, slotPublishKey } from \"../resolution/release-plane\";\nimport type { ResolutionSession } from \"../resolution/session\";\nimport { findWorkspaceRoot } from \"../workspace/workspace\";\n\n/**\n * The owned-slot realignment (the \"run bos plugin publish …\" repair, executed):\n * after an upgrade moves the framework version, owned slots built against the\n * old chain keep stale shared-singleton pins in the child's published config —\n * the divergence the dev audit reports and the #546 boot guard eventually\n * refuses. The upgrade closes the loop itself: audit the freshly resolved\n * plane, and for every owned slot still diverging, republish it through the\n * scoped deploy train (`bos deploy --packages <keys>`) from the newly\n * installed package.\n *\n * Best-effort by construction: no stored publish session skips the leg (the\n * repair stays a printed instruction), a failed republish is reported but\n * never fails the upgrade — the plane audit on the next `bos dev` still names\n * what remains.\n */\n\nexport interface OwnedRealignment {\n  /** Publish keys the audit found diverging (before any republish attempt). */\n  keys: string[];\n  /** Publish keys that republished successfully. */\n  realigned: string[];\n  failures: Array<{ key: string; error: string }>;\n}\n\nconst ownedKeysFrom = (lines: readonly PlaneAuditLine[]): string[] =>\n  [\n    ...new Set(\n      lines.filter((line) => line.kind === \"owned\").map((line) => slotPublishKey(line.slot)),\n    ),\n  ].sort();\n\n/** Detect owned slots the freshly resolved plane still finds diverging. */\nexport async function detectOwnedDivergentKeys(\n  session: NonNullable<ResolutionSession>,\n  options?: { fetchImpl?: typeof fetch },\n): Promise<{ keys: string[]; lines: PlaneAuditLine[] }> {\n  const lines = await auditSessionPlane(session, options);\n  return { keys: ownedKeysFrom(lines), lines };\n}\n\n/**\n * Republish `keys` through the scoped deploy train, running the freshly\n * installed bos binary. Output is forwarded to stderr — the migration phase\n * runs under `--json` re-exec, where stdout is the structured result.\n */\nexport async function realignOwnedSlots(\n  projectDir: string,\n  keys: readonly string[],\n  log: (message: string) => void = (message) => process.stderr.write(`${message}\\n`),\n): Promise<OwnedRealignment> {\n  const realigned: string[] = [];\n  const failures: OwnedRealignment[\"failures\"] = [];\n\n  if (!existsSync(join(projectDir, \".bos\", \"session.json\"))) {\n    log(\n      `  [realign] No stored CLI session in .bos/ — skipping the owned-slot republish of ${keys.join(\", \")}. Run \\`bos login\\`, then: bos deploy --packages ${keys.join(\",\")}`,\n    );\n    return { keys: [...keys], realigned, failures };\n  }\n\n  const workspaceDir = findWorkspaceRoot(projectDir)?.dir ?? projectDir;\n  const bosBin = join(workspaceDir, \"node_modules\", \".bin\", \"bos\");\n  if (!existsSync(bosBin)) {\n    log(`  [realign] bos binary not found at ${bosBin} — skipping the owned-slot republish`);\n    return { keys: [...keys], realigned, failures };\n  }\n\n  log(`  [realign] Republishing owned slots built against the old chain: ${keys.join(\", \")}`);\n  const child = spawnSync(bosBin, [\"deploy\", \"--packages\", keys.join(\",\")], {\n    cwd: projectDir,\n    stdio: [\"inherit\", \"pipe\", \"pipe\"],\n    encoding: \"utf-8\",\n    env: { ...process.env, BOS_NO_BANNER: \"1\" },\n  });\n  if (child.stdout) process.stderr.write(child.stdout);\n  if (child.stderr) process.stderr.write(child.stderr);\n\n  if (child.status === 0) {\n    realigned.push(...keys);\n  } else {\n    failures.push({\n      key: keys.join(\",\"),\n      error: `bos deploy --packages exited ${child.status ?? \"n/a\"}`,\n    });\n    log(`  [realign] Republish failed — realign by hand: bos deploy --packages ${keys.join(\",\")}`);\n  }\n  return { keys: [...keys], realigned, failures };\n}\n"],"mappings":";;;;;;;;;AAiCA,MAAM,iBAAiB,UACrB,CACE,GAAG,IAAI,IACL,MAAM,QAAQ,SAAS,KAAK,SAAS,OAAO,CAAC,CAAC,KAAK,SAAS,eAAe,KAAK,IAAI,CAAC,CACvF,CACF,CAAC,CAAC,KAAK;;AAGT,eAAsB,yBACpB,SACA,SACsD;CACtD,MAAM,QAAQ,MAAM,kBAAkB,SAAS,OAAO;CACtD,OAAO;EAAE,MAAM,cAAc,KAAK;EAAG;CAAM;AAC7C;;;;;;AAOA,eAAsB,kBACpB,YACA,MACA,OAAkC,YAAY,QAAQ,OAAO,MAAM,GAAG,QAAQ,GAAG,GACtD;CAC3B,MAAM,YAAsB,CAAC;CAC7B,MAAM,WAAyC,CAAC;CAEhD,IAAI,CAAC,WAAW,KAAK,YAAY,QAAQ,cAAc,CAAC,GAAG;EACzD,IACE,qFAAqF,KAAK,KAAK,IAAI,EAAE,mDAAmD,KAAK,KAAK,GAAG,GACvK;EACA,OAAO;GAAE,MAAM,CAAC,GAAG,IAAI;GAAG;GAAW;EAAS;CAChD;CAEA,MAAM,eAAe,kBAAkB,UAAU,CAAC,EAAE,OAAO;CAC3D,MAAM,SAAS,KAAK,cAAc,gBAAgB,QAAQ,KAAK;CAC/D,IAAI,CAAC,WAAW,MAAM,GAAG;EACvB,IAAI,uCAAuC,OAAO,qCAAqC;EACvF,OAAO;GAAE,MAAM,CAAC,GAAG,IAAI;GAAG;GAAW;EAAS;CAChD;CAEA,IAAI,qEAAqE,KAAK,KAAK,IAAI,GAAG;CAC1F,MAAM,QAAQ,UAAU,QAAQ;EAAC;EAAU;EAAc,KAAK,KAAK,GAAG;CAAC,GAAG;EACxE,KAAK;EACL,OAAO;GAAC;GAAW;GAAQ;EAAM;EACjC,UAAU;EACV,KAAK;GAAE,GAAG,QAAQ;GAAK,eAAe;EAAI;CAC5C,CAAC;CACD,IAAI,MAAM,QAAQ,QAAQ,OAAO,MAAM,MAAM,MAAM;CACnD,IAAI,MAAM,QAAQ,QAAQ,OAAO,MAAM,MAAM,MAAM;CAEnD,IAAI,MAAM,WAAW,GACnB,UAAU,KAAK,GAAG,IAAI;MACjB;EACL,SAAS,KAAK;GACZ,KAAK,KAAK,KAAK,GAAG;GAClB,OAAO,gCAAgC,MAAM,UAAU;EACzD,CAAC;EACD,IAAI,yEAAyE,KAAK,KAAK,GAAG,GAAG;CAC/F;CACA,OAAO;EAAE,MAAM,CAAC,GAAG,IAAI;EAAG;EAAW;CAAS;AAChD"}