/**
 * Intent Task Service — V2
 *
 * Manages the lifecycle of intent-based tasks with multi-intent decomposition:
 * - Decomposition: One chat message -> multiple intent tasks
 * - Intent Layer: classification, status management
 * - Execution Layer: Task -> Run -> Span tracking
 * - Association Layer: Schedule follow-up and project task linkage
 *
 * Integrates with TokenUsageService for per-task/run token tracking.
 *
 * @module services/intent-task/intent-task.service
 */
import { type IntentTask, type TaskRun, type TaskSpan, type IntentTaskStatus, type IntentTaskSummary, type CreateIntentTaskInput, type UpdateIntentTaskInput, type BatchCreateIntentTaskInput, type StartRunInput, type RecordSpanInput, type DecomposeMessageInput, type MessageGroup, type ProjectTaskStatus } from '../../types/intent-task.types.js';
/**
 * Service for creating, tracking, and managing intent-based tasks.
 *
 * V2 supports multi-intent decomposition: one chat message produces multiple
 * tasks grouped by messageId, displayed as a todo list.
 *
 * Uses in-memory storage with the Task -> Run -> Span execution model.
 * Token usage is bound to task_id + run_id via TokenUsageService integration.
 *
 * @example
 * ```typescript
 * const service = IntentTaskService.getInstance();
 * // Decompose a message into multiple tasks
 * const tasks = service.decomposeMessage({
 *   message: 'Search for abc then make it into a PDF'
 * });
 * // Each task can be worked on independently
 * const run = service.startRun(tasks[0].id, { sessionName: 'crewly-orc' });
 * service.completeRun(tasks[0].id, run.id);
 * service.completeTask(tasks[0].id, 'Found results');
 * ```
 */
