/** * `installed-packs.json` writer (mmnto-ai/totem#1768, Step 4). * * Walks two source surfaces โ€” the consumer's `package.json` dependencies * for `@mmnto/pack-*` entries, and the consumer's `totem.config.ts` * `extends` array โ€” deduplicates, resolves each pack's installed path * via npm/pnpm semantics, and writes `.totem/installed-packs.json` for * `pack-discovery.ts:loadInstalledPacks()` to consume at boot. * * Mismatch handling (ADR-097 ยง 5 Q4 + Open Question 4 disposition): * - In both surfaces: union, no warning. * - In `extends` only (declared but not resolvable via npm): emit a * warning naming the pack; skip from the manifest. Consumer must * `pnpm add` the pack to make it work. * - In `package.json` only (resolvable but not declared in extends): * emit a warning; skip from the manifest. Pack-merge only consumes * `extends`-declared packs; including the dep-only entry would be * misleading. * * Atomic write semantics: the writer goes through a temp file + * rename, mirroring `writeReviewExtensionsFile` (mmnto-ai/totem#1527). * * Filesystem access happens at the CLI boundary (this module is invoked * by `syncCommand`); the resolver itself takes paths + content as * inputs so tests can drive it without disk I/O. */ import type { TotemConfig } from './config-schema.js'; import type { InstalledPacksManifest } from './pack-discovery.js'; export interface PackResolutionWarning { /** Pack name surfaced in the warning. */ readonly name: string; /** * Why the pack didn't make it to the manifest. Two shapes: * * - `dep-only`: present in package.json but not declared in * `totem.config.ts` `extends`. Skipped because pack-merge only * consumes `extends`-declared packs. * - `extends-only`: declared in `extends` but not installed * (`require.resolve` failed). Skipped because the engine cannot * load it. * - `not-a-pack`: present somewhere but doesn't expose a `register` * callback (default export or named `register` function). Skipped * because pack-discovery would throw on first attempt. */ readonly reason: 'dep-only' | 'extends-only' | 'not-a-pack'; } export interface PackResolutionResult { /** Packs that landed in the manifest (sorted by name). */ readonly resolved: InstalledPacksManifest['packs']; /** Per-pack warnings for the consumer (sorted by name). */ readonly warnings: readonly PackResolutionWarning[]; } export interface ResolveInstalledPacksInput { /** Project root (where `package.json` lives). */ readonly projectRoot: string; /** Loaded totem config (read for `extends`). */ readonly config: TotemConfig; /** * Optional override for the package.json read. Tests pass a synthetic * dependencies map; production callers leave it undefined and the * function reads `/package.json`. */ readonly packageJsonDeps?: Readonly>; /** * Optional override for the require resolver. Tests stub this to * resolve fixture packs without writing to `node_modules`; production * callers use the default which delegates to `createRequire`. */ readonly resolvePackPath?: (name: string, fromDir: string) => string | undefined; } /** * Compute the deduplicated union of `package.json` `@mmnto/pack-*` deps * and `totem.config.ts` `extends` entries. Returns the manifest payload * shape ready for `installed-packs.json` plus per-pack warnings for any * surface mismatch. * * Pure function โ€” no filesystem write. The CLI integration calls * `writeInstalledPacksManifest()` to persist. */ export declare function resolveInstalledPacks(input: ResolveInstalledPacksInput): PackResolutionResult; /** * Atomically write `/installed-packs.json` with the given * manifest payload. Mirrors `writeReviewExtensionsFile` semantics: temp * file + rename so a concurrent boot-time read sees the old or new * contents, never a partial write. * * Stamps the `cohort` field with the running `@mmnto/totem` version * via `resolveEngineVersion()` when the caller has not pre-populated * one (mmnto-ai/totem#1811). Tests pass an explicit cohort to override * the stamp. */ export declare function writeInstalledPacksManifest(totemDirAbs: string, manifest: InstalledPacksManifest): string; //# sourceMappingURL=pack-manifest-writer.d.ts.map