import { z } from 'zod';
import { safeLicensed } from './safe-handler.js';
import { getSpec } from '../storage/spec-store.js';
import { hashProjectPath } from '../storage/base-store.js';
import { generatePromptFromSpec } from '../engine/spec-prompt-generator.js';
import { compactResult } from './output-formatter.js';
import { SpecIdSchema } from './schemas/index.js';
// ---------------------------------------------------------------------------
// In-memory registry of registered prompts for this session
// ---------------------------------------------------------------------------
export const registeredPrompts = new Map();
// ---------------------------------------------------------------------------
// Zod schemas
// ---------------------------------------------------------------------------
const ExposeSpecAsPromptInputSchema = {
    specId: SpecIdSchema.describe('The spec ID to expose as an MCP prompt (e.g. "SPEC-042")'),
    projectPath: z.string().describe('Absolute path to the project root where the spec is stored'),
    promptName: z
        .string()
        .optional()
        .describe('Optional custom prompt name. If omitted, the name is derived from specId and slug'),
};
const ListSpecPromptsInputSchema = {
    projectPath: z
        .string()
        .optional()
        .describe('Optional project path filter. If omitted, all registered prompts are returned'),
};
// ---------------------------------------------------------------------------
// Handler: expose_spec_as_prompt
// ---------------------------------------------------------------------------
async function handleExposeSpecAsPrompt(args, server) {
    const projectId = hashProjectPath(args.projectPath);
    const spec = await getSpec(projectId, args.specId);
    if (spec === null) {
        return {
            content: [
                {
                    type: 'text',
                    text: `Spec "${args.specId}" not found in project at "${args.projectPath}".`,
                },
            ],
        };
    }
    const promptDef = generatePromptFromSpec({
        id: spec.id,
        slug: spec.slug,
        title: spec.title,
        summary: undefined,
        criteria: undefined,
    });
    const finalName = args.promptName ?? promptDef.name;
    // Register prompt with the MCP server
    server.registerPrompt(finalName, {
        description: promptDef.description,
        argsSchema: {
            context: z.string().optional().describe('Additional context for this spec execution'),
        },
    }, (promptArgs) => {
        const extra = promptArgs.context !== undefined ? `\n\nAdditional context: ${promptArgs.context}` : '';
        return {
            messages: [
                {
                    role: 'user',
                    content: {
                        type: 'text',
                        text: `${promptDef.template}${extra}`,
                    },
                },
            ],
        };
    });
    // Store in session registry
    registeredPrompts.set(finalName, { ...promptDef, name: finalName, specId: spec.id });
    const humanSummary = `Spec "${spec.title}" (${spec.id}) is now available as MCP prompt "${finalName}". ` +
        `Agents can invoke it with context to get structured implementation instructions.`;
    return compactResult(JSON.stringify({
        promptName: finalName,
        argumentCount: promptDef.arguments.length,
        registered: true,
        humanSummary,
    }));
}
// ---------------------------------------------------------------------------
// Handler: list_spec_prompts
// ---------------------------------------------------------------------------
function handleListSpecPrompts(_args) {
    const prompts = [];
    registeredPrompts.forEach((def, name) => {
        prompts.push({
            promptName: name,
            specId: def.specId,
            title: def.description,
        });
    });
    return compactResult(JSON.stringify(prompts));
}
// ---------------------------------------------------------------------------
// Registration
// ---------------------------------------------------------------------------
export function registerSpecPromptHandlers(server) {
    server.registerTool('expose_spec_as_prompt', {
        description: 'Expose a Planu spec as an executable MCP prompt that external agents can invoke. ' +
            'The prompt contains acceptance criteria as structured instructions.',
        inputSchema: ExposeSpecAsPromptInputSchema,
        annotations: {
            title: 'Expose Spec as MCP Prompt',
            readOnlyHint: false,
            destructiveHint: false,
            openWorldHint: false,
        },
    }, safeLicensed('expose_spec_as_prompt', async (args) => handleExposeSpecAsPrompt(args, server)));
    server.registerTool('list_spec_prompts', {
        description: 'List all Planu spec prompts registered in the current session. ' +
            'Returns prompt names, spec IDs, and titles.',
        inputSchema: ListSpecPromptsInputSchema,
        annotations: {
            title: 'List Spec Prompts',
            readOnlyHint: true,
            destructiveHint: false,
            openWorldHint: false,
        },
    }, safeLicensed('list_spec_prompts', (args) => Promise.resolve(handleListSpecPrompts(args))));
}
//# sourceMappingURL=spec-prompt-handler.js.map