Skip to main content
Glama
PostHogEvents.kt9.01 kB
package maestro.cli.analytics import maestro.cli.model.FlowStatus import maestro.cli.util.EnvUtils import maestro.cli.util.IOSEnvUtils import maestro.device.util.AndroidEnvUtils /** * Organization status enum */ enum class OrgStatus(val value: String) { TRIAL_EXPIRED("TRIAL_EXPIRED"), GRACE_PERIOD_EXPIRED("GRACE_PERIOD_EXPIRED"), ACTIVE("ACTIVE"), TRIAL_NOT_ACTIVE("TRIAL_NOT_ACTIVE"), IN_GRACE_PERIOD("IN_GRACE_PERIOD"); } enum class OrgPlans(val value: String) { BASIC("BASIC"), CLOUD("CLOUD"), CLOUD_MANUAL("CLOUD_MANUAL"), ENTERPRISE("ENTERPRISE"), } /** * Strongly-typed PostHog events for Maestro CLI using discriminated unions * This ensures compile-time type safety for all analytics events */ /** * Super properties that are automatically included with every event */ data class SuperProperties( val app_version: String, val platform: String, val env: String, val app: String = "cli", val cli_version: String, val java_version: String, val os_arch: String, val os_version: String, val xcode_version: String? = null, val flutter_version: String? = null, val flutter_channel: String? = null, val android_versions: List<String>? = null, val ios_versions: List<String>? = null, ) { /** * Convert to Map for analytics tracking */ fun toMap(): Map<String, Any> { return mapOf( "app_version" to app_version, "platform" to platform, "env" to env, "app" to app, "cli_version" to cli_version, "java_version" to java_version, "os_arch" to os_arch, "os_version" to os_version, "xcode_version" to xcode_version, "flutter_version" to flutter_version, "flutter_channel" to flutter_channel, "android_versions" to android_versions, "ios_versions" to ios_versions ) as Map<String, Any> } /** * Create SuperProperties with current system information */ companion object { fun create(): SuperProperties { return SuperProperties( app_version = EnvUtils.getVersion().toString(), platform = EnvUtils.OS_NAME, env = if (System.getenv("MAESTRO_API_URL") != null) "dev" else "prod", app = "cli", cli_version = EnvUtils.CLI_VERSION.toString(), java_version = EnvUtils.getJavaVersion().toString(), os_arch = EnvUtils.OS_ARCH, os_version = EnvUtils.OS_VERSION, xcode_version = IOSEnvUtils.xcodeVersion, flutter_version = EnvUtils.getFlutterVersionAndChannel().first, flutter_channel = EnvUtils.getFlutterVersionAndChannel().second, android_versions = AndroidEnvUtils.androidEmulatorSdkVersions, ios_versions = IOSEnvUtils.simulatorRuntimes ) } } } /** * User properties for user identification */ data class UserProperties( val user_id: String?, val email: String?, val name: String?, val organizationId: String? = null, val org_id: String?, val org_name: String?, val plan: String?, val orgPlan: String?, val orgTrialExpiresOn: String?, ) { /** * Convert to Map for analytics tracking */ fun toMap(): Map<String, Any> { return mapOf( "user_id" to user_id, "email" to email, "name" to name, "organizationId" to organizationId, "org_id" to org_id, "org_name" to org_name, "plan" to plan, "orgPlan" to orgPlan, "orgTrialExpiresOn" to orgTrialExpiresOn ) as Map<String, Any> } /** * Create UserProperties from AnalyticsState */ companion object { fun fromAnalyticsState(state: AnalyticsState): UserProperties { return UserProperties( user_id = state.user_id, email = state.email, name = state.name, organizationId = state.orgId, org_id = state.orgId, org_name = state.orgName, plan = state.orgPlan, orgPlan = state.orgPlan, orgTrialExpiresOn = state.orgTrialExpiresOn, ) } } } /** * Base interface for all PostHog events */ sealed interface PostHogEvent { val name: String } /** * CLI Usage Events */ sealed interface CliUsageEvent : PostHogEvent data class CliCommandRunEvent( override val name: String = "maestro_cli_command_run", val command: String ) : CliUsageEvent /** * Test execution events */ sealed interface TestRunEvent : PostHogEvent data class TestRunStartedEvent( override val name: String = "test_run_started", val platform: String, ) : TestRunEvent data class TestRunFailedEvent( override val name: String = "test_run_failed", val error: String, val platform: String, ) : TestRunEvent data class TestRunFinishedEvent( override val name: String = "test_run_finished", val status: FlowStatus, val platform: String, val durationMs: Long ) : TestRunEvent /** * Workspace execution events */ sealed interface WorkspaceRunEvent : PostHogEvent data class WorkspaceRunStartedEvent( override val name: String = "workspace_run_started", val flowCount: Int, val platform: String, val deviceCount: Int ) : WorkspaceRunEvent data class WorkspaceRunFailedEvent( override val name: String = "workspace_run_failed", val error: String, val flowCount: Int, val platform: String, val deviceCount: Int, ) : WorkspaceRunEvent data class WorkspaceRunFinishedEvent( override val name: String = "workspace_run_finished", val flowCount: Int, val platform: String, val deviceCount: Int, val durationMs: Long ) : WorkspaceRunEvent /** * Record Screen Event */ sealed interface RecordEvent : PostHogEvent data class RecordStartedEvent( override val name: String = "maestro_cli_record_start", val platform: String, ) : RecordEvent data class RecordFinishedEvent( override val name: String = "maestro_cli_record_finished", val platform: String, val durationMs: Long ) : RecordEvent /** * Cloud Upload Events */ sealed interface CloudUploadEvent : PostHogEvent data class CloudUploadTriggeredEvent( override val name: String = "cloud_upload_triggered", val projectId: String, val platform: String, val isBinaryUpload: Boolean = false, val usesEnvironment: Boolean = false, val deviceModel: String? = null, val deviceOs: String? = null ) : CloudUploadEvent data class CloudUploadStartedEvent( override val name: String = "cloud_upload_started", val projectId: String, val platform: String, val isBinaryUpload: Boolean = false, val usesEnvironment: Boolean = false, val deviceModel: String? = null, val deviceOs: String? = null ) : CloudUploadEvent data class CloudUploadSucceededEvent( override val name: String = "cloud_upload_succeeded", val projectId: String, val platform: String, val isBinaryUpload: Boolean, val usesEnvironment: Boolean, val deviceModel: String? = null, val deviceOs: String? = null, ) : CloudUploadEvent /** * Cloud Run Event */ sealed interface CloudRunEvent : PostHogEvent data class CloudRunFinishedEvent( override val name: String = "cloud_run_finished", val projectId: String, val appPackageId: String, val totalFlows: Number, val totalPassedFlows: Number, val totalFailedFlows: Number, val wasAppLaunched: Boolean ) : CloudRunEvent /** * User Auth Event */ sealed interface AuthEvent : PostHogEvent data class UserAuthenticatedEvent( override val name: String = "user_authenticated", val isFirstAuth: Boolean, val authMethod: String, ) : AuthEvent data class UserLoggedOutEvent( override val name: String = "user_logged_out", ) : AuthEvent /** * Print Hierarchy Events */ sealed interface PrintHierarchyEvent : PostHogEvent data class PrintHierarchyStartedEvent( override val name: String = "print_hierarchy_started", val platform: String ) : PrintHierarchyEvent data class PrintHierarchyFinishedEvent( override val name: String = "print_hierarchy_finished", val platform: String, val success: Boolean, val durationMs: Long, val errorMessage: String? = null ) : PrintHierarchyEvent /** * Trial Events */ sealed interface TrialEvent : PostHogEvent data class TrialStartPromptedEvent( override val name: String = "trial_start_prompted", ) : TrialEvent data class TrialStartedEvent( override val name: String = "trial_started", val companyName: String, ) : TrialEvent data class TrialStartFailedEvent( override val name: String = "trial_start_failed", val companyName: String, val failureReason: String, ) : TrialEvent

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mobile-dev-inc/Maestro'

If you have feedback or need assistance with the MCP directory API, please join our Discord server