/**
 * Mission Context Service — auto-injectable mission card for agent prompts.
 *
 * Builds a compact (≤2KB) markdown card that summarizes the active
 * project OKR, the team's most-relevant active missions, and the team
 * sub-OKR (if any) so every agent wakes with the answer to "what
 * mission am I serving right now?".
 *
 * Per Memory Phase 1 / Fix M1: today, agents must call `recall` or
 * `get_goals` explicitly to find the mission they're serving — and per
 * the architecture audit, an agent can finish a sprint without ever
 * reading it. This service closes that gap by feeding a tiny mission
 * card into prompt assembly automatically.
 *
 * Out of scope for Phase 1 (deferred to later phases):
 *   - Narrative summarization of mission state (no LLM round-trip here)
 *   - Vector embedding / semantic recall
 *   - Memory review queue / supersession
 *
 * @module services/memory/mission-context.service
 */
import { type Mission } from '../../types/v2/mission.types.js';
/**
 * Hard upper bound on the rendered mission card. The spec calls for
 * 1-2KB; we cap at 2KB and truncate by section priority (most-recent
 * status → oldest first) when over budget.
 */
export declare const MISSION_CONTEXT_HARD_CAP_BYTES = 2048;
/**
 * Inputs accepted by `getContextForAgent`.
 *
 * `projectPath` is the absolute path to the project root (the directory
 * containing `.crewly/`). `teamSlug` is the human-readable team slug
 * used to resolve `<slug>-team-sub-okr.md`; if omitted, the team-sub-OKR
 * section is skipped.
 */
export interface MissionContextRequest {
    /** Agent session id, used for logging only. */
    agentId: string;
    /** Absolute path to the project root that owns `.crewly/`. */
    projectPath: string;
    /** Team id whose missions should be surfaced (matches `Mission.ownerTeamId`). */
    teamId: string;
    /**
     * Optional ancestor team ids whose missions should ALSO be surfaced
     * to the agent — covers the OKR hierarchy case where a sub-team agent
     * needs to see the parent team / company-level mission they ladder up
     * to. Supplied by the caller (PromptBuilderService) which has team-
     * graph access; the service does no graph traversal of its own.
     */
    ancestorTeamIds?: string[];
    /**
     * Human-readable team slug used to find `<slug>-team-sub-okr.md`
     * under `.crewly/goals/`. If omitted, the team-sub-OKR section
     * is skipped.
     */
    teamSlug?: string;
    /** Optional id (informational, not used for filtering today). */
    projectId?: string;
}
/**
 * Builds a small markdown card describing the agent's mission context.
 *
 * Singleton, side-effect-free reads. All file IO is fail-soft: any
 * read or parse error skips the affected section but never throws into
 * the prompt-assembly path.
 *
 * @example
 * ```ts
 * const svc = MissionContextService.getInstance();
 * const card = await svc.getContextForAgent({
 *   agentId: 'crewly-product-leo-21a5477e',
 *   projectPath: '/Users/me/projects/crewly',
 *   teamId: '28a4ac10-...',
 *   teamSlug: 'product',
 * });
 * if (card) prompt += `\n${card}`;
 * ```
 */
export declare class MissionContextService {
    private static instance;
    private readonly logger;
    private readonly goalService;
    private constructor();
    /** Get the shared singleton instance. */
    static getInstance(): MissionContextService;
    /** Reset for tests. */
    static clearInstance(): void;
    /**
     * Build the mission-context card for an agent.
     *
     * Returns the empty string when no signals are available — callers
     * should treat empty output as "skip the section entirely" rather
     * than rendering an empty heading.
     *
     * @param req - Request inputs
     * @returns A ≤2KB markdown card, or `''` when nothing is worth showing
     */
    getContextForAgent(req: MissionContextRequest): Promise<string>;
    /**
     * Read up to `GOALS_MAX_LINES` non-empty, non-comment lines from
     * the project's `goals.md`. Returns `[]` when the file is missing.
     */
    private loadProjectGoalsSlice;
    /**
     * Read all `*.json` files under `<projectPath>/.crewly/missions/`,
     * filter to active missions whose `ownerTeamId` is in the supplied
     * `teamScope` (own team + any ancestor teams the caller passed in),
     * and sort by priority + recency. Returns `[]` on any error.
     */
    private loadActiveTeamMissions;
    /**
     * Read the team sub-OKR file at
     * `<projectPath>/.crewly/goals/<teamSlug>-team-sub-okr.md`. Returns
     * `[]` when no slug, no file, or any read error.
     */
    private loadTeamSubOkrSlice;
}
/**
 * Recent mission status entry — pulled from `mission.lastReviewSummary`,
 * ordered by `lastReviewAt` desc.
 */
export interface RecentMissionStatus {
    missionId: string;
    objective: string;
    summary: string;
    reviewedAt?: string;
}
/**
 * Collect the most recent status updates across the supplied missions.
 * A mission contributes at most one entry. Missions with no
 * `lastReviewSummary` are skipped. Result is sorted by `lastReviewAt`
 * descending; missions with no `lastReviewAt` sort last.
 */
export declare function collectRecentStatusUpdates(missions: Mission[]): RecentMissionStatus[];
/**
 * Extract up to `maxLines` "meaningful" lines from a markdown blob.
 *
 * Rules:
 *   - skip empty lines
 *   - skip standalone HTML/MD comments
 *   - keep headings, prose, list items
 *   - trim trailing whitespace
 *   - de-duplicate consecutive identical lines
 */
export declare function extractMeaningfulLines(raw: string, maxLines: number): string[];
/**
 * Render the final mission card as markdown using the spec template.
 * Sections with no data are omitted entirely (no empty headings).
 */
export declare function renderMissionCard(args: {
    goalsLines: string[];
    missions: Mission[];
    teamSubOkrLines: string[];
    statusUpdates: RecentMissionStatus[];
}): string;
/**
 * Enforce the hard byte cap. If `card` already fits, returns it
 * unchanged. Otherwise truncates line-by-line from the bottom until
 * it fits, then appends a single ellipsis line so the card is
 * obviously truncated.
 */
export declare function enforceHardCap(card: string, maxBytes: number): string;
/**
 * Module-level convenience: get the singleton in one call.
 */
export declare const getMissionContextService: () => MissionContextService;
//# sourceMappingURL=mission-context.service.d.ts.map