// Planu — parallel safety engine (SPEC-373)
import { execSync } from 'node:child_process';
import { existsSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
export function getRepoRoot(cwd) {
    try {
        return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf8' }).trim();
    }
    catch {
        return null;
    }
}
export function detectCurrentWorktreeId(cwd) {
    const repoRoot = getRepoRoot(cwd);
    if (!repoRoot) {
        return null;
    }
    const normalCwd = cwd.replace(/\/$/, '');
    const normalRoot = repoRoot.replace(/\/$/, '');
    if (normalCwd === normalRoot) {
        return null;
    }
    const match = /agent-([a-f0-9]+)$/.exec(normalCwd);
    return match ? (match[1] ?? null) : null;
}
export function getActiveWorktreeIds(projectPath) {
    const worktreesDir = join(projectPath, '.claude', 'worktrees');
    if (!existsSync(worktreesDir)) {
        return [];
    }
    try {
        return readdirSync(worktreesDir, { withFileTypes: true })
            .filter((d) => d.isDirectory() && d.name.startsWith('agent-'))
            .map((d) => d.name.replace('agent-', ''));
    }
    catch {
        return [];
    }
}
export function generateSafeAgentNames(numAgents, activeIds, currentId) {
    const blocked = new Set([...activeIds, ...(currentId ? [currentId] : [])]);
    const names = [];
    let attempt = 0;
    while (names.length < numAgents && attempt < 1000) {
        const ts = Date.now().toString(16).slice(-6);
        const rand = Math.floor(Math.random() * 0xffff)
            .toString(16)
            .padStart(4, '0');
        const id = `${ts}${rand}`;
        if (!blocked.has(id)) {
            names.push(`safe-agent-${id}`);
            blocked.add(id);
        }
        attempt++;
    }
    return names;
}
export function checkParallelSafety(cwd, projectPath, numAgents = 6) {
    const currentWorktreeId = detectCurrentWorktreeId(cwd);
    const isInsideWorktree = currentWorktreeId !== null;
    const activeWorktreeIds = getActiveWorktreeIds(projectPath);
    const safeAgentNames = generateSafeAgentNames(numAgents, activeWorktreeIds, currentWorktreeId);
    let riskLevel = 'safe';
    const recommendations = [];
    if (isInsideWorktree) {
        riskLevel = 'danger';
        const prefix = currentWorktreeId ? currentWorktreeId.slice(0, 8) : '';
        recommendations.push(`You are running inside worktree 'agent-${currentWorktreeId}'. Do NOT use isolation:worktree for subagents — use named branches instead.`, `Use the provided safeAgentNames as the 'name:' parameter for each Agent tool call to avoid collisions.`, `If you must use isolation:worktree, ensure each agent has a unique name that does NOT start with '${prefix}'.`);
    }
    else if (activeWorktreeIds.length > 0) {
        riskLevel = 'warning';
        recommendations.push(`${activeWorktreeIds.length} active worktrees detected. Use the provided safeAgentNames to avoid collisions.`);
    }
    else {
        recommendations.push('Environment is safe for parallel agent execution with isolation:worktree.');
    }
    return {
        isInsideWorktree,
        currentWorktreeId,
        activeWorktreeIds,
        safeAgentNames,
        riskLevel,
        recommendations,
    };
}
export const PARALLEL_WORKTREE_SAFETY_RULE = `# parallel-worktree-safety

## Problem
When Claude Code runs inside a worktree (.claude/worktrees/agent-XXXX) and launches subagents
with \`isolation: "worktree"\`, a silent collision can occur if the new agent receives an ID whose
prefix matches the parent session's worktree. The result: the agent writes into the parent
session's worktree instead of a new one, and the work is lost when the worktree is cleaned up.

## Solution
Before launching parallel agents, call \`check_parallel_safety\` to:
1. Detect if you're inside a worktree
2. Get a list of safe agent names that won't collide
3. Use those names as the \`name:\` parameter in Agent tool calls

## Rules
- NEVER use \`isolation: "worktree"\` when already inside a worktree
- ALWAYS pass explicit \`name:\` to Agent tool calls when running parallel sessions
- USE \`check_parallel_safety\` at session start if launching 3+ parallel agents
- IF in a worktree, use manual branch strategy instead of isolation:worktree
`;
//# sourceMappingURL=parallel-safety-engine.js.map