/**
 * Move a loaded skill between storage levels.
 *
 * `promote` copies a project-level skill up to the global/personal config
 * dir, making it available in every repo on the machine. `demote` copies a
 * global (or built-in) skill down into the current project's `.nanocoder/`
 * so it gets committed and travels with the repo.
 *
 * Both directions reduce to one copy: a bundle copies its `<name>/`
 * directory, a single-file skill copies its one `.md` into the matching
 * flat dir (`commands|agents|tools`). The skill registry only holds the
 * shadow-winning copy, so destination-existence is checked directly on disk
 * and an overwrite requires an explicit `force`.
 *
 * See `/skills promote` / `/skills demote` in `source/commands/skills.tsx`.
 */
import type { Skill } from '../types/skills.js';
export type PromoteDirection = 'promote' | 'demote';
export type SkillLevel = 'global' | 'project';
export interface PromotionPlan {
    skillName: string;
    shape: 'single-file' | 'bundle';
    /** Current level the skill resolves from. */
    fromLevel: 'built-in' | 'personal' | 'project';
    /** Level the copy is written to. */
    toLevel: SkillLevel;
    source: string;
    dest: string;
}
/**
 * Validate the requested move and resolve concrete source/dest paths.
 * Returns either a ready-to-apply plan or a human-readable error.
 */
export declare function planPromotion(skill: Skill, direction: PromoteDirection, projectRoot: string): {
    plan: PromotionPlan;
} | {
    error: string;
};
export interface ApplyOptions {
    /** Overwrite an existing destination instead of refusing. */
    force?: boolean;
    /** Remove the source after a successful copy (move instead of copy). */
    move?: boolean;
}
export interface ApplyResult {
    ok: boolean;
    /** True when the destination already exists and `force` was not set. */
    destExists?: boolean;
    /** True when the source was removed (a `move`). */
    moved?: boolean;
    error?: string;
}
/**
 * Execute a plan. Refuses to overwrite an existing destination unless
 * `force` is true, so a promoted skill never clobbers a different copy at
 * the target level by accident. When `move` is set, the source is removed
 * after the copy succeeds, leaving only the destination copy.
 */
export declare function applyPromotion(plan: PromotionPlan, opts?: ApplyOptions): Promise<ApplyResult>;
//# sourceMappingURL=promote.d.ts.map