@sentrial/sdk 0.4.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +331 -41
- package/dist/cli.cjs +19 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +4 -46
- package/dist/cli.d.ts +4 -46
- package/dist/cli.js +19 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +4932 -1061
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +931 -517
- package/dist/index.d.ts +931 -517
- package/dist/index.js +4916 -1061
- package/dist/index.js.map +1 -1
- package/dist/types-BEf8OATP.d.cts +612 -0
- package/dist/types-BEf8OATP.d.ts +612 -0
- package/package.json +23 -12
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { spawn } from 'node:child_process';\nimport os from 'node:os';\nimport path from 'node:path';\nimport process from 'node:process';\nimport readline from 'node:readline/promises';\n\nconst DEFAULT_API_URL = 'https://api.sentrial.com';\nconst CLI_VERSION = '0.4.5';\nconst CONFIG_DIR = path.join(os.homedir(), '.sentrial');\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');\nconst TIME_RANGES = new Set(['24h', '3d', '7d', '30d']);\n\ntype FlagValue = string | boolean | undefined;\n\ninterface ParsedArgs {\n flags: Record<string, FlagValue>;\n positionals: string[];\n}\n\ninterface StoredConfig {\n apiKey?: string;\n apiUrl?: string;\n}\n\ninterface CliContext {\n apiKey?: string;\n apiUrl: string;\n json: boolean;\n color: boolean;\n}\n\ninterface ApiEnvelope<T> {\n data: T;\n meta?: Record<string, unknown>;\n}\n\ninterface SessionSummary {\n id: string;\n name?: string | null;\n agentName?: string | null;\n agentSlug?: string | null;\n userId?: string | null;\n status?: string | null;\n success?: boolean | null;\n failureReason?: string | null;\n totalEvents?: number | null;\n durationMs?: number | null;\n estimatedCost?: number | null;\n promptTokens?: number | null;\n completionTokens?: number | null;\n totalTokens?: number | null;\n score?: number | null;\n metricScores?: unknown;\n metricReasonings?: unknown;\n customMetrics?: unknown;\n userInput?: string | null;\n assistantOutput?: string | null;\n metadata?: unknown;\n detectedIssues?: unknown;\n createdAt?: string | null;\n completedAt?: string | null;\n}\n\ninterface EventSummary {\n id: string;\n sessionId: string;\n eventType: string;\n sequenceNumber?: number | null;\n timestamp?: string | null;\n toolName?: string | null;\n toolInput?: unknown;\n toolOutput?: unknown;\n toolError?: unknown;\n reasoning?: string | null;\n alternativesConsidered?: unknown;\n confidence?: number | null;\n estimatedCost?: number | null;\n tokenCount?: number | null;\n metadata?: unknown;\n traceId?: string | null;\n spanId?: string | null;\n}\n\ninterface SignalSummary {\n id: string;\n name: string;\n type: string;\n source?: string | null;\n count: number;\n affectedSessions: number;\n affectedUsers: number;\n description?: string | null;\n createdAt?: string | null;\n}\n\ninterface DiagnoseFinding {\n severity: 'high' | 'medium' | 'low' | 'info';\n title: string;\n detail: string;\n}\n\ninterface InstallPlan {\n language: 'typescript' | 'python';\n framework?: string;\n command: string;\n args: string[];\n packageName: string;\n}\n\nexport class CliError extends Error {\n readonly exitCode: number;\n\n constructor(message: string, exitCode = 1) {\n super(message);\n this.name = 'CliError';\n this.exitCode = exitCode;\n }\n}\n\nconst SHORT_FLAGS: Record<string, string> = {\n a: 'agent',\n f: 'force',\n h: 'help',\n j: 'json',\n l: 'last',\n s: 'status',\n t: 'type',\n v: 'version',\n y: 'yes',\n};\n\nconst BOOLEAN_FLAGS = new Set([\n 'force',\n 'help',\n 'include-api-key',\n 'json',\n 'dry-run',\n 'no-color',\n 'no-events',\n 'no-fail-on-regression',\n 'version',\n 'yes',\n]);\n\nconst HELP = `Sentrial CLI\n\nUsage:\n sentrial <command> [options]\n\nCommands:\n install Install the SDK package and scaffold integration files\n init Scaffold a safe example integration in this repo\n login Save an API key for future CLI calls\n sessions list List recent sessions\n sessions get <id> Show a session and its events\n events list <session-id> List events for a session\n signals list List detected signals\n diagnose <session-id> Print a terminal diagnosis from session events\n evaluate <experiment-id> Run the /api/v1/evaluate CI gate\n clusters Reserved for the upcoming clusters API\n fix <session-id> Reserved for the upcoming Fixer API\n replay <session-id> Reserved for the upcoming replay API\n\nGlobal options:\n --api-key <key> API key, otherwise SENTRIAL_API_KEY or ~/.sentrial/config.json\n --api-url <url> API URL, otherwise SENTRIAL_API_URL or ${DEFAULT_API_URL}\n --json Emit machine-readable JSON\n --no-color Disable ANSI color\n -h, --help Show help\n -v, --version Show version\n\nExamples:\n sentrial login --api-key sentrial_live_xxx\n sentrial install\n sentrial init\n sentrial sessions list --last 7d --status failed --agent support\n sentrial sessions get 00000000-0000-0000-0000-000000000000\n sentrial events list 00000000-0000-0000-0000-000000000000 --type tool_call\n sentrial signals list --type negative --last 30d\n sentrial diagnose 00000000-0000-0000-0000-000000000000\n sentrial evaluate 00000000-0000-0000-0000-000000000000 --min-score 80\n`;\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const flags: Record<string, FlagValue> = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i++) {\n const token = argv[i];\n if (token === '--') {\n positionals.push(...argv.slice(i + 1));\n break;\n }\n\n if (token.startsWith('--no-')) {\n flags[token.slice(5)] = false;\n continue;\n }\n\n if (token.startsWith('--')) {\n const [rawName, inlineValue] = token.slice(2).split('=', 2);\n if (inlineValue !== undefined) {\n flags[rawName] = inlineValue;\n } else if (BOOLEAN_FLAGS.has(rawName)) {\n flags[rawName] = true;\n } else {\n const next = argv[i + 1];\n if (next && !next.startsWith('-')) {\n flags[rawName] = next;\n i++;\n } else {\n flags[rawName] = true;\n }\n }\n continue;\n }\n\n if (token.startsWith('-') && token.length === 2) {\n const mapped = SHORT_FLAGS[token.slice(1)];\n if (!mapped) {\n throw new CliError(`Unknown flag: ${token}`);\n }\n if (BOOLEAN_FLAGS.has(mapped)) {\n flags[mapped] = true;\n } else {\n const next = argv[i + 1];\n if (!next || next.startsWith('-')) {\n throw new CliError(`Flag ${token} requires a value`);\n }\n flags[mapped] = next;\n i++;\n }\n continue;\n }\n\n positionals.push(token);\n }\n\n return { flags, positionals };\n}\n\nfunction getFlag(flags: Record<string, FlagValue>, ...names: string[]): FlagValue {\n for (const name of names) {\n if (flags[name] !== undefined) return flags[name];\n }\n return undefined;\n}\n\nfunction getStringFlag(flags: Record<string, FlagValue>, ...names: string[]): string | undefined {\n const value = getFlag(flags, ...names);\n if (typeof value === 'string') return value;\n return undefined;\n}\n\nfunction getBooleanFlag(flags: Record<string, FlagValue>, name: string): boolean {\n return flags[name] === true;\n}\n\nfunction readConfig(): StoredConfig {\n if (!existsSync(CONFIG_FILE)) return {};\n\n try {\n const parsed = JSON.parse(readFileSync(CONFIG_FILE, 'utf8')) as StoredConfig;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction writeConfig(config: StoredConfig): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n writeFileSync(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n try {\n chmodSync(CONFIG_FILE, 0o600);\n } catch {\n // Best effort only; some filesystems do not support chmod.\n }\n}\n\nfunction createContext(flags: Record<string, FlagValue>): CliContext {\n const config = readConfig();\n const apiKey = getStringFlag(flags, 'api-key') ?? process.env.SENTRIAL_API_KEY ?? config.apiKey;\n const apiUrl = (\n getStringFlag(flags, 'api-url') ??\n process.env.SENTRIAL_API_URL ??\n config.apiUrl ??\n DEFAULT_API_URL\n ).replace(/\\/$/, '');\n\n return {\n apiKey,\n apiUrl,\n json: getBooleanFlag(flags, 'json'),\n color: flags.color !== false && process.stdout.isTTY && !process.env.NO_COLOR,\n };\n}\n\nfunction requireApiKey(ctx: CliContext): string {\n if (!ctx.apiKey) {\n throw new CliError(\n 'Missing API key. Run `sentrial login --api-key sentrial_live_xxx` or set SENTRIAL_API_KEY.'\n );\n }\n return ctx.apiKey;\n}\n\nasync function apiRequest<T>(\n ctx: CliContext,\n apiPath: string,\n options: {\n method?: 'GET' | 'POST';\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n } = {}\n): Promise<T> {\n const apiKey = requireApiKey(ctx);\n const url = new URL(apiPath, `${ctx.apiUrl}/`);\n\n for (const [key, value] of Object.entries(options.query ?? {})) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${apiKey}`,\n Accept: 'application/json',\n };\n\n if (options.body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: options.method ?? 'GET',\n headers,\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n } catch (error) {\n throw new CliError(\n `Could not reach ${ctx.apiUrl}. ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n const text = await response.text();\n const parsed = parseResponseBody(text);\n\n if (!response.ok) {\n throw new CliError(\n `${options.method ?? 'GET'} ${url.pathname} failed (${response.status}): ${formatApiError(\n parsed\n )}`,\n response.status === 404 ? 4 : 1\n );\n }\n\n return parsed as T;\n}\n\nfunction parseResponseBody(text: string): unknown {\n if (!text.trim()) return {};\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction formatApiError(value: unknown): string {\n if (value && typeof value === 'object') {\n const record = value as Record<string, unknown>;\n if (typeof record.error === 'string') return record.error;\n if (record.error && typeof record.error === 'object') {\n const error = record.error as Record<string, unknown>;\n if (typeof error.message === 'string') return error.message;\n }\n }\n return typeof value === 'string' ? value : 'Unexpected API response';\n}\n\nasync function commandLogin(ctx: CliContext, flags: Record<string, FlagValue>): Promise<void> {\n let apiKey = getStringFlag(flags, 'api-key') ?? process.env.SENTRIAL_API_KEY;\n const apiUrl = getStringFlag(flags, 'api-url') ?? process.env.SENTRIAL_API_URL ?? ctx.apiUrl;\n\n if (!apiKey) {\n if (!process.stdin.isTTY) {\n throw new CliError('Pass --api-key or set SENTRIAL_API_KEY when stdin is not interactive.');\n }\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n apiKey = (await rl.question('Sentrial API key: ')).trim();\n rl.close();\n }\n\n if (!apiKey.startsWith('sentrial_')) {\n throw new CliError('API keys should look like sentrial_live_xxx or sentrial_test_xxx.');\n }\n\n writeConfig({ apiKey, apiUrl });\n\n if (ctx.json) {\n printJson({ ok: true, configPath: CONFIG_FILE, apiUrl });\n return;\n }\n\n process.stdout.write(`Saved credentials to ${CONFIG_FILE}\\n`);\n}\n\nasync function commandInstall(ctx: CliContext, flags: Record<string, FlagValue>): Promise<void> {\n const projectRoot = process.cwd();\n const requestedLanguage = getStringFlag(flags, 'language');\n const pythonCommand = getStringFlag(flags, 'python');\n const packageOverride = getStringFlag(flags, 'sdk-package') ?? process.env.SENTRIAL_SDK_PACKAGE;\n const plan = buildInstallPlan(projectRoot, requestedLanguage, pythonCommand, packageOverride);\n const dryRun = getBooleanFlag(flags, 'dry-run');\n\n if (ctx.json) {\n if (!dryRun) {\n throw new CliError('Use --dry-run with --json; real installs stream package-manager output.');\n }\n printJson({ dryRun: true, plan, wouldWrite: plannedScaffoldFiles(projectRoot, plan.language) });\n return;\n }\n\n process.stdout.write(`Detected: ${plan.framework ?? plan.language}\\n`);\n process.stdout.write(`Install: ${formatCommand(plan.command, plan.args)}\\n`);\n\n if (dryRun) {\n process.stdout.write('Dry run only. No files were changed.\\n');\n return;\n }\n\n await runSubprocess(plan.command, plan.args, projectRoot);\n await commandInit(ctx, flags);\n}\n\nasync function commandInit(ctx: CliContext, flags: Record<string, FlagValue>): Promise<void> {\n const projectRoot = process.cwd();\n const detected = detectProject(projectRoot);\n const requestedLanguage = getStringFlag(flags, 'language');\n const language = requestedLanguage ?? detected.language ?? 'typescript';\n const force = getBooleanFlag(flags, 'force');\n const apiKey = getBooleanFlag(flags, 'include-api-key')\n ? (ctx.apiKey ?? 'sentrial_live_xxx')\n : 'sentrial_live_xxx';\n\n if (language !== 'typescript' && language !== 'python') {\n throw new CliError('Supported init languages are \"typescript\" and \"python\".');\n }\n\n const files =\n language === 'python'\n ? [\n {\n path: path.join(projectRoot, 'sentrial.example.py'),\n content: pythonExample(),\n },\n ]\n : [\n {\n path: path.join(projectRoot, 'sentrial.example.ts'),\n content: typescriptExample(),\n },\n ];\n\n files.push({\n path: path.join(projectRoot, '.env.sentrial.example'),\n content: `SENTRIAL_API_KEY=${apiKey}\\nSENTRIAL_API_URL=${ctx.apiUrl}\\n`,\n });\n\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const file of files) {\n if (existsSync(file.path) && !force) {\n skipped.push(file.path);\n continue;\n }\n writeFileSync(file.path, file.content);\n written.push(file.path);\n }\n\n const installCommand =\n language === 'python'\n ? 'pip install sentrial'\n : `${detectPackageManager(projectRoot)} add @sentrial/sdk`;\n\n if (ctx.json) {\n printJson({\n detected,\n language,\n installCommand,\n written,\n skipped,\n });\n return;\n }\n\n process.stdout.write(`Detected: ${detected.framework ?? language}\\n`);\n process.stdout.write(`Install: ${installCommand}\\n`);\n if (written.length > 0) {\n process.stdout.write(\n `Written:\\n${written.map((file) => ` ${path.relative(projectRoot, file)}`).join('\\n')}\\n`\n );\n }\n if (skipped.length > 0) {\n process.stdout.write(\n `Skipped existing files:\\n${skipped.map((file) => ` ${path.relative(projectRoot, file)}`).join('\\n')}\\n`\n );\n }\n}\n\nasync function commandSessions(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n rest: string[]\n): Promise<void> {\n const subcommand = rest[0];\n if (subcommand === 'list') {\n await commandSessionsList(ctx, flags);\n return;\n }\n if (subcommand === 'get') {\n const sessionId = rest[1];\n if (!sessionId) throw new CliError('Usage: sentrial sessions get <id>');\n await commandSessionsGet(ctx, flags, sessionId);\n return;\n }\n throw new CliError('Usage: sentrial sessions <list|get>');\n}\n\nasync function commandSessionsList(\n ctx: CliContext,\n flags: Record<string, FlagValue>\n): Promise<void> {\n const query = buildTimeQuery(flags);\n const agentFilter = getStringFlag(flags, 'agent')?.toLowerCase();\n const hasExplicitLimit = getStringFlag(flags, 'limit') !== undefined;\n query.status = getStringFlag(flags, 'status') ?? 'all';\n query.limit = parseIntegerFlag(flags, 'limit', agentFilter && !hasExplicitLimit ? 500 : 50);\n query.offset = parseIntegerFlag(flags, 'offset', 0);\n\n const response = await apiRequest<ApiEnvelope<SessionSummary[]>>(ctx, '/api/v1/sessions', {\n query,\n });\n\n const sessions = agentFilter\n ? response.data.filter((session) =>\n `${session.agentName ?? ''} ${session.agentSlug ?? ''}`.toLowerCase().includes(agentFilter)\n )\n : response.data;\n\n if (ctx.json) {\n printJson({ data: sessions, meta: response.meta });\n return;\n }\n\n if (sessions.length === 0) {\n process.stdout.write('No sessions found.\\n');\n return;\n }\n\n printTable(sessions, [\n { header: 'ID', render: (s) => s.id, maxWidth: 36 },\n { header: 'Agent', render: (s) => s.agentName ?? s.agentSlug ?? '-', maxWidth: 18 },\n { header: 'Status', render: (s) => s.status ?? '-', maxWidth: 10 },\n { header: 'Result', render: (s) => formatResult(s.success), maxWidth: 8 },\n { header: 'Score', render: (s) => formatNullableNumber(s.score), maxWidth: 6 },\n { header: 'Dur', render: (s) => formatDuration(s.durationMs), maxWidth: 8 },\n { header: 'Cost', render: (s) => formatCost(s.estimatedCost), maxWidth: 10 },\n { header: 'Created', render: (s) => formatDate(s.createdAt), maxWidth: 16 },\n { header: 'Name', render: (s) => s.name ?? '-', maxWidth: 28 },\n ]);\n\n if (agentFilter) {\n process.stdout.write(`\\nFiltered locally by agent: ${agentFilter}\\n`);\n }\n}\n\nasync function commandSessionsGet(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n sessionId: string\n): Promise<void> {\n const sessionResponse = await apiRequest<ApiEnvelope<SessionSummary>>(\n ctx,\n `/api/v1/sessions/${sessionId}`\n );\n const includeEvents = flags.events !== false;\n const events = includeEvents ? await fetchSessionEvents(ctx, flags, sessionId) : [];\n\n if (ctx.json) {\n printJson({ data: sessionResponse.data, events });\n return;\n }\n\n printSession(sessionResponse.data, events, ctx);\n}\n\nasync function fetchSessionEvents(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n sessionId: string\n): Promise<EventSummary[]> {\n const eventType = getStringFlag(flags, 'event-type') ?? 'all';\n const response = await apiRequest<ApiEnvelope<EventSummary[]>>(\n ctx,\n `/api/v1/sessions/${sessionId}/events`,\n {\n query: {\n limit: parseIntegerFlag(flags, 'events-limit', 100),\n offset: parseIntegerFlag(flags, 'events-offset', 0),\n eventType,\n },\n }\n );\n return response.data;\n}\n\nasync function commandEvents(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n rest: string[]\n): Promise<void> {\n const subcommand = rest[0] ?? 'list';\n if (subcommand !== 'list') {\n throw new CliError('Usage: sentrial events list <session-id>');\n }\n\n const sessionId = rest[1] ?? getStringFlag(flags, 'session', 'session-id');\n if (!sessionId) {\n throw new CliError('Usage: sentrial events list <session-id>');\n }\n\n const eventType = getStringFlag(flags, 'type', 'event-type') ?? 'all';\n const response = await apiRequest<ApiEnvelope<EventSummary[]>>(\n ctx,\n `/api/v1/sessions/${sessionId}/events`,\n {\n query: {\n limit: parseIntegerFlag(flags, 'limit', 100),\n offset: parseIntegerFlag(flags, 'offset', 0),\n eventType,\n },\n }\n );\n\n if (ctx.json) {\n printJson(response);\n return;\n }\n\n if (response.data.length === 0) {\n process.stdout.write('No events found.\\n');\n return;\n }\n\n process.stdout.write(`${bold(ctx, 'Events')} ${sessionId}\\n`);\n for (const event of response.data) {\n printEvent(event, ctx);\n }\n}\n\nasync function commandSignals(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n rest: string[]\n): Promise<void> {\n const subcommand = rest[0] ?? 'list';\n if (subcommand !== 'list') {\n throw new CliError('Usage: sentrial signals list');\n }\n\n const query = buildTimeQuery(flags);\n query.type = getStringFlag(flags, 'type') ?? 'all';\n query.source = getStringFlag(flags, 'source') ?? 'all';\n\n const response = await apiRequest<ApiEnvelope<SignalSummary[]>>(ctx, '/api/v1/signals', {\n query,\n });\n\n if (ctx.json) {\n printJson(response);\n return;\n }\n\n if (response.data.length === 0) {\n process.stdout.write('No signals found.\\n');\n return;\n }\n\n printTable(response.data, [\n { header: 'Name', render: (s) => s.name, maxWidth: 28 },\n { header: 'Type', render: (s) => s.type, maxWidth: 10 },\n { header: 'Source', render: (s) => s.source ?? '-', maxWidth: 12 },\n { header: 'Count', render: (s) => String(s.count), maxWidth: 8 },\n { header: 'Sessions', render: (s) => String(s.affectedSessions), maxWidth: 10 },\n { header: 'Users', render: (s) => String(s.affectedUsers), maxWidth: 8 },\n { header: 'Created', render: (s) => formatDate(s.createdAt), maxWidth: 16 },\n { header: 'Description', render: (s) => s.description ?? '-', maxWidth: 36 },\n ]);\n}\n\nasync function commandDiagnose(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n sessionId: string | undefined\n): Promise<void> {\n if (!sessionId) throw new CliError('Usage: sentrial diagnose <session-id>');\n\n const sessionResponse = await apiRequest<ApiEnvelope<SessionSummary>>(\n ctx,\n `/api/v1/sessions/${sessionId}`\n );\n const events = await fetchSessionEvents(ctx, flags, sessionId);\n const findings = diagnoseSession(sessionResponse.data, events);\n\n if (ctx.json) {\n printJson({ session: sessionResponse.data, findings });\n return;\n }\n\n process.stdout.write(`${bold(ctx, 'Diagnosis')}\\n`);\n process.stdout.write(`Session: ${sessionResponse.data.id}\\n`);\n process.stdout.write(\n `Agent: ${sessionResponse.data.agentName ?? sessionResponse.data.agentSlug ?? '-'}\\n`\n );\n process.stdout.write(\n `Status: ${sessionResponse.data.status ?? '-'} (${formatResult(sessionResponse.data.success)})\\n`\n );\n if (sessionResponse.data.failureReason) {\n process.stdout.write(`Failure: ${sessionResponse.data.failureReason}\\n`);\n }\n process.stdout.write('\\n');\n\n if (findings.length === 0) {\n process.stdout.write('No obvious terminal-level issues found in the session events.\\n');\n return;\n }\n\n for (const finding of findings) {\n process.stdout.write(`${severityLabel(ctx, finding.severity)} ${finding.title}\\n`);\n process.stdout.write(` ${finding.detail}\\n`);\n }\n}\n\nasync function commandEvaluate(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n experimentId: string | undefined\n): Promise<void> {\n const resolvedExperimentId = experimentId ?? getStringFlag(flags, 'experiment', 'experiment-id');\n if (!resolvedExperimentId) {\n throw new CliError('Usage: sentrial evaluate <experiment-id> [--min-score 80]');\n }\n\n const body = {\n experimentId: resolvedExperimentId,\n baselineExperimentId: getStringFlag(flags, 'baseline', 'baseline-experiment-id'),\n thresholds: {\n minScore: parseOptionalNumberFlag(flags, 'min-score'),\n failOnRegression: flags['fail-on-regression'] === false ? false : undefined,\n maxRegressionPercent: parseOptionalNumberFlag(flags, 'max-regression-percent'),\n },\n };\n\n const response = await apiRequest<Record<string, unknown>>(ctx, '/api/v1/evaluate', {\n method: 'POST',\n body,\n });\n\n if (ctx.json) {\n printJson(response);\n } else {\n const passed = response.passed === true;\n process.stdout.write(`${passed ? color(ctx, 'green', 'PASS') : color(ctx, 'red', 'FAIL')}\\n`);\n if (Array.isArray(response.failures) && response.failures.length > 0) {\n process.stdout.write(\n `Failures:\\n${response.failures.map((f) => ` - ${String(f)}`).join('\\n')}\\n`\n );\n }\n if (response.summary && typeof response.summary === 'object') {\n printKeyValues(response.summary as Record<string, unknown>);\n }\n if (response.regression && typeof response.regression === 'object') {\n process.stdout.write('\\nRegression:\\n');\n printKeyValues(response.regression as Record<string, unknown>);\n }\n }\n\n if (response.passed === false) {\n process.exitCode = 1;\n }\n}\n\nfunction commandReserved(command: string): void {\n const messages: Record<string, string> = {\n clusters: 'The clusters CLI is reserved for the upcoming /api/v1/clusters endpoint.',\n fix: 'The Fixer CLI is reserved for the upcoming scriptable Fixer API.',\n replay: 'The replay CLI is reserved for the upcoming replay API.',\n };\n throw new CliError(messages[command] ?? `${command} is not available yet.`, 2);\n}\n\nfunction buildTimeQuery(flags: Record<string, FlagValue>): Record<string, string | number> {\n const query: Record<string, string | number> = {};\n const last = getStringFlag(flags, 'last', 'time-range') ?? '7d';\n const from = getStringFlag(flags, 'from');\n const to = getStringFlag(flags, 'to');\n\n if (from) {\n query.from = from;\n } else if (TIME_RANGES.has(last)) {\n query.timeRange = last;\n } else {\n throw new CliError(`--last must be one of: ${Array.from(TIME_RANGES).join(', ')}`);\n }\n\n if (to) query.to = to;\n return query;\n}\n\nfunction parseIntegerFlag(\n flags: Record<string, FlagValue>,\n name: string,\n fallback: number\n): number {\n const raw = getStringFlag(flags, name);\n if (raw === undefined) return fallback;\n const parsed = Number.parseInt(raw, 10);\n if (!Number.isFinite(parsed)) throw new CliError(`--${name} must be an integer`);\n return parsed;\n}\n\nfunction parseOptionalNumberFlag(\n flags: Record<string, FlagValue>,\n name: string\n): number | undefined {\n const raw = getStringFlag(flags, name);\n if (raw === undefined) return undefined;\n const parsed = Number.parseFloat(raw);\n if (!Number.isFinite(parsed)) throw new CliError(`--${name} must be a number`);\n return parsed;\n}\n\nexport function diagnoseSession(\n session: SessionSummary,\n events: EventSummary[]\n): DiagnoseFinding[] {\n const findings: DiagnoseFinding[] = [];\n const toolErrors = events.filter((event) => hasMeaningfulValue(event.toolError));\n const explicitErrors = events.filter((event) => event.eventType === 'error');\n const lowConfidence = events.filter(\n (event) => typeof event.confidence === 'number' && event.confidence < 0.5\n );\n\n if (session.success === false || session.status === 'failed') {\n findings.push({\n severity: 'high',\n title: 'Session ended unsuccessfully',\n detail: session.failureReason ?? 'The session is marked failed without a failure reason.',\n });\n }\n\n if (toolErrors.length > 0) {\n const grouped = groupBy(toolErrors, (event) => event.toolName ?? 'unknown_tool');\n const top = Array.from(grouped.entries())\n .map(([tool, group]) => `${tool} (${group.length})`)\n .join(', ');\n findings.push({\n severity: 'high',\n title: 'Tool errors occurred',\n detail: `${toolErrors.length} tool error event(s): ${top}. First error: ${formatCompactJson(\n toolErrors[0].toolError\n )}`,\n });\n }\n\n if (explicitErrors.length > 0) {\n findings.push({\n severity: 'high',\n title: 'Error events were recorded',\n detail: `${explicitErrors.length} error event(s). First event: ${summarizeEvent(\n explicitErrors[0]\n )}`,\n });\n }\n\n const repeatedCalls = findRepeatedToolCalls(events);\n if (repeatedCalls.length > 0) {\n findings.push({\n severity: 'medium',\n title: 'Repeated identical tool calls',\n detail: repeatedCalls\n .slice(0, 3)\n .map((call) => `${call.toolName} repeated ${call.count} times`)\n .join('; '),\n });\n }\n\n if (lowConfidence.length > 0) {\n findings.push({\n severity: 'medium',\n title: 'Low-confidence decisions',\n detail: `${lowConfidence.length} decision event(s) had confidence below 0.5.`,\n });\n }\n\n if (session.totalTokens && session.totalTokens > 100_000) {\n findings.push({\n severity: 'low',\n title: 'High token usage',\n detail: `This session used ${session.totalTokens.toLocaleString()} tokens.`,\n });\n }\n\n if (session.durationMs && session.durationMs > 120_000) {\n findings.push({\n severity: 'low',\n title: 'Long-running session',\n detail: `Duration was ${formatDuration(session.durationMs)}.`,\n });\n }\n\n if (session.status === 'completed' && !session.assistantOutput) {\n findings.push({\n severity: 'info',\n title: 'No assistant output stored',\n detail:\n 'The session completed, but assistantOutput is empty. Confirm finish({ output }) is wired.',\n });\n }\n\n return findings;\n}\n\nfunction findRepeatedToolCalls(events: EventSummary[]): Array<{ toolName: string; count: number }> {\n const counts = new Map<string, { toolName: string; count: number }>();\n for (const event of events) {\n if (event.eventType !== 'tool_call' || !event.toolName) continue;\n const key = `${event.toolName}:${formatCompactJson(event.toolInput)}`;\n const current = counts.get(key) ?? { toolName: event.toolName, count: 0 };\n current.count++;\n counts.set(key, current);\n }\n return Array.from(counts.values()).filter((entry) => entry.count >= 3);\n}\n\nfunction groupBy<T>(items: T[], keyFor: (item: T) => string): Map<string, T[]> {\n const result = new Map<string, T[]>();\n for (const item of items) {\n const key = keyFor(item);\n const existing = result.get(key) ?? [];\n existing.push(item);\n result.set(key, existing);\n }\n return result;\n}\n\nfunction hasMeaningfulValue(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') return Object.keys(value).length > 0;\n return true;\n}\n\nexport function detectProject(projectRoot: string): {\n language?: 'typescript' | 'python';\n framework?: string;\n} {\n const packageJsonPath = path.join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps.next) return { language: 'typescript', framework: 'Next.js' };\n if (deps.ai || deps['@ai-sdk/openai'])\n return { language: 'typescript', framework: 'Vercel AI SDK' };\n if (deps.langchain || deps['@langchain/core'])\n return { language: 'typescript', framework: 'LangChain' };\n if (deps.openai) return { language: 'typescript', framework: 'OpenAI Node' };\n return { language: 'typescript', framework: 'Node.js' };\n } catch {\n return { language: 'typescript', framework: 'Node.js' };\n }\n }\n\n const requirementsPath = path.join(projectRoot, 'requirements.txt');\n const pyprojectPath = path.join(projectRoot, 'pyproject.toml');\n if (existsSync(requirementsPath) || existsSync(pyprojectPath)) {\n const text = [requirementsPath, pyprojectPath]\n .filter((file) => existsSync(file))\n .map((file) => readFileSync(file, 'utf8').toLowerCase())\n .join('\\n');\n if (text.includes('fastapi')) return { language: 'python', framework: 'FastAPI' };\n if (text.includes('langchain')) return { language: 'python', framework: 'LangChain' };\n if (text.includes('crewai')) return { language: 'python', framework: 'CrewAI' };\n if (text.includes('openai')) return { language: 'python', framework: 'OpenAI Python' };\n return { language: 'python', framework: 'Python' };\n }\n\n return {};\n}\n\nexport function buildInstallPlan(\n projectRoot: string,\n languageOverride?: string,\n pythonCommand?: string,\n packageOverride?: string\n): InstallPlan {\n const detected = detectProject(projectRoot);\n const language = languageOverride ?? detected.language ?? 'typescript';\n\n if (language !== 'typescript' && language !== 'python') {\n throw new CliError('Supported install languages are \"typescript\" and \"python\".');\n }\n\n if (language === 'python') {\n const command = pythonCommand ?? (process.platform === 'win32' ? 'python' : 'python3');\n const packageName = packageOverride ?? 'sentrial';\n return {\n language,\n framework: detected.framework,\n command,\n args: ['-m', 'pip', 'install', packageName],\n packageName,\n };\n }\n\n const packageManager = detectPackageManager(projectRoot);\n const packageName = packageOverride ?? '@sentrial/sdk';\n return {\n language,\n framework: detected.framework,\n command: packageManager,\n args: packageManager === 'npm' ? ['install', packageName] : ['add', packageName],\n packageName,\n };\n}\n\nfunction detectPackageManager(projectRoot: string): 'pnpm' | 'npm' | 'yarn' {\n if (existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(path.join(projectRoot, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\nfunction plannedScaffoldFiles(projectRoot: string, language: InstallPlan['language']): string[] {\n const sampleFile = language === 'python' ? 'sentrial.example.py' : 'sentrial.example.ts';\n return [path.join(projectRoot, sampleFile), path.join(projectRoot, '.env.sentrial.example')];\n}\n\nfunction runSubprocess(command: string, args: string[], cwd: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n });\n\n child.on('error', (error) => {\n reject(new CliError(`Failed to run ${formatCommand(command, args)}: ${error.message}`));\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n reject(\n new CliError(`${formatCommand(command, args)} failed with exit code ${code ?? 'unknown'}`)\n );\n });\n });\n}\n\nfunction formatCommand(command: string, args: string[]): string {\n return [command, ...args].join(' ');\n}\n\nfunction typescriptExample(): string {\n return `import { configure, withSession } from '@sentrial/sdk';\n\nconfigure({\n apiKey: process.env.SENTRIAL_API_KEY,\n apiUrl: process.env.SENTRIAL_API_URL,\n});\n\nexport const runAgent = withSession('my-agent', async (userId: string, input: string) => {\n // Replace this with your real agent call. LLM/tool wrappers can be added around it.\n const output = \\`Echo: \\${input}\\`;\n return output;\n});\n\nawait runAgent('user_123', 'Hello from Sentrial');\n`;\n}\n\nfunction pythonExample(): string {\n return `from sentrial import SentrialClient\n\nclient = SentrialClient()\n\ninteraction = client.begin(\n user_id=\"user_123\",\n event=\"my-agent\",\n input=\"Hello from Sentrial\",\n)\n\ntry:\n # Replace this with your real agent call.\n output = \"Echo: Hello from Sentrial\"\n interaction.finish(output=output, success=True)\nexcept Exception as exc:\n interaction.finish(success=False, failure_reason=str(exc))\n raise\n`;\n}\n\nfunction printSession(session: SessionSummary, events: EventSummary[], ctx: CliContext): void {\n process.stdout.write(`${bold(ctx, 'Session')} ${session.id}\\n`);\n printKeyValues({\n name: session.name ?? '-',\n agent: session.agentName ?? session.agentSlug ?? '-',\n userId: session.userId ?? '-',\n status: `${session.status ?? '-'} (${formatResult(session.success)})`,\n score: formatNullableNumber(session.score),\n duration: formatDuration(session.durationMs),\n cost: formatCost(session.estimatedCost),\n tokens: session.totalTokens ?? '-',\n events: session.totalEvents ?? events.length,\n createdAt: formatDate(session.createdAt),\n completedAt: formatDate(session.completedAt),\n });\n\n if (session.failureReason) {\n process.stdout.write(`\\nFailure reason:\\n${indent(wrap(session.failureReason))}\\n`);\n }\n if (session.userInput) {\n process.stdout.write(`\\nInput:\\n${indent(wrap(session.userInput))}\\n`);\n }\n if (session.assistantOutput) {\n process.stdout.write(`\\nOutput:\\n${indent(wrap(session.assistantOutput))}\\n`);\n }\n\n if (events.length > 0) {\n process.stdout.write(`\\n${bold(ctx, 'Events')}\\n`);\n for (const event of events) {\n printEvent(event, ctx);\n }\n }\n}\n\nfunction printEvent(event: EventSummary, ctx: CliContext): void {\n const prefix = `#${event.sequenceNumber ?? '-'} ${event.eventType}`;\n const label =\n event.eventType === 'error' || hasMeaningfulValue(event.toolError)\n ? color(ctx, 'red', prefix)\n : color(ctx, 'cyan', prefix);\n process.stdout.write(`${label} ${formatDate(event.timestamp)}`);\n if (event.toolName) process.stdout.write(` tool=${event.toolName}`);\n if (event.estimatedCost) process.stdout.write(` cost=${formatCost(event.estimatedCost)}`);\n if (event.tokenCount) process.stdout.write(` tokens=${event.tokenCount}`);\n process.stdout.write('\\n');\n\n const summary = summarizeEvent(event);\n if (summary) process.stdout.write(`${indent(wrap(summary, 88))}\\n`);\n}\n\nfunction summarizeEvent(event: EventSummary): string {\n if (hasMeaningfulValue(event.toolError)) {\n return `Error: ${formatCompactJson(event.toolError)}`;\n }\n if (event.reasoning) {\n return event.reasoning;\n }\n if (hasMeaningfulValue(event.toolOutput)) {\n return `Output: ${formatCompactJson(event.toolOutput)}`;\n }\n if (hasMeaningfulValue(event.toolInput)) {\n return `Input: ${formatCompactJson(event.toolInput)}`;\n }\n return '';\n}\n\nfunction printKeyValues(values: Record<string, unknown>): void {\n const entries = Object.entries(values);\n const width = entries.reduce((max, [key]) => Math.max(max, key.length), 0);\n for (const [key, value] of entries) {\n process.stdout.write(`${key.padEnd(width)} ${String(value)}\\n`);\n }\n}\n\nfunction printJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\ninterface TableColumn<T> {\n header: string;\n maxWidth: number;\n render: (row: T) => string;\n}\n\nfunction printTable<T>(rows: T[], columns: Array<TableColumn<T>>): void {\n const widths = columns.map((column) => {\n const max = Math.max(column.header.length, ...rows.map((row) => column.render(row).length));\n return Math.min(max, column.maxWidth);\n });\n\n const header = columns\n .map((column, index) => pad(truncate(column.header, widths[index]), widths[index]))\n .join(' ');\n const divider = widths.map((width) => '-'.repeat(width)).join(' ');\n process.stdout.write(`${header}\\n${divider}\\n`);\n\n for (const row of rows) {\n const line = columns\n .map((column, index) => pad(truncate(column.render(row), widths[index]), widths[index]))\n .join(' ');\n process.stdout.write(`${line}\\n`);\n }\n}\n\nfunction truncate(value: string, width: number): string {\n if (value.length <= width) return value;\n if (width <= 1) return value.slice(0, width);\n return `${value.slice(0, width - 1)}...`.slice(0, width);\n}\n\nfunction pad(value: string, width: number): string {\n return `${value}${' '.repeat(Math.max(0, width - value.length))}`;\n}\n\nfunction color(ctx: CliContext, name: 'cyan' | 'green' | 'red' | 'yellow', value: string): string {\n if (!ctx.color) return value;\n const codes = {\n cyan: 36,\n green: 32,\n red: 31,\n yellow: 33,\n };\n return `\\u001b[${codes[name]}m${value}\\u001b[0m`;\n}\n\nfunction bold(ctx: CliContext, value: string): string {\n return ctx.color ? `\\u001b[1m${value}\\u001b[0m` : value;\n}\n\nfunction severityLabel(ctx: CliContext, severity: DiagnoseFinding['severity']): string {\n if (severity === 'high') return color(ctx, 'red', '[high]');\n if (severity === 'medium') return color(ctx, 'yellow', '[medium]');\n if (severity === 'low') return color(ctx, 'cyan', '[low]');\n return '[info]';\n}\n\nfunction formatResult(success: boolean | null | undefined): string {\n if (success === true) return 'pass';\n if (success === false) return 'fail';\n return '-';\n}\n\nfunction formatNullableNumber(value: number | null | undefined): string {\n return typeof value === 'number' ? String(Math.round(value * 10) / 10) : '-';\n}\n\nfunction formatDuration(ms: number | null | undefined): string {\n if (typeof ms !== 'number') return '-';\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60_000).toFixed(1)}m`;\n}\n\nfunction formatCost(cost: number | null | undefined): string {\n return typeof cost === 'number' ? `$${cost.toFixed(4)}` : '-';\n}\n\nfunction formatDate(value: string | null | undefined): string {\n if (!value) return '-';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 16);\n}\n\nfunction formatCompactJson(value: unknown): string {\n if (value === undefined) return '';\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction wrap(text: string, width = 92): string {\n const words = text.replace(/\\s+/g, ' ').trim().split(' ');\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n if (`${current} ${word}`.trim().length > width && current) {\n lines.push(current);\n current = word;\n } else {\n current = `${current} ${word}`.trim();\n }\n }\n if (current) lines.push(current);\n return lines.join('\\n');\n}\n\nfunction indent(text: string, spaces = 2): string {\n const prefix = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n');\n}\n\nexport async function run(argv: string[]): Promise<void> {\n const parsed = parseArgs(argv);\n const ctx = createContext(parsed.flags);\n const [command, ...rest] = parsed.positionals;\n\n if (getBooleanFlag(parsed.flags, 'version')) {\n process.stdout.write(`${CLI_VERSION}\\n`);\n return;\n }\n\n if (!command || getBooleanFlag(parsed.flags, 'help')) {\n process.stdout.write(HELP);\n return;\n }\n\n switch (command) {\n case 'install':\n await commandInstall(ctx, parsed.flags);\n break;\n case 'init':\n await commandInit(ctx, parsed.flags);\n break;\n case 'login':\n await commandLogin(ctx, parsed.flags);\n break;\n case 'sessions':\n await commandSessions(ctx, parsed.flags, rest);\n break;\n case 'events':\n await commandEvents(ctx, parsed.flags, rest);\n break;\n case 'signals':\n await commandSignals(ctx, parsed.flags, rest);\n break;\n case 'diagnose':\n await commandDiagnose(ctx, parsed.flags, rest[0]);\n break;\n case 'evaluate':\n await commandEvaluate(ctx, parsed.flags, rest[0]);\n break;\n case 'clusters':\n case 'fix':\n case 'replay':\n commandReserved(command);\n break;\n default:\n throw new CliError(`Unknown command: ${command}. Run sentrial --help.`);\n }\n}\n\nif (process.env.SENTRIAL_CLI_SKIP_AUTO_RUN !== '1') {\n run(process.argv.slice(2)).catch((error: unknown) => {\n if (error instanceof CliError) {\n if (process.env.SENTRIAL_CLI_DEBUG) {\n process.stderr.write(`${error.stack ?? error.message}\\n`);\n } else {\n process.stderr.write(`Error: ${error.message}\\n`);\n }\n process.exitCode = error.exitCode;\n return;\n }\n\n process.stderr.write(\n `${error instanceof Error ? (error.stack ?? error.message) : String(error)}\\n`\n );\n process.exitCode = 1;\n });\n}\n"],"mappings":"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","names":["path","os","process","readline","packageName"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/constants.ts","../package.json"],"sourcesContent":["#!/usr/bin/env node\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { spawn } from 'node:child_process';\nimport os from 'node:os';\nimport path from 'node:path';\nimport process from 'node:process';\nimport readline from 'node:readline/promises';\n\nimport { DEFAULT_API_URL } from './constants.js';\n// Named JSON import (no `with { type: 'json' }` attribute — that routes esbuild through the\n// spec-ESM path which exposes only a default export) so tsup/esbuild tree-shakes the manifest down\n// to just `version` rather than inlining the entire package.json (scripts, devDependencies, …).\nimport { version as CLI_VERSION } from '../package.json';\nconst CONFIG_DIR = path.join(os.homedir(), '.sentrial');\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');\nconst TIME_RANGES = new Set(['24h', '3d', '7d', '30d']);\n\ntype FlagValue = string | boolean | undefined;\n\ninterface ParsedArgs {\n flags: Record<string, FlagValue>;\n positionals: string[];\n}\n\ninterface StoredConfig {\n apiKey?: string;\n apiUrl?: string;\n}\n\ninterface CliContext {\n apiKey?: string;\n apiUrl: string;\n json: boolean;\n color: boolean;\n}\n\ninterface ApiEnvelope<T> {\n data: T;\n meta?: Record<string, unknown>;\n}\n\n// The CLI parses raw V1 API responses; reuse the canonical wire-response types\n// from ./types instead of re-declaring them here so they can't drift (#489).\nimport type { SessionResponse as SessionSummary, EventResponse as EventSummary } from './types.js';\n\ninterface SignalSummary {\n id: string;\n name: string;\n type: string;\n source?: string | null;\n count: number;\n affectedSessions: number;\n affectedUsers: number;\n description?: string | null;\n createdAt?: string | null;\n}\n\ninterface DiagnoseFinding {\n severity: 'high' | 'medium' | 'low' | 'info';\n title: string;\n detail: string;\n}\n\ninterface InstallPlan {\n language: 'typescript' | 'python';\n framework?: string;\n command: string;\n args: string[];\n packageName: string;\n}\n\nexport class CliError extends Error {\n readonly exitCode: number;\n\n constructor(message: string, exitCode = 1) {\n super(message);\n this.name = 'CliError';\n this.exitCode = exitCode;\n }\n}\n\nconst SHORT_FLAGS: Record<string, string> = {\n a: 'agent',\n f: 'force',\n h: 'help',\n j: 'json',\n l: 'last',\n s: 'status',\n t: 'type',\n v: 'version',\n y: 'yes',\n};\n\nconst BOOLEAN_FLAGS = new Set([\n 'force',\n 'help',\n 'include-api-key',\n 'json',\n 'dry-run',\n 'version',\n 'yes',\n]);\n\nconst HELP = `Sentrial CLI\n\nUsage:\n sentrial <command> [options]\n\nCommands:\n install Install the SDK package and scaffold integration files\n init Scaffold a safe example integration in this repo\n login Save an API key for future CLI calls\n sessions list List recent sessions\n sessions get <id> Show a session and its events\n events list <session-id> List events for a session\n signals list List detected signals\n diagnose <session-id> Print a terminal diagnosis from session events\n evaluate <experiment-id> Run the /api/v1/evaluate CI gate (API key needs the metrics:read scope)\n fix <session-id> Reserved for the upcoming Fixer API\n replay <session-id> Reserved for the upcoming replay API\n\nGlobal options:\n --api-key <key> API key, otherwise SENTRIAL_API_KEY or ~/.sentrial/config.json\n --api-url <url> API URL, otherwise SENTRIAL_API_URL or ${DEFAULT_API_URL}\n --json Emit machine-readable JSON\n --no-color Disable ANSI color\n -h, --help Show help\n -v, --version Show version\n\nExamples:\n sentrial login --api-key sentrial_live_xxx\n sentrial install\n sentrial init\n sentrial sessions list --last 7d --status failed --agent support\n sentrial sessions get 00000000-0000-0000-0000-000000000000\n sentrial events list 00000000-0000-0000-0000-000000000000 --type tool_call\n sentrial signals list --type negative --last 30d\n sentrial diagnose 00000000-0000-0000-0000-000000000000\n sentrial evaluate 00000000-0000-0000-0000-000000000000 --min-score 80\n`;\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const flags: Record<string, FlagValue> = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i++) {\n const token = argv[i];\n if (token === '--') {\n positionals.push(...argv.slice(i + 1));\n break;\n }\n\n if (token.startsWith('--no-')) {\n flags[token.slice(5)] = false;\n continue;\n }\n\n if (token.startsWith('--')) {\n const [rawName, inlineValue] = token.slice(2).split('=', 2);\n if (inlineValue !== undefined) {\n flags[rawName] = inlineValue;\n } else if (BOOLEAN_FLAGS.has(rawName)) {\n flags[rawName] = true;\n } else {\n const next = argv[i + 1];\n if (next && !next.startsWith('-')) {\n flags[rawName] = next;\n i++;\n } else {\n flags[rawName] = true;\n }\n }\n continue;\n }\n\n if (token.startsWith('-') && token.length === 2) {\n const mapped = SHORT_FLAGS[token.slice(1)];\n if (!mapped) {\n throw new CliError(`Unknown flag: ${token}`);\n }\n if (BOOLEAN_FLAGS.has(mapped)) {\n flags[mapped] = true;\n } else {\n const next = argv[i + 1];\n if (!next || next.startsWith('-')) {\n throw new CliError(`Flag ${token} requires a value`);\n }\n flags[mapped] = next;\n i++;\n }\n continue;\n }\n\n positionals.push(token);\n }\n\n return { flags, positionals };\n}\n\nfunction getFlag(flags: Record<string, FlagValue>, ...names: string[]): FlagValue {\n for (const name of names) {\n if (flags[name] !== undefined) return flags[name];\n }\n return undefined;\n}\n\nfunction getStringFlag(flags: Record<string, FlagValue>, ...names: string[]): string | undefined {\n const value = getFlag(flags, ...names);\n if (typeof value === 'string') return value;\n return undefined;\n}\n\nfunction getBooleanFlag(flags: Record<string, FlagValue>, name: string): boolean {\n return flags[name] === true;\n}\n\nfunction readConfig(): StoredConfig {\n if (!existsSync(CONFIG_FILE)) return {};\n\n try {\n const parsed = JSON.parse(readFileSync(CONFIG_FILE, 'utf8')) as StoredConfig;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n}\n\nfunction writeConfig(config: StoredConfig): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n writeFileSync(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n try {\n chmodSync(CONFIG_FILE, 0o600);\n } catch {\n // Best effort only; some filesystems do not support chmod.\n }\n}\n\nfunction createContext(flags: Record<string, FlagValue>): CliContext {\n const config = readConfig();\n const apiKey = getStringFlag(flags, 'api-key') ?? process.env.SENTRIAL_API_KEY ?? config.apiKey;\n const apiUrl = (\n getStringFlag(flags, 'api-url') ??\n process.env.SENTRIAL_API_URL ??\n config.apiUrl ??\n DEFAULT_API_URL\n ).replace(/\\/$/, '');\n\n return {\n apiKey,\n apiUrl,\n json: getBooleanFlag(flags, 'json'),\n color: flags.color !== false && process.stdout.isTTY && !process.env.NO_COLOR,\n };\n}\n\nfunction requireApiKey(ctx: CliContext): string {\n if (!ctx.apiKey) {\n throw new CliError(\n 'Missing API key. Run `sentrial login --api-key sentrial_live_xxx` or set SENTRIAL_API_KEY.'\n );\n }\n return ctx.apiKey;\n}\n\nasync function apiRequest<T>(\n ctx: CliContext,\n apiPath: string,\n options: {\n method?: 'GET' | 'POST';\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n } = {}\n): Promise<T> {\n const apiKey = requireApiKey(ctx);\n const url = new URL(apiPath, `${ctx.apiUrl}/`);\n\n for (const [key, value] of Object.entries(options.query ?? {})) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${apiKey}`,\n Accept: 'application/json',\n };\n\n if (options.body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: options.method ?? 'GET',\n headers,\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n } catch (error) {\n throw new CliError(\n `Could not reach ${ctx.apiUrl}. ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n const text = await response.text();\n const parsed = parseResponseBody(text);\n\n if (!response.ok) {\n throw new CliError(\n `${options.method ?? 'GET'} ${url.pathname} failed (${response.status}): ${formatApiError(\n parsed\n )}`,\n response.status === 404 ? 4 : 1\n );\n }\n\n return parsed as T;\n}\n\nfunction parseResponseBody(text: string): unknown {\n if (!text.trim()) return {};\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction formatApiError(value: unknown): string {\n if (value && typeof value === 'object') {\n const record = value as Record<string, unknown>;\n if (typeof record.error === 'string') return record.error;\n if (record.error && typeof record.error === 'object') {\n const error = record.error as Record<string, unknown>;\n if (typeof error.message === 'string') return error.message;\n }\n }\n return typeof value === 'string' ? value : 'Unexpected API response';\n}\n\nasync function commandLogin(ctx: CliContext, flags: Record<string, FlagValue>): Promise<void> {\n let apiKey = getStringFlag(flags, 'api-key') ?? process.env.SENTRIAL_API_KEY;\n const apiUrl = getStringFlag(flags, 'api-url') ?? process.env.SENTRIAL_API_URL ?? ctx.apiUrl;\n\n if (!apiKey) {\n if (!process.stdin.isTTY) {\n throw new CliError('Pass --api-key or set SENTRIAL_API_KEY when stdin is not interactive.');\n }\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n apiKey = (await rl.question('Sentrial API key: ')).trim();\n rl.close();\n }\n\n if (!apiKey.startsWith('sentrial_')) {\n throw new CliError('API keys should look like sentrial_live_xxx or sentrial_test_xxx.');\n }\n\n writeConfig({ apiKey, apiUrl });\n\n if (ctx.json) {\n printJson({ ok: true, configPath: CONFIG_FILE, apiUrl });\n return;\n }\n\n process.stdout.write(`Saved credentials to ${CONFIG_FILE}\\n`);\n}\n\nasync function commandInstall(ctx: CliContext, flags: Record<string, FlagValue>): Promise<void> {\n const projectRoot = process.cwd();\n const requestedLanguage = getStringFlag(flags, 'language');\n const pythonCommand = getStringFlag(flags, 'python');\n const packageOverride = getStringFlag(flags, 'sdk-package') ?? process.env.SENTRIAL_SDK_PACKAGE;\n const plan = buildInstallPlan(projectRoot, requestedLanguage, pythonCommand, packageOverride);\n const dryRun = getBooleanFlag(flags, 'dry-run');\n\n if (ctx.json) {\n if (!dryRun) {\n throw new CliError('Use --dry-run with --json; real installs stream package-manager output.');\n }\n printJson({ dryRun: true, plan, wouldWrite: plannedScaffoldFiles(projectRoot, plan.language) });\n return;\n }\n\n process.stdout.write(`Detected: ${plan.framework ?? plan.language}\\n`);\n process.stdout.write(`Install: ${formatCommand(plan.command, plan.args)}\\n`);\n\n if (dryRun) {\n process.stdout.write('Dry run only. No files were changed.\\n');\n return;\n }\n\n await runSubprocess(plan.command, plan.args, projectRoot);\n await commandInit(ctx, flags);\n}\n\nasync function commandInit(ctx: CliContext, flags: Record<string, FlagValue>): Promise<void> {\n const projectRoot = process.cwd();\n const detected = detectProject(projectRoot);\n const requestedLanguage = getStringFlag(flags, 'language');\n const language = requestedLanguage ?? detected.language ?? 'typescript';\n const force = getBooleanFlag(flags, 'force');\n const includeApiKey = getBooleanFlag(flags, 'include-api-key');\n\n if (language !== 'typescript' && language !== 'python') {\n throw new CliError('Supported init languages are \"typescript\" and \"python\".');\n }\n\n const files =\n language === 'python'\n ? [\n {\n path: path.join(projectRoot, 'sentrial.example.py'),\n content: pythonExample(),\n },\n ]\n : [\n {\n path: path.join(projectRoot, 'sentrial.example.ts'),\n content: typescriptExample(),\n },\n ];\n\n // .env.sentrial.example is conventionally committed to git, so it must NEVER contain a\n // real key — always the placeholder (#497).\n files.push({\n path: path.join(projectRoot, '.env.sentrial.example'),\n content: `SENTRIAL_API_KEY=sentrial_live_xxx\\nSENTRIAL_API_URL=${ctx.apiUrl}\\n`,\n });\n\n // --include-api-key bakes the caller's real key into the GITIGNORED .env.sentrial (a real\n // env file), not the committable .example — so the live key never lands in version control.\n if (includeApiKey && ctx.apiKey) {\n files.push({\n path: path.join(projectRoot, '.env.sentrial'),\n content: `SENTRIAL_API_KEY=${ctx.apiKey}\\nSENTRIAL_API_URL=${ctx.apiUrl}\\n`,\n });\n }\n\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const file of files) {\n if (existsSync(file.path) && !force) {\n skipped.push(file.path);\n continue;\n }\n writeFileSync(file.path, file.content);\n written.push(file.path);\n }\n\n const installCommand =\n language === 'python'\n ? 'pip install sentrial'\n : `${detectPackageManager(projectRoot)} add @sentrial/sdk`;\n\n if (ctx.json) {\n printJson({\n detected,\n language,\n installCommand,\n written,\n skipped,\n });\n return;\n }\n\n process.stdout.write(`Detected: ${detected.framework ?? language}\\n`);\n process.stdout.write(`Install: ${installCommand}\\n`);\n if (written.length > 0) {\n process.stdout.write(\n `Written:\\n${written.map((file) => ` ${path.relative(projectRoot, file)}`).join('\\n')}\\n`\n );\n }\n if (skipped.length > 0) {\n process.stdout.write(\n `Skipped existing files:\\n${skipped.map((file) => ` ${path.relative(projectRoot, file)}`).join('\\n')}\\n`\n );\n }\n}\n\nasync function commandSessions(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n rest: string[]\n): Promise<void> {\n const subcommand = rest[0];\n if (subcommand === 'list') {\n await commandSessionsList(ctx, flags);\n return;\n }\n if (subcommand === 'get') {\n const sessionId = rest[1];\n if (!sessionId) throw new CliError('Usage: sentrial sessions get <id>');\n await commandSessionsGet(ctx, flags, sessionId);\n return;\n }\n throw new CliError('Usage: sentrial sessions <list|get>');\n}\n\nasync function commandSessionsList(\n ctx: CliContext,\n flags: Record<string, FlagValue>\n): Promise<void> {\n const query = buildTimeQuery(flags);\n const agentFilter = getStringFlag(flags, 'agent')?.toLowerCase();\n const hasExplicitLimit = getStringFlag(flags, 'limit') !== undefined;\n query.status = getStringFlag(flags, 'status') ?? 'all';\n query.limit = parseIntegerFlag(flags, 'limit', agentFilter && !hasExplicitLimit ? 500 : 50);\n query.offset = parseIntegerFlag(flags, 'offset', 0);\n\n const response = await apiRequest<ApiEnvelope<SessionSummary[]>>(ctx, '/api/v1/sessions', {\n query,\n });\n\n const sessions = agentFilter\n ? response.data.filter((session) =>\n `${session.agentName ?? ''} ${session.agentSlug ?? ''}`.toLowerCase().includes(agentFilter)\n )\n : response.data;\n\n if (ctx.json) {\n printJson({ data: sessions, meta: response.meta });\n return;\n }\n\n if (sessions.length === 0) {\n process.stdout.write('No sessions found.\\n');\n return;\n }\n\n printTable(sessions, [\n { header: 'ID', render: (s) => s.id, maxWidth: 36 },\n { header: 'Agent', render: (s) => s.agentName ?? s.agentSlug ?? '-', maxWidth: 18 },\n { header: 'Status', render: (s) => s.status ?? '-', maxWidth: 10 },\n { header: 'Result', render: (s) => formatResult(s.success), maxWidth: 8 },\n { header: 'Score', render: (s) => formatNullableNumber(s.score), maxWidth: 6 },\n { header: 'Dur', render: (s) => formatDuration(s.durationMs), maxWidth: 8 },\n { header: 'Cost', render: (s) => formatCost(s.estimatedCost), maxWidth: 10 },\n { header: 'Created', render: (s) => formatDate(s.createdAt), maxWidth: 16 },\n { header: 'Name', render: (s) => s.name ?? '-', maxWidth: 28 },\n ]);\n\n if (agentFilter) {\n process.stdout.write(`\\nFiltered locally by agent: ${agentFilter}\\n`);\n }\n}\n\nasync function commandSessionsGet(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n sessionId: string\n): Promise<void> {\n const sessionResponse = await apiRequest<ApiEnvelope<SessionSummary>>(\n ctx,\n `/api/v1/sessions/${sessionId}`\n );\n const includeEvents = flags.events !== false;\n const events = includeEvents ? await fetchSessionEvents(ctx, flags, sessionId) : [];\n\n if (ctx.json) {\n printJson({ data: sessionResponse.data, events });\n return;\n }\n\n printSession(sessionResponse.data, events, ctx);\n}\n\nasync function fetchSessionEvents(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n sessionId: string\n): Promise<EventSummary[]> {\n const eventType = getStringFlag(flags, 'event-type') ?? 'all';\n const response = await apiRequest<ApiEnvelope<EventSummary[]>>(\n ctx,\n `/api/v1/sessions/${sessionId}/events`,\n {\n query: {\n limit: parseIntegerFlag(flags, 'events-limit', 100),\n offset: parseIntegerFlag(flags, 'events-offset', 0),\n eventType,\n },\n }\n );\n return response.data;\n}\n\nasync function commandEvents(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n rest: string[]\n): Promise<void> {\n const subcommand = rest[0] ?? 'list';\n if (subcommand !== 'list') {\n throw new CliError('Usage: sentrial events list <session-id>');\n }\n\n const sessionId = rest[1] ?? getStringFlag(flags, 'session', 'session-id');\n if (!sessionId) {\n throw new CliError('Usage: sentrial events list <session-id>');\n }\n\n const eventType = getStringFlag(flags, 'type', 'event-type') ?? 'all';\n const response = await apiRequest<ApiEnvelope<EventSummary[]>>(\n ctx,\n `/api/v1/sessions/${sessionId}/events`,\n {\n query: {\n limit: parseIntegerFlag(flags, 'limit', 100),\n offset: parseIntegerFlag(flags, 'offset', 0),\n eventType,\n },\n }\n );\n\n if (ctx.json) {\n printJson(response);\n return;\n }\n\n if (response.data.length === 0) {\n process.stdout.write('No events found.\\n');\n return;\n }\n\n process.stdout.write(`${bold(ctx, 'Events')} ${sessionId}\\n`);\n for (const event of response.data) {\n printEvent(event, ctx);\n }\n}\n\nasync function commandSignals(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n rest: string[]\n): Promise<void> {\n const subcommand = rest[0] ?? 'list';\n if (subcommand !== 'list') {\n throw new CliError('Usage: sentrial signals list');\n }\n\n const query = buildTimeQuery(flags);\n query.type = getStringFlag(flags, 'type') ?? 'all';\n query.source = getStringFlag(flags, 'source') ?? 'all';\n\n const response = await apiRequest<ApiEnvelope<SignalSummary[]>>(ctx, '/api/v1/signals', {\n query,\n });\n\n if (ctx.json) {\n printJson(response);\n return;\n }\n\n if (response.data.length === 0) {\n process.stdout.write('No signals found.\\n');\n return;\n }\n\n printTable(response.data, [\n { header: 'Name', render: (s) => s.name, maxWidth: 28 },\n { header: 'Type', render: (s) => s.type, maxWidth: 10 },\n { header: 'Source', render: (s) => s.source ?? '-', maxWidth: 12 },\n { header: 'Count', render: (s) => String(s.count), maxWidth: 8 },\n { header: 'Sessions', render: (s) => String(s.affectedSessions), maxWidth: 10 },\n { header: 'Users', render: (s) => String(s.affectedUsers), maxWidth: 8 },\n { header: 'Created', render: (s) => formatDate(s.createdAt), maxWidth: 16 },\n { header: 'Description', render: (s) => s.description ?? '-', maxWidth: 36 },\n ]);\n}\n\nasync function commandDiagnose(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n sessionId: string | undefined\n): Promise<void> {\n if (!sessionId) throw new CliError('Usage: sentrial diagnose <session-id>');\n\n const sessionResponse = await apiRequest<ApiEnvelope<SessionSummary>>(\n ctx,\n `/api/v1/sessions/${sessionId}`\n );\n const events = await fetchSessionEvents(ctx, flags, sessionId);\n const findings = diagnoseSession(sessionResponse.data, events);\n\n if (ctx.json) {\n printJson({ session: sessionResponse.data, findings });\n return;\n }\n\n process.stdout.write(`${bold(ctx, 'Diagnosis')}\\n`);\n process.stdout.write(`Session: ${sessionResponse.data.id}\\n`);\n process.stdout.write(\n `Agent: ${sessionResponse.data.agentName ?? sessionResponse.data.agentSlug ?? '-'}\\n`\n );\n process.stdout.write(\n `Status: ${sessionResponse.data.status ?? '-'} (${formatResult(sessionResponse.data.success)})\\n`\n );\n if (sessionResponse.data.failureReason) {\n process.stdout.write(`Failure: ${sessionResponse.data.failureReason}\\n`);\n }\n process.stdout.write('\\n');\n\n if (findings.length === 0) {\n process.stdout.write('No obvious terminal-level issues found in the session events.\\n');\n return;\n }\n\n for (const finding of findings) {\n process.stdout.write(`${severityLabel(ctx, finding.severity)} ${finding.title}\\n`);\n process.stdout.write(` ${finding.detail}\\n`);\n }\n}\n\nasync function commandEvaluate(\n ctx: CliContext,\n flags: Record<string, FlagValue>,\n experimentId: string | undefined\n): Promise<void> {\n const resolvedExperimentId = experimentId ?? getStringFlag(flags, 'experiment', 'experiment-id');\n if (!resolvedExperimentId) {\n throw new CliError('Usage: sentrial evaluate <experiment-id> [--min-score 80]');\n }\n\n const body = {\n experimentId: resolvedExperimentId,\n baselineExperimentId: getStringFlag(flags, 'baseline', 'baseline-experiment-id'),\n thresholds: {\n minScore: parseOptionalNumberFlag(flags, 'min-score'),\n failOnRegression: flags['fail-on-regression'] === false ? false : undefined,\n maxRegressionPercent: parseOptionalNumberFlag(flags, 'max-regression-percent'),\n },\n };\n\n const response = await apiRequest<Record<string, unknown>>(ctx, '/api/v1/evaluate', {\n method: 'POST',\n body,\n });\n\n if (ctx.json) {\n printJson(response);\n } else {\n const passed = response.passed === true;\n process.stdout.write(`${passed ? color(ctx, 'green', 'PASS') : color(ctx, 'red', 'FAIL')}\\n`);\n if (Array.isArray(response.failures) && response.failures.length > 0) {\n process.stdout.write(\n `Failures:\\n${response.failures.map((f) => ` - ${String(f)}`).join('\\n')}\\n`\n );\n }\n if (response.summary && typeof response.summary === 'object') {\n printKeyValues(response.summary as Record<string, unknown>);\n }\n if (response.regression && typeof response.regression === 'object') {\n process.stdout.write('\\nRegression:\\n');\n printKeyValues(response.regression as Record<string, unknown>);\n }\n }\n\n if (response.passed === false) {\n process.exitCode = 1;\n }\n}\n\nfunction commandReserved(command: string): void {\n const messages: Record<string, string> = {\n fix: 'The Fixer CLI is reserved for the upcoming scriptable Fixer API.',\n replay: 'The replay CLI is reserved for the upcoming replay API.',\n };\n throw new CliError(messages[command] ?? `${command} is not available yet.`, 2);\n}\n\nfunction buildTimeQuery(flags: Record<string, FlagValue>): Record<string, string | number> {\n const query: Record<string, string | number> = {};\n const last = getStringFlag(flags, 'last', 'time-range') ?? '7d';\n const from = getStringFlag(flags, 'from');\n const to = getStringFlag(flags, 'to');\n\n if (from) {\n query.from = from;\n } else if (TIME_RANGES.has(last)) {\n query.timeRange = last;\n } else {\n throw new CliError(`--last must be one of: ${Array.from(TIME_RANGES).join(', ')}`);\n }\n\n if (to) query.to = to;\n return query;\n}\n\nfunction parseIntegerFlag(\n flags: Record<string, FlagValue>,\n name: string,\n fallback: number\n): number {\n const raw = getStringFlag(flags, name);\n if (raw === undefined) return fallback;\n const parsed = Number.parseInt(raw, 10);\n if (!Number.isFinite(parsed)) throw new CliError(`--${name} must be an integer`);\n return parsed;\n}\n\nfunction parseOptionalNumberFlag(\n flags: Record<string, FlagValue>,\n name: string\n): number | undefined {\n const raw = getStringFlag(flags, name);\n if (raw === undefined) return undefined;\n const parsed = Number.parseFloat(raw);\n if (!Number.isFinite(parsed)) throw new CliError(`--${name} must be a number`);\n return parsed;\n}\n\nexport function diagnoseSession(\n session: SessionSummary,\n events: EventSummary[]\n): DiagnoseFinding[] {\n const findings: DiagnoseFinding[] = [];\n const toolErrors = events.filter((event) => hasMeaningfulValue(event.toolError));\n const explicitErrors = events.filter((event) => event.eventType === 'error');\n const lowConfidence = events.filter(\n (event) => typeof event.confidence === 'number' && event.confidence < 0.5\n );\n\n if (session.success === false || session.status === 'failed') {\n findings.push({\n severity: 'high',\n title: 'Session ended unsuccessfully',\n detail: session.failureReason ?? 'The session is marked failed without a failure reason.',\n });\n }\n\n if (toolErrors.length > 0) {\n const grouped = groupBy(toolErrors, (event) => event.toolName ?? 'unknown_tool');\n const top = Array.from(grouped.entries())\n .map(([tool, group]) => `${tool} (${group.length})`)\n .join(', ');\n findings.push({\n severity: 'high',\n title: 'Tool errors occurred',\n detail: `${toolErrors.length} tool error event(s): ${top}. First error: ${formatCompactJson(\n toolErrors[0].toolError\n )}`,\n });\n }\n\n if (explicitErrors.length > 0) {\n findings.push({\n severity: 'high',\n title: 'Error events were recorded',\n detail: `${explicitErrors.length} error event(s). First event: ${summarizeEvent(\n explicitErrors[0]\n )}`,\n });\n }\n\n const repeatedCalls = findRepeatedToolCalls(events);\n if (repeatedCalls.length > 0) {\n findings.push({\n severity: 'medium',\n title: 'Repeated identical tool calls',\n detail: repeatedCalls\n .slice(0, 3)\n .map((call) => `${call.toolName} repeated ${call.count} times`)\n .join('; '),\n });\n }\n\n if (lowConfidence.length > 0) {\n findings.push({\n severity: 'medium',\n title: 'Low-confidence decisions',\n detail: `${lowConfidence.length} decision event(s) had confidence below 0.5.`,\n });\n }\n\n if (session.totalTokens && session.totalTokens > 100_000) {\n findings.push({\n severity: 'low',\n title: 'High token usage',\n detail: `This session used ${session.totalTokens.toLocaleString()} tokens.`,\n });\n }\n\n if (session.durationMs && session.durationMs > 120_000) {\n findings.push({\n severity: 'low',\n title: 'Long-running session',\n detail: `Duration was ${formatDuration(session.durationMs)}.`,\n });\n }\n\n if (session.status === 'completed' && !session.assistantOutput) {\n findings.push({\n severity: 'info',\n title: 'No assistant output stored',\n detail:\n 'The session completed, but assistantOutput is empty. Confirm finish({ output }) is wired.',\n });\n }\n\n return findings;\n}\n\nfunction findRepeatedToolCalls(events: EventSummary[]): Array<{ toolName: string; count: number }> {\n const counts = new Map<string, { toolName: string; count: number }>();\n for (const event of events) {\n if (event.eventType !== 'tool_call' || !event.toolName) continue;\n const key = `${event.toolName}:${formatCompactJson(event.toolInput)}`;\n const current = counts.get(key) ?? { toolName: event.toolName, count: 0 };\n current.count++;\n counts.set(key, current);\n }\n return Array.from(counts.values()).filter((entry) => entry.count >= 3);\n}\n\nfunction groupBy<T>(items: T[], keyFor: (item: T) => string): Map<string, T[]> {\n const result = new Map<string, T[]>();\n for (const item of items) {\n const key = keyFor(item);\n const existing = result.get(key) ?? [];\n existing.push(item);\n result.set(key, existing);\n }\n return result;\n}\n\nfunction hasMeaningfulValue(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') return value.trim().length > 0;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object') return Object.keys(value).length > 0;\n return true;\n}\n\nexport function detectProject(projectRoot: string): {\n language?: 'typescript' | 'python';\n framework?: string;\n} {\n const packageJsonPath = path.join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps.next) return { language: 'typescript', framework: 'Next.js' };\n if (deps.ai || deps['@ai-sdk/openai'])\n return { language: 'typescript', framework: 'Vercel AI SDK' };\n if (deps.langchain || deps['@langchain/core'])\n return { language: 'typescript', framework: 'LangChain' };\n if (deps.openai) return { language: 'typescript', framework: 'OpenAI Node' };\n return { language: 'typescript', framework: 'Node.js' };\n } catch {\n return { language: 'typescript', framework: 'Node.js' };\n }\n }\n\n const requirementsPath = path.join(projectRoot, 'requirements.txt');\n const pyprojectPath = path.join(projectRoot, 'pyproject.toml');\n if (existsSync(requirementsPath) || existsSync(pyprojectPath)) {\n const text = [requirementsPath, pyprojectPath]\n .filter((file) => existsSync(file))\n .map((file) => readFileSync(file, 'utf8').toLowerCase())\n .join('\\n');\n if (text.includes('fastapi')) return { language: 'python', framework: 'FastAPI' };\n if (text.includes('langchain')) return { language: 'python', framework: 'LangChain' };\n if (text.includes('crewai')) return { language: 'python', framework: 'CrewAI' };\n if (text.includes('openai')) return { language: 'python', framework: 'OpenAI Python' };\n return { language: 'python', framework: 'Python' };\n }\n\n return {};\n}\n\nexport function buildInstallPlan(\n projectRoot: string,\n languageOverride?: string,\n pythonCommand?: string,\n packageOverride?: string\n): InstallPlan {\n const detected = detectProject(projectRoot);\n const language = languageOverride ?? detected.language ?? 'typescript';\n\n if (language !== 'typescript' && language !== 'python') {\n throw new CliError('Supported install languages are \"typescript\" and \"python\".');\n }\n\n if (language === 'python') {\n const command = pythonCommand ?? (process.platform === 'win32' ? 'python' : 'python3');\n const packageName = packageOverride ?? 'sentrial';\n return {\n language,\n framework: detected.framework,\n command,\n args: ['-m', 'pip', 'install', packageName],\n packageName,\n };\n }\n\n const packageManager = detectPackageManager(projectRoot);\n const packageName = packageOverride ?? '@sentrial/sdk';\n return {\n language,\n framework: detected.framework,\n command: packageManager,\n args: packageManager === 'npm' ? ['install', packageName] : ['add', packageName],\n packageName,\n };\n}\n\nfunction detectPackageManager(projectRoot: string): 'pnpm' | 'npm' | 'yarn' {\n if (existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(path.join(projectRoot, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\nfunction plannedScaffoldFiles(projectRoot: string, language: InstallPlan['language']): string[] {\n const sampleFile = language === 'python' ? 'sentrial.example.py' : 'sentrial.example.ts';\n return [path.join(projectRoot, sampleFile), path.join(projectRoot, '.env.sentrial.example')];\n}\n\nfunction runSubprocess(command: string, args: string[], cwd: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n });\n\n child.on('error', (error) => {\n reject(new CliError(`Failed to run ${formatCommand(command, args)}: ${error.message}`));\n });\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n reject(\n new CliError(`${formatCommand(command, args)} failed with exit code ${code ?? 'unknown'}`)\n );\n });\n });\n}\n\nfunction formatCommand(command: string, args: string[]): string {\n return [command, ...args].join(' ');\n}\n\nfunction typescriptExample(): string {\n return `import { configure, withSession } from '@sentrial/sdk';\n\nconfigure({\n apiKey: process.env.SENTRIAL_API_KEY,\n apiUrl: process.env.SENTRIAL_API_URL,\n});\n\nexport const runAgent = withSession('my-agent', async (userId: string, input: string) => {\n // Replace this with your real agent call. LLM/tool wrappers can be added around it.\n const output = \\`Echo: \\${input}\\`;\n return output;\n});\n\nawait runAgent('user_123', 'Hello from Sentrial');\n`;\n}\n\nfunction pythonExample(): string {\n return `from sentrial import SentrialClient\n\nclient = SentrialClient()\n\ninteraction = client.begin(\n user_id=\"user_123\",\n event=\"my-agent\",\n input=\"Hello from Sentrial\",\n)\n\ntry:\n # Replace this with your real agent call.\n output = \"Echo: Hello from Sentrial\"\n interaction.finish(output=output, success=True)\nexcept Exception as exc:\n interaction.finish(success=False, failure_reason=str(exc))\n raise\n`;\n}\n\nfunction printSession(session: SessionSummary, events: EventSummary[], ctx: CliContext): void {\n process.stdout.write(`${bold(ctx, 'Session')} ${session.id}\\n`);\n printKeyValues({\n name: session.name ?? '-',\n agent: session.agentName ?? session.agentSlug ?? '-',\n userId: session.userId ?? '-',\n status: `${session.status ?? '-'} (${formatResult(session.success)})`,\n score: formatNullableNumber(session.score),\n duration: formatDuration(session.durationMs),\n cost: formatCost(session.estimatedCost),\n tokens: session.totalTokens ?? '-',\n events: session.totalEvents ?? events.length,\n createdAt: formatDate(session.createdAt),\n completedAt: formatDate(session.completedAt),\n });\n\n if (session.failureReason) {\n process.stdout.write(`\\nFailure reason:\\n${indent(wrap(session.failureReason))}\\n`);\n }\n if (session.userInput) {\n process.stdout.write(`\\nInput:\\n${indent(wrap(session.userInput))}\\n`);\n }\n if (session.assistantOutput) {\n process.stdout.write(`\\nOutput:\\n${indent(wrap(session.assistantOutput))}\\n`);\n }\n\n if (events.length > 0) {\n process.stdout.write(`\\n${bold(ctx, 'Events')}\\n`);\n for (const event of events) {\n printEvent(event, ctx);\n }\n }\n}\n\nfunction printEvent(event: EventSummary, ctx: CliContext): void {\n const prefix = `#${event.sequenceNumber ?? '-'} ${event.eventType}`;\n const label =\n event.eventType === 'error' || hasMeaningfulValue(event.toolError)\n ? color(ctx, 'red', prefix)\n : color(ctx, 'cyan', prefix);\n process.stdout.write(`${label} ${formatDate(event.timestamp)}`);\n if (event.toolName) process.stdout.write(` tool=${event.toolName}`);\n if (event.estimatedCost) process.stdout.write(` cost=${formatCost(event.estimatedCost)}`);\n if (event.tokenCount) process.stdout.write(` tokens=${event.tokenCount}`);\n process.stdout.write('\\n');\n\n const summary = summarizeEvent(event);\n if (summary) process.stdout.write(`${indent(wrap(summary, 88))}\\n`);\n}\n\nfunction summarizeEvent(event: EventSummary): string {\n if (hasMeaningfulValue(event.toolError)) {\n return `Error: ${formatCompactJson(event.toolError)}`;\n }\n if (event.reasoning) {\n return event.reasoning;\n }\n if (hasMeaningfulValue(event.toolOutput)) {\n return `Output: ${formatCompactJson(event.toolOutput)}`;\n }\n if (hasMeaningfulValue(event.toolInput)) {\n return `Input: ${formatCompactJson(event.toolInput)}`;\n }\n return '';\n}\n\nfunction printKeyValues(values: Record<string, unknown>): void {\n const entries = Object.entries(values);\n const width = entries.reduce((max, [key]) => Math.max(max, key.length), 0);\n for (const [key, value] of entries) {\n process.stdout.write(`${key.padEnd(width)} ${String(value)}\\n`);\n }\n}\n\nfunction printJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n}\n\ninterface TableColumn<T> {\n header: string;\n maxWidth: number;\n render: (row: T) => string;\n}\n\nfunction printTable<T>(rows: T[], columns: Array<TableColumn<T>>): void {\n const widths = columns.map((column) => {\n const max = Math.max(column.header.length, ...rows.map((row) => column.render(row).length));\n return Math.min(max, column.maxWidth);\n });\n\n const header = columns\n .map((column, index) => pad(truncate(column.header, widths[index]), widths[index]))\n .join(' ');\n const divider = widths.map((width) => '-'.repeat(width)).join(' ');\n process.stdout.write(`${header}\\n${divider}\\n`);\n\n for (const row of rows) {\n const line = columns\n .map((column, index) => pad(truncate(column.render(row), widths[index]), widths[index]))\n .join(' ');\n process.stdout.write(`${line}\\n`);\n }\n}\n\nfunction truncate(value: string, width: number): string {\n if (value.length <= width) return value;\n if (width <= 1) return value.slice(0, width);\n return `${value.slice(0, width - 1)}...`.slice(0, width);\n}\n\nfunction pad(value: string, width: number): string {\n return `${value}${' '.repeat(Math.max(0, width - value.length))}`;\n}\n\nfunction color(ctx: CliContext, name: 'cyan' | 'green' | 'red' | 'yellow', value: string): string {\n if (!ctx.color) return value;\n const codes = {\n cyan: 36,\n green: 32,\n red: 31,\n yellow: 33,\n };\n return `\\u001b[${codes[name]}m${value}\\u001b[0m`;\n}\n\nfunction bold(ctx: CliContext, value: string): string {\n return ctx.color ? `\\u001b[1m${value}\\u001b[0m` : value;\n}\n\nfunction severityLabel(ctx: CliContext, severity: DiagnoseFinding['severity']): string {\n if (severity === 'high') return color(ctx, 'red', '[high]');\n if (severity === 'medium') return color(ctx, 'yellow', '[medium]');\n if (severity === 'low') return color(ctx, 'cyan', '[low]');\n return '[info]';\n}\n\nfunction formatResult(success: boolean | null | undefined): string {\n if (success === true) return 'pass';\n if (success === false) return 'fail';\n return '-';\n}\n\nfunction formatNullableNumber(value: number | null | undefined): string {\n return typeof value === 'number' ? String(Math.round(value * 10) / 10) : '-';\n}\n\nfunction formatDuration(ms: number | null | undefined): string {\n if (typeof ms !== 'number') return '-';\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60_000).toFixed(1)}m`;\n}\n\nfunction formatCost(cost: number | null | undefined): string {\n return typeof cost === 'number' ? `$${cost.toFixed(4)}` : '-';\n}\n\nfunction formatDate(value: string | null | undefined): string {\n if (!value) return '-';\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 16);\n}\n\nfunction formatCompactJson(value: unknown): string {\n if (value === undefined) return '';\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction wrap(text: string, width = 92): string {\n const words = text.replace(/\\s+/g, ' ').trim().split(' ');\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n if (`${current} ${word}`.trim().length > width && current) {\n lines.push(current);\n current = word;\n } else {\n current = `${current} ${word}`.trim();\n }\n }\n if (current) lines.push(current);\n return lines.join('\\n');\n}\n\nfunction indent(text: string, spaces = 2): string {\n const prefix = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n');\n}\n\nexport async function run(argv: string[]): Promise<void> {\n const parsed = parseArgs(argv);\n const ctx = createContext(parsed.flags);\n const [command, ...rest] = parsed.positionals;\n\n if (getBooleanFlag(parsed.flags, 'version')) {\n process.stdout.write(`${CLI_VERSION}\\n`);\n return;\n }\n\n if (!command || getBooleanFlag(parsed.flags, 'help')) {\n process.stdout.write(HELP);\n return;\n }\n\n switch (command) {\n case 'install':\n await commandInstall(ctx, parsed.flags);\n break;\n case 'init':\n await commandInit(ctx, parsed.flags);\n break;\n case 'login':\n await commandLogin(ctx, parsed.flags);\n break;\n case 'sessions':\n await commandSessions(ctx, parsed.flags, rest);\n break;\n case 'events':\n await commandEvents(ctx, parsed.flags, rest);\n break;\n case 'signals':\n await commandSignals(ctx, parsed.flags, rest);\n break;\n case 'diagnose':\n await commandDiagnose(ctx, parsed.flags, rest[0]);\n break;\n case 'evaluate':\n await commandEvaluate(ctx, parsed.flags, rest[0]);\n break;\n case 'fix':\n case 'replay':\n commandReserved(command);\n break;\n default:\n throw new CliError(`Unknown command: ${command}. Run sentrial --help.`);\n }\n}\n\nif (process.env.SENTRIAL_CLI_SKIP_AUTO_RUN !== '1') {\n run(process.argv.slice(2)).catch((error: unknown) => {\n if (error instanceof CliError) {\n if (process.env.SENTRIAL_CLI_DEBUG) {\n process.stderr.write(`${error.stack ?? error.message}\\n`);\n } else {\n process.stderr.write(`Error: ${error.message}\\n`);\n }\n process.exitCode = error.exitCode;\n return;\n }\n\n process.stderr.write(\n `${error instanceof Error ? (error.stack ?? error.message) : String(error)}\\n`\n );\n process.exitCode = 1;\n });\n}\n","/**\n * Shared SDK constants — single source so the client, OTLP transport, and CLI can't target\n * different endpoints if a path/URL changes.\n */\n\n/** Default Sentrial API base URL when neither a constructor arg nor SENTRIAL_API_URL is set. */\nexport const DEFAULT_API_URL = 'https://api.sentrial.com';\n\n/** OTLP traces ingest path, appended to the API base URL by the transport. */\nexport const OTEL_TRACES_PATH = '/api/otel/v1/traces';\n","{\n \"name\": \"@sentrial/sdk\",\n \"version\": \"0.5.0\",\n \"description\": \"Sentrial SDK for TypeScript/Node.js - AI agent observability and monitoring\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"sentrial\": \"./dist/cli.js\"\n },\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist\",\n \"prepublishOnly\": \"pnpm run build\"\n },\n \"keywords\": [\n \"sentrial\",\n \"ai\",\n \"agent\",\n \"observability\",\n \"monitoring\",\n \"llm\",\n \"tracing\",\n \"openai\",\n \"openai-agents\",\n \"anthropic\",\n \"vercel-ai-sdk\",\n \"google-adk\"\n ],\n \"dependencies\": {\n \"@opentelemetry/api\": \"^1.7.0\"\n },\n \"peerDependencies\": {\n \"@anthropic-ai/claude-agent-sdk\": \">=0.2.0 <1.0.0\",\n \"@google/adk\": \">=0.1.0 <2.0.0\",\n \"@openai/agents\": \">=0.1.0 <1.0.0\",\n \"ai\": \">=3.0.0 <8.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"ai\": {\n \"optional\": true\n },\n \"@anthropic-ai/claude-agent-sdk\": {\n \"optional\": true\n },\n \"@google/adk\": {\n \"optional\": true\n },\n \"@openai/agents\": {\n \"optional\": true\n }\n },\n \"author\": \"Sentrial\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/sentrialdev/Sentrial.git\",\n \"directory\": \"packages/typescript-sdk\"\n },\n \"homepage\": \"https://sentrial.com\",\n \"bugs\": {\n \"url\": \"https://github.com/sentrialdev/Sentrial/issues\"\n },\n \"engines\": {\n \"node\": \">=18\"\n },\n \"devDependencies\": {\n \"@sentrial/otlp\": \"workspace:*\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.3\",\n \"vitest\": \"^4.1.11\"\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBAA8E;AAC9E,gCAAsB;AACtB,qBAAe;AACf,uBAAiB;AACjB,0BAAoB;AACpB,sBAAqB;;;ACDd,IAAM,kBAAkB;;;ACJ7B,cAAW;;;AFYb,IAAM,aAAa,iBAAAA,QAAK,KAAK,eAAAC,QAAG,QAAQ,GAAG,WAAW;AACtD,IAAM,cAAc,iBAAAD,QAAK,KAAK,YAAY,aAAa;AACvD,IAAM,cAAc,oBAAI,IAAI,CAAC,OAAO,MAAM,MAAM,KAAK,CAAC;AAwD/C,IAAM,WAAN,cAAuB,MAAM;AAAA,EACzB;AAAA,EAET,YAAY,SAAiB,WAAW,GAAG;AACzC,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,WAAW;AAAA,EAClB;AACF;AAEA,IAAM,cAAsC;AAAA,EAC1C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wEAoB2D,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBhF,SAAS,UAAU,MAA4B;AACpD,QAAM,QAAmC,CAAC;AAC1C,QAAM,cAAwB,CAAC;AAE/B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,QAAQ,KAAK,CAAC;AACpB,QAAI,UAAU,MAAM;AAClB,kBAAY,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AACrC;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,OAAO,GAAG;AAC7B,YAAM,MAAM,MAAM,CAAC,CAAC,IAAI;AACxB;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,YAAM,CAAC,SAAS,WAAW,IAAI,MAAM,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC;AAC1D,UAAI,gBAAgB,QAAW;AAC7B,cAAM,OAAO,IAAI;AAAA,MACnB,WAAW,cAAc,IAAI,OAAO,GAAG;AACrC,cAAM,OAAO,IAAI;AAAA,MACnB,OAAO;AACL,cAAM,OAAO,KAAK,IAAI,CAAC;AACvB,YAAI,QAAQ,CAAC,KAAK,WAAW,GAAG,GAAG;AACjC,gBAAM,OAAO,IAAI;AACjB;AAAA,QACF,OAAO;AACL,gBAAM,OAAO,IAAI;AAAA,QACnB;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,GAAG,KAAK,MAAM,WAAW,GAAG;AAC/C,YAAM,SAAS,YAAY,MAAM,MAAM,CAAC,CAAC;AACzC,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,SAAS,iBAAiB,KAAK,EAAE;AAAA,MAC7C;AACA,UAAI,cAAc,IAAI,MAAM,GAAG;AAC7B,cAAM,MAAM,IAAI;AAAA,MAClB,OAAO;AACL,cAAM,OAAO,KAAK,IAAI,CAAC;AACvB,YAAI,CAAC,QAAQ,KAAK,WAAW,GAAG,GAAG;AACjC,gBAAM,IAAI,SAAS,QAAQ,KAAK,mBAAmB;AAAA,QACrD;AACA,cAAM,MAAM,IAAI;AAChB;AAAA,MACF;AACA;AAAA,IACF;AAEA,gBAAY,KAAK,KAAK;AAAA,EACxB;AAEA,SAAO,EAAE,OAAO,YAAY;AAC9B;AAEA,SAAS,QAAQ,UAAqC,OAA4B;AAChF,aAAW,QAAQ,OAAO;AACxB,QAAI,MAAM,IAAI,MAAM,OAAW,QAAO,MAAM,IAAI;AAAA,EAClD;AACA,SAAO;AACT;AAEA,SAAS,cAAc,UAAqC,OAAqC;AAC/F,QAAM,QAAQ,QAAQ,OAAO,GAAG,KAAK;AACrC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAEA,SAAS,eAAe,OAAkC,MAAuB;AAC/E,SAAO,MAAM,IAAI,MAAM;AACzB;AAEA,SAAS,aAA2B;AAClC,MAAI,KAAC,2BAAW,WAAW,EAAG,QAAO,CAAC;AAEtC,MAAI;AACF,UAAM,SAAS,KAAK,UAAM,6BAAa,aAAa,MAAM,CAAC;AAC3D,WAAO,UAAU,OAAO,WAAW,WAAW,SAAS,CAAC;AAAA,EAC1D,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,YAAY,QAA4B;AAC/C,gCAAU,YAAY,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACtD,oCAAc,aAAa,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,GAAM,EAAE,MAAM,IAAM,CAAC;AAClF,MAAI;AACF,kCAAU,aAAa,GAAK;AAAA,EAC9B,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,cAAc,OAA8C;AACnE,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,cAAc,OAAO,SAAS,KAAK,oBAAAE,QAAQ,IAAI,oBAAoB,OAAO;AACzF,QAAM,UACJ,cAAc,OAAO,SAAS,KAC9B,oBAAAA,QAAQ,IAAI,oBACZ,OAAO,UACP,iBACA,QAAQ,OAAO,EAAE;AAEnB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,eAAe,OAAO,MAAM;AAAA,IAClC,OAAO,MAAM,UAAU,SAAS,oBAAAA,QAAQ,OAAO,SAAS,CAAC,oBAAAA,QAAQ,IAAI;AAAA,EACvE;AACF;AAEA,SAAS,cAAc,KAAyB;AAC9C,MAAI,CAAC,IAAI,QAAQ;AACf,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI;AACb;AAEA,eAAe,WACb,KACA,SACA,UAII,CAAC,GACO;AACZ,QAAM,SAAS,cAAc,GAAG;AAChC,QAAM,MAAM,IAAI,IAAI,SAAS,GAAG,IAAI,MAAM,GAAG;AAE7C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,GAAG;AAC9D,QAAI,UAAU,QAAW;AACvB,UAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IACzC;AAAA,EACF;AAEA,QAAM,UAAkC;AAAA,IACtC,eAAe,UAAU,MAAM;AAAA,IAC/B,QAAQ;AAAA,EACV;AAEA,MAAI,QAAQ,SAAS,QAAW;AAC9B,YAAQ,cAAc,IAAI;AAAA,EAC5B;AAEA,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,MAAM,KAAK;AAAA,MAC1B,QAAQ,QAAQ,UAAU;AAAA,MAC1B;AAAA,MACA,MAAM,QAAQ,SAAS,SAAY,SAAY,KAAK,UAAU,QAAQ,IAAI;AAAA,IAC5E,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,mBAAmB,IAAI,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAC1F;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAM,SAAS,kBAAkB,IAAI;AAErC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,UAAU,KAAK,IAAI,IAAI,QAAQ,YAAY,SAAS,MAAM,MAAM;AAAA,QACzE;AAAA,MACF,CAAC;AAAA,MACD,SAAS,WAAW,MAAM,IAAI;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAuB;AAChD,MAAI,CAAC,KAAK,KAAK,EAAG,QAAO,CAAC;AAC1B,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,eAAe,OAAwB;AAC9C,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,SAAS;AACf,QAAI,OAAO,OAAO,UAAU,SAAU,QAAO,OAAO;AACpD,QAAI,OAAO,SAAS,OAAO,OAAO,UAAU,UAAU;AACpD,YAAM,QAAQ,OAAO;AACrB,UAAI,OAAO,MAAM,YAAY,SAAU,QAAO,MAAM;AAAA,IACtD;AAAA,EACF;AACA,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,eAAe,aAAa,KAAiB,OAAiD;AAC5F,MAAI,SAAS,cAAc,OAAO,SAAS,KAAK,oBAAAA,QAAQ,IAAI;AAC5D,QAAM,SAAS,cAAc,OAAO,SAAS,KAAK,oBAAAA,QAAQ,IAAI,oBAAoB,IAAI;AAEtF,MAAI,CAAC,QAAQ;AACX,QAAI,CAAC,oBAAAA,QAAQ,MAAM,OAAO;AACxB,YAAM,IAAI,SAAS,uEAAuE;AAAA,IAC5F;AACA,UAAM,KAAK,gBAAAC,QAAS,gBAAgB,EAAE,OAAO,oBAAAD,QAAQ,OAAO,QAAQ,oBAAAA,QAAQ,OAAO,CAAC;AACpF,cAAU,MAAM,GAAG,SAAS,oBAAoB,GAAG,KAAK;AACxD,OAAG,MAAM;AAAA,EACX;AAEA,MAAI,CAAC,OAAO,WAAW,WAAW,GAAG;AACnC,UAAM,IAAI,SAAS,mEAAmE;AAAA,EACxF;AAEA,cAAY,EAAE,QAAQ,OAAO,CAAC;AAE9B,MAAI,IAAI,MAAM;AACZ,cAAU,EAAE,IAAI,MAAM,YAAY,aAAa,OAAO,CAAC;AACvD;AAAA,EACF;AAEA,sBAAAA,QAAQ,OAAO,MAAM,wBAAwB,WAAW;AAAA,CAAI;AAC9D;AAEA,eAAe,eAAe,KAAiB,OAAiD;AAC9F,QAAM,cAAc,oBAAAA,QAAQ,IAAI;AAChC,QAAM,oBAAoB,cAAc,OAAO,UAAU;AACzD,QAAM,gBAAgB,cAAc,OAAO,QAAQ;AACnD,QAAM,kBAAkB,cAAc,OAAO,aAAa,KAAK,oBAAAA,QAAQ,IAAI;AAC3E,QAAM,OAAO,iBAAiB,aAAa,mBAAmB,eAAe,eAAe;AAC5F,QAAM,SAAS,eAAe,OAAO,SAAS;AAE9C,MAAI,IAAI,MAAM;AACZ,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,SAAS,yEAAyE;AAAA,IAC9F;AACA,cAAU,EAAE,QAAQ,MAAM,MAAM,YAAY,qBAAqB,aAAa,KAAK,QAAQ,EAAE,CAAC;AAC9F;AAAA,EACF;AAEA,sBAAAA,QAAQ,OAAO,MAAM,aAAa,KAAK,aAAa,KAAK,QAAQ;AAAA,CAAI;AACrE,sBAAAA,QAAQ,OAAO,MAAM,aAAa,cAAc,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,CAAI;AAE5E,MAAI,QAAQ;AACV,wBAAAA,QAAQ,OAAO,MAAM,wCAAwC;AAC7D;AAAA,EACF;AAEA,QAAM,cAAc,KAAK,SAAS,KAAK,MAAM,WAAW;AACxD,QAAM,YAAY,KAAK,KAAK;AAC9B;AAEA,eAAe,YAAY,KAAiB,OAAiD;AAC3F,QAAM,cAAc,oBAAAA,QAAQ,IAAI;AAChC,QAAM,WAAW,cAAc,WAAW;AAC1C,QAAM,oBAAoB,cAAc,OAAO,UAAU;AACzD,QAAM,WAAW,qBAAqB,SAAS,YAAY;AAC3D,QAAM,QAAQ,eAAe,OAAO,OAAO;AAC3C,QAAM,gBAAgB,eAAe,OAAO,iBAAiB;AAE7D,MAAI,aAAa,gBAAgB,aAAa,UAAU;AACtD,UAAM,IAAI,SAAS,yDAAyD;AAAA,EAC9E;AAEA,QAAM,QACJ,aAAa,WACT;AAAA,IACE;AAAA,MACE,MAAM,iBAAAF,QAAK,KAAK,aAAa,qBAAqB;AAAA,MAClD,SAAS,cAAc;AAAA,IACzB;AAAA,EACF,IACA;AAAA,IACE;AAAA,MACE,MAAM,iBAAAA,QAAK,KAAK,aAAa,qBAAqB;AAAA,MAClD,SAAS,kBAAkB;AAAA,IAC7B;AAAA,EACF;AAIN,QAAM,KAAK;AAAA,IACT,MAAM,iBAAAA,QAAK,KAAK,aAAa,uBAAuB;AAAA,IACpD,SAAS;AAAA,mBAAwD,IAAI,MAAM;AAAA;AAAA,EAC7E,CAAC;AAID,MAAI,iBAAiB,IAAI,QAAQ;AAC/B,UAAM,KAAK;AAAA,MACT,MAAM,iBAAAA,QAAK,KAAK,aAAa,eAAe;AAAA,MAC5C,SAAS,oBAAoB,IAAI,MAAM;AAAA,mBAAsB,IAAI,MAAM;AAAA;AAAA,IACzE,CAAC;AAAA,EACH;AAEA,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAE3B,aAAW,QAAQ,OAAO;AACxB,YAAI,2BAAW,KAAK,IAAI,KAAK,CAAC,OAAO;AACnC,cAAQ,KAAK,KAAK,IAAI;AACtB;AAAA,IACF;AACA,sCAAc,KAAK,MAAM,KAAK,OAAO;AACrC,YAAQ,KAAK,KAAK,IAAI;AAAA,EACxB;AAEA,QAAM,iBACJ,aAAa,WACT,yBACA,GAAG,qBAAqB,WAAW,CAAC;AAE1C,MAAI,IAAI,MAAM;AACZ,cAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,sBAAAE,QAAQ,OAAO,MAAM,aAAa,SAAS,aAAa,QAAQ;AAAA,CAAI;AACpE,sBAAAA,QAAQ,OAAO,MAAM,aAAa,cAAc;AAAA,CAAI;AACpD,MAAI,QAAQ,SAAS,GAAG;AACtB,wBAAAA,QAAQ,OAAO;AAAA,MACb;AAAA,EAAa,QAAQ,IAAI,CAAC,SAAS,KAAK,iBAAAF,QAAK,SAAS,aAAa,IAAI,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,IACxF;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,wBAAAE,QAAQ,OAAO;AAAA,MACb;AAAA,EAA4B,QAAQ,IAAI,CAAC,SAAS,KAAK,iBAAAF,QAAK,SAAS,aAAa,IAAI,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,IACvG;AAAA,EACF;AACF;AAEA,eAAe,gBACb,KACA,OACA,MACe;AACf,QAAM,aAAa,KAAK,CAAC;AACzB,MAAI,eAAe,QAAQ;AACzB,UAAM,oBAAoB,KAAK,KAAK;AACpC;AAAA,EACF;AACA,MAAI,eAAe,OAAO;AACxB,UAAM,YAAY,KAAK,CAAC;AACxB,QAAI,CAAC,UAAW,OAAM,IAAI,SAAS,mCAAmC;AACtE,UAAM,mBAAmB,KAAK,OAAO,SAAS;AAC9C;AAAA,EACF;AACA,QAAM,IAAI,SAAS,qCAAqC;AAC1D;AAEA,eAAe,oBACb,KACA,OACe;AACf,QAAM,QAAQ,eAAe,KAAK;AAClC,QAAM,cAAc,cAAc,OAAO,OAAO,GAAG,YAAY;AAC/D,QAAM,mBAAmB,cAAc,OAAO,OAAO,MAAM;AAC3D,QAAM,SAAS,cAAc,OAAO,QAAQ,KAAK;AACjD,QAAM,QAAQ,iBAAiB,OAAO,SAAS,eAAe,CAAC,mBAAmB,MAAM,EAAE;AAC1F,QAAM,SAAS,iBAAiB,OAAO,UAAU,CAAC;AAElD,QAAM,WAAW,MAAM,WAA0C,KAAK,oBAAoB;AAAA,IACxF;AAAA,EACF,CAAC;AAED,QAAM,WAAW,cACb,SAAS,KAAK;AAAA,IAAO,CAAC,YACpB,GAAG,QAAQ,aAAa,EAAE,IAAI,QAAQ,aAAa,EAAE,GAAG,YAAY,EAAE,SAAS,WAAW;AAAA,EAC5F,IACA,SAAS;AAEb,MAAI,IAAI,MAAM;AACZ,cAAU,EAAE,MAAM,UAAU,MAAM,SAAS,KAAK,CAAC;AACjD;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,wBAAAE,QAAQ,OAAO,MAAM,sBAAsB;AAC3C;AAAA,EACF;AAEA,aAAW,UAAU;AAAA,IACnB,EAAE,QAAQ,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,UAAU,GAAG;AAAA,IAClD,EAAE,QAAQ,SAAS,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,aAAa,KAAK,UAAU,GAAG;AAAA,IAClF,EAAE,QAAQ,UAAU,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,GAAG;AAAA,IACjE,EAAE,QAAQ,UAAU,QAAQ,CAAC,MAAM,aAAa,EAAE,OAAO,GAAG,UAAU,EAAE;AAAA,IACxE,EAAE,QAAQ,SAAS,QAAQ,CAAC,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,EAAE;AAAA,IAC7E,EAAE,QAAQ,OAAO,QAAQ,CAAC,MAAM,eAAe,EAAE,UAAU,GAAG,UAAU,EAAE;AAAA,IAC1E,EAAE,QAAQ,QAAQ,QAAQ,CAAC,MAAM,WAAW,EAAE,aAAa,GAAG,UAAU,GAAG;AAAA,IAC3E,EAAE,QAAQ,WAAW,QAAQ,CAAC,MAAM,WAAW,EAAE,SAAS,GAAG,UAAU,GAAG;AAAA,IAC1E,EAAE,QAAQ,QAAQ,QAAQ,CAAC,MAAM,EAAE,QAAQ,KAAK,UAAU,GAAG;AAAA,EAC/D,CAAC;AAED,MAAI,aAAa;AACf,wBAAAA,QAAQ,OAAO,MAAM;AAAA,6BAAgC,WAAW;AAAA,CAAI;AAAA,EACtE;AACF;AAEA,eAAe,mBACb,KACA,OACA,WACe;AACf,QAAM,kBAAkB,MAAM;AAAA,IAC5B;AAAA,IACA,oBAAoB,SAAS;AAAA,EAC/B;AACA,QAAM,gBAAgB,MAAM,WAAW;AACvC,QAAM,SAAS,gBAAgB,MAAM,mBAAmB,KAAK,OAAO,SAAS,IAAI,CAAC;AAElF,MAAI,IAAI,MAAM;AACZ,cAAU,EAAE,MAAM,gBAAgB,MAAM,OAAO,CAAC;AAChD;AAAA,EACF;AAEA,eAAa,gBAAgB,MAAM,QAAQ,GAAG;AAChD;AAEA,eAAe,mBACb,KACA,OACA,WACyB;AACzB,QAAM,YAAY,cAAc,OAAO,YAAY,KAAK;AACxD,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA,oBAAoB,SAAS;AAAA,IAC7B;AAAA,MACE,OAAO;AAAA,QACL,OAAO,iBAAiB,OAAO,gBAAgB,GAAG;AAAA,QAClD,QAAQ,iBAAiB,OAAO,iBAAiB,CAAC;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,SAAS;AAClB;AAEA,eAAe,cACb,KACA,OACA,MACe;AACf,QAAM,aAAa,KAAK,CAAC,KAAK;AAC9B,MAAI,eAAe,QAAQ;AACzB,UAAM,IAAI,SAAS,0CAA0C;AAAA,EAC/D;AAEA,QAAM,YAAY,KAAK,CAAC,KAAK,cAAc,OAAO,WAAW,YAAY;AACzE,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,SAAS,0CAA0C;AAAA,EAC/D;AAEA,QAAM,YAAY,cAAc,OAAO,QAAQ,YAAY,KAAK;AAChE,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IACA,oBAAoB,SAAS;AAAA,IAC7B;AAAA,MACE,OAAO;AAAA,QACL,OAAO,iBAAiB,OAAO,SAAS,GAAG;AAAA,QAC3C,QAAQ,iBAAiB,OAAO,UAAU,CAAC;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,IAAI,MAAM;AACZ,cAAU,QAAQ;AAClB;AAAA,EACF;AAEA,MAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,wBAAAA,QAAQ,OAAO,MAAM,oBAAoB;AACzC;AAAA,EACF;AAEA,sBAAAA,QAAQ,OAAO,MAAM,GAAG,KAAK,KAAK,QAAQ,CAAC,IAAI,SAAS;AAAA,CAAI;AAC5D,aAAW,SAAS,SAAS,MAAM;AACjC,eAAW,OAAO,GAAG;AAAA,EACvB;AACF;AAEA,eAAe,eACb,KACA,OACA,MACe;AACf,QAAM,aAAa,KAAK,CAAC,KAAK;AAC9B,MAAI,eAAe,QAAQ;AACzB,UAAM,IAAI,SAAS,8BAA8B;AAAA,EACnD;AAEA,QAAM,QAAQ,eAAe,KAAK;AAClC,QAAM,OAAO,cAAc,OAAO,MAAM,KAAK;AAC7C,QAAM,SAAS,cAAc,OAAO,QAAQ,KAAK;AAEjD,QAAM,WAAW,MAAM,WAAyC,KAAK,mBAAmB;AAAA,IACtF;AAAA,EACF,CAAC;AAED,MAAI,IAAI,MAAM;AACZ,cAAU,QAAQ;AAClB;AAAA,EACF;AAEA,MAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,wBAAAA,QAAQ,OAAO,MAAM,qBAAqB;AAC1C;AAAA,EACF;AAEA,aAAW,SAAS,MAAM;AAAA,IACxB,EAAE,QAAQ,QAAQ,QAAQ,CAAC,MAAM,EAAE,MAAM,UAAU,GAAG;AAAA,IACtD,EAAE,QAAQ,QAAQ,QAAQ,CAAC,MAAM,EAAE,MAAM,UAAU,GAAG;AAAA,IACtD,EAAE,QAAQ,UAAU,QAAQ,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,GAAG;AAAA,IACjE,EAAE,QAAQ,SAAS,QAAQ,CAAC,MAAM,OAAO,EAAE,KAAK,GAAG,UAAU,EAAE;AAAA,IAC/D,EAAE,QAAQ,YAAY,QAAQ,CAAC,MAAM,OAAO,EAAE,gBAAgB,GAAG,UAAU,GAAG;AAAA,IAC9E,EAAE,QAAQ,SAAS,QAAQ,CAAC,MAAM,OAAO,EAAE,aAAa,GAAG,UAAU,EAAE;AAAA,IACvE,EAAE,QAAQ,WAAW,QAAQ,CAAC,MAAM,WAAW,EAAE,SAAS,GAAG,UAAU,GAAG;AAAA,IAC1E,EAAE,QAAQ,eAAe,QAAQ,CAAC,MAAM,EAAE,eAAe,KAAK,UAAU,GAAG;AAAA,EAC7E,CAAC;AACH;AAEA,eAAe,gBACb,KACA,OACA,WACe;AACf,MAAI,CAAC,UAAW,OAAM,IAAI,SAAS,uCAAuC;AAE1E,QAAM,kBAAkB,MAAM;AAAA,IAC5B;AAAA,IACA,oBAAoB,SAAS;AAAA,EAC/B;AACA,QAAM,SAAS,MAAM,mBAAmB,KAAK,OAAO,SAAS;AAC7D,QAAM,WAAW,gBAAgB,gBAAgB,MAAM,MAAM;AAE7D,MAAI,IAAI,MAAM;AACZ,cAAU,EAAE,SAAS,gBAAgB,MAAM,SAAS,CAAC;AACrD;AAAA,EACF;AAEA,sBAAAA,QAAQ,OAAO,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC;AAAA,CAAI;AAClD,sBAAAA,QAAQ,OAAO,MAAM,YAAY,gBAAgB,KAAK,EAAE;AAAA,CAAI;AAC5D,sBAAAA,QAAQ,OAAO;AAAA,IACb,YAAY,gBAAgB,KAAK,aAAa,gBAAgB,KAAK,aAAa,GAAG;AAAA;AAAA,EACrF;AACA,sBAAAA,QAAQ,OAAO;AAAA,IACb,YAAY,gBAAgB,KAAK,UAAU,GAAG,KAAK,aAAa,gBAAgB,KAAK,OAAO,CAAC;AAAA;AAAA,EAC/F;AACA,MAAI,gBAAgB,KAAK,eAAe;AACtC,wBAAAA,QAAQ,OAAO,MAAM,YAAY,gBAAgB,KAAK,aAAa;AAAA,CAAI;AAAA,EACzE;AACA,sBAAAA,QAAQ,OAAO,MAAM,IAAI;AAEzB,MAAI,SAAS,WAAW,GAAG;AACzB,wBAAAA,QAAQ,OAAO,MAAM,iEAAiE;AACtF;AAAA,EACF;AAEA,aAAW,WAAW,UAAU;AAC9B,wBAAAA,QAAQ,OAAO,MAAM,GAAG,cAAc,KAAK,QAAQ,QAAQ,CAAC,IAAI,QAAQ,KAAK;AAAA,CAAI;AACjF,wBAAAA,QAAQ,OAAO,MAAM,KAAK,QAAQ,MAAM;AAAA,CAAI;AAAA,EAC9C;AACF;AAEA,eAAe,gBACb,KACA,OACA,cACe;AACf,QAAM,uBAAuB,gBAAgB,cAAc,OAAO,cAAc,eAAe;AAC/F,MAAI,CAAC,sBAAsB;AACzB,UAAM,IAAI,SAAS,2DAA2D;AAAA,EAChF;AAEA,QAAM,OAAO;AAAA,IACX,cAAc;AAAA,IACd,sBAAsB,cAAc,OAAO,YAAY,wBAAwB;AAAA,IAC/E,YAAY;AAAA,MACV,UAAU,wBAAwB,OAAO,WAAW;AAAA,MACpD,kBAAkB,MAAM,oBAAoB,MAAM,QAAQ,QAAQ;AAAA,MAClE,sBAAsB,wBAAwB,OAAO,wBAAwB;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,WAAoC,KAAK,oBAAoB;AAAA,IAClF,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAED,MAAI,IAAI,MAAM;AACZ,cAAU,QAAQ;AAAA,EACpB,OAAO;AACL,UAAM,SAAS,SAAS,WAAW;AACnC,wBAAAA,QAAQ,OAAO,MAAM,GAAG,SAAS,MAAM,KAAK,SAAS,MAAM,IAAI,MAAM,KAAK,OAAO,MAAM,CAAC;AAAA,CAAI;AAC5F,QAAI,MAAM,QAAQ,SAAS,QAAQ,KAAK,SAAS,SAAS,SAAS,GAAG;AACpE,0BAAAA,QAAQ,OAAO;AAAA,QACb;AAAA,EAAc,SAAS,SAAS,IAAI,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,MAC3E;AAAA,IACF;AACA,QAAI,SAAS,WAAW,OAAO,SAAS,YAAY,UAAU;AAC5D,qBAAe,SAAS,OAAkC;AAAA,IAC5D;AACA,QAAI,SAAS,cAAc,OAAO,SAAS,eAAe,UAAU;AAClE,0BAAAA,QAAQ,OAAO,MAAM,iBAAiB;AACtC,qBAAe,SAAS,UAAqC;AAAA,IAC/D;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,OAAO;AAC7B,wBAAAA,QAAQ,WAAW;AAAA,EACrB;AACF;AAEA,SAAS,gBAAgB,SAAuB;AAC9C,QAAM,WAAmC;AAAA,IACvC,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AACA,QAAM,IAAI,SAAS,SAAS,OAAO,KAAK,GAAG,OAAO,0BAA0B,CAAC;AAC/E;AAEA,SAAS,eAAe,OAAmE;AACzF,QAAM,QAAyC,CAAC;AAChD,QAAM,OAAO,cAAc,OAAO,QAAQ,YAAY,KAAK;AAC3D,QAAM,OAAO,cAAc,OAAO,MAAM;AACxC,QAAM,KAAK,cAAc,OAAO,IAAI;AAEpC,MAAI,MAAM;AACR,UAAM,OAAO;AAAA,EACf,WAAW,YAAY,IAAI,IAAI,GAAG;AAChC,UAAM,YAAY;AAAA,EACpB,OAAO;AACL,UAAM,IAAI,SAAS,0BAA0B,MAAM,KAAK,WAAW,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACnF;AAEA,MAAI,GAAI,OAAM,KAAK;AACnB,SAAO;AACT;AAEA,SAAS,iBACP,OACA,MACA,UACQ;AACR,QAAM,MAAM,cAAc,OAAO,IAAI;AACrC,MAAI,QAAQ,OAAW,QAAO;AAC9B,QAAM,SAAS,OAAO,SAAS,KAAK,EAAE;AACtC,MAAI,CAAC,OAAO,SAAS,MAAM,EAAG,OAAM,IAAI,SAAS,KAAK,IAAI,qBAAqB;AAC/E,SAAO;AACT;AAEA,SAAS,wBACP,OACA,MACoB;AACpB,QAAM,MAAM,cAAc,OAAO,IAAI;AACrC,MAAI,QAAQ,OAAW,QAAO;AAC9B,QAAM,SAAS,OAAO,WAAW,GAAG;AACpC,MAAI,CAAC,OAAO,SAAS,MAAM,EAAG,OAAM,IAAI,SAAS,KAAK,IAAI,mBAAmB;AAC7E,SAAO;AACT;AAEO,SAAS,gBACd,SACA,QACmB;AACnB,QAAM,WAA8B,CAAC;AACrC,QAAM,aAAa,OAAO,OAAO,CAAC,UAAU,mBAAmB,MAAM,SAAS,CAAC;AAC/E,QAAM,iBAAiB,OAAO,OAAO,CAAC,UAAU,MAAM,cAAc,OAAO;AAC3E,QAAM,gBAAgB,OAAO;AAAA,IAC3B,CAAC,UAAU,OAAO,MAAM,eAAe,YAAY,MAAM,aAAa;AAAA,EACxE;AAEA,MAAI,QAAQ,YAAY,SAAS,QAAQ,WAAW,UAAU;AAC5D,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,QAAQ,iBAAiB;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,UAAU,QAAQ,YAAY,CAAC,UAAU,MAAM,YAAY,cAAc;AAC/E,UAAM,MAAM,MAAM,KAAK,QAAQ,QAAQ,CAAC,EACrC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,GAAG,IAAI,KAAK,MAAM,MAAM,GAAG,EAClD,KAAK,IAAI;AACZ,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,GAAG,WAAW,MAAM,yBAAyB,GAAG,kBAAkB;AAAA,QACxE,WAAW,CAAC,EAAE;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,GAAG,eAAe,MAAM,iCAAiC;AAAA,QAC/D,eAAe,CAAC;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB,sBAAsB,MAAM;AAClD,MAAI,cAAc,SAAS,GAAG;AAC5B,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,cACL,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,SAAS,GAAG,KAAK,QAAQ,aAAa,KAAK,KAAK,QAAQ,EAC7D,KAAK,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,GAAG,cAAc,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,eAAe,QAAQ,cAAc,KAAS;AACxD,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,qBAAqB,QAAQ,YAAY,eAAe,CAAC;AAAA,IACnE,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,cAAc,QAAQ,aAAa,MAAS;AACtD,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,gBAAgB,eAAe,QAAQ,UAAU,CAAC;AAAA,IAC5D,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,WAAW,eAAe,CAAC,QAAQ,iBAAiB;AAC9D,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,QACE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,QAAoE;AACjG,QAAM,SAAS,oBAAI,IAAiD;AACpE,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,cAAc,eAAe,CAAC,MAAM,SAAU;AACxD,UAAM,MAAM,GAAG,MAAM,QAAQ,IAAI,kBAAkB,MAAM,SAAS,CAAC;AACnE,UAAM,UAAU,OAAO,IAAI,GAAG,KAAK,EAAE,UAAU,MAAM,UAAU,OAAO,EAAE;AACxE,YAAQ;AACR,WAAO,IAAI,KAAK,OAAO;AAAA,EACzB;AACA,SAAO,MAAM,KAAK,OAAO,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AACvE;AAEA,SAAS,QAAW,OAAY,QAA+C;AAC7E,QAAM,SAAS,oBAAI,IAAiB;AACpC,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,OAAO,IAAI;AACvB,UAAM,WAAW,OAAO,IAAI,GAAG,KAAK,CAAC;AACrC,aAAS,KAAK,IAAI;AAClB,WAAO,IAAI,KAAK,QAAQ;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAyB;AACnD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,MAAM,KAAK,EAAE,SAAS;AAC5D,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,SAAS;AAChD,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK,KAAK,EAAE,SAAS;AAClE,SAAO;AACT;AAEO,SAAS,cAAc,aAG5B;AACA,QAAM,kBAAkB,iBAAAF,QAAK,KAAK,aAAa,cAAc;AAC7D,UAAI,2BAAW,eAAe,GAAG;AAC/B,QAAI;AACF,YAAM,MAAM,KAAK,UAAM,6BAAa,iBAAiB,MAAM,CAAC;AAI5D,YAAM,OAAO,EAAE,GAAG,IAAI,cAAc,GAAG,IAAI,gBAAgB;AAC3D,UAAI,KAAK,KAAM,QAAO,EAAE,UAAU,cAAc,WAAW,UAAU;AACrE,UAAI,KAAK,MAAM,KAAK,gBAAgB;AAClC,eAAO,EAAE,UAAU,cAAc,WAAW,gBAAgB;AAC9D,UAAI,KAAK,aAAa,KAAK,iBAAiB;AAC1C,eAAO,EAAE,UAAU,cAAc,WAAW,YAAY;AAC1D,UAAI,KAAK,OAAQ,QAAO,EAAE,UAAU,cAAc,WAAW,cAAc;AAC3E,aAAO,EAAE,UAAU,cAAc,WAAW,UAAU;AAAA,IACxD,QAAQ;AACN,aAAO,EAAE,UAAU,cAAc,WAAW,UAAU;AAAA,IACxD;AAAA,EACF;AAEA,QAAM,mBAAmB,iBAAAA,QAAK,KAAK,aAAa,kBAAkB;AAClE,QAAM,gBAAgB,iBAAAA,QAAK,KAAK,aAAa,gBAAgB;AAC7D,UAAI,2BAAW,gBAAgB,SAAK,2BAAW,aAAa,GAAG;AAC7D,UAAM,OAAO,CAAC,kBAAkB,aAAa,EAC1C,OAAO,CAAC,aAAS,2BAAW,IAAI,CAAC,EACjC,IAAI,CAAC,aAAS,6BAAa,MAAM,MAAM,EAAE,YAAY,CAAC,EACtD,KAAK,IAAI;AACZ,QAAI,KAAK,SAAS,SAAS,EAAG,QAAO,EAAE,UAAU,UAAU,WAAW,UAAU;AAChF,QAAI,KAAK,SAAS,WAAW,EAAG,QAAO,EAAE,UAAU,UAAU,WAAW,YAAY;AACpF,QAAI,KAAK,SAAS,QAAQ,EAAG,QAAO,EAAE,UAAU,UAAU,WAAW,SAAS;AAC9E,QAAI,KAAK,SAAS,QAAQ,EAAG,QAAO,EAAE,UAAU,UAAU,WAAW,gBAAgB;AACrF,WAAO,EAAE,UAAU,UAAU,WAAW,SAAS;AAAA,EACnD;AAEA,SAAO,CAAC;AACV;AAEO,SAAS,iBACd,aACA,kBACA,eACA,iBACa;AACb,QAAM,WAAW,cAAc,WAAW;AAC1C,QAAM,WAAW,oBAAoB,SAAS,YAAY;AAE1D,MAAI,aAAa,gBAAgB,aAAa,UAAU;AACtD,UAAM,IAAI,SAAS,4DAA4D;AAAA,EACjF;AAEA,MAAI,aAAa,UAAU;AACzB,UAAM,UAAU,kBAAkB,oBAAAE,QAAQ,aAAa,UAAU,WAAW;AAC5E,UAAME,eAAc,mBAAmB;AACvC,WAAO;AAAA,MACL;AAAA,MACA,WAAW,SAAS;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,MAAM,OAAO,WAAWA,YAAW;AAAA,MAC1C,aAAAA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,qBAAqB,WAAW;AACvD,QAAM,cAAc,mBAAmB;AACvC,SAAO;AAAA,IACL;AAAA,IACA,WAAW,SAAS;AAAA,IACpB,SAAS;AAAA,IACT,MAAM,mBAAmB,QAAQ,CAAC,WAAW,WAAW,IAAI,CAAC,OAAO,WAAW;AAAA,IAC/E;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,aAA8C;AAC1E,UAAI,2BAAW,iBAAAJ,QAAK,KAAK,aAAa,gBAAgB,CAAC,EAAG,QAAO;AACjE,UAAI,2BAAW,iBAAAA,QAAK,KAAK,aAAa,WAAW,CAAC,EAAG,QAAO;AAC5D,SAAO;AACT;AAEA,SAAS,qBAAqB,aAAqB,UAA6C;AAC9F,QAAM,aAAa,aAAa,WAAW,wBAAwB;AACnE,SAAO,CAAC,iBAAAA,QAAK,KAAK,aAAa,UAAU,GAAG,iBAAAA,QAAK,KAAK,aAAa,uBAAuB,CAAC;AAC7F;AAEA,SAAS,cAAc,SAAiB,MAAgB,KAA4B;AAClF,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,YAAQ,iCAAM,SAAS,MAAM;AAAA,MACjC;AAAA,MACA,OAAO;AAAA,MACP,OAAO,oBAAAE,QAAQ,aAAa;AAAA,IAC9B,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,UAAU;AAC3B,aAAO,IAAI,SAAS,iBAAiB,cAAc,SAAS,IAAI,CAAC,KAAK,MAAM,OAAO,EAAE,CAAC;AAAA,IACxF,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,UAAI,SAAS,GAAG;AACd,gBAAQ;AACR;AAAA,MACF;AACA;AAAA,QACE,IAAI,SAAS,GAAG,cAAc,SAAS,IAAI,CAAC,0BAA0B,QAAQ,SAAS,EAAE;AAAA,MAC3F;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,cAAc,SAAiB,MAAwB;AAC9D,SAAO,CAAC,SAAS,GAAG,IAAI,EAAE,KAAK,GAAG;AACpC;AAEA,SAAS,oBAA4B;AACnC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeT;AAEA,SAAS,gBAAwB;AAC/B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBT;AAEA,SAAS,aAAa,SAAyB,QAAwB,KAAuB;AAC5F,sBAAAA,QAAQ,OAAO,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,IAAI,QAAQ,EAAE;AAAA,CAAI;AAC9D,iBAAe;AAAA,IACb,MAAM,QAAQ,QAAQ;AAAA,IACtB,OAAO,QAAQ,aAAa,QAAQ,aAAa;AAAA,IACjD,QAAQ,QAAQ,UAAU;AAAA,IAC1B,QAAQ,GAAG,QAAQ,UAAU,GAAG,KAAK,aAAa,QAAQ,OAAO,CAAC;AAAA,IAClE,OAAO,qBAAqB,QAAQ,KAAK;AAAA,IACzC,UAAU,eAAe,QAAQ,UAAU;AAAA,IAC3C,MAAM,WAAW,QAAQ,aAAa;AAAA,IACtC,QAAQ,QAAQ,eAAe;AAAA,IAC/B,QAAQ,QAAQ,eAAe,OAAO;AAAA,IACtC,WAAW,WAAW,QAAQ,SAAS;AAAA,IACvC,aAAa,WAAW,QAAQ,WAAW;AAAA,EAC7C,CAAC;AAED,MAAI,QAAQ,eAAe;AACzB,wBAAAA,QAAQ,OAAO,MAAM;AAAA;AAAA,EAAsB,OAAO,KAAK,QAAQ,aAAa,CAAC,CAAC;AAAA,CAAI;AAAA,EACpF;AACA,MAAI,QAAQ,WAAW;AACrB,wBAAAA,QAAQ,OAAO,MAAM;AAAA;AAAA,EAAa,OAAO,KAAK,QAAQ,SAAS,CAAC,CAAC;AAAA,CAAI;AAAA,EACvE;AACA,MAAI,QAAQ,iBAAiB;AAC3B,wBAAAA,QAAQ,OAAO,MAAM;AAAA;AAAA,EAAc,OAAO,KAAK,QAAQ,eAAe,CAAC,CAAC;AAAA,CAAI;AAAA,EAC9E;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,wBAAAA,QAAQ,OAAO,MAAM;AAAA,EAAK,KAAK,KAAK,QAAQ,CAAC;AAAA,CAAI;AACjD,eAAW,SAAS,QAAQ;AAC1B,iBAAW,OAAO,GAAG;AAAA,IACvB;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAAqB,KAAuB;AAC9D,QAAM,SAAS,IAAI,MAAM,kBAAkB,GAAG,IAAI,MAAM,SAAS;AACjE,QAAM,QACJ,MAAM,cAAc,WAAW,mBAAmB,MAAM,SAAS,IAC7D,MAAM,KAAK,OAAO,MAAM,IACxB,MAAM,KAAK,QAAQ,MAAM;AAC/B,sBAAAA,QAAQ,OAAO,MAAM,GAAG,KAAK,IAAI,WAAW,MAAM,SAAS,CAAC,EAAE;AAC9D,MAAI,MAAM,SAAU,qBAAAA,QAAQ,OAAO,MAAM,SAAS,MAAM,QAAQ,EAAE;AAClE,MAAI,MAAM,cAAe,qBAAAA,QAAQ,OAAO,MAAM,SAAS,WAAW,MAAM,aAAa,CAAC,EAAE;AACxF,MAAI,MAAM,WAAY,qBAAAA,QAAQ,OAAO,MAAM,WAAW,MAAM,UAAU,EAAE;AACxE,sBAAAA,QAAQ,OAAO,MAAM,IAAI;AAEzB,QAAM,UAAU,eAAe,KAAK;AACpC,MAAI,QAAS,qBAAAA,QAAQ,OAAO,MAAM,GAAG,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAAA,CAAI;AACpE;AAEA,SAAS,eAAe,OAA6B;AACnD,MAAI,mBAAmB,MAAM,SAAS,GAAG;AACvC,WAAO,UAAU,kBAAkB,MAAM,SAAS,CAAC;AAAA,EACrD;AACA,MAAI,MAAM,WAAW;AACnB,WAAO,MAAM;AAAA,EACf;AACA,MAAI,mBAAmB,MAAM,UAAU,GAAG;AACxC,WAAO,WAAW,kBAAkB,MAAM,UAAU,CAAC;AAAA,EACvD;AACA,MAAI,mBAAmB,MAAM,SAAS,GAAG;AACvC,WAAO,UAAU,kBAAkB,MAAM,SAAS,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,QAAuC;AAC7D,QAAM,UAAU,OAAO,QAAQ,MAAM;AACrC,QAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,IAAI,KAAK,IAAI,MAAM,GAAG,CAAC;AACzE,aAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,wBAAAA,QAAQ,OAAO,MAAM,GAAG,IAAI,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC;AAAA,CAAI;AAAA,EACjE;AACF;AAEA,SAAS,UAAU,OAAsB;AACvC,sBAAAA,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAC5D;AAQA,SAAS,WAAc,MAAW,SAAsC;AACtE,QAAM,SAAS,QAAQ,IAAI,CAAC,WAAW;AACrC,UAAM,MAAM,KAAK,IAAI,OAAO,OAAO,QAAQ,GAAG,KAAK,IAAI,CAAC,QAAQ,OAAO,OAAO,GAAG,EAAE,MAAM,CAAC;AAC1F,WAAO,KAAK,IAAI,KAAK,OAAO,QAAQ;AAAA,EACtC,CAAC;AAED,QAAM,SAAS,QACZ,IAAI,CAAC,QAAQ,UAAU,IAAI,SAAS,OAAO,QAAQ,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,CAAC,EACjF,KAAK,IAAI;AACZ,QAAM,UAAU,OAAO,IAAI,CAAC,UAAU,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,IAAI;AAClE,sBAAAA,QAAQ,OAAO,MAAM,GAAG,MAAM;AAAA,EAAK,OAAO;AAAA,CAAI;AAE9C,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,QACV,IAAI,CAAC,QAAQ,UAAU,IAAI,SAAS,OAAO,OAAO,GAAG,GAAG,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,CAAC,EACtF,KAAK,IAAI;AACZ,wBAAAA,QAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,EAClC;AACF;AAEA,SAAS,SAAS,OAAe,OAAuB;AACtD,MAAI,MAAM,UAAU,MAAO,QAAO;AAClC,MAAI,SAAS,EAAG,QAAO,MAAM,MAAM,GAAG,KAAK;AAC3C,SAAO,GAAG,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,MAAM,MAAM,GAAG,KAAK;AACzD;AAEA,SAAS,IAAI,OAAe,OAAuB;AACjD,SAAO,GAAG,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,GAAG,QAAQ,MAAM,MAAM,CAAC,CAAC;AACjE;AAEA,SAAS,MAAM,KAAiB,MAA2C,OAAuB;AAChG,MAAI,CAAC,IAAI,MAAO,QAAO;AACvB,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AACA,SAAO,QAAU,MAAM,IAAI,CAAC,IAAI,KAAK;AACvC;AAEA,SAAS,KAAK,KAAiB,OAAuB;AACpD,SAAO,IAAI,QAAQ,UAAY,KAAK,YAAc;AACpD;AAEA,SAAS,cAAc,KAAiB,UAA+C;AACrF,MAAI,aAAa,OAAQ,QAAO,MAAM,KAAK,OAAO,QAAQ;AAC1D,MAAI,aAAa,SAAU,QAAO,MAAM,KAAK,UAAU,UAAU;AACjE,MAAI,aAAa,MAAO,QAAO,MAAM,KAAK,QAAQ,OAAO;AACzD,SAAO;AACT;AAEA,SAAS,aAAa,SAA6C;AACjE,MAAI,YAAY,KAAM,QAAO;AAC7B,MAAI,YAAY,MAAO,QAAO;AAC9B,SAAO;AACT;AAEA,SAAS,qBAAqB,OAA0C;AACtE,SAAO,OAAO,UAAU,WAAW,OAAO,KAAK,MAAM,QAAQ,EAAE,IAAI,EAAE,IAAI;AAC3E;AAEA,SAAS,eAAe,IAAuC;AAC7D,MAAI,OAAO,OAAO,SAAU,QAAO;AACnC,MAAI,KAAK,IAAM,QAAO,GAAG,EAAE;AAC3B,MAAI,KAAK,IAAQ,QAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AACjD,SAAO,IAAI,KAAK,KAAQ,QAAQ,CAAC,CAAC;AACpC;AAEA,SAAS,WAAW,MAAyC;AAC3D,SAAO,OAAO,SAAS,WAAW,IAAI,KAAK,QAAQ,CAAC,CAAC,KAAK;AAC5D;AAEA,SAAS,WAAW,OAA0C;AAC5D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,KAAK,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AACzD;AAEA,SAAS,kBAAkB,OAAwB;AACjD,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAEA,SAAS,KAAK,MAAc,QAAQ,IAAY;AAC9C,QAAM,QAAQ,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG;AACxD,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAU;AACd,aAAW,QAAQ,OAAO;AACxB,QAAI,GAAG,OAAO,IAAI,IAAI,GAAG,KAAK,EAAE,SAAS,SAAS,SAAS;AACzD,YAAM,KAAK,OAAO;AAClB,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU,GAAG,OAAO,IAAI,IAAI,GAAG,KAAK;AAAA,IACtC;AAAA,EACF;AACA,MAAI,QAAS,OAAM,KAAK,OAAO;AAC/B,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,OAAO,MAAc,SAAS,GAAW;AAChD,QAAM,SAAS,IAAI,OAAO,MAAM;AAChC,SAAO,KACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,EAAE,EAChC,KAAK,IAAI;AACd;AAEA,eAAsB,IAAI,MAA+B;AACvD,QAAM,SAAS,UAAU,IAAI;AAC7B,QAAM,MAAM,cAAc,OAAO,KAAK;AACtC,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI,OAAO;AAElC,MAAI,eAAe,OAAO,OAAO,SAAS,GAAG;AAC3C,wBAAAA,QAAQ,OAAO,MAAM,GAAG,OAAW;AAAA,CAAI;AACvC;AAAA,EACF;AAEA,MAAI,CAAC,WAAW,eAAe,OAAO,OAAO,MAAM,GAAG;AACpD,wBAAAA,QAAQ,OAAO,MAAM,IAAI;AACzB;AAAA,EACF;AAEA,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,YAAM,eAAe,KAAK,OAAO,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,YAAY,KAAK,OAAO,KAAK;AACnC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,KAAK,OAAO,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,gBAAgB,KAAK,OAAO,OAAO,IAAI;AAC7C;AAAA,IACF,KAAK;AACH,YAAM,cAAc,KAAK,OAAO,OAAO,IAAI;AAC3C;AAAA,IACF,KAAK;AACH,YAAM,eAAe,KAAK,OAAO,OAAO,IAAI;AAC5C;AAAA,IACF,KAAK;AACH,YAAM,gBAAgB,KAAK,OAAO,OAAO,KAAK,CAAC,CAAC;AAChD;AAAA,IACF,KAAK;AACH,YAAM,gBAAgB,KAAK,OAAO,OAAO,KAAK,CAAC,CAAC;AAChD;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACH,sBAAgB,OAAO;AACvB;AAAA,IACF;AACE,YAAM,IAAI,SAAS,oBAAoB,OAAO,wBAAwB;AAAA,EAC1E;AACF;AAEA,IAAI,oBAAAA,QAAQ,IAAI,+BAA+B,KAAK;AAClD,MAAI,oBAAAA,QAAQ,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,UAAmB;AACnD,QAAI,iBAAiB,UAAU;AAC7B,UAAI,oBAAAA,QAAQ,IAAI,oBAAoB;AAClC,4BAAAA,QAAQ,OAAO,MAAM,GAAG,MAAM,SAAS,MAAM,OAAO;AAAA,CAAI;AAAA,MAC1D,OAAO;AACL,4BAAAA,QAAQ,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,CAAI;AAAA,MAClD;AACA,0BAAAA,QAAQ,WAAW,MAAM;AACzB;AAAA,IACF;AAEA,wBAAAA,QAAQ,OAAO;AAAA,MACb,GAAG,iBAAiB,QAAS,MAAM,SAAS,MAAM,UAAW,OAAO,KAAK,CAAC;AAAA;AAAA,IAC5E;AACA,wBAAAA,QAAQ,WAAW;AAAA,EACrB,CAAC;AACH;","names":["path","os","process","readline","packageName"]}
|
package/dist/cli.d.cts
CHANGED
|
@@ -1,54 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { S as SessionResponse, E as EventResponse } from './types-BEf8OATP.cjs';
|
|
3
|
+
|
|
2
4
|
type FlagValue = string | boolean | undefined;
|
|
3
5
|
interface ParsedArgs {
|
|
4
6
|
flags: Record<string, FlagValue>;
|
|
5
7
|
positionals: string[];
|
|
6
8
|
}
|
|
7
|
-
|
|
8
|
-
id: string;
|
|
9
|
-
name?: string | null;
|
|
10
|
-
agentName?: string | null;
|
|
11
|
-
agentSlug?: string | null;
|
|
12
|
-
userId?: string | null;
|
|
13
|
-
status?: string | null;
|
|
14
|
-
success?: boolean | null;
|
|
15
|
-
failureReason?: string | null;
|
|
16
|
-
totalEvents?: number | null;
|
|
17
|
-
durationMs?: number | null;
|
|
18
|
-
estimatedCost?: number | null;
|
|
19
|
-
promptTokens?: number | null;
|
|
20
|
-
completionTokens?: number | null;
|
|
21
|
-
totalTokens?: number | null;
|
|
22
|
-
score?: number | null;
|
|
23
|
-
metricScores?: unknown;
|
|
24
|
-
metricReasonings?: unknown;
|
|
25
|
-
customMetrics?: unknown;
|
|
26
|
-
userInput?: string | null;
|
|
27
|
-
assistantOutput?: string | null;
|
|
28
|
-
metadata?: unknown;
|
|
29
|
-
detectedIssues?: unknown;
|
|
30
|
-
createdAt?: string | null;
|
|
31
|
-
completedAt?: string | null;
|
|
32
|
-
}
|
|
33
|
-
interface EventSummary {
|
|
34
|
-
id: string;
|
|
35
|
-
sessionId: string;
|
|
36
|
-
eventType: string;
|
|
37
|
-
sequenceNumber?: number | null;
|
|
38
|
-
timestamp?: string | null;
|
|
39
|
-
toolName?: string | null;
|
|
40
|
-
toolInput?: unknown;
|
|
41
|
-
toolOutput?: unknown;
|
|
42
|
-
toolError?: unknown;
|
|
43
|
-
reasoning?: string | null;
|
|
44
|
-
alternativesConsidered?: unknown;
|
|
45
|
-
confidence?: number | null;
|
|
46
|
-
estimatedCost?: number | null;
|
|
47
|
-
tokenCount?: number | null;
|
|
48
|
-
metadata?: unknown;
|
|
49
|
-
traceId?: string | null;
|
|
50
|
-
spanId?: string | null;
|
|
51
|
-
}
|
|
9
|
+
|
|
52
10
|
interface DiagnoseFinding {
|
|
53
11
|
severity: 'high' | 'medium' | 'low' | 'info';
|
|
54
12
|
title: string;
|
|
@@ -66,7 +24,7 @@ declare class CliError extends Error {
|
|
|
66
24
|
constructor(message: string, exitCode?: number);
|
|
67
25
|
}
|
|
68
26
|
declare function parseArgs(argv: string[]): ParsedArgs;
|
|
69
|
-
declare function diagnoseSession(session:
|
|
27
|
+
declare function diagnoseSession(session: SessionResponse, events: EventResponse[]): DiagnoseFinding[];
|
|
70
28
|
declare function detectProject(projectRoot: string): {
|
|
71
29
|
language?: 'typescript' | 'python';
|
|
72
30
|
framework?: string;
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,54 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { S as SessionResponse, E as EventResponse } from './types-BEf8OATP.js';
|
|
3
|
+
|
|
2
4
|
type FlagValue = string | boolean | undefined;
|
|
3
5
|
interface ParsedArgs {
|
|
4
6
|
flags: Record<string, FlagValue>;
|
|
5
7
|
positionals: string[];
|
|
6
8
|
}
|
|
7
|
-
|
|
8
|
-
id: string;
|
|
9
|
-
name?: string | null;
|
|
10
|
-
agentName?: string | null;
|
|
11
|
-
agentSlug?: string | null;
|
|
12
|
-
userId?: string | null;
|
|
13
|
-
status?: string | null;
|
|
14
|
-
success?: boolean | null;
|
|
15
|
-
failureReason?: string | null;
|
|
16
|
-
totalEvents?: number | null;
|
|
17
|
-
durationMs?: number | null;
|
|
18
|
-
estimatedCost?: number | null;
|
|
19
|
-
promptTokens?: number | null;
|
|
20
|
-
completionTokens?: number | null;
|
|
21
|
-
totalTokens?: number | null;
|
|
22
|
-
score?: number | null;
|
|
23
|
-
metricScores?: unknown;
|
|
24
|
-
metricReasonings?: unknown;
|
|
25
|
-
customMetrics?: unknown;
|
|
26
|
-
userInput?: string | null;
|
|
27
|
-
assistantOutput?: string | null;
|
|
28
|
-
metadata?: unknown;
|
|
29
|
-
detectedIssues?: unknown;
|
|
30
|
-
createdAt?: string | null;
|
|
31
|
-
completedAt?: string | null;
|
|
32
|
-
}
|
|
33
|
-
interface EventSummary {
|
|
34
|
-
id: string;
|
|
35
|
-
sessionId: string;
|
|
36
|
-
eventType: string;
|
|
37
|
-
sequenceNumber?: number | null;
|
|
38
|
-
timestamp?: string | null;
|
|
39
|
-
toolName?: string | null;
|
|
40
|
-
toolInput?: unknown;
|
|
41
|
-
toolOutput?: unknown;
|
|
42
|
-
toolError?: unknown;
|
|
43
|
-
reasoning?: string | null;
|
|
44
|
-
alternativesConsidered?: unknown;
|
|
45
|
-
confidence?: number | null;
|
|
46
|
-
estimatedCost?: number | null;
|
|
47
|
-
tokenCount?: number | null;
|
|
48
|
-
metadata?: unknown;
|
|
49
|
-
traceId?: string | null;
|
|
50
|
-
spanId?: string | null;
|
|
51
|
-
}
|
|
9
|
+
|
|
52
10
|
interface DiagnoseFinding {
|
|
53
11
|
severity: 'high' | 'medium' | 'low' | 'info';
|
|
54
12
|
title: string;
|
|
@@ -66,7 +24,7 @@ declare class CliError extends Error {
|
|
|
66
24
|
constructor(message: string, exitCode?: number);
|
|
67
25
|
}
|
|
68
26
|
declare function parseArgs(argv: string[]): ParsedArgs;
|
|
69
|
-
declare function diagnoseSession(session:
|
|
27
|
+
declare function diagnoseSession(session: SessionResponse, events: EventResponse[]): DiagnoseFinding[];
|
|
70
28
|
declare function detectProject(projectRoot: string): {
|
|
71
29
|
language?: 'typescript' | 'python';
|
|
72
30
|
framework?: string;
|
package/dist/cli.js
CHANGED
|
@@ -7,8 +7,14 @@ import os from "os";
|
|
|
7
7
|
import path from "path";
|
|
8
8
|
import process from "process";
|
|
9
9
|
import readline from "readline/promises";
|
|
10
|
+
|
|
11
|
+
// src/constants.ts
|
|
10
12
|
var DEFAULT_API_URL = "https://api.sentrial.com";
|
|
11
|
-
|
|
13
|
+
|
|
14
|
+
// package.json
|
|
15
|
+
var version = "0.5.0";
|
|
16
|
+
|
|
17
|
+
// src/cli.ts
|
|
12
18
|
var CONFIG_DIR = path.join(os.homedir(), ".sentrial");
|
|
13
19
|
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
14
20
|
var TIME_RANGES = /* @__PURE__ */ new Set(["24h", "3d", "7d", "30d"]);
|
|
@@ -37,9 +43,6 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
37
43
|
"include-api-key",
|
|
38
44
|
"json",
|
|
39
45
|
"dry-run",
|
|
40
|
-
"no-color",
|
|
41
|
-
"no-events",
|
|
42
|
-
"no-fail-on-regression",
|
|
43
46
|
"version",
|
|
44
47
|
"yes"
|
|
45
48
|
]);
|
|
@@ -57,8 +60,7 @@ Commands:
|
|
|
57
60
|
events list <session-id> List events for a session
|
|
58
61
|
signals list List detected signals
|
|
59
62
|
diagnose <session-id> Print a terminal diagnosis from session events
|
|
60
|
-
evaluate <experiment-id> Run the /api/v1/evaluate CI gate
|
|
61
|
-
clusters Reserved for the upcoming clusters API
|
|
63
|
+
evaluate <experiment-id> Run the /api/v1/evaluate CI gate (API key needs the metrics:read scope)
|
|
62
64
|
fix <session-id> Reserved for the upcoming Fixer API
|
|
63
65
|
replay <session-id> Reserved for the upcoming replay API
|
|
64
66
|
|
|
@@ -294,7 +296,7 @@ async function commandInit(ctx, flags) {
|
|
|
294
296
|
const requestedLanguage = getStringFlag(flags, "language");
|
|
295
297
|
const language = requestedLanguage ?? detected.language ?? "typescript";
|
|
296
298
|
const force = getBooleanFlag(flags, "force");
|
|
297
|
-
const
|
|
299
|
+
const includeApiKey = getBooleanFlag(flags, "include-api-key");
|
|
298
300
|
if (language !== "typescript" && language !== "python") {
|
|
299
301
|
throw new CliError('Supported init languages are "typescript" and "python".');
|
|
300
302
|
}
|
|
@@ -311,10 +313,18 @@ async function commandInit(ctx, flags) {
|
|
|
311
313
|
];
|
|
312
314
|
files.push({
|
|
313
315
|
path: path.join(projectRoot, ".env.sentrial.example"),
|
|
314
|
-
content: `SENTRIAL_API_KEY
|
|
316
|
+
content: `SENTRIAL_API_KEY=sentrial_live_xxx
|
|
315
317
|
SENTRIAL_API_URL=${ctx.apiUrl}
|
|
316
318
|
`
|
|
317
319
|
});
|
|
320
|
+
if (includeApiKey && ctx.apiKey) {
|
|
321
|
+
files.push({
|
|
322
|
+
path: path.join(projectRoot, ".env.sentrial"),
|
|
323
|
+
content: `SENTRIAL_API_KEY=${ctx.apiKey}
|
|
324
|
+
SENTRIAL_API_URL=${ctx.apiUrl}
|
|
325
|
+
`
|
|
326
|
+
});
|
|
327
|
+
}
|
|
318
328
|
const written = [];
|
|
319
329
|
const skipped = [];
|
|
320
330
|
for (const file of files) {
|
|
@@ -585,7 +595,6 @@ ${response.failures.map((f) => ` - ${String(f)}`).join("\n")}
|
|
|
585
595
|
}
|
|
586
596
|
function commandReserved(command) {
|
|
587
597
|
const messages = {
|
|
588
|
-
clusters: "The clusters CLI is reserved for the upcoming /api/v1/clusters endpoint.",
|
|
589
598
|
fix: "The Fixer CLI is reserved for the upcoming scriptable Fixer API.",
|
|
590
599
|
replay: "The replay CLI is reserved for the upcoming replay API."
|
|
591
600
|
};
|
|
@@ -1027,7 +1036,7 @@ async function run(argv) {
|
|
|
1027
1036
|
const ctx = createContext(parsed.flags);
|
|
1028
1037
|
const [command, ...rest] = parsed.positionals;
|
|
1029
1038
|
if (getBooleanFlag(parsed.flags, "version")) {
|
|
1030
|
-
process.stdout.write(`${
|
|
1039
|
+
process.stdout.write(`${version}
|
|
1031
1040
|
`);
|
|
1032
1041
|
return;
|
|
1033
1042
|
}
|
|
@@ -1060,7 +1069,6 @@ async function run(argv) {
|
|
|
1060
1069
|
case "evaluate":
|
|
1061
1070
|
await commandEvaluate(ctx, parsed.flags, rest[0]);
|
|
1062
1071
|
break;
|
|
1063
|
-
case "clusters":
|
|
1064
1072
|
case "fix":
|
|
1065
1073
|
case "replay":
|
|
1066
1074
|
commandReserved(command);
|