/**
 * Diagnostic sidecar writer for compaction planner output.
 *
 * When the one-pass range planner returns malformed output or no usable ranges,
 * this module writes a private diagnostic file next to the persisted session
 * file. The sidecar is never written for in-memory sessions.
 *
 * Additionally, successful partial recovery from length-truncated responses
 * writes a private recovery diagnostic sidecar for operational observability.
 */
import { chmodSync, writeFileSync } from "fs";
import { basename, dirname, join } from "path";
function buildDiagnosticPayload(ctx) {
    return {
        version: 1,
        timestamp: new Date().toISOString(),
        failureCategory: ctx.failureCategory,
        failureMessage: ctx.failureMessage,
        rawResponse: ctx.rawResponseText,
        stopReason: ctx.response?.stopReason,
        providerError: ctx.response?.errorMessage,
        usage: ctx.response?.usage,
        requestMaxTokens: ctx.requestMaxTokens,
        model: {
            provider: ctx.model.provider,
            id: ctx.model.id,
            api: ctx.model.api,
            contextWindow: ctx.model.contextWindow,
            maxTokens: ctx.model.maxTokens,
        },
    };
}
/**
 * Derive the sidecar file path from a session file path and current timestamp.
 * The sidecar sits alongside the session file with a `-compaction-diagnostic-<ts>.json` suffix.
 */
export function diagnosticSidecarPath(sessionFilePath) {
    const dir = dirname(sessionFilePath);
    const base = basename(sessionFilePath, ".jsonl");
    const ts = Date.now();
    return join(dir, `${base}-compaction-diagnostic-${ts}.json`);
}
/**
 * Attempt to write a diagnostic sidecar file. Returns the written path on
 * success, or undefined if the session is in-memory or writing fails.
 *
 * The file is written with mode 0o600 (owner-only read/write) on platforms
 * that support POSIX permissions.
 */
export function writeDiagnosticSidecar(ctx) {
    if (!ctx.sessionFilePath)
        return undefined;
    const payload = buildDiagnosticPayload(ctx);
    const filePath = diagnosticSidecarPath(ctx.sessionFilePath);
    try {
        writeFileSync(filePath, JSON.stringify(payload, null, 2), { encoding: "utf-8", mode: 0o600 });
        try {
            chmodSync(filePath, 0o600);
        }
        catch { /* best-effort on non-POSIX */ }
        return filePath;
    }
    catch {
        return undefined;
    }
}
/**
 * Build the diagnostic payload without writing. Exported for testing.
 */
export { buildDiagnosticPayload };
function buildRecoveryPayload(ctx) {
    return {
        version: 1,
        timestamp: new Date().toISOString(),
        recoveryCategory: ctx.recoveryCategory,
        rawResponse: ctx.rawResponseText,
        stopReason: ctx.response.stopReason,
        usage: ctx.response.usage,
        requestMaxTokens: ctx.requestMaxTokens,
        model: {
            provider: ctx.model.provider,
            id: ctx.model.id,
            api: ctx.model.api,
            contextWindow: ctx.model.contextWindow,
            maxTokens: ctx.model.maxTokens,
        },
        recoveredRangeCount: ctx.recoveredRangeCount,
    };
}
/**
 * Write a recovery diagnostic sidecar on successful partial recovery.
 * Returns the written path on success, or undefined if write fails or session is in-memory.
 * Write failures are silently swallowed — recovery success is never affected.
 */
export function writeRecoveryDiagnosticSidecar(ctx) {
    if (!ctx.sessionFilePath)
        return undefined;
    const payload = buildRecoveryPayload(ctx);
    const dir = dirname(ctx.sessionFilePath);
    const base = basename(ctx.sessionFilePath, ".jsonl");
    const ts = Date.now();
    const filePath = join(dir, `${base}-compaction-recovery-${ts}.json`);
    try {
        writeFileSync(filePath, JSON.stringify(payload, null, 2), { encoding: "utf-8", mode: 0o600 });
        try {
            chmodSync(filePath, 0o600);
        }
        catch { /* best-effort on non-POSIX */ }
        return filePath;
    }
    catch {
        return undefined;
    }
}
export { buildRecoveryPayload };
//# sourceMappingURL=range-planner-diagnostics.js.map