import { createRun, createRunStore, createTask, getActiveRun, runDir, updateTask } from "../features/run-state/index.js";
import { appendEvent } from "../features/observability/index.js";
import { ensureTeamRuntime, recordTeamMemberLaunch } from "../features/team-mode/index.js";
import { formatLabMeetingNotice, initializeLabMeetingState, triggerLabMeetingNow } from "../features/lab-meeting/index.js";
import { seedRuntimeLanguageInstruction } from "../features/language/index.js";
import { buildSeedStatusBoard } from "../features/status-board/index.js";
import { recordSeedCommandSession } from "./command-mode.js";
import { formatLabMeetingBackgroundCompletionFollowup, requestBackgroundCompletionFromActiveBackgrounds } from "./lab-meeting-control.js";
export function createCommandExecuteBeforeHandler(ctx) {
    const store = createRunStore(ctx.input.directory, ctx.config);
    return async function commandExecuteBefore(input, output) {
        if (!isSeedCommand(input.command))
            return;
        const normalizedArguments = normalizeSeedCommandArguments(input.command, input.arguments);
        recordSeedCommandSession(ctx, input.sessionID, {
            args: normalizedArguments,
            source: "command_execute_before",
        });
        const text = await handleSeedCommand(ctx, store, {
            ...input,
            arguments: normalizedArguments,
        });
        output.parts = [
            {
                id: `seed-command-${Date.now()}`,
                sessionID: input.sessionID,
                messageID: `seed-command-${input.sessionID}`,
                type: "text",
                text,
                synthetic: true,
            },
        ];
    };
}
const seedCommandAliases = {
    "seed-status": "status",
    "seed-lab-meeting": "lab-meeting",
};
function isSeedCommand(command) {
    return command === "seed" || Object.prototype.hasOwnProperty.call(seedCommandAliases, command);
}
function normalizeSeedCommandArguments(command, args) {
    const trimmed = args.trim();
    const prefix = seedCommandAliases[command];
    if (!prefix)
        return trimmed;
    return [prefix, trimmed].filter(Boolean).join(" ");
}
async function handleSeedCommand(ctx, store, input) {
    const args = input.arguments.trim();
    const [, ...rest] = splitArgs(args);
    if (input.command === "seed-status") {
        return buildSeedStatusBoard(store, rest[0]);
    }
    if (input.command === "seed-lab-meeting") {
        const active = await getActiveRun(store);
        const runId = rest.find((token) => token.startsWith("seed_")) ?? active?.run_id;
        if (!runId)
            return "No active SEED run found.";
        const result = await triggerLabMeetingNow(store, runId, "manual");
        const followup = result.state?.status === "wrap_up"
            ? await requestBackgroundCompletionFromActiveBackgrounds({ directory: ctx.input.directory, client: ctx.input.client, worktree: ctx.input.worktree }, store, runId, {
                sessionId: input.sessionID,
                meetingId: result.state.current_meeting_id,
            })
            : undefined;
        return `${formatLabMeetingNotice(result)}${followup ? `\n\n${formatLabMeetingBackgroundCompletionFollowup(followup)}` : ""}`;
    }
    const model = ctx.modelBySession.get(input.sessionID);
    const run = await createRun(store, {
        goal: args || "SEED lab run",
        sessionId: input.sessionID,
        modelProvider: model?.providerID,
        modelId: model?.modelID,
        modelVariant: model?.variant,
        runMode: "coordinator",
    });
    await initializeLabMeetingState(store, run.run_id);
    await ensureTeamRuntime(store, run.run_id);
    await recordTeamMemberLaunch(store, run.run_id, ctx.config.default_run_agent, {
        status: "active",
        session_id: input.sessionID,
        resolved_agent: ctx.config.default_run_agent,
        opencode_agent: ctx.config.default_run_agent,
    });
    const task = await createTask(store, run.run_id, {
        title: "Complete professor goal",
        description: run.professor_goal,
        owner_agent: ctx.config.default_run_agent,
        priority: 1,
        acceptance_criteria: run.acceptance_criteria,
    });
    const primaryTask = await updateTask(store, run.run_id, task.task_id, { status: "in_progress" });
    await appendEvent(store, run.run_id, {
        type: "work_started",
        actor: ctx.config.default_run_agent,
        session_id: input.sessionID,
        summary: "Professor goal accepted through /seed",
        related_task_id: primaryTask.task_id,
    });
    return `SEED run ${run.run_id} started.

Run directory: ${runDir(store, run.run_id)}
Professor goal: ${run.professor_goal}
Primary task: ${primaryTask.task_id}

Lab-Representative instructions:
- Use the primary task above with seed_task_update; create additional tasks only for genuine subtasks or delegated work.
- Operate the automation loop yourself: call SEED workers/tools/scripts/MCPs, read outputs/errors, and continue until the primary task is completed or a real blocker is recorded.
- For substantial tasks, synthesize a dynamic inline team spec, validate it, then launch it with seed_team_create; do not assume a built-in task-specific workflow template. After the spec is accepted, do not fall back to raw seed_delegate* team formation unless seed_team_create is blocked or failed with a recorded reason.
- Follow up with existing team members by role id, and add new members only when the task reveals missing expertise.
- Do not ask the professor to copy-paste prompts between agents; use SEED team/mailbox/meeting/follow-up tools for agent-to-agent work so team/conversation.jsonl records explicit from/to traffic.
- For long-running background work, use seed_background_checkpoint for compact progress updates instead of waiting blindly or treating duration as failure.
- ${seedRuntimeLanguageInstruction(ctx.config)}
- If a required Linux dependency is missing, recover deliberately: inspect the tool error and environment, identify candidate binaries/packages for the current distro, use seed_tool_policy_check when useful, and only then attempt a bounded non-interactive install through seed_run_script when package manager, network, permissions, and policy allow it. Do not assume a hard-coded package manager or package name. If installation is blocked, record the blocker with the exact command the professor/admin can run.
- Check source/MCP/search evidence before implementation decisions. For substantial research/document-analysis tasks, record whether websearch/webfetch was used or deliberately skipped.
- Delegate to SEED lab researchers when useful.
- Keep progress.md and final_report.md current.
- Final claims must cite task, tool, agent, or evidence records.`;
}
function splitArgs(input) {
    return input.split(/\s+/).filter(Boolean);
}
//# sourceMappingURL=command-execute-before.js.map