/**
 * Memory Service Coordinator
 *
 * Provides a unified interface for both agent-level and project-level memory services.
 * Handles cross-cutting concerns like logging, validation, and combined context generation.
 *
 * @module services/memory/memory.service
 */
import { IAgentMemoryService } from './agent-memory.service.js';
import { IProjectMemoryService } from './project-memory.service.js';
import type { PatternCategory, GotchaSeverity, TaskHistoryEntry } from '../../types/memory.types.js';
/**
 * Categories for the unified remember operation
 */
export type RememberCategory = 'fact' | 'pattern' | 'decision' | 'gotcha' | 'preference' | 'user_preference' | 'relationship';
/**
 * Scope for memory operations
 */
export type MemoryScope = 'agent' | 'project' | 'both';
/**
 * Parameters for the remember operation
 */
export interface RememberParams {
    /** Agent identifier */
    agentId: string;
    /** Project path (required for project scope) */
    projectPath?: string;
    /** Content to remember */
    content: string;
    /** Category of memory */
    category: RememberCategory;
    /** Scope: agent or project */
    scope: 'agent' | 'project';
    /** Additional metadata */
    metadata?: {
        /** Task ID where this was learned */
        taskId?: string;
        /** Title for patterns/decisions/gotchas */
        title?: string;
        /** Pattern category */
        patternCategory?: PatternCategory;
        /** Code example */
        example?: string;
        /** Related files */
        files?: string[];
        /** Rationale for decisions */
        rationale?: string;
        /** Alternatives considered for decisions */
        alternatives?: string[];
        /** Areas affected by decisions */
        affectedAreas?: string[];
        /** Solution for gotchas */
        solution?: string;
        /** Severity for gotchas */
        severity?: GotchaSeverity;
        /** Relationship type */
        relationshipType?: 'depends-on' | 'uses' | 'extends' | 'implements' | 'calls' | 'imported-by';
        /** Target component for relationships */
        targetComponent?: string;
        /** Task ID where this knowledge was learned */
        sourceTaskId?: string;
        /** Objective/goal ID this knowledge relates to */
        sourceObjectiveId?: string;
        /** Outcome of the task where this was learned */
        sourceOutcome?: string;
        /** What contexts/domains this knowledge applies to */
        appliesTo?: string[];
        /** ID of entry being superseded by this one */
        supersedes?: string;
    };
}
/**
 * Parameters for the recall operation
 */
export interface RecallParams {
    /** Agent identifier */
    agentId: string;
    /** Project path (required for project/both scope) */
    projectPath?: string;
    /** Context/query for finding relevant memories */
    context: string;
    /** Scope: agent, project, or both */
    scope: MemoryScope;
    /** Maximum number of results */
    limit?: number;
    /**
     * v3 (M4 — NOTE-A): Include entries that are normally hidden from default
     * recall (superseded or TTL-expired entries). Default `false`.
     *
     * Use this to surface audit-only memories — e.g. when a TL is reviewing
     * what an agent learned before a fact was superseded, or when a debugging
     * tool needs the full trail. Production prompt-injection paths must keep
     * this `false` (or unset) so superseded entries do not pollute context.
     */
    includeHidden?: boolean;
    /**
     * Optional capability filter. When set, recall queries the project's
     * task-history ledger for entries whose `capabilities[]` contains an
     * exact match. The matching entries surface on
     * {@link RecallResult.taskHistory} sorted most-recent first.
     *
     * This is the load-bearing field for "who in my team has done X?"
     * — the orchestrator's delegation-first prompt queries with this
     * parameter before deciding whether to delegate or self-execute.
     *
     * Format: canonical `<category>:<resource>` strings
     * (`gmail:read`, `oauth:gmail`, `slack:post`, etc. — see
     * CapabilityInferenceService for the registry).
     */
    capability?: string;
}
/**
 * Result of a recall operation
 */
