import { t as createSubsystemLogger } from "./subsystem-B57zAnh3.js";
import path from "node:path";
import { readFileSync, statSync } from "node:fs";
import process from "node:process";
import * as Sentry from "@sentry/node";

//#region src/events/crash-journal.ts
const log$3 = createSubsystemLogger("crash-journal");
const MAX_JOURNAL_BYTES = 1024 * 1024;

//#endregion
//#region src/events/turso-sync.ts
/**
* Turso write-behind sync engine — batches local events to remote Turso DB.
*
* Reads unsyncedEvents from the local EventStore and upserts them into
* the hub's `unified_events` table via `INSERT OR IGNORE` (dedup on
* serverId + localEventId). Uses exponential backoff on failures
* (max 30 minutes).
*
* Pattern follows the Turso client init approach used by the gateway.
*
* @module
*/
const log$2 = createSubsystemLogger("turso-sync");
const MAX_BACKOFF_MS = 1800 * 1e3;

//#endregion
//#region src/events/emitter.ts
/**
* Centralized event emitter — single emitEvent() entry point.
*
* All gateway event producers call emitEvent(). Internally:
* 1. Writes to local SQLite (synchronous via node:sqlite DatabaseSync)
* 2. Broadcasts "events.new" to connected WebSocket clients
* 3. Rate-limits high-frequency categories (tool, message)
*
* initEventSystem() is the full lifecycle wrapper called by server.impl.ts:
* - Creates EventStore
* - Replays crash journal into event store
* - Starts retention cleanup (immediate + daily)
* - Monitors DB size
* - Optionally starts TursoSyncEngine
* - Returns async shutdown that flushes sync before closing
*
* Singleton pattern matching existing reliability.ts style.
*
* @module
*/
const log$1 = createSubsystemLogger("events");
/** Categories subject to rate limiting. */
const RATE_LIMITED_CATEGORIES = new Set(["tool", "message"]);
/** Rate limit window per event name (ms). */
const RATE_LIMIT_MS$1 = 5e3;
/** Stale key cleanup interval (ms). */
const STALE_KEY_CLEANUP_MS$1 = 5 * 6e4;
const rateLimitMap$1 = /* @__PURE__ */ new Map();
function isRateLimited$1(category, eventName) {
	if (!RATE_LIMITED_CATEGORIES.has(category)) return false;
	const key = `${category}:${eventName}`;
	const now = Date.now();
	const last = rateLimitMap$1.get(key);
	if (last && now - last < RATE_LIMIT_MS$1) return true;
	rateLimitMap$1.set(key, now);
	return false;
}
let store = null;
let broadcastFn$1 = null;
/**
* Emit an event. Safe to call from any context — never throws.
*
* Writes to local SQLite, broadcasts to WebSocket clients, and
* rate-limits high-frequency categories (tool, message).
*/
function emitEvent(input) {
	if (!store) {
		log$1.warn("emitEvent called before initEventEmitter — event dropped");
		return;
	}
	if (isRateLimited$1(input.category, input.event)) return;
	try {
		const id = store.insert(input);
		if (broadcastFn$1) {
			const record = store.get(id);
			if (record) broadcastFn$1("events.new", record, { dropIfSlow: true });
		}
	} catch (err) {
		log$1.debug(`emitEvent error: ${err instanceof Error ? err.message : String(err)}`);
	}
}
/** One day in milliseconds. */
const ONE_DAY_MS = 1440 * 60 * 1e3;