export declare class IntentTaskService {
    private static instance;
    /** In-memory task storage keyed by task ID */
    private readonly tasks;
    /** Maps messageId to original message text for reconstruction */
    private readonly messageTexts;
    /** File path for JSON persistence */
    private readonly persistencePath;
    /** Timer handle for debounced save */
    private saveTimer;
    /**
     * @param persistencePath - Override file path (used in tests to avoid touching real data)
     */
    constructor(persistencePath?: string);
    /** Override persistence path for the next getInstance() call (testing only) */
    private static overridePath;
    /**
     * Get the singleton instance.
     *
     * @returns Shared IntentTaskService instance
     */
    static getInstance(): IntentTaskService;
    /**
     * Reset the singleton (for testing).
     * Flushes any pending writes before discarding.
     */
    static resetInstance(): void;
    /**
     * Set a custom persistence path for the next getInstance() call.
     * Pass undefined to reset to default path.
     * Used in tests to isolate from real user data.
     *
     * @param path - Custom file path, or undefined for default
     */
    static setPersistencePath(path: string | undefined): void;
    /**
     * Load tasks and messageTexts from the JSON persistence file.
     * Called once in the constructor. Silently starts empty if file is missing or corrupt.
     */
    private loadFromDisk;
    /**
     * Schedule a debounced write to disk.
     * Coalesces rapid mutations into a single file write after SAVE_DEBOUNCE_MS.
     */
    private scheduleSave;
    /**
     * Immediately write current state to disk.
     * Creates parent directories if they don't exist.
     */
    private saveToDisk;
    /**
     * Flush any pending debounced writes immediately.
     * Called before instance teardown and useful in tests.
     */
    flushSync(): void;
    /**
     * Decompose a user message into multiple intent tasks.
     *
     * Splits the message using heuristic patterns, classifies each intent,
     * and creates individual tasks grouped by a shared messageId.
     *
     * @param input - The message to decompose and optional metadata
     * @returns Array of created IntentTasks
     */
    decomposeMessage(input: DecomposeMessageInput): IntentTask[];
    /**
     * Create a new intent task.
     *
     * Auto-classifies level and category if not provided.
     * Generates a messageId if not supplied (for single-task creation).
     *
     * @param input - Task creation input
     * @returns The created IntentTask
     */
    createTask(input: CreateIntentTaskInput): IntentTask;
    /**
     * Create multiple intent tasks in a single batch, grouped by a shared messageId.
     *
     * Used by the orchestrator to create all tasks from one chat message at once.
     * All tasks share the same messageId for grouping in the todo-list UI.
     *
     * @param input - Batch creation input with tasks array and optional originalMessage
     * @returns Array of created IntentTasks
     */
    batchCreateTasks(input: BatchCreateIntentTaskInput): IntentTask[];
    /**
     * Schedule follow-up reminders for newly created tasks.
     * Lazy-imports IntentTaskFollowUpService to avoid circular dependency.
     * Runs asynchronously — does not block task creation.
     *
     * @param tasks - Newly created tasks to schedule follow-ups for
     */
    private scheduleFollowUpsAsync;
    /**
     * Get a task by ID.
     *
     * @param taskId - Task identifier
     * @returns The task, or null if not found
     */
    getTask(taskId: string): IntentTask | null;
    /**
     * List all tasks, optionally filtered by status.
     *
     * @param status - Optional status filter
     * @returns Array of tasks sorted by updatedAt descending
     */
    listTasks(status?: IntentTaskStatus): IntentTask[];
    /**
     * List task summaries for UI display.
     *
     * @param status - Optional status filter
     * @returns Array of task summaries
     */
    listTaskSummaries(status?: IntentTaskStatus): IntentTaskSummary[];
    /**
     * Update a task's status and/or metadata.
     *
     * When a task completes, this method also handles schedule cancellation
     * (clears scheduleId on terminal statuses).
     *
     * @param taskId - Task identifier
     * @param input - Fields to update
     * @returns The updated task
     * @throws Error if task not found
     */
    updateTask(taskId: string, input: UpdateIntentTaskInput): IntentTask;
    /**
     * Convenience: mark a task as completed with an optional result summary.
     * Clears scheduleId automatically and cancels any follow-up schedule.
     *
     * @param taskId - Task identifier
     * @param result - Optional result summary
     * @returns The updated task
     */
    completeTask(taskId: string, result?: string): IntentTask;
    /**
     * Convenience: mark a task as failed.
     * Clears scheduleId automatically and cancels any follow-up schedule.
     *
     * @param taskId - Task identifier
     * @param result - Optional error description
     * @returns The updated task
     */
    failTask(taskId: string, result?: string): IntentTask;
    /**
     * Delete a task by ID.
     *
     * @param taskId - Task identifier
     * @returns True if deleted, false if not found
     */
    deleteTask(taskId: string): boolean;
    /**
     * List tasks grouped by messageId, forming todo-list style groups.
     *
     * Each group represents one original chat message with its decomposed tasks.
     * Groups are sorted by creation time (newest first).
     *
     * When a status filter is provided, only groups containing at least one task
     * with that status are returned. The originalMessage is always preserved from
     * the stored messageTexts map (never rebuilt from filtered intents).
     *
     * @param status - Optional status filter; only groups with matching tasks are returned
     * @returns Array of MessageGroup objects
     */
    listMessageGroups(status?: IntentTaskStatus): MessageGroup[];
    /**
     * Get tasks for a specific message ID.
     *
     * @param messageId - Message identifier
     * @returns Array of tasks belonging to this message, sorted by order
     */
    getTasksByMessage(messageId: string): IntentTask[];
    /**
     * Get the completion status of a project task based on its linked intent tasks.
     *
     * @param projectTaskId - The project task ID from .crewly/tasks/
     * @returns ProjectTaskStatus with completion counts, or null if no tasks linked
     */
    getProjectTaskStatus(projectTaskId: string): ProjectTaskStatus | null;
    /**
     * Associate a schedule with a task for automatic follow-up.
     *
     * @param taskId - Task identifier
     * @param scheduleId - Schedule identifier to associate
     * @returns The updated task
     * @throws Error if task not found
     */
    setSchedule(taskId: string, scheduleId: string): IntentTask;
    /**
     * Get the schedule ID associated with a task.
     *
     * @param taskId - Task identifier
     * @returns The schedule ID, or undefined if none
     */
    getScheduleId(taskId: string): string | undefined;
    /**
     * Start a new run for a task.
     *
     * Sets the task to in_progress and binds token tracking via TokenUsageService.
     *
     * @param taskId - Task identifier
     * @param input - Run creation input (sessionName)
     * @returns The created TaskRun
     * @throws Error if task not found
     */
    startRun(taskId: string, input: StartRunInput): TaskRun;
    /**
     * Complete a run, aggregating token totals.
     *
     * @param taskId - Task identifier
     * @param runId - Run identifier
     * @returns The completed run
     * @throws Error if task or run not found
     */
    completeRun(taskId: string, runId: string): TaskRun;
    /**
     * Fail a run with an optional error message.
     *
     * @param taskId - Task identifier
     * @param runId - Run identifier
     * @param error - Optional error message
     * @returns The failed run
     * @throws Error if task or run not found
     */
    failRun(taskId: string, runId: string, error?: string): TaskRun;
    /**
     * Get a specific run.
     *
     * @param taskId - Task identifier
     * @param runId - Run identifier
     * @returns The run, or null if not found
     */
    getRun(taskId: string, runId: string): TaskRun | null;
    /**
     * Record a completed span within a run.
     *
     * Automatically updates run and task token aggregates.
     * For skill_call spans, use costOverride to record non-token costs.
     * Validates that the runId matches the current token tracking context.
     *
     * @param taskId - Task identifier
     * @param runId - Run identifier
     * @param input - Span data (supports costOverride for skill costs)
     * @returns The recorded span
     * @throws Error if task or run not found, run is not running, or runId mismatch
     */
    recordSpan(taskId: string, runId: string, input: RecordSpanInput): TaskSpan;
    /**
     * Get aggregate statistics across all tasks.
     *
     * @returns Object with counts and token totals
     */
    getStatistics(): {
        totalTasks: number;
        byStatus: Record<string, number>;
        byLevel: Record<string, number>;
        totalTokens: number;
        totalCost: number;
        llmCost: number;
        skillCost: number;
        totalMessages: number;
    };
    /**
     * Get the total number of tasks (for testing).
     *
     * @returns Number of tasks
     */
    getTaskCount(): number;
    /**
     * Get all unresolved tasks (status is not terminal: completed, failed, cancelled).
     *
     * Useful for follow-up scheduling and dashboard displays of tasks
     * that still need attention.
     *
     * @returns Array of tasks with non-terminal statuses, sorted by updatedAt descending
     */
    getUnresolvedTasks(): IntentTask[];
    /**
     * Cancel follow-up schedule if the task has one.
     * Lazily imports IntentTaskFollowUpService to avoid circular dependency.
     *
     * @param taskId - Task identifier
     */
    private cancelFollowUpIfExists;
    /**
     * Convert an IntentTask to an IntentTaskSummary for UI display.
     *
     * Includes originalMessage from the messageTexts map so that filtered
     * flat-list views preserve the user's original input context.
     */
    private toSummary;
    /**
     * Finish a run with a given status, aggregating totals.
     */
    private finishRun;
}
//# sourceMappingURL=intent-task.service.d.ts.map