export const codeDebugRunDescriptor = { toolName: "code.debugRun", toolId: "code.debugRun", toolFamily: "codeBase.debugCode", purpose: "launch or attach a debug run through runtime-owned debug support", dryRunOnly: false, unsafeSideEffects: false };
function sv(value) { return typeof value === "string" ? value : undefined; }
function blank(value) { return typeof value !== "string" || value.trim().length === 0; }
function list(values) { return Array.isArray(values) ? [...new Set(values.map((value) => (typeof value === "string" ? value.trim() : "")).filter(Boolean))] : []; }
function failure(code, message, boundary) { return { ok: false, error: { code, message, boundary, safeForRuntimeInspection: true, internalDetailExposed: false }, events: ["agentCore.basicTool.code.debugRun.rejected"] }; }
function auditEvent(type, normalized, metadata) { return { type, toolId: "code.debugRun", invocationId: normalized?.invocationId ?? "code.debugRun:unknown", dryRun: normalized?.dryRun ?? true, metadata: { ...(normalized?.context.auditMetadata ?? {}), ...(metadata ?? {}) } }; }
function toolFailure(code, message, boundary, normalized) { return { ok: false, toolId: "code.debugRun", error: { code, message, boundary, safeForRuntimeInspection: true, internalDetailExposed: false }, audit: [auditEvent("agentCore.basicTool.code.debugRun.rejected", normalized, { code, boundary })], events: ["agentCore.basicTool.code.debugRun.rejected"] }; }
function normalizeCommand(command) { if (command === undefined)
    return []; if (!Array.isArray(command))
    return failure("INVALID_COMMAND", "code.debugRun command must be an array of safe strings", "input"); const out = []; for (const arg of command) {
    if (typeof arg !== "string" || arg.trim().length === 0 || arg.includes("\0"))
        return failure("INVALID_COMMAND", "code.debugRun command entries must be non-empty safe strings", "input");
    out.push(arg.trim());
} return out; }
function normalizeBreakpoints(breakpoints) { const out = []; for (const [index, breakpoint] of (breakpoints ?? []).entries()) {
    if (blank(breakpoint.file) || !Number.isInteger(breakpoint.line) || (breakpoint.line ?? 0) < 1)
        return failure("INVALID_BREAKPOINT", `code.debugRun breakpoint ${index} requires file and positive line`, "input");
    out.push({ file: breakpoint.file?.trim() ?? "", line: breakpoint.line ?? 1 });
} return out; }
function normalizeEnv(value) { if (value === undefined)
    return undefined; if (typeof value !== "object" || value === null || Array.isArray(value))
    return failure("INVALID_ENVIRONMENT", "code.debugRun environment must be a string record", "input"); const env = {}; for (const [key, entry] of Object.entries(value)) {
    if (typeof entry !== "string" || key.trim().length === 0 || key.includes("\0") || entry.includes("\0"))
        return failure("INVALID_ENVIRONMENT", "code.debugRun environment must be a string record", "input");
    env[key] = entry;
} return env; }
function rejected(...gates) { return gates.find((gate) => gate?.accepted === false || gate?.allowed === false); }
function approved(...gates) { return gates.some((gate) => gate?.accepted === true || gate?.allowed === true); }
function normalizeTimeout(value) { if (value !== undefined && typeof value !== "number")
    return failure("INVALID_TIMEOUT", "code.debugRun timeoutMs must be a positive integer", "input"); const timeout = value ?? 30_000; if (!Number.isInteger(timeout) || timeout < 1 || timeout > 600_000)
    return failure("INVALID_TIMEOUT", "code.debugRun timeoutMs must be between 1 and 600000", "input"); return timeout; }
