/** * `totem install pack/` — pack install command (mmnto-ai/totem#1491). * * Executes the ADR-085 pack install flow: * 1. Validate the target syntax (`pack/name` or `pack/@scope/name`). * 2. Short-circuit if the pack is already in the `extends` array. * 3. Fetch the pack via the repo's existing package manager (pm-detection * mirrors `totem init`). * 4. Validate the pack manifest structure before mutating any repo state * outside `node_modules`. This ordering matters: if validation fails * we have not yet touched `totem.config.ts` or the local rules file, * so the user's repo stays in a clean state. * 5. Update the `extends` array in `totem.config.ts`. * 6. Merge pack rules into `.totem/compiled-rules.json` via the * mmnto-ai/totem#1515 `mergeRules` primitive. * 7. Merge `.totemignore` entries. Without `--yes` the command prints a * diff preview and skips the merge with a reminder; with `--yes` it * appends the missing entries. * * All errors thread the underlying cause through `TotemConfigError` so the * central error handler can present the full chain. */ import type { CompiledRule } from '@mmnto/totem'; /** * The activation hint printed after a successful `totem install` so the user * knows pack rules are inert until the first `totem lint` invokes the Stage 4 * verifier on their codebase. Exported as a named constant so tests can lock * the string byte-exactly per #1684 design-doc Invariant #8. */ export declare const PACK_INSTALL_ACTIVATION_MESSAGE = "Run `totem lint` to activate pack rules"; /** * Force every pack-supplied rule into `status: 'pending-verification'` for * the duration of the install. The pack's authoring environment (cloud * compile in particular) cannot have run Stage 4 against the consumer's * codebase, so any status it shipped is meaningless on the consumer side. * The first-lint promotion interceptor (mmnto-ai/totem#1684 T5) replaces * this status on first encounter; subsequent runs read the recorded * outcome from `.totem/verification-outcomes.json`. * * Returns a new array with new rule objects — never mutates the input. * Pure so it can be unit-tested without staging the full install flow. */ export declare function stampPackRulesAsPending(rules: readonly CompiledRule[]): CompiledRule[]; export declare function detectPackageManager(fs: { existsSync: (p: string) => boolean; }, path: { join: (...paths: string[]) => string; }, cwd: string): 'pnpm' | 'yarn' | 'bun' | 'npm'; /** * Resolve the npm package name from a `pack/` or `pack/@scope/` target. * Accepts raw npm names unchanged so callers that have already normalized * do not double-strip the prefix. */ export declare function resolvePackName(target: string): string; /** * Gate on the `pack/` or `pack/@scope/` shape. Rejects leading * hyphens in the name segment (a flag-injection hardening pair with the * `--` delimiter on the install invocation below). Rejects targets longer * than 214 chars per the npm package-name spec. */ export declare function isValidTarget(target: string): boolean; /** * Resolve the actual filesystem subpath declared under a package's * `exports['./compiled-rules.json']` entry. Accepts: * - `"./compiled-rules.json"` (plain string) * - `{ default: "./dist/compiled-rules.json" }` (single-condition object) * - `{ import: "./dist/foo.json", require: "./dist/foo.json" }` (first * string value wins; packs should not need multiple conditions for * a JSON payload but we accept it without choking) * * Returns null when the export value cannot be resolved to a usable * subpath, so the caller can produce a targeted error. Shield finding * on PR mmnto-ai/totem#1516: hardcoding `compiled-rules.json` bypassed the exports * contract and would mis-read packs that publish to a subdirectory. */ export declare function resolveCompiledRulesExport(exportValue: unknown): string | null; /** * Check whether the pack is already referenced inside the `extends` array. * Scoped to the array contents so that a comment or unrelated property * containing the same string does not short-circuit the install. * * Uses `stripComments` to locate the extends array range (so a * commented-out `// extends: [...]` line or string-literal content is * not mistaken for the active declaration), then searches the ORIGINAL * content at those offsets for the pack name — the stripped version * has scrubbed string contents and would miss real array entries. */ export declare function isInExtends(configContent: string, packName: string): boolean; /** * Build the `.totemignore` diff shown to the user when `--yes` is not * provided. Returns only the lines that would be appended. */ export declare function buildTotemignoreDiff(packIgnoreContent: string, localIgnoreContent: string): string[]; export interface InstallOptions { /** * Skip the interactive diff preview for the `.totemignore` merge and * append missing entries directly. Required in non-interactive contexts * (CI) per the mmnto-ai/totem#1491 AC. */ yes?: boolean; } export declare function installCommand(target: string, options?: InstallOptions): Promise; //# sourceMappingURL=install.d.ts.map