const isSessionBeforeEvent = (event) => event.type === "session_before_switch" ||
    event.type === "session_before_fork" ||
    event.type === "session_before_compact" ||
    event.type === "session_before_tree";
const emitCaughtError = (emitError, extensionPath, event, error) => {
    emitError({
        extensionPath,
        event,
        error: error instanceof Error ? error.message : String(error),
        stack: error instanceof Error ? error.stack : undefined,
    });
};
export async function runGenericHandlers(extensions, ctx, event, emitError) {
    let result;
    for (const ext of extensions) {
        const handlers = ext.handlers.get(event.type);
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const handlerResult = await handler(event, ctx);
                if (isSessionBeforeEvent(event) && handlerResult) {
                    result = handlerResult;
                    if (result.cancel)
                        return result;
                }
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, event.type, error);
            }
        }
    }
    return result;
}
export async function runMessageEndHandlers(extensions, ctx, event, emitError) {
    let currentMessage = event.message;
    let modified = false;
    for (const ext of extensions) {
        const handlers = ext.handlers.get("message_end");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const currentEvent = { ...event, message: currentMessage };
                const handlerResult = (await handler(currentEvent, ctx));
                if (!handlerResult?.message)
                    continue;
                if (handlerResult.message.role !== currentMessage.role) {
                    emitError({
                        extensionPath: ext.path,
                        event: "message_end",
                        error: "message_end handlers must return a message with the same role",
                    });
                    continue;
                }
                currentMessage = handlerResult.message;
                modified = true;
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "message_end", error);
            }
        }
    }
    return modified ? currentMessage : undefined;
}
export async function runToolResultHandlers(extensions, ctx, event, emitError) {
    const currentEvent = { ...event };
    let modified = false;
    for (const ext of extensions) {
        const handlers = ext.handlers.get("tool_result");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const handlerResult = (await handler(currentEvent, ctx));
                if (!handlerResult)
                    continue;
                if (handlerResult.content !== undefined) {
                    currentEvent.content = handlerResult.content;
                    modified = true;
                }
                if (handlerResult.details !== undefined) {
                    currentEvent.details = handlerResult.details;
                    modified = true;
                }
                if (handlerResult.isError !== undefined) {
                    currentEvent.isError = handlerResult.isError;
                    modified = true;
                }
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "tool_result", error);
            }
        }
    }
    return modified
        ? { content: currentEvent.content, details: currentEvent.details, isError: currentEvent.isError }
        : undefined;
}
export async function runToolCallHandlers(extensions, ctx, event) {
    let result;
    for (const ext of extensions) {
        const handlers = ext.handlers.get("tool_call");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            const handlerResult = await handler(event, ctx);
            if (handlerResult) {
                result = handlerResult;
                if (result.block)
                    return result;
            }
        }
    }
    return result;
}
export async function runUserBashHandlers(extensions, ctx, event, emitError) {
    for (const ext of extensions) {
        const handlers = ext.handlers.get("user_bash");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const handlerResult = await handler(event, ctx);
                if (handlerResult)
                    return handlerResult;
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "user_bash", error);
            }
        }
    }
    return undefined;
}
export async function runContextHandlers(extensions, ctx, messages, emitError) {
    let currentMessages = structuredClone(messages);
    for (const ext of extensions) {
        const handlers = ext.handlers.get("context");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const event = { type: "context", messages: currentMessages };
                const handlerResult = await handler(event, ctx);
                if (handlerResult && handlerResult.messages) {
                    currentMessages = handlerResult.messages;
                }
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "context", error);
            }
        }
    }
    return currentMessages;
}
export async function runBeforeProviderRequestHandlers(extensions, ctx, payload, emitError) {
    let currentPayload = payload;
    for (const ext of extensions) {
        const handlers = ext.handlers.get("before_provider_request");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const event = { type: "before_provider_request", payload: currentPayload };
                const handlerResult = await handler(event, ctx);
                if (handlerResult !== undefined)
                    currentPayload = handlerResult;
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "before_provider_request", error);
            }
        }
    }
    return currentPayload;
}
export async function runBeforeAgentStartHandlers(extensions, baseCtx, assertActive, prompt, images, systemPrompt, systemPromptOptions, emitError) {
    let currentSystemPrompt = systemPrompt;
    const ctx = Object.defineProperties({}, Object.getOwnPropertyDescriptors(baseCtx));
    ctx.getSystemPrompt = () => {
        assertActive();
        return currentSystemPrompt;
    };
    const messages = [];
    let systemPromptModified = false;
    for (const ext of extensions) {
        const handlers = ext.handlers.get("before_agent_start");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const event = {
                    type: "before_agent_start",
                    prompt,
                    images,
                    systemPrompt: currentSystemPrompt,
                    systemPromptOptions,
                };
                const handlerResult = await handler(event, ctx);
                if (!handlerResult)
                    continue;
                const result = handlerResult;
                if (result.message)
                    messages.push(result.message);
                if (result.systemPrompt !== undefined) {
                    currentSystemPrompt = result.systemPrompt;
                    systemPromptModified = true;
                }
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "before_agent_start", error);
            }
        }
    }
    return messages.length > 0 || systemPromptModified
        ? {
            messages: messages.length > 0 ? messages : undefined,
            systemPrompt: systemPromptModified ? currentSystemPrompt : undefined,
        }
        : undefined;
}
export async function runResourcesDiscoverHandlers(extensions, ctx, cwd, reason, emitError) {
    const skillPaths = [];
    const promptPaths = [];
    const themePaths = [];
    for (const ext of extensions) {
        const handlers = ext.handlers.get("resources_discover");
        if (!handlers || handlers.length === 0)
            continue;
        for (const handler of handlers) {
            try {
                const event = { type: "resources_discover", cwd, reason };
                const result = (await handler(event, ctx));
                if (result?.skillPaths?.length) {
                    skillPaths.push(...result.skillPaths.map((path) => ({ path, extensionPath: ext.path })));
                }
                if (result?.promptPaths?.length) {
                    promptPaths.push(...result.promptPaths.map((path) => ({ path, extensionPath: ext.path })));
                }
                if (result?.themePaths?.length) {
                    themePaths.push(...result.themePaths.map((path) => ({ path, extensionPath: ext.path })));
                }
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "resources_discover", error);
            }
        }
    }
    return { skillPaths, promptPaths, themePaths };
}
export async function runInputHandlers(extensions, ctx, text, images, source, streamingBehavior, emitError) {
    let currentText = text;
    let currentImages = images;
    for (const ext of extensions) {
        for (const handler of ext.handlers.get("input") ?? []) {
            try {
                const event = {
                    type: "input",
                    text: currentText,
                    images: currentImages,
                    source,
                    streamingBehavior,
                };
                const result = (await handler(event, ctx));
                if (result?.action === "handled")
                    return result;
                if (result?.action === "transform") {
                    currentText = result.text;
                    currentImages = result.images ?? currentImages;
                }
            }
            catch (error) {
                emitCaughtError(emitError, ext.path, "input", error);
            }
        }
    }
    return currentText !== text || currentImages !== images
        ? { action: "transform", text: currentText, images: currentImages }
        : { action: "continue" };
}
//# sourceMappingURL=runner-events.js.map