/** * Where the celilo monorepo is, if we are inside one. * * Its own module because two unrelated consumers need it and neither may * import the other: `cli/build.ts` uses it to find modules to package, and * `doctor.ts` uses it to fingerprint the source a baked image came from — * and `build.ts` already imports `doctor.ts`, so the reverse edge would be a * cycle. Re-exported from `cli/build.ts` so its existing callers and its * recurrence test are unchanged. */ import { existsSync } from 'node:fs'; import { join, resolve } from 'node:path'; /** * Walk up from `startDir` to the celilo checkout, or null. * * The marker is `apps/celilo/package.json` and must stay that specific * (ce-dbc): keying on a bare `modules/` directory made a stray empty * `node_modules/modules` from a botched `bun add -g` read as the monorepo * root, which skipped the published-staging path and crashed the packer for * every npm consumer. */ export function findMonorepoRoot(startDir: string): string | null { let dir = startDir; for (let i = 0; i < 10; i++) { if (existsSync(join(dir, 'apps', 'celilo', 'package.json'))) return dir; const parent = resolve(dir, '..'); if (parent === dir) break; dir = parent; } return null; }