function normalize(request = {}) {
    const context = request.context ?? {};
    const runtimeId = sv(context.runtimeId ?? request.runtimeId)?.trim() ?? "";
    const sessionId = sv(context.sessionId ?? request.sessionId)?.trim() ?? "";
    if (runtimeId.length === 0)
        return failure("MISSING_RUNTIME_ID", "code.debugRun requires runtimeId", "input");
    if (sessionId.length === 0)
        return failure("MISSING_SESSION_ID", "code.debugRun requires sessionId", "input");
    if (request.target === undefined || request.target.kind === undefined)
        return failure("MISSING_DEBUG_TARGET", "code.debugRun requires a debug target kind", "input");
    const command = normalizeCommand(request.target.command);
    if ("ok" in command)
        return command;
    if (blank(request.target.label) && blank(request.target.entrypoint) && command.length === 0)
        return failure("MISSING_TARGET_LABEL", "code.debugRun requires a label, entrypoint, or command", "input");
    const deniedGate = rejected(request.contract, request.governance, request.guard, context.guard);
    if (deniedGate !== undefined)
        return failure(deniedGate === request.contract ? "CONTRACT_REJECTED" : "GOVERNANCE_REJECTED", deniedGate.reason ?? "code.debugRun was rejected by runtime governance", deniedGate === request.contract ? "contract" : "governance");
    const breakpoints = normalizeBreakpoints(request.breakpoints);
    if (!Array.isArray(breakpoints))
        return breakpoints;
    const env = normalizeEnv(request.environment);
    if (env !== undefined && "ok" in env)
        return env;
    const normalizedEnv = env;
    const timeoutMs = normalizeTimeout(request.timeoutMs);
    if (typeof timeoutMs !== "number")
        return timeoutMs;
    const requested = list(context.requestedScopes ?? request.requestedScopes);
    const allowed = list(context.allowedScopes ?? request.allowedScopes);
    const denied = requested.filter((scope) => !allowed.includes(scope));
    if (denied.length > 0)
        return failure("SCOPE_DENIED", `debug run scope ${denied[0]} is outside runtime governance`, "scope");
    const label = request.target.label?.trim() || request.target.entrypoint?.trim() || command.join(" ");
    const plannedSteps = ["validate-debug-target", "prepare-breakpoints", "prepare-redacted-environment", request.target.kind === "attach" ? "plan-debug-attach" : "plan-debug-launch", "handoff-to-tap-governance"];
    return { runtimeId, sessionId, invocationId: sv(context.invocationId ?? request.invocationId)?.trim() || `${runtimeId}:${sessionId}:code.debugRun`, target: { kind: request.target.kind, label, entrypoint: request.target.entrypoint?.trim() || undefined, command, cwd: request.target.cwd?.trim() || undefined }, breakpoints, environmentKeys: list(Object.keys(normalizedEnv ?? {})), dryRun: request.dryRun !== false && context.dryRun !== false, context, environment: normalizedEnv, timeoutMs, plannedSteps };
}
function planFrom(n) { return { toolName: "code.debugRun", runtimeId: n.runtimeId, sessionId: n.sessionId, invocationId: n.invocationId, target: n.target, breakpoints: n.breakpoints, environmentKeys: n.environmentKeys, permissions: ["debug:read", "debug:run"], execution: { dryRun: true, launched: false, attached: false, unsafeSideEffects: false }, plannedSteps: n.plannedSteps, audit: { governanceRequired: true, tapHandoffReady: true }, storage: { logic: { persisted: false }, records: [{ toolName: "code.debugRun" }] } }; }
function empty(n) { return { kind: "agentCore.basicTool.code.debugRun.output", runtimeId: n.runtimeId, sessionId: n.sessionId, invocationId: n.invocationId, target: n.target, breakpoints: n.breakpoints, environmentKeys: n.environmentKeys, timeoutMs: n.timeoutMs, runtimeEntry: { owner: "runtime", port: "BaseToolExecutorPort.debug.launch", method: "launch" }, dryRun: true, providerCalled: false, state: "planned", eventsPreview: [], unsafeSideEffects: false }; }
export function planCodeDebugRun(request = {}) { if (request.dryRun === false || request.context?.dryRun === false)
    return failure("REAL_DEBUG_RUN_NOT_ALLOWED", "planCodeDebugRun only creates a dry-run debug run envelope", "governance"); const n = normalize(request); if ("ok" in n)
    return n; return { ok: true, plan: planFrom(n), events: ["agentCore.basicTool.code.debugRun.planned"] }; }
export async function executeCodeDebugRun(request = {}) {
    const n = normalize(request);
    if ("ok" in n)
        return toolFailure(n.error.code, n.error.message, n.error.boundary);
    if (n.dryRun)
        return { ok: true, toolId: "code.debugRun", output: empty(n), audit: [auditEvent("agentCore.basicTool.code.debugRun.planned", n)], events: ["agentCore.basicTool.code.debugRun.planned"] };
    if (!approved(request.guard, request.governance, n.context.guard))
        return toolFailure("GOVERNANCE_REJECTED", "code.debugRun real launch requires an affirmative runtime guard", "governance", n);
    if (request.provider === undefined)
        return toolFailure("PROVIDER_UNAVAILABLE", "code.debugRun requires runtime debug.launch support", "provider", n);
    try {
        const result = await request.provider({ target: n.target, breakpoints: n.breakpoints, environment: n.environment, timeoutMs: n.timeoutMs }, n.context);
        return { ok: true, toolId: "code.debugRun", output: { ...empty(n), dryRun: false, providerCalled: true, debugSessionId: result.debugSessionId, state: result.state, breakpointsAccepted: result.breakpointsAccepted, eventsPreview: (result.events ?? []).slice(0, 20) }, audit: [auditEvent("agentCore.basicTool.code.debugRun.completed", n, { debugSessionId: result.debugSessionId })], events: ["agentCore.basicTool.code.debugRun.completed"] };
    }
    catch {
        return toolFailure("PROVIDER_FAILURE", "code.debugRun provider failed while launching the runtime-owned debug session", "provider", n);
    }
}