//#endregion
//#region src/infra/sentry.ts
let initialized = false;
/**
* Capture an error in Sentry with optional extra context.
* No-ops if Sentry was not initialized.
*/
function captureError(err, context) {
	if (!initialized) return;
	Sentry.withScope((scope) => {
		if (context) scope.setExtras(context);
		Sentry.captureException(err);
	});
}
/**
* Add a breadcrumb to the current Sentry scope.
* No-ops if Sentry was not initialized.
*/
function addSentryBreadcrumb(crumb) {
	if (!initialized) return;
	Sentry.addBreadcrumb(crumb);
}
/**
* Start a Sentry span wrapping the provided async function.
* No-ops (calls fn directly) if Sentry was not initialized.
*/
async function startSentrySpan(options, fn) {
	if (!initialized) return fn(void 0);
	return Sentry.startSpan({
		op: options.op,
		name: options.name,
		attributes: options.attributes
	}, (span) => fn(span));
}
/**
* Run a function in a Sentry isolation scope so concurrent agent runs
* don't bleed context into each other.
* No-ops (calls fn directly) if Sentry was not initialized.
*/
async function withSentryIsolationScope(fn) {
	if (!initialized) return fn();
	return new Promise((resolve, reject) => {
		Sentry.withIsolationScope(() => {
			fn().then(resolve, reject);
		});
	});
}

//#endregion
//#region src/logging/reliability.ts
const log = createSubsystemLogger("reliability");
let broadcastFn = null;
const startedAtMs = Date.now();
const RATE_LIMIT_MS = 6e4;
const STALE_KEY_CLEANUP_MS = 5 * 6e4;
const rateLimitMap = /* @__PURE__ */ new Map();
function isRateLimited(eventType) {
	const now = Date.now();
	const last = rateLimitMap.get(eventType);
	if (last && now - last < RATE_LIMIT_MS) return true;
	rateLimitMap.set(eventType, now);
	return false;
}
/**
* Emit a reliability event. Thin wrapper around emitEvent() — routes the
* event through the unified event store while preserving backward-compatible
* broadcast on the "reliability" channel for legacy hub clients.
*/
function emitReliabilityEvent(input) {
	if (isRateLimited(input.event)) return;
	const timestamp = Date.now();
	emitEvent({
		category: input.category,
		severity: input.severity,
		event: input.event,
		message: input.message,
		agentId: input.agentId,
		correlationId: input.sessionKey,
		metadata: input.metadata,
		timestamp
	});
	if (broadcastFn) broadcastFn("reliability", {
		...input,
		timestamp
	}, { dropIfSlow: true });
	if (input.severity === "critical" || input.severity === "high") {
		log.warn(`[${input.category}] ${input.event}: ${input.message}`);
		captureError(/* @__PURE__ */ new Error(`[${input.category}] ${input.event}: ${input.message}`), {
			category: input.category,
			event: input.event,
			severity: input.severity,
			metadata: input.metadata
		});
	} else log.debug(`[${input.category}] ${input.event}: ${input.message}`);
}
/**
* Track every tool execution (not just skills). Persists to the event store
* under category "agent" (not rate-limited) so we can compute Tool Selection
* Accuracy (TSA) baseline metrics: error rate, retry rate, tool distribution.
* Best-effort — never throws.
*/
function trackToolExecution(stat) {
	try {
		emitEvent({
			category: "agent",
			severity: stat.status === "error" ? "low" : "info",
			event: `tool.exec.${stat.status}`,
			message: `Tool ${stat.toolName}: ${stat.status}`,
			correlationId: stat.runId,
			metadata: {
				toolName: stat.toolName,
				durationMs: stat.durationMs,
				...stat.errorMessage ? { errorMessage: stat.errorMessage } : {}
			},
			timestamp: stat.occurredAt
		});
	} catch {}
}
/**
* Track a skill (plugin) tool execution. Routes through the unified event
* store and forwards to the hub metrics push client if active.
* Best-effort — never throws.
*/
function trackSkillExecution(stat) {
	try {
		emitEvent({
			category: "skill",
			severity: "info",
			event: `skill.${stat.status}`,
			message: `Skill ${stat.skillName}: ${stat.status}`,
			metadata: {
				skillName: stat.skillName,
				durationMs: stat.durationMs,
				errorMessage: stat.errorMessage
			},
			timestamp: stat.occurredAt
		});
	} catch {}
}

//#endregion
export { startSentrySpan as a, addSentryBreadcrumb as i, trackSkillExecution as n, withSentryIsolationScope as o, trackToolExecution as r, emitEvent as s, emitReliabilityEvent as t };