/**
 * SpecVerse AI Module — public surface.
 *
 * Post AI-SDK replatform (2026-04, engines 6.0):
 *   - Provider abstraction is Vercel AI SDK (`ai` + `@ai-sdk/*`).
 *   - SpecVerse-specific: model-resolver picks claude-cli | anthropic |
 *     openai-compatible | stub based on SPECVERSE_AI_PROVIDER.
 *   - Behaviour generation at realize time delegates to generateText()
 *     through the resolved model; skill-aware system-prompt assembly.
 *
 * What was removed in 6.0:
 *   - LLMProvider, LLMProviderRegistry, ProviderFactory
 *   - OpenAIProvider, AnthropicProvider, InteractiveProvider
 *   - SpecVerseOrchestrator, InteractiveWorkflow (dead code, no consumers)
 *   - ConfigLoader / SpecVerseConfig (consumed only by the orchestrator)
 *   - config-loader.ts (no consumers)
 * Consumers on those APIs should migrate to resolveModel() + generateText()
 * from 'ai'. See docs/guides/SPECVERSE-AI.md.
 */
// Commands — prompt-text generators for `spv ai {enhance,fill,suggest,template}`.
export * from './commands/index.js';
// Ecosystem prompt manager — used internally by enhance/suggest to surface
// library hints.
export * from './core/ecosystem-prompt-manager.js';
// Types.
export * from './types/index.js';
// Sessions — tracked job queue for multi-step spec generation.
export { SessionManager } from './session/session-manager.js';
// Behaviour generation — session-aware, provider-agnostic LLM call for
// unmatched behavior steps. Used by ai-behaviors-generator at realize time.
export { BehaviorAIService } from './behavior-ai-service.js';
// Regenerate a single owner's AI behaviors file on demand.
// Used by `specverse ai regenerate <Owner.fn>`.
export { regenerateBehavior } from './behavior-regenerate.js';
// Model resolver — pick a LanguageModelV3 from SPECVERSE_AI_PROVIDER env.
export { resolveModel, resolveProviderId, describeActiveProvider } from './model-resolver.js';
// AI-behavior library whitelist — single source of truth for which
// libraries the realized backend is allowed to dynamic-import from
// generated *.ai.ts pure-function bodies. See library-whitelist.ts header.
export { AI_BEHAVIOR_LIBRARY_WHITELIST, AI_BEHAVIOR_LIBRARY_TRIGGERS, isWhitelistedLibrary, predictAiBehaviorLibraries, extractDynamicImports, validateImportWhitelist, } from './library-whitelist.js';
// Custom providers — thin wrappers around claude CLI and no-op stub. Most
// consumers should use resolveModel() rather than calling these directly.
export { claudeCli, isClaudeCliAvailable, detectClaudePath } from './providers/claude-cli.js';
export { stubModel } from './providers/stub.js';
// Prompt runner — load + assemble + call a SpecVerse prompt YAML through
// the active provider. Used by analyse-runner / create-runner; also useful
// for eval harnesses that want to invoke prompts directly.
export { loadPrompt, substitute, assembleSystem, assembleUser, buildRunModel, runPrompt, extractSpec, extractSpecAndManifest, } from './prompt-runner.js';
// Analyse runner — high-level orchestrator for `spv ai analyse`. Takes a
// source dir, runs the LLM workflow (facts → analyse → validate → verify
// → validate → optional realize), writes the structured run output.
export { runAnalyse } from './analyse-runner.js';
// Behaviours runner — engines 6.29.0+. The LLM-heavy second phase of the
// analyse/behaviours split. Reads an analysed-spec dir + facts sidecars
// produced by `runAnalyse({withBehaviours: false})` and fills action
// bodies via per-action LLM micro-calls. Used by `spv ai behaviours`.
export { runBehaviours } from './behaviours-runner.js';
// Create runner — high-level orchestrator for `spv ai create`. Takes a
// natural-language request, runs the LLM workflow (create → validate →
// verify-create → validate → optional realize), writes structured output.
export { runCreate } from './create-runner.js';
// Run-paths — structured per-case run dir layout. Used by `spv ai analyse`
// / `spv ai create` (when those land via TODO #21) and the eval harness.
// One writer; consistent layout regardless of caller.
export { buildRunFolder, caseRunPath, ensureSubdirs, inputDir, factsDir, promptsDir, llmOutputDir, specsDir, projectDir, writeStageSpec, writeProjectReadme, writeManifest, writeScore, writeReadme, SUBDIRS, } from './run-paths.js';
// Skill detection — true if the SpecVerse skill is installed in a location
// Claude Code will auto-load. Used by behavior-ai-service to decide whether
// to skip the fullContext block in the system prompt.
export { detectInstalledSkill } from './skill-detection.js';
import { BehaviorAIService } from './behavior-ai-service.js';
class SpecVerseAIEngine {
    name = 'ai';
    version = '6.0.0';
    capabilities = ['ai-prompts', 'ai-suggestions', 'ai-templates', 'ai-behaviour'];
    manager = null;
    async initialize(config) {
        try {
            const { EcosystemPromptManager } = await import('./core/ecosystem-prompt-manager.js');
            this.manager = new EcosystemPromptManager(config?.catalogPath);
        }
        catch (error) {
            console.warn(`AI engine initialization: ${error instanceof Error ? error.message : String(error)}`);
        }
    }
    getInfo() {
        return { name: this.name, version: this.version, capabilities: this.capabilities };
    }
    async generatePrompt(spec, _options) {
        const components = spec?.components || [];
        const lines = [];
        lines.push('# SpecVerse Implementation Prompt');
        lines.push('');
        lines.push('Implement the following specification. The spec is declarative — it defines WHAT, not HOW.');
        lines.push('');
        for (const component of components) {
            lines.push(`## Component: ${component.name}`);
            if (component.description)
                lines.push(`\n${component.description}`);
            lines.push('');
            const models = component.models || [];
            if (models.length > 0) {
                lines.push(`### Models (${models.length})`);
                lines.push('');
                for (const model of models) {
                    lines.push(`#### ${model.name}`);
                    if (model.description)
                        lines.push(model.description);
                    const attrs = model.attributes || [];
                    if (attrs.length > 0) {
                        lines.push('');
                        lines.push('| Attribute | Type | Required | Unique |');
                        lines.push('|-----------|------|----------|--------|');
                        for (const attr of attrs) {
                            lines.push(`| ${attr.name} | ${attr.type || 'String'} | ${attr.required ? 'yes' : 'no'} | ${attr.unique ? 'yes' : 'no'} |`);
                        }
                    }
                    const rels = model.relationships || [];
                    if (rels.length > 0) {
                        lines.push('');
                        lines.push('**Relationships:**');
                        for (const rel of rels) {
                            lines.push(`- ${rel.name}: ${rel.type} ${rel.target}`);
                        }
                    }
                    lines.push('');
                }
            }
            const controllers = component.controllers || [];
            if (controllers.length > 0) {
                lines.push(`### Controllers (${controllers.length})`);
                for (const ctrl of controllers) {
                    lines.push(`- **${ctrl.name}** → ${ctrl.modelReference || ctrl.model || 'unknown model'}`);
                }
                lines.push('');
            }
            const services = component.services || [];
            if (services.length > 0) {
                lines.push(`### Services (${services.length})`);
                for (const svc of services) {
                    lines.push(`- **${svc.name}**`);
                    if (svc.operations) {
                        for (const [opName, op] of Object.entries(svc.operations)) {
                            lines.push(`  - ${opName}: ${op.description || ''}`);
                        }
                    }
                }
                lines.push('');
            }
            const events = component.events || [];
            if (events.length > 0) {
                lines.push(`### Events (${events.length})`);
                for (const evt of events) {
                    lines.push(`- **${evt.name}**`);
                }
                lines.push('');
            }
        }
        lines.push('## Implementation Guidelines');
        lines.push('');
        lines.push('1. Create database models matching the attribute and relationship specifications');
        lines.push('2. Implement CURVED controllers for each controller listed');
        lines.push('3. Add service methods as specified, with proper error handling');
        lines.push('4. Wire event handlers for cross-model communication');
        lines.push('5. Follow the relationship types: belongsTo (FK on this model), hasMany (FK on related model), hasOne, manyToMany');
        lines.push('');
        return lines.join('\n');
    }
    async suggest(spec, _context) {
        const { analyseSpec } = await import('./commands/spec-analyser.js');
        return analyseSpec(spec);
    }
    /**
     * Generate a TypeScript function body for an unmatched behavior step.
     * Delegates to BehaviorAIService which resolves the active provider
     * (claude-cli / anthropic / openai-compatible / stub) based on env.
     */
    async generateBehavior(step, context) {
        try {
            const service = new BehaviorAIService();
            if (!service.isAvailable)
                return null;
            return await service.generateBehavior({
                step,
                modelName: context.modelName,
                operationName: context.operationName,
                functionName: context.functionName,
                parameterNames: context.parameterNames,
                availableModels: context.availableModels || [],
                spec: context.spec,
            });
        }
        catch {
            return null;
        }
    }
    async template(operation, options) {
        try {
            const { getTemplate } = await import('./commands/template.js');
            const tmpl = await getTemplate(operation, { pver: options?.pver || 'default' });
            const lines = [];
            lines.push(`# ${tmpl.name}`);
            lines.push(`Version: ${tmpl.version}`);
            lines.push('');
            if (tmpl.system) {
                lines.push('## System Prompt');
                lines.push(tmpl.system);
                lines.push('');
            }
            if (tmpl.context) {
                lines.push('## Context');
                lines.push(tmpl.context);
                lines.push('');
            }
            if (tmpl.user) {
                lines.push('## User Prompt Template');
                lines.push(tmpl.user);
                lines.push('');
            }
            if (tmpl.variables && tmpl.variables.length > 0) {
                lines.push('## Variables');
                tmpl.variables.forEach((v) => lines.push(`- {{${v}}}`));
            }
            return lines.join('\n');
        }
        catch (error) {
            return `# Template: ${operation}\n\nPrompt templates are not available. Install prompts with: specverse init\n\nError: ${error instanceof Error ? error.message : String(error)}`;
        }
    }
}
export const engine = new SpecVerseAIEngine();
export default engine;
export { SpecVerseAIEngine };
//# sourceMappingURL=index.js.map