const require_chunk = require('./chunk-DWy1uDak.cjs');
const require_errors = require('./errors-BtJEw2Z-.cjs');
const require_define = require('./define-BfP4rFlE.cjs');
const require_api = require('./api-CZD9zwQ-.cjs');
const require_schema = require('./schema-Cv_VNAHz.cjs');
const __sentry_core = require_chunk.__toESM(require("@sentry/core"));

//#region src/tools/get-trace-details.ts
const MAX_DEPTH = 2;
const MINIMUM_DURATION_THRESHOLD_MS = 10;
const MIN_MEANINGFUL_CHILD_DURATION = 5;
const MIN_AVG_DURATION_MS = 5;
var get_trace_details_default = require_define.defineTool({
	name: "get_trace_details",
	requiredScopes: ["event:read"],
	description: [
		"Get detailed information about a specific Sentry trace by ID.",
		"",
		"🔍 USE THIS TOOL WHEN USERS:",
		"- Provide a specific trace ID (e.g., 'a4d1aae7216b47ff8117cf4e09ce9d0a')",
		"- Ask to 'show me trace [TRACE-ID]', 'explain trace [TRACE-ID]'",
		"- Want high-level overview and link to view trace details in Sentry",
		"- Need trace statistics and span breakdown",
		"",
		"❌ DO NOT USE for:",
		"- General searching for traces (use search_events with trace queries)",
		"- Individual span details (this shows trace overview)",
		"",
		"TRIGGER PATTERNS:",
		"- 'Show me trace abc123' → use get_trace_details",
		"- 'Explain trace a4d1aae7216b47ff8117cf4e09ce9d0a' → use get_trace_details",
		"- 'What is trace [trace-id]' → use get_trace_details",
		"",
		"<examples>",
		"### Get trace overview",
		"```",
		"get_trace_details(organizationSlug='my-organization', traceId='a4d1aae7216b47ff8117cf4e09ce9d0a')",
		"```",
		"</examples>",
		"",
		"<hints>",
		"- Trace IDs are 32-character hexadecimal strings",
		"</hints>"
	].join("\n"),
	inputSchema: {
		organizationSlug: require_schema.ParamOrganizationSlug,
		regionUrl: require_schema.ParamRegionUrl.optional(),
		traceId: require_schema.ParamTraceId
	},
	annotations: {
		readOnlyHint: true,
		openWorldHint: true
	},
	async handler(params, context) {
		if (!/^[0-9a-fA-F]{32}$/.test(params.traceId)) throw new require_errors.UserInputError("Trace ID must be a 32-character hexadecimal string");
		const apiService = require_api.apiServiceFromContext(context, { regionUrl: params.regionUrl });
		(0, __sentry_core.setTag)("organization.slug", params.organizationSlug);
		(0, __sentry_core.setTag)("trace.id", params.traceId);
		const traceMeta = await apiService.getTraceMeta({
			organizationSlug: params.organizationSlug,
			traceId: params.traceId,
			statsPeriod: "14d"
		});
		const trace = await apiService.getTrace({
			organizationSlug: params.organizationSlug,
			traceId: params.traceId,
			limit: 10,
			statsPeriod: "14d"
		});
		return formatTraceOutput({
			organizationSlug: params.organizationSlug,
			traceId: params.traceId,
			traceMeta,
			trace,
			apiService
		});
	}
});
/**
* Selects a subset of "interesting" spans from a trace for display in the overview.
*
* Creates a fake root span representing the entire trace, with selected interesting
* spans as children. This provides a unified tree view of the trace.
*
* The goal is to provide a meaningful sample of the trace that highlights the most
* important operations while staying within display limits. Selection prioritizes:
*
* 1. **Transactions** - Top-level operations that represent complete user requests
* 2. **Error spans** - Any spans that contain errors (critical for debugging)
* 3. **Long-running spans** - Operations >= 10ms duration (performance bottlenecks)
* 4. **Hierarchical context** - Maintains parent-child relationships for understanding
*
* Span inclusion rules:
* - All transactions are included (they're typically root-level operations)
* - Spans with errors are always included (debugging importance)
* - Spans with duration >= 10ms are included (performance relevance)
* - Children are recursively added up to 2 levels deep:
*   - Transactions can have up to 2 children each
*   - Regular spans can have up to 1 child each
* - Total output is capped at maxSpans to prevent overwhelming display
*
* @param spans - Complete array of trace spans with nested children
* @param traceId - Trace ID to display in the fake root span
* @param maxSpans - Maximum number of spans to include in output (default: 20)
* @returns Single-element array containing fake root span with selected spans as children
*/
function selectInterestingSpans(spans, traceId, maxSpans = 20) {
	const selected = [];
	let spanCount = 0;
	const actualSpans = spans.filter((item) => item && typeof item === "object" && "children" in item && Array.isArray(item.children) && "duration" in item);
	function addSpan(span, level) {
		if (spanCount >= maxSpans || level > MAX_DEPTH) return false;
		const duration = span.duration || 0;
		const isTransaction = span.is_transaction;
		const hasErrors = span.errors?.length > 0;
		const shouldInclude = isTransaction || hasErrors || level === 0 || duration >= MINIMUM_DURATION_THRESHOLD_MS;
		if (!shouldInclude) return false;
		const selectedSpan = {
			event_id: span.event_id,
			op: span.op || "unknown",
			name: span.name || null,
			description: span.description || span.transaction || "unnamed",
			duration,
			is_transaction: isTransaction,
			children: [],
			level
		};
		spanCount++;
		if (level < MAX_DEPTH && span.children?.length > 0) {
			const sortedChildren = span.children.filter((child) => child.duration > MIN_MEANINGFUL_CHILD_DURATION).sort((a, b) => (b.duration || 0) - (a.duration || 0));
			const maxChildren = isTransaction ? 2 : 1;
			let addedChildren = 0;
			for (const child of sortedChildren) {
				if (addedChildren >= maxChildren || spanCount >= maxSpans) break;
				if (addSpan(child, level + 1)) {
					const childSpan = selected[selected.length - 1];
					selectedSpan.children.push(childSpan);
					addedChildren++;
				}
			}
		}
		selected.push(selectedSpan);
		return true;
	}
	const sortedRoots = actualSpans.sort((a, b) => (b.duration || 0) - (a.duration || 0)).slice(0, 5);
	for (const root of sortedRoots) {
		if (spanCount >= maxSpans) break;
		addSpan(root, 0);
	}
	const rootSpans = selected.filter((span) => span.level === 0);
	const fakeRoot = {
		event_id: traceId,
		op: "trace",
		name: null,
		description: `Trace ${traceId.substring(0, 8)}`,
		duration: 0,
		is_transaction: false,
		children: rootSpans,
		level: -1
	};
	return [fakeRoot];
}
/**
* Formats a span display name for the tree view.
*
* Uses span.name if available (OTEL-native), otherwise falls back to span.description.
*
* @param span - The span to format
* @returns A formatted display name for the span
*/
function formatSpanDisplayName(span) {
	if (span.op === "trace") return "trace";
	return span.name?.trim() || span.description || "unnamed";
}
/**
* Renders a hierarchical tree structure of spans using Unicode box-drawing characters.
*
* Creates a visual tree representation showing parent-child relationships between spans,
* with proper indentation and connecting lines. Each span shows its operation, short ID,
* description, duration, and type (transaction vs span).
*
* Tree format:
* - Root spans have no prefix
* - Child spans use ├─ for intermediate children, └─ for last child
* - Continuation lines use │ for vertical connections
* - Proper spacing maintains visual alignment
*
* @param spans - Array of selected spans with their nested children structure
* @returns Array of formatted markdown strings representing the tree structure
*/
function renderSpanTree(spans) {
	const lines = [];
	function renderSpan(span, prefix = "", isLast = true) {
		const shortId = span.event_id.substring(0, 8);
		const connector = prefix === "" ? "" : isLast ? "└─ " : "├─ ";
		const displayName = formatSpanDisplayName(span);
		if (span.op === "trace") lines.push(`${prefix}${connector}${displayName} [${shortId}]`);
		else {
			const duration = span.duration ? `${Math.round(span.duration)}ms` : "unknown";
			const opDisplay = span.op === "default" ? "" : ` · ${span.op}`;
			lines.push(`${prefix}${connector}${displayName} [${shortId}${opDisplay} · ${duration}]`);
		}
		for (let i = 0; i < span.children.length; i++) {
			const child = span.children[i];
			const isLastChild = i === span.children.length - 1;
			const childPrefix = prefix + (isLast ? "   " : "│  ");
			renderSpan(child, childPrefix, isLastChild);
		}
	}
	for (let i = 0; i < spans.length; i++) {
		const span = spans[i];
		const isLastRoot = i === spans.length - 1;
		renderSpan(span, "", isLastRoot);
	}
	return lines;
}
function calculateOperationStats(spans) {
	const allSpans = getAllSpansFlattened(spans);
	const operationSpans = {};
	for (const span of allSpans) if (!span.children || span.children.length === 0) {
		const op = span.op || (span.name ? span.name.split(" ")[0] : "unknown");
		if (!operationSpans[op]) operationSpans[op] = [];
		operationSpans[op].push(span);
	}
	const stats = {};
	for (const [op, opSpans] of Object.entries(operationSpans)) {
		const durations = opSpans.map((span) => span.duration || 0).filter((duration) => duration > 0).sort((a, b) => a - b);
		const count = opSpans.length;
		const avgDuration = durations.length > 0 ? durations.reduce((sum, duration) => sum + duration, 0) / durations.length : 0;
		const p95Index = Math.floor(durations.length * .95);
		const p95Duration = durations.length > 0 ? durations[p95Index] || 0 : 0;
		stats[op] = {
			count,
			avgDuration,
			p95Duration
		};
	}
	return stats;
}
function getAllSpansFlattened(spans) {
	const result = [];
	const actualSpans = spans.filter((item) => item && typeof item === "object" && "children" in item && Array.isArray(item.children) && "duration" in item);
	function collectSpans(spanList) {
		for (const span of spanList) {
			result.push(span);
			if (span.children && span.children.length > 0) collectSpans(span.children);
		}
	}
	collectSpans(actualSpans);
	return result;
}
function formatTraceOutput({ organizationSlug, traceId, traceMeta, trace, apiService }) {
	const sections = [];
	sections.push(`# Trace \`${traceId}\` in **${organizationSlug}**`);
	sections.push("");
	sections.push("## Summary");
	sections.push("");
	sections.push(`**Total Spans**: ${traceMeta.span_count}`);
	sections.push(`**Errors**: ${traceMeta.errors}`);
	sections.push(`**Performance Issues**: ${traceMeta.performance_issues}`);
	sections.push(`**Logs**: ${traceMeta.logs}`);
	if (trace.length > 0) {
		const operationStats = calculateOperationStats(trace);
		const sortedOps = Object.entries(operationStats).filter(([, stats]) => stats.avgDuration >= MIN_AVG_DURATION_MS).sort(([, a], [, b]) => b.count - a.count).slice(0, 10);
		if (sortedOps.length > 0) {
			sections.push("");
			sections.push("## Operation Breakdown");
			sections.push("");
			for (const [op, stats] of sortedOps) {
				const avgDuration = Math.round(stats.avgDuration);
				const p95Duration = Math.round(stats.p95Duration);
				sections.push(`- **${op}**: ${stats.count} spans (avg: ${avgDuration}ms, p95: ${p95Duration}ms)`);
			}
			sections.push("");
		}
	}
	if (trace.length > 0) {
		const selectedSpans = selectInterestingSpans(trace, traceId);
		if (selectedSpans.length > 0) {
			sections.push("## Overview");
			sections.push("");
			const treeLines = renderSpanTree(selectedSpans);
			sections.push(...treeLines);
			sections.push("");
			sections.push("*Note: This shows a subset of spans. View the full trace for complete details.*");
			sections.push("");
		}
	}
	const traceUrl = apiService.getTraceUrl(organizationSlug, traceId);
	sections.push("## View Full Trace");
	sections.push("");
	sections.push(`**Sentry URL**: ${traceUrl}`);
	sections.push("");
	sections.push("## Find Related Events");
	sections.push("");
	sections.push(`Use this search query to find all events in this trace:`);
	sections.push("```");
	sections.push(`trace:${traceId}`);
	sections.push("```");
	sections.push("");
	sections.push("You can use this query with the `search_events` tool to get detailed event data from this trace.");
	return sections.join("\n");
}

//#endregion
Object.defineProperty(exports, 'get_trace_details_default', {
  enumerable: true,
  get: function () {
    return get_trace_details_default;
  }
});
//# sourceMappingURL=get-trace-details-iDp34mms.cjs.map