import { findActionInputFieldHint, filterResolvedActionOptions, getActionSpecForCatalogSurface, getSerializedActionSpecForSurface, searchSerializedActionSpecsForSurface, serializeActionFieldOptions, } from './actionCatalog.js';
import { resolveRequestedSessionModeId } from './sessionModeIds.js';
import { ActionSurfaceSchema, getActionSpec, isActionSpecSurfacedOn } from './actionSpecs.js';
import { ApprovalRequestV1Schema } from '../approvals/approvalRequestV1.js';
import { BackendTargetKeySchema, buildBackendTargetKey, parseBackendTargetKey } from '../backendTargets/backendTargetRef.js';
import { SessionHandoffWorkspaceTransferSchema, } from '../sessionControl/handoff/handoffSchemas.js';
import { SessionControlErrorCodeSchema } from '../sessionControl/contract.js';
function normalizeId(raw) {
    return String(raw ?? '').trim();
}
const ActionSurfaceKeySchema = ActionSurfaceSchema.keyof();
function parseActionSurfaceKey(value) {
    const parsed = ActionSurfaceKeySchema.safeParse(value);
    return parsed.success ? parsed.data : null;
}
function resolveSessionIdFromInput(input, ctx) {
    const sessionId = normalizeId(input?.sessionId);
    if (sessionId)
        return sessionId;
    const fallback = normalizeId(ctx.defaultSessionId);
    return fallback || null;
}
function mapApprovalCreatedBySurface(surface) {
    if (surface === 'voice_tool' || surface === 'voice_action_block')
        return 'voice';
    if (surface === 'session_agent')
        return 'session_agent';
    if (surface === 'mcp')
        return 'mcp';
    if (surface === 'cli')
        return 'cli';
    // UI surfaces (and unknown surfaces) map to `system`.
    return 'system';
}
function buildApprovalSummary(spec, sessionId) {
    const base = String(spec.title ?? '').trim() || String(spec.id);
    return sessionId ? `${base} — ${sessionId}` : base;
}
function extractListedSessions(value) {
    const sessions = Array.isArray(value?.sessions)
        ? value.sessions
        : Array.isArray(value?.items)
            ? value.items
            : [];
    return sessions
        .map((session) => {
        const id = normalizeId(session?.id);
        const title = normalizeId(session?.title ?? session?.label);
        if (!id || !title)
            return null;
        return { id, title };
    })
        .filter(Boolean);
}
async function resolveSessionIdByTitle(deps, rawSessionTitle) {
    const sessionTitle = normalizeId(rawSessionTitle);
    if (!sessionTitle)
        return { kind: 'not_found' };
    let cursor = null;
    let matchedSessionId = null;
    for (let page = 0; page < 20; page += 1) {
        const response = await deps.sessionList({ limit: 100, ...(cursor ? { cursor } : {}) });
        for (const session of extractListedSessions(response)) {
            if (session.title !== sessionTitle)
                continue;
            if (matchedSessionId && matchedSessionId !== session.id) {
                return { kind: 'ambiguous' };
            }
            matchedSessionId = session.id;
        }
        const nextCursor = normalizeId(response?.nextCursor);
        if (!nextCursor)
            break;
        cursor = nextCursor;
    }
    return matchedSessionId ? { kind: 'resolved', sessionId: matchedSessionId } : { kind: 'not_found' };
}
function resolveServerIdForSession(deps, ctx, sessionId) {
    const explicit = normalizeId(ctx.serverId);
    if (explicit)
        return explicit;
    return deps.resolveServerIdForSessionId ? deps.resolveServerIdForSessionId(sessionId) : null;
}
function normalizeResolvedOptions(value) {
    const items = Array.isArray(value?.items)
        ? value.items
        : Array.isArray(value)
            ? value
            : [];
    return items
        .map((item) => {
        const valueCandidate = typeof item?.targetKey === 'string'
            ? item.targetKey
            : typeof item?.value === 'string'
                ? item.value
                : typeof item?.id === 'string'
                    ? item.id
                    : typeof item?.agentId === 'string'
                        ? item.agentId
                        : typeof item?.engineId === 'string'
                            ? item.engineId
                            : null;
        if (!valueCandidate)
            return null;
        const labelCandidate = typeof item?.label === 'string'
            ? item.label
            : typeof item?.title === 'string'
                ? item.title
                : valueCandidate;
        const descriptionCandidate = typeof item?.description === 'string' ? item.description : undefined;
        const disabledCandidate = item?.disabled === true || item?.enabled === false ? true : undefined;
        return {
            value: valueCandidate,
            label: labelCandidate,
            ...(descriptionCandidate ? { description: descriptionCandidate } : {}),
            ...(disabledCandidate ? { disabled: true } : {}),
        };
    })
        .filter(Boolean);
}
function normalizeExecutionBackendOptionValue(value) {
    const parsed = BackendTargetKeySchema.safeParse(value);
    if (parsed.success)
        return parsed.data;
    return buildBackendTargetKey({ kind: 'builtInAgent', agentId: value });
}
async function resolveDynamicActionOptions(params) {
    const { deps, ctx, optionsSourceId, input } = params;
    if (optionsSourceId === 'execution.backends.enabled') {
        const result = await deps.agentsBackendsList({
            ...(typeof input.includeDisabled === 'boolean' ? { includeDisabled: input.includeDisabled } : { includeDisabled: false }),
            ...(typeof input.limit === 'number' ? { limit: input.limit } : {}),
        });
        return {
            ok: true,
            result: normalizeResolvedOptions(result).map((option) => ({
                ...option,
                value: normalizeExecutionBackendOptionValue(option.value),
            })),
        };
    }
    if (optionsSourceId === 'review.engines.available') {
        const sessionId = resolveSessionIdFromInput(input, ctx);
        if (!sessionId)
            return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
        const result = await deps.reviewEnginesList({
            sessionId,
            ...(typeof input.includeDisabled === 'boolean' ? { includeDisabled: input.includeDisabled } : {}),
        });
        return { ok: true, result: normalizeResolvedOptions(result) };
    }
    if (optionsSourceId === 'session.modes.available') {
        const sessionId = resolveSessionIdFromInput(input, ctx);
        if (!sessionId)
            return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
        const result = await deps.sessionModesList({ sessionId });
        return { ok: true, result: normalizeResolvedOptions(result) };
    }
    return { ok: false, errorCode: 'options_source_not_supported', error: 'options_source_not_supported' };
}
function normalizeSuccessfulFanoutStartResult(result) {
    if (result
        && typeof result === 'object'
        && result.ok === true
        && result.data
        && typeof result.data === 'object') {
        return result.data;
    }
    return result;
}
function readFanoutStartError(result) {
    const errorCode = result
        && typeof result === 'object'
        && typeof result.errorCode === 'string'
        ? String(result.errorCode)
        : result
            && typeof result === 'object'
            && typeof result.code === 'string'
            ? String(result.code)
            : undefined;
    const error = result
        && typeof result === 'object'
        && typeof result.error === 'string'
        ? String(result.error)
        : result
            && typeof result === 'object'
            && typeof result.message === 'string'
            ? String(result.message)
            : 'execution_run_failed';
    return {
        error,
        ...(errorCode ? { errorCode } : {}),
    };
}
async function fanoutStarts(params) {
    const results = await Promise.all(params.keys.map(async (key) => {
        try {
            const rawResult = await params.startOne(key);
            const result = normalizeSuccessfulFanoutStartResult(rawResult);
            if (result && typeof result === 'object' && result.ok === false) {
                return {
                    key,
                    ok: false,
                    ...readFanoutStartError(result),
                };
            }
            if (result
                && typeof result === 'object'
                && (typeof result.runId !== 'string'
                    || typeof result.callId !== 'string'
                    || typeof result.sidechainId !== 'string')) {
                return {
                    key,
                    ok: false,
                    ...readFanoutStartError(result),
                };
            }
            return { key, ok: true, result };
        }
        catch (error) {
            return { key, ok: false, error: error instanceof Error ? error.message : 'execution_run_failed' };
        }
    }));
    return results;
}
function buildApprovalDecisionResult(request) {
    return {
        ok: true,
        result: {
            ok: true,
            status: request.status,
            ...(request.execution ? { execution: request.execution } : {}),
        },
    };
}
function resolveApprovalRequestExecutionSurface(createdBySurface) {
    if (createdBySurface === 'session_agent')
        return 'session_agent';
    if (createdBySurface === 'mcp')
        return 'mcp';
    if (createdBySurface === 'voice')
        return 'voice_tool';
    if (createdBySurface === 'cli')
        return 'cli';
    return null;
}
function normalizeActionExecutorThrownError(error) {
    const anyErr = error;
    const rawCode = typeof anyErr?.code === 'string' ? String(anyErr.code).trim() : '';
    const message = error instanceof Error
        ? error.message
        : typeof error === 'string'
            ? error
            : typeof anyErr?.message === 'string'
                ? String(anyErr.message)
                : '';
    if (rawCode && SessionControlErrorCodeSchema.safeParse(rawCode).success) {
        return { errorCode: rawCode, error: message || rawCode };
    }
    // Common network failures from axios/node.
    if (rawCode && ['ECONNREFUSED', 'ECONNRESET', 'ENOTFOUND', 'EAI_AGAIN', 'ETIMEDOUT'].includes(rawCode)) {
        return { errorCode: 'server_unreachable', error: message || 'server_unreachable' };
    }
    return { errorCode: 'action_failed', error: message || 'action_failed' };
}
export function createActionExecutor(deps) {
    const policyAllowsAction = deps.isActionEnabled ?? ((_id, _ctx) => true);
    const isActionEnabledByPolicy = (spec, ctx) => policyAllowsAction(spec.id, ctx);
    const isActionEnabledBySurface = (spec, ctx) => isActionSpecSurfacedOn(spec, ctx.surface);
    const isActionEnabled = (spec, ctx) => isActionEnabledBySurface(spec, ctx) && isActionEnabledByPolicy(spec, ctx);
    const execute = async (actionId, input, context) => {
        const ctx = context ?? {};
        const spec = getActionSpec(actionId);
        const approvalRequired = ctx.bypassApprovals ? false : deps.isActionApprovalRequired?.(actionId, ctx) === true;
        const isApprovalAction = actionId === 'approval.request.create' || actionId === 'approval.request.decide';
        if (!isActionEnabled(spec, ctx)) {
            return { ok: false, errorCode: 'action_disabled', error: 'action_disabled' };
        }
        const parsed = spec.inputSchema.safeParse(input ?? {});
        if (!parsed.success) {
            return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
        }
        try {
            if (approvalRequired && !isApprovalAction) {
                if (!deps.approvalsCreate) {
                    return { ok: false, errorCode: 'approvals_not_supported', error: 'approvals_not_supported' };
                }
                const now = Date.now();
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                const requestedSurface = parseActionSurfaceKey(ctx.surface);
                const createdBy = {
                    surface: mapApprovalCreatedBySurface(ctx.surface ?? null),
                    ...(sessionId ? { sessionId } : {}),
                };
                const request = {
                    v: 1,
                    status: 'open',
                    createdAtMs: now,
                    updatedAtMs: now,
                    createdBy,
                    ...(requestedSurface ? { requestedSurface } : {}),
                    actionId,
                    actionArgs: parsed.data,
                    summary: buildApprovalSummary(spec, sessionId),
                    preview: { actionId, actionArgs: parsed.data },
                    ...(normalizeId(ctx.serverId) ? { serverId: normalizeId(ctx.serverId) } : {}),
                };
                const res = await deps.approvalsCreate({ request, serverId: normalizeId(ctx.serverId) || null });
                return {
                    ok: true,
                    result: {
                        kind: 'approval_request_created',
                        artifactId: res?.artifactId,
                        actionId,
                    },
                };
            }
            // Switch by actionId; keep substrate generic.
            if (actionId === 'review.start') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const engineIds = Array.isArray(parsed.data.engineIds) ? parsed.data.engineIds : [];
                const instructions = String(parsed.data.instructions ?? '').trim();
                const intentInputBase = { ...parsed.data };
                const results = await fanoutStarts({
                    keys: engineIds,
                    startOne: async (engineId) => deps.executionRunStart(sessionId, {
                        intent: 'review',
                        backendTarget: parseBackendTargetKey(normalizeExecutionBackendOptionValue(engineId)),
                        instructions,
                        permissionMode: parsed.data.permissionMode ?? 'read_only',
                        retentionPolicy: 'resumable',
                        runClass: 'bounded',
                        // Reviews should stream sidechain progress (and tool traffic) into the parent session.
                        ioMode: 'streaming',
                        intentInput: { ...intentInputBase, engineId },
                    }, opts),
                });
                return { ok: true, result: { intent: 'review', sessionId, results } };
            }
            if (actionId === 'subagents.plan.start' || actionId === 'subagents.delegate.start' || actionId === 'voice_agent.start') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const backendTargetKeys = Array.isArray(parsed.data.backendTargetKeys)
                    ? parsed.data.backendTargetKeys
                    : [];
                const instructions = String(parsed.data.instructions ?? '').trim();
                const intent = actionId === 'subagents.plan.start' ? 'plan' : actionId === 'subagents.delegate.start' ? 'delegate' : 'voice_agent';
                const permissionModeDefault = intent === 'delegate' ? 'workspace_write' : 'read_only';
                const results = await fanoutStarts({
                    keys: backendTargetKeys,
                    startOne: async (backendTargetKey) => deps.executionRunStart(sessionId, {
                        intent,
                        backendTarget: parseBackendTargetKey(backendTargetKey),
                        instructions,
                        permissionMode: parsed.data.permissionMode ?? permissionModeDefault,
                        retentionPolicy: parsed.data.retentionPolicy ?? 'ephemeral',
                        runClass: parsed.data.runClass ?? 'bounded',
                        ioMode: parsed.data.ioMode ?? 'request_response',
                        intentInput: { ...parsed.data, backendTargetKey },
                    }, opts),
                });
                return { ok: true, result: { intent, sessionId, results } };
            }
            if (actionId === 'action.spec.search') {
                return {
                    ok: true,
                    result: {
                        actionSpecs: searchSerializedActionSpecsForSurface({
                            surface: ctx.surface ?? null,
                            query: typeof parsed.data.query === 'string' ? parsed.data.query : '',
                            limit: typeof parsed.data.limit === 'number' ? parsed.data.limit : undefined,
                            isActionEnabled: (id) => isActionEnabled(getActionSpec(id), ctx),
                        }),
                    },
                };
            }
            if (actionId === 'action.spec.get') {
                try {
                    const requested = getSerializedActionSpecForSurface({
                        id: String(parsed.data.id),
                        surface: ctx.surface ?? null,
                        isActionEnabled: (id) => isActionEnabled(getActionSpec(id), ctx),
                    });
                    if (!requested) {
                        return { ok: false, errorCode: 'action_disabled', error: 'action_disabled' };
                    }
                    return { ok: true, result: { actionSpec: requested } };
                }
                catch {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
            }
            if (actionId === 'action.options.resolve') {
                const actionIdRaw = normalizeId(parsed.data.actionId);
                const fieldPath = normalizeId(parsed.data.fieldPath);
                const directOptionsSourceId = normalizeId(parsed.data.optionsSourceId);
                let optionsSourceId = directOptionsSourceId;
                if (actionIdRaw && fieldPath) {
                    try {
                        getActionSpec(actionIdRaw);
                    }
                    catch {
                        return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                    }
                    const requestedSpec = getActionSpecForCatalogSurface({
                        id: actionIdRaw,
                        surface: ctx.surface ?? null,
                        isActionEnabled: (id) => isActionEnabled(getActionSpec(id), ctx),
                    });
                    if (!requestedSpec) {
                        return { ok: false, errorCode: 'action_disabled', error: 'action_disabled' };
                    }
                    const field = findActionInputFieldHint(requestedSpec, fieldPath);
                    if (!field) {
                        return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                    }
                    const staticOptions = serializeActionFieldOptions(field);
                    if (staticOptions.length > 0) {
                        return {
                            ok: true,
                            result: {
                                actionId: requestedSpec.id,
                                fieldPath,
                                optionsSourceId: null,
                                options: filterResolvedActionOptions(staticOptions, parsed.data),
                            },
                        };
                    }
                    optionsSourceId = normalizeId(field.optionsSourceId) || directOptionsSourceId;
                }
                if (!optionsSourceId) {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                const dynamic = await resolveDynamicActionOptions({
                    deps,
                    ctx,
                    optionsSourceId,
                    input: parsed.data,
                });
                if (!dynamic.ok)
                    return dynamic;
                return {
                    ok: true,
                    result: {
                        actionId: actionIdRaw || null,
                        fieldPath: fieldPath || null,
                        optionsSourceId,
                        options: filterResolvedActionOptions(dynamic.result, parsed.data),
                    },
                };
            }
            if (actionId === 'execution.run.start') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const { sessionId: _ignored, ...request } = parsed.data;
                const res = await deps.executionRunStart(sessionId, request, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'execution.run.list') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const res = await deps.executionRunList(sessionId, parsed.data, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'execution.run.get') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const res = await deps.executionRunGet(sessionId, { runId: parsed.data.runId, includeStructured: parsed.data.includeStructured === true }, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'execution.run.send') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const res = await deps.executionRunSend(sessionId, {
                    runId: parsed.data.runId,
                    message: parsed.data.message,
                    delivery: typeof parsed.data.delivery === 'string'
                        ? parsed.data.delivery
                        : 'steer_if_supported',
                    ...(parsed.data.resume === true ? { resume: true } : {}),
                }, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'execution.run.stop') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const res = await deps.executionRunStop(sessionId, { runId: parsed.data.runId }, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'execution.run.action') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const res = await deps.executionRunAction(sessionId, { runId: parsed.data.runId, actionId: parsed.data.actionId, input: parsed.data.input }, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'execution.run.wait') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const opts = serverId ? { serverId } : undefined;
                const res = await deps.executionRunWait(sessionId, {
                    runId: parsed.data.runId,
                    ...(typeof parsed.data.timeoutSeconds === 'number' ? { timeoutSeconds: parsed.data.timeoutSeconds } : {}),
                    ...(typeof parsed.data.pollIntervalMs === 'number' ? { pollIntervalMs: parsed.data.pollIntervalMs } : {}),
                }, opts);
                return { ok: true, result: res };
            }
            if (actionId === 'session.open') {
                const explicitSessionId = normalizeId(parsed.data.sessionId);
                const titleResolution = explicitSessionId ? null : await resolveSessionIdByTitle(deps, parsed.data.sessionTitle);
                if (titleResolution?.kind === 'ambiguous') {
                    return { ok: false, errorCode: 'session_id_ambiguous', error: 'session_id_ambiguous' };
                }
                const sessionId = explicitSessionId || (titleResolution?.kind === 'resolved' ? titleResolution.sessionId : null);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const res = await deps.sessionOpen({ sessionId });
                return { ok: true, result: res };
            }
            if (actionId === 'session.fork') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionFork({ sessionId, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.rollback') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const rawTarget = parsed.data?.target;
                const target = rawTarget && typeof rawTarget === 'object' ? rawTarget : undefined;
                const res = await deps.sessionRollback({ sessionId, ...(serverId ? { serverId } : {}), ...(target ? { target } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.handoff') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const targetMachineId = normalizeId(parsed.data.targetMachineId);
                if (!targetMachineId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionHandoffStart) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.handoff' };
                }
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const targetSessionStorageMode = parsed.data.targetSessionStorageMode === 'direct' || parsed.data.targetSessionStorageMode === 'persisted'
                    ? parsed.data.targetSessionStorageMode
                    : undefined;
                const workspaceTransferParsed = SessionHandoffWorkspaceTransferSchema.safeParse(parsed.data.workspaceTransfer);
                const workspaceTransfer = workspaceTransferParsed.success ? workspaceTransferParsed.data : undefined;
                const res = await deps.sessionHandoffStart({
                    sessionId,
                    targetMachineId,
                    ...(targetSessionStorageMode ? { targetSessionStorageMode } : {}),
                    ...(workspaceTransfer ? { workspaceTransfer } : {}),
                    ...(serverId ? { serverId } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.spawn_new') {
                const res = await deps.sessionSpawnNew({
                    ...((parsed.data.tag) ? { tag: String(parsed.data.tag) } : {}),
                    ...((parsed.data.agentId) ? { agentId: String(parsed.data.agentId) } : {}),
                    ...((parsed.data.modelId) ? { modelId: String(parsed.data.modelId) } : {}),
                    ...((parsed.data.backendTargetKey) ? { backendTargetKey: String(parsed.data.backendTargetKey) } : {}),
                    ...((parsed.data.title) ? { title: String(parsed.data.title) } : {}),
                    ...((parsed.data.path) ? { path: String(parsed.data.path) } : {}),
                    ...((parsed.data.host) ? { host: String(parsed.data.host) } : {}),
                    ...((parsed.data.initialMessage) ? { initialMessage: String(parsed.data.initialMessage) } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.spawn_picker') {
                const res = await deps.sessionSpawnPicker({
                    ...((parsed.data.tag) ? { tag: String(parsed.data.tag) } : {}),
                    ...((parsed.data.agentId) ? { agentId: String(parsed.data.agentId) } : {}),
                    ...((parsed.data.modelId) ? { modelId: String(parsed.data.modelId) } : {}),
                    ...((parsed.data.initialMessage) ? { initialMessage: String(parsed.data.initialMessage) } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'paths.list_recent') {
                const res = await deps.pathsListRecent({
                    ...((parsed.data.machineId) ? { machineId: String(parsed.data.machineId) } : {}),
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'machines.list') {
                const res = await deps.machinesList({
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'servers.list') {
                const res = await deps.serversList({
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'review.engines.list') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const res = await deps.reviewEnginesList({
                    sessionId,
                    ...(typeof parsed.data.includeDisabled === 'boolean' ? { includeDisabled: parsed.data.includeDisabled } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'agents.backends.list') {
                const res = await deps.agentsBackendsList({
                    ...(typeof parsed.data.includeDisabled === 'boolean' ? { includeDisabled: parsed.data.includeDisabled } : {}),
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'agents.models.list') {
                const backendTargetKey = normalizeId(parsed.data.backendTargetKey);
                let resolvedAgentId = normalizeId(parsed.data.agentId);
                if (backendTargetKey) {
                    const parsedTarget = parseBackendTargetKey(backendTargetKey);
                    const derivedAgentId = parsedTarget.kind === 'builtInAgent' ? parsedTarget.agentId : 'customAcp';
                    if (resolvedAgentId && resolvedAgentId !== derivedAgentId) {
                        return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                    }
                    resolvedAgentId = derivedAgentId;
                }
                if (resolvedAgentId === 'customAcp' && !backendTargetKey) {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                if (!resolvedAgentId) {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                const res = await deps.agentsModelsList({
                    agentId: resolvedAgentId,
                    ...((parsed.data.machineId) ? { machineId: String(parsed.data.machineId) } : {}),
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                    ...(backendTargetKey ? { backendTargetKey } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.message.send') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const modelOverrideRaw = Object.prototype.hasOwnProperty.call(parsed.data, 'modelOverride')
                    ? parsed.data.modelOverride
                    : undefined;
                const res = await deps.sessionSendMessage({
                    sessionId,
                    message: parsed.data.message,
                    ...((parsed.data.permissionModeOverride) ? { permissionModeOverride: parsed.data.permissionModeOverride } : {}),
                    ...(modelOverrideRaw === null
                        ? { modelOverride: null }
                        : typeof modelOverrideRaw === 'string' && modelOverrideRaw.trim().length > 0
                            ? { modelOverride: modelOverrideRaw.trim() }
                            : {}),
                    ...(typeof parsed.data.wait === 'boolean' ? { wait: parsed.data.wait } : {}),
                    ...(typeof parsed.data.timeoutSeconds === 'number' ? { timeoutSeconds: parsed.data.timeoutSeconds } : {}),
                    ...(serverId ? { serverId } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.title.set') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                if (!deps.sessionTitleSet) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.title.set' };
                }
                const title = String(parsed.data.title ?? '').trim();
                if (!title)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionTitleSet({ sessionId, title, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.stop') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionStop) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.stop' };
                }
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionStop({ sessionId, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.permission_mode.set') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionPermissionModeSet) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.permission_mode.set' };
                }
                const permissionMode = normalizeId(parsed.data.permissionMode);
                if (!permissionMode)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionPermissionModeSet({ sessionId, permissionMode, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.model.set') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionModelSet) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.model.set' };
                }
                const modelId = normalizeId(parsed.data.modelId);
                if (!modelId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionModelSet({ sessionId, modelId, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.archive' || actionId === 'session.unarchive') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionArchiveSet) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.archive' };
                }
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionArchiveSet({
                    sessionId,
                    archived: actionId === 'session.archive',
                    ...(serverId ? { serverId } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.status.get') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionStatusGet) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.status.get' };
                }
                const live = parsed.data.live === true;
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionStatusGet({ sessionId, live, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.history.get') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionHistoryGet) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.history.get' };
                }
                const limit = typeof parsed.data.limit === 'number' ? parsed.data.limit : 50;
                const format = parsed.data.format === 'raw' ? 'raw' : 'compact';
                const includeMeta = parsed.data.includeMeta === true;
                const includeStructuredPayload = parsed.data.includeStructuredPayload === true;
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionHistoryGet({
                    sessionId,
                    limit,
                    format,
                    includeMeta,
                    includeStructuredPayload,
                    ...(serverId ? { serverId } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.wait.idle') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                if (!deps.sessionWaitIdle) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.wait.idle' };
                }
                const timeoutSeconds = typeof parsed.data.timeoutSeconds === 'number' ? parsed.data.timeoutSeconds : 300;
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionWaitIdle({ sessionId, timeoutSeconds, ...(serverId ? { serverId } : {}) });
                return { ok: true, result: res };
            }
            if (actionId === 'session.permission.respond') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                if (!deps.sessionPermissionRespond) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.permission.respond' };
                }
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionPermissionRespond({
                    sessionId,
                    decision: parsed.data.decision,
                    requestId: Object.prototype.hasOwnProperty.call(parsed.data, 'requestId') ? (parsed.data.requestId ?? null) : null,
                    ...(serverId ? { serverId } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.user_action.answer') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                if (!deps.sessionUserActionAnswer) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:session.user_action.answer' };
                }
                const serverId = resolveServerIdForSession(deps, ctx, sessionId);
                const res = await deps.sessionUserActionAnswer({
                    sessionId,
                    requestId: Object.prototype.hasOwnProperty.call(parsed.data, 'requestId') ? (parsed.data.requestId ?? null) : null,
                    answers: Array.isArray(parsed.data.answers) ? (parsed.data.answers.map((entry) => ({
                        question: String(entry?.question ?? ''),
                        answer: String(entry?.answer ?? ''),
                    }))) : [],
                    ...(typeof parsed.data.decision === 'string' ? { decision: parsed.data.decision } : {}),
                    ...(typeof parsed.data.reason === 'string' ? { reason: parsed.data.reason } : {}),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'updatedPermissions') ? { updatedPermissions: parsed.data.updatedPermissions } : {}),
                    ...(serverId ? { serverId } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.mode.set') {
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const modeIdRaw = normalizeId(parsed.data.modeId);
                const availableModes = normalizeResolvedOptions(await deps.sessionModesList({ sessionId }));
                const modeId = resolveRequestedSessionModeId(modeIdRaw, availableModes);
                if (modeId && availableModes.length > 0) {
                    if (!availableModes.some((option) => normalizeId(option.value) === modeId)) {
                        return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                    }
                }
                const res = await deps.sessionModeSet({ sessionId, modeId });
                return { ok: true, result: res };
            }
            if (actionId === 'session.target.primary.set') {
                const raw = parsed.data.sessionId;
                const explicitSessionId = raw === null ? null : normalizeId(raw);
                const titleResolution = raw === null || explicitSessionId ? null : await resolveSessionIdByTitle(deps, parsed.data.sessionTitle);
                if (titleResolution?.kind === 'ambiguous') {
                    return { ok: false, errorCode: 'session_id_ambiguous', error: 'session_id_ambiguous' };
                }
                const sessionId = raw === null
                    ? null
                    : explicitSessionId || (titleResolution?.kind === 'resolved' ? titleResolution.sessionId : null);
                const res = await deps.sessionTargetPrimarySet({ sessionId: sessionId || null });
                return { ok: true, result: res };
            }
            if (actionId === 'session.target.tracked.set') {
                const res = await deps.sessionTargetTrackedSet({
                    sessionIds: Array.isArray(parsed.data.sessionIds) ? (parsed.data.sessionIds.map((v) => String(v))) : [],
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.list') {
                const res = await deps.sessionList({
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'cursor') ? { cursor: (parsed.data.cursor ?? null) } : {}),
                    ...(typeof parsed.data.includeLastMessagePreview === 'boolean' ? { includeLastMessagePreview: parsed.data.includeLastMessagePreview } : {}),
                    ...(typeof parsed.data.activeOnly === 'boolean' ? { activeOnly: parsed.data.activeOnly } : {}),
                    ...(typeof parsed.data.archivedOnly === 'boolean' ? { archivedOnly: parsed.data.archivedOnly } : {}),
                    ...(typeof parsed.data.includeSystem === 'boolean' ? { includeSystem: parsed.data.includeSystem } : {}),
                    ...(typeof parsed.data.resumableOnly === 'boolean' ? { resumableOnly: parsed.data.resumableOnly } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.activity.get') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const res = await deps.sessionActivityGet({
                    sessionId,
                    ...(typeof parsed.data.windowSeconds === 'number' ? { windowSeconds: parsed.data.windowSeconds } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'session.messages.recent.get') {
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const res = await deps.sessionRecentMessagesGet({
                    sessionId,
                    defaultSessionId: normalizeId(ctx.defaultSessionId) || null,
                    ...(typeof parsed.data.limit === 'number' ? { limit: parsed.data.limit } : {}),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'cursor') ? { cursor: (parsed.data.cursor ?? null) } : {}),
                    ...(typeof parsed.data.includeUser === 'boolean' ? { includeUser: parsed.data.includeUser } : {}),
                    ...(typeof parsed.data.includeAssistant === 'boolean' ? { includeAssistant: parsed.data.includeAssistant } : {}),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'maxCharsPerMessage') ? { maxCharsPerMessage: (parsed.data.maxCharsPerMessage ?? null) } : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'memory.search') {
                const machineId = normalizeId(parsed.data.machineId);
                if (!machineId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const query = parsed.data.query;
                const res = await deps.daemonMemorySearch({ machineId, query, serverId: normalizeId(ctx.serverId) || null });
                return { ok: true, result: res };
            }
            if (actionId === 'memory.get_window') {
                const machineId = normalizeId(parsed.data.machineId);
                const sessionId = normalizeId(parsed.data.sessionId);
                if (!machineId || !sessionId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const res = await deps.daemonMemoryGetWindow({
                    machineId,
                    sessionId,
                    seqFrom: Number(parsed.data.seqFrom ?? 0),
                    seqTo: Number(parsed.data.seqTo ?? 0),
                    serverId: normalizeId(ctx.serverId) || null,
                });
                return { ok: true, result: res };
            }
            if (actionId === 'memory.ensure_up_to_date') {
                const machineId = normalizeId(parsed.data.machineId);
                if (!machineId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const sessionId = normalizeId(parsed.data.sessionId);
                const res = await deps.daemonMemoryEnsureUpToDate({
                    machineId,
                    ...(sessionId ? { sessionId } : {}),
                    serverId: normalizeId(ctx.serverId) || null,
                });
                return { ok: true, result: res };
            }
            if (actionId === 'ui.voice_global.reset') {
                await deps.resetGlobalVoiceAgent();
                return { ok: true, result: { ok: true } };
            }
            if (actionId === 'ui.voice_agent.teleport') {
                if (!deps.teleportVoiceAgentToSessionRoot) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:ui.voice_agent.teleport' };
                }
                const sessionId = resolveSessionIdFromInput(parsed.data, ctx);
                if (!sessionId)
                    return { ok: false, errorCode: 'session_not_selected', error: 'session_not_selected' };
                const result = await deps.teleportVoiceAgentToSessionRoot({ sessionId });
                if (result?.ok === false) {
                    const errorCode = String(result?.code ?? 'voice_teleport_failed');
                    return { ok: false, errorCode, error: errorCode };
                }
                return { ok: true, result: { ok: true, sessionId } };
            }
            if (actionId === 'prompt_doc.update') {
                if (!deps.promptDocUpdate) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:prompt_doc.update' };
                }
                const artifactId = normalizeId(parsed.data.artifactId);
                const title = String(parsed.data.title ?? '').trim();
                if (!artifactId || !title)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const res = await deps.promptDocUpdate({
                    artifactId,
                    title,
                    markdown: String(parsed.data.markdown ?? ''),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'folderId')
                        ? { folderId: (parsed.data.folderId ?? null) }
                        : {}),
                    ...(Array.isArray(parsed.data.tags)
                        ? { tags: parsed.data.tags.filter((entry) => typeof entry === 'string') }
                        : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'prompt_bundle.update') {
                if (!deps.promptBundleUpdate) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:prompt_bundle.update' };
                }
                const artifactId = normalizeId(parsed.data.artifactId);
                const title = String(parsed.data.title ?? '').trim();
                if (!artifactId || !title)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const res = await deps.promptBundleUpdate({
                    artifactId,
                    title,
                    skillMarkdown: String(parsed.data.skillMarkdown ?? ''),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'folderId')
                        ? { folderId: (parsed.data.folderId ?? null) }
                        : {}),
                    ...(Array.isArray(parsed.data.tags)
                        ? { tags: parsed.data.tags.filter((entry) => typeof entry === 'string') }
                        : {}),
                });
                return { ok: true, result: res };
            }
            if (actionId === 'prompt_asset.export') {
                if (!deps.promptAssetExport) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:prompt_asset.export' };
                }
                const artifactId = normalizeId(parsed.data.artifactId);
                const machineId = normalizeId(parsed.data.machineId);
                const assetTypeId = normalizeId(parsed.data.assetTypeId);
                const scope = parsed.data.scope === 'project' ? 'project' : parsed.data.scope === 'user' ? 'user' : null;
                if (!artifactId || !machineId || !assetTypeId || !scope) {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                const res = await deps.promptAssetExport({
                    artifactId,
                    machineId,
                    assetTypeId,
                    scope,
                    ...(normalizeId(ctx.serverId) ? { serverId: normalizeId(ctx.serverId) } : {}),
                    ...(typeof parsed.data.directory === 'string' && String(parsed.data.directory).trim().length > 0
                        ? { directory: String(parsed.data.directory).trim() }
                        : {}),
                    ...(typeof parsed.data.targetPath === 'string' && String(parsed.data.targetPath).trim().length > 0
                        ? { targetPath: String(parsed.data.targetPath).trim() }
                        : {}),
                    ...(typeof parsed.data.targetName === 'string' && String(parsed.data.targetName).trim().length > 0
                        ? { targetName: String(parsed.data.targetName).trim() }
                        : {}),
                    ...(parsed.data.installMode === 'copy' || parsed.data.installMode === 'symlink'
                        ? { installMode: parsed.data.installMode }
                        : {}),
                });
                if (res?.ok === false) {
                    return {
                        ok: false,
                        errorCode: typeof res.errorCode === 'string' ? res.errorCode : 'action_failed',
                        error: typeof res.error === 'string' ? res.error : 'action_failed',
                    };
                }
                return { ok: true, result: res };
            }
            if (actionId === 'prompt_registry.install') {
                if (!deps.promptRegistryInstall) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:prompt_registry.install' };
                }
                const machineId = normalizeId(parsed.data.machineId);
                const sourceId = normalizeId(parsed.data.sourceId);
                const itemId = normalizeId(parsed.data.itemId);
                if (!machineId || !sourceId || !itemId) {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                const installTargetRaw = parsed.data.installTarget;
                const installTarget = installTargetRaw
                    && typeof installTargetRaw === 'object'
                    && typeof installTargetRaw.assetTypeId === 'string'
                    && typeof installTargetRaw.targetName === 'string'
                    && (installTargetRaw.scope === 'project' || installTargetRaw.scope === 'user')
                    ? {
                        assetTypeId: installTargetRaw.assetTypeId,
                        scope: installTargetRaw.scope,
                        ...(typeof installTargetRaw.directory === 'string' && installTargetRaw.directory.trim().length > 0
                            ? { directory: installTargetRaw.directory.trim() }
                            : {}),
                        targetName: installTargetRaw.targetName,
                        ...((installTargetRaw.installMode === 'copy' || installTargetRaw.installMode === 'symlink')
                            ? { installMode: installTargetRaw.installMode }
                            : {}),
                    }
                    : undefined;
                const res = await deps.promptRegistryInstall({
                    machineId,
                    sourceId,
                    itemId,
                    configuredSources: Array.isArray(parsed.data.configuredSources) ? parsed.data.configuredSources : [],
                    ...(normalizeId(ctx.serverId) ? { serverId: normalizeId(ctx.serverId) } : {}),
                    ...(installTarget ? { installTarget } : {}),
                });
                if (res?.ok === false) {
                    return {
                        ok: false,
                        errorCode: typeof res.errorCode === 'string' ? res.errorCode : 'action_failed',
                        error: typeof res.error === 'string' ? res.error : 'action_failed',
                    };
                }
                return { ok: true, result: res };
            }
            if (actionId === 'approval.request.create') {
                if (!deps.approvalsCreate) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:approvals' };
                }
                const now = Date.now();
                const targetActionId = parsed.data.actionId;
                if (targetActionId === 'approval.request.create' || targetActionId === 'approval.request.decide') {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                // Approvals eligibility is policy-driven (settings/surface), not safety-driven.
                // Safety metadata remains useful for UI copy and defaults, but it is not a hard gate here.
                getActionSpec(targetActionId);
                const rawCreatedBy = parsed.data.createdBy;
                const forcedSurface = mapApprovalCreatedBySurface(ctx.surface ?? null);
                const actionArgsSessionId = normalizeId(parsed.data.actionArgs?.sessionId);
                const ctxDefaultSessionId = normalizeId(ctx.defaultSessionId);
                const rawAgentId = rawCreatedBy && typeof rawCreatedBy === 'object' ? normalizeId(rawCreatedBy.agentId) : null;
                const requestedSurface = parseActionSurfaceKey(ctx.surface);
                const createdBy = {
                    surface: forcedSurface,
                    ...(rawAgentId ? { agentId: rawAgentId } : {}),
                    ...(actionArgsSessionId ? { sessionId: actionArgsSessionId } : ctxDefaultSessionId ? { sessionId: ctxDefaultSessionId } : {}),
                };
                const summary = String(parsed.data.summary ?? '').trim();
                if (!summary)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const request = {
                    v: 1,
                    status: 'open',
                    createdAtMs: now,
                    updatedAtMs: now,
                    createdBy,
                    ...(requestedSurface ? { requestedSurface } : {}),
                    actionId: targetActionId,
                    actionArgs: parsed.data.actionArgs,
                    summary,
                    ...(normalizeId(ctx.serverId) ? { serverId: normalizeId(ctx.serverId) } : {}),
                    ...(Object.prototype.hasOwnProperty.call(parsed.data, 'preview') ? { preview: parsed.data.preview } : {}),
                };
                const res = await deps.approvalsCreate({ request, serverId: normalizeId(ctx.serverId) || null });
                return { ok: true, result: res };
            }
            if (actionId === 'approval.request.decide') {
                if (!deps.approvalsGet || !deps.approvalsUpdate) {
                    return { ok: false, errorCode: 'unsupported_action', error: 'unsupported_action:approvals' };
                }
                const artifactId = normalizeId(parsed.data.artifactId);
                if (!artifactId)
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                const existingRaw = await deps.approvalsGet({ artifactId, serverId: normalizeId(ctx.serverId) || null });
                if (!existingRaw)
                    return { ok: false, errorCode: 'approval_not_found', error: 'approval_not_found' };
                const existingParsed = ApprovalRequestV1Schema.safeParse(existingRaw);
                if (!existingParsed.success)
                    return { ok: false, errorCode: 'approval_invalid', error: 'approval_invalid' };
                const existing = existingParsed.data;
                const effectiveServerId = normalizeId(ctx.serverId) || normalizeId(existing.serverId) || null;
                const decision = parsed.data.decision;
                if (existing.actionId === 'approval.request.create' || existing.actionId === 'approval.request.decide') {
                    return { ok: false, errorCode: 'invalid_parameters', error: 'invalid_parameters' };
                }
                const isRecoverableApproved = decision === 'approve'
                    && existing.status === 'approved'
                    && existing.decision?.kind === 'approve'
                    && !existing.execution;
                if (decision === 'reject' && existing.status === 'rejected' && existing.decision?.kind === 'reject') {
                    return buildApprovalDecisionResult(existing);
                }
                if (decision === 'approve'
                    && (existing.status === 'approved' || existing.status === 'executed' || existing.status === 'failed')
                    && existing.decision?.kind === 'approve'
                    && !isRecoverableApproved) {
                    return buildApprovalDecisionResult(existing);
                }
                if (existing.status !== 'open' && !isRecoverableApproved) {
                    return { ok: false, errorCode: 'approval_not_open', error: 'approval_not_open' };
                }
                const now = Date.now();
                if (decision === 'reject') {
                    const nextRejected = {
                        ...existing,
                        status: 'rejected',
                        updatedAtMs: now,
                        decision: { kind: 'reject', decidedAtMs: now },
                    };
                    const updated = await deps.approvalsUpdate({ artifactId, request: nextRejected, serverId: effectiveServerId });
                    if (updated?.ok === false)
                        return { ok: false, errorCode: updated.errorCode, error: updated.error };
                    return buildApprovalDecisionResult(nextRejected);
                }
                let approvedRequest = existing;
                if (existing.status === 'open') {
                    approvedRequest = {
                        ...existing,
                        status: 'approved',
                        updatedAtMs: now,
                        decision: { kind: 'approve', decidedAtMs: now },
                    };
                    const approved = await deps.approvalsUpdate({
                        artifactId,
                        request: approvedRequest,
                        serverId: effectiveServerId,
                    });
                    if (approved?.ok === false) {
                        return { ok: false, errorCode: approved.errorCode, error: approved.error };
                    }
                }
                const requestSurface = parseActionSurfaceKey(approvedRequest.requestedSurface)
                    ?? resolveApprovalRequestExecutionSurface(existing.createdBy.surface);
                const requestDefaultSessionId = typeof existing.createdBy.sessionId === 'string' ? existing.createdBy.sessionId.trim() : '';
                const exec = requestSurface
                    ? await execute(existing.actionId, existing.actionArgs, {
                        ...ctx,
                        ...(effectiveServerId ? { serverId: effectiveServerId } : {}),
                        ...(requestDefaultSessionId ? { defaultSessionId: requestDefaultSessionId } : {}),
                        surface: requestSurface,
                        placement: null,
                        bypassApprovals: true,
                    })
                    : { ok: false, errorCode: 'approval_execution_surface_invalid', error: 'approval_execution_surface_invalid' };
                const executedAtMs = Date.now();
                const nextExecuted = {
                    ...approvedRequest,
                    status: exec.ok ? 'executed' : 'failed',
                    updatedAtMs: executedAtMs,
                    execution: exec.ok
                        ? { executedAtMs, ok: true, result: exec.result }
                        : { executedAtMs, ok: false, errorCode: exec.errorCode, error: exec.error },
                };
                const updated = await deps.approvalsUpdate({ artifactId, request: nextExecuted, serverId: effectiveServerId });
                if (updated?.ok === false)
                    return { ok: false, errorCode: updated.errorCode, error: updated.error };
                return buildApprovalDecisionResult(nextExecuted);
            }
            return { ok: false, errorCode: 'unsupported_action', error: `unsupported_action:${actionId}` };
        }
        catch (error) {
            const normalized = normalizeActionExecutorThrownError(error);
            return { ok: false, errorCode: normalized.errorCode, error: normalized.error };
        }
    };
    return {
        execute,
    };
}
//# sourceMappingURL=actionExecutor.js.map