import { Bt as discriminatedUnion, Et as array, Rn as string, Zn as unknown, dn as literal, fn as looseObject, wc as NEVER, wn as number, yt as _enum } from "./schemas-CZ9Toj_c.js";
import { i as resolveWorkspaceStateIdentity } from "./workspace-state-identity-CTYP_Hxy.js";
import { o as registerPluginStateSyncSequencedJournalEntry, v as pluginStateEntriesInKeyRange } from "./plugin-state-store-CUzhevT9.js";
import { createHash } from "node:crypto";
//#region src/memory-host-sdk/event-store.ts
const MEMORY_HOST_EVENTS_PLUGIN_ID = "memory-core";
const MEMORY_HOST_EVENTS_NAMESPACE = "memory-host.events";
const MEMORY_HOST_EVENT_CURSORS_NAMESPACE = "memory-host.event-cursors";
const MAX_MEMORY_HOST_EVENTS = 1e4;
const MAX_MEMORY_HOST_EVENT_CURSORS = 1e3;
const MAX_MEMORY_HOST_EVENT_JSON_BYTES = 8 * 1024;
const MAX_MEMORY_HOST_EVENT_ITEMS = 10;
const MAX_MEMORY_HOST_EVENT_TEXT_BYTES = 2 * 1024;
const MAX_MEMORY_HOST_EVENT_PATH_BYTES = 256;
const WORKSPACE_HASH_BYTES = 24;
const memoryHostFiniteNumberSchema = number().finite();
const memoryHostRecallResultSchema = looseObject({
	path: string(),
	startLine: memoryHostFiniteNumberSchema,
	endLine: memoryHostFiniteNumberSchema,
	score: memoryHostFiniteNumberSchema
});
const memoryHostSkippedRecallResultSchema = memoryHostRecallResultSchema.extend({ reason: literal("non-short-term-memory-path") });
const boundedRecallResultsSchema = array(unknown()).transform((values, context) => {
	const parsed = array(memoryHostRecallResultSchema).safeParse(values.slice(0, MAX_MEMORY_HOST_EVENT_ITEMS));
	if (!parsed.success) {
		context.addIssue({
			code: "custom",
			message: "invalid recall result"
		});
		return NEVER;
	}
	return {
		items: parsed.data,
		truncated: values.length > MAX_MEMORY_HOST_EVENT_ITEMS
	};
});
const boundedSkippedRecallResultsSchema = array(unknown()).transform((values, context) => {
	const parsed = array(memoryHostSkippedRecallResultSchema).safeParse(values.slice(0, MAX_MEMORY_HOST_EVENT_ITEMS));
	if (!parsed.success) {
		context.addIssue({
			code: "custom",
			message: "invalid skipped recall result"
		});
		return NEVER;
	}
	return {
		items: parsed.data,
		truncated: values.length > MAX_MEMORY_HOST_EVENT_ITEMS
	};
});
const memoryHostPromotionCandidateSchema = looseObject({
	key: string(),
	path: string(),
	startLine: memoryHostFiniteNumberSchema,
	endLine: memoryHostFiniteNumberSchema,
	score: memoryHostFiniteNumberSchema,
	recallCount: memoryHostFiniteNumberSchema
});
const boundedPromotionCandidatesSchema = array(unknown()).transform((values, context) => {
	const parsed = array(memoryHostPromotionCandidateSchema).safeParse(values.slice(0, MAX_MEMORY_HOST_EVENT_ITEMS));
	if (!parsed.success) {
		context.addIssue({
			code: "custom",
			message: "invalid promotion candidate"
		});
		return NEVER;
	}
	return {
		items: parsed.data,
		truncated: values.length > MAX_MEMORY_HOST_EVENT_ITEMS
	};
});
const memoryHostEventRecordSchema = discriminatedUnion("type", [
	looseObject({
		type: literal("memory.recall.recorded"),
		timestamp: string(),
		storageTruncated: unknown().optional(),
		query: string(),
		resultCount: memoryHostFiniteNumberSchema,
		results: boundedRecallResultsSchema
	}),
	looseObject({
		type: literal("memory.recall.skipped"),
		timestamp: string(),
		storageTruncated: unknown().optional(),
		query: string(),
		reason: literal("non-short-term-memory-path"),
		eligibleResultCount: memoryHostFiniteNumberSchema,
		skippedResultCount: memoryHostFiniteNumberSchema,
		results: boundedSkippedRecallResultsSchema
	}),
	looseObject({
		type: literal("memory.promotion.applied"),
		timestamp: string(),
		storageTruncated: unknown().optional(),
		memoryPath: string(),
		applied: memoryHostFiniteNumberSchema,
		candidates: boundedPromotionCandidatesSchema
	}),
	looseObject({
		type: literal("memory.dream.completed"),
		timestamp: string(),
		storageTruncated: unknown().optional(),
		phase: _enum([
			"light",
			"deep",
			"rem"
		]),
		outcome: _enum(["completed", "failed"]).optional(),
		error: string().optional(),
		inlinePath: string().optional(),
		reportPath: string().optional(),
		lineCount: memoryHostFiniteNumberSchema,
		storageMode: _enum([
			"inline",
			"separate",
			"both"
		])
	})
]);
function normalizeMemoryHostWorkspaceKey(workspaceDir) {
	const resolved = resolveWorkspaceStateIdentity(workspaceDir).workspacePath.replace(/\\/g, "/");
	return process.platform === "win32" ? resolved.toLowerCase() : resolved;
}
function memoryHostWorkspacePrefix(workspaceDir) {
	return createHash("sha256").update(normalizeMemoryHostWorkspaceKey(workspaceDir)).digest("hex").slice(0, WORKSPACE_HASH_BYTES);
}
function eventKeyPrefix(workspaceDir) {
	return `${memoryHostWorkspacePrefix(workspaceDir)}:event:`;
}
function eventKeyRangeEnd(workspaceDir) {
	return `${memoryHostWorkspacePrefix(workspaceDir)}:event;`;
}
function memoryHostEventStorageKey(workspaceDir, sequence) {
	if (!Number.isSafeInteger(sequence)) throw new Error("Memory host event sequence must be a safe integer");
	return `${eventKeyPrefix(workspaceDir)}1:${sequence.toString().padStart(16, "0")}`;
}
function cursorKey(workspaceDir) {
	return `${memoryHostWorkspacePrefix(workspaceDir)}:cursor`;
}
function truncateUtf8(value, maxBytes) {
	if (Buffer.byteLength(value, "utf8") <= maxBytes) return {
		value,
		truncated: false
	};
	let low = 0;
	let high = value.length;
	while (low < high) {
		const middle = Math.ceil((low + high) / 2);
		if (Buffer.byteLength(value.slice(0, middle), "utf8") <= maxBytes - 3) low = middle;
		else high = middle - 1;
	}
	const end = low > 0 && /[\uD800-\uDBFF]/u.test(value.charAt(low - 1)) ? low - 1 : low;
	return {
		value: `${value.slice(0, end)}…`,
		truncated: true
	};
}
/** Validate and bound one diagnostic event before storing it in plugin state. */
function normalizeMemoryHostEventRecordForStorage(value) {
	const parsed = memoryHostEventRecordSchema.safeParse(value);
	if (!parsed.success) return null;
	const event = parsed.data;
	const timestamp = truncateUtf8(event.timestamp, 128);
	let truncated = timestamp.truncated || event.storageTruncated === true;
	if (event.type === "memory.recall.recorded" || event.type === "memory.recall.skipped") {
		const query = truncateUtf8(event.query, MAX_MEMORY_HOST_EVENT_TEXT_BYTES);
		truncated ||= query.truncated || event.results.truncated;
		const results = event.results.items.map((result) => {
			const resultPath = truncateUtf8(result.path, MAX_MEMORY_HOST_EVENT_PATH_BYTES);
			truncated ||= resultPath.truncated;
			return {
				path: resultPath.value,
				startLine: result.startLine,
				endLine: result.endLine,
				score: result.score,
				...event.type === "memory.recall.skipped" ? { reason: "non-short-term-memory-path" } : {}
			};
		});
		const normalized = event.type === "memory.recall.recorded" ? {
			type: "memory.recall.recorded",
			timestamp: timestamp.value,
			query: query.value,
			resultCount: event.resultCount,
			results: results.map((result) => ({
				path: result.path,
				startLine: result.startLine,
				endLine: result.endLine,
				score: result.score
			})),
			...truncated ? { storageTruncated: true } : {}
		} : {
			type: "memory.recall.skipped",
			timestamp: timestamp.value,
			query: query.value,
			reason: "non-short-term-memory-path",
			eligibleResultCount: event.eligibleResultCount,
			skippedResultCount: event.skippedResultCount,
			results: results.map((result) => ({
				path: result.path,
				startLine: result.startLine,
				endLine: result.endLine,
				score: result.score,
				reason: "non-short-term-memory-path"
			})),
			...truncated ? { storageTruncated: true } : {}
		};
		return Buffer.byteLength(JSON.stringify(normalized), "utf8") <= MAX_MEMORY_HOST_EVENT_JSON_BYTES ? normalized : {
			...normalized,
			results: [],
			storageTruncated: true
		};
	}
	if (event.type === "memory.promotion.applied") {
		const memoryPath = truncateUtf8(event.memoryPath, MAX_MEMORY_HOST_EVENT_PATH_BYTES);
		truncated ||= memoryPath.truncated || event.candidates.truncated;
		const candidates = event.candidates.items.map((candidate) => {
			const key = truncateUtf8(candidate.key, MAX_MEMORY_HOST_EVENT_PATH_BYTES);
			const candidatePath = truncateUtf8(candidate.path, MAX_MEMORY_HOST_EVENT_PATH_BYTES);
			truncated ||= key.truncated || candidatePath.truncated;
			return {
				key: key.value,
				path: candidatePath.value,
				startLine: candidate.startLine,
				endLine: candidate.endLine,
				score: candidate.score,
				recallCount: candidate.recallCount
			};
		});
		const normalized = {
			type: "memory.promotion.applied",
			timestamp: timestamp.value,
			memoryPath: memoryPath.value,
			applied: event.applied,
			candidates,
			...truncated ? { storageTruncated: true } : {}
		};
		return Buffer.byteLength(JSON.stringify(normalized), "utf8") <= MAX_MEMORY_HOST_EVENT_JSON_BYTES ? normalized : {
			...normalized,
			candidates: [],
			storageTruncated: true
		};
	}
	if (event.type === "memory.dream.completed") {
		const error = event.error ? truncateUtf8(event.error, MAX_MEMORY_HOST_EVENT_TEXT_BYTES) : void 0;
		const inlinePath = event.inlinePath ? truncateUtf8(event.inlinePath, MAX_MEMORY_HOST_EVENT_PATH_BYTES) : void 0;
		const reportPath = event.reportPath ? truncateUtf8(event.reportPath, MAX_MEMORY_HOST_EVENT_PATH_BYTES) : void 0;
		truncated ||= Boolean(error?.truncated || inlinePath?.truncated || reportPath?.truncated);
		return {
			type: event.type,
			timestamp: timestamp.value,
			phase: event.phase,
			...event.outcome ? { outcome: event.outcome } : {},
			...error ? { error: error.value } : {},
			...inlinePath ? { inlinePath: inlinePath.value } : {},
			...reportPath ? { reportPath: reportPath.value } : {},
			lineCount: event.lineCount,
			storageMode: event.storageMode,
			...truncated ? { storageTruncated: true } : {}
		};
	}
	return null;
}
function registerMemoryHostEvent(params) {
	const event = normalizeMemoryHostEventRecordForStorage(params.event);
	if (!event) throw new TypeError("Memory host event is invalid");
	const initialSequence = Math.max(0, listStoredMemoryHostEvents({
		workspaceDir: params.workspaceDir,
		limit: 1,
		...params.env ? { env: params.env } : {}
	}).at(-1)?.value.sequence ?? 0);
	const recordedAt = Date.now();
	registerPluginStateSyncSequencedJournalEntry({
		pluginId: MEMORY_HOST_EVENTS_PLUGIN_ID,
		cursorOptions: {
			namespace: MEMORY_HOST_EVENT_CURSORS_NAMESPACE,
			maxEntries: MAX_MEMORY_HOST_EVENT_CURSORS,
			...params.env ? { env: params.env } : {}
		},
		cursorKey: cursorKey(params.workspaceDir),
		journalOptions: {
			namespace: MEMORY_HOST_EVENTS_NAMESPACE,
			maxEntries: MAX_MEMORY_HOST_EVENTS,
			...params.env ? { env: params.env } : {}
		},
		initialSequence,
		journalKey: (sequence) => memoryHostEventStorageKey(params.workspaceDir, sequence),
		journalValue: (sequence) => ({
			kind: "event",
			event,
			recordedAt,
			sequence
		})
	});
}
function listStoredMemoryHostEvents(params) {
	const limit = Number.isFinite(params.limit) ? Math.max(1, Math.min(MAX_MEMORY_HOST_EVENTS, Math.floor(params.limit))) : MAX_MEMORY_HOST_EVENTS;
	return pluginStateEntriesInKeyRange({
		pluginId: MEMORY_HOST_EVENTS_PLUGIN_ID,
		namespace: MEMORY_HOST_EVENTS_NAMESPACE,
		keyStartInclusive: eventKeyPrefix(params.workspaceDir),
		keyEndExclusive: eventKeyRangeEnd(params.workspaceDir),
		limit,
		order: "desc",
		...params.env ? { env: params.env } : {}
	}).flatMap((entry) => {
		const value = entry.value;
		return value.kind === "event" ? [{
			...entry,
			value
		}] : [];
	}).toReversed();
}
//#endregion
export { normalizeMemoryHostEventRecordForStorage as n, registerMemoryHostEvent as r, listStoredMemoryHostEvents as t };
