export const DASHBOARD_COMPATIBILITY_CAPABILITIES = [
    'runs',
    'memory',
    'pod',
    'clients',
    'events',
    'stream',
    'specialists',
    'crews',
    'planner',
    'hooks',
    'automations',
    'federation',
    'orchestration',
    'tokens',
    'tokenSources',
    'instructionPacket',
    'orchestrationLedger',
    'knowledgeFabric',
    'ragCollections',
    'patterns',
    'modelTiers',
    'workerPlan',
    'artifactOutcomes',
    'memoryTrace',
    'memoryShared',
    'worktreeHealth',
    'featureRegistry',
    'synapse',
    'architects',
    'dashboardSummary',
    'dashboardSurfaces',
    'nexusLayer',
    'skillDistribution',
    'runtimeHealth',
];
export function createEngineHealthStatus(input) {
    const available = Boolean(input.available);
    const ready = Boolean(input.ready);
    const deferred = Boolean(input.deferred ?? (!ready && !available && input.reason?.includes('deferred')));
    const degraded = ready && (Boolean(input.fallbackApplied) || Boolean(input.reason));
    const mode = deferred
        ? 'deferred'
        : ready
            ? (degraded ? 'degraded' : 'ready')
            : available ? 'degraded' : 'blocked';
    return {
        name: input.name,
        available,
        ready,
        deferred,
        mode,
        required: !deferred, // deferred engines are opt-in, not required
        repoRoot: input.repoRoot,
        requestedStorageRoot: input.requestedStorageRoot,
        storageRoot: input.storageRoot,
        dbPath: input.dbPath,
        fallbackApplied: Boolean(input.fallbackApplied),
        reason: input.reason,
        quarantinePath: input.quarantinePath,
        remediation: (ready && !degraded) || deferred
            ? []
            : [
                `Inspect ${input.name} startup logs for the requested DB path.`,
                'Ensure better-sqlite3 is compiled and the resolved workspace state root is writable.',
                'Run nexus_doctor or nexus_runtime_health for the structured runtime envelope.',
            ],
    };
}
export function buildRuntimeHealthEnvelope(input) {
    const runtime = input.runtime;
    const memory = input.memory;
    const usage = runtime?.getUsageSnapshot();
    const memoryStorage = memory?.getStorageStatus?.();
    const clients = input.clients ?? [];
    const worktreeHealth = usage?.worktreeHealth;
    const selection = usage?.artifactSelectionAudit;
    const degradedReasons = [
        // Only count an engine as a degraded reason when it is neither ready nor intentionally deferred
        (input.synapse.mode === 'ready' || input.synapse.deferred) ? null : input.synapse.reason ?? `Synapse is ${input.synapse.mode}.`,
        (input.architects.mode === 'ready' || input.architects.deferred) ? null : input.architects.reason ?? `Architects is ${input.architects.mode}.`,
    ].filter((value) => Boolean(value));
    // Only flag a capability as missing when the engine failed (not when it was intentionally deferred)
    const missingCapabilities = ['synapse', 'architects'].filter((capability) => capability === 'synapse'
        ? (!input.synapse.ready && !input.synapse.deferred)
        : (!input.architects.ready && !input.architects.deferred));
    // Use 'healthy' if no true failures. Deferred engines don't drive status down.
    const hasRealFailure = degradedReasons.length > 0;
    const status = !hasRealFailure
        ? 'healthy'
        : (input.synapse.available || input.architects.available) ? 'degraded' : 'blocked';
    return {
        schemaVersion: 1,
        status,
        workspace: {
            workspaceRoot: input.workspace.workspaceRoot,
            repoRoot: input.workspace.repoRoot,
            stateRoot: input.workspace.stateRoot,
            source: input.workspace.source,
            notes: input.workspace.notes,
        },
        engines: {
            synapse: input.synapse,
            architects: input.architects,
        },
        runtime: {
            available: Boolean(runtime),
            runtimeId: runtime?.getRuntimeId?.() ?? null,
            latestRunId: usage?.latestRun?.runId ?? null,
            runsTracked: runtime?.listRuns?.(1_000)?.length ?? 0,
        },
        memory: {
            available: Boolean(memory),
            activeDbPath: memoryStorage?.activeDbPath ?? null,
            fallbackApplied: Boolean(memoryStorage?.fallbackApplied),
        },
        clients: {
            primaryClientId: input.primaryClient?.clientId ?? null,
            total: clients.length,
            active: clients.filter((client) => client.state === 'primaryActive' || client.state === 'active').length,
        },
        worktree: {
            status: worktreeHealth?.summary ?? 'No worktree health recorded yet.',
            actions: Array.isArray(worktreeHealth?.actions) ? worktreeHealth.actions.slice(0, 4) : [],
        },
        selection: {
            summary: selection?.summary ?? 'No selection audit recorded yet.',
            selected: selection?.selected?.length ?? 0,
            rejected: selection?.rejected?.length ?? 0,
        },
        compatibility: {
            requiredCapabilities: [...DASHBOARD_COMPATIBILITY_CAPABILITIES],
            missingCapabilities,
            ready: missingCapabilities.length === 0,
        },
        degradedReasons,
    };
}