export interface RecallResult {
    /** Memories from agent level */
    agentMemories: string[];
    /** Memories from project level */
    projectMemories: string[];
    /** Combined formatted result */
    combined: string;
    /** Current project goals (if projectPath provided) */
    activeGoals?: string[];
    /** Current team focus (if projectPath provided) */
    currentFocus?: string;
    /** Active tasks for this agent */
    activeTasks?: Array<{
        id: string;
        name: string;
        status: string;
        hasWorkingNotes: boolean;
    }>;
    /**
     * Task-history entries matching {@link RecallParams.capability}. Present
     * when the caller passed a capability filter. Sorted most-recent first;
     * empty array means "no team member has demonstrated this capability."
     */
    taskHistory?: TaskHistoryEntry[];
}
/**
 * Parameters for recording a learning
 */
export interface LearningParams {
    /** Agent identifier */
    agentId: string;
    /** Agent's role */
    agentRole: string;
    /** Project path */
    projectPath: string;
    /** The learning content */
    learning: string;
    /** Related task/ticket ID */
    relatedTask?: string;
    /** Related file paths */
    relatedFiles?: string[];
}
/**
 * Interface for the unified Memory Service
 */
export interface IMemoryService {
    remember(params: RememberParams): Promise<string>;
    recall(params: RecallParams): Promise<RecallResult>;
    getFullContext(agentId: string, projectPath: string): Promise<string>;
    recordLearning(params: LearningParams): Promise<void>;
    initializeForSession(agentId: string, role: string, projectPath: string): Promise<void>;
    getAgentMemoryService(): IAgentMemoryService;
    getProjectMemoryService(): IProjectMemoryService;
}
/**
 * Unified Memory Service Coordinator
 *
 * Provides a single entry point for all memory operations, coordinating
 * between agent-level and project-level memory services.
 *
 * @example
 * ```typescript
 * const memoryService = MemoryService.getInstance();
 *
 * // Initialize for a session
 * await memoryService.initializeForSession('dev-001', 'developer', '/path/to/project');
 *
 * // Remember something
 * await memoryService.remember({
 *   agentId: 'dev-001',
 *   projectPath: '/path/to/project',
 *   content: 'Always use async/await instead of callbacks',
 *   category: 'pattern',
 *   scope: 'project',
 *   metadata: { title: 'Async Pattern' }
 * });
 *
 * // Get full context for prompts
 * const context = await memoryService.getFullContext('dev-001', '/path/to/project');
 * ```
 */
