/**
 * Orchestrator Task Metadata Types
 *
 * This module defines the metadata structure for tasks in the orchestration system.
 * Tasks gain additional metadata when managed by the orchestrator to track:
 * - Git branch association
 * - Worktree location
 * - Claude Code session ID for resumption
 *
 * This metadata is stored in the task's `metadata` field alongside any existing
 * task metadata.
 */
/**
 * All valid merge status values
 */
export const MergeStatusValues = [
    'pending',
    'testing',
    'merging',
    'merged',
    'conflict',
    'test_failed',
    'failed',
    'not_applicable',
];
/**
 * Type guard to check if a value is a valid MergeStatus
 */
export function isMergeStatus(value) {
    return typeof value === 'string' && MergeStatusValues.includes(value);
}
/**
 * Type guard to check if a value is a valid TestResult
 */
export function isTestResult(value) {
    if (typeof value !== 'object' || value === null) {
        return false;
    }
    const obj = value;
    return (typeof obj.passed === 'boolean' &&
        typeof obj.completedAt === 'string');
}
// ============================================================================
// Orchestrator Task Metadata Utilities
// ============================================================================
/**
 * Extracts orchestrator metadata from a task's metadata field
 */
export function getOrchestratorTaskMeta(taskMetadata) {
    if (!taskMetadata || typeof taskMetadata.orchestrator !== 'object') {
        return undefined;
    }
    return taskMetadata.orchestrator;
}
/**
 * Sets orchestrator metadata on a task's metadata field
 */
export function setOrchestratorTaskMeta(existingMetadata, orchestratorMeta) {
    return {
        ...existingMetadata,
        orchestrator: orchestratorMeta,
    };
}
/**
 * Updates orchestrator metadata on a task's metadata field
 */
export function updateOrchestratorTaskMeta(existingMetadata, updates) {
    const existing = getOrchestratorTaskMeta(existingMetadata) ?? {};
    return setOrchestratorTaskMeta(existingMetadata, {
        ...existing,
        ...updates,
    });
}
/**
 * Type guard to validate OrchestratorTaskMeta structure
 */
export function isOrchestratorTaskMeta(value) {
    if (typeof value !== 'object' || value === null) {
        return false;
    }
    const obj = value;
    // All fields are optional, so we just check types if present
    if (obj.branch !== undefined && typeof obj.branch !== 'string')
        return false;
    if (obj.worktree !== undefined && typeof obj.worktree !== 'string')
        return false;
    if (obj.sessionId !== undefined && typeof obj.sessionId !== 'string')
        return false;
    if (obj.assignedAgent !== undefined && typeof obj.assignedAgent !== 'string')
        return false;
    if (obj.mergeStatus !== undefined && !isMergeStatus(obj.mergeStatus))
        return false;
    if (obj.lastTestResult !== undefined && !isTestResult(obj.lastTestResult))
        return false;
    return true;
}
// ============================================================================
// Session History Utilities
// ============================================================================
/** Maximum number of session history entries to keep per task */
const MAX_SESSION_HISTORY_ENTRIES = 50;
/**
 * Appends a session history entry to the task's orchestrator metadata.
 * Caps the history at MAX_SESSION_HISTORY_ENTRIES entries.
 *
 * @param existingMetadata - The task's existing metadata
 * @param entry - The session history entry to append
 * @returns Updated task metadata with the new session history entry
 */
export function appendTaskSessionHistory(existingMetadata, entry) {
    const existing = getOrchestratorTaskMeta(existingMetadata);
    const existingHistory = existing?.sessionHistory ?? [];
    const newHistory = [...existingHistory, entry].slice(-MAX_SESSION_HISTORY_ENTRIES);
    return updateOrchestratorTaskMeta(existingMetadata, {
        sessionHistory: newHistory,
    });
}
/**
 * Closes a session history entry by setting the endedAt timestamp.
 * Finds the session history entry matching the sessionId that has no endedAt.
 *
 * @param existingMetadata - The task's existing metadata
 * @param sessionId - The session ID to close
 * @param endedAt - The timestamp when the session ended
 * @returns Updated task metadata with the closed session history entry
 */
export function closeTaskSessionHistory(existingMetadata, sessionId, endedAt) {
    const existing = getOrchestratorTaskMeta(existingMetadata);
    const existingHistory = existing?.sessionHistory ?? [];
    const updatedHistory = existingHistory.map((entry) => {
        if (entry.sessionId === sessionId && entry.endedAt === undefined) {
            return { ...entry, endedAt };
        }
        return entry;
    });
    return updateOrchestratorTaskMeta(existingMetadata, {
        sessionHistory: updatedHistory,
    });
}
// ============================================================================
// Branch and Worktree Naming Utilities
// ============================================================================
/**
 * Generates a branch name for an agent working on a task
 *
 * Format: agent/{worker-name}/{task-id}-{slug}
 *
 * @param workerName - The agent's name
 * @param taskId - The task ID
 * @param slug - URL-friendly slug derived from task title (optional)
 */
export function generateBranchName(workerName, taskId, slug) {
    const safeName = workerName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
    const safeTaskId = taskId.toLowerCase();
    if (slug) {
        const safeSlug = slug.toLowerCase().replace(/[^a-z0-9-]/g, '-').slice(0, 30);
        return `agent/${safeName}/${safeTaskId}-${safeSlug}`;
    }
    return `agent/${safeName}/${safeTaskId}`;
}
/**
 * Generates a worktree path for an agent working on a task
 *
 * Format: .stoneforge/.worktrees/{worker-name}-{task-slug}/
 *
 * @param workerName - The agent's name
 * @param slug - URL-friendly slug derived from task title (optional)
 */
export function generateWorktreePath(workerName, slug) {
    const safeName = workerName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
    if (slug) {
        const safeSlug = slug.toLowerCase().replace(/[^a-z0-9-]/g, '-').slice(0, 30);
        return `.stoneforge/.worktrees/${safeName}-${safeSlug}`;
    }
    return `.stoneforge/.worktrees/${safeName}`;
}
/**
 * Generates a branch name for a persistent worker session
 *
 * Format: session/{worker-name}-{timestamp}
 *
 * @param workerName - The agent's name
 * @param timestamp - Timestamp string (e.g. '20240115143022')
 */
export function generateSessionBranchName(workerName, timestamp) {
    const safeName = workerName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
    return `session/${safeName}-${timestamp}`;
}
/**
 * Generates a worktree path for a persistent worker session
 *
 * Format: .stoneforge/.worktrees/{worker-name}-session-{timestamp}/
 *
 * @param workerName - The agent's name
 * @param timestamp - Timestamp string (e.g. '20240115143022')
 */
export function generateSessionWorktreePath(workerName, timestamp) {
    const safeName = workerName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
    return `.stoneforge/.worktrees/${safeName}-session-${timestamp}`;
}
/**
 * Creates a URL-friendly slug from a task title
 */
export function createSlugFromTitle(title) {
    return title
        .toLowerCase()
        .replace(/[^a-z0-9\s-]/g, '') // Remove special characters
        .replace(/\s+/g, '-') // Replace spaces with hyphens
        .replace(/-+/g, '-') // Collapse multiple hyphens
        .slice(0, 30) // Limit length
        .replace(/^-|-$/g, ''); // Trim leading/trailing hyphens
}
//# sourceMappingURL=task-meta.js.map