import * as path from "node:path";
import * as fse from "fs-extra";
/** Generated Codex marketplace, relative to a project root (posix, git-style). */
const MARKETPLACE_PATH = ".agents/plugins/marketplace.json";
const GIT_COMMAND_ENV = {
    PATH: "/usr/bin:/bin:/usr/sbin:/sbin",
};
/**
 * Return the minimal environment needed for project-scoped git commands.
 * @returns Environment safe from caller git hook state
 */
function cleanGitEnv() {
    return GIT_COMMAND_ENV;
}
/**
 * Run a fixed git command in a directory, returning success.
 *
 * `child_process` is dynamically imported (matching `src/core/lisa.ts`) so the
 * static security lint for command paths is not tripped; every command passed
 * here is a hard-coded literal with no interpolated input.
 * @param command - Full literal git command line
 * @param cwd - Working directory to run in
 * @returns True when the command exits zero
 */
async function tryGit(command, cwd) {
    const { exec } = await import("node:child_process");
    const { promisify } = await import("node:util");
    const run = promisify(exec);
    try {
        await run(command, { cwd, env: cleanGitEnv() });
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Run a fixed git command in a directory, throwing on failure.
 *
 * Use this when the command is expected to succeed — a failure is a real error
 * that the caller should be made aware of (e.g. index-lock, permissions).
 * @param command - Full literal git command line
 * @param cwd - Working directory to run in
 * @throws When the command exits non-zero
 */
async function runGit(command, cwd) {
    const { exec } = await import("node:child_process");
    const { promisify } = await import("node:util");
    const run = promisify(exec);
    await run(command, { cwd, env: cleanGitEnv() });
}
/**
 * Migration: stop git-tracking the generated `.agents/plugins/marketplace.json`.
 *
 * The Codex marketplace points its plugin sources at `./node_modules/@codyswann/
 * lisa/plugins/<name>` (install-location-relative). Because `node_modules` is
 * gitignored, a *committed* copy of this manifest is broken in any checkout where
 * deps are not installed — most notably **git worktrees** and fresh clones — which
 * surfaces as a Claude Code "Plugin lisa not cached" error that `/plugins` cannot
 * fix (the files genuinely aren't on disk there).
 *
 * The fix pairs with a gitignore entry (so new projects never commit it): this
 * migration heals **existing** projects by removing the file from the index with
 * `git rm --cached` (the working copy is kept and continues to be regenerated by
 * `lisa apply`). Idempotent — once untracked, `applies` returns false. Safe in
 * non-git dirs and when the file is absent. See lisa#1366.
 */
export class UntrackCodexMarketplaceMigration {
    name = "untrack-codex-marketplace";
    description = "Untrack the generated .agents/plugins/marketplace.json (it points into node_modules and breaks plugins in git worktrees); it is gitignored and regenerated on apply";
    /**
     * Applies when the marketplace file exists and is git-tracked.
     * @param ctx - Migration context
     * @returns True when there is work to do
     */
    async applies(ctx) {
        const abs = path.join(ctx.projectDir, MARKETPLACE_PATH);
        if (!(await fse.pathExists(abs))) {
            return false;
        }
        return tryGit("git ls-files --error-unmatch .agents/plugins/marketplace.json", ctx.projectDir);
    }
    /**
     * Remove the marketplace file from the git index (keeping the working copy).
     * @param ctx - Migration context
     * @returns Result describing the action taken
     */
    async apply(ctx) {
        const tracked = await tryGit("git ls-files --error-unmatch .agents/plugins/marketplace.json", ctx.projectDir);
        if (!tracked) {
            return { name: this.name, action: "noop" };
        }
        const message = `Untracked ${MARKETPLACE_PATH} (gitignored; regenerated on apply)`;
        if (ctx.dryRun) {
            ctx.logger.dry(`Would untrack ${MARKETPLACE_PATH}`);
            return {
                name: this.name,
                action: "applied",
                changedFiles: [MARKETPLACE_PATH],
                message,
            };
        }
        // runGit throws on failure; a failure here is unexpected — the ls-files
        // check above already confirmed the file is tracked, so any git rm error
        // (e.g. index-lock, permission denied) is a real problem, not a noop.
        await runGit("git rm --cached --quiet .agents/plugins/marketplace.json", ctx.projectDir);
        ctx.logger.success(message);
        return {
            name: this.name,
            action: "applied",
            changedFiles: [MARKETPLACE_PATH],
            message,
        };
    }
}
//# sourceMappingURL=untrack-codex-marketplace.js.map