export declare class MemoryService implements IMemoryService {
    private static instance;
    private readonly agentMemory;
    private readonly projectMemory;
    private readonly logger;
    /**
     * Creates a new MemoryService instance
     */
    private constructor();
    /**
     * Backwards-compatible no-op. Kept so existing call sites in `index.ts`
     * compile during the TaskTrackingService deletion window. Operational
     * context enrichment now reads from the V3 task-pool directly (see
     * {@link enrichWithOperational}).
     *
     * @deprecated Will be removed in a follow-up. Do not call from new code.
     */
    setTaskTrackingService(_service: unknown): void;
    /**
     * Resolve the wiki vault paths that back semantic recall for a given scope.
     *
     * The retired embedding/vector store has been replaced by BM25 search over
     * the LLM-wiki vaults (see {@link wikiRecallSearch}). This maps a memory
     * scope to the vaults whose `llm-curated/` content should be searched:
     *   - `project` → the project's own vault (`<projectPath>/.crewly/wiki`)
     *   - `global`  → the cross-project `~/.crewly/global-wiki` plus every team
     *     vault (`~/.crewly/teams/<id>/wiki`); agent-scope learnings are mirrored
     *     into these by {@link ingestToWiki}.
     *
     * Only vaults that actually exist (carry a `SCHEMA.md`) are returned.
     *
     * @param scope - Memory scope being recalled.
     * @param projectPath - Project root, required for `project` scope.
     * @returns Absolute vault paths to search (possibly empty).
     */
    private resolveRecallVaults;
    /**
     * Gets the singleton instance of MemoryService
     *
     * @returns The singleton MemoryService instance
     */
    static getInstance(): MemoryService;
    /**
     * Clears the singleton instance (useful for testing)
     */
    static clearInstance(): void;
    /**
     * Gets the underlying AgentMemoryService
     *
     * @returns The AgentMemoryService instance
     */
    getAgentMemoryService(): IAgentMemoryService;
    /**
     * Gets the underlying ProjectMemoryService
     *
     * @returns The ProjectMemoryService instance
     */
    getProjectMemoryService(): IProjectMemoryService;
    /**
     * Maps RememberCategory to RoleKnowledgeCategory for agent memory.
     *
     * Public-API categories that map cleanly to internal storage:
     * - `fact` / `decision` → `best-practice` (positive learnings the agent should follow)
     * - `pattern` / `preference` → `workflow` (how-to / process knowledge)
     * - `gotcha` → `anti-pattern` (things to avoid; F4 fix 2026-05-06)
     *
     * Categories that do NOT reach this mapper because `rememberForAgent`
     * routes them differently or rejects them: `relationship` and
     * `user_preference` are project-only by design.
     */
    private mapToKnowledgeCategory;
    /**
     * Derives a content-aware title when the caller omits `metadata.title`.
     *
     * Defense-in-depth for the P0-SEV silent-success fix: even after dedup is
     * tightened to require title+content match, two different rememberings that
     * BOTH lacked an explicit title used to collide on the same default
     * ('Gotcha', 'Untitled Pattern', 'Untitled Decision'). Auto-deriving from
     * content makes those titles distinct, so any future dedup-predicate
     * regression cannot fully silently collapse them.
     *
     * Strategy: take the first ~60 chars of content, prefer a word boundary;
     * fall back to the caller-provided default if content is empty.
     *
     * @param content - The user-supplied content payload
     * @param fallback - The category-specific default title to use when content is empty
     * @returns A derived title string (max ~60 chars), never empty
     */
    private deriveTitleFromContent;
    /**
     * Parses a preference string into AgentPreferences
     */
    private parsePreference;
    /**
     * Checks if a learning is role-relevant (should be stored in agent memory)
     */
    private isRoleRelevant;
    /**
     * Filters memories by relevance to a context.
     *
     * **M3 (spec §183-187):** Default recall hides superseded and expired
     * entries via {@link isHiddenFromDefaultRecall}. They remain in the raw
     * store for audit / explicit recall, but they no longer pollute the
     * agent's recall path.
     *
     * **M4 (NOTE-A):** Pass `includeHidden=true` to surface superseded /
     * expired entries (audit-only paths). Production prompt-injection callers
     * must leave this `false` (default).
     */
    private filterRelevant;
    /**
     * Formats search results into strings
     */
    private formatSearchResults;
    /**
     * Combines agent and project memories into a formatted string
     */
    /**
     * Combines agent and project memories into a formatted string.
     *
     * Separates completed task markers (#219) into their own section so
     * orchestrators and PMs can easily identify work that is already done
     * and avoid re-delegating it.
     *
     * @param result - The recall result containing agent and project memories
     * @returns Formatted combined string with clear section headings
     */
    private combineMemories;
    /**
     * Mirror a remembered learning into the LLM-wiki so BM25 recall can surface
     * it. Replaces the retired embed-into-vector-store path: instead of computing
     * an embedding (the Gemini model was retired → 404), we append the content to
     * the target vault's `llm-curated/log.md` via {@link WikiIngestService}.
     *
     * No-ops silently when the target vault does not exist yet (no SCHEMA.md) so a
     * first-run machine without an initialised wiki still stores the file-based
     * memory without error. Fire-and-forget; never throws.
     *
     * @param id - Unique identifier for the memory entry (used as the source ref).
     * @param content - Text content to ingest.
     * @param metadata - Memory metadata (category/title surface in the log header).
     * @param scope - Storage scope ('global' → global-wiki, 'project' → project vault).
     * @param projectPath - Required when scope is 'project'.
     */
    private ingestToWiki;
    /**
     * BM25 full-text search over the LLM-wiki vaults backing semantic recall.
     * Replaces the retired embedding/vector-store search: ranks `.md` pages by
     * Okapi BM25 (see {@link WikiSearchService}) — CJK-aware, no external index,
     * no API key. Falls back gracefully to empty results when no vault exists.
     *
     * @param context - Search query text.
     * @param scope - Storage scope ('global' or 'project').
     * @param projectPath - Required when scope is 'project'.
     * @param limit - Maximum number of results.
     * @returns Formatted memory strings from the BM25 search.
     */
    private wikiRecallSearch;
    /**
     * Merge BM25 wiki hits into a base list of memory strings, de-duplicating
     * and capping the result to `limit`. The base (file-based) memories keep
     * priority; wiki hits fill any remaining slots.
     *
     * @param base - File-based memories already collected for this scope.
     * @param extra - BM25 wiki hits to fold in.
     * @param limit - Maximum size of the merged list.
     * @returns The merged, de-duplicated, capped list.
     */
    private mergeCapped;
    /**
     * Human-readable label for a wiki vault, derived from its path:
     * `global-wiki` → `global`, `teams/<id>/wiki` → `team:<id>`,
     * `<project>/.crewly/wiki` → the project directory name.
     *
     * @param vaultPath - Absolute vault path.
     * @returns A short label used to prefix recall hits.
     */
    private wikiVaultLabel;
    /**
     * Unified remember operation - stores content in appropriate memory
     *
     * @param params - Remember parameters
     * @returns ID of the stored memory entry
     *
     * @example
     * ```typescript
     * // Remember a pattern for the project
     * await memoryService.remember({
     *   agentId: 'dev-001',
     *   projectPath: '/path/to/project',
     *   content: 'Use error wrapper for all API endpoints',
     *   category: 'pattern',
     *   scope: 'project',
     *   metadata: {
     *     title: 'API Error Handling',
     *     patternCategory: 'api',
     *     example: 'handleApiError(handler)'
     *   }
     * });
     * ```
     */
    remember(params: RememberParams): Promise<string>;
    /**
     * Stores memory at agent level.
     *
     * Valid public-API categories for agent scope:
     * - `fact`, `pattern` → role knowledge (existing behavior)
     * - `gotcha` → role knowledge with internal `anti-pattern` category
     *   (F4 fix 2026-05-06: agents can now record personal gotchas without
     *    polluting project memory).
     * - `preference` → updates AgentPreferences struct
     *
     * Categories `relationship` and `user_preference` remain project-only
     * by design (relationship describes codebase component edges;
     * user_preference is scoped to a specific project's user).
     */
    private rememberForAgent;
    /**
     * Stores memory at project level
     */
    private rememberForProject;
    /**
     * Unified recall operation - retrieves relevant memories
     *
     * @param params - Recall parameters
     * @returns Recall results from appropriate scopes
     *
     * @example
     * ```typescript
     * const memories = await memoryService.recall({
     *   agentId: 'dev-001',
     *   projectPath: '/path/to/project',
     *   context: 'error handling in API endpoints',
     *   scope: 'both',
     *   limit: 10
     * });
     * console.log(memories.combined);
     * ```
     */
    recall(params: RecallParams): Promise<RecallResult>;
    /**
     * Enrich recall result with operational context: goals, focus, active tasks.
     * All lookups are non-fatal — missing data is silently skipped.
     */
    private enrichWithOperationalContext;
    /**
     * Generates combined context from both agent and project memory
     *
     * @param agentId - Agent identifier
     * @param projectPath - Project path
     * @returns Combined context string for prompt injection
     */
    getFullContext(agentId: string, projectPath: string): Promise<string>;
    /**
     * Records a learning to both project learnings and potentially agent memory
     *
     * @param params - Learning parameters
     */
    recordLearning(params: LearningParams): Promise<void>;
    /**
     * Initializes memory for a new session
     *
     * @param agentId - Agent identifier
     * @param role - Agent's role
     * @param projectPath - Project path
     */
    initializeForSession(agentId: string, role: string, projectPath: string): Promise<void>;
    /**
     * Recalls knowledge from all agents that have worked on a project
     *
     * Reads the project's agents-index.json, then searches each agent's role
     * knowledge for entries relevant to the given context. Results are merged,
     * deduplicated, and sorted by relevance.
     *
     * @param projectPath - Absolute path to the project
     * @param context - Search context for relevance filtering
     * @param limit - Maximum number of results (default 20)
     * @returns Array of formatted memory strings from all agents
     *
     * @example
     * ```typescript
     * const teamKnowledge = await memoryService.recallFromAllAgents(
     *   '/projects/app',
     *   'authentication middleware',
     *   15,
     * );
     * ```
     */
    recallFromAllAgents(projectPath: string, context: string, limit?: number): Promise<string[]>;
}
//# sourceMappingURL=memory.service.d.ts.map